Skip to content

Library Overrides and USD

Blender and USD both support overrides. This page will look at a possible mapping between both override structures.

For this research we exported an asset to USD and tried to construct overrides in a similar way how it could be implemented.

Definition versus override

In USD there are two ways how to override. One is by adding a new definition of referencing the original definition and the other is with the over keyword.

An override in USD would look like this. Here we override the RIG_hairspray that is stored in the hairspray.usda file and add a relative translation.

over "refHairspray1" (  
    prepend references = @./hairspray.usda@</RIG_hairspray>  
)  
{  
    double3 xformOp:translate = (-0.1, 0, 0)  
    uniform token[] xformOpOrder = ["xformOp:transform", "xformOp:translate"]  
}

This can also be done by adding a new definition.

def Xform "refHairspray2" (  
    prepend references = @./hairspray.usda@</RIG_hairspray>  
)  
{  
    double3 xformOp:translate = (-0.1, 0, 0)  
    uniform token[] xformOpOrder = ["xformOp:transform", "xformOp:translate"]  
}

During testing we didn't detect any difference using the overrides or definitions. Also when overriding overrides.

over "refHairsprayRe1" (  
    prepend references = @./override.usda@</refHairspray3>  
)  
{  
    ....  
}

The proposal is to use the over keyword for library overrides and use def keyword for local objects.

Override hierarchy

Overrides work in hierarchy. In USD this is also supported. It is important to that the hierarchy match that of the referenced object.

over "refHairspray3" (  
    prepend references = @./hairspray.usda@</RIG_hairspray>  
)  
{  
    double3 xformOp:translate = (0.1, 0, 0)  
    uniform token[] xformOpOrder = ["xformOp:transform","xformOp:translate"]  

    over "GEO_hairspray_valve"  
    {  
        matrix4d xformOp:transform = ( (0.800000011920929, -1.4252121944522605e-26, 0, 0), (-1.425212040377865e-26, 0.800000011920929, 0, 0), (0, 0, 0.800000011920929, 0), (-0.0000020586885511875153, 3.6675849862357543e-32, 0.08, 1) )  
    }     
}

A local object can replace a child of an overridden asset. In USD this is done by name matching. the name "Circle" maps to the mesh data of the hairspray valve. If the name aren't exact both geometries will appear. The local object can reference to any further hierarchy by using its full path @./hairspray.usda@</RIG_hairspray/GEO_hairspray_valve/...>.

over "refHairsprayLocal" (  
    prepend references = @./hairspray.usda@</RIG_hairspray>  
)  
{  
    def Xform "GEO_hairspray_valve"  
    {  
        def Sphere "Circle"  
        {  
            float3[] extent = [(-2, -2, -2), (2, 2, 2)]  
            color3f[] primvars:displayColor = [(0, 0, 0.4)]  
            double radius = 0.01  
        }  
    }  
}

Animation

Blender exports animations to USD by exporting the baked result. This to ensure that the animation is the same when the USD animation is used. Due to this setup complex override setup would be exported correctly.

Materials

Blender currently does not export full materials definitions.

Putting it all together

Example of overrides loaded in gaffer using USD