Created
December 27, 2023 17:23
-
-
Save BigRoy/415669c52de00a0b31e3969ed3fc2417 to your computer and use it in GitHub Desktop.
Create Default Assembly Rig Setup as shown in How RISE VFX Reached New Creative Heights with USD in Maya talk
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Create Default Assembly Rig Setup as shown in How RISE VFX Reached New Creative Heights with USD in Maya talk | |
See: https://youtu.be/8UIW-g1_heg?t=1902 | |
""" | |
import pxr | |
import ufe | |
import pymel.core as pm | |
from mayaUsd import lib as mayaUsdLib | |
USD_SCHEMA = "UsdSchemaBase" | |
def create_default_assembly_rig_setup(assembly_rig_stage_shape, rig_grp, stage_driver_grp): | |
"""Create default assembly rig setup. | |
Args: | |
assembly_rig_stage_shape (pm.PyNode): Maya USD Proxy Shape to transform. | |
This should reference a USD file with a default prim defined. | |
rig_grp (pm.PyNode): Maya group that should act as the rig group | |
stage_driver_grp (pm.PyNode): Group in which the locator should be | |
placed that can be moved around. | |
""" | |
stage = mayaUsdLib.GetPrim(assembly_rig_stage_shape.name(long=True)).GetStage() | |
# create default control setup | |
grp = pm.group(name='root_001_TRN', empty=True) | |
pm.group(name="root_001_OFFSET") | |
root_grp = pm.group(name="root_001_GRP") | |
root_ctrl = pm.circle(c=(0, 0, 0), normal=(0, 1, 0), sweep=360, radius=10, degree=3, ut=0, tol=0.01, s=8, constructionHistory=False, name="root_001_CTRL")[0] | |
root_ctrl.overrideEnabled.set(True) | |
root_ctrl.overrideColor.set(17) | |
pm.parent(root_ctrl, grp) | |
# create default control setup | |
grp = pm.group(name='rootOffset_001_TRN', empty=True) | |
pm.group(name="rootOffset_001_OFFSET") | |
root_offset_grp = pm.group(name="rootOffset_001_GRP") | |
root_offset_ctrl = pm.circle(c=(0, 0, 0), normal=(0, 1, 0), sweep=360, radius=10, degree=3, ut=0, tol=0.01, s=8, constructionHistory=False, name="rootOffset_001_CTRL")[0] | |
pm.parent(root_offset_ctrl, grp) | |
pm.parent(root_offset_grp, grp) | |
# parent control setup under rig group | |
pm.parent(root_grp, rig_grp) | |
pm.select(clear=True) | |
# create the stage root driver as an locator and parent under driver group | |
locator = pm.spaceLocator('root_LOC') | |
pm.parent(locator, stage_driver_grp) | |
pm.parentConstraint(root_offset_ctrl, locator, maintainOffset=False) | |
pm.scaleConstraint(root_offset_ctrl, locator) | |
# get default prim path, and build selection string to stage default prim | |
root_prim_path = str(stage.GetDefaultPrim().GetPath()) | |
stage_selection = "{}.{}".format( | |
assembly_rig_stage_shape.name(long=True), root_prim_path | |
) | |
# create connection to default/root prim | |
pm.select([stage_selection, locator]) | |
def connect_maya_node_to_usd_prim(translate_op=True, rotate_op=True, scale_op=True): | |
"""Select two objects, one xformable prim in Maya USD Proxy and a maya native transform | |
Then running this function will connect the maya transform to the xformable prim as | |
driven transforms. | |
""" | |
global_selection = ufe.GlobalSelection.get() | |
ufe_object = global_selection.front() | |
if USD_SCHEMA not in ufe_object.ancestorNodeTypes(): | |
return | |
stage_path, prim_path = mayaUsdLib.proxyAccessor.getDagAndPrimFromUfe(ufe_object) | |
stage_shape = pm.PyNode(stage_path) | |
stage = mayaUsdLib.GetPrim(stage_path).GetStage() | |
prim = stage.GetPrimAtPath(prim_path) | |
maya_node = pm.ls(selection=True)[0] | |
x_formable = pxr.UsdGeom.Xformable(prim) | |
if translate_op and not prim.GetAttribute("xformOp:translate").IsValid(): | |
translate = x_formable.AddTranslateOp() | |
translate.Set(pxr.Gf.Vec3f([0, 0, 0])) | |
if rotate_op and not prim.GetAttribute("xformOp:rotateXYZ").IsValid(): | |
rotate = x_formable.AddRotateXYZOp() | |
rotate.Set(pxr.Gf.Vec3f([0, 0, 0])) | |
if scale_op and not prim.GetAttribute("xformOp:scale").IsValid(): | |
scale = x_formable.AddScaleOp() | |
scale.Set(pxr.Gf.Vec3f([1, 1, 1])) | |
reset_set = ["!resetXformStack!"] | |
if translate_op: | |
reset_set.append("xformOp:translate") | |
if rotate_op: | |
reset_set.append("xformOp:rotateXYZ") | |
if scale_op: | |
reset_set.append("xformOp:scale") | |
prim.GetAttribute("xformOpOrder").Set(reset_set) | |
for src_attr, target_attr_name in { | |
maya_node.translate: "xformOp:translate", | |
maya_node.rotate: "xformOp:rotateXYZ", | |
maya_node.scale: "xformOp:scale", | |
}.items(): | |
accessor = mayaUsdLib.proxyAccessor.getOrCreateAccessPlug(ufeObject=ufe_object, usdAttrName=target_attr_name) | |
accessor_attr = stage_shape.attr(accessor) | |
pm.connectAttr(src_attr, accessor_attr, force=True) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Just connect a maya native object to control transform of an object inside Maya USD Proxy shape, without pymel: