I believe I have tracked this back to the ComputeInstanceTransformsAtTime method of the PointInstancer, as I can re-create this using an inlinelop and a pythonlop.
Here I have some USD representing a smaller section of a circle, instancing a simple box. Pop this into the inlinelop.
#sdf 1.4.32 def PointInstancer "my_instancer" { int64[] invisibleIds = [] quath[] orientations = [(0.998535, 0, 0, -0.0565186), (0.999023, 0, 0, -0.0439758), (0.999512, 0, 0, -0.0314026), (1, 0, 0, -0.0188446), (1, 0, 0, -0.00628281), (1, 0, 0, 0.00628281), (1, 0, 0, 0.0188446), (0.999512, 0, 0, 0.0314026), (0.999023, 0, 0, 0.0439758), (0.998535, 0, 0, 0.0565186)] point3f[] positions = [(-8.911743, 0.5044851, 0), (-6.937198, 0.30531064, 0), (-4.9582753, 0.15582031, 0), (-2.9762185, 0.05610727, 0), (-0.99228066, 0.006234976, 0), (0.99228066, 0.006234976, 0), (2.976217, 0.056106895, 0), (4.958278, 0.15581957, 0), (6.9371996, 0.30531064, 0), (8.911743, 0.5044858, 0)] int[] protoIndices = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] rel prototypes = </my_instancer/Prototypes/Root> def Scope "Prototypes" { def Xform "Root" ( ) { def Cube "cube" ( ) { double size = 2 } } } }
Here is a snippet to go into a pythonlop iterating over the instances, and grabbing the matrix from the point, and applying it to the new prims Xform. If I compare their orients after this, I can see a small discrepancy near the pole.
node = hou.pwd() stage = node.editableStage() import pxr prim = stage.GetPrimAtPath("/my_instancer") instancer = pxr.UsdGeom.PointInstancer(prim) orients = instancer.GetOrientationsAttr().Get() xforms = instancer.ComputeInstanceTransformsAtTime(pxr.Usd.TimeCode.Default(), pxr.Usd.TimeCode.Default()) for index, xform in enumerate(xforms): xform_prim = pxr.UsdGeom.Xform.Define(stage, '/cube_grp{}'.format(index)) cube_prim = pxr.UsdGeom.Cube.Define(stage, '/cube_grp{}/cube'.format(index)) cube_prim.GetDisplayColorAttr().Set([(1, 0, 0)]) xform_prim.AddTransformOp(opSuffix="from_instancer").Set(xform) prim_orient = xform_prim.GetLocalTransformation().ExtractRotation().GetQuat() prim_quat_h = pxr.Gf.Quath(prim_orient) # I have converted the Quatd to a Quath to match the types print "xform prim orient:" print prim_quat_h print "instancer point orient:" print orients[index] match = prim_quat_h == orients[index] # This will error assert match == True
you will see a small shift in the rotation, and the angle between the 2 quaternions is slightly off. If you use a lopimport sop in SOPS, you will also visually see the shift as I have colored the prims red. Is this something that will first need to be fixed on the USD side? Or is this something to do with the formatting of the orientations?
Cheers,
Aaron.