1111
1212import omni .physx .scripts .utils as physx_utils
1313from omni .physx .scripts import deformableUtils as deformable_utils
14- from pxr import PhysxSchema , Usd , UsdPhysics
14+ from pxr import Usd , UsdPhysics
1515
1616from isaaclab .sim .utils .stage import get_current_stage
17+ from isaaclab .utils .string import to_camel_case
1718
1819from ..utils import (
1920 apply_nested ,
2021 find_global_fixed_joint_prim ,
2122 get_all_matching_child_prims ,
23+ safe_set_attribute_on_usd_prim ,
2224 safe_set_attribute_on_usd_schema ,
2325)
2426from . import schemas_cfg
@@ -116,9 +118,10 @@ def modify_articulation_root_properties(
116118 if not UsdPhysics .ArticulationRootAPI (articulation_prim ):
117119 return False
118120 # retrieve the articulation api
119- physx_articulation_api = PhysxSchema .PhysxArticulationAPI (articulation_prim )
120- if not physx_articulation_api :
121- physx_articulation_api = PhysxSchema .PhysxArticulationAPI .Apply (articulation_prim )
121+
122+ applied_schemas = articulation_prim .GetAppliedSchemas ()
123+ if "PhysxArticulationAPI" not in applied_schemas :
124+ articulation_prim .AddAppliedSchema ("PhysxArticulationAPI" )
122125
123126 # convert to dict
124127 cfg = cfg .to_dict ()
@@ -127,7 +130,10 @@ def modify_articulation_root_properties(
127130
128131 # set into physx api
129132 for attr_name , value in cfg .items ():
130- safe_set_attribute_on_usd_schema (physx_articulation_api , attr_name , value , camel_case = True )
133+ # safe_set_attribute_on_usd_schema(physx_articulation_api, attr_name, value, camel_case=True)
134+ safe_set_attribute_on_usd_prim (
135+ articulation_prim , f"physxArticulation:{ to_camel_case (attr_name )} " , value , camel_case = True
136+ )
131137
132138 # fix root link based on input
133139 # we do the fixed joint processing later to not interfere with setting other properties
@@ -165,23 +171,28 @@ def modify_articulation_root_properties(
165171 parent_prim = articulation_prim .GetParent ()
166172 # apply api to parent
167173 UsdPhysics .ArticulationRootAPI .Apply (parent_prim )
168- PhysxSchema .PhysxArticulationAPI .Apply (parent_prim )
174+ parent_applied_schemas = parent_prim .GetAppliedSchemas ()
175+ if "PhysxArticulationAPI" not in parent_applied_schemas :
176+ parent_prim .AddAppliedSchema ("PhysxArticulationAPI" )
169177
170178 # copy the attributes
171179 # -- usd attributes
172180 usd_articulation_api = UsdPhysics .ArticulationRootAPI (articulation_prim )
173181 for attr_name in usd_articulation_api .GetSchemaAttributeNames ():
174182 attr = articulation_prim .GetAttribute (attr_name )
175- parent_prim .GetAttribute (attr_name ).Set (attr .Get ())
183+ parent_attr = parent_prim .GetAttribute (attr_name )
184+ if not parent_attr :
185+ parent_attr = parent_prim .CreateAttribute (attr_name , attr .GetTypeName ())
186+ parent_attr .Set (attr .Get ())
176187 # -- physx attributes
177- physx_articulation_api = PhysxSchema . PhysxArticulationAPI ( articulation_prim )
178- for attr_name in physx_articulation_api . GetSchemaAttributeNames ():
179- attr = articulation_prim . GetAttribute (attr_name )
180- parent_prim . GetAttribute ( attr_name ). Set ( attr . Get () )
188+ for attr_name , value in cfg . items ():
189+ safe_set_attribute_on_usd_prim (
190+ parent_prim , f"physxArticulation: { to_camel_case (attr_name )} " , value , camel_case = True
191+ )
181192
182193 # remove api from root
183194 articulation_prim .RemoveAPI (UsdPhysics .ArticulationRootAPI )
184- articulation_prim .RemoveAPI ( PhysxSchema . PhysxArticulationAPI )
195+ articulation_prim .RemoveAppliedSchema ( " PhysxArticulationAPI" )
185196
186197 # success
187198 return True
@@ -268,9 +279,9 @@ def modify_rigid_body_properties(
268279 # retrieve the USD rigid-body api
269280 usd_rigid_body_api = UsdPhysics .RigidBodyAPI (rigid_body_prim )
270281 # retrieve the physx rigid-body api
271- physx_rigid_body_api = PhysxSchema . PhysxRigidBodyAPI ( rigid_body_prim )
272- if not physx_rigid_body_api :
273- physx_rigid_body_api = PhysxSchema . PhysxRigidBodyAPI . Apply ( rigid_body_prim )
282+ applied_schemas = rigid_body_prim . GetAppliedSchemas ( )
283+ if "PhysxRigidBodyAPI" not in applied_schemas :
284+ rigid_body_prim . AddAppliedSchema ( "PhysxRigidBodyAPI" )
274285
275286 # convert to dict
276287 cfg = cfg .to_dict ()
@@ -280,7 +291,9 @@ def modify_rigid_body_properties(
280291 safe_set_attribute_on_usd_schema (usd_rigid_body_api , attr_name , value , camel_case = True )
281292 # set into PhysX API
282293 for attr_name , value in cfg .items ():
283- safe_set_attribute_on_usd_schema (physx_rigid_body_api , attr_name , value , camel_case = True )
294+ safe_set_attribute_on_usd_prim (
295+ rigid_body_prim , f"physxRigidBody:{ to_camel_case (attr_name )} " , value , camel_case = True
296+ )
284297 # success
285298 return True
286299
@@ -365,9 +378,9 @@ def modify_collision_properties(
365378 # retrieve the mesh collision api
366379 usd_mesh_collision_api = UsdPhysics .MeshCollisionAPI (collider_prim )
367380 # retrieve the collision api
368- physx_collision_api = PhysxSchema . PhysxCollisionAPI ( collider_prim )
369- if not physx_collision_api :
370- physx_collision_api = PhysxSchema . PhysxCollisionAPI . Apply ( collider_prim )
381+ applied_schemas = collider_prim . GetAppliedSchemas ( )
382+ if "PhysxCollisionAPI" not in applied_schemas :
383+ collider_prim . AddAppliedSchema ( "PhysxCollisionAPI" )
371384
372385 # convert to dict
373386 cfg = cfg .to_dict ()
@@ -380,7 +393,9 @@ def modify_collision_properties(
380393 safe_set_attribute_on_usd_schema (usd_mesh_collision_api , attr_name , value , camel_case = True )
381394 # set into PhysX API
382395 for attr_name , value in cfg .items ():
383- safe_set_attribute_on_usd_schema (physx_collision_api , attr_name , value , camel_case = True )
396+ safe_set_attribute_on_usd_prim (
397+ collider_prim , f"physxCollision:{ to_camel_case (attr_name )} " , value , camel_case = True
398+ )
384399 # success
385400 return True
386401
@@ -515,17 +530,18 @@ def activate_contact_sensors(prim_path: str, threshold: float = 0.0, stage: Usd.
515530 # check its children
516531 if child_prim .HasAPI (UsdPhysics .RigidBodyAPI ):
517532 # set sleep threshold to zero
518- rb = PhysxSchema .PhysxRigidBodyAPI .Get (stage , prim .GetPrimPath ())
519- rb .CreateSleepThresholdAttr ().Set (0.0 )
533+ applied_schemas = child_prim .GetAppliedSchemas ()
534+ if "PhysxRigidBodyAPI" not in applied_schemas :
535+ child_prim .AddAppliedSchema ("PhysxRigidBodyAPI" )
536+ safe_set_attribute_on_usd_prim (child_prim , "PhysxRigidBodyAPI:sleep_threshold" , 0.0 , camel_case = True )
520537 # add contact report API with threshold of zero
521- if not child_prim . HasAPI ( PhysxSchema . PhysxContactReportAPI ) :
538+ if "PhysxContactReportAPI" not in applied_schemas :
522539 logger .debug (f"Adding contact report API to prim: '{ child_prim .GetPrimPath ()} '" )
523- cr_api = PhysxSchema . PhysxContactReportAPI . Apply ( child_prim )
540+ child_prim . AddAppliedSchema ( "PhysxContactReportAPI" )
524541 else :
525542 logger .debug (f"Contact report API already exists on prim: '{ child_prim .GetPrimPath ()} '" )
526- cr_api = PhysxSchema .PhysxContactReportAPI .Get (stage , child_prim .GetPrimPath ())
527543 # set threshold to zero
528- cr_api . CreateThresholdAttr (). Set ( threshold )
544+ safe_set_attribute_on_usd_prim ( child_prim , "physxContactReport: threshold" , threshold , camel_case = True )
529545 # increment number of contact sensors
530546 num_contact_sensors += 1
531547 else :
@@ -600,17 +616,19 @@ def modify_joint_drive_properties(
600616 return False
601617 # check that prim is not a tendon child prim
602618 # note: root prim is what "controls" the tendon so we still want to apply the drive to it
603- if prim .HasAPI (PhysxSchema .PhysxTendonAxisAPI ) and not prim .HasAPI (PhysxSchema .PhysxTendonAxisRootAPI ):
619+ applied_schemas = prim .GetAppliedSchemas ()
620+ has_tendon_axis = "PhysxTendonAxisAPI" in applied_schemas
621+ has_tendon_axis_root = "PhysxTendonAxisRootAPI" in applied_schemas
622+ if has_tendon_axis and not has_tendon_axis_root :
604623 return False
605624
606625 # check if prim has joint drive applied on it
607626 usd_drive_api = UsdPhysics .DriveAPI (prim , drive_api_name )
608627 if not usd_drive_api :
609628 usd_drive_api = UsdPhysics .DriveAPI .Apply (prim , drive_api_name )
610629 # check if prim has Physx joint drive applied on it
611- physx_joint_api = PhysxSchema .PhysxJointAPI (prim )
612- if not physx_joint_api :
613- physx_joint_api = PhysxSchema .PhysxJointAPI .Apply (prim )
630+ if "PhysxJointAPI" not in applied_schemas :
631+ prim .AddAppliedSchema ("PhysxJointAPI" )
614632
615633 # mapping from configuration name to USD attribute name
616634 cfg_to_usd_map = {
@@ -639,7 +657,7 @@ def modify_joint_drive_properties(
639657 for attr_name in ["max_velocity" ]:
640658 value = cfg .pop (attr_name , None )
641659 attr_name = cfg_to_usd_map [attr_name ]
642- safe_set_attribute_on_usd_schema ( physx_joint_api , attr_name , value , camel_case = True )
660+ safe_set_attribute_on_usd_prim ( prim , f"physxJoint: { to_camel_case ( attr_name ) } " , value , camel_case = True )
643661 # set into USD API
644662 for attr_name , attr_value in cfg .items ():
645663 attr_name = cfg_to_usd_map .get (attr_name , attr_name )
@@ -691,24 +709,22 @@ def modify_fixed_tendon_properties(
691709 # get USD prim
692710 tendon_prim = stage .GetPrimAtPath (prim_path )
693711 # check if prim has fixed tendon applied on it
694- has_root_fixed_tendon = tendon_prim .HasAPI (PhysxSchema .PhysxTendonAxisRootAPI )
712+ applied_schemas = tendon_prim .GetAppliedSchemas ()
713+ has_root_fixed_tendon = "PhysxTendonAxisRootAPI" in applied_schemas
695714 if not has_root_fixed_tendon :
696715 return False
697716
717+ cfg = cfg .to_dict ()
698718 # resolve all available instances of the schema since it is multi-instance
699- for schema_name in tendon_prim . GetAppliedSchemas () :
719+ for schema_name in applied_schemas :
700720 # only consider the fixed tendon schema
701721 if "PhysxTendonAxisRootAPI" not in schema_name :
702722 continue
703- # retrieve the USD tendon api
704- instance_name = schema_name .split (":" )[- 1 ]
705- physx_tendon_axis_api = PhysxSchema .PhysxTendonAxisRootAPI (tendon_prim , instance_name )
706-
707- # convert to dict
708- cfg = cfg .to_dict ()
709723 # set into PhysX API
710724 for attr_name , value in cfg .items ():
711- safe_set_attribute_on_usd_schema (physx_tendon_axis_api , attr_name , value , camel_case = True )
725+ safe_set_attribute_on_usd_prim (
726+ tendon_prim , f"{ schema_name } :{ to_camel_case (attr_name )} " , value , camel_case = True
727+ )
712728 # success
713729 return True
714730
@@ -757,29 +773,24 @@ def modify_spatial_tendon_properties(
757773 # get USD prim
758774 tendon_prim = stage .GetPrimAtPath (prim_path )
759775 # check if prim has spatial tendon applied on it
760- has_spatial_tendon = tendon_prim .HasAPI (PhysxSchema .PhysxTendonAttachmentRootAPI ) or tendon_prim .HasAPI (
761- PhysxSchema .PhysxTendonAttachmentLeafAPI
776+ applied_schemas = tendon_prim .GetAppliedSchemas ()
777+ has_spatial_tendon = ("PhysxTendonAttachmentRootAPI" in applied_schemas ) or (
778+ "PhysxTendonAttachmentLeafAPI" in applied_schemas
762779 )
763780 if not has_spatial_tendon :
764781 return False
765782
783+ cfg = cfg .to_dict ()
766784 # resolve all available instances of the schema since it is multi-instance
767- for schema_name in tendon_prim . GetAppliedSchemas () :
785+ for schema_name in applied_schemas :
768786 # only consider the spatial tendon schema
769- # retrieve the USD tendon api
770- if "PhysxTendonAttachmentRootAPI" in schema_name :
771- instance_name = schema_name .split (":" )[- 1 ]
772- physx_tendon_spatial_api = PhysxSchema .PhysxTendonAttachmentRootAPI (tendon_prim , instance_name )
773- elif "PhysxTendonAttachmentLeafAPI" in schema_name :
774- instance_name = schema_name .split (":" )[- 1 ]
775- physx_tendon_spatial_api = PhysxSchema .PhysxTendonAttachmentLeafAPI (tendon_prim , instance_name )
776- else :
787+ if "PhysxTendonAttachmentRootAPI" not in schema_name and "PhysxTendonAttachmentLeafAPI" not in schema_name :
777788 continue
778- # convert to dict
779- cfg = cfg .to_dict ()
780789 # set into PhysX API
781790 for attr_name , value in cfg .items ():
782- safe_set_attribute_on_usd_schema (physx_tendon_spatial_api , attr_name , value , camel_case = True )
791+ safe_set_attribute_on_usd_prim (
792+ tendon_prim , f"{ schema_name } :{ to_camel_case (attr_name )} " , value , camel_case = True
793+ )
783794 # success
784795 return True
785796
@@ -837,8 +848,9 @@ def define_deformable_body_properties(
837848 # get deformable-body USD prim
838849 mesh_prim = matching_prims [0 ]
839850 # check if prim has deformable-body applied on it
840- if not PhysxSchema .PhysxDeformableBodyAPI (mesh_prim ):
841- PhysxSchema .PhysxDeformableBodyAPI .Apply (mesh_prim )
851+ applied_schemas = mesh_prim .GetAppliedSchemas ()
852+ if "PhysxDeformableBodyAPI" not in applied_schemas :
853+ mesh_prim .AddAppliedSchema ("PhysxDeformableBodyAPI" )
842854 # set deformable body properties
843855 modify_deformable_body_properties (mesh_prim .GetPrimPath (), cfg , stage )
844856
@@ -895,14 +907,10 @@ def modify_deformable_body_properties(
895907 deformable_body_prim = stage .GetPrimAtPath (prim_path )
896908
897909 # check if the prim is valid and has the deformable-body API
898- if not deformable_body_prim .IsValid () or not PhysxSchema .PhysxDeformableBodyAPI (deformable_body_prim ):
910+ applied_schemas = deformable_body_prim .GetAppliedSchemas ()
911+ if not deformable_body_prim .IsValid () or "PhysxDeformableBodyAPI" not in applied_schemas :
899912 return False
900913
901- # retrieve the physx deformable-body api
902- physx_deformable_body_api = PhysxSchema .PhysxDeformableBodyAPI (deformable_body_prim )
903- # retrieve the physx deformable api
904- physx_deformable_api = PhysxSchema .PhysxDeformableAPI (physx_deformable_body_api )
905-
906914 # convert to dict
907915 cfg = cfg .to_dict ()
908916 # set into deformable body API
@@ -930,15 +938,22 @@ def modify_deformable_body_properties(
930938 if not status :
931939 return False
932940
933- # obtain the PhysX collision API (this is set when the deformable body is added)
934- physx_collision_api = PhysxSchema .PhysxCollisionAPI (deformable_body_prim )
941+ applied_schemas = deformable_body_prim .GetAppliedSchemas ()
942+ if "PhysxCollisionAPI" not in applied_schemas :
943+ deformable_body_prim .AddAppliedSchema ("PhysxCollisionAPI" )
944+ if "PhysxDeformableAPI" not in applied_schemas :
945+ deformable_body_prim .AddAppliedSchema ("PhysxDeformableAPI" )
935946
936947 # set into PhysX API
937948 for attr_name , value in cfg .items ():
938949 if attr_name in ["rest_offset" , "contact_offset" ]:
939- safe_set_attribute_on_usd_schema (physx_collision_api , attr_name , value , camel_case = True )
950+ safe_set_attribute_on_usd_prim (
951+ deformable_body_prim , f"physxCollision:{ to_camel_case (attr_name )} " , value , camel_case = True
952+ )
940953 else :
941- safe_set_attribute_on_usd_schema (physx_deformable_api , attr_name , value , camel_case = True )
954+ safe_set_attribute_on_usd_prim (
955+ deformable_body_prim , f"physxDeformable:{ to_camel_case (attr_name )} " , value , camel_case = True
956+ )
942957
943958 # success
944959 return True
0 commit comments