Skip to content

Rod Api and its attachment - #70

Open
lyd405121 wants to merge 14 commits into
newton-physics:mainfrom
lyd405121:main
Open

Rod Api and its attachment#70
lyd405121 wants to merge 14 commits into
newton-physics:mainfrom
lyd405121:main

Conversation

@lyd405121

Copy link
Copy Markdown

Make rods parse easier

  • Support close chain
ClosedChain.mp4
  • Support graph rods
newton-graph.mp4
  • support attachment
GraphAttach.mp4

Things should disscussed

  • Use youngs modulus, possion ratio, armature,which are not included in vbd but useful and more accurate
  • Twist param are added for future solvers
  • Attachment using direct node index instead of fixed joint which not allowed in newton's add_usd

lyd405121 added 5 commits June 3, 2026 19:17
Added NewtonRodAPI and NewtonRodAttachmentAPI schemas for rod simulation.

Signed-off-by: 蕉太狼 <1251212394@qq.com>
Signed-off-by: 蕉太狼 <1251212394@qq.com>
This file contains unit tests for the Newton Rod API and its attachment API, verifying API registration, application, and attribute behavior.

Signed-off-by: 蕉太狼 <1251212394@qq.com>
Signed-off-by: 蕉太狼 <1251212394@qq.com>
Signed-off-by: 蕉太狼 <1251212394@qq.com>
@codecov

codecov Bot commented Jun 3, 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

Copy link
Copy Markdown
Member

@lyd405121 you can likely address the linter failure with uv run poe format & you can check results locally with uv run poe lint

@lyd405121

Copy link
Copy Markdown
Author

Add rod visual api

  • Visual api apply to basic curve only
  • Need no modifction for visualize
  • Only one attribute for simulation and rendering sync

Static Test

  • usdview load and render usda file with current schema
closed graph

IsaacSim

  • We can load it with isaacsim too
isaasim lightwheel-isaaclab

More work

  • Not tested for simulation and rendering fabric array sync.
  • After isaaclab3.0 GA release , I will test it
  • There are two things should be done
  • One is zero copy
  • Another is rendering issue

Code and Assets

@chschuma-disney chschuma-disney 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 putting together this RodAPI proposal! I did a first pass to get the discussion started.

In general, I would favor the schema being a bit more distanced from the actual implementation in Newton, so that it is general enough that it could also represent other types of rods (e.g., ones not represented by connected capsules), and wouldn't need to be updated if the Newton implementation was modified. This mostly concerns the documentation and default values.

Besides that, I think there's a bigger (structural) question that I believe is worth thinking about or discussing. USD already provides some variant of rod geometry through BasisCurves, and in an ideal world, these would provide all the geometry that we need, so the RodAPI could apply to a curve and just add all physics attributes. In practice, there's obviously the issue with junctions that are not representable by BasisCurves. So we're stuck with either defining everything ourselves, or using BasisCurves and then adding a mechanism to attach curves to each other to form a junction. If you have any insights into why one is better, it would be great to share them here.

Comment thread newton_usd_schemas/generatedSchema.usda Outdated
doc = """Capsule radii for rod segment bodies, in metres.

Array length semantics (E = number of edges / segments):
- Empty: the engine uses a default of 0.005 for all E segments.

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.

Small point, but following the convention of the rest of the schemas, I would refer to the engine's default without specifying the numerical value itself.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I will polish this.

Comment thread newton_usd_schemas/generatedSchema.usda Outdated
)


int[] newton:fixedPoints (

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.

I think it might be a bit confusing to have two different mechanisms for constraining points: this fixedPoints attribute and NewtonRodAttachmentAPI. I could imagine that both cases could be covered by NewtonRodAttachmentAPI if we also specify the type of attachment (to a body, to world, ...), which would also allow us to extend this in to future to other types of attachments.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Nice! Attachment to the world, means fixed!

Comment thread newton_usd_schemas/generatedSchema.usda Outdated
A value of -1 (default sentinel) means the attribute is unset; the engine uses
`newton:stretchStiffness` and `newton:bendStiffness` directly.

Range: (0, inf) when active; -1 as sentinel for "unset"

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.

Small point, but using -inf as the sentinel value would better align with the other schemas.

Comment thread newton_usd_schemas/generatedSchema.usda Outdated

A value of -1 (default sentinel) means the attribute is unset.

Range: (-1, 0.5] when active; -1 as sentinel for "unset"

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.

I might be mistaken, but I thought that the theoretical bounds for Poisson's ratio were [-1, 0.5], so including -1. Even if it's not useful for this application, having -1 as the "unset" sentinel might be confusing. I'd recommend using -inf instead.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Make sense

Comment thread newton_usd_schemas/generatedSchema.usda Outdated
- Length E: each entry is associated with the corresponding segment/edge."""
)

bool newton:closed = false (

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.

I'm wondering if this is necessary when we have the option to build the same rod by just specifying the edges explicitly.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Reasons

  • The reseason is newton's rod api has this attribute, which will make the parser easy to impelment
image
  • And deeper, add_rod api most of the time will use wrap_in_articulation=true to avoid orphan joints
  • If not telling it is a closed form, some solver will fail for looped joints articulation
  • As I know, only disney's kamino solver support looped joints

My thoughts

  • Remove the 'closed' attribute, will be more natual to read
  • But we should remove the 'closed' parameter for add_rod api

Comment thread newton_usd_schemas/generatedSchema.usda Outdated
Ignored when `newton:edges` is non-empty."""
)

quatf[] newton:quaternions (

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.

Minor point, but I'd call this orientations or some variant of that. quaternions just describes the representation, but not the function.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I agree with you.

  • And this is also the parameter name for add_rod api, I just copy it
  • I think a better way is using orientations instaed of quaternions, but make notions in the schema doc

@lyd405121

Copy link
Copy Markdown
Author

Thanks for putting together this RodAPI proposal! I did a first pass to get the discussion started.

In general, I would favor the schema being a bit more distanced from the actual implementation in Newton, so that it is general enough that it could also represent other types of rods (e.g., ones not represented by connected capsules), and wouldn't need to be updated if the Newton implementation was modified. This mostly concerns the documentation and default values.

Besides that, I think there's a bigger (structural) question that I believe is worth thinking about or discussing. USD already provides some variant of rod geometry through BasisCurves, and in an ideal world, these would provide all the geometry that we need, so the RodAPI could apply to a curve and just add all physics attributes. In practice, there's obviously the issue with junctions that are not representable by BasisCurves. So we're stuck with either defining everything ourselves, or using BasisCurves and then adding a mechanism to attach curves to each other to form a junction. If you have any insights into why one is better, it would be great to share them here.

I have thought about this

  • The key point is simulation and rendering data should be sperated

Case

  • For performance, we choose to use less points to simulate
  • And for visuals, we use more points to make it smooth
case.mp4
  • If simulation and rendering using some number of points, you can see there is a small gap between segments
  • But if we break the rule for equal number of points, we can use a strategy like skinning animation even rigging

1. delete closed attribute, always use edges
2. delete fixed points,use attachment api instead
3. rename quaternion to orientation
4. attachment api allows multiple nodes attach to one body/world
5. youngsModulus / poissonRatio default value to -inf

@andrewkaufman andrewkaufman 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 lyd405121! Sorry it has taken so long to get you a review of this. I was waiting to be able to refer to the upcoming AOUSD proposal for deformable curves, but it has not been officially posted yet. I have instead included some details of that proposal in my comments here & linked you a draft copy on our Newton chat space. @frankchenlw can share it if you're not on the chat.

My main comment is that I think we need to re-align with this AOUSD proposal, as it is likely to get adopted & become part of the UsdPhysics standard. If we find issues that make it difficult to do this for Newton Rods, we should provide that feedback to AOUSD directly (once the proposal is posted) to ensure the standard doesn't contradict our needs.

Comment thread newton_usd_schemas/generatedSchema.usda Outdated
Comment on lines +1129 to +1163
class NewtonRodAPI "NewtonRodAPI" (
doc = """`NewtonRodAPI` applies on top of an `Xform` prim, enabling Newton rod simulation.

The rod geometry is defined entirely by attributes on this prim:
`newton:points` (N node positions) and `newton:radius` (uniform capsule radius).

Topology:
`newton:edges` is the required topology attribute for all rods. Each entry (u, v)
defines one segment between two nodes in `newton:points`. Linear rods should author
explicit edges such as (0,1), (1,2), ..., (N-2, N-1); closed loops and branching
junctions are expressed by the same edge list.

E is the number of authored edges / rod segments. All per-segment and per-joint array
attributes use E as their reference length.

Visual representation:
Attach one or more `BasisCurves` child prims, each carrying `NewtonRodVisualCurveAPI`,
to this Xform for rendering. Each curve represents one connected strand of the rod graph
(e.g. trunk, branch A, branch B). The `newton:rodPointIndices` attribute on each curve
maps its vertex positions to rod node indices, allowing an engine or tool to synchronize
the rendered curve with the simulated rod in real time.

Example layout for a branching graph:
/World/cable (Xform + NewtonRodAPI, 10 nodes)
/visual_trunk (BasisCurves + NewtonRodVisualCurveAPI) indices=[0,1,2,3,4]
/visual_branchA (BasisCurves + NewtonRodVisualCurveAPI) indices=[2,5,6,7]
/visual_branchB (BasisCurves + NewtonRodVisualCurveAPI) indices=[2,8,9]

Contact material:
Rod segment capsules inherit contact properties from the standard USD material binding
mechanism. Apply `MaterialBindingAPI` to this prim and bind a `Material` prim carrying
`NewtonMaterialAPI` (and optionally `PhysicsMaterialAPI`). The engine reads
`newton:contactStiffness`, `newton:contactDamping`, and `newton:contactFrictionGain`
from the bound material for all rod-object contacts."""
)

@andrewkaufman andrewkaufman Jun 15, 2026

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.

I agree with @chschuma-disney, most of the non-physics attributes on NewtonRodAPI appear to be re-formulations of BasisCurve (e.g. points, radius->widths, orientations->normals, closed->wrap). In general, we aim to re-use existing schema whenever possible, unless there is sufficent justification to deviate.

The key point is simulation and rendering data should be seperated. If simulation and rendering using some number of points, you can see there is a small gap between segments

This is very common in USD & is still commonly done with BasisCurves. e.g. for hair in film VFX they would use 2 BasisCurve prims, one is a "guide" purpose & has lower resolution (not just less points per curve, but usually also fewer total number of curves). The other BasisCurves is "default" or "render" purpose, is considerably denser, often uses a non-linear basis, and is "skinned" to the simulated curves to inherit & interpolate the motion.

As some additional context, AOUSD has a proposal for adding Deformables to UsdPhysics, and many of the physics attributes on NewtonRodAPI are being proposed on PhysicsCurvesDeformableSimAPI & PhysicsCurvesDeformableMaterialAPI, both of which apply to BasisCurves. There is as well a proposed PhysicsDeformablePoseAPI to define "geometry embeddings" between graphics prims & deforming physics prims. Given this direction of the specification, I think it makes sense for Newton to follow suite, by using & extending PhysicsCurvesDeformableSimAPI and PhysicsCurvesDeformableMaterialAPI with a NewtonCurvesDeformableSimAPI and/or NewtonCurvesDeformableMaterialAPI if we need additional attributes (e.g. the damping attrs or wrapInArticulation).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks for your time and advice.

  • I think I am not doing it the right way 😭

Question

  • I have a question about where can I find the PhysicsCurvesDeformableSimAPI
  • I searched openusd and aousd and google chat, find nothing

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.

Yes, sorry it is not yet posted officially (just due to some administration issue), you can find a tmp copy here TMP AOUSD UsdPhysics Deformables proposal

Comment thread newton_usd_schemas/generatedSchema.usda Outdated
)


float newton:youngsModulus = -inf (

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.

I don't think newton rods in the runtime expose youngsModulus of poissonRatio currently. How did you decide to add them here? When do you prefer them over authoring the stiffnesses directly?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

  • Youngs' modulus and Poisson ratio are more accurate and easy to get
  • And I thought for robotics, measuable is important
  • It is ok to remove this, but please keep the 'twist' parameter, though newton is not using it

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.

Ok thank you, I will provide this feedback on the AOUSD proposal. I believe @jumyungc has a draft PR to support twist in newton as well, and the AOUSD already does have twist

Comment thread newton_usd_schemas/generatedSchema.usda Outdated
}
)

float[] newton:stretchStiffness (

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.

In the AOUSD proposal, these stiffnesses are placed on the material prim instead & are inherantly uniform (the single value case). GeomSubsets can then be used to provide different values to different vertices (or segments).

I would like to know how granularly you want to vary stiffness?

If you only need a couple values over the curve, Subsets may be a viable solution. If you need a unique value for each segment, Subsets become a bit burdensome & this float[] could act more like a primvar -- an array to override/drive the material value across the surface. That would simplify the documentation (no need to explain the length 1 case, the array is only used when non-uniform values are necessary).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I will read aousd and update this

Comment thread newton_usd_schemas/generatedSchema.usda Outdated
where the natural capsule inertia is very small and causes ill-conditioning.

Range: [0, inf)
Units: kg·m²"""

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.

Please follow the units notation of the other schemas using "distance" and "mass". It is more confusing perhaps, but in keeping with USD style, as the stage metrics might not be in kg & meters.

Comment thread newton_usd_schemas/generatedSchema.usda Outdated
}
)

float newton:armature = 0.0 (

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.

Does this correspond to armature of the cable joint in newton runtime? Or if not, where does this armature get recorded? When would you decide to set armature rather than mass (on the PhysicsDeformableBodyAPI or masses on PhysicsCurvesDeformableSimAPI)?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

  • This is a legacy value of newton for making the solver stable
  • I reiewed newton's api, it may be deprecated in the future
  • So I will delete this

Comment thread newton_usd_schemas/generatedSchema.usda Outdated
enabling efficient constraint solving for stiff rods."""
)

int newton:collisionFilterNeighborDistance = 1 (

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.

Is this used only in wrapInArticulation mode? If so, & if we decide to go with NewtonArticulationRootAPI, then I wonder if this can be re-formulated along with the collision filtering mode on NewtonArticulationRootAPI

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

  • Emmm, some solver will break down for orphan joints
  • Like mujoco and featherstone,most of the time, it has to be true

Comment thread newton_usd_schemas/generatedSchema.usda Outdated

}

class NewtonRodAttachmentAPI "NewtonRodAttachmentAPI" (

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.

I'd like to understand if this can be modelled with PhysicsAttachment and PhysicsElementCollisionFilter from the AOUSD proposal

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

OK,I will look into it

Comment thread newton_usd_schemas/generatedSchema.usda Outdated
Comment on lines +1451 to +1452
doc = """`NewtonRodVisualCurveAPI` marks a `BasisCurves` prim as a visual representation
of a Newton rod strand.

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.

As mentioned on the first comment, the traditional way to mark a graphics prim vs a simulation prim is using purpose -- sim prims are "guide" purpose, while graphics prims are any of "default", "render", or "proxy" purpose

Comment thread newton_usd_schemas/generatedSchema.usda Outdated
int[] newton:rodPointIndices = [0, 1, 2, ..., N-1]"""
)
{
int[] newton:rodPointIndices (

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.

I'd like to understand if this can be re-formualted using PhysicsDeformablePoseAPI from the AOUSD proposal

Comment thread newton_usd_schemas/generatedSchema.usda Outdated
Comment on lines +1153 to +1155
/visual_trunk (BasisCurves + NewtonRodVisualCurveAPI) indices=[0,1,2,3,4]
/visual_branchA (BasisCurves + NewtonRodVisualCurveAPI) indices=[2,5,6,7]
/visual_branchB (BasisCurves + NewtonRodVisualCurveAPI) indices=[2,8,9]

@andrewkaufman andrewkaufman Jun 15, 2026

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.

BasisCurves have a packed representation, we shouldnt need to split these out into 3 prims just for branching. We can split them out if that's desirable from a content authoring perspective, or if it makes the geomety embeddings via PhysicsDeformablePoseAPI easier. Just noting it's not strictly necessary for visualization.

eg I think this is the same rendered result, where each p variable is a Vec3f point position. p2 appears in the points listing 3 times, which is allowed

/visual_trunk   (BasisCurves)  curveVertexCounts[5, 4, 3], points=[p0,p1,p2,p3,p4,p2,p5,p6,p7,p2,p8,p9]

@andrewkaufman

Copy link
Copy Markdown
Member

We should also syncronize with newton-physics/newton#3192 & verify that PR is loading rod they way you need it to. Can you please review the rod section of that PR when you have some time @lyd405121 ?

@lyd405121

lyd405121 commented Jun 20, 2026

Copy link
Copy Markdown
Author

Reduced schema

@andrewkaufman @chschuma-disney

  • Now only 6 property remains in NewtonCurvesDeformableMaterialAPI
   newton:youngsModulus 
   newton:poissonRatio
   newton:stretchDamping 
   newton:bendDamping
   newton:twistDamping 

Detail

How to make a rod graph

  • I now represent graph rods with standard PhysicsAttachment: each branch is a BasisCurves deformable, and junctions between branches are curve-to-curve attachments. The importer scans these attachments before creating rods, groups connected curves, and calls add_rod_graph for the whole graph component. Simple unattached curves still use the normal rod path.

Fixed points

  • I use 'PhysicsAttachment' to make segment attach to the world
  • The Kinematic Deformables and Mass Distribution defines the whole curve a static object, not flexible enough

Other changes

  • Using periodic to represent ‘Closed’ in newton
  • Remove armature and wrapInArticulation

Test

  • I regenerate all the sample files and all of them can be parsed , simulated and rendered . The picture and video I have posted before can be reproduced in with reduced schema

Question

  • I found young's modulus and poisson ratio are already in the aousd standard for 3D deformables, I am curious about why curve as 1D deformable and cloth as 2D, not having it

  • I use sub geom to make every segment has different NewtonCurvesDeformableMaterialAPI,get an warning

image
  • The simulation seems right
subGeom.mp4

The review

  • Something the loader have not implemented
  PhysicsAttachment for rigidbody or kinematic body
  Curve-to-curve junction graphs
  World / segment attachments
  USD import path for add_rod_graph()
  Per-segment materials via GeomSubset
  Newton damping extensions
  NewtonArticulationRootAPI semantics currently used by our assets

@andrewkaufman

andrewkaufman commented Jun 22, 2026

Copy link
Copy Markdown
Member

I use sub geom to make every segment has different NewtonCurvesDeformableMaterialAPI,get an warning

Can you let me know what version of usdview you are testing in? I just tried in both 24.08 and 25.05 and I did not get those warnings in either.

@andrewkaufman

Copy link
Copy Markdown
Member

Something the loader have not implemented

Can you or @frankchenlw please makes those comments on that PR so the author knows we need those? I already made the PhysicsAttachment comment but not the others.

@andrewkaufman

Copy link
Copy Markdown
Member

I found young's modulus and poisson ratio are already in the aousd standard for 3D deformables, I am curious about why curve as 1D deformable and cloth as 2D, not having it

I've asked for feedback from AOUSD, will let you know when I hear back.

@andrewkaufman

Copy link
Copy Markdown
Member

Fixed points: I use 'PhysicsAttachment' to make segment attach to the world

Do you find this is effective? Or do you think we should consider a per-vertex or per-segment kinematic flag?

@andrewkaufman

Copy link
Copy Markdown
Member

Maybe my test files can help

These are very helpful, I think we should contribute them under https://github.com/newton-physics/newton-assets perhaps. Or maybe they are so simple they can be test cases in newton directly in that PR implementing deformables support.

@lyd405121

Copy link
Copy Markdown
Author

I use sub geom to make every segment has different NewtonCurvesDeformableMaterialAPI,get an warning

Can you let me know what version of usdview you are testing in? I just tried in both 24.08 and 25.05 and I did not get those warnings in either.

  • Latest version:Version 26.05

@lyd405121

Copy link
Copy Markdown
Author

Fixed points: I use 'PhysicsAttachment' to make segment attach to the world

Do you find this is effective? Or do you think we should consider a per-vertex or per-segment kinematic flag?

  • It works and only using aousd, other solvers can use it too

@lyd405121

Copy link
Copy Markdown
Author

Maybe my test files can help

These are very helpful, I think we should contribute them under https://github.com/newton-physics/newton-assets perhaps. Or maybe they are so simple they can be test cases in newton directly in that PR implementing deformables support.

  • Yes, the assets are too simple, and I will leave some comments to the pr

@lyd405121

Copy link
Copy Markdown
Author

Something the loader have not implemented

Can you or @frankchenlw please makes those comments on that PR so the author knows we need those? I already made the PhysicsAttachment comment but not the others.

done!

@andrewkaufman

Copy link
Copy Markdown
Member

I've reproduced your GeomSubset warniing in USD v25.11 as well. It seems related to Hydra 2.0. You can suppress the warning by disabling Hydra 2 (export USDIMAGINGGL_ENGINE_ENABLE_SCENE_INDEX=0)

I've logged the issue here:
PixarAnimationStudios/OpenUSD#4121

Note, you probably do want to add the "physics" binding purppose to those assets, so its clear they are not visual materials. If you're using usd-exchange to author assets, we have usdex.core.bindPhysicsMaterial to do that. Otherwise, its a trivial 2-liner: https://gitlab-master.nvidia.com/omniverse/usd-exchange/usd-exchange/-/blob/main/source/core/library/PhysicsMaterialAlgo.cpp?ref_type=heads#L155-156

Comment thread newton_usd_schemas/generatedSchema.usda Outdated
Comment on lines +879 to +910
float newton:youngsModulus = -inf (
doc = """Youngs modulus used by Newton importers to derive curve stiffness when
AOUSD stiffness values are not authored or an importer chooses an elastic-material
parameterization.

If set to -inf, the importer should use the authored AOUSD curve stiffness values
or its simulator defaults.

Range: [0, inf)
Units: pressure"""
limits = {
dictionary soft = {
float minimum = 0
}
}
)

float newton:poissonRatio = -inf (
doc = """Poisson ratio used with `newton:youngsModulus` to derive shear or twist
response for Newton curve solvers.

If set to -inf, the value is unset.

Range: [-1, 0.5]
Units: dimensionless"""
limits = {
dictionary soft = {
float minimum = -1
float maximum = 0.5
}
}
)

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.

My understanding is that youngsModulus and poissonRatio are going to be added to the AOUSD proposal soon, so we can drop them here for now & just add a note that their inclussion in Newton runtime is a requirement for us.

@lyd405121 lyd405121 Jul 29, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done

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.

The note in the class doc satisfies this, and the physics it states is right — G = E / (2 * (1 + nu)) governing both transverse shear and torsion is the standard Timoshenko rod formulation, and cross-sectional area, second/polar moments, shear correction and segment rest length are the correct list of factors.

Recording the Newton-side gaps it implies, so they don't get lost:

  • The cable path does not read physics:youngsModulus or physics:poissonsRatio at all. _cable_stiffnesses_from_material (newton/_src/utils/import_usd_deformable_cable.py:82-98) consumes only the four stiffnesses; there are no references to either modulus in that file. Only the volume/tet path reads them (newton/_src/usd/utils.py:1924-1951).
  • The authoring helper create_cable_stiffness_from_elastic_moduli (newton/_src/utils/cable.py:70-190) derives G but applies it to twist only — its docstring scopes G to torsion and CableStiffness documents "No shear field, by design." Transverse shear currently has no modulus-derived value.
  • There is no shear correction coefficient anywhere in the cable path.

So all three items in the doc note are genuinely unimplemented rather than partially present, which is worth knowing when this gets filed against the runtime.

}
)

float newton:stretchDamping = -inf (

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.

AOUSD exposes 4 stiffnesses, but we only expose 3 dampings here. Is that intentional?

@lyd405121 lyd405121 Jul 29, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

  • Emmm,I have done this in my repository
image
  • It is werid why it not come up in this pr

  • Let me check this

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.

Confirming four is correct, and the author's screenshot matches what the runtime exposes.

ModelBuilder.add_rod takes four independent damping arguments (newton/_src/sim/builder.py:7653/7655/7657/7659), as do add_rod_graph (:7882-7888) and add_joint_cable (:5219-5225). They resolve into four separate JointDofConfig(target_kd=...) entries (:5295-5316) and reach the VBD solver as four distinct per-DOF coefficients — JointType.CABLE is built with linear_axes=[stretch, shear] and angular_axes=[bend, twist], and SolverVBD._init_joint_penalty_k (newton/_src/solvers/vbd/solver_vbd.py:1345-1385) fills four consecutive slots. So four is the right number and none of them collapse.

Two related facts worth recording here:

The defaults are asymmetric. shear_damping inherits stretch_damping only when both shear_stiffness and shear_damping are unset (builder.py:5298-5303); the same condition governs twist inheriting bend (:5306-5312). Otherwise it is 0.0. Authoring newton:stretchDamping alone therefore changes shear behavior as a side effect, and authoring newton:shearStiffness silently switches shear damping from inherited to zero. That is worth a sentence in the class doc.

Nothing consumes these yet. import_usd_deformable_cable.py:708-721 calls add_rod with no damping arguments, so all four are inert until the importer is plumbed. That is newton-physics/newton#3485's scope, not this PR's, but it means these attributes cannot be validated end-to-end yet.

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.

Just sharing the full context: previously, stretch/shear and bend/twist were handled together and shared the same stiffness. Now that we have four independent controls, users who set only stretch and bend stiffness, as before, get backward-compatible defaults: shear inherits stretch stiffness, and twist inherits bend stiffness. This fallback is Newton-specific and can be reconsidered of course via the deprecation process if independent defaults would be better.

@andrewkaufman andrewkaufman 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 @lyd405121, some last comments to address then I think we can get this merged. Once its released I'll update the newton parsing side & ask you to test that PR

Comment thread newton_usd_schemas/generatedSchema.usda Outdated
Newton's curve-deformable runtime requires Young's modulus `E` and Poisson ratio
`nu` to be provided by the AOUSD curve material schema once those attributes are
standardized; `E` governs stretch and bend response, while `E` and `nu` determine
the shear modulus `G = E / (2 * (1 + nu))`, which governs shear and twist response.

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.

The four dampings have no Units: line. Every other float attribute in this file carries one, and the direct precedent is newton:damping (L408), which uses a dual form because its dimensions differ per DOF type:

Units: effort * seconds / degrees (angular DOFs) or effort * seconds / distance (linear DOFs).

These four split the same way, so one units string cannot cover all of them.

Author them as the time-derivative siblings of the AOUSD curve stiffnesses, which are stretch/shear = force and bend/twist = force * distance * distance. Damping is stiffness times time:

Units: force * time (stretch, shear) or force * distance * distance * time (bend, twist)

Please add that to all four, following this file's convention of "distance"/"force"/"time" rather than named SI units.

On why that is the right target: the AOUSD proposal currently documents all four curve stiffnesses as force/area, which is dimensionally inconsistent for each of them (see PixarAnimationStudios/OpenUSD-proposals#111). AOUSD has indicated the proposal will be updated so that these are true stiffnesses, with units corrected. Newton's importer presently reads them as moduli and multiplies by A/L, A/L, I/L, J/L (newton/_src/utils/import_usd_deformable_cable.py:83-98); that becomes a plain division by segment rest length L, which is a Newton-side change tracked separately. Authoring these dampings in the same convention keeps this schema consistent with the updated proposal and lets the importer apply the identical L division to all eight attributes.

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.

Just FYI, I’m currently adding per-joint stiffness assignment in Newton. One relevant detail: the discretization length is the joint’s local dual rest length, L_joint = 0.5 * (L_parent + L_child).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

  • Add unit for damping
  • Add a per-joint doc
    Done

Comment thread newton_usd_schemas/generatedSchema.usda Outdated
float newton:stretchDamping = -inf (
doc = """Newton stretch damping for curve deformables.

AOUSD curve materials do not define solver damping. If set to -inf, the importer

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.

The sentinel wording deviates from this file's standard phrasing. Every other sentinel attribute here names the attribute and refers to the engine, for example L606:

If `newton:contactGap` is set to `-inf`, the engine's default should be used instead.

Please match that form on all four, naming each attribute and using "engine" rather than "importer":

If `newton:stretchDamping` is set to `-inf`, the engine's default should be used instead.

"the importer should use its simulator default" also misplaces the responsibility: the sentinel is resolved by whoever builds the model, not specifically by the USD importer.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

  • Use similar description of damping like other property
    Done

Comment thread newton_usd_schemas/generatedSchema.usda Outdated

Newton's curve-deformable runtime requires Young's modulus `E` and Poisson ratio
`nu` to be provided by the AOUSD curve material schema once those attributes are
standardized; `E` governs stretch and bend response, while `E` and `nu` determine

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.

Trailing whitespace on L880, L881 and L883.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

remove blank space at the end of lines.done

}
)

float newton:stretchDamping = -inf (

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.

Confirming four is correct, and the author's screenshot matches what the runtime exposes.

ModelBuilder.add_rod takes four independent damping arguments (newton/_src/sim/builder.py:7653/7655/7657/7659), as do add_rod_graph (:7882-7888) and add_joint_cable (:5219-5225). They resolve into four separate JointDofConfig(target_kd=...) entries (:5295-5316) and reach the VBD solver as four distinct per-DOF coefficients — JointType.CABLE is built with linear_axes=[stretch, shear] and angular_axes=[bend, twist], and SolverVBD._init_joint_penalty_k (newton/_src/solvers/vbd/solver_vbd.py:1345-1385) fills four consecutive slots. So four is the right number and none of them collapse.

Two related facts worth recording here:

The defaults are asymmetric. shear_damping inherits stretch_damping only when both shear_stiffness and shear_damping are unset (builder.py:5298-5303); the same condition governs twist inheriting bend (:5306-5312). Otherwise it is 0.0. Authoring newton:stretchDamping alone therefore changes shear behavior as a side effect, and authoring newton:shearStiffness silently switches shear damping from inherited to zero. That is worth a sentence in the class doc.

Nothing consumes these yet. import_usd_deformable_cable.py:708-721 calls add_rod with no damping arguments, so all four are inert until the importer is plumbed. That is newton-physics/newton#3485's scope, not this PR's, but it means these attributes cannot be validated end-to-end yet.

Comment thread newton_usd_schemas/generatedSchema.usda Outdated
Comment on lines +879 to +910
float newton:youngsModulus = -inf (
doc = """Youngs modulus used by Newton importers to derive curve stiffness when
AOUSD stiffness values are not authored or an importer chooses an elastic-material
parameterization.

If set to -inf, the importer should use the authored AOUSD curve stiffness values
or its simulator defaults.

Range: [0, inf)
Units: pressure"""
limits = {
dictionary soft = {
float minimum = 0
}
}
)

float newton:poissonRatio = -inf (
doc = """Poisson ratio used with `newton:youngsModulus` to derive shear or twist
response for Newton curve solvers.

If set to -inf, the value is unset.

Range: [-1, 0.5]
Units: dimensionless"""
limits = {
dictionary soft = {
float minimum = -1
float maximum = 0.5
}
}
)

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.

The note in the class doc satisfies this, and the physics it states is right — G = E / (2 * (1 + nu)) governing both transverse shear and torsion is the standard Timoshenko rod formulation, and cross-sectional area, second/polar moments, shear correction and segment rest length are the correct list of factors.

Recording the Newton-side gaps it implies, so they don't get lost:

  • The cable path does not read physics:youngsModulus or physics:poissonsRatio at all. _cable_stiffnesses_from_material (newton/_src/utils/import_usd_deformable_cable.py:82-98) consumes only the four stiffnesses; there are no references to either modulus in that file. Only the volume/tet path reads them (newton/_src/usd/utils.py:1924-1951).
  • The authoring helper create_cable_stiffness_from_elastic_moduli (newton/_src/utils/cable.py:70-190) derives G but applies it to twist only — its docstring scopes G to torsion and CableStiffness documents "No shear field, by design." Transverse shear currently has no modulus-derived value.
  • There is no shear correction coefficient anywhere in the cable path.

So all three items in the doc note are genuinely unimplemented rather than partially present, which is worth knowing when this gets filed against the runtime.

Comment thread tests/test_rods.py Outdated
}
for name, value in values.items():
attr = self.material.GetAttribute(name)
self.assertTrue(attr.Set(value), name)

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.

Please follow the existing per-attribute test style rather than dict-driven loops.

tests/test_material.py is the closest precedent — same sentinel and same soft-limit shape as these four. It gives each attribute its own test (test_contact_stiffness, test_contact_damping, test_contact_adhesion, ...), and each one covers the absence of the attribute before the API is applied, the sentinel fallback, authored-value state, a Set() round-trip, and the declared limits:

def test_contact_damping(self):
    self.assertFalse(self.material.HasAttribute("newton:contactDamping"))

    self.material.ApplyAPI("NewtonMaterialAPI")
    attr = self.material.GetAttribute("newton:contactDamping")
    self.assertIsNotNone(attr)
    self.assertFalse(attr.HasAuthoredValue())
    self.assertEqual(attr.Get(), -math.inf)

    success = attr.Set(200.0)
    self.assertTrue(success)
    self.assertTrue(attr.HasAuthoredValue())
    self.assertAlmostEqual(attr.Get(), 200.0)

    if USD_HAS_LIMITS:
        soft = attr.GetSoftLimits()
        self.assertTrue(soft.IsValid())
        self.assertAlmostEqual(soft.GetMinimum(), 0.0)
        self.assertIsNone(soft.GetMaximum())

Here the same coverage is spread across four separate tests that each loop over the same four attribute names — test_api_application, test_material_parameter_defaults, test_material_parameter_roundtrip and test_limits. Please restructure into test_stretch_damping, test_shear_damping, test_bend_damping and test_twist_damping, each self-contained in the form above, keeping test_api_registered, test_api_application and test_api_limitations as they are.

Two gaps that closing this would also fix: nothing currently asserts HasAuthoredValue() is false before a value is set (which is what distinguishes a real authored -inf from the fallback), and test_material_parameter_roundtrip does not assert the attribute was absent prior to ApplyAPI.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

  • Writing test code for every property instead of in a big loop
  • Done

@chschuma-disney chschuma-disney 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.

I'm seconding Andrew's comments. Other than that, the PR looks good to me.

lightwheel-linken and others added 2 commits July 31, 2026 22:09
- remove blank space at the end of lines
- use similar description of damping
- add unit for damping
- test code for every property instead of in a loop
- add a per-joint doc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants