Skip to content

Parse contact response attributes from NewtonMaterialAPI - #3005

Merged
jcarius-nv merged 8 commits into
newton-physics:mainfrom
andrewkaufman:akaufman/contact-material-parsing
Jun 2, 2026
Merged

Parse contact response attributes from NewtonMaterialAPI#3005
jcarius-nv merged 8 commits into
newton-physics:mainfrom
andrewkaufman:akaufman/contact-material-parsing

Conversation

@andrewkaufman

@andrewkaufman andrewkaufman commented May 29, 2026

Copy link
Copy Markdown
Member

Description

Read contact response attributes (ke, kd, kf, ka) from NewtonMaterialAPI on bound materials during USD import instead of per-shape custom attributes. The schema resolver resolves these across Newton (newton:contactStiffness/contactDamping/contactFrictionStiffness/contactAdhesion), PhysX (physxMaterial:compliantContactStiffness/Damping), and MuJoCo (mjc:solref) at the MATERIAL level, with configurable resolver priority.

Legacy newton:contact_ke/kd custom attributes on shape prims are retained as a lowest-priority fallback when no material value is authored, emitting a DeprecationWarning at resolve time. mjc:solref on material prims is similarly deprecated. Explicitly authoring -inf on a material attr ("use engine default") blocks legacy fallback.

Requires newton-usd-schemas>=0.3.0.

  • New or existing tests cover these changes
  • The documentation is up to date with these changes
  • CHANGELOG.md has been updated (if user-facing change)

Test plan

uv run --extra dev -m newton.tests -k test_contact_response
uv run --extra dev -m newton.tests -k test_contact_response_attrs
uv run --extra dev -m newton.tests -k test_contact_response_legacy

New feature / API change

def Material "RubberMaterial" (
    prepend apiSchemas = ["NewtonMaterialAPI", "PhysicsMaterialAPI"]
)
{
    float newton:contactStiffness = 5000.0
    float newton:contactDamping = 200.0
    float newton:contactFrictionStiffness = 800.0
    float newton:contactAdhesion = 0.01
}

def Cube "Collider" (
    prepend apiSchemas = ["PhysicsCollisionAPI"]
)
{
    rel material:binding:physics = </RubberMaterial>
}

Summary by CodeRabbit

  • New Features

    • Added support for USD parsing of Newton material contact-response attributes (stiffness, damping, friction, adhesion) from NewtonMaterialAPI on bound materials.
  • Deprecated

    • Per-shape contact custom attributes (newton:contact_ke/newton:contact_kd) are now deprecated. Authors should use newton:contactStiffness/newton:contactDamping on bound NewtonMaterialAPI materials instead.
  • Documentation

    • Updated collision documentation with Newton USD schema APIs for collision, material, and mesh collision handling.

Review Change Stack

@andrewkaufman
andrewkaufman requested a review from a team as a code owner May 29, 2026 20:58
@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR migrates contact response parameters (ke, kd, kf, ka) from legacy per-shape USD custom attributes to material-level NewtonMaterialAPI mappings. Schema resolvers for Newton, PhysX, and MuJoCo are updated with deprecation-aware getters. The internal PhysicsMaterial model is extended to hold material-level contact parameters, and shape resolution logic implements two-stage precedence: material values with fallback to builder defaults, plus per-shape overrides only for ke/kd when material omits them. Comprehensive tests and documentation updates complete the migration.

Changes

Contact Response Migration

