Using conditional variable expression in usd so one variantSet switches another

Hi, I’m trying to use “if” variable expressions in usd so that when selection is made in variantSet “ControlVarset”, it automatically switches variantSet “Light”:

#usda 1.0
(
    endTimeCode = 1
    framesPerSecond = 24
    metersPerUnit = 1
    startTimeCode = 1
    subLayers = [
        @./geo/layer_1.usd@,
        @./geo/layer_0.usd@
    ]
    timeCodesPerSecond = 24
    upAxis = "Y"

    # unsure how to use this expression assignment part, it's from documentation :
    expressionVariables = {
        string MODEL_VARIANT = "red"
    }
)

def Xform "Variants"
{
    def Scope "Light" (
        variants = {
            string LightVar = "`if(${ControlVarset} == 'variant1', 'domelight1', \
                                 if(${ControlVarset} == variant2', 'domelight2', 'domelight4')))`"
        }
        prepend variantSets = "LightVar"
    )
    {
        variantSet "LightVar" = {
            "domelight1" {
                def DomeLight "lightMORNING" (
                    prepend apiSchemas = ["HoudiniViewportGuideAPI"]
                )
                {
                    custom rel filters = None
                    float houdini:guidescale = 1
                    bool houdini:inviewermenu = 0
                    color3f inputs:color = (1, 1, 1)
                    float inputs:diffuse = 1
                    bool inputs:enableColorTemperature = 0
                    float inputs:exposure = 0
                    float inputs:intensity = 350
                    bool inputs:normalize = 0
                    float inputs:specular = 1
                    asset inputs:texture:file = @@
                    token inputs:texture:format = "automatic"
                    rel light:filters = None
                    rel portals = None
                    matrix4d xformOp:transform = ((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1))
                    uniform token[] xformOpOrder = ["xformOp:transform"]
                }
            }
            "domelight2" {
                def DomeLight "lightDAY" (
                    prepend apiSchemas = ["HoudiniViewportGuideAPI"]
                )
                {
                    custom rel filters = None
                    float houdini:guidescale = 1
                    bool houdini:inviewermenu = 0
                    color3f inputs:color = (1, 1, 1)
                    float inputs:diffuse = 1
                    bool inputs:enableColorTemperature = 0
                    float inputs:exposure = 0
                    float inputs:intensity = 500
                    bool inputs:normalize = 0
                    float inputs:specular = 1
                    asset inputs:texture:file = @@
                    token inputs:texture:format = "automatic"
                    rel light:filters = None
                    rel portals = None
                    matrix4d xformOp:transform = ((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1))
                    uniform token[] xformOpOrder = ["xformOp:transform"]
                }
            }
        }
    }

    def Scope "Controller" (
        variants = {
            string ControlVarset = "variant1"
        }
        prepend variantSets = "ControlVarset"
    )
    {
        variantSet "ControlVarset" = {
            "variant1" {
                def DomeLight "lightMORNING" (
                    prepend apiSchemas = ["HoudiniViewportGuideAPI"]
                )
                {
                }
            }
            "variant2" {
                def DomeLight "lightDAY" (
                    prepend apiSchemas = ["HoudiniViewportGuideAPI"]
                )
                {
                }
            }
        }
    }
}

Is there a way to conditionally switch Light variantSet according to what I set ControlVarset to?

I’m unsure how to apply examples from USD Variable Expressions — Universal Scene Description 24.05 documentation in this scenario.

Hi @magda , no variant selections can only reference the values of stage-level expressionVariables, not the selections of other variantSets. The only way to make the selection of one variantSet depend on another is to “nest” the dependent set inside the controlling one. That way, each variant of the controlling VS can express a different selection for the dependent VS that gets declared inside it. This Issue is the only place I could quickly find an example of how to create nested variantSets.

Now, using the at() operator in your variant selections, in combination with a set of string-array-valued expressionVariables and an integer SELECTION_INDEX expressionVariable, you would be able to correlate any number of VariantSets’ selections to the “selection” of the control VariantSet.

The limitation with this approach is that you have a doozy of a GUI/interface issue to address, because you can no longer expect to make direct variant selections on the control VariantSet - instead, you must change the value (by integer index, no less) of the SELECTION_INDEX in your stage’s expressionVariables metadata.

I am not proposing this as a useable solution, just putting out the closest I can think of coming to what you’re exploring, to see if it sparks any further ideas or disussion.

Cheers

1 Like

Hi @spiff, thanks for clarifying things. That nesting approach does sounds like somewhat of a headache. I was looking for a clean USD solution that’d be software independent. Back to the drawing board :slight_smile:

We hope that DCC’s and viewing apps will grow GUI-level support for manipulating expression variables over time… it’s just still a quite-new feature, and we’re IP building our own GUI facilities for it in Presto, ourselves.

I’m looking forward to that as well, thanks Sebastian :slight_smile: