Loading OpenUSD Scenes and Performing Format Conversions in Newton: A Complete Guide
Newton's ModelBuilder.add_usd function imports OpenUSD scenes and automatically converts physics attributes, geometry, and solver-specific metadata into Warp-compatible simulation data.
Newton, an open-source physics simulation framework developed by newton-physics, provides a robust pipeline for loading OpenUSD scenes and performing format conversions. The ModelBuilder.add_usd method in newton/_src/sim/builder.py serves as the primary entry point, handling everything from stage acquisition to rigid-body creation while preserving solver-specific attributes from PhysX, MuJoCo, or custom schemas.
How Newton Imports OpenUSD Scenes via ModelBuilder.add_usd
The core import logic resides in ModelBuilder.add_usd (lines 2199–2265 of newton/_src/sim/builder.py). This method treats a USD file or an already-opened Usd.Stage as a complete description of one or more rigid-body articulations.
Stage Acquisition and Root Transform Handling
When add_usd is called, Newton first acquires the USD stage. If the source argument is a string, Newton opens the file via Usd.Stage.Open (or a URL). If it is already a UsdStage object, the stage is reused.
An optional xform (a newton.Transform) is either composed with the articulation’s root transform or, when override_root_xform=True, replaces it entirely. This lets you clone an articulation at a specific pose without moving any of its internal geometry.
Schema Resolution for Solver-Specific Attributes
Newton ships with three built-in resolvers that know how to read solver-specific attributes from USD prims:
SchemaResolverNewtonSchemaResolverPhysxSchemaResolverMjc
These classes are defined in newton/_src/usd/schema_resolver.py and registered in newton/_src/usd/schemas.py. Users can pass a custom list via the schema_resolvers argument to collect additional namespaced attributes; the result is returned in the "schema_attrs" entry of the mapping returned by add_usd.
Attribute Conversion to Warp Types
Low-level helpers in newton/_src/usd/utils.py translate USD scalar, vector, and quaternion attributes into Warp-compatible values (float, wp.vec3, wp.quat). For example, get_quat reads a quaternion attribute and returns a wp.quat in Newton’s internal x, y, z, w ordering.
Converting USD Physics Data to Newton Simulation Elements
Once attributes are resolved and converted, add_usd iterates over the stage prims to instantiate simulation objects.
Rigid Bodies and Inertia Tensors
Rigid bodies are added for each prim that implements the PhysicsRigidBodyAPI. Their mass and inertia are read from physics:mass and physics:inertiaTensor, with the latter converted to a wp.mat33. The newton:selfCollisionEnabled flag is applied if present.
Joints and Articulation Hierarchies
Joints are created from PhysicsJointAPI prims. The floating, base_joint, and parent_body arguments control how the root body attaches to the world or to an existing body. This enables complex articulation hierarchies where a USD scene is grafted onto an existing simulation.
Collision Geometry and Mesh Approximation
Collision and visual geometry is extracted from UsdGeom prims. Meshes can be approximated to convex hulls using the mesh_maxhullvert parameter, skipped entirely with skip_mesh_approximation, or forced to be visible with force_show_colliders.
Post-Processing and Scene Optimization
After instantiation, Newton applies several optimization passes:
- Fixed-joint collapse: When
collapse_fixed_joints=True, bodies connected by fixed joints are merged, and a"collapse_results"dictionary is returned detailing the merges. - Up-axis handling: The
apply_up_axis_from_stageoption respects the stage’s authored up-axis. - MuJoCo option parsing: The
parse_mujoco_optionsflag processes MuJoCo-specific compiler and option attributes.
The method returns a dictionary containing meta-information (FPS, duration, up-axis, unit scaling) and mapping tables from USD prim paths to Newton body/joint/shape indices. These mappings enable downstream inspection or custom processing of the imported scene.
Practical Code Examples for OpenUSD Integration
The following examples demonstrate common workflows for loading OpenUSD scenes and performing format conversions in Newton.
import newton as nx
# 1. Simple USD import – load the built‑in bunny asset.
builder = nx.ModelBuilder()
usd_path = nx.examples.get_asset("bunny.usd") # helper that returns a local path
result = builder.add_usd(usd_path, floating=True) # FREE joint at world root
print("Imported bodies:", result["path_body_map"].keys())
# 2. Apply a transform and override the root pose.
builder = nx.ModelBuilder()
stage = nx.usd.Usd.Stage.Open(usd_path) # low‑level USD API
builder.add_usd(
stage,
xform=nx.transform(wp.vec3(1.0, 0.0, 0.5), wp.quat_identity()),
override_root_xform=True,
collapse_fixed_joints=True,
)
# 3. Custom schema resolver to capture PhysX‑specific attributes.
from newton._src.usd.schema_resolver import SchemaResolverPhysx
builder = nx.ModelBuilder()
result = builder.add_usd(
usd_path,
schema_resolvers=[nx.usd.SchemaResolverNewton(),
SchemaResolverPhysx()], # include PhysX attrs
)
print("PhysX attrs found:", result["schema_attrs"])
# 4. Skipping mesh approximation and disabling collision‑shape visibility.
builder = nx.ModelBuilder()
builder.add_usd(
usd_path,
skip_mesh_approximation=True,
force_show_colliders=False,
hide_collision_shapes=True,
)
Key Source Files and Architecture
Understanding the source layout helps when extending or debugging the OpenUSD import pipeline.
| File | Role | Link |
|---|---|---|
newton/usd.py |
Public façade exposing utility functions and schema resolver types used by ModelBuilder.add_usd. |
https://github.com/newton-physics/newton/blob/main/newton/usd.py |
newton/_src/sim/builder.py |
Core implementation of ModelBuilder.add_usd and all related import logic. |
https://github.com/newton-physics/newton/blob/main/newton/_src/sim/builder.py |
newton/_src/usd/utils.py |
Low‑level helpers for reading USD attributes and converting them to Warp types. | https://github.com/newton-physics/newton/blob/main/newton/_src/usd/utils.py |
newton/_src/usd/schema_resolver.py |
Abstract base and concrete resolver classes that map USD attribute namespaces to Newton data structures. | https://github.com/newton-physics/newton/blob/main/newton/_src/usd/schema_resolver.py |
newton/_src/usd/schemas.py |
Registers the built‑in resolvers (Newton, Physx, Mjc) and defines the priority order. |
https://github.com/newton-physics/newton/blob/main/newton/_src/usd/schemas.py |
Summary
- Primary entry point: The
ModelBuilder.add_usdmethod innewton/_src/sim/builder.py(lines 2199–2265) handles the complete OpenUSD import pipeline. - Flexible stage input: Accepts either a file path string or an existing
Usd.Stageobject, automatically handling URL resolution and stage reuse. - Solver-agnostic schemas: Built-in resolvers for Newton, PhysX, and MuJoCo attributes preserve domain-specific metadata in the
"schema_attrs"dictionary. - Automatic conversion: Low-level utilities in
newton/_src/usd/utils.pytranslate USD scalars, vectors, and quaternions into Warp-native types (wp.vec3,wp.quat,wp.mat33). - Optimization options: Fixed-joint collapse, mesh convex-hull approximation, and up-axis correction are applied as post-processing steps.
Frequently Asked Questions
What USD schemas does Newton support out of the box?
Newton natively supports PhysicsRigidBodyAPI, PhysicsJointAPI, and UsdGeom prims. Through the built-in schema resolvers—SchemaResolverNewton, SchemaResolverPhysx, and SchemaResolverMjc—it also captures solver-specific attributes from PhysX, MuJoCo, and custom newton:* namespaces.
How do I preserve PhysX-specific attributes when loading a USD scene?
Pass a custom list of schema resolvers to add_usd that includes SchemaResolverPhysx from newton._src.usd.schema_resolver. The function returns a dictionary containing "schema_attrs", which maps prim paths to the captured PhysX metadata.
Can I override the root transform of an imported articulation without modifying internal geometry?
Yes. Use the xform argument to provide a newton.Transform, and set override_root_xform=True. This replaces the articulation’s root pose entirely, allowing you to instantiate the same USD asset at different locations without altering the relative transforms of its internal bodies or joints.
How does Newton handle mesh geometry from USD for collision detection?
Newton extracts vertices and indices from UsdGeom.Mesh prims and converts them to Warp-compatible wp.vec3 arrays. By default, it can approximate meshes to convex hulls using the mesh_maxhullvert parameter. You can disable approximation with skip_mesh_approximation=True or control visibility with force_show_colliders and hide_collision_shapes.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →