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
-
USD Loading: The system opens a
Usd.Stagefrom a file path, URL, or existing stage object. The helperresolve_usd_from_urlinnewton/_src/utils/import_usd.pyhandles path resolution and optional conversion to USDA format. -
Schema Resolution: Low-level helpers in
newton.usdutilizeSchemaResolverclasses to read physics-specific attributes. The resolvers extract Newton-specific (newton:*), PhysX-specific (physx*), and MuJoCo-specific (mjc:*) attributes from USD prims. -
Builder Population: The parsed data feeds into
ModelBuilderto create simulation entities. This stage respects optional flags such asload_sites,collapse_fixed_joints,apply_up_axis_from_stage, andenable_self_collisions.
Key Source Files and Architecture
The core implementation resides in two primary locations:
-
newton/_src/sim/builder.py(lines 2199-2265): Contains theModelBuilder.add_usdmethod 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, andSchemaResolverMjc.
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: Extractsnewton:*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:
- Loads the
pendulum.usdafile viaModelBuilder.add_usdusing theresolve_usd_from_urlhelper. - Applies an optional transform (
xform) to align the USD stage's coordinate system with Newton's expectations. - Preserves all sites and visual shapes so they appear correctly in the Newton viewer.
- Finalises the model into a simulation-ready state.
- 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_usdis the primary entry point for converting USD stages into Newton simulations, located innewton/_src/sim/builder.py.- The conversion pipeline uses three stages: USD loading, schema resolution via
SchemaResolverclasses, and builder population to create bodies, joints, and shapes. - Schema resolvers (
SchemaResolverNewton,SchemaResolverPhysx,SchemaResolverMjc) handle physics-specific attributes from different dialects, defined innewton/usd.py. - Visualization flags like
load_visual_shapes,load_sites, andapply_up_axis_from_stagecontrol 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →