Deformables
A deformable is an asset whose shape changes during simulation. Unlike a rigid body, it has no rigid root frame: its state is the position and velocity of every node of its simulation mesh.
Isaac Lab models three kinds of deformable, distinguished by the dimensionality of the simulated geometry:
Volume and surface deformables share one asset class and one authoring pattern; they differ only
in the physics material assigned to them. Cables are a separate asset class with their own
spawner, material, and state layout, and are covered in Cables_.
Particle-based materials such as fluids and granular media are not deformables in this sense. They use a separate asset and solver; see /source/concepts/using_mpm.
All three kinds are under active development. On Newton, deformables are implemented in
isaaclab_newton.assets, alongside rigid objects and articulations.
Cable support in particular is experimental: its spawner cfg, asset class, and material
defaults may still change.
Backend support
On Newton, deformables of every kind are simulated by the VBD solver, so a scene containing them must select a physics cfg whose solver is VBD. For the solver parameters, for running a rigid robot and a deformable in one scene, and for the tuning workflow, see /source/how-to/solver_tuning_vbd and /source/concepts/coupled_solvers.
OvPhysX deformables carry further restrictions on node counts and startup cost. See /source/concepts/physics-backends/ovphysx.
Volume and surface deformables
Authoring
A deformable is a mesh spawner with two extra fields:
deformable_props, a backend-specific*DeformableBodyPropertiesCfg. Setting it is what turns the mesh into a deformable at all.physics_material, a deformable material cfg. Its type selects volume or surface.
Wrap the spawner in a ~isaaclab.assets.DeformableObjectCfg to get a runtime asset.
The same object on Newton swaps the two backend cfgs:
The two backends parameterize elasticity differently: PhysX takes youngs_modulus and
poissons_ratio, Newton takes the Lame parameters k_mu and k_lambda. The values above
are the same material, converted with k_mu = E / (2 * (1 + nu)) and
k_lambda = E * nu / ((1 + nu) * (1 - 2 * nu)).
A surface deformable is authored the same way, with a 2D mesh spawner and a surface material:
The material values above are the tuned ones from Isaac-Lift-Cloth-Franka rather than the
defaults. For what each parameter does and what it defaults to, see
/source/how-to/solver_tuning_vbd, which also covers cloth self-contact. Self-contact
is off by default, so cloth passes through itself until it is enabled.
edge_refinement sets the simulation resolution for both kinds: the maximum surface edge length
is the bounding-box diagonal divided by this value, and volume deformables reuse it as the
tetrahedralization target. It defaults to 4.0 and must be at least 1.0. Values near 1.0
make tetrahedralization significantly slower.
The mesh spawner rejects combinations that cannot work: deformable_props together with
rigid_props or mass_props, or with a physics_material that is not a deformable
material, raise a ValueError at spawn time.
Loading from USD
A deformable can also come from a pre-authored asset. Pass deformable_props and
physics_material to ~isaaclab.sim.spawners.from_files.UsdFileCfg; the spawner applies
the deformable schema to the loaded prim, or modifies it in place if the prim already carries one.
Volume or surface
There is no explicit type field, and no separate cloth asset class. At authoring time the kind
follows from the material cfg: a material deriving from
~isaaclab.sim.spawners.materials.SurfaceDeformableBodyMaterialBaseCfg produces a surface
deformable, and anything else produces a volume deformable. That choice decides what USD is
authored, a UsdGeom.TetMesh simulation mesh for volume and a triangle UsdGeom.Mesh copy of
the visual mesh for surface.
At initialization the asset re-derives the kind from the stage. PhysX and OvPhysX read the applied
schema on the bound physics material, falling back to mesh topology when that is inconclusive;
Newton uses topology alone, treating a UsdGeom.TetMesh under the prim as volume and a plain
UsdGeom.Mesh as surface.
So the material cfg is load-bearing: pairing a volume material with a cloth-shaped mesh authors a tetrahedralized solid, not a sheet.
Tetrahedralization
Volume deformables need a tetrahedral simulation mesh. When the spawned prim does not already
contain a UsdGeom.TetMesh, Isaac Lab generates one, which requires the optional
tetrahedralization dependencies on every backend:
Surface deformables never need it, and neither do volume deformables loaded from a USD that already
ships a pre-tetrahedralized UsdGeom.TetMesh under the deformable prim.
Runtime state
The state of a deformable is nodal, expressed in the simulation world frame. N below is
isaaclab.assets.DeformableObject.max_sim_vertices_per_body.
data.nodal_pos_wanddata.nodal_vel_w, shape(num_instances, N)ofvec3f, positions [m] and velocities [m/s].data.nodal_state_w, the same data as(num_instances, N)ofvec6f.data.default_nodal_state_w, the spawn state, used for resets.data.root_pos_wanddata.root_vel_w, shape(num_instances,). These are derived quantities, computed as the mean over the simulation nodes. There is no root orientation.
Write state back with the indexed setters. ~isaaclab.assets.DeformableObject.transform_nodal_pos
applies a pose offset relative to the current nodal mean, which is how a spawn-state buffer is
scattered across environment origins.
Like every other asset, a ~isaaclab.assets.DeformableObject integrates with
~isaaclab.scene.InteractiveScene, scene.get_state / scene.reset_to, and the
reset_scene_to_default event term.
The unsuffixed writers (write_nodal_state_to_sim and friends) are deprecated in favor of the
_to_sim_index and _to_sim_mask variants. The mask variants are CUDA-graph capturable.
Cables
A cable is a 1D rod: a single open UsdGeom.BasisCurves prim carrying the
PhysicsCurvesDeformableSimAPI schema, simulated as a chain of per-segment capsule bodies joined
by cable joints.
Cable authoring
A cable is configured with a ~isaaclab.sim.spawners.shapes.CableCfg plus a
~isaaclab.sim.spawners.materials.CableMaterialCfg. Adjacent pairs in positions become
segments, each materialized as a capsule of diameter thickness and joined to its neighbor by a
cable joint. N control points produce N-1 segment bodies and N-2 joints; the root
segment is free-floating.
This authors a straight 0.9 m red cable along the cable-local x-axis: 9 capsule segments (0.1 m
long, 0.03 m diameter) joined by 8 cable joints. The inherited init_state sets the cable root’s
spawn pose in each environment.
Cable material parameters
~isaaclab.sim.spawners.materials.CableMaterialCfg defines the cable’s geometry and
stiffness. All values are validated at author time; nonfinite or out-of-range values raise a
ValueError before any prim is created.
The stiffness fields are elastic moduli, not joint stiffnesses. Each rod joint gets its own
discretized stiffness, using that joint’s dual rest length L = 0.5 * (L_parent + L_child),
where L_parent and L_child are the rest lengths of the two segments it spans.
A cable joint has four degrees of freedom: linear stretch and shear, and angular bend and
twist. Leaving shear_stiffness or twist_stiffness unset does not mean the cable has
no shear or twist resistance; it means the solver falls back to the stretch and bend values.
Authoring 0.0 is distinct from leaving them unset: it removes that resistance.
The two fallbacks are not symmetric. Shear reuses the stretch modulus, applied to the same
cross-section area. Twist reuses the bend structural stiffness E * I / L, whereas an
explicitly authored twist_stiffness is applied to the polar moment J = 2 * I. Setting
twist_stiffness = bend_stiffness therefore gives twice the fallback stiffness, not the same
value.
Damping is not exposed. The rod joints have damping, but the USD curve-material schema Isaac Lab authors has no attribute for it.
To target a specific axial E * A or bending E * I, invert these relations to pick the
modulus; examples/cables.py does this from a target stiffness and the segment geometry.
Cable collision
Collision is opt-in through collision_props. When enabled, the importer applies
adjacent-segment-only filtering: directly connected segments, which share a joint anchor and
would otherwise jitter, are filtered, while every other pair collides. As a result:
- The cable collides with the ground and with other cables.
- Non-adjacent segments of the same cable collide, so a cable can self-arrest when it loops back on itself.
When collision_props is omitted, the cable imports as a dynamics-only rod and does not collide.
Cable runtime state
~isaaclab.assets.CableObject exposes per-segment world state and integrates with
~isaaclab.scene.InteractiveScene, scene.get_state / scene.reset_to, and the
reset_scene_to_default event term.
cable.data.segment_pose_w, shape(num_instances, num_segments)ofwp.transformf, position [m] followed by quaternion(x, y, z, w). The Torch view has a trailing dimension of 7.cable.data.segment_velocity_w, shape(num_instances, num_segments)ofwp.spatial_vectorf, linear [m/s] followed by angular [rad/s]. The Torch view has a trailing dimension of 6.cable.data.default_segment_pose_wanddefault_segment_velocity_w, the spawn state.
Write per-segment state back with the indexed or masked setters; the masked form is CUDA-graph capturable.
Writes update the maximal-coordinate body state directly, for both simulation states, and flag the affected environments for a solver reset.
Loading cables from USD
Physics is authored in place on the curve: ~isaaclab.sim.spawners.shapes.spawn_cable applies
the PhysicsCurvesDeformableSimAPI schema and binds a deformable-curve material, and the curve is
imported natively. Topology comes from the curve’s own points and curveVertexCounts; no
custom edge attribute is required.
A cable can therefore also be loaded from an external USD, for example one authored in a DCC tool,
via ~isaaclab.sim.spawners.from_files.UsdFileCfg, provided the curve already carries:
- a single open, linear, nonperiodic
UsdGeom.BasisCurvesunder the loaded prim, - the
PhysicsCurvesDeformableSimAPIapplied schema, and - a bound deformable-curve material (
PhysicsCurvesDeformableMaterialAPI) supplyingthickness,density,stretchStiffness, andbendStiffnessin thephysics:namespace.
Two failure modes follow from that list. A curve without the sim schema is not part of the
deformable import at all and is silently skipped. A curve that has the schema but no resolvable
thickness is imported with a default radius and a warning. Author cables through
~isaaclab.sim.spawners.shapes.spawn_cable, or apply the schema and material to the imported
prim before construction.
Cable rendering
Cables render in the Kit viewport as UsdGeom.BasisCurves. At render cadence the curve points are
refreshed from the cable segment endpoints so the rendered shape always matches the simulation.
Curve points are synchronized through CPU Fabric because the RTX Hydra delegate does not
read GPU-backed Fabric arrays for BasisCurves (NVBug 6502662). Periodic curves are skipped
by the sync.
Cable limitations
- One standalone, unwelded cable per object.
~isaaclab.assets.CableObjectrequires exactly oneBasisCurvesprim carryingPhysicsCurvesDeformableSimAPIunderprim_path, holding a single open curve that is not welded to another cable. Multi-curveBasisCurvesprims, periodic (closed) curves, and hard coincident curve-to-curvePhysicsAttachmentwelds all fail during initialization. - Cable ends can be pinned, not clamped. A
PhysicsAttachmentto an xform target lowers to a ball joint, so it constrains position only and the cable pivots freely at the anchor. Rigid plugs and end fittings that must transfer orientation are not representable. - No damping knobs. The four stiffness moduli are exposed; their damping counterparts are not.
- CPU-only render sync (NVBug 6502662); periodic curves are not synced.
An attachment joint is created only when the attachment stiffness is unauthored or infinite. A finite stiffness is kept as metadata and no joint is created. Both cases are import warnings rather than errors, so the cable initializes normally with the attachment missing. Check the importer output when an attachment appears to have no effect.
Topologies the runtime object rejects still simulate: the physics model is built from the whole
USD stage, so every curve carrying PhysicsCurvesDeformableSimAPI is imported whether or not
a ~isaaclab.assets.CableObject wraps it. Drive them through
~isaaclab_newton.physics.NewtonManager get_model() / get_state_0() and your own
newton.selection.ArticulationView. There is no Isaac Lab asset wrapper for those cases.
Material parameters in practice
Each animation below runs the same scene three times, changing one material parameter and holding everything else fixed. The labels give the value used in each run.
Volume

Young's modulus: overall stiffness. At 1e3 Pa the ball collapses into a pancake on impact; at 1e5 Pa it barely deforms. This is the first knob to reach for when a soft body is too floppy or too rigid.

Poisson's ratio: how strongly the material preserves volume under compression. At 0.10 the ball squashes without spreading. At 0.49 it is nearly incompressible, so the same squash has to go somewhere and pushes outward into a wide bulge.

Particle radius: the contact thickness around each simulation node, not a material property. A larger radius detects contact further from the surface, so the ball rests visibly higher off the table and cannot be compressed as thin. Too small and contacts are missed or detected late; too large relative to the mesh resolution and they start too early.
Surface

Stretch stiffness: resistance to in-plane elongation. The low value lets the sheet stretch and sag under its own weight; the high value holds it near its rest length.

Bend stiffness: resistance to folding. At 1e-2 the sheet crumples into a loose heap; at 1e0 it keeps large, stiff folds and stays draped over the roller. This is the difference between silk and canvas.
Cable

Bend stiffness: at 1e0 the cable droops between its supports like slack rope; at 1e2 it holds itself straight like a stiff hose.

Twist stiffness: a weighted cable is twisted at its anchor. At 1e-1 the twist is absorbed locally and the cable hangs straight. At 1e1 torsion is carried along the rod until it buckles and coils into a helix. Set this explicitly when a cable should resist winding, since leaving it unset falls back to the bend value as described above.
Examples and tasks
Run an example first to confirm that the spawner, solver, and visualizer all work in your environment.
scripts/environments/state_machine/lift_franka_soft.py drives Isaac-Lift-Soft-Franka with a
scripted state machine, which is a useful starting point for a deformable manipulation task.
Related
- Interacting with a deformable object walks through a volume deformable step by step.
- /source/how-to/solver_tuning_vbd covers the VBD solver parameters, the Newton material tables, cloth self-contact, and the tuning workflow.
- /source/concepts/coupled_solvers covers running a rigid robot and a deformable in one scene.
- Migration of Deformables covers the Isaac Lab 3.0 deformable API changes.
- /source/concepts/physics-backends/ovphysx covers the OvPhysX deformable limitations.
- /source/api/lab/isaaclab.assets and /source/api/lab/isaaclab.sim.spawners are the API references for the asset, spawner, and material classes used here.