Skip to content

xform_prim

XFormPrim

Bases: BasePrim

Provides high level functions to deal with an Xform prim and its attributes/ properties. If there is an Xform prim present at the path, it will use it. Otherwise, a new XForm prim at the specified prim path will be created when self.load(...) is called.

the prim will have "xformOp:orient", "xformOp:translate" and "xformOp:scale" only post init,

unless it is a non-root articulation link.

Parameters:

Name Type Description Default
prim_path str

prim path of the Prim to encapsulate or create.

required
name str

Name for the object. Names need to be unique per scene.

required
load_config None or dict

If specified, should contain keyword-mapped values that are relevant for loading this prim at runtime. For this xform prim, the below values can be specified:

scale (None or float or 3-array): If specified, sets the scale for this object. A single number corresponds to uniform scaling along the x,y,z axes, whereas a 3-array specifies per-axis scaling.

None
Source code in prims/xform_prim.py
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
class XFormPrim(BasePrim):
    """
    Provides high level functions to deal with an Xform prim and its attributes/ properties.
    If there is an Xform prim present at the path, it will use it. Otherwise, a new XForm prim at
    the specified prim path will be created when self.load(...) is called.

    Note: the prim will have "xformOp:orient", "xformOp:translate" and "xformOp:scale" only post init,
        unless it is a non-root articulation link.

    Args:
        prim_path (str): prim path of the Prim to encapsulate or create.
        name (str): Name for the object. Names need to be unique per scene.
        load_config (None or dict): If specified, should contain keyword-mapped values that are relevant for
            loading this prim at runtime. For this xform prim, the below values can be specified:

            scale (None or float or 3-array): If specified, sets the scale for this object. A single number corresponds
                to uniform scaling along the x,y,z axes, whereas a 3-array specifies per-axis scaling.
    """

    def __init__(
        self,
        prim_path,
        name,
        load_config=None,
    ):
        # Other values that will be filled in at runtime
        self._binding_api = None
        self._material = None
        self._collision_filter_api = None

        # Run super method
        super().__init__(
            prim_path=prim_path,
            name=name,
            load_config=load_config,
        )

    def _load(self, simulator=None):
        # Define an Xform prim at the current stage, or the simulator's stage if specified
        stage = get_current_stage()
        prim = stage.DefinePrim(self._prim_path, "Xform")

        return prim

    def _post_load(self):
        # run super first
        super()._post_load()

        # Make sure all xforms have pose and scaling info
        self._set_xform_properties()

        # Create collision filter API
        self._collision_filter_api = UsdPhysics.FilteredPairsAPI(self._prim) if \
            self._prim.HasAPI(UsdPhysics.FilteredPairsAPI) else UsdPhysics.FilteredPairsAPI.Apply(self._prim)

        # Create binding API
        self._binding_api = UsdShade.MaterialBindingAPI(self.prim) if \
            self._prim.HasAPI(UsdShade.MaterialBindingAPI) else UsdShade.MaterialBindingAPI.Apply(self.prim)

        # Grab the attached material if it exists
        if self.has_material():
            self._material = MaterialPrim(
                prim_path=self._binding_api.GetDirectBinding().GetMaterialPath().pathString,
                name=f"{self.name}:material",
            )

        # Optionally set the scale and visibility
        if "scale" in self._load_config and self._load_config["scale"] is not None:
            self.scale = self._load_config["scale"]

    def _set_xform_properties(self):
        current_position, current_orientation = self.get_position_orientation()
        properties_to_remove = [
            "xformOp:rotateX",
            "xformOp:rotateXZY",
            "xformOp:rotateY",
            "xformOp:rotateYXZ",
            "xformOp:rotateYZX",
            "xformOp:rotateZ",
            "xformOp:rotateZYX",
            "xformOp:rotateZXY",
            "xformOp:rotateXYZ",
            "xformOp:transform",
        ]
        prop_names = self.prim.GetPropertyNames()
        xformable = UsdGeom.Xformable(self.prim)
        xformable.ClearXformOpOrder()
        # TODO: wont be able to delete props for non root links on articulated objects
        for prop_name in prop_names:
            if prop_name in properties_to_remove:
                self.prim.RemoveProperty(prop_name)
        if "xformOp:scale" not in prop_names:
            xform_op_scale = xformable.AddXformOp(UsdGeom.XformOp.TypeScale, UsdGeom.XformOp.PrecisionDouble, "")
            xform_op_scale.Set(Gf.Vec3d([1.0, 1.0, 1.0]))
        else:
            xform_op_scale = UsdGeom.XformOp(self._prim.GetAttribute("xformOp:scale"))

        if "xformOp:translate" not in prop_names:
            xform_op_translate = xformable.AddXformOp(
                UsdGeom.XformOp.TypeTranslate, UsdGeom.XformOp.PrecisionDouble, ""
            )
        else:
            xform_op_translate = UsdGeom.XformOp(self._prim.GetAttribute("xformOp:translate"))

        if "xformOp:orient" not in prop_names:
            xform_op_rot = xformable.AddXformOp(UsdGeom.XformOp.TypeOrient, UsdGeom.XformOp.PrecisionDouble, "")
        else:
            xform_op_rot = UsdGeom.XformOp(self._prim.GetAttribute("xformOp:orient"))
        xformable.SetXformOpOrder([xform_op_translate, xform_op_rot, xform_op_scale])

        self.set_position_orientation(position=current_position, orientation=current_orientation)
        new_position, new_orientation = self.get_position_orientation()
        r1 = R.from_quat(current_orientation).as_matrix()
        r2 = R.from_quat(new_orientation).as_matrix()
        # Make sure setting is done correctly
        assert np.allclose(new_position, current_position, atol=1e-4) and np.allclose(r1, r2, atol=1e-4), \
            f"{self.prim_path}: old_pos: {current_position}, new_pos: {new_position}, " \
            f"old_orn: {current_orientation}, new_orn: {new_orientation}"

    def has_material(self):
        """
        Returns:
            bool: True if there is a visual material bound to this prim. False otherwise
        """
        material_path = self._binding_api.GetDirectBinding().GetMaterialPath().pathString
        return False if material_path == "" else True

    def set_position_orientation(self, position=None, orientation=None):
        """
        Sets prim's pose with respect to the world frame

        Args:
            position (None or 3-array): if specified, (x,y,z) position in the world frame
                Default is None, which means left unchanged.
            orientation (None or 4-array): if specified, (x,y,z,w) quaternion orientation in the world frame.
                Default is None, which means left unchanged.
        """
        current_position, current_orientation = self.get_position_orientation()
        position = current_position if position is None else np.array(position, dtype=float)
        orientation = current_orientation if orientation is None else np.array(orientation, dtype=float)
        orientation = orientation[[3, 0, 1, 2]]     # Flip from x,y,z,w to w,x,y,z

        mat = Gf.Transform()
        mat.SetRotation(Gf.Rotation(Gf.Quatd(*orientation)))
        mat.SetTranslation(Gf.Vec3d(*position))

        # mat.SetScale(Gf.Vec3d(*(self.get_world_scale() / self.scale)))
        # TODO (eric): understand why this (mat.setScale) works - this works empirically but it's unclear why.
        mat.SetScale(Gf.Vec3d(*(self.scale.astype(np.float64))))
        my_world_transform = np.transpose(mat.GetMatrix())

        parent_world_tf = UsdGeom.Xformable(get_prim_parent(self._prim)).ComputeLocalToWorldTransform(Usd.TimeCode.Default())
        parent_world_transform = np.transpose(parent_world_tf)

        local_transform = np.matmul(np.linalg.inv(parent_world_transform), my_world_transform)
        transform = Gf.Transform()
        transform.SetMatrix(Gf.Matrix4d(np.transpose(local_transform)))
        calculated_translation = transform.GetTranslation()
        calculated_orientation = transform.GetRotation().GetQuat()
        self.set_local_pose(
            translation=np.array(calculated_translation), orientation=gf_quat_to_np_array(calculated_orientation)[[1, 2, 3, 0]]     # Flip from w,x,y,z to x,y,z,w
        )

    def get_position_orientation(self):
        """
        Gets prim's pose with respect to the world's frame.

        Returns:
            2-tuple:
                - 3-array: (x,y,z) position in the world frame
                - 4-array: (x,y,z,w) quaternion orientation in the world frame
        """
        prim_tf = UsdGeom.Xformable(self._prim).ComputeLocalToWorldTransform(Usd.TimeCode.Default())
        transform = Gf.Transform()
        transform.SetMatrix(prim_tf)
        position = transform.GetTranslation()
        orientation = transform.GetRotation().GetQuat()
        return np.array(position), gf_quat_to_np_array(orientation)[[1, 2, 3, 0]]

    def set_position(self, position):
        """
        Set this prim's position with respect to the world frame

        Args:
            position (3-array): (x,y,z) global cartesian position to set
        """
        self.set_position_orientation(position=position)

    def get_position(self):
        """
        Get this prim's position with respect to the world frame

        Returns:
            3-array: (x,y,z) global cartesian position of this prim
        """
        return self.get_position_orientation()[0]

    def set_orientation(self, orientation):
        """
        Set this prim's orientation with respect to the world frame

        Args:
            orientation (4-array): (x,y,z,w) global quaternion orientation to set
        """
        self.set_position_orientation(orientation=orientation)

    def get_orientation(self):
        """
        Get this prim's orientation with respect to the world frame

        Returns:
            4-array: (x,y,z,w) global quaternion orientation of this prim
        """
        return self.get_position_orientation()[1]

    def get_rpy(self):
        """
        Get this prim's orientation with respect to the world frame

        Returns:
            3-array: (roll, pitch, yaw) global euler orientation of this prim
        """
        return mat2euler(quat2mat(self.get_orientation()))

    def get_local_pose(self):
        """
        Gets prim's pose with respect to the prim's local frame (it's parent frame)

        Returns:
            2-tuple:
                - 3-array: (x,y,z) position in the local frame
                - 4-array: (x,y,z,w) quaternion orientation in the local frame
        """
        xform_translate_op = self.get_attribute("xformOp:translate")
        xform_orient_op = self.get_attribute("xformOp:orient")
        return np.array(xform_translate_op), gf_quat_to_np_array(xform_orient_op)[[1, 2, 3, 0]]

    def set_local_pose(self, translation=None, orientation=None):
        """
        Sets prim's pose with respect to the local frame (the prim's parent frame).

        Args:
            translation (None or 3-array): if specified, (x,y,z) translation in the local frame of the prim
                (with respect to its parent prim). Default is None, which means left unchanged.
            orientation (None or 4-array): if specified, (x,y,z,w) quaternion orientation in the local frame of the prim
                (with respect to its parent prim). Default is None, which means left unchanged.
        """
        properties = self.prim.GetPropertyNames()
        if translation is not None:
            translation = Gf.Vec3d(*np.array(translation, dtype=float))
            if "xformOp:translate" not in properties:
                carb.log_error(
                    "Translate property needs to be set for {} before setting its position".format(self.name)
                )
            self.set_attribute("xformOp:translate", translation)
        if orientation is not None:
            orientation = np.array(orientation, dtype=float)[[3, 0, 1, 2]]
            if "xformOp:orient" not in properties:
                carb.log_error(
                    "Orient property needs to be set for {} before setting its orientation".format(self.name)
                )
            xform_op = self._prim.GetAttribute("xformOp:orient")
            if xform_op.GetTypeName() == "quatf":
                rotq = Gf.Quatf(*orientation)
            else:
                rotq = Gf.Quatd(*orientation)
            xform_op.Set(rotq)
        return

    def get_world_scale(self):
        """
        Gets prim's scale with respect to the world's frame.

        Returns:
            np.ndarray: scale applied to the prim's dimensions in the world frame. shape is (3, ).
        """
        prim_tf = UsdGeom.Xformable(self._prim).ComputeLocalToWorldTransform(Usd.TimeCode.Default())
        transform = Gf.Transform()
        transform.SetMatrix(prim_tf)
        return np.array(transform.GetScale())

    @property
    def scale(self):
        """
        Gets prim's scale with respect to the local frame (the parent's frame).

        Returns:
            np.ndarray: scale applied to the prim's dimensions in the local frame. shape is (3, ).
        """
        return np.array(self.get_attribute("xformOp:scale"))

    @scale.setter
    def scale(self, scale):
        """
        Sets prim's scale with respect to the local frame (the prim's parent frame).

        Args:
            scale (float or np.ndarray): scale to be applied to the prim's dimensions. shape is (3, ).
                                          Defaults to None, which means left unchanged.
        """
        scale = np.array(scale, dtype=float) if isinstance(scale, Iterable) else np.ones(3) * scale
        scale = Gf.Vec3d(*scale)
        properties = self.prim.GetPropertyNames()
        if "xformOp:scale" not in properties:
            carb.log_error("Scale property needs to be set for {} before setting its scale".format(self.name))
        self.set_attribute("xformOp:scale", scale)

    @property
    def aabb(self):
        """
        Get this xform's actual bounding box, axis-aligned in the world frame

        Returns:
            2-tuple:
                - 3-array: (x,y,z) lower corner of the bounding box
                - 3-array: (x,y,z) upper corner of the bounding box
        """
        return BoundingBoxAPI.compute_aabb(self.prim_path)

    @property
    def aabb_extent(self):
        """
        Get this xform's actual bounding box extent

        Returns:
            3-array: (x,y,z) bounding box
        """
        min_corner, max_corner = self.aabb
        return max_corner - min_corner

    @property
    def aabb_center(self):
        """
        Get this xform's actual bounding box center

        Returns:
            3-array: (x,y,z) bounding box center
        """
        min_corner, max_corner = self.aabb
        return (max_corner + min_corner) / 2.0

    @property
    def material(self):
        """
        Returns:
            None or MaterialPrim: The bound material to this prim, if there is one
        """
        return self._material

    @material.setter
    def material(self, material):
        """
        Set the material @material for this prim. This will also bind the material to this prim

        Args:
            material (MaterialPrim): Material to bind to this prim
        """
        self._binding_api.Bind(UsdShade.Material(material.prim), bindingStrength=UsdShade.Tokens.weakerThanDescendants)
        self._material = material

    def add_filtered_collision_pair(self, prim):
        """
        Adds a collision filter pair with another prim

        Args:
            prim (XFormPrim): Another prim to filter collisions with
        """
        # Add to both this prim's and the other prim's filtered pair
        self._collision_filter_api.GetFilteredPairsRel().AddTarget(prim.prim_path)
        prim._collision_filter_api.GetFilteredPairsRel().AddTarget(self._prim_path)

    def remove_filtered_collision_pair(self, prim):
        """
        Removes a collision filter pair with another prim

        Args:
            prim (XFormPrim): Another prim to remove filter collisions with
        """
        # Add to both this prim's and the other prim's filtered pair
        self._collision_filter_api.GetFilteredPairsRel().RemoveTarget(prim.prim_path)
        prim._collision_filter_api.GetFilteredPairsRel().RemoveTarget(self._prim_path)

    def _dump_state(self):
        pos, ori = self.get_position_orientation()
        return OrderedDict(pos=pos, ori=ori)

    def _load_state(self, state):
        self.set_position_orientation(np.array(state["pos"]), np.array(state["ori"]))

    def _serialize(self, state):
        # We serialize by iterating over the keys and adding them to a list that's concatenated at the end
        # This is a deterministic mapping because we assume the state is an OrderedDict
        return np.concatenate(list(state.values())).astype(float)

    def _deserialize(self, state):
        # We deserialize deterministically by knowing the order of values -- pos, ori
        return OrderedDict(pos=state[0:3], ori=state[3:7]), 7

aabb property

Get this xform's actual bounding box, axis-aligned in the world frame

Returns:

Type Description

2-tuple: - 3-array: (x,y,z) lower corner of the bounding box - 3-array: (x,y,z) upper corner of the bounding box

aabb_center property

Get this xform's actual bounding box center

Returns:

Type Description

3-array: (x,y,z) bounding box center

aabb_extent property

Get this xform's actual bounding box extent

Returns:

Type Description

3-array: (x,y,z) bounding box

material property writable

Returns:

Type Description

None or MaterialPrim: The bound material to this prim, if there is one

scale property writable

Gets prim's scale with respect to the local frame (the parent's frame).

Returns:

Type Description

np.ndarray: scale applied to the prim's dimensions in the local frame. shape is (3, ).

add_filtered_collision_pair(prim)

Adds a collision filter pair with another prim

Parameters:

Name Type Description Default
prim XFormPrim

Another prim to filter collisions with

required
Source code in prims/xform_prim.py
def add_filtered_collision_pair(self, prim):
    """
    Adds a collision filter pair with another prim

    Args:
        prim (XFormPrim): Another prim to filter collisions with
    """
    # Add to both this prim's and the other prim's filtered pair
    self._collision_filter_api.GetFilteredPairsRel().AddTarget(prim.prim_path)
    prim._collision_filter_api.GetFilteredPairsRel().AddTarget(self._prim_path)

get_local_pose()

Gets prim's pose with respect to the prim's local frame (it's parent frame)

Returns:

Type Description

2-tuple: - 3-array: (x,y,z) position in the local frame - 4-array: (x,y,z,w) quaternion orientation in the local frame

Source code in prims/xform_prim.py
def get_local_pose(self):
    """
    Gets prim's pose with respect to the prim's local frame (it's parent frame)

    Returns:
        2-tuple:
            - 3-array: (x,y,z) position in the local frame
            - 4-array: (x,y,z,w) quaternion orientation in the local frame
    """
    xform_translate_op = self.get_attribute("xformOp:translate")
    xform_orient_op = self.get_attribute("xformOp:orient")
    return np.array(xform_translate_op), gf_quat_to_np_array(xform_orient_op)[[1, 2, 3, 0]]

get_orientation()

Get this prim's orientation with respect to the world frame

Returns:

Type Description

4-array: (x,y,z,w) global quaternion orientation of this prim

Source code in prims/xform_prim.py
def get_orientation(self):
    """
    Get this prim's orientation with respect to the world frame

    Returns:
        4-array: (x,y,z,w) global quaternion orientation of this prim
    """
    return self.get_position_orientation()[1]

get_position()

Get this prim's position with respect to the world frame

Returns:

Type Description

3-array: (x,y,z) global cartesian position of this prim

Source code in prims/xform_prim.py
def get_position(self):
    """
    Get this prim's position with respect to the world frame

    Returns:
        3-array: (x,y,z) global cartesian position of this prim
    """
    return self.get_position_orientation()[0]

get_position_orientation()

Gets prim's pose with respect to the world's frame.

Returns:

Type Description

2-tuple: - 3-array: (x,y,z) position in the world frame - 4-array: (x,y,z,w) quaternion orientation in the world frame

Source code in prims/xform_prim.py
def get_position_orientation(self):
    """
    Gets prim's pose with respect to the world's frame.

    Returns:
        2-tuple:
            - 3-array: (x,y,z) position in the world frame
            - 4-array: (x,y,z,w) quaternion orientation in the world frame
    """
    prim_tf = UsdGeom.Xformable(self._prim).ComputeLocalToWorldTransform(Usd.TimeCode.Default())
    transform = Gf.Transform()
    transform.SetMatrix(prim_tf)
    position = transform.GetTranslation()
    orientation = transform.GetRotation().GetQuat()
    return np.array(position), gf_quat_to_np_array(orientation)[[1, 2, 3, 0]]

get_rpy()

Get this prim's orientation with respect to the world frame

Returns:

Type Description

3-array: (roll, pitch, yaw) global euler orientation of this prim

Source code in prims/xform_prim.py
def get_rpy(self):
    """
    Get this prim's orientation with respect to the world frame

    Returns:
        3-array: (roll, pitch, yaw) global euler orientation of this prim
    """
    return mat2euler(quat2mat(self.get_orientation()))

get_world_scale()

Gets prim's scale with respect to the world's frame.

Returns:

Type Description

np.ndarray: scale applied to the prim's dimensions in the world frame. shape is (3, ).

Source code in prims/xform_prim.py
def get_world_scale(self):
    """
    Gets prim's scale with respect to the world's frame.

    Returns:
        np.ndarray: scale applied to the prim's dimensions in the world frame. shape is (3, ).
    """
    prim_tf = UsdGeom.Xformable(self._prim).ComputeLocalToWorldTransform(Usd.TimeCode.Default())
    transform = Gf.Transform()
    transform.SetMatrix(prim_tf)
    return np.array(transform.GetScale())

has_material()

Returns:

Name Type Description
bool

True if there is a visual material bound to this prim. False otherwise

Source code in prims/xform_prim.py
def has_material(self):
    """
    Returns:
        bool: True if there is a visual material bound to this prim. False otherwise
    """
    material_path = self._binding_api.GetDirectBinding().GetMaterialPath().pathString
    return False if material_path == "" else True

remove_filtered_collision_pair(prim)

Removes a collision filter pair with another prim

Parameters:

Name Type Description Default
prim XFormPrim

Another prim to remove filter collisions with

required
Source code in prims/xform_prim.py
def remove_filtered_collision_pair(self, prim):
    """
    Removes a collision filter pair with another prim

    Args:
        prim (XFormPrim): Another prim to remove filter collisions with
    """
    # Add to both this prim's and the other prim's filtered pair
    self._collision_filter_api.GetFilteredPairsRel().RemoveTarget(prim.prim_path)
    prim._collision_filter_api.GetFilteredPairsRel().RemoveTarget(self._prim_path)

set_local_pose(translation=None, orientation=None)

Sets prim's pose with respect to the local frame (the prim's parent frame).

Parameters:

Name Type Description Default
translation None or 3-array

if specified, (x,y,z) translation in the local frame of the prim (with respect to its parent prim). Default is None, which means left unchanged.

None
orientation None or 4-array

if specified, (x,y,z,w) quaternion orientation in the local frame of the prim (with respect to its parent prim). Default is None, which means left unchanged.

None
Source code in prims/xform_prim.py
def set_local_pose(self, translation=None, orientation=None):
    """
    Sets prim's pose with respect to the local frame (the prim's parent frame).

    Args:
        translation (None or 3-array): if specified, (x,y,z) translation in the local frame of the prim
            (with respect to its parent prim). Default is None, which means left unchanged.
        orientation (None or 4-array): if specified, (x,y,z,w) quaternion orientation in the local frame of the prim
            (with respect to its parent prim). Default is None, which means left unchanged.
    """
    properties = self.prim.GetPropertyNames()
    if translation is not None:
        translation = Gf.Vec3d(*np.array(translation, dtype=float))
        if "xformOp:translate" not in properties:
            carb.log_error(
                "Translate property needs to be set for {} before setting its position".format(self.name)
            )
        self.set_attribute("xformOp:translate", translation)
    if orientation is not None:
        orientation = np.array(orientation, dtype=float)[[3, 0, 1, 2]]
        if "xformOp:orient" not in properties:
            carb.log_error(
                "Orient property needs to be set for {} before setting its orientation".format(self.name)
            )
        xform_op = self._prim.GetAttribute("xformOp:orient")
        if xform_op.GetTypeName() == "quatf":
            rotq = Gf.Quatf(*orientation)
        else:
            rotq = Gf.Quatd(*orientation)
        xform_op.Set(rotq)
    return

set_orientation(orientation)

Set this prim's orientation with respect to the world frame

Parameters:

Name Type Description Default
orientation 4-array

(x,y,z,w) global quaternion orientation to set

required
Source code in prims/xform_prim.py
def set_orientation(self, orientation):
    """
    Set this prim's orientation with respect to the world frame

    Args:
        orientation (4-array): (x,y,z,w) global quaternion orientation to set
    """
    self.set_position_orientation(orientation=orientation)

set_position(position)

Set this prim's position with respect to the world frame

Parameters:

Name Type Description Default
position 3-array

(x,y,z) global cartesian position to set

required
Source code in prims/xform_prim.py
def set_position(self, position):
    """
    Set this prim's position with respect to the world frame

    Args:
        position (3-array): (x,y,z) global cartesian position to set
    """
    self.set_position_orientation(position=position)

set_position_orientation(position=None, orientation=None)

Sets prim's pose with respect to the world frame

Parameters:

Name Type Description Default
position None or 3-array

if specified, (x,y,z) position in the world frame Default is None, which means left unchanged.

None
orientation None or 4-array

if specified, (x,y,z,w) quaternion orientation in the world frame. Default is None, which means left unchanged.

None
Source code in prims/xform_prim.py
def set_position_orientation(self, position=None, orientation=None):
    """
    Sets prim's pose with respect to the world frame

    Args:
        position (None or 3-array): if specified, (x,y,z) position in the world frame
            Default is None, which means left unchanged.
        orientation (None or 4-array): if specified, (x,y,z,w) quaternion orientation in the world frame.
            Default is None, which means left unchanged.
    """
    current_position, current_orientation = self.get_position_orientation()
    position = current_position if position is None else np.array(position, dtype=float)
    orientation = current_orientation if orientation is None else np.array(orientation, dtype=float)
    orientation = orientation[[3, 0, 1, 2]]     # Flip from x,y,z,w to w,x,y,z

    mat = Gf.Transform()
    mat.SetRotation(Gf.Rotation(Gf.Quatd(*orientation)))
    mat.SetTranslation(Gf.Vec3d(*position))

    # mat.SetScale(Gf.Vec3d(*(self.get_world_scale() / self.scale)))
    # TODO (eric): understand why this (mat.setScale) works - this works empirically but it's unclear why.
    mat.SetScale(Gf.Vec3d(*(self.scale.astype(np.float64))))
    my_world_transform = np.transpose(mat.GetMatrix())

    parent_world_tf = UsdGeom.Xformable(get_prim_parent(self._prim)).ComputeLocalToWorldTransform(Usd.TimeCode.Default())
    parent_world_transform = np.transpose(parent_world_tf)

    local_transform = np.matmul(np.linalg.inv(parent_world_transform), my_world_transform)
    transform = Gf.Transform()
    transform.SetMatrix(Gf.Matrix4d(np.transpose(local_transform)))
    calculated_translation = transform.GetTranslation()
    calculated_orientation = transform.GetRotation().GetQuat()
    self.set_local_pose(
        translation=np.array(calculated_translation), orientation=gf_quat_to_np_array(calculated_orientation)[[1, 2, 3, 0]]     # Flip from w,x,y,z to x,y,z,w
    )