Layer / File(s) Summary
Schema resolver helpers and mappings
newton/_src/usd/schemas.py, newton/tests/test_schema_resolver.py
Deprecation-aware getters added for legacy per-shape Newton and MuJoCo material attributes. Newton resolver adds material-level ke/kd/kf/ka mappings; PhysX and MuJoCo resolvers refactored to use ke/kd keys with None defaults and mjc:solref conversion via deprecation getter.
PhysicsMaterial model and material parsing
newton/_src/utils/import_usd.py
PhysicsMaterial dataclass extended with optional ke/kd/kf/ka fields. Local _resolve_contact_attr helper added to extract material-level contact attributes from USD. Material parsing populates new PhysicsMaterial contact fields from UsdPhysics.ObjectType.RigidBodyMaterial entries.
Shape-level contact response resolution
newton/_src/utils/import_usd.py
Contact-response resolution refactored to prefer material-authored values when finite; fall back to builder.default_shape_cfg otherwise. Per-shape overrides allowed only for ke/kd when material value is None and per-shape value is finite. Old (prim, physics_scene_prim) binding removed. Resolved kf/ka threaded into ModelBuilder.ShapeConfig.
Schema resolver tests
newton/tests/test_schema_resolver.py
Four new unit tests validate contact-response resolution across Newton/PhysX/MuJoCo resolvers and material/shape prim types. Tests cover unset behavior, -inf sentinel passthrough, authored attribute mapping, compliant-contact mappings, mjc:solref conversion, legacy per-shape attributes with DeprecationWarning capture, and cross-resolver priority.
USD import tests
newton/tests/test_import_usd.py
Three new unit tests verify material-bound contact-response parsing, -inf sentinel treatment, and legacy per-shape fallback with DeprecationWarning assertions. Tests confirm material precedence over builder defaults and per-shape overrides only when material omits attributes.
Documentation and changelog
docs/concepts/collisions.rst, CHANGELOG.md
Collision docs updated with Newton USD schema API sections (NewtonCollisionAPI, NewtonMaterialAPI, NewtonMeshCollisionAPI, custom properties) and -inf semantics. Changelog entries added for new material-level parsing feature and deprecation of legacy per-shape contact attributes.

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • adenzler-nvidia
  • eric-heiden
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main change: parsing contact response attributes from NewtonMaterialAPI instead of per-shape attributes.
Docstring Coverage ✅ Passed Docstring coverage is 82.35% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
newton/tests/test_schema_resolver.py (2)

1766-1772: 💤 Low value

Inconsistent warning capture pattern.

For consistency with the patterns used in test_contact_response_attrs (line 1680) and test_contact_response_legacy_shape (line 1718), this should convert warnings to strings:

-            deprecation_msgs = [x for x in w if issubclass(x.category, DeprecationWarning)]
+            deprecation_msgs = [str(x.message) for x in w if issubclass(x.category, DeprecationWarning)]

The current code works correctly since only the length is checked, but matching the established pattern improves consistency.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@newton/tests/test_schema_resolver.py` around lines 1766 - 1772, The test
currently collects warning records in variable w and filters them by category;
update it to follow the project's pattern by converting the matched
DeprecationWarning records to strings: when using SchemaResolverManager with
SchemaResolverNewton and SchemaResolverMjc and calling get_value(collider,
PrimType.SHAPE, "ke"), build deprecation_msgs by filtering w for
issubclass(x.category, DeprecationWarning) and mapping each matching record to a
string (e.g., str(x.message)) before asserting the length equals 1 so the
warning content is stored as strings consistently with other tests.

1636-1703: ⚡ Quick win

Consider adding -inf sentinel test coverage.

The PR summary indicates that "explicitly authoring -inf on a material attribute blocks the legacy fallback." This test validates material-level attribute resolution and priority, but doesn't verify that a material with newton:contactStiffness = -inf blocks fallback to a shape's legacy newton:contact_ke attribute. Consider adding a test case like:

# Material has -inf (engine default), shape has legacy attr
material.GetAttribute("newton:contactStiffness").Set(float("-inf"))
collider.CreateAttribute("newton:contact_ke", Sdf.ValueTypeNames.Float).Set(1000.0)
# Should return -inf, not 1000.0, blocking the legacy fallback

This would ensure the sentinel behavior is explicitly validated.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@newton/tests/test_schema_resolver.py` around lines 1636 - 1703, Add a test
that verifies the -inf sentinel on a material blocks legacy fallback: create a
collider prim that has the legacy attribute "newton:contact_ke" set (e.g.,
1000.0), set the material's "newton:contactStiffness" to float("-inf"), then use
SchemaResolverManager with SchemaResolverNewton (and any legacy resolver used in
other tests) to call get_value for "ke" (on the material/PrimType.MATERIAL or
via the shape resolution path used elsewhere) and assert the returned value is
-inf (not the collider's legacy 1000.0); reference the existing
test_contact_response_attrs setup, the material prim, the collider prim, and
get_value/SchemaResolverManager/SchemaResolverNewton symbols to locate where to
add this case.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@newton/_src/utils/import_usd.py`:
- Around line 2650-2665: The change drops legacy per-shape fallback for kf/ka
causing silent breakage; restore the compatibility path by treating "kf" and
"ka" like "ke"/"kd": when material.kf or material.ka is None, attempt to read
per-shape values via R.get_value(prim, prim_type=PrimType.SHAPE, key=attr_key,
verbose=verbose) and use them if finite before falling back to
builder.default_shape_cfg (update the loop over attr_key to include "kf","ka"
and assign shape_kf/shape_ka accordingly), and add matching deprecated resolver
entries for newton:contact_kf and newton:contact_ka in
newton/_src/usd/schemas.py mirroring the ke/kd shims so callers get warnings
before removal.

---

Nitpick comments:
In `@newton/tests/test_schema_resolver.py`:
- Around line 1766-1772: The test currently collects warning records in variable
w and filters them by category; update it to follow the project's pattern by
converting the matched DeprecationWarning records to strings: when using
SchemaResolverManager with SchemaResolverNewton and SchemaResolverMjc and
calling get_value(collider, PrimType.SHAPE, "ke"), build deprecation_msgs by
filtering w for issubclass(x.category, DeprecationWarning) and mapping each
matching record to a string (e.g., str(x.message)) before asserting the length
equals 1 so the warning content is stored as strings consistently with other
tests.
- Around line 1636-1703: Add a test that verifies the -inf sentinel on a
material blocks legacy fallback: create a collider prim that has the legacy
attribute "newton:contact_ke" set (e.g., 1000.0), set the material's
"newton:contactStiffness" to float("-inf"), then use SchemaResolverManager with
SchemaResolverNewton (and any legacy resolver used in other tests) to call
get_value for "ke" (on the material/PrimType.MATERIAL or via the shape
resolution path used elsewhere) and assert the returned value is -inf (not the
collider's legacy 1000.0); reference the existing test_contact_response_attrs
setup, the material prim, the collider prim, and
get_value/SchemaResolverManager/SchemaResolverNewton symbols to locate where to
add this case.
🪄 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: 662643d0-5413-421d-88d5-dbcf0ab0a5f7

📥 Commits

Reviewing files that changed from the base of the PR and between 3cd0fe8 and 0d2d056.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • CHANGELOG.md
  • docs/concepts/collisions.rst
  • newton/_src/usd/schemas.py
  • newton/_src/utils/import_usd.py
  • newton/tests/test_import_usd.py
  • newton/tests/test_schema_resolver.py
  • pyproject.toml

Comment thread newton/_src/utils/import_usd.py Outdated
@andrewkaufman
andrewkaufman force-pushed the akaufman/contact-material-parsing branch from 0d2d056 to 7ff487e Compare May 29, 2026 21:04
@andrewkaufman andrewkaufman self-assigned this May 29, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CHANGELOG.md`:
- Line 39: Update the CHANGELOG entry to use the full deprecated attribute names
for clarity: replace the ambiguous `newton:contact_ke`/`kd` phrasing with both
explicit keys `newton:contact_ke` and `newton:contact_kd`, and expand the
migration guidance to instruct authors to instead put `newton:contactStiffness`
and `newton:contactDamping` on the bound `NewtonMaterialAPI` material; ensure
this `Deprecated` entry follows the repository's changelog guideline format for
migration guidance.
🪄 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: c6f802a5-a28a-4cd6-a27c-8561b0dfbdfc

📥 Commits

Reviewing files that changed from the base of the PR and between 0d2d056 and 7ff487e.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • CHANGELOG.md
  • docs/concepts/collisions.rst
  • newton/_src/usd/schemas.py
  • newton/_src/utils/import_usd.py
  • newton/tests/test_import_usd.py
  • newton/tests/test_schema_resolver.py
  • pyproject.toml
✅ Files skipped from review due to trivial changes (1)
  • docs/concepts/collisions.rst
🚧 Files skipped from review as they are similar to previous changes (5)
  • pyproject.toml
  • newton/tests/test_import_usd.py
  • newton/tests/test_schema_resolver.py
  • newton/_src/usd/schemas.py
  • newton/_src/utils/import_usd.py

Comment thread CHANGELOG.md Outdated
@andrewkaufman
andrewkaufman force-pushed the akaufman/contact-material-parsing branch from 7ff487e to 8c6cd87 Compare May 29, 2026 21:14
Comment thread newton/_src/usd/schemas.py Outdated
@codecov

codecov Bot commented May 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@andrewkaufman andrewkaufman moved this to In Progress in Newton Roadmap May 29, 2026
@andrewkaufman andrewkaufman added this to the 1.3 Release milestone May 29, 2026
@andrewkaufman andrewkaufman added the usd Issues regarding USD import/export label May 29, 2026
@andrewkaufman
andrewkaufman force-pushed the akaufman/contact-material-parsing branch 2 times, most recently from 8c7a8b5 to d17cfaf Compare June 1, 2026 17:51
Comment thread newton/_src/usd/schemas.py
Comment thread newton/_src/usd/schemas.py
Comment thread newton/_src/usd/schemas.py Outdated
Comment thread newton/_src/usd/schemas.py

@jcarius-nv jcarius-nv left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for moving the canonical contact-response representation onto materials; that is the right direction. I think there are two compatibility/precedence issues to resolve before merging, plus a couple of tests that should pin down the intended behavior.

Comment thread newton/_src/utils/import_usd.py
Comment thread newton/_src/utils/import_usd.py Outdated
Comment thread newton/_src/utils/import_usd.py Outdated
Comment thread newton/_src/usd/schemas.py
eric-heiden
eric-heiden previously approved these changes Jun 1, 2026

@andrewkaufman andrewkaufman left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Address review feedback on precedence, legacy kf/ka, and solref warning

Comment thread newton/_src/utils/import_usd.py
Comment thread newton/_src/utils/import_usd.py Outdated
Comment thread newton/_src/utils/import_usd.py Outdated
Comment thread newton/_src/usd/schemas.py
Comment thread newton/_src/usd/schemas.py
@andrewkaufman
andrewkaufman force-pushed the akaufman/contact-material-parsing branch from 5f1efe2 to ee2369f Compare June 1, 2026 22:09
@andrewkaufman
andrewkaufman force-pushed the akaufman/contact-material-parsing branch from ee2369f to 9448771 Compare June 2, 2026 14:23
andrewkaufman and others added 8 commits June 2, 2026 17:20
Read ke/kd/kf/ka from NewtonMaterialAPI on bound materials during USD
import. The schema resolver resolves these across Newton, PhysX
(compliantContactStiffness/Damping), and MuJoCo (solref) at the
MATERIAL level, with configurable resolver priority.

Legacy newton:contact_ke/kd custom attributes on shape prims are
retained as a fallback when no material value is authored, emitting a
DeprecationWarning at resolve time directing users to the
NewtonMaterialAPI attrs. MuJoCo mjc:solref on material prims is
similarly deprecated. Explicitly authoring -inf on a material attr
("use engine default") blocks legacy fallback.

Requires newton-usd-schemas>=0.3.0.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
newton-usd-schemas 0.3.1 renamed this attribute. Update schema resolver,
docs, tests, and bump dependency to >=0.3.1.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Per-shape mjc:solref (MjcGeomAPI) is unchanged; only material-level
solref is deprecated in favor of NewtonMaterialAPI attrs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Correct precedence: non-legacy per-shape (MuJoCo solref) > material >
legacy per-shape attr > builder default.  Material now correctly wins
over deprecated newton:contact_* attrs; MuJoCo solref still wins over
material when authored on the shape.

- Detect legacy vs non-legacy per-shape values via DeprecationWarning
  emitted by legacy getters; non-legacy (solref) emits none
- Add legacy newton:contact_kf / newton:contact_ka to Newton SHAPE
  resolver with deprecation warning getters
- Update mjc:solref material deprecation to recommend both
  NewtonMaterialAPI and per-shape mjc:solref (MjcGeomAPI)
- Add test_contact_response_solref_over_material covering MuJoCo
  per-geom solref winning over material ke/kd

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Per-shape mjc:solref should only win over material contact attrs when
the MuJoCo resolver appears before Newton in the resolver list. Add
reverse-precedence test verifying material wins when Newton is first.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The rebase incorrectly picked up newton-physics#2964's [0.02, 1.0] default instead of
preserving our None fallback, which ensures ke/kd only resolve when
mjc:solref is actually authored on the prim.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@andrewkaufman
andrewkaufman force-pushed the akaufman/contact-material-parsing branch from 236bcf7 to 6443fb1 Compare June 2, 2026 17:20

@Milad-Rakhsha-NV Milad-Rakhsha-NV left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jcarius-nv
jcarius-nv dismissed their stale review June 2, 2026 18:34

was discussed and fixed

@jcarius-nv
jcarius-nv added this pull request to the merge queue Jun 2, 2026
Merged via the queue into newton-physics:main with commit cf8f7c3 Jun 2, 2026
25 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress to Done in Newton Roadmap Jun 2, 2026
@andrewkaufman
andrewkaufman deleted the akaufman/contact-material-parsing branch June 2, 2026 19:37
jkuzmeski pushed a commit to jkuzmeski/newton that referenced this pull request Jun 2, 2026
…ics#3005)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

usd Issues regarding USD import/export

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants