Skip to content

Latest commit

 

History

History
245 lines (176 loc) · 13.4 KB

usd.md

File metadata and controls

245 lines (176 loc) · 13.4 KB

USD Wiki

I've been using Pixar's USD in a CG pipeline for over a year now. Here's some helpful things I've noted.

C++/Python

Most of these are following are python snippets. The function interface is mostly the same with the C++ API with some noticeable language differences:

  • Wrap values with pxr::VtValue(10.0f) pxr::VtValue("Value")
  • Paths with pxr::SdfPath("/path")

Resources

Stage

Creation

Code
memory stage = Usd.Stage.CreateInMemory()
file stage = Usd.Stage.CreateNew("/path/to/stage.usda")

Metadata

Code
comment stage.SetMetadata('comment', 'This will be the comment')
documentation stage.SetMetadata('documentation', 'This will be the documentation')
documentation stage.GetPseduoRoot().SetDocumentation('This will be the documentation")
renderSettingsPrimPath stage.SetMetadata('renderSettingsPrimPath', '/RenderSettings/Prim')

Interesting note is that there is no current API to set render settings prim path except explicitly via token...

Output

Code Docs
save stage.GetRootLayer().Save() docs
save as stage.Export( "/path/to/output.usda" ) docs
print print( stage.ExportToString() ) docs

Traversal

Stage

To traverse recursively through every prim:

Python

for prim in stage.Traverse():
    print(prim)

C++

for (pxr::UsdPrim prim: usd_stage->Traverse()) {
    std::cout << "Prim path: " << prim.GetPath().GetText() << '\n';
}

or

pxr::UsdPrimRange prim_range = usd_stage->Traverse();
for (auto it = prim_range.begin(); it!=prim_range.end(); ++it) {
    std::cout << "Found prim: " << it->GetPath().GetText() << '\n';
    
}

Children

C++

for (const pxr::UsdPrim &childPrim : prim.GetChildren()) {
    // Do something...
}

Layers

Layers are core part of USD composition. A usd file can have "SubLayers". A Stage can have multiple "Layers". Both "In Memory Layers" and "On Disk Layers".

There is not as nice of an API for layers, and it actaully differs whether in Python or C++. (Link)[https://groups.google.com/g/usd-interest/c/usUeP1USk04/m/ENTOmMsBBwAJ]

Code Docs Tips
add sublayer stage.GetRootLayer().subLayerPaths.append(usd_file) (python)
get layer stack stage.GetLayerStack() (python)

Prims

Code Docs Tips
define stage.DefinePrim("/primpath") docs Gets or creates prim at primpath. To transform, prim must be an xform (or sub type)
exists stage.GetPrimAtPath("/primpath") docs Return prim object. Can be invalid (Check with IsValid)
valid prim.IsValid() docs False if not valid (Doesn't exist)
attribute prim.GetAttribute('attribName') docs Use .Get() and .Set(val)
type (string) prim.GetTypeName() docs
prim path prim.GetPath() docs Explicitly as C++ String prim.GetPath().GetString()
prim name prim.GetName() docs Explicitly as C++ String prim.GetName().GetString()

Tokens

USD Tokens are a handle for a registered string. Basically all strings must be tokens. In python these are usually converted automagically.

Sanitize String

In order to "sanitize" a string to be a valid usd token you can use this function: docs

Python

from pxr import Tf
token = Tf.MakeValidIdentifier("some.illegal/string") 

C++

TfToken token = TfMakeValidIdentifier("some.illegal/string");

Attributes

Note: Value Types for C++: pxr::SdfValueTypeNames->String Value Types for Python: Sdf.ValueTypeNames.String

For userProperties, append userProperties: to attribute name.

Code Docs Tips
create attribute prim.CreateAttribute(name, Sdf.ValueTypeNames.Int, isCustom) docs
get attribute prim.GetAttribute(name) docs
set attribute (value) attribute.Set() docs In C++ you need to use the specific template Set<float>(0.5f)
get attribute (value) attribute.Get() docs In C++ you need to use a template Get<float>()
is time varying attribute.ValueMightBeTimeVarying() docs Return true if value might change. If false, it's certain that this value remains constant.

Composition

The idea of composition is one of the key parts of what makes USD so flexible. There are a few core ways to compose a USD stage.

References

USD References can either be prepended or appended. Combined with this, the reference's order in said list is used in stage composition.

Code Docs Tips
Add Reference prim.GetReferences().AddReference("C:/file/on/disk.usd") docs Adds a reference to back of prepend list
Add Reference (specific) prim.GetReferences().AddReference("C:/file/on/disk.usd", position = Usd.ListPositionFrontOfAppendList) docs Adds a reference to back of prepend list
Get References prim.GetPrimStack() docs There is no proper way yet to retrieve a list of references. This will return the composed stack, it is not recommended.

Xformables

from pxr import UsdGeom

Code Docs Tips
define xform xform = stage.DefinePrim("/primpath", "Xform") docs Gets or creates an xform prim at primpath. To transform a prim, it must be an Xform or child type
define xform xform = UsdGeom.Xform.Define(stage, "/primpath") docs Same as above.
set position UsdGeom.XformCommonAPI(xform).SetTranslate(Gf.Vec3d(x, y, z), timecode) docs
set rotation (euler) UsdGeom.XformCommonAPI(xform).SetRotate(Gf.Vec3d(x, y, z), timecode) docs Degrees
set rotation (quaternion) UsdGeom.XformCommonAPI(xform).SetRotate(Gf.Rotation(Gf.Vec3d(x, y, z), w), timecode) docs
get transform (local) UsdGeom.XformCommonAPI(xform).GetXformVectors(timecode) docs Returns tuple of (translation, rotation, scale, pivot, rotationOrder)
get transform (world) mat4 = UsdGeom.XformCache(timecode).GetLocalToWorldTransform(prim) docs Returns matrix 4x4
set transform xform.AddTransformOp().Set(transform_matrix) docs Returns tuple of (translation, rotation, scale, pivot, rotationOrder)

Gf

Graphics Foundations

from pxr import Gf

Code Docs Tips
define matrix4 mat4 = Gf.Matrix4d(2) docs Creates identity matrix
define translate matrix4 mat4 = Gf.Matrix4d(2).SetTranslate(Gf.Vec3d(x, y, z)) docs Creates translate matrix
define per element matrix4 mat4 = Gf.Matrix4d(2).SetTranslate(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1) docs Creates translate matrix
get translation mat4.ExtractTranslation() docs Get vec3 translation
get rotation mat4.ExtractRotation() docs Get rotation
get scale scale = (mat4.GetRow3(0).GetLength(), mat4.GetRow3(1).GetLength(), mat4.GetRow3(2).GetLength()) Get all axis scale

Lights

from pxr import UsdLux

Code Docs Tips
define light light_prim = stage.DefinePrim("/primpath", "DomeLight") docs This will return a prim object, no light methods attached
access light light = UsdLux.DomeLight(light_prim) docs
set dome texture dome_light.CreateTextureFileAttr().Set("/path/to/texture.exr") docs

Shaders

from pxr import UsdShade

Code Docs Tips
get shader from prim shader = UsdShade.Shader(prim) docs This will return a shader object
get filename shader.GetInput("filename").Get() docs Gets the texture filename string (Has '@' at start and end.
set existing filename shader.GetInput("filename").Set("C:/new_path.png") docs

USDZip

Sometimes you may need to zip a usd scene to a .usdz without running the provided usdzip command line tool. Turns out this is easy.

from pxr import Sdf, UsdUtils
UsdUtils.CreateNewARKitUsdzPackage(Sdf.AssetPath(usd_path), usdzip_path)
# or 
UsdUtils.CreateNewUsdzPackage(Sdf.AssetPath(usd_path), usdzip_path)

Tips

  • Most API functions are CamelCase.

Utils

Match Size / Fit to 1:1 box

Source: usd/match_size.py

USDZip Gotchas

These are somethings that got me when working with USDZips, particularly on iOS quicklook.

  • If there are multiple root prims and no default prim, iOS quicklook freaks out. Add a defaultPrim to the stage
  • "File size is too large" I've found usdzips work best when small.
    • Beware large textures. The usdzip can be small but the texture budget could be 100x as much...
  • If a texture path has an invalid path it can bundle in empty 1kb files with no extension
    • Too many (Any?) of these can sometimes cause quicklook to not display it at all
  • Scene size is important, as is the sceneUnits layer property
  • USD Apple Schemas: https://developer.apple.com/documentation/arkit/usdz_schemas_for_ar

Apple Quicklook

There are some hidden URL parameters when linking to usdz from the web