Hi @ido.sefi, this config file is able to create the mesh for the deformable body but it does not update the visual mesh which is the problem. I think the currently implementation does not support updating the deformable mesh so I will create a ticket to have that fixed.
In the meantime, another approach you can take is to use the Deformable Prim API directly and provide it mesh data. Here is example code that generates a cylinder programatically and assigns it to the deformable prim. I noticed you were trying to use very thin cylinder which may be an issue for simulation as interpenetrations can happen easily. If you can try to not use such small objects, it will be better.
Example code:
# Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved.
#
# NVIDIA CORPORATION and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto. Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA CORPORATION is strictly prohibited.
#
from isaacsim import SimulationApp
simulation_app = SimulationApp({"headless": False})
from isaacsim.core.api import World
from isaacsim.core.utils.stage import add_reference_to_stage
from isaacsim.storage.native import get_assets_root_path
import carb
import sys
from pxr import UsdGeom, Gf, PhysxSchema, Sdf
import numpy as np
import torch
import math
# Create a deformable mesh
from isaacsim.core.api.materials.deformable_material import DeformableMaterial
from isaacsim.core.prims import SingleDeformablePrim
from omni.physx.scripts import deformableUtils, physicsUtils
import isaacsim.core.utils.deformable_mesh_utils as deformableMeshUtils
def createTriangleMeshCylinder(radius=0.5, height=1.0, num_segments=16):
"""
Create a triangle mesh cylinder programmatically.
Args:
radius: Radius of the cylinder
height: Height of the cylinder
num_segments: Number of segments around the circumference
Returns:
tuple: (points, indices) - Triangle mesh points and indices
"""
points = []
indices = []
# Generate vertices for top and bottom circles
for i in range(num_segments):
angle = 2.0 * math.pi * i / num_segments
x = radius * math.cos(angle)
y = radius * math.sin(angle)
# Bottom circle vertices
points.append(Gf.Vec3f(x, y, -height/2.0))
# Top circle vertices
points.append(Gf.Vec3f(x, y, height/2.0))
# Add center vertices for top and bottom faces
bottom_center_idx = len(points)
points.append(Gf.Vec3f(0.0, 0.0, -height/2.0))
top_center_idx = len(points)
points.append(Gf.Vec3f(0.0, 0.0, height/2.0))
# Generate triangles for side faces
for i in range(num_segments):
next_i = (i + 1) % num_segments
# Bottom vertices indices
bottom_curr = i * 2
bottom_next = next_i * 2
# Top vertices indices
top_curr = i * 2 + 1
top_next = next_i * 2 + 1
# Side face triangles (two triangles per quad)
indices.extend([bottom_curr, top_curr, bottom_next])
indices.extend([top_curr, top_next, bottom_next])
# Generate triangles for top and bottom faces
for i in range(num_segments):
next_i = (i + 1) % num_segments
# Bottom face
bottom_curr = i * 2
bottom_next = next_i * 2
indices.extend([bottom_center_idx, bottom_curr, bottom_next])
# Top face
top_curr = i * 2 + 1
top_next = next_i * 2 + 1
indices.extend([top_center_idx, top_next, top_curr])
return points, indices
# Create world with torch backend for better deformable performance
my_world = World(stage_units_in_meters=1.0, backend="torch", device="cuda")
print("Using torch backend with CUDA")
# # Add default ground plane
my_world.scene.add_default_ground_plane()
# Get stage
stage = simulation_app.context.get_stage()
# Create parent scope for organization
env_scope = UsdGeom.Scope.Define(stage, "/World/Envs")
cube_path = "/World/Envs/DeformableCylinder"
cube_xform = UsdGeom.Xform.Define(stage, cube_path)
# Define the mesh path where deformable physics will be applied
mesh_path = cube_xform.GetPrim().GetPath().AppendChild("cylinder").pathString
cube_mesh = UsdGeom.Mesh.Define(stage, mesh_path)
# Rotate the cube mesh by 90 degrees around the X-axis
# Create rotation attribute and set it to 90 degrees around X-axis
# Get the prim at the mesh path and add rotation attribute
rotation_attr = cube_mesh.AddRotateXOp().Set(90.0)
# Create cylinder mesh
tri_points, tri_indices = createTriangleMeshCylinder(radius=0.01, height=1.0, num_segments=16)
# Set initial location
init_loc = Gf.Vec3f(0.0, 0.0, 4.0)
physicsUtils.set_or_add_translate_op(cube_mesh, init_loc)
# Set mesh attributes
cube_mesh.GetPointsAttr().Set(tri_points)
cube_mesh.GetFaceVertexIndicesAttr().Set(tri_indices)
cube_mesh.GetFaceVertexCountsAttr().Set([3] * (len(tri_indices) // 3))
# Create deformable material
deformable_material = DeformableMaterial(
prim_path=cube_path + "/deformableMaterial",
dynamic_friction=0.5,
youngs_modulus=5e4, # Controls stiffness
poissons_ratio=0.4, # Controls volume preservation
damping_scale=0.1, # Controls damping of deformation
elasticity_damping=0.1, # Controls damping of elastic forces
)
# Create deformable prim
deformable_cube = SingleDeformablePrim(
name="deformableCylinder",
prim_path=mesh_path,
deformable_material=deformable_material,
vertex_velocity_damping=0.0,
sleep_damping=1.0,
sleep_threshold=0.05,
settling_threshold=0.1,
self_collision=True,
self_collision_filter_distance=0.05,
solver_position_iteration_count=20,
kinematic_enabled=False,
simulation_hexahedral_resolution=2, # Resolution of the simulation mesh
collision_simplification=True,
)
# Add the deformable cube to the scene
my_world.scene.add(deformable_cube)
physx_scene = PhysxSchema.PhysxSceneAPI.Apply(stage.GetPrimAtPath("/physicsScene"))
physx_scene.GetTimeStepsPerSecondAttr().Set(240)
# Set simulation timesteps
my_world.reset()
# Main simulation loop
import time
start_time = time.time()
print("Simulation started. The cylinder will be pushed every 3 seconds.")
print("Press Ctrl+C to exit.")
while simulation_app.is_running():
current_time = time.time() - start_time
# Step the simulation
my_world.step(render=True)