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:

  • SchemaResolverNewton
  • SchemaResolverPhysx
  • SchemaResolverMjc

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_stage option respects the stage’s authored up-axis.
  • MuJoCo option parsing: The parse_mujoco_options flag 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_usd method in newton/_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.Stage object, 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.py translate 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →