#usda 1.0 ( "This file describes the USD Geometric schemata for code generation." subLayers = [ @usd/schema.usda@ ] ) over "GLOBAL" ( customData = { string libraryName = "usdGeom" string libraryPath = "pxr/usd/usdGeom" # string libraryPrefix = "UsdGeom" # string tokensPrefix = "UsdGeom" dictionary libraryTokens = { dictionary interpolation = { string doc = """UsdGeomPrimvar - How a Primvar interpolates across a primitive; equivalent to RenderMan's \\ref Usd_InterpolationVals "class specifier" """ } dictionary elementSize = { string doc = """UsdGeomPrimvar - The number of values in the value array that must be aggregated for each element on the primitive.""" } dictionary unauthoredValuesIndex = { string doc = """UsdGeomPrimvar - The index that represents unauthored values in the indices array of an indexed primvar.""" } dictionary constant ={ string doc = """Possible value for UsdGeomPrimvar::SetInterpolation. Default value for UsdGeomPrimvar::GetInterpolation. One value remains constant over the entire surface primitive.""" } dictionary uniform = { string doc = """Possible value for UsdGeomPrimvar::SetInterpolation. One value remains constant for each uv patch segment of the surface primitive (which is a \\em face for meshes).""" } dictionary varying = { string doc = """Possible value for UsdGeomPrimvar::SetInterpolation. Four values are interpolated over each uv patch segment of the surface. Bilinear interpolation is used for interpolation between the four values.""" } dictionary vertex = { string doc = """Possible value for UsdGeomPrimvar::SetInterpolation. Values are interpolated between each vertex in the surface primitive. The basis function of the surface is used for interpolation between vertices.""" } dictionary faceVarying = { string doc = """Possible value for UsdGeomPrimvar::SetInterpolation. For polygons and subdivision surfaces, four values are interpolated over each face of the mesh. Bilinear interpolation is used for interpolation between the four values.""" } dictionary upAxis = { string doc = """Stage-level metadata that encodes a scene's orientation as a token whose value can be "Y" or "Z".""" } dictionary metersPerUnit = { string doc = """Stage-level metadata that encodes a scene's linear unit of measure as meters per encoded unit.""" } dictionary partition = { string doc = """A type of family of GeomSubsets. It implies that every element appears exacly once in only one of the subsets in the family.""" } dictionary nonOverlapping = { string doc = """A type of family of GeomSubsets. It implies that the elements in the various subsets belonging to the family are mutually exclusive, i.e., an element that appears in one subset may not belong to any other subset in the family.""" } dictionary unrestricted = { string doc = """A type of family of GeomSubsets. It implies that there are no restrictions w.r.t. the membership of elements in the subsets. There could be overlapping members in subsets belonging to the family and the union of all subsets in the family may not contain all the elements.""" } dictionary hermite = { string doc = """A deprecated basis token for UsdGeomBasisCurves. Consumers of USD should transition to using the UsdGeomHermiteCurves schema.""" } dictionary power = { string doc = """A deprecated basis token for UsdGeomBasisCurves.""" } } } ) { } class "Imageable" ( inherits = doc = """Base class for all prims that may require rendering or visualization of some sort. The primary attributes of Imageable are \\em visibility and \\em purpose, which each provide instructions for what geometry should be included for processing by rendering and other computations. \\deprecated Imageable also provides API for accessing primvars, which has been moved to the UsdGeomPrimvarsAPI schema, because primvars can now be applied on non-Imageable prim types. This API is planned to be removed, UsdGeomPrimvarsAPI should be used directly instead.""" customData = { string extraIncludes = """ #include "pxr/base/gf/bbox3d.h" #include "pxr/usd/usdGeom/primvar.h" """ } ) { token visibility = "inherited" ( allowedTokens = ["inherited", "invisible"] doc = """Visibility is meant to be the simplest form of "pruning" visibility that is supported by most DCC apps. Visibility is animatable, allowing a sub-tree of geometry to be present for some segment of a shot, and absent from others; unlike the action of deactivating geometry prims, invisible geometry is still available for inspection, for positioning, for defining volumes, etc.""" ) uniform token purpose = "default" ( allowedTokens = ["default", "render", "proxy", "guide"] doc = """Purpose is a classification of geometry into categories that can each be independently included or excluded from traversals of prims on a stage, such as rendering or bounding-box computation traversals. See \\ref UsdGeom_ImageablePurpose for more detail about how \\em purpose is computed and used.""" ) rel proxyPrim ( doc = """The \\em proxyPrim relationship allows us to link a prim whose \\em purpose is "render" to its (single target) purpose="proxy" prim. This is entirely optional, but can be useful in several scenarios: \\li In a pipeline that does pruning (for complexity management) by deactivating prims composed from asset references, when we deactivate a purpose="render" prim, we will be able to discover and additionally deactivate its associated purpose="proxy" prim, so that preview renders reflect the pruning accurately. \\li DCC importers may be able to make more aggressive optimizations for interactive processing and display if they can discover the proxy for a given render prim. \\li With a little more work, a Hydra-based application will be able to map a picked proxy prim back to its render geometry for selection. \\note It is only valid to author the proxyPrim relationship on prims whose purpose is "render".""" ) } class "PrimvarsAPI" ( inherits = doc = """UsdGeomPrimvarsAPI encodes geometric "primitive variables", as UsdGeomPrimvar, which interpolate across a primitive's topology, can override shader inputs, and inherit down namespace. \\section usdGeom_PrimvarFetchingAPI Which Method to Use to Retrieve Primvars While creating primvars is unambiguous (CreatePrimvar()), there are quite a few methods available for retrieving primvars, making it potentially confusing knowing which one to use. Here are some guidelines: \\li If you are populating a GUI with the primvars already available for authoring values on a prim, use GetPrimvars(). \\li If you want all of the "useful" (e.g. to a renderer) primvars available at a prim, including those inherited from ancestor prims, use FindPrimvarsWithInheritance(). Note that doing so individually for many prims will be inefficient. \\li To find a particular primvar defined directly on a prim, which may or may not provide a value, use GetPrimvar(). \\li To find a particular primvar defined on a prim or inherited from ancestors, which may or may not provide a value, use FindPrimvarWithInheritance(). \\li To *efficiently* query for primvars using the overloads of FindPrimvarWithInheritance() and FindPrimvarsWithInheritance(), one must first cache the results of FindIncrementallyInheritablePrimvars() for each non-leaf prim on the stage. """ customData = { token apiSchemaType = "nonApplied" string extraIncludes = """ #include "pxr/usd/usdGeom/primvar.h" """ } ) { } class "Xformable" ( inherits = customData = { string extraIncludes = """ #include "pxr/usd/usdGeom/xformOp.h" #include """ } doc = """Base class for all transformable prims, which allows arbitrary sequences of component affine transformations to be encoded. \\note You may find it useful to review \\ref UsdGeom_LinAlgBasics while reading this class description. Supported Component Transformation Operations UsdGeomXformable currently supports arbitrary sequences of the following operations, each of which can be encoded in an attribute of the proper shape in any supported precision: \\li translate - 3D \\li scale - 3D \\li rotateX - 1D angle in degrees \\li rotateY - 1D angle in degrees \\li rotateZ - 1D angle in degrees \\li rotateABC - 3D where ABC can be any combination of the six principle Euler Angle sets: XYZ, XZY, YXZ, YZX, ZXY, ZYX. See \\ref usdGeom_rotationPackingOrder "note on rotation packing order" \\li orient - 4D (quaternion) \\li transform - 4x4D Creating a Component Transformation To add components to a UsdGeomXformable prim, simply call AddXformOp() with the desired op type, as enumerated in \\ref UsdGeomXformOp::Type, and the desired precision, which is one of \\ref UsdGeomXformOp::Precision. Optionally, you can also provide an "op suffix" for the operator that disambiguates it from other components of the same type on the same prim. Application-specific transform schemas can use the suffixes to fill a role similar to that played by AbcGeom::XformOp's "Hint" enums for their own round-tripping logic. We also provide specific "Add" API for each type, for clarity and conciseness, e.g. AddTranslateOp(), AddRotateXYZOp() etc. AddXformOp() will return a UsdGeomXformOp object, which is a schema on a newly created UsdAttribute that provides convenience API for authoring and computing the component transformations. The UsdGeomXformOp can then be used to author any number of timesamples and default for the op. Each successive call to AddXformOp() adds an operator that will be applied "more locally" than the preceding operator, just as if we were pushing transforms onto a transformation stack - which is precisely what should happen when the operators are consumed by a reader. \\note If you can, please try to use the UsdGeomXformCommonAPI, which wraps the UsdGeomXformable with an interface in which Op creation is taken care of for you, and there is a much higher chance that the data you author will be importable without flattening into other DCC's, as it conforms to a fixed set of Scale-Rotate-Translate Ops. \\sa \\ref usdGeom_xformableExamples "Using the Authoring API" Data Encoding and Op Ordering Because there is no "fixed schema" of operations, all of the attributes that encode transform operations are dynamic, and are scoped in the namespace "xformOp". The second component of an attribute's name provides the \\em type of operation, as listed above. An "xformOp" attribute can have additional namespace components derived from the \\em opSuffix argument to the AddXformOp() suite of methods, which provides a preferred way of naming the ops such that we can have multiple "translate" ops with unique attribute names. For example, in the attribute named "xformOp:translate:maya:pivot", "translate" is the type of operation and "maya:pivot" is the suffix. The following ordered list of attribute declarations in usda define a basic Scale-Rotate-Translate with XYZ Euler angles, wherein the translation is double-precision, and the remainder of the ops are single, in which we will:
  1. Scale by 2.0 in each dimension
  2. Rotate about the X, Y, and Z axes by 30, 60, and 90 degrees, respectively
  3. Translate by 100 units in the Y direction
\\code float3 xformOp:rotateXYZ = (30, 60, 90) float3 xformOp:scale = (2, 2, 2) double3 xformOp:translate = (0, 100, 0) uniform token[] xformOpOrder = [ "xformOp:translate", "xformOp:rotateXYZ", "xformOp:scale" ] \\endcode The attributes appear in the dictionary order in which USD, by default, sorts them. To ensure the ops are recovered and evaluated in the correct order, the schema introduces the **xformOpOrder** attribute, which contains the names of the op attributes, in the precise sequence in which they should be pushed onto a transform stack. **Note** that the order is opposite to what you might expect, given the matrix algebra described in \\ref UsdGeom_LinAlgBasics. This also dictates order of op creation, since each call to AddXformOp() adds a new op to the end of the \\b xformOpOrder array, as a new "most-local" operation. See \\ref usdGeom_xformableExamples "Example 2 below" for C++ code that could have produced this USD. If it were important for the prim's rotations to be independently overridable, we could equivalently (at some performance cost) encode the transformation also like so: \\code float xformOp:rotateX = 30 float xformOp:rotateY = 60 float xformOp:rotateZ = 90 float3 xformOp:scale = (2, 2, 2) double3 xformOp:translate = (0, 100, 0) uniform token[] xformOpOrder = [ "xformOp:translate", "xformOp:rotateZ", "xformOp:rotateY", "xformOp:rotateX", "xformOp:scale" ] \\endcode Again, note that although we are encoding an XYZ rotation, the three rotations appear in the **xformOpOrder** in the opposite order, with Z, followed, by Y, followed by X. Were we to add a Maya-style scalePivot to the above example, it might look like the following: \\code float3 xformOp:rotateXYZ = (30, 60, 90) float3 xformOp:scale = (2, 2, 2) double3 xformOp:translate = (0, 100, 0) double3 xformOp:translate:scalePivot uniform token[] xformOpOrder = [ "xformOp:translate", "xformOp:rotateXYZ", "xformOp:translate:scalePivot", "xformOp:scale" ] \\endcode Paired "Inverted" Ops We have been claiming that the ordered list of ops serves as a set of instructions to a transform stack, but you may have noticed in the last example that there is a missing operation - the pivot for the scale op needs to be applied in its inverse-form as a final (most local) op! In the AbcGeom::Xform schema, we would have encoded an actual "final" translation op whose value was authored by the exporter as the negation of the pivot's value. However, doing so would be brittle in USD, given that each op can be independently overridden, and the constraint that one attribute must be maintained as the negation of the other in order for successful re-importation of the schema cannot be expressed in USD. Our solution leverages the **xformOpOrder** member of the schema, which, in addition to ordering the ops, may also contain one of two special tokens that address the paired op and "stack resetting" behavior. The "paired op" behavior is encoded as an "!invert!" prefix in \\b xformOpOrder, as the result of an AddXformOp(isInverseOp=True) call. The \\b xformOpOrder for the last example would look like: \\code uniform token[] xformOpOrder = [ "xformOp:translate", "xformOp:rotateXYZ", "xformOp:translate:scalePivot", "xformOp:scale", "!invert!xformOp:translate:scalePivot" ] \\endcode When asked for its value via UsdGeomXformOp::GetOpTransform(), an "inverted" Op (i.e. the "inverted" half of a set of paired Ops) will fetch the value of its paired attribute and return its negation. This works for all op types - an error will be issued if a "transform" type op is singular and cannot be inverted. When getting the authored value of an inverted op via UsdGeomXformOp::Get(), the raw, uninverted value of the associated attribute is returned. For the sake of robustness, setting a value on an inverted op is disallowed. Attempting to set a value on an inverted op will result in a coding error and no value being set. Resetting the Transform Stack The other special op/token that can appear in \\em xformOpOrder is \\em "!resetXformStack!", which, appearing as the first element of \\em xformOpOrder, indicates this prim should not inherit the transformation of its namespace parent. See SetResetXformStack() Expected Behavior for "Missing" Ops If an importer expects Scale-Rotate-Translate operations, but a prim has only translate and rotate ops authored, the importer should assume an identity scale. This allows us to optimize the data a bit, if only a few components of a very rich schema (like Maya's) are authored in the app. \\anchor usdGeom_xformableExamples Using the C++ API #1. Creating a simple transform matrix encoding \\snippet examples.cpp CreateMatrixWithDefault #2. Creating the simple SRT from the example above \\snippet examples.cpp CreateExampleSRT #3. Creating a parameterized SRT with pivot using UsdGeomXformCommonAPI \\snippet examples.cpp CreateSRTWithDefaults #4. Creating a rotate-only pivot transform with animated rotation and translation \\snippet examples.cpp CreateAnimatedTransform """ ) { uniform token[] xformOpOrder ( doc = """Encodes the sequence of transformation operations in the order in which they should be pushed onto a transform stack while visiting a UsdStage's prims in a graph traversal that will effect the desired positioning for this prim and its descendant prims. You should rarely, if ever, need to manipulate this attribute directly. It is managed by the AddXformOp(), SetResetXformStack(), and SetXformOpOrder(), and consulted by GetOrderedXformOps() and GetLocalTransformation().""" ) } class Scope "Scope" ( inherits = doc = """Scope is the simplest grouping primitive, and does not carry the baggage of transformability. Note that transforms should inherit down through a Scope successfully - it is just a guaranteed no-op from a transformability perspective.""" ) { } class Xform "Xform" ( inherits = doc = """Concrete prim schema for a transform, which implements Xformable """ ) { } class "Boundable" ( inherits = doc = """Boundable introduces the ability for a prim to persistently cache a rectilinear, local-space, extent. \\section UsdGeom_Boundable_Extent Why Extent and not Bounds ? Boundable introduces the notion of "extent", which is a cached computation of a prim's local-space 3D range for its resolved attributes at the layer and time in which extent is authored. We have found that with composed scene description, attempting to cache pre-computed bounds at interior prims in a scene graph is very fragile, given the ease with which one can author a single attribute in a stronger layer that can invalidate many authored caches - or with which a re-published, referenced asset can do the same. Therefore, we limit to precomputing (generally) leaf-prim extent, which avoids the need to read in large point arrays to compute bounds, and provides UsdGeomBBoxCache the means to efficiently compute and (session-only) cache intermediate bounds. You are free to compute and author intermediate bounds into your scenes, of course, which may work well if you have sufficient locks on your pipeline to guarantee that once authored, the geometry and transforms upon which they are based will remain unchanged, or if accuracy of the bounds is not an ironclad requisite. When intermediate bounds are authored on Boundable parents, the child prims will be pruned from BBox computation; the authored extent is expected to incorporate all child bounds.""" ) { # XXX: Note this is really a GfRange3f, which is not fully supported # in Vt I/O. float3[] extent ( doc = """Extent is a three dimensional range measuring the geometric extent of the authored gprim in its own local space (i.e. its own transform not applied), \\em without accounting for any shader-induced displacement. Whenever any geometry-affecting attribute is authored for any gprim in a layer, extent must also be authored at the same timesample; failure to do so will result in incorrect bounds-computation. \\sa \\ref UsdGeom_Boundable_Extent. An authored extent on a prim which has children is expected to include the extent of all children, as they will be pruned from BBox computation during traversal.""" ) } class "Gprim" ( inherits = doc = """Base class for all geometric primitives. Gprim encodes basic graphical properties such as \\em doubleSided and \\em orientation, and provides primvars for "display color" and "display opacity" that travel with geometry to be used as shader overrides. """ ) { color3f[] primvars:displayColor ( customData = { string apiName = "displayColor" } doc = """It is useful to have an "official" colorSet that can be used as a display or modeling color, even in the absence of any specified shader for a gprim. DisplayColor serves this role; because it is a UsdGeomPrimvar, it can also be used as a gprim override for any shader that consumes a \\em displayColor parameter.""" ) float[] primvars:displayOpacity ( customData = { string apiName = "displayOpacity" } doc = """Companion to \\em displayColor that specifies opacity, broken out as an independent attribute rather than an rgba color, both so that each can be independently overridden, and because shaders rarely consume rgba parameters.""" ) uniform bool doubleSided = false ( doc = """Although some renderers treat all parametric or polygonal surfaces as if they were effectively laminae with outward-facing normals on both sides, some renderers derive significant optimizations by considering these surfaces to have only a single outward side, typically determined by control-point winding order and/or \\em orientation. By doing so they can perform "backface culling" to avoid drawing the many polygons of most closed surfaces that face away from the viewer. However, it is often advantageous to model thin objects such as paper and cloth as single, open surfaces that must be viewable from both sides, always. Setting a gprim's \\em doubleSided attribute to \\c true instructs all renderers to disable optimizations such as backface culling for the gprim, and attempt (not all renderers are able to do so, but the USD reference GL renderer always will) to provide forward-facing normals on each side of the surface for lighting calculations.""" ) uniform token orientation = "rightHanded" ( allowedTokens = ["rightHanded", "leftHanded"] doc = """Orientation specifies whether the gprim's surface normal should be computed using the right hand rule, or the left hand rule. Please see \\ref UsdGeom_WindingOrder for a deeper explanation and generalization of orientation to composed scenes with transformation hierarchies.""" ) } class Cube "Cube" ( inherits = doc = """Defines a primitive rectilinear cube centered at the origin. The fallback values for Cube, Sphere, Cone, and Cylinder are set so that they all pack into the same volume/bounds.""" customData = { dictionary extraPlugInfo = { bool implementsComputeExtent = true } } ) { double size = 2.0 ( doc = """Indicates the length of each edge of the cube. If you author \\em size you must also author \\em extent. \\sa GetExtentAttr()""" ) float3[] extent = [(-1.0, -1.0, -1.0), (1.0, 1.0, 1.0)] ( doc = """Extent is re-defined on Cube only to provide a fallback value. \\sa UsdGeomGprim::GetExtentAttr().""" ) } class Sphere "Sphere" ( inherits = doc = """Defines a primitive sphere centered at the origin. The fallback values for Cube, Sphere, Cone, and Cylinder are set so that they all pack into the same volume/bounds.""" customData = { dictionary extraPlugInfo = { bool implementsComputeExtent = true } } ) { double radius = 1.0 ( doc = """Indicates the sphere's radius. If you author \\em radius you must also author \\em extent. \\sa GetExtentAttr()""" ) float3[] extent = [(-1.0, -1.0, -1.0), (1.0, 1.0, 1.0)] ( doc = """Extent is re-defined on Sphere only to provide a fallback value. \\sa UsdGeomGprim::GetExtentAttr().""" ) } class Cylinder "Cylinder" ( inherits = doc = """Defines a primitive cylinder with closed ends, centered at the origin, whose spine is along the specified \\em axis. The fallback values for Cube, Sphere, Cone, and Cylinder are set so that they all pack into the same volume/bounds.""" customData = { dictionary extraPlugInfo = { bool implementsComputeExtent = true } } ) { double height = 2 ( doc = """The size of the cylinder's spine along the specified \\em axis. If you author \\em height you must also author \\em extent. \\sa GetExtentAttr()""" ) double radius = 1.0 ( doc = """The radius of the cylinder. If you author \\em radius you must also author \\em extent. \\sa GetExtentAttr()""" ) uniform token axis = "Z" ( allowedTokens = ["X", "Y", "Z"] doc = """The axis along which the spine of the cylinder is aligned""" ) float3[] extent = [(-1.0, -1.0, -1.0), (1.0, 1.0, 1.0)] ( doc = """Extent is re-defined on Cylinder only to provide a fallback value. \\sa UsdGeomGprim::GetExtentAttr().""" ) } class Capsule "Capsule" ( inherits = doc = """Defines a primitive capsule, i.e. a cylinder capped by two half spheres, centered at the origin, whose spine is along the specified \\em axis.""" customData = { dictionary extraPlugInfo = { bool implementsComputeExtent = true } } ) { double height = 1.0 ( doc = """The size of the capsule's spine along the specified \\em axis excluding the size of the two half spheres, i.e. the size of the cylinder portion of the capsule. If you author \\em height you must also author \\em extent. \\sa GetExtentAttr()""" ) double radius = 0.5 ( doc = """The radius of the capsule. If you author \\em radius you must also author \\em extent. \\sa GetExtentAttr()""" ) uniform token axis = "Z" ( allowedTokens = ["X", "Y", "Z"] doc = """The axis along which the spine of the capsule is aligned""" ) float3[] extent = [(-0.5, -0.5, -1.0), (0.5, 0.5, 1.0)] ( doc = """Extent is re-defined on Capsule only to provide a fallback value. \\sa UsdGeomGprim::GetExtentAttr().""" ) } class Cone "Cone" ( inherits = doc = """Defines a primitive cone, centered at the origin, whose spine is along the specified \\em axis, with the apex of the cone pointing in the direction of the positive axis. The fallback values for Cube, Sphere, Cone, and Cylinder are set so that they all pack into the same volume/bounds.""" customData = { dictionary extraPlugInfo = { bool implementsComputeExtent = true } } ) { double height = 2.0 ( doc = """The size of the cone's spine along the specified \\em axis. If you author \\em height you must also author \\em extent. \\sa GetExtentAttr()""" ) double radius = 1.0 ( doc = """The radius of the cone. If you author \\em radius you must also author \\em extent. \\sa GetExtentAttr()""" ) uniform token axis = "Z" ( allowedTokens = ["X", "Y", "Z"] doc = """The axis along which the spine of the cone is aligned""" ) float3[] extent = [(-1.0, -1.0, -1.0), (1.0, 1.0, 1.0)] ( doc = """Extent is re-defined on Cone only to provide a fallback value. \\sa UsdGeomGprim::GetExtentAttr().""" ) } class "PointBased" ( doc = """Base class for all UsdGeomGprims that possess points, providing common attributes such as normals and velocities.""" inherits = customData = { dictionary extraPlugInfo = { bool implementsComputeExtent = true } } ) { # positional point3f[] points ( doc = """The primary geometry attribute for all PointBased primitives, describes points in (local) space.""" ) vector3f[] velocities ( doc = """If provided, 'velocities' should be used by renderers to compute positions between samples for the 'points' attribute, rather than interpolating between neighboring 'points' samples. This is the only reasonable means of computing motion blur for topologically varying PointBased primitives. It follows that the length of each 'velocities' sample must match the length of the corresponding 'points' sample. Velocity is measured in position units per second, as per most simulation software. To convert to position units per UsdTimeCode, divide by UsdStage::GetTimeCodesPerSecond(). See also \\ref UsdGeom_VelocityInterpolation .""" ) vector3f[] accelerations ( doc = """If provided, 'accelerations' should be used with velocities to compute positions between samples for the 'points' attribute rather than interpolating between neighboring 'points' samples. Acceleration is measured in position units per second-squared. To convert to position units per squared UsdTimeCode, divide by the square of UsdStage::GetTimeCodesPerSecond().""" ) # shaping normal3f[] normals ( doc = """Provide an object-space orientation for individual points, which, depending on subclass, may define a surface, curve, or free points. Note that 'normals' should not be authored on any Mesh that is subdivided, since the subdivision algorithm will define its own normals. 'normals' is not a generic primvar, but the number of elements in this attribute will be determined by its 'interpolation'. See \\ref SetNormalsInterpolation() . If 'normals' and 'primvars:normals' are both specified, the latter has precedence.""" ) } class Mesh "Mesh" ( inherits = customData = { string extraIncludes = """ #include "pxr/usd/usd/timeCode.h" """ } doc="""Encodes a mesh with optional subdivision properties and features. As a point-based primitive, meshes are defined in terms of points that are connected into edges and faces. Many references to meshes use the term 'vertex' in place of or interchangeably with 'points', while some use 'vertex' to refer to the 'face-vertices' that define a face. To avoid confusion, the term 'vertex' is intentionally avoided in favor of 'points' or 'face-vertices'. The connectivity between points, edges and faces is encoded using a common minimal topological description of the faces of the mesh. Each face is defined by a set of face-vertices using indices into the Mesh's _points_ array (inherited from UsdGeomPointBased) and laid out in a single linear _faceVertexIndices_ array for efficiency. A companion _faceVertexCounts_ array provides, for each face, the number of consecutive face-vertices in _faceVertexIndices_ that define the face. No additional connectivity information is required or constructed, so no adjacency or neighborhood queries are available. A key property of this mesh schema is that it encodes both subdivision surfaces and simpler polygonal meshes. This is achieved by varying the _subdivisionScheme_ attribute, which is set to specify Catmull-Clark subdivision by default, so polygonal meshes must always be explicitly declared. The available subdivision schemes and additional subdivision features encoded in optional attributes conform to the feature set of OpenSubdiv (https://graphics.pixar.com/opensubdiv/docs/subdivision_surfaces.html). \\anchor UsdGeom_Mesh_Primvars __A Note About Primvars__ The following list clarifies the number of elements for and the interpolation behavior of the different primvar interpolation types for meshes: - __constant__: One element for the entire mesh; no interpolation. - __uniform__: One element for each face of the mesh; elements are typically not interpolated but are inherited by other faces derived from a given face (via subdivision, tessellation, etc.). - __varying__: One element for each point of the mesh; interpolation of point data is always linear. - __vertex__: One element for each point of the mesh; interpolation of point data is applied according to the _subdivisionScheme_ attribute. - __faceVarying__: One element for each of the face-vertices that define the mesh topology; interpolation of face-vertex data may be smooth or linear, according to the _subdivisionScheme_ and _faceVaryingLinearInterpolation_ attributes. Primvar interpolation types and related utilities are described more generally in \\ref Usd_InterpolationVals. \\anchor UsdGeom_Mesh_Normals __A Note About Normals__ Normals should not be authored on a subdivision mesh, since subdivision algorithms define their own normals. They should only be authored for polygonal meshes (_subdivisionScheme_ = "none"). The _normals_ attribute inherited from UsdGeomPointBased is not a generic primvar, but the number of elements in this attribute will be determined by its _interpolation_. See \\ref UsdGeomPointBased::GetNormalsInterpolation() . If _normals_ and _primvars:normals_ are both specified, the latter has precedence. If a polygonal mesh specifies __neither__ _normals_ nor _primvars:normals_, then it should be treated and rendered as faceted, with no attempt to compute smooth normals. The normals generated for smooth subdivision schemes, e.g. Catmull-Clark and Loop, will likewise be smooth, but others, e.g. Bilinear, may be discontinuous between faces and/or within non-planar irregular faces.""" ) { # # Common Properties # int[] faceVertexIndices ( doc = """Flat list of the index (into the _points_ attribute) of each vertex of each face in the mesh. If this attribute has more than one timeSample, the mesh is considered to be topologically varying.""" ) int[] faceVertexCounts ( doc = """Provides the number of vertices in each face of the mesh, which is also the number of consecutive indices in _faceVertexIndices_ that define the face. The length of this attribute is the number of faces in the mesh. If this attribute has more than one timeSample, the mesh is considered to be topologically varying.""" ) # # Subdiv Properties # uniform token subdivisionScheme = "catmullClark" ( allowedTokens = ["catmullClark", "loop", "bilinear", "none"] doc = """The subdivision scheme to be applied to the surface. Valid values are: - __catmullClark__: The default, Catmull-Clark subdivision; preferred for quad-dominant meshes (generalizes B-splines); interpolation of point data is smooth (non-linear) - __loop__: Loop subdivision; preferred for purely triangular meshes; interpolation of point data is smooth (non-linear) - __bilinear__: Subdivision reduces all faces to quads (topologically similar to "catmullClark"); interpolation of point data is bilinear - __none__: No subdivision, i.e. a simple polygonal mesh; interpolation of point data is linear Polygonal meshes are typically lighter weight and faster to render, depending on renderer and render mode. Use of "bilinear" will produce a similar shape to a polygonal mesh and may offer additional guarantees of watertightness and additional subdivision features (e.g. holes) but may also not respect authored normals.""") token interpolateBoundary = "edgeAndCorner" ( allowedTokens = ["none", "edgeOnly", "edgeAndCorner"] doc = """Specifies how subdivision is applied for faces adjacent to boundary edges and boundary points. Valid values correspond to choices available in OpenSubdiv: - __none__: No boundary interpolation is applied and boundary faces are effectively treated as holes - __edgeOnly__: A sequence of boundary edges defines a smooth curve to which the edges of subdivided boundary faces converge - __edgeAndCorner__: The default, similar to "edgeOnly" but the smooth boundary curve is made sharp at corner points These are illustrated and described in more detail in the OpenSubdiv documentation: https://graphics.pixar.com/opensubdiv/docs/subdivision_surfaces.html#boundary-interpolation-rules""") token faceVaryingLinearInterpolation = "cornersPlus1" ( allowedTokens = ["none", "cornersOnly", "cornersPlus1", "cornersPlus2", "boundaries", "all"] doc = """Specifies how elements of a primvar of interpolation type "faceVarying" are interpolated for subdivision surfaces. Interpolation can be as smooth as a "vertex" primvar or constrained to be linear at features specified by several options. Valid values correspond to choices available in OpenSubdiv: - __none__: No linear constraints or sharpening, smooth everywhere - __cornersOnly__: Sharpen corners of discontinuous boundaries only, smooth everywhere else - __cornersPlus1__: The default, same as "cornersOnly" plus additional sharpening at points where three or more distinct face-varying values occur - __cornersPlus2__: Same as "cornersPlus1" plus additional sharpening at points with at least one discontinuous boundary corner or only one discontinuous boundary edge (a dart) - __boundaries__: Piecewise linear along discontinuous boundaries, smooth interior - __all__: Piecewise linear everywhere These are illustrated and described in more detail in the OpenSubdiv documentation: https://graphics.pixar.com/opensubdiv/docs/subdivision_surfaces.html#face-varying-interpolation-rules""") token triangleSubdivisionRule = "catmullClark" ( allowedTokens = ["catmullClark", "smooth"] doc = """Specifies an option to the subdivision rules for the Catmull-Clark scheme to try and improve undesirable artifacts when subdividing triangles. Valid values are "catmullClark" for the standard rules (the default) and "smooth" for the improvement. See https://graphics.pixar.com/opensubdiv/docs/subdivision_surfaces.html#triangle-subdivision-rule""") int[] holeIndices = [] ( doc = """The indices of all faces that should be treated as holes, i.e. made invisible. This is traditionally a feature of subdivision surfaces and not generally applied to polygonal meshes.""") int[] cornerIndices = [] ( doc = """The indices of points for which a corresponding sharpness value is specified in _cornerSharpnesses_ (so the size of this array must match that of _cornerSharpnesses_).""") float[] cornerSharpnesses = [] ( doc = """The sharpness values associated with a corresponding set of points specified in _cornerIndices_ (so the size of this array must match that of _cornerIndices_). Use the constant `SHARPNESS_INFINITE` for a perfectly sharp corner.""") int[] creaseIndices = [] ( doc = """The indices of points grouped into sets of successive pairs that identify edges to be creased. The size of this array must be equal to the sum of all elements of the _creaseLengths_ attribute.""") int[] creaseLengths = [] ( doc = """The length of this array specifies the number of creases (sets of adjacent sharpened edges) on the mesh. Each element gives the number of points of each crease, whose indices are successively laid out in the _creaseIndices_ attribute. Since each crease must be at least one edge long, each element of this array must be at least two.""") float[] creaseSharpnesses = [] ( doc = """The per-crease or per-edge sharpness values for all creases. Since _creaseLengths_ encodes the number of points in each crease, the number of elements in this array will be either len(creaseLengths) or the sum over all X of (creaseLengths[X] - 1). Note that while the RI spec allows each crease to have either a single sharpness or a value per-edge, USD will encode either a single sharpness per crease on a mesh, or sharpnesses for all edges making up the creases on a mesh. Use the constant `SHARPNESS_INFINITE` for a perfectly sharp crease.""") } class GeomSubset "GeomSubset" ( inherits = doc = """Encodes a subset of a piece of geometry (i.e. a UsdGeomImageable) as a set of indices. Currently only supports encoding of face-subsets, but could be extended in the future to support subsets representing edges, segments, points etc. To apply to a geometric prim, a GeomSubset prim must be defined as a child of it in namespace. This restriction makes it easy and efficient to discover subsets of a prim. We might want to relax this restriction if it's common to have multiple families of subsets on a gprim and if it's useful to be able to organize subsets belonging to a family under a common scope. See 'familyName' attribute for more info on defining a family of subsets. Note that a GeomSubset isn't an imageable (i.e. doesn't derive from UsdGeomImageable). So, you can't author visibility for it or override its purpose. Materials are bound to GeomSubsets just as they are for regular geometry using API available in UsdShade (UsdShadeMaterial::Bind). """ customData = { string className = "Subset" string extraIncludes = """ #include "pxr/base/tf/token.h" #include "pxr/usd/usdGeom/imageable.h" """ } ) { uniform token elementType = "face" ( allowedTokens = ["face"] doc = """The type of element that the indices target. Currently only allows "face" and defaults to it.""" ) int[] indices = [] ( doc = """The set of indices included in this subset. The indices need not be sorted, but the same index should not appear more than once.""" ) uniform token familyName = "" ( doc = """The name of the family of subsets that this subset belongs to. This is optional and is primarily useful when there are multiple families of subsets under a geometric prim. In some cases, this could also be used for achieving proper roundtripping of subset data between DCC apps. When multiple subsets belonging to a prim have the same familyName, they are said to belong to the family. A familyType value can be encoded on the owner of a family of subsets as a token using the static method UsdGeomSubset::SetFamilyType(). "familyType" can have one of the following values: \\note The validity of subset data is not enforced by the authoring APIs, however they can be checked using UsdGeomSubset::ValidateFamily(). """ ) } class NurbsPatch "NurbsPatch" ( inherits = doc = """Encodes a rational or polynomial non-uniform B-spline surface, with optional trim curves. The encoding mostly follows that of RiNuPatch and RiTrimCurve: https://renderman.pixar.com/resources/current/RenderMan/geometricPrimitives.html#rinupatch , with some minor renaming and coalescing for clarity. The layout of control vertices in the \\em points attribute inherited from UsdGeomPointBased is row-major with U considered rows, and V columns. \\anchor UsdGeom_NurbsPatch_Form NurbsPatch Form The authored points, orders, knots, weights, and ranges are all that is required to render the nurbs patch. However, the only way to model closed surfaces with nurbs is to ensure that the first and last control points along the given axis are coincident. Similarly, to ensure the surface is not only closed but also C2 continuous, the last \\em order - 1 control points must be (correspondingly) coincident with the first \\em order - 1 control points, and also the spacing of the last corresponding knots must be the same as the first corresponding knots. Form is provided as an aid to interchange between modeling and animation applications so that they can robustly identify the intent with which the surface was modelled, and take measures (if they are able) to preserve the continuity/concidence constraints as the surface may be rigged or deformed. \\li An \\em open-form NurbsPatch has no continuity constraints. \\li A \\em closed-form NurbsPatch expects the first and last control points to overlap \\li A \\em periodic-form NurbsPatch expects the first and last \\em order - 1 control points to overlap. Nurbs vs Subdivision Surfaces Nurbs are an important modeling primitive in CAD/CAM tools and early computer graphics DCC's. Because they have a natural UV parameterization they easily support "trim curves", which allow smooth shapes to be carved out of the surface. However, the topology of the patch is always rectangular, and joining two nurbs patches together (especially when they have differing numbers of spans) is difficult to do smoothly. Also, nurbs are not supported by the Ptex texturing technology (http://ptex.us). Neither of these limitations are shared by subdivision surfaces; therefore, although they do not subscribe to trim-curve-based shaping, subdivs are often considered a more flexible modeling primitive. """ ) { int uVertexCount ( doc = """Number of vertices in the U direction. Should be at least as large as uOrder.""" ) int vVertexCount ( doc = """Number of vertices in the V direction. Should be at least as large as vOrder.""" ) int uOrder ( doc = """Order in the U direction. Order must be positive and is equal to the degree of the polynomial basis to be evaluated, plus 1.""" ) int vOrder ( doc = """Order in the V direction. Order must be positive and is equal to the degree of the polynomial basis to be evaluated, plus 1.""" ) double[] uKnots ( doc = """Knot vector for U direction providing U parameterization. The length of this array must be ( uVertexCount + uOrder ), and its entries must take on monotonically increasing values.""" ) double[] vKnots ( doc = """Knot vector for V direction providing U parameterization. The length of this array must be ( vVertexCount + vOrder ), and its entries must take on monotonically increasing values.""" ) uniform token uForm = "open" ( allowedTokens = ["open", "closed", "periodic"] doc = """Interpret the control grid and knot vectors as representing an open, geometrically closed, or geometrically closed and C2 continuous surface along the U dimension. \\sa \\ref UsdGeom_NurbsPatch_Form "NurbsPatch Form" """ ) uniform token vForm = "open" ( allowedTokens = ["open", "closed", "periodic"] doc = """Interpret the control grid and knot vectors as representing an open, geometrically closed, or geometrically closed and C2 continuous surface along the V dimension. \\sa \\ref UsdGeom_NurbsPatch_Form "NurbsPatch Form" """ ) # Alembic's NuPatch does not encode these... wonder how they # get away with that? Just assume it's the full range, presumably. double2 uRange ( doc = """Provides the minimum and maximum parametric values (as defined by uKnots) over which the surface is actually defined. The minimum must be less than the maximum, and greater than or equal to the value of uKnots[uOrder-1]. The maxium must be less than or equal to the last element's value in uKnots.""" ) double2 vRange ( doc = """Provides the minimum and maximum parametric values (as defined by vKnots) over which the surface is actually defined. The minimum must be less than the maximum, and greater than or equal to the value of vKnots[vOrder-1]. The maxium must be less than or equal to the last element's value in vKnots.""" ) double[] pointWeights ( doc = """Optionally provides "w" components for each control point, thus must be the same length as the points attribute. If authored, the patch will be rational. If unauthored, the patch will be polynomial, i.e. weight for all points is 1.0. \\note Some DCC's pre-weight the \\em points, but in this schema, \\em points are not pre-weighted.""" ) int[] trimCurve:counts ( doc = """Each element specifies how many curves are present in each "loop" of the trimCurve, and the length of the array determines how many loops the trimCurve contains. The sum of all elements is the total nuber of curves in the trim, to which we will refer as \\em nCurves in describing the other trim attributes.""" ) int[] trimCurve:orders ( doc = """Flat list of orders for each of the \\em nCurves curves.""" ) int[] trimCurve:vertexCounts ( doc = """Flat list of number of vertices for each of the \\em nCurves curves.""" ) double[] trimCurve:knots ( doc = """Flat list of parametric values for each of the \\em nCurves curves. There will be as many knots as the sum over all elements of \\em vertexCounts plus the sum over all elements of \\em orders.""" ) double2[] trimCurve:ranges ( doc = """Flat list of minimum and maximum parametric values (as defined by \\em knots) for each of the \\em nCurves curves.""" ) double3[] trimCurve:points ( doc = """Flat list of homogeneous 2D points (u, v, w) that comprise the \\em nCurves curves. The number of points should be equal to the um over all elements of \\em vertexCounts.""" ) } class "Curves" ( customData = { dictionary extraPlugInfo = { bool implementsComputeExtent = true } } inherits = doc = """Base class for UsdGeomBasisCurves, UsdGeomNurbsCurves, and UsdGeomHermiteCurves. The BasisCurves schema is designed to be analagous to offline renderers' notion of batched curves (such as the classical RIB definition via Basis and Curves statements), while the NurbsCurve schema is designed to be analgous to the NURBS curves found in packages like Maya and Houdini while retaining their consistency with the RenderMan specification for NURBS Patches. HermiteCurves are useful for the interchange of animation guides and paths. """ ) { # topology attributes int[] curveVertexCounts ( doc = """Curves-derived primitives can represent multiple distinct, potentially disconnected curves. The length of 'curveVertexCounts' gives the number of such curves, and each element describes the number of vertices in the corresponding curve""" ) # shaping attributes float[] widths ( doc = """Provides width specification for the curves, whose application will depend on whether the curve is oriented (normals are defined for it), in which case widths are "ribbon width", or unoriented, in which case widths are cylinder width. 'widths' is not a generic Primvar, but the number of elements in this attribute will be determined by its 'interpolation'. See \\ref SetWidthsInterpolation() . If 'widths' and 'primvars:widths' are both specified, the latter has precedence.""" ) } class BasisCurves "BasisCurves" ( inherits = doc = """BasisCurves are a batched curve representation analogous to the classic RIB definition via Basis and Curves statements. BasisCurves are often used to render dense aggregate geometry like hair or grass. A 'matrix' and 'vstep' associated with the \\em basis are used to interpolate the vertices of a cubic BasisCurves. (The basis attribute is unused for linear BasisCurves.) A single prim may have many curves whose count is determined implicitly by the length of the \\em curveVertexCounts vector. Each individual curve is composed of one or more segments. Each segment is defined by four vertices for cubic curves and two vertices for linear curves. See the next section for more information on how to map curve vertex counts to segment counts. \\section UsdGeomBasisCurves_Segment Segment Indexing Interpolating a curve requires knowing how to decompose it into its individual segments. The segments of a cubic curve are determined by the vertex count, the \\em wrap (periodicity), and the vstep of the basis. For linear curves, the basis token is ignored and only the vertex count and wrap are needed. cubic basis | vstep ------------- | ------ bezier | 3 catmullRom | 1 bspline | 1 The first segment of a cubic (nonperiodic) curve is always defined by its first four points. The vstep is the increment used to determine what vertex indices define the next segment. For a two segment (nonperiodic) bspline basis curve (vstep = 1), the first segment will be defined by interpolating vertices [0, 1, 2, 3] and the second segment will be defined by [1, 2, 3, 4]. For a two segment bezier basis curve (vstep = 3), the first segment will be defined by interpolating vertices [0, 1, 2, 3] and the second segment will be defined by [3, 4, 5, 6]. If the vstep is not one, then you must take special care to make sure that the number of cvs properly divides by your vstep. (The indices described are relative to the initial vertex index for a batched curve.) For periodic curves, at least one of the curve's initial vertices are repeated to close the curve. For cubic curves, the number of vertices repeated is '4 - vstep'. For linear curves, only one vertex is repeated to close the loop. Pinned curves are a special case of nonperiodic curves that only affects the behavior of cubic Bspline and Catmull-Rom curves. To evaluate or render pinned curves, a client must effectively add 'phantom points' at the beginning and end of every curve in a batch. These phantom points are injected to ensure that the inteprolated curve begins at P[0] and ends at P[n-1]. For a curve with initial point P[0] and last point P[n-1], the phantom points are defined as. P[-1] = 2 * P[0] - P[1] P[n] = 2 * P[n-1] - P[n-2] Pinned cubic curves will (usually) have to be unpacked into the standard nonperiodic representation before rendering. This unpacking can add some additional overhead. However, using pinned curves reduces the amount of data recorded in a scene and (more importantly) better records the authors' intent for interchange. \\note The additional phantom points mean that the minimum curve vertex count for cubic bspline and catmullRom curves is 2. Linear curve segments are defined by two vertices. A two segment linear curve's first segment would be defined by interpolating vertices [0, 1]. The second segment would be defined by vertices [1, 2]. (Again, for a batched curve, indices are relative to the initial vertex index.) When validating curve topology, each renderable entry in the curveVertexCounts vector must pass this check. type | wrap | validitity ------- | --------------------------- | ---------------- linear | nonperiodic | curveVertexCounts[i] > 2 linear | periodic | curveVertexCounts[i] > 3 cubic | nonperiodic | (curveVertexCounts[i] - 4) % vstep == 0 cubic | periodic | (curveVertexCounts[i]) % vstep == 0 cubic | pinned (catmullRom/bspline) | (curveVertexCounts[i] - 2) >= 0 \\section UsdGeomBasisCurves_BasisMatrix Cubic Vertex Interpolation \\image html USDCurveBasisMatrix.png width=750 \\section UsdGeomBasisCurves_Linear Linear Vertex Interpolation Linear interpolation is always used on curves of type linear. 't' with domain [0, 1], the curve is defined by the equation P0 * (1-t) + P1 * t. t at 0 describes the first point and t at 1 describes the end point. \\section UsdGeomBasisCurves_PrimvarInterpolation Primvar Interpolation For cubic curves, primvar data can be either interpolated cubically between vertices or linearly across segments. The corresponding token for cubic interpolation is 'vertex' and for linear interpolation is 'varying'. Per vertex data should be the same size as the number of vertices in your curve. Segment varying data is dependent on the wrap (periodicity) and number of segments in your curve. For linear curves, varying and vertex data would be interpolated the same way. By convention varying is the preferred interpolation because of the association of varying with linear interpolation. \\image html USDCurvePrimvars.png To convert an entry in the curveVertexCounts vector into a segment count for an individual curve, apply these rules. Sum up all the results in order to compute how many total segments all curves have. The following tables describe the expected segment count for the 'i'th curve in a curve batch as well as the entire batch. Python syntax like '[:]' (to describe all members of an array) and 'len(...)' (to describe the length of an array) are used. type | wrap | curve segment count | batch segment count ------- | --------------------------- | -------------------------------------- | -------------------------- linear | nonperiodic | curveVertexCounts[i] - 1 | sum(curveVertexCounts[:]) - len(curveVertexCounts) linear | periodic | curveVertexCounts[i] | sum(curveVertexCounts[:]) cubic | nonperiodic | (curveVertexCounts[i] - 4) / vstep + 1 | sum(curveVertexCounts[:] - 4) / vstep + len(curveVertexCounts) cubic | periodic | curveVertexCounts[i] / vstep | sum(curveVertexCounts[:]) / vstep cubic | pinned (catmullRom/bspline) | (curveVertexCounts[i] - 2) + 1 | sum(curveVertexCounts[:] - 2) + len(curveVertexCounts) The following table descrives the expected size of varying (linearly interpolated) data, derived from the segment counts computed above. wrap | curve varying count | batch varying count ------------------- | ---------------------------- | ------------------------------------------------ nonperiodic/pinned | segmentCounts[i] + 1 | sum(segmentCounts[:]) + len(curveVertexCounts) periodic | segmentCounts[i] | sum(segmentCounts[:]) Both curve types additionally define 'constant' interpolation for the entire prim and 'uniform' interpolation as per curve data. \\note Take care when providing support for linearly interpolated data for cubic curves. Its shape doesn't provide a one to one mapping with either the number of curves (like 'uniform') or the number of vertices (like 'vertex') and so it is often overlooked. This is the only primitive in UsdGeom (as of this writing) where this is true. For meshes, while they use different interpolation methods, 'varying' and 'vertex' are both specified per point. It's common to assume that curves follow a similar pattern and build in structures and language for per primitive, per element, and per point data only to come upon these arrays that don't quite fit into either of those categories. It is also common to conflate 'varying' with being per segment data and use the segmentCount rules table instead of its neighboring varying data table rules. We suspect that this is because for the common case of nonperiodic cubic curves, both the provided segment count and varying data size formula end with '+ 1'. While debugging, users may look at the double '+ 1' as a mistake and try to remove it. We take this time to enumerate these issues because we've fallen into them before and hope that we save others time in their own implementations. As an example of deriving per curve segment and varying primvar data counts from the wrap, type, basis, and curveVertexCount, the following table is provided. wrap | type | basis | curveVertexCount | curveSegmentCount | varyingDataCount ------------- | ------- | ------- | ----------------- | ------------------ | ------------------------- nonperiodic | linear | N/A | [2 3 2 5] | [1 2 1 4] | [2 3 2 5] nonperiodic | cubic | bezier | [4 7 10 4 7] | [1 2 3 1 2] | [2 3 4 2 3] nonperiodic | cubic | bspline | [5 4 6 7] | [2 1 3 4] | [3 2 4 5] periodic | cubic | bezier | [6 9 6] | [2 3 2] | [2 3 2] periodic | linear | N/A | [3 7] | [3 7] | [3 7] \\section UsdGeomBasisCurves_TubesAndRibbons Tubes and Ribbons The strictest definition of a curve as an infinitely thin wire is not particularly useful for describing production scenes. The additional \\em widths and \\em normals attributes can be used to describe cylindrical tubes and or flat oriented ribbons. Curves with only widths defined are imaged as tubes with radius 'width / 2'. Curves with both widths and normals are imaged as ribbons oriented in the direction of the interpolated normal vectors. While not technically UsdGeomPrimvars, widths and normals also have interpolation metadata. It's common for authored widths to have constant, varying, or vertex interpolation (see UsdGeomCurves::GetWidthsInterpolation()). It's common for authored normals to have varying interpolation (see UsdGeomPointBased::GetNormalsInterpolation()). \\image html USDCurveHydra.png The file used to generate these curves can be found in pxr/extras/examples/usdGeomExamples/basisCurves.usda. It's provided as a reference on how to properly image both tubes and ribbons. The first row of curves are linear; the second are cubic bezier. (We aim in future releases of HdSt to fix the discontinuity seen with broken tangents to better match offline renderers like RenderMan.) The yellow and violet cubic curves represent cubic vertex width interpolation for which there is no equivalent for linear curves. \\note How did this prim type get its name? This prim is a portmanteau of two different statements in the original RenderMan specification: 'Basis' and 'Curves'. """ ) { # interpolation attributes uniform token type = "cubic" ( allowedTokens = ["linear", "cubic"] doc = """Linear curves interpolate linearly between two vertices. Cubic curves use a basis matrix with four vertices to interpolate a segment.""") uniform token basis = "bezier" ( allowedTokens = ["bezier", "bspline", "catmullRom"] doc = """The basis specifies the vstep and matrix used for cubic interpolation. \\note The 'hermite' and 'power' tokens have been removed. We've provided UsdGeomHermiteCurves as an alternative for the 'hermite' basis.""") uniform token wrap = "nonperiodic" ( allowedTokens = ["nonperiodic", "periodic", "pinned"] doc = """If wrap is set to periodic, the curve when rendered will repeat the initial vertices (dependent on the vstep) to close the curve. If wrap is set to 'pinned', phantom points may be created to ensure that the curve interpolation starts at P[0] and ends at P[n-1]. """) } class NurbsCurves "NurbsCurves" ( inherits = doc = """This schema is analagous to NURBS Curves in packages like Maya and Houdini, often used for interchange of rigging and modeling curves. Unlike Maya, this curve spec supports batching of multiple curves into a single prim, widths, and normals in the schema. Additionally, we require 'numSegments + 2 * degree + 1' knots (2 more than maya does). This is to be more consistent with RenderMan's NURBS patch specification. To express a periodic curve: - knot[0] = knot[1] - (knots[-2] - knots[-3]; - knot[-1] = knot[-2] + (knot[2] - knots[1]); To express a nonperiodic curve: - knot[0] = knot[1]; - knot[-1] = knot[-2]; In spite of these slight differences in the spec, curves generated in Maya should be preserved when roundtripping. \\em order and \\em range, when representing a batched NurbsCurve should be authored one value per curve. \\em knots should be the concatentation of all batched curves.""" ) { # topology attributes int[] order = [] ( doc = """Order of the curve. Order must be positive and is equal to the degree of the polynomial basis to be evaluated, plus 1. Its value for the 'i'th curve must be less than or equal to curveVertexCount[i]""") # interpolation attributes double[] knots ( doc = """Knot vector providing curve parameterization. The length of the slice of the array for the ith curve must be ( curveVertexCount[i] + order[i] ), and its entries must take on monotonically increasing values.""") double2[] ranges ( doc = """Provides the minimum and maximum parametric values (as defined by knots) over which the curve is actually defined. The minimum must be less than the maximum, and greater than or equal to the value of the knots['i'th curve slice][order[i]-1]. The maxium must be less than or equal to the last element's value in knots['i'th curve slice]. Range maps to (vmin, vmax) in the RenderMan spec.""") } class Points "Points" ( customData = { dictionary extraPlugInfo = { bool implementsComputeExtent = true } } inherits = doc = """Points are analogous to the RiPoints spec. Points can be an efficient means of storing and rendering particle effects comprised of thousands or millions of small particles. Points generally receive a single shading sample each, which should take \\em normals into account, if present. While not technically UsdGeomPrimvars, the widths and normals also have interpolation metadata. It's common for authored widths and normals to have constant or varying interpolation.""" ) { # shaping attributes float[] widths ( doc = """Widths are defined as the \\em diameter of the points, in object space. 'widths' is not a generic Primvar, but the number of elements in this attribute will be determined by its 'interpolation'. See \\ref SetWidthsInterpolation() . If 'widths' and 'primvars:widths' are both specified, the latter has precedence.""" ) int64[] ids ( doc = """Ids are optional; if authored, the ids array should be the same length as the points array, specifying (at each timesample if point identities are changing) the id of each point. The type is signed intentionally, so that clients can encode some binary state on Id'd points without adding a separate primvar.""" ) } class PointInstancer "PointInstancer" ( doc = """Encodes vectorized instancing of multiple, potentially animated, prototypes (object/instance masters), which can be arbitrary prims/subtrees on a UsdStage. PointInstancer is a "multi instancer", as it allows multiple prototypes to be scattered among its "points". We use a UsdRelationship \\em prototypes to identify and order all of the possible prototypes, by targeting the root prim of each prototype. The ordering imparted by relationships associates a zero-based integer with each prototype, and it is these integers we use to identify the prototype of each instance, compactly, and allowing prototypes to be swapped out without needing to reauthor all of the per-instance data. The PointInstancer schema is designed to scale to billions of instances, which motivates the choice to split the per-instance transformation into position, (quaternion) orientation, and scales, rather than a 4x4 matrix per-instance. In addition to requiring fewer bytes even if all elements are authored (32 bytes vs 64 for a single-precision 4x4 matrix), we can also be selective about which attributes need to animate over time, for substantial data reduction in many cases. Note that PointInstancer is \\em not a Gprim, since it is not a graphical primitive by any stretch of the imagination. It \\em is, however, Boundable, since we will sometimes want to treat the entire PointInstancer similarly to a procedural, from the perspective of inclusion or framing. \\section UsdGeomPointInstancer_varyingTopo Varying Instance Identity over Time PointInstancers originating from simulations often have the characteristic that points/instances are "born", move around for some time period, and then die (or leave the area of interest). In such cases, billions of instances may be birthed over time, while at any \\em specific time, only a much smaller number are actually alive. To encode this situation efficiently, the simulator may re-use indices in the instance arrays, when a particle dies, its index will be taken over by a new particle that may be birthed in a much different location. This presents challenges both for identity-tracking, and for motion-blur. We facilitate identity tracking by providing an optional, animatable \\em ids attribute, that specifies the 64 bit integer ID of the particle at each index, at each point in time. If the simulator keeps monotonically increasing a particle-count each time a new particle is birthed, it will serve perfectly as particle \\em ids. We facilitate motion blur for varying-topology particle streams by optionally allowing per-instance \\em velocities and \\em angularVelocities to be authored. If instance transforms are requested at a time between samples and either of the velocity attributes is authored, then we will not attempt to interpolate samples of \\em positions or \\em orientations. If not authored, and the bracketing samples have the same length, then we will interpolate. \\section UsdGeomPointInstancer_transform Computing an Instance Transform Each instance's transformation is a combination of the SRT affine transform described by its scale, orientation, and position, applied \\em after (i.e. less locally) than the transformation computed at the root of the prototype it is instancing. In other words, to put an instance of a PointInstancer into the space of the PointInstancer's parent prim: 1. Apply (most locally) the authored transformation for prototypes[protoIndices[i]] 2. If *scales* is authored, next apply the scaling matrix from *scales[i]* 3. If *orientations* is authored: **if *angularVelocities* is authored**, first multiply *orientations[i]* by the unit quaternion derived by scaling *angularVelocities[i]* by the \\ref UsdGeom_PITimeScaling "time differential" from the left-bracketing timeSample for *orientation* to the requested evaluation time *t*, storing the result in *R*, **else** assign *R* directly from *orientations[i]*. Apply the rotation matrix derived from *R*. 4. Apply the translation derived from *positions[i]*. If *velocities* is authored, apply the translation deriving from *velocities[i]* scaled by the time differential from the left-bracketing timeSample for *positions* to the requested evaluation time *t*. 5. Least locally, apply the transformation authored on the PointInstancer prim itself (or the UsdGeomImageable::ComputeLocalToWorldTransform() of the PointInstancer to put the instance directly into world space) If neither *velocities* nor *angularVelocities* are authored, we fallback to standard position and orientation computation logic (using linear interpolation between timeSamples) as described by \\ref UsdGeom_VelocityInterpolation . \\anchor UsdGeom_PITimeScaling Scaling Velocities for Interpolation When computing time-differentials by which to apply velocity or angularVelocity to positions or orientations, we must scale by ( 1.0 / UsdStage::GetTimeCodesPerSecond() ), because velocities are recorded in units/second, while we are interpolating in UsdTimeCode ordinates. Additionally, if *motion:velocityScale* is authored or inherited (see UsdGeomMotionAPI::ComputeVelocityScale()), it is used to scale both the velocity and angular velocity by a constant value during computation. The *motion:velocityScale* attribute is encoded by UsdGeomMotionAPI. We provide both high and low-level API's for dealing with the transformation as a matrix, both will compute the instance matrices using multiple threads; the low-level API allows the client to cache unvarying inputs so that they need not be read duplicately when computing over time. See also \\ref UsdGeom_VelocityInterpolation . \\section UsdGeomPointInstancer_primvars Primvars on PointInstancer \\ref UsdGeomPrimvar "Primvars" authored on a PointInstancer prim should always be applied to each instance with \\em constant interpolation at the root of the instance. When you are authoring primvars on a PointInstancer, think about it as if you were authoring them on a point-cloud (e.g. a UsdGeomPoints gprim). The same interpolation rules for points apply here, substituting "instance" for "point". In other words, the (constant) value extracted for each instance from the authored primvar value depends on the authored \\em interpolation and \\em elementSize of the primvar, as follows: \\li constant or uniform : the entire authored value of the primvar should be applied exactly to each instance. \\li varying, vertex, or faceVarying: the first \\em elementSize elements of the authored primvar array should be assigned to instance zero, the second \\em elementSize elements should be assigned to instance one, and so forth. \\section UsdGeomPointInstancer_masking Masking Instances: "Deactivating" and Invising Often a PointInstancer is created "upstream" in a graphics pipeline, and the needs of "downstream" clients necessitate eliminating some of the instances from further consideration. Accomplishing this pruning by re-authoring all of the per-instance attributes is not very attractive, since it may mean destructively editing a large quantity of data. We therefore provide means of "masking" instances by ID, such that the instance data is unmolested, but per-instance transform and primvar data can be retrieved with the no-longer-desired instances eliminated from the (smaller) arrays. PointInstancer allows two independent means of masking instances by ID, each with different features that meet the needs of various clients in a pipeline. Both pruning features' lists of ID's are combined to produce the mask returned by ComputeMaskAtTime(). \\note If a PointInstancer has no authored \\em ids attribute, the masking features will still be available, with the integers specifying element position in the \\em protoIndices array rather than ID. \\subsection UsdGeomPointInstancer_inactiveIds InactiveIds: List-edited, Unvarying Masking The first masking feature encodes a list of IDs in a list-editable metadatum called \\em inactiveIds, which, although it does not have any similar impact to stage population as \\ref UsdPrim::SetActive() "prim activation", it shares with that feature that its application is uniform over all time. Because it is list-editable, we can \\em sparsely add and remove instances from it in many layers. This sparse application pattern makes \\em inactiveIds a good choice when further downstream clients may need to reverse masking decisions made upstream, in a manner that is robust to many kinds of future changes to the upstream data. See ActivateId(), ActivateIds(), DeactivateId(), DeactivateIds(), ActivateAllIds() \\subsection UsdGeomPointInstancer_invisibleIds invisibleIds: Animatable Masking The second masking feature encodes a list of IDs in a time-varying Int64Array-valued UsdAttribute called \\em invisibleIds , since it shares with \\ref UsdGeomImageable::GetVisibilityAttr() "Imageable visibility" the ability to animate object visibility. Unlike \\em inactiveIds, overriding a set of opinions for \\em invisibleIds is not at all straightforward, because one will, in general need to reauthor (in the overriding layer) **all** timeSamples for the attribute just to change one Id's visibility state, so it cannot be authored sparsely. But it can be a very useful tool for situations like encoding pre-computed camera-frustum culling of geometry when either or both of the instances or the camera is animated. See VisId(), VisIds(), InvisId(), InvisIds(), VisAllIds() \\section UsdGeomPointInstancer_protoProcessing Processing and Not Processing Prototypes Any prim in the scenegraph can be targetted as a prototype by the \\em prototypes relationship. We do not, however, provide a specific mechanism for identifying prototypes as geometry that should not be drawn (or processed) in their own, local spaces in the scenegraph. We encourage organizing all prototypes as children of the PointInstancer prim that consumes them, and pruning "raw" processing and drawing traversals when they encounter a PointInstancer prim; this is what the UsdGeomBBoxCache and UsdImaging engines do. There \\em is a pattern one can deploy for organizing the prototypes such that they will automatically be skipped by basic UsdPrim::GetChildren() or UsdPrimRange traversals. Usd prims each have a \\ref Usd_PrimSpecifiers "specifier" of "def", "over", or "class". The default traversals skip over prims that are "pure overs" or classes. So to protect prototypes from all generic traversals and processing, place them under a prim that is just an "over". For example, \\code 01 def PointInstancer "Crowd_Mid" 02 { 03 rel prototypes = [ , ] 04 05 over "Prototypes" 06 { 07 def "MaleThin_Business" ( 08 references = [@MaleGroupA/usd/MaleGroupA.usd@] 09 variants = { 10 string modelingVariant = "Thin" 11 string costumeVariant = "BusinessAttire" 12 } 13 ) 14 { ... } 15 16 def "MaleThin_Casual" 17 ... 18 } 19 } \\endcode """ inherits = customData = { dictionary extraPlugInfo = { bool implementsComputeExtent = true } dictionary schemaTokens = { dictionary inactiveIds = { string doc = """int64listop prim metadata that specifies the PointInstancer ids that should be masked (unrenderable) over all time.""" } } } ) { rel prototypes ( doc = """Required property. Orders and targets the prototype root prims, which can be located anywhere in the scenegraph that is convenient, although we promote organizing prototypes as children of the PointInstancer. The position of a prototype in this relationship defines the value an instance would specify in the \\em protoIndices attribute to instance that prototype. Since relationships are uniform, this property cannot be animated.""" ) int[] protoIndices ( doc = """Required property. Per-instance index into \\em prototypes relationship that identifies what geometry should be drawn for each instance. Topology attribute - can be animated, but at a potential performance impact for streaming.""" ) int64[] ids ( doc = """Ids are optional; if authored, the ids array should be the same length as the \\em protoIndices array, specifying (at each timeSample if instance identities are changing) the id of each instance. The type is signed intentionally, so that clients can encode some binary state on Id'd instances without adding a separate primvar. See also \\ref UsdGeomPointInstancer_varyingTopo""" ) point3f[] positions ( doc = """Required property. Per-instance position. See also \\ref UsdGeomPointInstancer_transform .""" ) quath[] orientations ( doc="""If authored, per-instance orientation of each instance about its prototype's origin, represented as a unit length quaternion, which allows us to encode it with sufficient precision in a compact GfQuath. It is client's responsibility to ensure that authored quaternions are unit length; the convenience API below for authoring orientations from rotation matrices will ensure that quaternions are unit length, though it will not make any attempt to select the "better (for interpolation with respect to neighboring samples)" of the two possible quaternions that encode the rotation. See also \\ref UsdGeomPointInstancer_transform .""" ) float3[] scales ( doc="""If authored, per-instance scale to be applied to each instance, before any rotation is applied. See also \\ref UsdGeomPointInstancer_transform .""" ) vector3f[] velocities ( doc = """If provided, per-instance 'velocities' will be used to compute positions between samples for the 'positions' attribute, rather than interpolating between neighboring 'positions' samples. Velocities should be considered mandatory if both \\em protoIndices and \\em positions are animated. Velocity is measured in position units per second, as per most simulation software. To convert to position units per UsdTimeCode, divide by UsdStage::GetTimeCodesPerSecond(). See also \\ref UsdGeomPointInstancer_transform, \\ref UsdGeom_VelocityInterpolation .""" ) vector3f[] accelerations ( doc = """If authored, per-instance 'accelerations' will be used with velocities to compute positions between samples for the 'positions' attribute rather than interpolating between neighboring 'positions' samples. Acceleration is measured in position units per second-squared. To convert to position units per squared UsdTimeCode, divide by the square of UsdStage::GetTimeCodesPerSecond().""" ) vector3f[] angularVelocities ( doc="""If authored, per-instance angular velocity vector to be used for interoplating orientations. Angular velocities should be considered mandatory if both \\em protoIndices and \\em orientations are animated. Angular velocity is measured in degrees per second. To convert to degrees per UsdTimeCode, divide by UsdStage::GetTimeCodesPerSecond(). See also \\ref UsdGeomPointInstancer_transform .""" ) int64[] invisibleIds = [] ( doc="""A list of id's to make invisible at the evaluation time. See \\ref UsdGeomPointInstancer_invisibleIds .""" ) } class Camera "Camera" ( doc = """Transformable camera. Describes optical properties of a camera via a common set of attributes that provide control over the camera's frustum as well as its depth of field. For stereo, the left and right camera are individual prims tagged through the \\ref UsdGeomCamera::GetStereoRoleAttr() "stereoRole attribute". There is a corresponding class GfCamera, which can hold the state of a camera (at a particular time). \\ref UsdGeomCamera::GetCamera() and \\ref UsdGeomCamera::SetFromCamera() convert between a USD camera prim and a GfCamera. To obtain the camera's location in world space, call the following on a UsdGeomCamera 'camera': \\code GfMatrix4d camXform = camera.ComputeLocalToWorldTransform(time); \\endcode \\note Cameras in USD are always "Y up", regardless of the stage's orientation (i.e. UsdGeomGetStageUpAxis()). This means that the inverse of 'camXform' (the VIEW half of the MODELVIEW transform in OpenGL parlance) will transform the world such that the camera is at the origin, looking down the -Z axis, with +Y as the up axis, and +X pointing to the right. This describes a __right handed coordinate system__. \\sa \\ref UsdGeom_LinAlgBasics """ inherits = customData = { string extraIncludes = """ #include "pxr/base/gf/camera.h" """ } ) { # viewing frustum token projection = "perspective" ( allowedTokens = ["perspective", "orthographic"]) float horizontalAperture = 20.9550 ( doc = """Horizontal aperture in millimeters (or, more general, tenths of a world unit). Defaults to the standard 35mm spherical projector aperture.""") float verticalAperture = 15.2908 ( doc = """Vertical aperture in millimeters (or, more general, tenths of a world unit). Defaults to the standard 35mm spherical projector aperture.""") float horizontalApertureOffset = 0.0 ( doc = """Horizontal aperture offset in the same units as horizontalAperture. Defaults to 0.""") float verticalApertureOffset = 0.0 ( doc = """Vertical aperture offset in the same units as verticalAperture. Defaults to 0.""") float focalLength = 50.0 ( doc = """Perspective focal length in millimeters (or, more general, tenths of a world unit).""") float2 clippingRange = (1, 1000000) ( doc = """Near and far clipping distances in centimeters (or, more general, world units).""") float4[] clippingPlanes = [] ( doc = """Additional, arbitrarily oriented clipping planes. A vector (a,b,c,d) encodes a clipping plane that cuts off (x,y,z) with a * x + b * y + c * z + d * 1 < 0 where (x,y,z) are the coordinates in the camera's space.""") # depth of field float fStop = 0.0 ( doc = """Lens aperture. Defaults to 0.0, which turns off focusing.""") float focusDistance = 0.0 ( doc = """Distance from the camera to the focus plane in centimeters (or more general, world units).""") # stereoscopic 3D uniform token stereoRole = "mono" ( allowedTokens = ["mono", "left", "right"] doc = """If different from mono, the camera is intended to be the left or right camera of a stereo setup.""") # Parameters for motion blur double shutter:open = 0.0 ( doc = """Frame relative shutter open time in UsdTimeCode units (negative value indicates that the shutter opens before the current frame time). Used for motion blur.""" ) double shutter:close = 0.0 ( doc = """Frame relative shutter close time, analogous comments from shutter:open apply. A value greater or equal to shutter:open should be authored, otherwise there is no exposure and a renderer should produce a black image.""" ) } class "GeomModelAPI" ( inherits = customData = { string className = "ModelAPI" string extraIncludes = """ #include "pxr/usd/usdGeom/bboxCache.h" #include "pxr/usd/usdGeom/constraintTarget.h" #include "pxr/usd/usdGeom/imageable.h" """ dictionary schemaTokens = { dictionary extentsHint = { string doc = """Name of the attribute used to author extents hints at the root of leaf models. Extents hints are stored by purpose as a vector of GfVec3f values. They are ordered based on the order of purpose tokens returned by UsdGeomImageable::GetOrderedPurposeTokens.""" } } } doc = """UsdGeomModelAPI extends the generic UsdModelAPI schema with geometry specific concepts such as cached extents for the entire model, constraint targets, and geometry-inspired extensions to the payload lofting process. As described in GetExtentsHint() below, it is useful to cache extents at the model level. UsdGeomModelAPI provides schema for computing and storing these cached extents, which can be consumed by UsdGeomBBoxCache to provide fast access to precomputed extents that will be used as the model's bounds ( see UsdGeomBBoxCache::UsdGeomBBoxCache() ). \\section UsdGeomModelAPI_drawMode Draw Modes Draw modes provide optional alternate imaging behavior for USD subtrees with kind model. \\em model:drawMode (which is inheritable) and \\em model:applyDrawMode (which is not) are resolved into a decision to stop traversing the scene graph at a certain point, and replace a USD subtree with proxy geometry. The value of \\em model:drawMode determines the type of proxy geometry: - \\em origin - Draw the model-space basis vectors of the replaced prim. - \\em bounds - Draw the model-space bounding box of the replaced prim. - \\em cards - Draw textured quads as a placeholder for the replaced prim. - \\em default - An explicit opinion to draw the USD subtree as normal. \\em model:drawMode is inheritable so that a whole scene, a large group, or all prototypes of a model hierarchy PointInstancer can be assigned a draw mode with a single attribute edit. \\em model:applyDrawMode is meant to be written when an asset is authored, and provides flexibility for different asset types. For example, a character assembly (composed of character, clothes, etc) might have \\em model:applyDrawMode set at the top of the subtree so the whole group can be drawn as a single card object. An effects subtree might have \\em model:applyDrawMode set at a lower level so each particle group draws individually. Models of kind component are treated as if \\em model:applyDrawMode were true. This means a prim is drawn with proxy geometry when: the prim has kind component, and/or \\em model:applyDrawMode is set; and the prim or an ancestor has a non-default value for \\em model:drawMode. A value for \\em model:drawMode on a child prim takes precedence over a value on a parent prim. \\section UsdGeomModelAPI_cardGeometry Cards Geometry The specific geometry used in cards mode is controlled by the \\em model:cardGeometry attribute: - \\em cross - Generate a quad normal to each basis direction and negative. Locate each quad so that it bisects the model extents. - \\em box - Generate a quad normal to each basis direction and negative. Locate each quad on a face of the model extents, facing out. - \\em fromTexture - Generate a quad for each supplied texture from attributes stored in that texture's metadata. For \\em cross and \\em box mode, the extents are calculated for purposes \\em default, \\em proxy, and \\em render, at their earliest authored time. If the model has no textures, all six card faces are rendered using \\em model:drawModeColor. If one or more textures are present, only axes with one or more textures assigned are drawn. For each axis, if both textures (positive and negative) are specified, they'll be used on the corresponding card faces; if only one texture is specified, it will be mapped to the opposite card face after being flipped on the texture's s-axis. Any card faces with invalid asset paths will be drawn with \\em model:drawModeColor. Both \\em model:cardGeometry and \\em model:drawModeColor should be authored on the prim where the draw mode takes effect, since these attributes are not inherited. For \\em fromTexture mode, only card faces with valid textures assigned are drawn. The geometry is generated by pulling the \\em worldtoscreen attribute out of texture metadata. This is expected to be a 4x4 matrix mapping the model-space position of the card quad to the clip-space quad with corners (-1,-1,0) and (1,1,0). The card vertices are generated by transforming the clip-space corners by the inverse of \\em worldtoscreen. Textures are mapped so that (s) and (t) map to (+x) and (+y) in clip space. If the metadata cannot be read in the right format, or the matrix can't be inverted, the card face is not drawn. All card faces are drawn and textured as single-sided. \\todo CreatePayload() """ ) { uniform token model:drawMode ( allowedTokens = ["origin", "bounds", "cards", "default"] doc = """Alternate imaging mode; applied to this prim or child prims where \\em model:applyDrawMode is true, or where the prim has kind \\em component. See \\ref UsdGeomModelAPI_drawMode for mode descriptions.""" ) uniform bool model:applyDrawMode ( doc = """If true, and this prim or parent prims have \\em model:drawMode set, apply an alternate imaging mode to this prim. See \\ref UsdGeomModelAPI_drawMode.""" ) uniform float3 model:drawModeColor ( doc = """The base color of imaging prims inserted for alternate imaging modes. For \\em origin and \\em bounds modes, this controls line color; for \\em cards mode, this controls the fallback quad color. If unspecified, it should be interpreted as (0.18, 0.18, 0.18).""" ) uniform token model:cardGeometry ( allowedTokens = ["cross", "box", "fromTexture"] doc = """The geometry to generate for imaging prims inserted for \\em cards imaging mode. See \\ref UsdGeomModelAPI_cardGeometry for geometry descriptions. If unspecified, it should be interpreted as \\em cross.""" ) asset model:cardTextureXPos ( doc = """In \\em cards imaging mode, the texture applied to the X+ quad. The texture axes (s,t) are mapped to model-space axes (-y, -z).""" ) asset model:cardTextureYPos ( doc = """In \\em cards imaging mode, the texture applied to the Y+ quad. The texture axes (s,t) are mapped to model-space axes (x, -z).""" ) asset model:cardTextureZPos ( doc = """In \\em cards imaging mode, the texture applied to the Z+ quad. The texture axes (s,t) are mapped to model-space axes (x, -y).""" ) asset model:cardTextureXNeg ( doc = """In \\em cards imaging mode, the texture applied to the X- quad. The texture axes (s,t) are mapped to model-space axes (y, -z).""" ) asset model:cardTextureYNeg ( doc = """In \\em cards imaging mode, the texture applied to the Y- quad. The texture axes (s,t) are mapped to model-space axes (-x, -z).""" ) asset model:cardTextureZNeg ( doc = """In \\em cards imaging mode, the texture applied to the Z- quad. The texture axes (s,t) are mapped to model-space axes (-x, -y).""" ) } class "MotionAPI" ( inherits = doc = """UsdGeomMotionAPI encodes data that can live on any prim that may affect computations involving: - computed motion for motion blur - sampling for motion blur For example, UsdGeomMotionAPI provides *velocityScale* (GetVelocityScaleAttr()) for controlling how motion-blur samples should be computed by velocity-consuming schemas.""" ) { float motion:velocityScale = 1.0 ( customData = { string apiName = "velocityScale" } doc = """VelocityScale is an **inherited** float attribute that velocity-based schemas (e.g. PointBased, PointInstancer) can consume to compute interpolated positions and orientations by applying velocity and angularVelocity, which is required for interpolating between samples when topology is varying over time. Although these quantities are generally physically computed by a simulator, sometimes we require more or less motion-blur to achieve the desired look. VelocityScale allows artists to dial-in, as a post-sim correction, a scale factor to be applied to the velocity prior to computing interpolated positions from it. See also ComputeVelocityScale()""" ) } class "XformCommonAPI" ( inherits = doc = """This class provides API for authoring and retrieving a standard set of component transformations which include a scale, a rotation, a scale-rotate pivot and a translation. The goal of the API is to enhance component-wise interchange. It achieves this by limiting the set of allowed basic ops and by specifying the order in which they are applied. In addition to the basic set of ops, the 'resetXformStack' bit can also be set to indicate whether the underlying xformable resets the parent transformation (i.e. does not inherit it's parent's transformation). \\sa UsdGeomXformCommonAPI::GetResetXformStack() \\sa UsdGeomXformCommonAPI::SetResetXformStack() The operator-bool for the class will inform you whether an existing xformable is compatible with this API. The scale-rotate pivot is represented by a pair of (translate, inverse-translate) xformOps around the scale and rotate operations. The rotation operation can be any of the six allowed Euler angle sets. \\sa UsdGeomXformOp::Type. The xformOpOrder of an xformable that has all of the supported basic ops is as follows: ["xformOp:translate", "xformOp:translate:pivot", "xformOp:rotateXYZ", "xformOp:scale", "!invert!xformOp:translate:pivot"]. It is worth noting that all of the ops are optional. For example, an xformable may have only a translate or a rotate. It would still be considered as compatible with this API. Individual SetTranslate(), SetRotate(), SetScale() and SetPivot() methods are provided by this API to allow such sparse authoring.""" customData = { string apiSchemaType = "nonApplied" string extraIncludes = """ #include "pxr/usd/usdGeom/xformable.h" #include "pxr/usd/usdGeom/xformOp.h" """ dictionary schemaTokens = { dictionary pivot = { string doc = """Op suffix for the standard scale-rotate pivot on a UsdGeomXformCommonAPI-compatible prim. """ } } } ) { } class HermiteCurves "HermiteCurves" ( inherits = doc = """This schema specifies a cubically hermite interpolated curve as sometimes used for defining guides for animation. While hermite curves can be useful because they interpolate their points, they are not well supported by high-end renderers for imaging. Therefore, while we include this schema for interchange, we strongly recommend the use of UsdGeomBasisCurves as the representation of curves intended to be rendered (ie. hair or grass). Hermite curves can be converted to a Bezier representation (though not from Bezier back to Hermite in general). \\section UsdGeomHermiteCurves_Interpolation Point Interpolation The initial cubic curve segment is defined by the first two points and first two tangents. Additional segments are defined by additional point / tangent pairs. The number of segments for non-batched hermite curve would be len(hermite.points) - 1. The total number of segments for the batched UsdGeomHermiteCurves representation is len(points) - len(curveVertexCounts). \\section UsdGeomHermiteCurves_Primvars Primvar, Width, and Normal Interpolation Primvar interpolation is not well specified for this type as it is not intended as a rendering representation. We suggest that per point primvars would be linearly interpolated across the point and should be tagged as 'varying'. It is not immediately clear how to specify cubic or 'vertex' interpolation for this type, as we lack a specification for primvar tangents. This also means that width and normal interpolation should be restricted to varying (linear), uniform (per curve element), or constant (per prim). """ ) { vector3f[] tangents = [] ( doc = """Defines the outgoing trajectory tangent for each point. Tangents should be the same size as the points attribute.""") }