Converting Newton Simulations to USD Format for Visualization

Use ModelBuilder.add_usd() to import any USD stage into Newton, leveraging built-in schema resolvers to automatically map physics attributes from Newton, PhysX, or MuJoCo schemas while controlling visualization through flags like load_visual_shapes and load_sites.

Converting Newton simulations to USD format for visualization is handled through the high-level import pipeline provided by the newton-physics/newton repository. The framework's ModelBuilder.add_usd API parses a USD stage—or a path/URL to a USD file—and automatically creates the corresponding Newton bodies, shapes, joints, sites, and visual geometry. This enables seamless integration of external USD assets into Newton's physics simulation environment for immediate visualization and analysis.

Understanding the USD Import Pipeline

The conversion process operates in three distinct stages that transform USD prims into Newton simulation entities.

The Three-Stage Conversion Process

  1. USD Loading: The system opens a Usd.Stage from a file path, URL, or existing stage object. The helper resolve_usd_from_url in newton/_src/utils/import_usd.py handles path resolution and optional conversion to USDA format.

  2. Schema Resolution: Low-level helpers in newton.usd utilize SchemaResolver classes to read physics-specific attributes. The resolvers extract Newton-specific (newton:*), PhysX-specific (physx*), and MuJoCo-specific (mjc:*) attributes from USD prims.

  3. Builder Population: The parsed data feeds into ModelBuilder to create simulation entities. This stage respects optional flags such as load_sites, collapse_fixed_joints, apply_up_axis_from_stage, and enable_self_collisions.

Key Source Files and Architecture

The core implementation resides in two primary locations:

  • newton/_src/sim/builder.py (lines 2199-2265): Contains the ModelBuilder.add_usd method implementation, handling stage acquisition, transform composition, and entity creation loops.

  • newton/usd.py (lines 25-84): Public API exposing utility functions and the three built-in schema resolvers: SchemaResolverNewton, SchemaResolverPhysx, and SchemaResolverMjc.

Additional utility functions for mesh conversion and attribute extraction reside in newton/_src/usd/schema_resolver.py and newton/_src/utils/import_usd.py.

Using ModelBuilder.add_usd for USD Conversion

The primary entry point for converting USD to Newton simulations is the add_usd method of ModelBuilder.

Method Signature and Parameters

def add_usd(
    self,
    source: str | UsdStage,
    *,
    xform: Transform | None = None,
    floating: bool | None = None,
    base_joint: dict | None = None,
    parent_body: int = -1,
    only_load_enabled_rigid_bodies: bool = False,
    only_load_enabled_joints: bool = True,
    joint_drive_gains_scaling: float = 1.0,
    verbose: bool = False,
    ignore_paths: list[str] | None = None,
    collapse_fixed_joints: bool = False,
    enable_self_collisions: bool = True,
    apply_up_axis_from_stage: bool = False,
    root_path: str = "/",
    joint_ordering: Literal["bfs", "dfs"] | None = "dfs",
    bodies_follow_joint_ordering: bool = True,
    skip_mesh_approximation: bool = False,
    load_sites: bool = True,
    load_visual_shapes: bool = True,
    hide_collision_shapes: bool = False,
    force_show_colliders: bool = False,
    parse_mujoco_options: bool = True,
    mesh_maxhullvert: int | None = None,
    schema_resolvers: list[SchemaResolver] | None = None,
    force_position_velocity_actuation: bool = False,
    override_root_xform: bool = False,
) -> dict[str, Any]:
    ...

Key parameters for visualization control include:

  • load_visual_shapes: Imports visual-only meshes for rendering.
  • load_sites: Imports MuJoCo site primitives as Newton sites.
  • hide_collision_shapes / force_show_colliders: Controls visibility of collision geometry.
  • apply_up_axis_from_stage: Automatically respects the USD stage's up-axis (Y or Z).
  • xform: Applies a global transform to the imported stage.

Return Value Structure

The method returns a dictionary containing rich metadata about the imported scene:

Key Description
fps Frames-per-second of the USD stage
duration Time span of the stage
up_axis Detected up-axis (X, Y, or Z)
path_body_map / path_joint_map / path_shape_map Mappings from USD prim paths to Newton indices
mass_unit / linear_unit Unit scaling from USD metadata
scene_attributes Attributes applied to the PhysicsScene prim
collapse_results Information about fixed-joint collapsing
schema_attrs Collected schema-specific attributes

Schema Resolvers and Attribute Mapping

Newton supports multiple physics schemas through a pluggable resolver system defined in newton/usd.py.

Built-in Schema Resolvers

The three built-in resolvers handle different physics dialects:

  • SchemaResolverNewton: Extracts newton:* attributes (e.g., newton:selfCollisionEnabled).
  • SchemaResolverPhysx: Extracts PhysX-specific attributes (physx*).
  • SchemaResolverMjc: Extracts MuJoCo-specific fields (mjc:*).
from newton.usd import SchemaResolverNewton, SchemaResolverPhysx, SchemaResolverMjc

# Use specific resolvers to import PhysX-specific data

builder.add_usd(
    source="robot.usd",
    schema_resolvers=[SchemaResolverPhysx()]
)

Utility Functions

newton.usd also exports low-level helpers for direct USD manipulation:

  • get_mesh(): Extracts mesh geometry as Warp-compatible numpy arrays.
  • get_attribute(): Safely retrieves USD attributes.
  • type_to_warp(): Converts USD types to Warp types.

These utilities reside in newton/usd.py (lines 44-61) and support the internal conversion pipeline.

Practical Example: Loading and Visualizing a USD Scene

Below is a complete workflow that loads a USD pendulum model, configures the import for visualization, and renders it using Newton's viewer.

import newton
from newton import ModelBuilder
from newton.viewer import Viewer
from pathlib import Path

# Path to a USD file (could also be a URL)

usd_path = Path(__file__).parent / "assets" / "pendulum.usda"

# Create a builder and import the USD stage

builder = ModelBuilder()

# Optional: apply a global transform (rotate 90° about X to match Y-up)

builder.add_usd(
    source=str(usd_path),
    xform=newton.Transform.from_euler_xyz((90.0, 0.0, 0.0), deg=True),
    load_sites=True,               # import MjcSiteAPI primitives as Newton sites

    load_visual_shapes=True,       # bring in visual-only meshes

    collapse_fixed_joints=False,   # keep fixed joints (useful for debugging)

    apply_up_axis_from_stage=True, # respect any up-axis encoded in the file

)

# Finalise the model

model = builder.finalize()

# Run a short simulation and visualise

viewer = Viewer(model)
viewer.run(duration=3.0, fps=60)

What the script accomplishes:

  1. Loads the pendulum.usda file via ModelBuilder.add_usd using the resolve_usd_from_url helper.
  2. Applies an optional transform (xform) to align the USD stage's coordinate system with Newton's expectations.
  3. Preserves all sites and visual shapes so they appear correctly in the Newton viewer.
  4. Finalises the model into a simulation-ready state.
  5. Visualizes the result using the built-in viewer at 60 FPS.

You can customize the import by toggling flags such as collapse_fixed_joints=True to merge fixed bodies into single rigid bodies, or by specifying schema_resolvers=[newton.SchemaResolverPhysx()] to prioritize PhysX-specific attributes over Newton's defaults.

Summary

  • ModelBuilder.add_usd is the primary entry point for converting USD stages into Newton simulations, located in newton/_src/sim/builder.py.
  • The conversion pipeline uses three stages: USD loading, schema resolution via SchemaResolver classes, and builder population to create bodies, joints, and shapes.
  • Schema resolvers (SchemaResolverNewton, SchemaResolverPhysx, SchemaResolverMjc) handle physics-specific attributes from different dialects, defined in newton/usd.py.
  • Visualization flags like load_visual_shapes, load_sites, and apply_up_axis_from_stage control how geometry and coordinate systems are handled during import.
  • The method returns a metadata dictionary containing mappings between USD prim paths and Newton indices, scene attributes, and unit scaling information.

Frequently Asked Questions

What is the primary entry point for converting USD files in Newton?

The primary entry point is ModelBuilder.add_usd(), implemented in newton/_src/sim/builder.py (lines 2199-2265). This method accepts a USD file path, URL, or Usd.Stage object and automatically populates the ModelBuilder with corresponding rigid bodies, joints, shapes, and visual geometry.

How does Newton handle different physics schemas like PhysX or MuJoCo?

Newton handles multiple physics schemas through a pluggable resolver system defined in newton/usd.py. The three built-in SchemaResolver classes—SchemaResolverNewton, SchemaResolverPhysx, and SchemaResolverMjc—extract attributes prefixed with newton:*, physx*, and mjc:* respectively. You can specify which resolvers to use via the schema_resolvers parameter in add_usd().

Can I apply custom transforms when importing USD files?

Yes, the add_usd() method accepts an xform parameter of type Transform that applies a global transformation to the entire USD stage during import. Additionally, setting apply_up_axis_from_stage=True automatically adjusts the coordinate system to match the USD file's up-axis (Y-up or Z-up), ensuring correct orientation in Newton's viewer.

What information does the add_usd method return?

The add_usd() method returns a comprehensive dictionary containing metadata about the imported scene. Key entries include path_body_map, path_joint_map, and path_shape_map (mapping USD prim paths to Newton indices), up_axis and scene_attributes (coordinate system and physics scene settings), schema_attrs (captured physics attributes from various schemas), and unit scaling information (mass_unit, linear_unit).

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 →