Kit 105 Upgrade Migration Guide
What’s Changed? (Relevant Release Notes)
Breaking Change: Applied API Schemas, Inheritance, and Built-Ins
Breaking Change: Retrieving Schema Type Names
New Feature: Auto-Applied API Schemas
New Feature: Abstract Typed Schemas and the Schema Registry
New Feature: Additional GLOBAL Schema Metadata to Define Use of Literal Identifier Names
Ar 2.0 (Asset Resolution Re-architecture)
Breaking Change: IsSearchPath() Removed
Breaking Change: IsRelativePath() Removed
Breaking Change: AnchorRelativePath() Renamed
Breaking Change: ComputeNormalizedPath() Removed
Breaking Change: ComputeRepositoryPath() Removed
Breaking Change: ComputeLocalPath() Removed
Breaking Change: Resolve() Signature Changed
Breaking Change: ResolveWithAssetInfo() Removed
Breaking Change: GetModificationTimestamp() Signature Changed
Breaking Change: OpenAsset() / ArAsset Signature Changes
Welcome!
It’s no easy feat to roll out 2+ years of contributions to Python, Visual Studio, and the USD Ecosystem in Omniverse– thank you for taking the time to use this guide to navigate the myriad incompatibilities introduced in this massive upgrade.
For the latest Omniverse Forum posts related to Kit 105 migration, please go [here]
Kit Extensions Upgrade
This section on upgrading Kit extensions contains information about breaking changes necessary to get building.
A fair amount of the toolset that we build on has been upgraded. This includes a new version of Visual Studio (2019), Boost 1.76, Python 3.10 and USD 22.11. These changes do impact Kit Extension developers and this next section will walk through some of the changes needed to upgrade an Extension to support all these changes.
The following steps assume that your Kit Extension is based on the Kit Extensions Template. The steps here should help the upgrade process but might be different depending on how the repository is set up to build.
Visual Studio 2019
The first step is to make sure your Extension is compatible with Visual Studio 2019.
Update your host-deps.packman.xml
Change your premake dependency to a more recent version. Currently, this is “5.0.0-beta1+nv1-${platform}”
Make your msvc dependency compatible with Visual Studio 2019. Currently, this is “2019-16.11.17-2”
Also use an updated version of winsdk which is “10.0.19608.0”
Next, you’ll need to update your version of repo_kit_tools in repo-deps.packman.xml. This updated version is needed so that premake will use the Visual Studio 2019 generator during the build process. Currently, this is “0.9.9”.
These updated dependencies should get the Extension repository pulling in the necessary dependencies for a Windows build using Visual Studio 2019
NOTE: An issue was encountered where the Extension(s) would still issue Windows build errors if built from a normal Windows Command Prompt. Switching to a Visual Studio 2019 Command Prompt fixed the issue. The exact build error was:
TRACKER : error TRK0005: Failed to locate: “CL.exe”. The system cannot find the file specified. [C:\omniverse\kit-ext-tpl-cpp-int\_compiler\vs2019\omni.example.cpp.commands.tests\omni.example.cpp.commands.tests.vcxproj]
TRACKER : error TRK0005: Failed to locate: “CL.exe”. The system cannot find the file specified. [C:\omniverse\kit-ext-tpl-cpp-int\_compiler\vs2019\omni.example.cpp.commands.plugin\omni.example.cpp.commands.plugin.vcxproj]
Issues with USD
The main issue that we are aware of when building a USD plugin, such as a SdfFileFormat plugin, against Visual Studio 2019 is an optimization that the compiler makes with release builds. Visual Studio 2019 enables the “/Zc:inline” option by default, we need to make sure that this option is disabled otherwise USD will not be able to construct your USD plugin in a release build.
In premake.lua make sure that you add the ”/Zc:inline-” buildoption for release builds to disable that behavior
If you are curious about why this needs to be done you can read more about the issue [here]
Kit SDK
Next, we’ll need to point our Extension at a kit-sdk dependency that includes all the changes necessary for Usd 22.11 and Python 3.10. As of this writing, we were just able to get a publish of kit-sdk that is compatible with USD 22.11 and Python 3.10 but until everything is merged into master we’ll need to use a package based on MR 21860. A quick search in packman could be used to find the most recent version:
All Changes related to Usd 22.11 + Python 3.10 have been merged into kit/master. Please use the released packman package or any subsequent releases:
We will also need to correctly import these new upstream dependencies from our kit-sdk dependency:
In target-deps.packman.xml (or kit-sdk-deps.packman.xml) make sure that you are importing both the python and nv_usd dependencies from kit-sdk
Make sure that your import path is pulling from all-deps.packman.xml in kit
[Include nv_usd_py310_$config]
This only needs to be added or changed if you extension depends on nv_usd. So if you see a dependency like nv_usd_py37_$config make sure that it is updated to nv_usd_py310_$config
At a minimum, your target-deps.packman.xml should be updated to look something like:
<project toolsVersion="5.6">
<import path="../_build/${platform}/${config}/kit/dev/all-deps.packman.xml">
<filter include="python" />
<filter include="nv_usd_py310_${config}" />
</import>
<dependency name="nv_usd_py310_${config}"
linkPath="../_build/target-deps/nv_usd/${config}" />
</project>
If you are pulling your nv_usd or python dependencies directly from packman, it might be a good time to update your dependencies and import directly from Kit’s all-deps.packman.xml. For example, if you are declaring your python and nv_usd dependencies like:
<project toolsVersion="5.6">
<dependency name="nv-usd_${config}" linkPath="../_build/deps/usd_${config}" >
<package name="nv-usd" version="20.08.nv.1.2.2404.6bf74556-win64_py37_${config}-main" platforms="windows-x86_64" />
<package name="nv-usd" version="20.08.nv.1.2.2404.6bf74556-linux64_py37-centos_${config}-main" platforms="linux-x86_64" />
<package name="nv-usd" version="20.08.nv.1.2.2404.6bf74556-linux-aarch64_py37_${config}-main" platforms="linux-aarch64" />
</dependency>
<dependency name="python" linkPath="../_build/deps/python" >
<package name="python" version="3.7.12+nv1-${platform}" platforms="windows-x86_64 linux-x86_64 linux-aarch64" />
</dependency>
</project>
Both python and nv_usd dependencies should be updated to use importing like:
<project toolsVersion="5.6">
<import path="../_build/${platform}/${config}/kit/dev/all-deps.packman.xml">
<filter include="python" />
<filter include="nv_usd_py310_${config}" />
</import>
<dependency name="nv_usd_py310_${config}" linkPath="../_build/target-deps/nv_usd/${config}" />
</project>
Update premake lua
We should have all of the necessary dependencies for MSVC 2019, Python 3.10, Boost 1.76 and USD 22.11 correctly set up. The next part of the process is updating the premake.lua scripts for each extension. Unfortunately, each one of these premake.lua scripts can be different depending on what’s required to build the extension. For example, if your extension is purely Python no changes to premake.lua should be necessary. But if your extension depends on USD and links against Boost for Python bindings it’s very likely that premake.lua will need to be updated
Update Python Include Paths or Links
If you have an Extension that creates Python bindings for a Native Extension, you’ll more than likely need to tweak some include paths and links in premake.lua.
In premake.lua for each Extension search for usages of “python3.7” and update to “python3.10”. Typically, these will be limited to “includedirs” and “links” in premake.
This should be as simple as search and replace but YMMV with complex build scripts.
The important part is that the Python 3.10 headers and binaries can be found when you go to build / link your Extension.
Update Boost Links
If the Extension you are building depends on Boost, include paths and links might need to change. This is definitely the case with Windows. Currently, we need to manually link boost against the vc141 toolset for Visual Studio 2019. See the Boost upgrade to version 1_76 section above which describes it in more detail. But until we get the vc142 toolset all sorted out we can do the following:
Use the link_boost_for_windows function. When calling “link_boost_for_windows({“boost_python310”})” that should correctly link against boost for Python 3.10 using the vc141 toolset.
NOTE: Once we have vc142 toolset support the auto-linking from boost should work and the link_boost_for_windows function should not be necessary
Odds and Ends
The location of the omni.usd binary has changed. To properly link against omni.usd you will need to change the library path to find it:
libdirs {“%{kit_sdk}/extscore/omni.usd.core/bin”} -> libdirs {“%{kit_sdk}/exts/omni.usd.core/bin”}
Common Errors
Unable to find Python headers / library for building Python bindings
The following error usually means that an include directory within a premake5.lua build script might be misconfigured and not set to the correct directory
../../../_build/target-deps/nv_usd/debug/include/boost/python/detail/wrap_python.hpp:57:11:
fatal error: pyconfig.h: No such file or directory
Within your premake5.lua scripts a couple examples of incorrect paths:
includedirs { target_deps.."/python/include/python3.10**m**" }
includedirs { target_deps.."/python/include/python3.7m" }
includedirs { target_deps.."/python/include/python3.7" }
These include directories should be set to the following now that kit-sdk is using Python 3.10
includedirs { target_deps.."/python/include/python3.10" }
Usd 22.11 and Python 3.10 Updates
From here, the Extension repository should at least be able to find all
the necessary dependencies, build and link against them. The next part
will be to make any necessary changes for Python 3.10, such as calling
super().__init__()
, and USD 22.11. These changes can vary wildly
between repositories and developers should refer to all the
documentation in this guide on how to properly migrate their repository.
Publishing Extensions
Publishing of extensions is usually handled via CI / CD . This typically happens after all tests pass on the main branch of the extension’s repository. The location of where extensions are published to are handled by configuration in their repo.toml or using the default settings set within kit-sdk. Kit 105.0 has not changed this behavior but a couple of features have been added to help with the new version of USD. Specifically, these features are USD package targets and USD extension registries.
Package Targets
Package targets are metadata embedded with the extension that help determine compatibility with the Kit runtime. Some simple examples of package targets are an extension’s platform (Windows, Linux, aarch, etc), configuration (release, debug), python version (3.6, 3.7, 3.10) and so on. To help with the transition to a new USD version we have added a USD package target that can be optionally written to metadata. The USD package target helps the Kit runtime load the correct version of the extension with the version of USD being used. For example, Kit 104.2 will need to load extensions that are built using USD 20.08 whereas Kit 105.0 will need extensions compatible with USD 22.11. The USD package target provides this information to the Kit runtime to load the right version of the extension. More information on package targets for extensions can be found in the [documentation]
Writing Package Targets
Not all extensions directly depend on USD, as such they do not need to write out the USD package target. But there are a couple of scenarios where an extension should write out the USD package target:
Native extensions that build and link against USD libraries. For example:
a. Extensions that add USD plugins like SdfFileFormat, ArResolver, > ArPackageResolver, UsdSchemaAPI, UsdTypedSchema, etc
b. Extensions that use USD APIs to operate on USD data
Python extensions that use new USD APIs and are not backward compatible with older versions of USD.
For these types of extensions, writing out the USD package target helps ensure that the correct version of the extension will be loaded. To write out the USD package target it as simple as adding the following configuration to your extension.toml:
[package]
## ... additional package configuration settings
writeTarget.usd = true
Once your extension has been configured to write out its USD package target the publishing process will take care of the rest. It will get all the information needed for the USD version and embed that metadata into the published extension. The Kit runtime will then load the correct version of the extension according to the USD version being used. You can find more information about writing package targets in the [documentation]
Extension Registries
Another feature added to the Extension publishing process are USD version specific Extension Registries. These Extension Registries provide a greater level of isolation than USD package targets as the Extensions are uploaded to a completely separate location. This allows for Extensions to be published even when kit-sdk is still in the process of being upgraded to the new version of USD. The benefit here is that a downstream Extension repository can be upgraded and published without affecting main-line Extension Registries used by Applications. After an Extension is published it can then be tested via ETM or resolved by any dependent Extensions that also need to be upgraded.
Enabling USD Extension Registries
Enabling USD version specific Extension Registries is handled through configuration. The usd.version_compatibility.enable configuration setting is what enables this behavior and is intended to be set in one of two places:
Within repo_tools.toml for kit-sdk itself
In an Extension repository’s repo.toml
Enabling usd.version_compatibility in kit-sdk is intended to “opt-in” all Extensions that upgrade to this build of kit-sdk. For example, with the un-merged https://gitlab-master.nvidia.com/omniverse/kit/-/merge_requests/21860 we have this configuration setting enabled since all the changes affect API, ABI and Behavioral incompatibilities. This allows for us to upgrade and publish downstream Extensions freely without risking Applications pulling in these incompatible Extensions. We can use ETM on our MR to see how the upgrade is progressing with downstream Extensions.
The other way to enable this is by enabling the same
usd.version_compatibility.enable
setting in an Extension
repository’s repo.toml. This is for Extensions to selectively
“opt-in” to use USD version specific Extension Registries. The
intention for setting it at this level is when Extensions want to or
need to use a custom build of USD for things such as testing ABI
compatibility.
An example of an Extension repository enabling this behavior in it’s
repo.toml
configuration file is:
[repo_publish_exts]
## ... additional publish_exts configuration settings
## Enable USD version compatiblity so the extension is published to the
## corresponding USD compatible extension registry
usd.version_compatibility.enable = true
Publishing to USD Extension Registries
The question of “can I publish my upgraded USD Extension or should I
wait until everything is merged into kit-sdk/master?” has come up in
the past couple of days. The answer is that, yes, we can publish
upgraded Extensions without affecting Applications using those
Extensions since we have usd.version_compatibility.enable
turned on
for
[https://gitlab-master.nvidia.com/omniverse/kit/-/merge_requests/21860].
With the current configuration, the Extensions will be published to the
following Extension Registry:
omniverse://kit-extensions.ov.nvidia.com/exts/kit/usd/nv-usd/22.11/merge_pxr_22-11-py310/
Updated Extension Repositories
The two main Extension repositories that support the new toolset are:
As an Extension is being upgraded it might be good to reference these repositories if you hit any issues not described in this section. I don’t expect these repositories to be exhaustive in all the issues we may encounter but it’s a good starting point. As more developers upgrade their Extensions we will probably uncover more issues that we are currently unaware of. Feel free to add to this guide with any issues that have been encountered and you believe will help out other developers.
Python 3.10 Upgrade
Breaking Change: must call super __init__
function
All derived classes that override
__init__
must call the super__init__
function. This does not limit only to omni.ext.IExt, but any class, the following example will also fail:
class A:
def __init__(self):
self.x = 0
class B(A):
def __init__(self):
self.y = 0
b = B()
print(b.x, b.y)
Omitting this is now an error in 3.10. The simplest way is to call
super().__init__()
with arguments if there are any.
Breaking Change: DLL load behavior
DLL load behavior changed on Windows in Python 3.8+.
The PATH environment variable is no longer used for directories to load DLLs from. Anything outside of the script dir/python exe dir must be added in code now. There’s a new function in the os module called add_dll_directory that takes a string path arg.
Breaking Change: Boost upgrade to version 1_76
Boost has an auto linker for Windows that is enabled by default. The lib names for Windows vary based on compiler, config, and mt or not. The auto linker handles determining the correct version based on the active build tooling. Boost 1_76 is aware of the VS 2019 build tools, unlike version 1_68 that was being used previously. USD is still being built with 2017, so at the Kit build phase, boost detects 2019 and searches for those libraries, but they don’t exist because USD built with 2017. As a workaround until all of the other USD dependents are built with VS 2019, boost needs to be linked manually. There’s a premake helper function in Kit called link_boost_for_windows that takes a list of the short names and links the full ones.
Schema Development
Introduction
Between 20.08 and 22.08, schema extensions have undergone a number of changes that include new features (such as codeless and auto-applied schemas) and breaking changes (such as API schemas no longer supporting inheritance). This section discusses both, along with examples of changes that need to be made for schema extensions to be compliant with USD 22.11.
What’s Changed? (Relevant Release Notes)
22.11
Added
"GetAll"
method for multi-apply schemas in codegenTemplates.
22.08
Added the apiSchemaOverride feature to usdGenSchema that allows a schema definition to explicitly define sparse overrides to properties it expects to be included from a built-in API schema. See: https://graphics.pixar.com/usd/release/api/_usd__page__generating_schemas.html#Usd_APISchemaPropertyOverride
22.05
Changes for usdGenSchema:
Disabled inheritance for multiple apply API schemas, now that built-in API schemas are supported for multiple apply schemas.
Fixed issue where schema tokens with invalid C++ identifiers would be generated. These tokens will now be converted into a valid identifier. Tokens beginning with a numeral are now prefixed with ‘_’.
Added ability to generate C++ identifiers using property names and values exactly as authored in schema.usda instead of camel-casing them by specifying useLiteralIdentifier in the GLOBAL schema metadata. This is helpful in scenarios where schema.usda is generated using utilities like usdgenschemafromsdr instead of being hand authored.
Fixed Python 3 compatibility by explicitly included the None keyword in reserved list.
22.03
Changes for applied API schemas:
Multiple-apply API schemas can now include other multiple-apply API schemas as built-ins.
"prepend apiSchemas"
must be used in schema.usda to set built-in API schemas on another schema.Applied API schemas authored on a prim can no longer change the type of a property defined by that prim’s type or built-in API schemas.
21.11
Updated connectedAPIBehavior so that APISchemas can now provide connectableAPIBehavior by explicitly registering a new behavior associated with the APISchemaType or by providing plug metadata to configure the connectability behavior. Note that the latter can be used for codeless schemas.
Single apply API schemas can now include built-in API schemas and can auto apply to other single apply API schemas. API schemas are now only allowed to inherit directly from UsdAPISchemaBase.
Applied API schemas can no longer inherit from other other applied API schemas, which allows UsdPrim::HasAPI() to be a much faster query. Non-applied schemas may still inherit from other non-applied schemas.
21.08
Added support for “codeless” USD schemas that do not have any C++ or Python code. Changes to these schemas’ definitions do not require any code to be recompiled; instead, the generatedSchema.usda just needs to be regenerated via usdGenSchema and reinstalled.
Added ability to specify allowed prim types for API schemas in the customData dictionary for the schema in schema.usda.
Added UsdPrim::CanApplyAPI and CanApply to all API schema classes to check if an API schema can be applied to a prim based on the restrictions above.
API schemas can now provide connectability behavior, which can override behavior based on prim type.
21.05
Updated usdGenSchema to not error when generating a dynamic schema and libraryPath is not specified.
Fixed usdGenSchema to honor apiName metadata for auto generated tokens.h. This results in correct doxygen documentation for the correct API names.
usdGenSchema now adds a type alias for abstract typed schemas, which means abstract typed schemas now have an official USD type name which is registered with the UsdSchemaRegistry.
Auto apply API schemas in USD can now specify abstract typed schemas to auto apply to, indicating that the API should be applied to all schemas that derive from the abstract schema type.
21.02
Added support for auto-apply API schemas. This allows single-apply API schemas to be automatically applied to prims using one of a list of associated concrete schema types instead of requiring the user to manually apply the API schema.
Renamed UsdSchemaType to UsdSchemaKind to disambiguate between the schema type (e.g. UsdGeomSphere) and kind (e.g. non-applied, single-apply, etc).
Deprecated functions using the
"schema type"
terminology in favor of"schema kind"
.
Breaking Change: Applied API Schemas, Inheritance, and Built-Ins
As of v21.11, USD no longer supports inheritance chains for API schemas
(although still fully supported for IsA schemas). The primary reason for
this breaking change was the need to make
UsdPrim::HasAPI<SchemaType>()
more efficient by not continuously
checking derivation chains. To that end, support for inheritance was
removed from API schemas. Instead, API schemas have the ability to
define built-ins, which are semantically similar to defining inheritance
chains, but more performant from a USD run-time perspective.
Unfortunately, this has a significant impact to our own custom schema
definitions (particularly physics) and requires that these schemas be
migrated to conform to the new requirements.
Inheriting </APISchemaBase>
and Applying Built-Ins To Represent Dependencies
All API schema types (both single and multiple-apply) are now required
to inherit </APISchemaBase>
. This means that any derivation chains
that exist in applied API schemas must be converted such that the
inherits attribute of the schema type is </APISchemaBase>
:
class "MyAppliedAPI" (
inherits = </APISchemaBase>
) {
}
To simulate inheritance and define a dependency chain, USD has introduced the concept of built-ins. This is the inverse of the auto-applied API schema feature - when an applied API schema is applied to a prim instance, all applied API schemas declared as built-ins are applied as well. Built-ins work recursively such that if SchemaType1API declared built-ins of SchemaType2API and SchemaType3API, and SchemaType2API declared built-ins of SchemaType4API, then applying SchemaType1API to a prim instance will also apply SchemaType2API, SchemaType3API, and SchemaType4API.
All built-ins specified must be either single-apply API or named instances of multiple-apply API schemas (IsA schemas cannot be built-ins).
Declaring an applied API schema type as a built-in involves placing it’s schema type name in the prepend apiSchemas attribute of the schema type that uses it as a built-in:
class "ExampleSchema1API" (
inherits = </APISchemaBase>
customData = {
token apiSchemaType = "singleApply"
}
prepend apiSchemas = ["ExampleSchema2API"]
) {
}
This definition states that when ExampleSchema1API is applied to a prim instance, ExampleSchema2API will also be applied as a schema built-in to ExampleSchemaAPI. This mimics inheritance in the sense that applying ExampleSchema1API will always also apply ExampleSchema2API, so all attributes from both will be present on the prim (as you would expect in the normal inheritance chain).
Note: A schema can have a stronger opinion on a property that may come from one of its built-ins if it declares the property itself. This is useful to override the default value of the property. Be careful not to do this unintentionally and do things like e.g. change the type of the property!
Multiple-apply schemas have an additional set of consequences since they must always be applied to a prim instance using the same instance name. This results in the following:
If a multiple-apply API schema is listed as a built-in without an instance name, it is always applied to the prim instance using the same instance name as the schema type declaring the built-in.
If a multiple-apply API schema is listed as a built-in with an instance name, it will be applied with a suffixed instance name that combines the built-in instance name and the instance name of the schema type declaring the built-in.
For example, consider the following definition:
class "MultipleApplySchema1API" (
inherits = </APISchemaBase>
customData = {
token apiSchemaType = "multipleApply"
}
prepend apiSchemas = ["MultipleApplySchema2API"]
) {
}
Applying MultipleApplySchema1API to a prim instance with the instance name foo will also result in MultipleApplySchema2API being applied to the prim instance with the instance name foo. Now consider a slight modification to this definition:
class "MultipleApplySchema1API" (
inherits = </APISchemaBase>
customData = {
token apiSchemaType = "multipleApply"
}
prepend apiSchemas = ["MultipleApplySchema2API:bar"]
)
{
}
In this case, applying MultipleApplySchema1API to a prim instance with the instance name foo will result in MultipleApplySchemaAPI2 being applied with the suffixed instance name foo:bar.
Note that built-ins apply to IsA schema types as well (that is, you can define a list of built-in API schema types that are applied to a prim instance of the IsA type). In this case, inherited types will inherit the built-ins from their base types.
What do I need to change?
Based on this breaking change, there are two things that must be done in existing schemas:
All applied API schemas must be changed to inherit from
</APISchemaBase>
The existing inheritance hierarchy must be converted to a set of built-ins (see examples below)
As an example, consider three applied API schemas Schema1API, Schema2API, and Schema3API, each currently inheriting from the one before as so:
class "Schema1API" (
inherits = </APISchemaBase>
customData = {
token apiSchemaType = "singleApply"
}
) {
}
class "Schema2API" (
inherits = </Schema1API>
customData = {
token apiSchemaType = "singleApply"
}
) {
}
class "Schema3API" (
inherits = </Schema2API>
customData = {
token apiSchemaType = "singleApply"
}
) {
}
To convert these, each would be modified to inherit APISchemaBase and to prepend the schema type they inherit as follows:
class "Schema1API" (
inherits = </APISchemaBase>
customData = {
token apiSchemaType = "singleApply"
}
) {
}
class "Schema2API" (
inherits = </APISchemaBase>
customData = {
token apiSchemaType = "singleApply"
}
prepend apiSchemas = ["Schema1API"]
) {
}
class "Schema3API" (
inherits = </APISchemaBase>
customData = {
token apiSchemaType = "singleApply"
}
prepend apiSchemas = ["Schema2API"]
) {
}
Since built-ins are recursive, we get the properties that we would expect from all three applied schemas when applying Schema3API to a prim, just as we would in the inheritance scenario.
Accessing API Schema Attributes
Unfortunately, using the API schemas becomes a bit more burdensome than it is with inheritance. Prior to this change, a developer could modify any of the inherited attributes via the most-derived type:
Schema3API schema3API = Schema3API::Apply(prim);
int x = schema3API.GetSchema3Attr1().Get<int>();
double y = schema3API.GetSchema2Attr1().Get<double>();
This same approach does not work with built-ins, and so it is necessary at the current time to acquire the different API schemas in the built-ins set to set the attributes on each appropriately:
Schema3API schema3API = Schema3API::Apply(prim);
int x = schema3API.GetSchema3Attr1().Get<int>();
Schema2API schema2API = Schema2API(prim);
double y = schema2API.GetSchema2Attr1().Get<double>();
This requires (extensively) refactoring existing code, especially for schemas like physics that have API schemas that are heavily inheritance based. The expectation is that this will be addressed by USD to make this more developer friendly.
Breaking Change: Schema Kind
From v21.02 onward, what used to be schema type is now referred to as schema kind. This change was made to disambiguate the schema type name (e.g. Schema1API) and what kind of schema it is (e.g. single-apply, multiple-apply, etc.). While the impact is small, it does require:
Regeneration of the schema classes such that the GetSchemaKind method is generated over the GetSchemaType method (which will return a UsdSchemaKind not a UsdSchemaType
Code changes in any code that uses those methods of the schema (or associated methods of the UsdSchemaRegistry to reflect on schema types).
In practice, since the values of UsdSchemaKind are the same as the old UsdSchemaType enumeration, this means replacing any code that calls GetSchemaType with calls to GetSchemaKind and using UsdSchemaKind as the return value, on both schema types themselves and any code involving the UsdSchemaRegistry.
Also, if your plugInfo.json is missing the schemaKind field, it may silently fail to load.
For details on API breakage, see:
[Other Breaking Changes: Schemas: pugInfo.json: plugInfo.json now requires schemaKind field]
Breaking Change: Retrieving Schema Type Names
From v21.02 onward, the GetSchemaPrimSpec method on UsdPrimDefinition has been removed. This method was used to get the “schema prim spec”, from which the schema type name of an e.g., C++ type could be retrieved. While there is no direct replacement on UsdPrimDefinition, similar functionality can be found in the UsdSchemaRegistry singleton object via the method GetSchemaTypeName:
/// Return the type name in the USD schema for prims or API schemas of
the
/// given registered \\p SchemaType.
template <class SchemaType>
static TfToken GetSchemaTypeName() {
return GetSchemaTypeName(SchemaType::_GetStaticTfType());
}
New Feature: Auto-Applied API Schemas
An auto-applied API schema refers to a single-apply API schema that will be automatically attached to a set of prim instances of one or more defined schema types. This is a new feature that requires no migration of existing schema content and has two advantages:
An existing schema set can be extended with additional attributes without having to modify the original schema. That is, if a schema Schema1 supplied a set of attributes, and a developer decides that there is an additional set of attributes that are directly relevant to prims that have Schema1 applied, then they can create a new schema Schema2API containing those new attributes and declare that it should be auto-applied to all prim instances of type Schema1 (in the case of typed schemas) or for which Schema1 is applied (in the case of API schemas), without modifying Schema1 itself. In the case of IsA schemas, the auto-apply rule would trigger on the specified schema being applied to a prim instance as well as any inherited type of that schema being applied.
All prim instances that satisfy the auto apply to criteria automatically get the new schema applied without developers having to explicitly call Apply on each prim they want the schema to apply to.
The mechanism for defining this in a schema definition is via the apiSchemaAutoApplyTo attribute of the API schema type’s customData dictionary. This is an array of token strings defining the names of the schemas applied to a prim instance that trigger the auto-apply rule. Note this is an or set, not an and set (only one of the listed schemas need be applied to a prim instance for the auto-apply rule to trigger). For example, if a developer wanted to auto-apply a new schema type Schema1API to all prim instances of type UsdGeomMesh, their definition would look as follows:
class "Schema1API" {
inherits = </APISchemaBase>
customData = {
token[] apiSchemaAutoApplyTo = ["UsdGeomMesh"]
}
}
Note that this functionality only applies to single-apply API schemas (as multiple-apply API schemas require an instance name to be specified on application).
The above technique is applied at schema generation time, which is sufficient for a broad number of use cases. USD also has an additional mechanism for supplying this information which applies later in the pipeline (i.e. after schema generation has occurred and is distributed). This is referred to as plugin defined auto-applied API schemas. This allows developers to specify additional auto-apply rules that may only affect a subset of schema consumers. While an uncommon use case, USD allows this type of auto-apply schema to be specified directly in the plugInfo.json file via the AutoApplyApiSchemas key contained in the Plugins.Info key. Representing the example above in the plugInfo.json file would look as follows:
{
"Plugins": [
"Info": {
"AutoApplyAPISchemas": {
"Schema1API" : {
"apiSchemaAutoApplyTo": [
"UsdGeomMesh"
]
}
}
}
]
}
New Feature: Abstract Typed Schemas and the Schema Registry
Prior to v21.05, USD did not record abstract typed schemas as official USD type names in the schema registry. This effectively meant that developers could not refer to these abstract typed schemas in scenarios such as auto-apply of API schemas. This minor change makes abstract typed schemas first class citizens in the schema registry, and their type names can be used in auto-apply scenarios to capture a large number of prims who’s schemas are derived from the abstract schema. That is, consider the scenario below:
Figure 1: Abstract Typed Schemas with Auto-Apply
In this case, AppliedSchema1API will be auto-applied to all prims of type ConcreteSchema1, ConcreteSchema2, or ConcreteSchema3. Prior to this change, AppliedSchema1API would only have been allowed to specify one (or more) of the concrete schema types to auto-apply to.
New Feature: Codeless Schemas
v21.08 introduced the concept of codeless schemas. These schemas have no generated code - only the type definition. This makes them easy to distribute, use, and iterate; providing a data contract without binary distribution issues (although codeless schemas are still discovered through the standard USD plug-in system). You may already be taking advantage of this feature - it was cherry picked into NVIDIA’s v20.08 USD source and made available to usdgenschema. Codeless schemas can be declared by adding the skipCodeGeneration attribute to the GLOBAL schema metadata. Note that this will cause all schemas defined in the schema.usda file to be codeless, so if you want both codeful and codeless schemas be sure to separate out their definitions into different schema.usda files.
As an example, let’s define a codeless schema for the following simple scenario:
Figure 2: Codeless Schema Example
over "GLOBAL" (
customData = {
bool skipCodeGeneration = true
}
) {
}
class "Schema1API" (
inherits = </APISchemaBase>
customData = {
token apiSchemaType = "singleApply"
}
)
{
int schema1:property1 = 5 (
)
int schema1:property2 = 2 (
)
}
The downside to codeless schemas is that you don’t get the nice wrappers for accessing properties on a prim associated with that schema that are available through the code generation. All property access must go through the generic API’s available on UsdPrim.
TfType schemaType =
UsdSchemaRegistry::GetAPITypeFromSchemaTypeName("Schema1API");
bool hasApi = prim.HasAPI(schemaType);
if (hasApi)
{
int schema1APIProperty1Value = 0;
int schema1APIProperty2Value = 0;
prim.GetAttribute("schema1:property1").Get<int>(&schema1APIProperty1Value);
prim.GetAttribute("schema1:property2").Get<int>(&schema1APIProperty2Value);
assert(schema1APIProperty2Value == 2);
prim.GetAttribute("schema1:property2").Set<int>(schema1APIProperty1Value);
prim.GetAttribute("schema1:property2").Get<int>(&schemaAPIProperty2Value);
assert(schema1APIProperty2Value == 5);
}
New Feature: Additional GLOBAL Schema Metadata to Define Use of Literal Identifier Names
In v22.05, USD added the ability for schema authors to specify that property names should be generated verbatim as written rather than the normal behavior of camel-casing them. This is a minor change, but helpful in scenarios where the schema.usda file is auto-generated by a tool rather than hand authored (e.g. usdgenschemafromsdr). To invoke this behavior, a new metadata key was added to the GLOBAL schema metadata:
over "GLOBAL" (
customData = {
string libraryName = "exampleLibrary"
string libraryPath = "."
bool useLiteralIdentifier = true
}
)
}
Adding this metadata informs usdgenschema to attempt to use the written property names verbatim. Note that normal rules still apply for identifiers, and usdgenschema will make the property name a valid identifier (via TfMakeValidIdentifier) if it is invalid, even in cases where useLiteralIdentifier is set in the GLOBAL metadata.
New Feature: Defining Sparse Overrides From Built-Ins
In v22.08, USD introduced the ability for an API schema to perform a sparse override of a built-in’s property. In this scenario, an API schema may have an opinion on the default value of a property from one of its built-ins, without defining or owning the property itself. This is functionally similar to an over for the property, where the API schema defines a stronger opinion of the default value. Consider the following:
Figure 3: Sparse Overrides on Built-Ins
This new functionality can be taken advantage of by adding the apiSchemaOverride to the customData dictionary of the property.
class "Schema1API" (
) {
uniform int schema1:property = 5 (
)
}
class "Schema2API" (
prepend apiSchemas = ["Schema1API"]
) {
uniform int schema1:property = 2 (
customData = {
bool apiSchemaOverride = true
}
)
}
In this scenario, Schema2API has declared Schema1API a built-in and provided a sparse override of the schema1:property default value. Note that when doing this, the property must be declared with the exact same type and variability (e.g., uniform int in the above example), otherwise the override is ignored. Also note that this functionality is only available to API schemas and does not apply to overriding properties via IsA schema inheritance.
Ar 2 (Asset Resolution Re-architecture)
Introduction
The public interface to Ar (Asset Resolution) has changed significantly, hence the version change from 1.0 to 2.0. While it is a significant change, the functionality is mostly the same but provides better hooks for cloud-based asset backends such as Nucleus. The parts of Ar that changed mostly relate to removed and renamed methods. In most circumstances, methods were removed since they really only applied to Pixar’s way of resolving assets. Other methods were renamed to more accurately convey their intent.
Breaking Change: IsSearchPath() Removed
Search paths are no longer a part of the public interface of Ar 2.0. This was done for good reason as not all asset management systems support search paths. Internally, an implementation of Ar 2.0 can support search paths but there is no publicly available method such as ArGetResolver().IsSearchPath(). Originally, this method was made a part of the public Ar interface so Sdf could perform the “look here first” approach when resolving an SdfAssetPath that fit the criteria of a search path. If you are using ArGetResolver().IsSearchPath() it might be a good time to assess why you are using it before migrating your code as there is not an out-of-the-box solution. If ArGetResolver().IsSearchPath() is used in a lot of places we could add a utility function to mimic it’s behavior.
In order to migrate your code to check if an asset path is a search path it will need to pass the following checks:
It is not a URL prefixed with a scheme such as omniverse:// or https://
It is not an absolute file path i.e starting with / or \
It is not a file relative path:
a. Does not start with ./ or ../
b. Does not start with .\ or ..\
A C++ implementation would be:
// Add the C++ Implementation similar to what we are using in OmniUsdResolver_Ar1.cpp
For details on API breakage, see:
Breaking Change: IsRelativePath() Removed
As a part of the process to decouple assets from the filesystem, ArGetResolver().IsRelativePath() was also removed. While sometimes useful, it also made for a confusing API when paired with ArGetResolver().AnchorRelativePath(). It would make the caller think that you need to check if the asset path was relative before calling ArGetResolver().AnchorRelativePath() which was not always the case. If you find that you’re calling ArGetResolver().IsRelativePath() on asset paths before ArGetResolver().AnchorRelativePath() a better way to migrate your code would be to use a utility from Sdf:
auto stage = UsdStage::Open(“omniverse://some/asset.usd”);
const std::string assetPath = “./geom.usd”;
// SdfComputeAssetPathRelativeToLayer works for both Ar 1.0 and Ar 2.0
// It will also handle all the edge cases dealing with things like anonymous layers,
// package relative paths, etc.
const std::string assetId = SdfComputeAssetPathRelativeToLayer(stage->GetRootLayer(), assetPath);
If you find that you do need to check if some string is relative, TfIsRelativePath() could be used. But it’s important to understand that TfIsRelativePath() will only work with filesystem paths. For example, TfIsRelativePath(“omniverse://some/asset.usd”) would return true. So only use TfIsRelativePath() if you’re sure it’s a filesystem path and not a URL.
For details on API breakage, see:
Breaking Change: AnchorRelativePath() Renamed
ArGetResolver().AnchorRelativePath() was correctly renamed to ArGetResolver().CreateIdentifier(). The reason for this method being renamed is to clarify its intent which is to create an identifier for an incoming asset path. The incoming asset path may or may not be relative, but ArGetResolver().AnchorRelativePath() was always called to make sure the returned result was a valid identifier that could be consistently resolved.
const std::string anchor = "omniverse://some/asset.usd";
const std::string assetPath = "./geom.usd";
##if !defined(AR_VERSION) || AR_VERSION < 2
// Ar 1.0
const std::string identifierAr1 =
ArGetResolver().AnchorRelativePath(anchor, assetPath);
##else
// Ar 2.0 - The ArResolvedPath is required for the anchor to indicate to
the ArResolver plugin
// implementing _CreateIdentifier that the anchor has already been
resolved
const ArResolvedPath resolvedAnchor(anchor);
// Ar 2.0 - Note how the anchor and asset path order are switched
const std::string identifierAr2 =
ArGetResolver().CreateIdentifier(assetPath, resolvedAnchor);
##endif
For details on API breakage, see:
API Breaking Changes: Ar.Resolver: AnchorRelativePath() to CreateIdentifier()
Breaking Change: ComputeNormalizedPath() Removed
ArGetResolver().ComputeNormalizedPath() has been removed since in most cases it was a redundant call. Most ArResolver plugins would return the normalized form of an incoming asset path in ArGetResolver().AnchorRelativePath(). However, ArGetResolver().AnchorRelativePath() was vague as to the expected result. ArGetResolver().CreateIdentifier() clarifies that its returned result should be in its final normalized form.
For details on API breakage, see:
API Breaking Changes: Ar.Resolver: ComputeNormalizedPath() Removed
Breaking Change: ComputeRepositoryPath() Removed
ArGetResolver().ComputeRepositoryPath() has been removed. A repository path, or repoPath, was a very Pixar specific way of identifying their assets within Perforce. For the majority of their assets they could compute the resolved path or local path to a repository path (identifier) in Perforce. In some ArResolver plugins a resolved path can not be computed to its repository path (identifier). For this reason, an ArResolver plugin would just return the incoming path as-is and adds to a confusing ArResolver interface.
In order to migrate your code the call to ArGetResolver().ComputeRepositoryPath() should just be removed. The OmniUsdResolver would just return the incoming path, nothing was actually computed since client-library does not support converting a resolved cached path to the URL it was resolved from.
For details on API breakage, see:
API Breaking Changes: Ar.Resolver: ComputeRepositoryPath() Removed
Breaking Change: ComputeLocalPath() Removed
ComputeLocalPath() has been removed and replaced with more accurately named methods. In Ar 1.0, ComputeLocalPath() was called in SdfLayer::CreateNew to redirect a new layer to some local path on disk so it could still resolve. Ar 2.0 clarifies the interface by adding CreateIdentifierForNewAsset / ResolveForNewAsset methods
const std::string assetPath = "omniverse://some/new/asset.usd";
// Not completely necessary but makes sure the assetPath is absolute + normalized
const std::string identifier = ArGetResolver().CreateIdentifierForNewAsset(assetPath);
const ArResolvedPath resolvedPath = ArGetResolver().ResolveForNewAsset(identifier);
For details on API breakage, see:
API Breaking Changes: Ar.Resolver: ComputeLocalPath() Removed
Breaking Change: Resolve() Signature Changed
Resolve() has changed the return type from std::string to ArResolvedPath. The ArResolvedPath type is just a shim around std::string to clarify the interface when an ArResolver plugin can expect to receive a resolved path. One of the confusing aspects of Ar 1.0 for an ArResolver plugin implementation was when you were receiving an unresolved asset path or a fully resolved path. This led to numerous subtle bugs when the plugin would assume a resolved path but would actually be receiving an asset path since everything was just typed from std::string.
The code required to support this change can be done in a few different ways and should be handled according to preference or coding style:
const std::string assetPath = "omniverse://some/asset.usd";
// In Ar 1.0
const std::string resolvedPath = ArGetResolver().Resolve(assetPath);
// In Ar 2.0
const ArResolvedPath resolvedPath = ArGetResolver().Resolve(assetPath);
// or to support Ar 1.0 + Ar 2.0
auto resolvedPath = ArGetResolver().Resolve(assetPath);
Another very important aspect of Resolve() is that USD no longer assumes that the returned result will point to a normal file path on disk! It is expected that Resolve() can return things such as URIs where any file system calls, i.e ArchOpenFile() and ArchGetFileLength(), will not work correctly and more than likely fail. If you are currently using any file system operations on a resolved asset path your code should be updated to use the ArAsset / ArWritableAsset abstractions so you can properly read / write data. See the sections on OpenAsset() / OpenAssetForWrite() for examples on reading / writing.
For details on API breakage, see:
API Breaking Changes: Ar.Resolver: Resolve() Signature Changed
Breaking Change: ResolveWithAssetInfo() Removed
ResolveWithAssetInfo() has been removed and separated into two methods; Resolve() and GetAssetInfo(). GetAssetInfo() accepts an asset path and an ArResolvedPath as input to accurately find all the information related to the asset. The ArResolvedPath can help with asset management systems that might need the identifier, along with the resolved result of that identifier to accurately return the ArAssetInfo with all the correct information.
// In Ar 1.0
// Note that assetPath would typically be the identifier returned from AnchorRelativePath()
const std::string assetPath = "omniverse://some/asset.usd";
ArAssetInfo assetInfo;
const std::string resolvedPath = ArGetResolver().ResolveWithAssetInfo(assetPath, &assetInfo);
// In Ar 2.0
const std::string assetPath = "omniverse://some/asset.usd";
const ArResolvedPath resolvedPath = ArGetResolver().Resolve(assetPath);
ArAssetInfo assetInfo = ArGetResolver().GetAssetInfo(assetPath,
resolvedPath);
For details on API breakage, see:
API Breaking Changes: Ar.Resolver: ResolveWithAssetInfo() Removed
Breaking Change: GetModificationTimestamp() Signature Changed
GetModificationTimestamp() is another method that changes the return type to clarify what was expected to be returned for ArResolver plugin implementations. The return type for GetModificationTimestamp() changed from a VtValue to an ArTimestamp. The ArTimestamp is a more suitable type for external APIs to correctly sort and compare an asset’s modification timestamp due to its guaranteed comparison overload operators. These operators are important for a library such as Sdf to correctly reload layers, since the asset representing the SdfLayer needs to be sorted and compared based on the time the asset was last modified.
// In Ar 1.0
// Note that assetPath would typically be the identifier returned from AnchorRelativePath()
const std::string assetPath = "omniverse://some/asset.usd";
const std::string resolvedPath = ArGetResolver().Resolve(assetPath);
VtValue timestamp = ArGetResolver().GetModificationTimestamp(assetPath,
resolvedPath);
// In Ar 2.0
const std::string assetPath = "omniverse://some/asset.usd";
const ArResolvedPath resolvedPath = ArGetResolver().Resolve(assetPath);
ArTimestamp ts = ArGetResolver().GetModificationTimestamp(assetPath,
resolvedPath);
For details on API breakage, see:
API Breaking Changes: Ar.Resolver: GetModificationTimestamp() Signature Changed
Breaking Change: OpenAsset() and ArAsset Signature Changes
The change will mostly affect ArResolver plugin implementations, but is still a breaking change. OpenAsset() has changed its signature to ensure const-correctness. In Ar 1.0 this seemed like a bug, or oversight, where an ArResolver plugin would modify its own state when opening an asset for reading. This has been corrected in Ar 2.0 to guarantee that OpenAsset() is indeed const and will not modify its own state. The only required change here is for ArResolver plugin implementations to update their function signatures to mark it as const-qualified. This change also allows a const-qualified function to call ArGetResolver().OpenAsset() along with the virtual methods exposed by ArAsset such as GetSize(), GetBuffer(), Read(), etc.
Additionally, the type of resolvedPath has changed from a std::string to an ArResolvedPath.
Using OpenAsset() for reading assets has been supported since Ar 1.0. But now that ArGetResolver().Resolve() no longer assumes a file path on disk being returned, it’s very important to use OpenAsset() when data needs to be read from an asset path. Typical usage can look like the following:
// In Ar 2.0
const std::string assetPath = "omniverse://some/asset.usd";
const ArResolvedPath resolvedPath = ArGetResolver().Resolve(assetPath);
auto asset = ArGetResolver().OpenAsset(resolvedPath);
if (asset) {
// get the buffer to read data into
std::shared_ptr<const char> buffer = asset->GetBuffer();
if (!buffer) {
TF_RUNTIME_ERROR("Failed to GetBuffer()");
return;
}
size_t bytesRead = asset->Read(buffer.get(), asset->GetSize(), 0);
if (bytesRead == 0) {
TF_RUNTIME_ERROR("Failed to read asset");
return;
}
// buffer should now contain bytesRead chars read from resolvedPath
}
For details on API breakage, see:
API Breaking Changes: Ar.Resolver: OpenAsset() / ArAsset Signature Changes
New Feature: OpenAssetForWrite() and ArWritableAsset
One of the big features of Ar 2.0 is the ability to write data directly to the underlying asset management system in an abstracted, and extendable, way. ArGetResolver().OpenAssetForWrite() is a hook in an ArResolver plugin implementation to assist and control how something is written to the asset management system. This new feature allows for things like streaming writes without the need to directly link against custom libraries like client-library. This greatly simplifies the process of getting new assets into asset management systems such as Nucleus, and is natively supported across all of USD through facilities like SdfFileFormat plugins. A very naive implementation could look something like the following:
// In Ar 2.0
const std::string assetPath = "omniverse://some/asset.usd";
// if writing to an existing asset
const ArResolvedPath resolvedPath = ArGetResolver().Resolve(assetPath);
// or if writing to a new asset
const ArResolvedPath resolvedPath = ArGetResolver().ResolveForNewAsset(assetPath);
// create a buffer that contains the data we want to write
const size_t bufferSize = 4096;
std::unique_ptr<char[]> buffer(new char[bufferSize]);
// put some data into the buffer
const std::string data = "some asset data";
memcpy(buffer.get(), data.c_str(), data.length());
// open the asset for writing
auto writableAsset = ArGetResolver().OpenAssetForWrite(resolvedPath, ArResolver::WriteMode::Replace);
if (writableAsset) {
const size_t bytesWritten = writabelAsset->Write(buffer.get(),
data.length(), 0);
if (bytesWritten == 0) {
TF_RUNTIME_ERROR(\"Failed to write asset\");
return;
}
// close out the asset to indicate that all data has been written
asset->Close();
}
New Feature: ArAsset Detached Assets
TODO: This is new as of 22.11 and I () don’t have much experience with it. It sounds like this creates an in-memory copy of the ArAsset so any changes to the original asset doesn’t have any impact on the detached asset. I think this might solve a problem we had at Disney where users performed reads and writes on top of one another due to NFS and not having a robust version control / asset management system like Perforce / Nucleus. This led to all sorts of crashes but creating in-memory copies of assets seems really expensive[Joshua Miller US]
API Breaking Changes
Base
Arch
Arch Filesystem
ArchFile removed
TODO
Tf
pxr Tf Python Module
Reference Commits: |
||
Python Find Regex: |
from +. +import +(.*)[\r\n+]from +pxr +import +Tf[\r\n]+Tf.PrepareModule \( \1 , *locals\(\) *\)[\r\n]+del Tf(?:((?:[\r\n]+.))[\r\n]*try:[\r\n]+([ \t]+)import +__DOC(?:.|\r|\n)*[\r\n]except +Exception:(?:[r\n]+\3.)+)? |
|
Python Replace Regex: |
from pxr import Tf\nTf.PreparePythonModule()\ndel Tf |
|
Python Example Before: |
from . import _usdMdl |
|
Python Example After (22.11+ only): |
from pxr import Tf |
|
Python Example After (branched): |
from pxr import Tf |
|
Python Error Strings: |
ImportError: DLL load while importing {MODULE}: The specified module could not be found. |
PrepareModule to PreparePythonModule
Usd
Ar
Ar Resolver
IsSearchPath() Removed
For a detailed explanation, see: Breaking Change: IsSearchPath() Removed
Reference Commits: |
* [ar 2.0] Add identifier API to ArResolver |
|
C++ Find Regex: |
(?<=\W)IsSearchPath(?=\W) |
|
C++ Error Strings (Linux): |
* ‘class pxrInternal_v0_22__pxrReserved__::ArResolver’ has no member named ‘IsSearchPath’ |
|
C++ Error Strings (Windows): |
* E0135 class “pxrInternal_v0_22__pxrReserved__::ArResolver” has no member “IsSearchPath” |
IsRelativePath() Removed
For a detailed explanation, see: Breaking Change: IsRelativePath() Removed
Reference Commits: |
* [ar 2.0] Add identifier API to ArResolver |
|
C++/Python Find Regex: |
(?<=\W)IsRelativePath(?=\W) |
|
C++ Example Before: |
SdfLayerHandle layer = stage->GetRootLayer(); |
|
C++ Example After (all versions): |
SdfLayerHandle layer = stage->GetRootLayer(); |
|
Python Example Before: |
from pxr import Ar, Usd |
|
Python Example After (all versions): |
from pxr import Ar, Usd |
|
C++ Error Strings (Linux): |
* ‘class pxrInternal_v0_22__pxrReserved__::ArResolver’ has no member named ‘IsRelativePath’ |
|
C++ Error Strings (Windows): |
* E0135 class “pxrInternal_v0_22__pxrReserved__::ArResolver” has no member “IsRelativePath” |
|
Python Error Strings: |
* AttributeError: ‘Resolver’ object has no attribute ‘IsRelativePath’ |
AnchorRelativePath() to CreateIdentifier()
For a detailed explanation, see: Breaking Change: AnchorRelativePath() Renamed
Reference Commits: |
* [ar 2.0] Add identifier API to ArResolver |
|
C++/Python Find Regex: |
(?<=\W)AnchorRelativePath(?=\W) |
|
C++ Example Before: |
const std::string anchor = “omniverse://some/asset.usd”; |
|
C++ Example After (AR2 only): |
const std::string anchor = “omniverse://some/asset.usd”; |
|
C++ Example After (branched): |
const std::string anchor = “omniverse://some/asset.usd”; |
|
Python Example Before: |
from pxr import Ar |
|
Python Example After (AR2 only): |
from pxr import Ar |
|
Python Example After (branched): |
from pxr import Ar |
|
C++ Error Strings (Linux): |
* ‘class pxrInternal_v0_22__pxrReserved__::ArResolver’ has no member named ‘AnchorRelativePath’ |
|
C++ Error Strings (Windows): |
* E0135 class “pxrInternal_v0_22__pxrReserved__::ArResolver” has no member “AnchorRelativePath” |
|
Python Error Strings: |
* AttributeError: ‘Resolver’ object has no attribute ‘AnchorRelativePath’ |
ComputeNormalizedPath() Removed
For a detailed explanation, see: Breaking Change: ComputeNormalizedPath() Removed
Reference Commits: |
* [ar 2.0] Remove ArResolver::ComputeNormalizedPath |
|
C++ Find Regex: |
(?<=\W)ComputeNormalizedPath(?=\W) |
|
C++ Example Before: |
const std::string assetPath = “./geom.usd”; |
|
C++ Example After (AR2 only): |
const std::string assetPath = “./geom.usd”; |
|
C++ Example After (branched): |
const std::string assetPath = “./geom.usd”; |
|
C++ Error Strings (Linux): |
* ‘class pxrInternal_v0_22__pxrReserved__::ArResolver’ has no member named ‘ComputeNormalizedPath’ |
|
C++ Error Strings (Windows): |
* E0135 class “pxrInternal_v0_22__pxrReserved__::ArResolver” has no member “ComputeNormalizedPath” |
ComputeRepositoryPath() Removed
For a detailed explanation, see: Breaking Change: ComputeRepositoryPath() Removed
Reference Commits: |
* [ar 2.0] Remove ArResolver::ComputeNormalizedPath |
|
C++ Find Regex: |
(?<=\W)ComputeNormalizedPath(?=\W) |
|
C++ Example Before: |
const std::string assetPath = “./geom.usd”; |
|
C++ Example After (AR2 only): |
const std::string assetPath = “./geom.usd”; |
|
C++ Example After (branched): |
const std::string assetPath = “./geom.usd”; |
|
C++ Error Strings (Linux): |
* ‘class pxrInternal_v0_22__pxrReserved__::ArResolver’ has no member named ‘ComputeNormalizedPath’ |
|
C++ Error Strings (Windows): |
* E0135 class “pxrInternal_v0_22__pxrReserved__::ArResolver” has no member “ComputeNormalizedPath” |
ComputeLocalPath() Removed
For a detailed explanation, see: Breaking Change: ComputeLocalPath() Removed
Reference Commits: |
* [ar 2.0] Introduce ArResolver::ResolveForNewAsset |
|
C++ Find Regex: |
(?<=\W)ComputeLocalPath(?=\W) |
|
C++ Example Before: |
const std::string assetPath = “omniverse://some/new/asset.usd”; |
|
C++ Example After (AR2 only): |
const std::string assetPath = “omniverse://some/new/asset.usd”; |
|
C++ Example After (branched): |
const std::string assetPath = “omniverse://some/new/asset.usd”; |
|
C++ Error Strings (Linux): |
* ‘class pxrInternal_v0_22__pxrReserved__::ArResolver’ has no member named ‘ComputeLocalPath’ |
|
C++ Error Strings (Windows): |
* E0135 class “pxrInternal_v0_22__pxrReserved__::ArResolver” has no member “ComputeLocalPath” |
Resolve() Signature Changed
For a detailed explanation, see: Breaking Change: Resolve() Signature Changed
Also see: GetResolvedPath return type changed
Reference Commits: |
* [ar 2.0] Update Resolve API on ArResolver |
|
C++/Python Find Regex: |
(?<=\W)Resolve\( |
|
C++ Example Before: |
const std::string assetPath = “omniverse://some/new/asset.usd”; |
|
C++ Example After (AR2 only): |
const std::string assetPath = “omniverse://some/new/asset.usd”; |
|
C++ Example After (all versions): |
const std::string assetPath = “omniverse://some/new/asset.usd”; |
|
Python Example Before: |
NOTE: in most contexts, you will feed the resolves of Resolve() to a function that now expects an Ar.ResolvedPath object, such as ArResolver.CreateIdentifier, so NO CHANGES are needed |
|
Python Example After (all versions): |
from pxr import Ar |
|
C++ Error Strings (Linux): |
* cannot convert ‘const string’ {aka ‘const std::__cxx11::basic_string<char>’} to ‘const pxrInternal_v0_22__pxrReserved__::ArResolvedPath&’ |
|
C++ Error Strings (Windows): |
* E0312 no suitable user-defined conversion from “const std::string” to “const pxrInternal_v0_22__pxrReserved__::ArResolvedPath” exists |
|
Python Error Strings: |
* AttributeError: ‘ResolvedPath’ object has no attribute ‘capitalize’ |
ResolveWithAssetInfo() Removed
For a detailed explanation, see: Breaking Change: ResolveWithAssetInfo() Removed
Reference Commits: |
* [ar 2.0] Update Resolve API on ArResolver |
|
C++/Python Find Regex: |
(?<=\W)ResolveWithAssetInfo(?=\W) |
|
C++ Example Before: |
const std::string assetPath = “omniverse://some/asset.usd”; |
|
C++ Example After (AR2 only): |
const std::string assetPath = “omniverse://some/asset.usd”; |
|
C++ Example After (branched): |
const std::string assetPath = “omniverse://some/asset.usd”; |
|
C++ Error Strings (Linux): |
* ‘class pxrInternal_v0_22__pxrReserved__::ArResolver’ has no member named ‘ResolveWithAssetInfo’ |
|
C++ Error Strings (Windows): |
* C2039 ‘ResolveWithAssetInfo’: is not a member of ‘pxrInternal_v0_22__pxrReserved__::ArResolver’ |
GetModificationTimestamp() Signature Changed
For a detailed explanation, see: Breaking Change: GetModificationTimestamp() Signature Changed
Reference Commits: |
* [ar 2.0] Require Unix time for asset modification times |
|
C++ Find Regex: |
(?<=\W)GetModificationTimestamp(?=\W) |
|
C++ Example Before: |
const std::string assetPath = “omniverse://some/asset.usd”; |
|
C++ Example After (AR2 only): |
const std::string assetPath = “omniverse://some/asset.usd”; |
|
C++ Example After (all versions): |
const std::string assetPath = “omniverse://some/asset.usd”; |
|
C++ Error Strings (Linux): |
* conversion from ‘pxrInternal_v0_22__pxrReserved__::ArTimestamp’ to non-scalar type ‘pxrInternal_v0_22__pxrReserved__::VtValue’ requested |
|
C++ Error Strings (Windows): |
* C2440 ‘initializing’: cannot convert from ‘pxrInternal_v0_22__pxrReserved__::ArTimestamp’ to ‘pxrInternal_v0_22__pxrReserved__::VtValue’ |
OpenAsset() and ArAsset Signature Changes
For a detailed explanation, see: Breaking Change: OpenAsset() / ArAsset Signature Changes
Reference Commits: |
* [ar 2.0] Conform ArResolver::OpenAsset for Ar 2.0 |
|
C++ Find Regex: |
(?<=\W)OpenAsset(?=\W) |
|
C++ Example Before: |
class MyResolver |
|
C++ Example After (AR2 only): |
class MyResolver |
|
C++ Error Strings (Linux): |
* cannot declare variable ‘resolver’ to be of abstract type ‘RESOLVER_SUBCLASS’ |
|
C++ Error Strings (Windows): |
* E0322 object of abstract class type “RESOLVER_SUBCLASS” is not allowed: |
Sdf
Sdf.ChangeBlock
Sdf.ChangeBlock(fastUpdates) to Sdf.ChangeBlock()
OMNIVERSE ONLY
‘fastUpdates’ is an early OV-only prototype and has long been deprecated, and has been removed from the API in nv-usd 22.05, to avoid conflicting with the “enabled” parameter added by Pixar in USD v22.03
Reference Commits: |
* sdf: Rework SdfChangeBlock so that we can avoid tls lookup & atomic ops when closing change blocks that are not the innermost |
|
Python Find Regex: |
(?<=\W)Sdf.ChangeBlock\([^\)]+\) |
|
Python Replace Regex: |
Sdf.ChangeBlock() |
|
C++ Example Before: |
SdfChangeBlock changeBlock(true /* fastUpdates /); |
|
C++ Example After (all versions): |
SdfChangeBlock changeBlock; |
|
Python Example Before: |
from pxr import Sdf |
|
Python Example After (all versions): |
from pxr import Sdf |
|
C++ Error Strings (Linux): |
no matching function for call to ‘pxrInternal_v0_22__pxrReserved__::SdfChangeBlock::SdfChangeBlock(bool)’ |
|
C++ Error Strings (Windows): |
* E0289 no instance of constructor “pxrInternal_v0_22__pxrReserved__::SdfChangeBlock::SdfChangeBlock” matches the argument list |
|
Python Error Strings: |
WARNING |
Sdf Layer
GetResolvedPath return type changed
Also see: Resolve() Signature Changed
TODO
Usd
Usd.CollectionAPI
Reference Commits: |
* UsdCollectionAPI is no longer generated using ‘isPrivateApply = true’ |
|
Python Find Regex: |
(?<=\W)Usd.CollectionAPI.ApplyCollection(?=\W) |
|
Python Replace Regex: |
Usd.CollectionAPI.Apply |
|
Python Example Before: |
from pxr import Usd |
|
Python Example After (20.11+ only): |
from pxr import Usd |
|
Python Example After (branched): |
from pxr import Usd |
|
C++ Error Strings (Linux): |
‘ApplyCollection’ is not a member of ‘pxrInternal_v0_22__pxrReserved__::UsdCollectionAPI’ |
|
C++ Error Strings (Windows): |
* E0135 class “pxrInternal_v0_22__pxrReserved__::UsdCollectionAPI” has no member “ApplyCollection” |
|
Python Error Strings: |
AttributeError: type object ‘CollectionAPI’ has no attribute ‘ApplyCollection’. Did you mean: ‘BlockCollection’? |
ApplyCollection to Apply
Usd Prim
“Master” to “Prototype”
IsMasterPath to IsPrototypePath
IsPathInMaster to IsPathInPrototype
IsMaster to IsPrototype
IsInMaster to IsInPrototype
GetMaster to GetPrototype
GetPrimInMaster to GetPrimInPrototype
Reference Commits: |
* Deprecate “master” API in favor of new “prototype” API on UsdPrim |
|
Python/C++ Find Regex: |
(?<=\W)(?:(IsPathIn|Is|IsIn|Get|GetPrimIn)Master|(Is)Master(Path))(?=\W) |
|
Python/C++ Replace Regex: |
$1$2Prototype$3 |
|
C++ Example Before: |
if (UsdPrim::IsMasterPath(SdfPath(“/myPath”))) { TF_WARN(”…”);} |
|
C++ Example After (22.11+ only): |
if (UsdPrim::IsPrototypePath(SdfPath(“/myPath”))) { TF_WARN(”…”);} |
|
C++ Example After (branched): |
#if PXR_VERSION >= 2011 |
|
Python Example Before: |
from pxr import Usd |
|
Python Example After (20.11+ only): |
from pxr import Usd |
|
Python Example After (branched): |
from pxr import Usd |
|
C++ Error Strings (Linux): |
* ‘IsMasterPath’ is not a member of ‘pxrInternal_v0_22__pxrReserved__::UsdPrim’ |
|
C++ Error Strings (Windows): |
* E0135 class “pxrInternal_v0_22__pxrReserved__::UsdPrim” has no member “IsMasterPath” |
|
Python Error Strings: |
* AttributeError: type object ‘Prim’ has no attribute ‘IsMasterPath’ |
GetAppliedSchemas: Now filters out non-existent schemas
To get the list of apiSchema tokens that are authored on the prim (whether they exists or not), use GetPrimTypeInfo().GetAppliedAPISchemas()
Reference Commits: |
* Refactoring some of the functionality in UsdPrimDefinition for how we build prim definitions… There’s also one minor functional change in that API schema names that can’t be mapped to a valid prim definition are no longer included in the composed API schema list of a UsdPrimDefinition that is built with them |
|
Python/C++ Find Regex: |
.GetAppliedAPISchemas\(\) |
|
Python/C++ Replace Regex: |
.GetPrimTypeInfo().GetAppliedAPISchemas() |
|
C++ Example Before: |
auto appliedSchemas = usdPrim.GetAppliedSchemas(); |
|
C++ Example After: |
auto appliedSchemas = usdPrim.GetPrimTypeInfo().GetAppliedAPISchemas(); |
|
Python Example Before: |
# In v21.08, this will print |
|
Python Example After (all versions): |
# In both v21.08 + v21.11, this will print |
Usd SchemaRegistry
SchemaType to SchemaKind
For a detailed explanation, see: Breaking Change: Schema Kind
Reference Commits: |
* UsdSchemaRegistry can now query about schema kind from the schemaKind plugInfo metadata that is generated by usdGenSchema for schema types. This is directly exposed through the new GetSchemaKind functions added to UsdSchemaRegistry. |
|
C++/Python Find Regex: |
SchemaType |
|
C++/Python Replace Regex: |
SchemaKind |
|
Python Example Before: |
from pxr import Usd, UsdGeom |
|
Python Example After (21.02+ only): |
from pxr import Usd, UsdGeom |
|
Python Example After (branched): |
from pxr import Usd, UsdGeom |
|
C++ Error Strings (Linux): |
* ‘UsdSchemaType’ has not been declared |
|
C++ Error Strings (Windows): |
* E0135 class “pxrInternal_v0_22__pxrReserved__::UsdAPISchemaBase” has no member “schemaType” |
|
Python Error Strings: |
* AttributeError: ‘Animation’ object has no attribute ‘GetSchemaType’. Did you mean: ‘GetSchemaKind’? |
Property Names of MultipleApply Schemas now namespaced in schema spec
ie, the schema spec for CollectionAPI’s “includes” relationship was formerly just includes
Now, it includes a template for the instance name, and is:
collection:__INSTANCE_NAME__:includes
Use Usd.SchemaRegistry.GetMultipleApplyNameTemplateBaseName(propertySpec.name) to return just the “includes” portion, as before.
Functions for dealing with the new templated names can be found in [UsdSchemaRegistry]:
Reference Commits: |
||
Python Example Before: |
from pxr import Usd |
|
Python Example After (22.03+ only): |
from pxr import Usd |
|
Python Example After (branching): |
from pxr import Usd |
Usd.Stage
GetMasters to GetPrototypes
Reference Commits: |
* Deprecate “master” API in favor of new “prototype” API on UsdStage |
|
C++/Python Find Regex: |
(?<=\W)GetMasters(?=\W) |
|
C++/Python Replace Regex: |
GetPrototypes |
|
C++ Example Before: |
for (auto const& master : myStage->GetMasters()) |
|
C++ Example After (20.11+ only): |
for (auto const& prototype : myStage->GetPrototypes()) |
|
C++ Example After (branched): |
#if PXR_VERSION >= 2011 |
|
C++ Error Strings (Linux): |
* ‘class pxrInternal_v0_22__pxrReserved__::UsdStage’ has no member named ‘GetMasters’ |
|
C++ Error Strings (Windows): |
* E0135 class “pxrInternal_v0_22__pxrReserved__::UsdStage” has no member “GetMasters” |
|
Python Error Strings: |
AttributeError: ‘Stage’ object has no attribute ‘GetMasters’ |
UsdGeom
UsdGeom.Imageable
UsdGeomImageable has removed convenience APIs for accessing primvars
Primvars for derived types of UsdGeomImageage, such as UsdGeomMesh, must be accessed through the UsdGeomPrimvarsAPI
Reference Commits: |
||
C++ Example Before: |
PXR_NS::UsdStageRefPtr stage = PXR_NS::UsdStage::Open(boxUrl); |
|
C++ Example After: |
PXR_NS::UsdStageRefPtr stage = PXR_NS::UsdStage::Open(boxUrl); |
|
C++ Error Strings (Windows): |
* error C2039: ‘HasPrimvar’: is not a member of ‘pxrInternal_v0_22__pxrReserved__::UsdGeomGprim’ |
|
C++ Error Strings (Linux): |
* ‘HasPrimvar’: is not a member of ‘pxrInternal_v0_22__pxrReserved__::UsdGeomGprim’ |
UsdGeom Subset
Material bindings authored on GeomSubsets are honored by renderers only if their familyName is UsdShadeTokens->materialBind. This allows robust interchange of subset bindings between multiple DCC apps. See more at [OM-32124].
Assets can be repaired via the Asset Validator extension, see [UsdMaterialBindingApi].
Reference Commits: |
UsdLux
All properties now prefixed with "inputs:"
… including shaping and shadow attributes
Assets can be repaired via the Asset Validator extension, see [UsdLuxSchemaChecker]
Property Name Changes, By Schema:
Light:
intensity to inputs:intensity
exposure to inputs:exposure
diffuse to inputs:diffuse
specular to inputs:specular
normalize to inputs:normalize
color to inputs:color
enableColorTemperature to inputs:enableColorTemperature
colorTemperature to inputs:colorTemperature
DistantLight:
angle to inputs:angle
DiskLight:
radius to inputs:radius
RectLight:
width to inputs:width
height to inputs:height
texture:file to inputs:texture:file
SphereLight:
radius to inputs:radius
CylinderLight:
length to inputs:length
radius to inputs:radius
DomeLight:
texture:file to inputs:texture:file
texture:format to inputs:texture:format
ShapingAPI:
shaping:focus to inputs:shaping:focus
shaping:focusTint to inputs:shaping:focusTint
shaping:cone:angle to inputs:shaping:cone:angle
shaping:cone:softness to inputs:shaping:cone:softness
shaping:ies:file to inputs:shaping:ies:file
shaping:ies:angleScale to inputs:shaping:ies:angleScale
shaping:ies:normalize to inputs:shaping:ies:normalize
ShadowAPI:
shadow:enable to inputs:shadow:enable
shadow:color to inputs:shadow:color
shadow:distance to inputs:shadow:distance
shadow:falloff to inputs:shadow:falloff
shadow:falloffGamma to inputs:shadow:falloffGamma
UsdLuxTokens name changes:
angle to inputsAngle
color to inputsColor
colorTemperature to inputsColorTemperature
diffuse to inputsDiffuse
enableColorTemperature to inputsEnableColorTemperature
exposure to inputsExposure
height to inputsHeight
intensity to inputsIntensity
length to inputsLength
normalize to inputsNormalize
radius to inputsRadius
shadowColor to inputsShadowColor
shadowDistance to inputsShadowDistance
shadowEnable to inputsShadowEnable
shadowFalloff to inputsShadowFalloff
shadowFalloffGamma to inputsShadowFalloffGamma
shapingConeAngle to inputsShapingConeAngle
shapingConeSoftness to inputsShapingConeSoftness
shapingFocus to inputsShapingFocus
shapingFocusTint to inputsShapingFocusTint
shapingIesAngleScale to inputsShapingIesAngleScale
shapingIesFile to inputsShapingIesFile
shapingIesNormalize to inputsShapingIesNormalize
specular to inputsSpecular
textureFile to inputsTextureFile
textureFormat to inputsTextureFormat
width to inputsWidth
Reference Commits: |
* Updated the schema in usdLux to have all attributes of Light and its inherited types use the “inputs:” prefix (with the exception of treatAsLine and treatAsPoint) |
|
C++/Python Find Regex: |
(?<=UsdLux.Tokens.|UsdLuxTokens->)(angle|color|colorTemperature|diffuse|enableColorTemperature|exposure|height|intensity|length|normalize|radius|shadowColor|shadowDistance|shadowEnable|shadowFalloff|shadowFalloffGamma|shapingConeAngle|shapingConeSoftness|shapingFocus|shapingFocusTint|shapingIesAngleScale|shapingIesFile|shapingIesNormalize|specular|textureFile|textureFormat|width)(?=\W) |
|
Python Example Before: |
print(UsdLux.Tokens.angle) |
|
Python Example After (21.02+ only): |
from pxr import UsdLux |
|
Python Example After (branched): |
from pxr import UsdLux |
|
C++ Error Strings (Linux): |
* ‘struct pxrInternal_v0_22__pxrReserved__::UsdLuxTokensType’ has no member named ‘angle’; did you mean ‘angular’\? |
|
C++ Error Strings (Windows): |
* E0135 class “pxrInternal_v0_22__pxrReserved__::UsdLuxTokensType” has no member “angle” |
|
Python Error Strings: |
* AttributeError: type object ‘Tokens’ has no attribute ‘angle’ |
UsdLux.Light
UsdLux Light to UsdLuxLightAPI
Reference Commits: |
* Creates the new single apply UsdLuxLightAPI applied API schema in preparation for migrating lights to having an applied LightAPI |
|
C++/Python Find Regex: |
(?<=\W)Usd(?:.)LuxLight(?=\W) |
|
C++ Example Before: |
auto myStage = UsdStage::CreateInMemory(); |
|
C++ Example After (21.11+ only): |
auto myStage = UsdStage::CreateInMemory(); |
|
C++ Example After (branched): |
auto myStage = UsdStage::CreateInMemory(); |
|
C++ Error Strings (Linux): |
* ‘class pxrInternal_v0_22__pxrReserved__::UsdLuxCylinderLight’ has no member named ‘GetLightLinkCollectionAPI’ |
|
C++ Error Strings (Windows): |
* C2039 ‘GetLightLinkCollectionAPI’: is not a member of ‘pxrInternal_v0_22__pxrReserved__::UsdLuxCylinderLight’ |
|
Python Error Strings: |
* AttributeError: module ‘pxr.UsdLux’ has no attribute ‘Light’ |
UsdLux LightPortal to UsdLux PortalLight
TODO
UsdLuxLight.ComputeBaseEmission() removed
This function existed “solely as a reference example implementation of how to interpret [UsdLuxLight’s] parameters.” It has been removed, and there is no replacement. If you were making use of it, you will have to add your own implementation - this function would duplicate the old behavior:
GfVec3f ComputeBaseEmission(const UsdLuxLightAPI& light)
{
GfVec3f e(1.0);
float intensity = 1.0;
light.GetIntensityAttr().Get(&intensity);
e *= intensity;
float exposure = 0.0;
light.GetExposureAttr().Get(&exposure);
e *= exp2(exposure);
GfVec3f color(1.0);
light.GetColorAttr().Get(&color);
e = GfCompMult(e, color);
bool enableColorTemp = false;
light.GetEnableColorTemperatureAttr().Get(&enableColorTemp);
if (enableColorTemp) {
float colorTemp = 6500;
if (light.GetColorTemperatureAttr().Get(&colorTemp)) {
e = GfCompMult(e, UsdLuxBlackbodyTemperatureAsRgb(colorTemp));
}
}
return e;
}
Reference Commits: |
||
C++/Python Find Regex: |
(?<=\W)ComputeBaseEmission(?=\W) |
|
C++ Error Strings (Linux): |
* ‘class pxrInternal_v0_22__pxrReserved__::UsdLuxCylinderLight’ has no member named ‘ComputeBaseEmission’ |
|
C++ Error Strings (Windows): |
* E0135 class “pxrInternal_v0_22__pxrReserved__::UsdLuxCylinderLight” has no member “ComputeBaseEmission” |
|
Python Error Strings: |
* AttributeError: ‘CylinderLight’ object has no attribute ‘ComputeBaseEmission’ |
UsdLux.LightFilterAPI removed
UsdPhysics
UsdPhysics Schema Changes
UsdPhysics uses USD stock schema.
Reference Commits: |
||
C++ Example Before: |
#include <usdPhysics/tokens.h> |
|
C++ Example After (all versions): |
#include <pxr/usd/usdPhysics/tokens.h> |
|
C++ Error Strings |
* Cannot open include file: ‘usdPhyiscs/articulationRootAPI.h’: No such file or directory |
UsdRender
UsdRender.SettingsAPI
UsdRender SettingsAPI removed
TODO
UsdShade
UsdShade.ConnectableAPI
Explicit ctor required for shaders and nodegraphs
See also: https://groups.google.com/g/usd-interest/c/I7gY7LpNkjw/m/Zjm7gFVUBgAJ
Reference Commits: |
||
Python Example Before: |
material.CreateSurfaceOutput().ConnectToSource(shader, “out”) |
|
Python Example After (all versions): |
material.CreateSurfaceOutput().ConnectToSource(shader.ConnectableAPI(), “out”) |
|
C++ Error Strings (Linux): |
* no known conversion for argument 1 from ‘pxrInternal_v0_22__pxrReserved__::UsdShadeMaterial’ to ‘const pxrInternal_v0_22__pxrReserved__::UsdShadeConnectableAPI&’ |
|
C++ Error Strings (Windows): |
* E0304 no instance of overloaded function “pxrInternal_v0_22__pxrReserved__::UsdShadeConnectableAPI::ConnectToSource” matches the argument list |
|
Python Error Strings: |
* Boost.Python.ArgumentError: Python argument types in |
IsNodeGraph replaced with IsContainer
Reference Commits: |
* UsdShade: Add a concept of “containers” for connectable nodes. |
|
C++/Python Find Regex: |
(?<=\W)IsNodeGraph(?=\W) |
|
C++/Python Replace Regex: |
IsContainer |
|
Python Example Before: |
from pxr import Usd, UsdShade |
|
Python Example After (21.02+ only): |
from pxr import Usd, UsdShade |
|
Python Example After (branched): |
from pxr import Usd, UsdShade |
|
C++ Error Strings (Linux): |
* ‘class pxrInternal_v0_22__pxrReserved__::UsdShadeConnectableAPI’ has no member named ‘IsNodeGraph’ |
|
C++ Error Strings (Windows): |
* E0135 class “pxrInternal_v0_22__pxrReserved__::UsdShadeConnectableAPI” has no member “IsNodeGraph” |
|
Python Error Strings: |
* AttributeError: ‘ConnectableAPI’ object has no attribute ‘IsNodeGraph’ |
UsdShade.MaterialBindingAPI
Material bindings require UsdShadeMaterialBindingAPI to be applied
All code which authors material bindings should Apply() UsdShadeMaterialBindingAPI to the prim upon which the binding is to be authored
Current default is to post warnings at runtime, but still apply material bindings if is not applied
May set USD_SHADE_MATERIAL_BINDING_API_CHECK env var to change behavior:
allowMissingAPI
silence warnings and apply materials even if MaterialBindingAPI not applied
warnOnMissingAPI
current default
print warnings, but still apply materials even if MaterialBindingAPI not applied
strict
future default
only apply material bindings if MaterialBindingAPI applied
Assets can be repaired via the Asset Validator extension, see UsdMaterialBindingApi.
Reference Commits: |
* BindingAtPrim should return early if the prim doesn’t have a MaterialBindingAPI Applied. |
|
Runtime Warning Strings: |
* Found material bindings on prim at path (%s) but MaterialBindingAPI is not applied on the prim |
UsdSkel
UsdSkel Cache
Populate/ComputeSkelBinding/ComputeSkelBindings now require a predicate parameter
To maintain the same behavior, pass UsdPrimDefaultPredicate as the predicate; if you wish to allow instancing of skeletons, use UsdTraverseInstanceProxies instead
Reference Commits: |
||
C++/Python Find Regex: |
(?<=.|->)(Populate|ComputeSkelBindings?)\( |
|
Python Example Before: |
from pxr import Usd, UsdSkel |
|
Python Example After (21.02+ only): |
from pxr import Usd, UsdSkel |
|
Python Example After (branched): |
from pxr import Usd, UsdSkel |
|
C++ Error Strings (Linux): |
* no matching function for call to ‘pxrInternal_v0_22__pxrReserved__::UsdSkelCache::ComputeSkelBinding(pxrInternal_v0_22__pxrReserved__::UsdSkelRoot&, pxrInternal_v0_22__pxrReserved__::UsdSkelSkeleton&, pxrInternal_v0_22__pxrReserved__::UsdSkelBinding*)’ |
|
C++ Error Strings (Windows): |
* C2660 ‘pxrInternal_v0_22__pxrReserved__::UsdSkelCache::Populate’: function does not take 1 arguments |
|
Python Error Strings: |
* Boost.Python.ArgumentError: Python argument types in |
Imaging
Glf
Removed glew dependency
Reference Commits: |
||
C++ Find Regex: |
(?<=\W)(GLEW|Glew|glew)(?=\W|_) |
|
C++ Example Before: |
// Generally code will include one or the other of these, not both - they are |
|
C++ Example After (21.02+ only): |
#include “pxr/imaging/garch/glApi.h” |
|
C++ Example After (branched): |
#if PXR_VERSION >= 2102 |
|
C++ Error Strings (Linux): |
* pxr/imaging/glf/glew.h: No such file or directory |
|
C++ Error Strings (Windows): |
* E1696 cannot open source file “pxr/imaging/glf/glew.h” |
|
Python Error Strings: |
* AttributeError: module ‘pxr.Glf’ has no attribute ‘GlewInit’ |
Other Breaking Changes
Schemas
pluginInfo.json
plugInfo json now requires schemaKind field
Without it, schemas may silently fail to load.
For more information on schemaKind, see: [Breaking Change: Schema Kind]
TODO: more investigation / details
https://nvidia.slack.com/archives/C04190ZMT6U/p1677673185286159
https://nvidia.slack.com/archives/C04190ZMT6U/p1678264560240499
Python Error Strings: |
* ‘ApplyAPI: Provided schema type ‘<SCHEMA_NAME>’ is not a single-apply API schema type.’ |
Non-Breaking Changes
Imaging
Hdx
Hdx TaskController
Added HdxTaskController SetPresentationOutput
It seems that when SetPresentationOutput was originally added in 22.05, calling it from UsdImagingGLEngine / omni.hydra.pxr’s SimpleUsdGLEngine.cpp may have been required, but in 22.08 the functionality was moved to HgiInteropOpenGL
Upgrading assets and test files
The previous sections cover most of the changes you need to perform to your code base, i.e. C++, Python files, as well as compilation and interpretation errors. After following the previous fixes you may still find that your assets or test files (i.e. your USDs) have stopped working.
We have implemented forward compatibility tests in Omni Asset Validation. This is an extension implemented in Kit, at the moment of writing this document (03/23/2023) the latest version is 0.3.2. Please refer to the documentation on how to quickly use it with the graphical user interface.
For the scope of this document, please select the Rules of the category USD Schema. Those rules will help you out to fix all your documents. Below you will find some of the common problem:
UsdGeomSubsetChecker
Problems |
* GeomSubset has a material binding but no valid family name attribute. |
|
See |
||
Resolution |
* Enable USD Schema / UsdGeomSubsetChecker. |
UsdLuxSchemaChecker
Problems |
* UsdLux attribute has been renamed to USD 21.02 and should be prefixed with ‘inputs:’. |
|
See |
||
Resolution |
* Enable USD Schema / UsdLuxSchemaChecker. |
UsdMaterialBindingApi
Problems |
* Prim has a material binding but does not have the MaterialBindingApi. |
|
See |
* Material bindings require UsdShadeMaterialBindingAPI to be applied |
|
Resolution |
* Enable USD Schema / UsdMaterialBindingApi. |
UsdDanglingMaterialBindingApi
Problems |
* Prim has a material binding but the material binding is not found in the stage. The stage may not render properly. Example: https://nvidia-omniverse.atlassian.net/browse/OM-87439 |
|
See |
* Material bindings require UsdShadeMaterialBindingAPI to be applied |
|
Resolution |
* Enable USD Schema / UsdDanglingMaterialBindingApi. |
Dumping Ground
A place for extra notes / incomplete items that we don’t want to forget
Schemas removed
UsdLuxLight
UsdLuxLightPortal
UsdMdlMdlAPI
UsdRenderSettingsAPI
UsdRiLightAPI
UsdRiLightFilterAPI
UsdRiLightPortalAPI
UsdRiPxrAovLight
UsdRiPxrBarnLightFilter
UsdRiPxrCookieLightFilter
UsdRiPxrEnvDayLight
UsdRiPxrIntMultLightFilter
UsdRiPxrRampLightFilter
UsdRiPxrRodLightFilter
UsdRiRiLightFilterAPI
UsdRiRisBxdf
UsdRiRisIntegrator
UsdRiRisObject
UsdRiRisOslPattern
UsdRiRisPattern
UsdRiRslShader
UsdRiTextureAPI
Schemas added
UsdGeomPlane
UsdGeomVisibilityAPI
UsdHydraGenerativeProceduralAPI
UsdLuxBoundableLightBase
UsdLuxLightAPI
UsdLuxLightListAPI
UsdLuxMeshLightAPI
UsdLuxNonboundableLightBase
UsdLuxPluginLight
UsdLuxPluginLightFilter
UsdLuxPortalLight
UsdLuxVolumeLightAPI
UsdMdlAPIMdlAPI
UsdPhysicsArticulationRootAPI
UsdPhysicsCollisionAPI
UsdPhysicsCollisionGroup
UsdPhysicsDistanceJoint
UsdPhysicsDriveAPI
UsdPhysicsFilteredPairsAPI
UsdPhysicsFixedJoint
UsdPhysicsJoint
UsdPhysicsMassAPI
UsdPhysicsMaterialAPI
UsdPhysicsMeshCollisionAPI
UsdPhysicsPrismaticJoint
UsdPhysicsRevoluteJoint
UsdPhysicsRigidBodyAPI
UsdPhysicsScene
UsdPhysicsSphericalJoint
UsdRenderDenoisePass
UsdRenderPass
UsdShadeNodeDefAPI