Conversation
OmniPBR MDL shaders use diffuse_tint for their base color, but _extract_shader_properties only searched diffuse_color_constant and similar names. Add diffuse_tint to the fallback list so robot meshes with OmniPBR materials get their correct colors. Also add a last-resort displayColor primvar check in resolve_material_properties_for_prim for prims without material bindings (e.g. collision-only ground planes whose color is set via displayColor rather than a shader).
Visual primitive shapes (box, sphere, plane, capsule, cylinder, cone) in _load_visual_shapes_impl never extracted material colors, falling back to the shape palette. Resolve the material color (with parent- prim fallback for inherited bindings) and pass color= to each add_shape_* call. Similarly, the collision shape loading path never included color in shape_params. Add material color extraction with parent fallback for visible collision shapes.
Cube primitives with textured materials cannot render textures in Newton because box shapes lack UVs and texture coordinate support. When a cube's material has a texture, convert it to a 24-vertex box mesh with per-face UVs via _cube_to_textured_mesh(), so Newton's texture pipeline can sample the texture. Untextured cubes continue to use add_shape_box as before.
Stop stripping mesh.texture when UVs are missing — the texture is kept so that renderers with projected-UV support (triplanar sampling) can use it. The warning is updated to reflect this. When a texture is present, set mesh.color to white (1,1,1) so the texture renders at full brightness. The previous behavior used diffuse_color_constant as a multiplier, which is the untextured fallback in OmniPBR and incorrectly darkened textured surfaces.
|
📝 WalkthroughWalkthroughThe changes enhance USD material property resolution and mesh import by adding fallback mechanisms for shader inputs, supporting Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
newton/_src/utils/import_usd.py (1)
652-681:⚠️ Potential issue | 🟠 MajorPass
_prim_colorthrough the cone branch too.This is the only primitive case in
_load_visual_shapes_impl()that still omitscolor=_prim_color, so visual cones keep falling back to the palette instead of the resolved USD material color.💡 Suggested fix
shape_id = builder.add_shape_cone( parent_body_id, xform, radius, half_height, cfg=visual_shape_cfg, as_site=is_site, + color=_prim_color, label=path_name, )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@newton/_src/utils/import_usd.py` around lines 652 - 681, In _load_visual_shapes_impl(), the cone primitive branch calls builder.add_shape_cone without passing the resolved USD material color, so cones fall back to the palette; update the builder.add_shape_cone call (in the cone branch) to include color=_prim_color (matching how builder.add_shape_cylinder is invoked) and keep the existing cfg/as_site/label args intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@newton/_src/utils/import_usd.py`:
- Around line 2225-2240: The code is incorrectly forcing an explicit "color"
into shape_params which overrides textured mesh albedo; change the logic around
_collider_color so you only add "color" to shape_params when the resolved
material has no texture (i.e., when _get_material_props_cached(prim) or its
parent returns a color and does not contain a texture entry). In practice,
inspect the material props returned by _get_material_props_cached (used here and
by _get_mesh_with_visual_material()) and only set shape_params["color"] when
that material has no texture; otherwise omit the "color" key so
ModelBuilder.add_shape() will use src.color (preserving textures).
---
Outside diff comments:
In `@newton/_src/utils/import_usd.py`:
- Around line 652-681: In _load_visual_shapes_impl(), the cone primitive branch
calls builder.add_shape_cone without passing the resolved USD material color, so
cones fall back to the palette; update the builder.add_shape_cone call (in the
cone branch) to include color=_prim_color (matching how
builder.add_shape_cylinder is invoked) and keep the existing cfg/as_site/label
args intact.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: 964ada78-e61d-4f31-88be-aba62c965edd
📒 Files selected for processing (2)
newton/_src/usd/utils.pynewton/_src/utils/import_usd.py
| # Resolve material color for visible collision shapes so they | ||
| # render with the correct colour instead of the palette fallback. | ||
| # Walk up to the parent if the prim itself has no material. | ||
| _collider_color = None | ||
| if collider_is_visible: | ||
| _coll_mat = _get_material_props_cached(prim) | ||
| _collider_color = _coll_mat.get("color") | ||
| if _collider_color is None: | ||
| _coll_parent = prim.GetParent() | ||
| if _coll_parent and _coll_parent.IsValid(): | ||
| _collider_color = _get_material_props_cached(_coll_parent).get("color") | ||
|
|
||
| shape_params = { | ||
| "body": body_id, | ||
| "xform": shape_xform, | ||
| "color": _collider_color, |
There was a problem hiding this comment.
Don’t override textured mesh collider albedo with an explicit shape color.
For visible MeshShape colliders, _get_mesh_with_visual_material() already forces mesh.color to white when a texture exists. ModelBuilder.add_shape() prefers the explicit color argument over src.color, so wiring _collider_color into shape_params re-tints/darkens textured colliders.
💡 Suggested fix
- _collider_color = None
+ _collider_color = None
+ _collider_texture = None
if collider_is_visible:
_coll_mat = _get_material_props_cached(prim)
_collider_color = _coll_mat.get("color")
+ _collider_texture = _coll_mat.get("texture")
if _collider_color is None:
_coll_parent = prim.GetParent()
if _coll_parent and _coll_parent.IsValid():
- _collider_color = _get_material_props_cached(_coll_parent).get("color")
+ _coll_parent_props = _get_material_props_cached(_coll_parent)
+ _collider_color = _coll_parent_props.get("color")
+ _collider_texture = _collider_texture or _coll_parent_props.get("texture")
shape_params = {
"body": body_id,
"xform": shape_xform,
- "color": _collider_color,
+ "color": None
+ if key == UsdPhysics.ObjectType.MeshShape and _collider_texture is not None
+ else _collider_color,
"cfg": ModelBuilder.ShapeConfig(🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@newton/_src/utils/import_usd.py` around lines 2225 - 2240, The code is
incorrectly forcing an explicit "color" into shape_params which overrides
textured mesh albedo; change the logic around _collider_color so you only add
"color" to shape_params when the resolved material has no texture (i.e., when
_get_material_props_cached(prim) or its parent returns a color and does not
contain a texture entry). In practice, inspect the material props returned by
_get_material_props_cached (used here and by _get_mesh_with_visual_material())
and only set shape_params["color"] when that material has no texture; otherwise
omit the "color" key so ModelBuilder.add_shape() will use src.color (preserving
textures).
Description
Fix material color extraction from USD so that OmniPBR/MDL materials, primitive shapes, and collision shapes render with correct colors instead of falling back to the shape palette.
Four gaps addressed:
diffuse_tintfor their base color, but_extract_shader_propertiesdidn't include it in the fallback name list.displayColorprimvar fallback.Checklist
CHANGELOG.mdhas been updated (if user-facing change)Test plan
Verified end-to-end with a dextrah Kuka-Allegro manipulation scene (64 envs, Newton Warp renderer) containing:
arm_gray,arm_orange,allegro_black) — now render with correct material colors instead of palette rainbowdisplayColorinstead of palette blueBug fix
Steps to reproduce:
ModelBuilder.add_usd(stage)SensorTiledCamerawithenable_textures=Truerender without textures.
Minimal reproduction: