How can I make deformable body in python?

I want to make deformable body in python program.
But, I have the following error.
What should I do to make deformable body in python?
Please tell me the solution.

[Error] [omni.physx.plugin] Deformable Body feature is only supported on GPU. Please enable GPU dynamics flag in Property/Scene of physics scene!

GPU_error

from omni.isaac.examples.base_sample import BaseSample
import numpy as np
import math

from omni.physx.scripts import deformableUtils, physicsUtils  
import omni.physxdemos as demo
import omni.usd

from pxr import UsdGeom, Sdf, Gf, PhysxSchema, UsdPhysics

import omni.physx
from pxr import UsdGeom

import omni
import carb 

class HelloWorld(BaseSample):  
    def __init__(self) -> None: 
        super().__init__()
        return

    def setup_scene(self):
        world = self.get_world()
        
        world.scene.add_default_ground_plane()
        
        stage = omni.usd.get_context().get_stage()
        physics_scene = UsdPhysics.Scene.Define(stage, Sdf.Path("/World/physicsScene"))
        physx_scene = PhysxSchema.PhysxSceneAPI.Apply(physics_scene.GetPrim())
        physx_scene.CreateEnableGPUDynamicsAttr().Set(True)  #enable GPU
        
        world.set_simulation_dt(physics_dt=1.0 / 600.0, rendering_dt=1.0 / 60.0)   #change dt
        
        #make cube
        result, path = omni.kit.commands.execute("CreateMeshPrimCommand", prim_type="Cube")
        # Get the prim
        cube_prim = stage.GetPrimAtPath(path)
        
        xform = UsdGeom.Xformable(cube_prim)
        transform = xform.AddTransformOp()
        mat = Gf.Matrix4d()
        xform.AddTranslateOp().Set(Gf.Vec3d(0.0,0.0,1.0))   
        mat.SetRotateOnly(Gf.Rotation(Gf.Vec3d(0,0,0), 290))  
        xform.AddScaleOp().Set(Gf.Vec3f(0.5, 0.5, 0.5))
        transform.Set(mat)
        
        simulation_resolution = 10

        # Apply PhysxDeformableBodyAPI and PhysxCollisionAPI to skin mesh and set parameter to default values
        success = deformableUtils.add_physx_deformable_body(
            stage,
            xform.GetPath(),
            collision_simplification=True,
            simulation_hexahedral_resolution=simulation_resolution,
            self_collision=False,
        )

        # Create a deformable body material and set it on the deformable body
        deformable_material_path = omni.usd.get_stage_next_free_path(stage, "Cube", True)
        deformableUtils.add_deformable_body_material(
            stage,
            deformable_material_path,
            youngs_modulus=10000.0,
            poissons_ratio=0.49,
            damping_scale=0.0,
            dynamic_friction=0.5,
        )
        physicsUtils.add_physics_material_to_prim(stage, xform.GetPrim(), deformable_material_path)       
    
    async def setup_post_load(self):        
        self._world = self.get_world()
        return

1 Like

Hi,
ah yes, this does ring a bell, I think this is a duplicate issue of this forum question:

See the answer from Kelly at the end, I think its the same issue. The GPU dynamics on a physics scene needs to be enabled, but is somehow turned off by the Isaac scripts.

Regards,
Ales

Thanks, Ales.

I added SimulationContext(set_defaults=False), but I got the same error. Is there something wrong with my program’s coding?

from omni.isaac.examples.base_sample import BaseSample
import numpy as np
import math

from omni.physx.scripts import deformableUtils, physicsUtils  
import omni.physxdemos as demo
import omni.usd

from pxr import UsdGeom, Sdf, Gf, PhysxSchema, UsdPhysics

import omni.physx
from pxr import UsdGeom

import omni
import carb 

from omni.isaac.core import SimulationContext

class HelloWorld(BaseSample):  
    def __init__(self) -> None: 
        super().__init__()
        return

    def setup_scene(self):
        #world = self.get_world()
        world = SimulationContext(set_defaults=False)
        
        world.scene.add_default_ground_plane()
        
        stage = omni.usd.get_context().get_stage()
        physics_scene = UsdPhysics.Scene.Define(stage, Sdf.Path("/World/physicsScene"))
        physx_scene = PhysxSchema.PhysxSceneAPI.Apply(physics_scene.GetPrim())
        
        physx_scene.CreateEnableGPUDynamicsAttr().Set(True)  #enable GPU
        
        world.set_simulation_dt(physics_dt=1.0 / 600.0, rendering_dt=1.0 / 60.0)   #change dt
        
        #make cube
        result, path = omni.kit.commands.execute("CreateMeshPrimCommand", prim_type="Cube")
        # Get the prim
        cube_prim = stage.GetPrimAtPath(path)
        
        xform = UsdGeom.Xformable(cube_prim)
        transform = xform.AddTransformOp()
        mat = Gf.Matrix4d()
        xform.AddTranslateOp().Set(Gf.Vec3d(0.0,0.0,1.0))   
        mat.SetRotateOnly(Gf.Rotation(Gf.Vec3d(0,0,0), 290))  
        xform.AddScaleOp().Set(Gf.Vec3f(0.5, 0.5, 0.5))
        transform.Set(mat)
        
        simulation_resolution = 10

        # Apply PhysxDeformableBodyAPI and PhysxCollisionAPI to skin mesh and set parameter to default values
        success = deformableUtils.add_physx_deformable_body(
            stage,
            xform.GetPath(),
            collision_simplification=True,
            simulation_hexahedral_resolution=simulation_resolution,
            self_collision=False,
        )

        # Create a deformable body material and set it on the deformable body
        deformable_material_path = omni.usd.get_stage_next_free_path(stage, "Cube", True)
        deformableUtils.add_deformable_body_material(
            stage,
            deformable_material_path,
            youngs_modulus=10000.0,
            poissons_ratio=0.49,
            damping_scale=0.0,
            dynamic_friction=0.5,
        )
        physicsUtils.add_physics_material_to_prim(stage, xform.GetPrim(), deformable_material_path)       
    
    async def setup_post_load(self):        
        self._world = self.get_world()
        return

I think what you need are these lines:

# Configure the physics scene to use GPU dynamics for particles (fluids)
physics_context = simulation_context.get_physics_context()
physics_context.enable_gpu_dynamics(True)

Thanks for the fast reply Ales.
I tried to add your lines, but I got same error.
Is it wrong to write the following?

from omni.isaac.examples.base_sample import BaseSample
import numpy as np
import math

from omni.physx.scripts import deformableUtils, physicsUtils  
import omni.physxdemos as demo
import omni.usd

from pxr import UsdGeom, Sdf, Gf, PhysxSchema, UsdPhysics

import omni.physx
from pxr import UsdGeom

import omni
import carb 

from omni.isaac.core import SimulationContext

class HelloWorld(BaseSample):  
    def __init__(self) -> None: 
        super().__init__()
        return

    def setup_scene(self):
        #world = self.get_world()
        world = SimulationContext(set_defaults=False)
        
        world.scene.add_default_ground_plane()
        
        stage = omni.usd.get_context().get_stage()
        
        # Configure the physics scene to use GPU dynamics for particles (fluids)
        physics_context = world.get_physics_context()
        physics_context.enable_gpu_dynamics(True)
        
        world.set_simulation_dt(physics_dt=1.0 / 600.0, rendering_dt=1.0 / 60.0)   #change dt
        
        #make cube
        result, path = omni.kit.commands.execute("CreateMeshPrimCommand", prim_type="Cube")
        # Get the prim
        cube_prim = stage.GetPrimAtPath(path)
        
        xform = UsdGeom.Xformable(cube_prim)
        transform = xform.AddTransformOp()
        mat = Gf.Matrix4d()
        xform.AddTranslateOp().Set(Gf.Vec3d(0.0,0.0,1.0))   
        mat.SetRotateOnly(Gf.Rotation(Gf.Vec3d(0,0,0), 290))  
        xform.AddScaleOp().Set(Gf.Vec3f(0.5, 0.5, 0.5))
        transform.Set(mat)
        
        simulation_resolution = 10

        # Apply PhysxDeformableBodyAPI and PhysxCollisionAPI to skin mesh and set parameter to default values
        success = deformableUtils.add_physx_deformable_body(
            stage,
            xform.GetPath(),
            collision_simplification=True,
            simulation_hexahedral_resolution=simulation_resolution,
            self_collision=False,
        )

        # Create a deformable body material and set it on the deformable body
        deformable_material_path = omni.usd.get_stage_next_free_path(stage, "Cube", True)
        deformableUtils.add_deformable_body_material(
            stage,
            deformable_material_path,
            youngs_modulus=10000.0,
            poissons_ratio=0.49,
            damping_scale=0.0,
            dynamic_friction=0.5,
        )
        physicsUtils.add_physics_material_to_prim(stage, xform.GetPrim(), deformable_material_path) 
            
    
    async def setup_post_load(self):        
        self._world = self.get_world()
        return

Hi @Yuya_t - The error message you’re seeing is indicating that the GPU dynamics flag needs to be enabled in the physics scene properties. This is because deformable bodies in PhysX require GPU acceleration.

You are already enabling GPU dynamics in your code with the line physics_context.enable_gpu_dynamics(True). However, it seems like this is not taking effect.

One possible reason could be that the GPU dynamics flag needs to be set before the physics scene is created. If the physics scene is already created before this line is executed, the change might not take effect.

You can try moving the enable_gpu_dynamics(True) line to be before the world.scene.add_default_ground_plane() line, like this:

physics_context = world.get_physics_context()
physics_context.enable_gpu_dynamics(True)

world.scene.add_default_ground_plane()
This ensures that the GPU dynamics flag is set before the physics scene is created.

If this doesn’t solve the issue, it could be that your system doesn’t support GPU acceleration, or the necessary GPU drivers are not installed. You can check if your system supports GPU acceleration and if the necessary drivers are installed.

Thank you for reply @rthaker .
I tried your opinion, but I didn’t solve error.

I enabled gpu again at GUI, the problem was solved.

Hi @Yuya_t - There is a new Isaac Sim release coming around Aug/Sep timeframe. I think this should not happen with that latest release.

That’s good news! I am expectantly waiting for that.

Try this one bro ;) - Worked at Isaac Sim 2023.1.1

from omni.isaac.core.physics_context.physics_context import PhysicsContext
...
        self._scene = PhysicsContext()
        self._scene.set_solver_type("TGS")
        self._scene.set_broadphase_type("GPU")
        self._scene.enable_gpu_dynamics(flag=True)
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.