# Using conditional variable expression in usd so one variantSet switches another

**URL:** <https://forum.aousd.org/t/using-conditional-variable-expression-in-usd-so-one-variantset-switches-another/1559>\
**Category:** USD\
**Tags:** python\
**Created:** [May 28, 2024, 1:36pm UTC](https://forum.aousd.org/t/using-conditional-variable-expression-in-usd-so-one-variantset-switches-another/1559 "2024-05-28T13:36:30Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![magda](https://avatars.discourse-cdn.com/v4/letter/m/dc4da7/32.png) [@magda](https://forum.aousd.org/u/magda)\
**Post date:** [May 28, 2024, 1:36pm UTC](https://forum.aousd.org/t/using-conditional-variable-expression-in-usd-so-one-variantset-switches-another/1559/1 "2024-05-28T13:36:30Z")

</div>

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”:

```auto
#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](https://openusd.org/release/user_guides/variable_expressions.html#expression-function-reference) in this scenario.

---

<div class="post-metadata">

**Author:** ![spiff](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.aousd.org/spiff/32/22_2.png) [@spiff](https://forum.aousd.org/u/spiff)\
**Post date:** [May 31, 2024, 12:19am UTC](https://forum.aousd.org/t/using-conditional-variable-expression-in-usd-so-one-variantset-switches-another/1559/2 "2024-05-31T00:19:17Z")

</div>

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](https://github.com/PixarAnimationStudios/OpenUSD/issues/1957) is the only place I could quickly find an example of how to create nested variantSets.

Now, using the [at()](https://openusd.org/release/user_guides/variable_expressions.html#at-list-or-string-index) 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

---

<div class="post-metadata">

**Author:** ![magda](https://avatars.discourse-cdn.com/v4/letter/m/dc4da7/32.png) [@magda](https://forum.aousd.org/u/magda)\
**Post date:** [June 5, 2024, 12:21pm UTC](https://forum.aousd.org/t/using-conditional-variable-expression-in-usd-so-one-variantset-switches-another/1559/3 "2024-06-05T12:21:34Z")

</div>

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 🙂

---

<div class="post-metadata">

**Author:** ![spiff](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.aousd.org/spiff/32/22_2.png) [@spiff](https://forum.aousd.org/u/spiff)\
**Post date:** [June 5, 2024, 2:23pm UTC](https://forum.aousd.org/t/using-conditional-variable-expression-in-usd-so-one-variantset-switches-another/1559/4 "2024-06-05T14:23:33Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![magda](https://avatars.discourse-cdn.com/v4/letter/m/dc4da7/32.png) [@magda](https://forum.aousd.org/u/magda)\
**Post date:** [June 6, 2024, 9:09am UTC](https://forum.aousd.org/t/using-conditional-variable-expression-in-usd-so-one-variantset-switches-another/1559/5 "2024-06-06T09:09:15Z")

</div>

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