def add_top_level_ctrl(origCtrl, type, geo, *args):
"""
creates a new ctrl, orients it to the geo and parent constrains the orig ctrl rig under itself
:param origCtrl: the control we're working from
:param type: the ctrl type of shape see zbw_rig.createControl for options
:param geo: the geo to orient to
:param args:
:return: topCtrl (the new ctrl), grp (the top ctrl grp freeze grp)
"""
# THIS IS THE XTRA CTRL LAYER, THIS ORIENTS CTRL AND CONNECTS ORIG CTRL TO THE NEW CTRL
origCtrlPos = cmds.xform(origCtrl, q=True, ws=True, rp=True)
topCtrl = rig.createControl(name="{0}_moveCtrl".format(origCtrl.rpartition("_")[0]), type=type, axis="z",
color="yellow")
grp = rig.groupFreeze(topCtrl)
cmds.xform(grp, ws=True, t=origCtrlPos)
nc = cmds.normalConstraint(geo, grp, worldUpType="vector", upVector=(0, 1, 0))
cmds.delete(nc)
pc = cmds.parentConstraint(topCtrl, origCtrl, mo=True)
sc = cmds.scaleConstraint(topCtrl, origCtrl, mo=True)
return(topCtrl, grp)
python类parent()的实例源码
def _output_node(source, type, suffix):
newname = lib.unique(name=source.rsplit("_", 1)[0] + suffix)
node = cmds.createNode(type)
node = [cmds.listRelatives(node, parent=True) or node][0]
node = cmds.rename(node, newname)
try:
cmds.parent(node, source)
match_transform(node, source)
except Exception:
cmds.warning("Could not create %s" % node)
cmds.delete(node)
return node
def follicle(shape, u=0, v=0, name=""):
"""Attach follicle to "shape" at specified "u" and "v" values"""
type = cmds.nodeType(shape)
assert type in ("mesh", "nurbsSurface"), (
"follicle() works on polygonal meshes and nurbs")
src, dst = {
"mesh": (".outMesh", ".inputMesh"),
"nurbsSurface": (".local", ".inputSurface")
}[type]
follicle = cmds.createNode("follicle", name=name + "Shape")
transform = cmds.listRelatives(follicle, parent=True)[0]
cmds.setAttr(follicle + ".parameterU", u)
cmds.setAttr(follicle + ".parameterV", v)
cmds.connectAttr(follicle + ".outTranslate", transform + ".translate")
cmds.connectAttr(follicle + ".outRotate", transform + ".rotate")
cmds.connectAttr(shape + ".worldMatrix[0]", follicle + ".inputWorldMatrix")
cmds.connectAttr(shape + src, follicle + dst, force=True)
return transform
def orient_to_world(joints):
"""Orients the given joints with the world.
@param joints: Joints to orient.
"""
for joint in joints:
children = _unparent_children(joint)
print children
parent = cmds.listRelatives(joint, parent=True, path=True)
orig_joint = joint.split('|')[-1]
if parent:
joint = cmds.parent(joint, world=True)[0]
cmds.joint(joint, e=True, oj='none', zso=True)
if parent:
joint = cmds.parent(joint, parent)[0]
print 'Renaming {0} to {1}'.format(joint, orig_joint)
joint = cmds.rename(joint, orig_joint)
_reparent_children(joint, children)
if joints:
cmds.select(joints)
def create_node(node_dictionary, parent=None):
"""Create the Maya node described by the given data dictionary.
:param node_dictionary: The data dictionary generated by one of the load/get functions.
:param parent: The node to parent the created node to.
"""
node = cmds.createNode(node_dictionary['nodeType'], name=node_dictionary['name'])
if parent:
cmds.parent(node, parent)
cmds.setAttr('{0}.t'.format(node), *node_dictionary['translate'])
cmds.setAttr('{0}.r'.format(node), *node_dictionary['rotate'])
cmds.setAttr('{0}.s'.format(node), *node_dictionary['scale'])
cmds.setAttr('{0}.rotateOrder'.format(node), node_dictionary['rotateOrder'])
cmds.setAttr('{0}.rotateAxis'.format(node), *node_dictionary['rotateAxis'])
if node_dictionary['nodeType'] == 'joint':
cmds.setAttr('{0}.jointOrient'.format(node), *node_dictionary['jointOrient'])
cmds.setAttr('{0}.radius'.format(node), node_dictionary['radius'])
cmds.setAttr('{0}.side'.format(node), node_dictionary['side'])
cmds.setAttr('{0}.type'.format(node), node_dictionary['type'])
cmds.setAttr('{0}.otherType'.format(node), node_dictionary['otherType'], type='string')
cmds.setAttr('{0}.jointTypeX'.format(node), node_dictionary['jointTypeX'])
cmds.setAttr('{0}.jointTypeY'.format(node), node_dictionary['jointTypeY'])
cmds.setAttr('{0}.jointTypeZ'.format(node), node_dictionary['jointTypeZ'])
for child in node_dictionary.get('children', []):
create_node(child, node)
def mirror(joint, search_for, replace_with):
joints = [joint, ] + (cmds.listRelatives(joint, ad=True, path=True) or [])
for joint in joints:
mirrored_joint = joint.replace(search_for, replace_with)
if cmds.objExists(mirrored_joint):
translate = list(cmds.getAttr('{0}.t'.format(joint))[0])
parent = cmds.listRelatives(joint, parent=True, path=True)
if parent and search_for not in parent[0]:
translate[2] *= -1.0
else:
translate = [x * -1.0 for x in translate]
cmds.setAttr('{0}.t'.format(mirrored_joint), *translate)
rotate = cmds.getAttr('{0}.r'.format(joint))[0]
cmds.setAttr('{0}.r'.format(mirrored_joint), *rotate)
scale = cmds.getAttr('{0}.s'.format(joint))[0]
cmds.setAttr('{0}.s'.format(mirrored_joint), *scale)
def get_stack_parent(node):
"""Get the parent of the transform stack belonging to the given node.
:param node: Node to query.
:return: The parent node or None if there is no parent.
"""
previous_parent = cmds.listRelatives(node, parent=True, path=True)
if not previous_parent:
return None
previous_parent = previous_parent[0]
while previous_parent and STACK_ATTRIBUTE in (cmds.listAttr(previous_parent, ud=True) or []):
parent = cmds.listRelatives(previous_parent, parent=True, path=True)
if parent:
parent = parent[0]
previous_parent = parent
return previous_parent
def setUp(self):
self.group = cmds.createNode('transform', name='skeleton_grp')
cmds.select(cl=True)
j1 = cmds.joint(p=(0, 10, 0))
cmds.joint(p=(1, 9, 0))
cmds.joint(p=(2, 8, 0))
j = cmds.joint(p=(3, 9, 0))
cmds.joint(p=(4, 6, 0))
cmds.joint(p=(5, 5, 0))
cmds.joint(p=(6, 3, 0))
self.cube = cmds.polyCube()[0]
cmds.parent(self.cube, j)
cmds.parent(j1, self.group)
self.translates = [cmds.getAttr('{0}.t'.format(x))[0] for x in cmds.ls(type='joint')]
self.rotates = [cmds.getAttr('{0}.r'.format(x))[0] for x in cmds.ls(type='joint')]
self.orients = [cmds.getAttr('{0}.jo'.format(x))[0] for x in cmds.ls(type='joint')]
def curve_to_hair(curve_shape, hair_system):
curve = cmds.listRelatives(curve_shape, parent=True, f=True)[0]
curve_name = curve.split('|')[-1]
# Create follicle
follicle_shape = cmds.createNode('follicle')
follicle = cmds.listRelatives(follicle_shape, parent=True, f=True)[0]
follicle = cmds.rename(follicle, curve_name + '_follicle#')
follicle_shape = cmds.listRelatives(follicle, shapes=True, f=True)[0]
cmds.connectAttr(curve + '.worldMatrix', follicle_shape + '.startPositionMatrix')
cmds.connectAttr(curve_shape + '.local', follicle_shape + '.startPosition')
# # Create output curve
out_curve_shape = cmds.createNode('nurbsCurve')
out_curve = cmds.listRelatives(out_curve_shape, parent=True, f=True)[0]
out_curve = cmds.rename(out_curve, curve_name + '_out#')
out_curve_shape = cmds.listRelatives(out_curve, shapes=True, f=True)[0]
cmds.connectAttr(follicle + '.outCurve', out_curve_shape + '.create')
# Add follicle to hair system
add_follicle(follicle_shape, hair_system)
return [[follicle, follicle_shape], [out_curve, out_curve_shape]]
def add_curve_to_system(curve_shape, hair_system=None):
if hair_system is None:
selection = cmds.ls(sl=True, dag=True, leaf=True, type='hairSystem')
if selection:
hair_system = selection[0]
else:
hair_system = create_hair_system()
follicle_nodes, out_curve_nodes = curve_to_hair(curve_shape, hair_system)
follicles_grp = hair_system + 'Follicles'
if not cmds.objExists(follicles_grp):
cmds.group(empty=True, name=follicles_grp)
cmds.parent(follicle_nodes[0], follicles_grp)
outcurves_grp = hair_system + 'OutputCurves'
if not cmds.objExists(outcurves_grp):
cmds.group(empty=True, name=outcurves_grp)
cmds.parent(out_curve_nodes[0], outcurves_grp)
return follicle_nodes
def insertGroupAbove(*args):
sel = cmds.ls(sl=True)
for obj in sel:
par = cmds.listRelatives(obj, p=True)
grp = cmds.group(em=True, n="{}_Grp".format(obj))
# grp = nameCheck(grp)
pos = cmds.xform(obj, q=True, ws=True, rp=True)
rot = cmds.xform(obj, q=True, ws=True, ro=True)
cmds.xform(grp, ws=True, t=pos)
cmds.xform(grp, ws=True, ro=rot)
cmds.parent(obj, grp)
if par:
cmds.parent(grp, par[0])
def freezeAndConnect(*args):
sel = cmds.ls(sl=True)
ctrlOrig = sel[0]
for x in range(1, len(sel)):
obj = sel[x]
ctrl = cmds.duplicate(ctrlOrig, n = "{}Ctrl".format(obj))[0]
pos = cmds.xform(obj, ws=True, q=True, rp=True)
rot = cmds.xform(obj, ws=True, q=True, ro=True)
grp = cmds.group(em=True, n="{}Grp".format(ctrl))
cmds.parent(ctrl, grp)
cmds.xform(grp, ws=True, t=pos)
cmds.xform(grp, ws=True, ro=rot)
cmds.parentConstraint(ctrl, obj)
def capReplace(*args):
sel = cmds.ls(sl=True, type="transform")
if sel < 2:
cmds.warning("You don't have two things selected (cap and one ctrl minimum)!")
return
newCap = sel[0]
ctrls = sel[1:]
for ctrl in ctrls:
oldCap = cmds.connectionInfo("{0}.capRig".format(ctrl), sfd=True).partition(".")[0]
dupe = rig.swapDupe(newCap, oldCap, delete=True, name=oldCap)
cmds.connectAttr("{0}.rotateCap".format(ctrl), "{0}.rotateY".format(dupe))
cmds.connectAttr("{0}.message".format(dupe), "{0}.capRig".format(ctrl))
cmds.setAttr("{0}.v".format(dupe), 1)
# if not already, parent cap replace obj in folder and hide
par = cmds.listRelatives(newCap, p=True)
if not par or par[0] != "pastaRigSetupComponents_Grp":
cmds.parent(newCap, "pastaRigSetupComponents_Grp")
cmds.setAttr("{0}.v".format(newCap), 0)
cmds.select(ctrls, r=True)
def addBaseCap(*args):
sel = cmds.ls(sl=True, type="transform")
if sel < 2:
cmds.warning("You don't have two things selected (cap and one ctrl minimum)!")
return
newCap = sel[0]
ctrls = sel[1:]
for ctrl in ctrls:
tempCap = cmds.connectionInfo("{0}.tempBaseCap".format(ctrl), sfd=True).partition(".")[0]
dupe = rig.swapDupe(newCap, tempCap, delete=True, name="{0}_baseCap".format(ctrl))
cmds.setAttr("{0}.v".format(dupe), 1)
cmds.connectAttr("{0}.rotateBaseCap".format(ctrl), "{0}.rotateY".format(dupe))
cmds.connectAttr("{0}.message".format(dupe), "{0}.tempBaseCap".format(ctrl))
# if not already, parent cap replace obj in folder and hide
par = cmds.listRelatives(newCap, p=True)
if not par or par[0] != "pastaRigSetupComponents_Grp":
cmds.parent(newCap, "pastaRigSetupComponents_Grp")
cmds.setAttr("{0}.v".format(newCap), 0)
cmds.select(ctrls, r=True)
def addGroupAbove(obj="none", suff="none", *args):
"""name of existing obj, new group suffix. New group will be oriented to the object BELOW it"""
#FIX THE OBJ, SUFIX TO BE EITHER SELECTED OR ENTERED
sel = cmds.ls(sl=True, type = "transform")
for obj in sel:
suff = "_new"
name = obj + suff + "_GRP"
#get worldspace location of existing obj
loc = cmds.xform(obj, q=True, ws=True, rp=True)
#create new group, name it, move it to new postion in ws and Orient it
grp = cmds.group(empty=True, name=name)
cmds.move(loc[0], loc[1], loc[2], grp, ws=True)
oc = cmds.orientConstraint(obj, grp)
cmds.delete(oc)
#check if there's a parent to the old group
par = cmds.listRelatives(obj, p=True)
print(par)
if par:
cmds.parent(grp, par)
cmds.parent(obj, grp)
def insertGroupAbove(obj, *args):
par = cmds.listRelatives(obj, p=True)
grp = cmds.group(em=True, n="{}_Grp".format(obj))
# grp = nameCheck(grp)
pos = cmds.xform(obj, q=True, ws=True, rp=True)
rot = cmds.xform(obj, q=True, ws=True, ro=True)
cmds.xform(grp, ws=True, t=pos)
cmds.xform(grp, ws=True, ro=rot)
cmds.parent(obj, grp)
if par:
cmds.parent(grp, par[0])
return(grp)
def makeSequence(obj = "", name = "", frameStart = 0, frameEnd = 1, step = 1):
"""duplicate selected geo based on settings from UI"""
dupes = []
numCopies = (frameEnd-frameStart)/step
#check here if we want to create more than 25 duplicates?
confirm = cmds.confirmDialog(t="Confirm", m= "This will create %d copies of %s. \nFrames: %d to %d\nFor dense meshes, this could get heavy\nAre you sure you want to do this?"%(numCopies, obj, frameStart, frameEnd), button = ["Yes", "No"], cancelButton = "No")
if confirm == "Yes":
for frame in range(frameStart, frameEnd + 1, step):
cmds.currentTime(frame, edit=True)
dupe = cmds.duplicate(obj, n="%s_%d"%(name, frame), ic = False, un = False)
dupes.append(dupe)
if dupes:
grp = cmds.group(em = True, n = "%s_GRP"%name)
for dupe in dupes:
cmds.parent(dupe, grp)
#cmds.currentTime(currentFrame, e=True)
def applyBrush(curve, parent):
'''
Simply applies the paint effects brush to the curve with the settings we want.
'''
mc.AttachBrushToCurves(curve)
stroke = mc.ls(sl=True)[0]
stroke = mc.parent(stroke,parent)[0]
mc.setAttr(stroke+'.displayPercent',92)
mc.setAttr(stroke+'.sampleDensity',0.5)
mc.setAttr(stroke+'.inheritsTransform',0)
mc.setAttr(stroke+'.translate',0,0,0)
mc.setAttr(stroke+'.rotate',0,0,0)
return stroke
def isNodeVisible(node):
'''
Simply return whether or not the node can be seen.
'''
if not mc.attributeQuery('visibility', node=node, exists=True):
return False
if not mc.getAttr(node+'.v'):
return False
if mc.attributeQuery('intermediateObject', node=node, exists=True):
if mc.getAttr(node+'.intermediateObject'):
return False
if not mc.getAttr(node+'.lodVisibility'):
return False
if mc.getAttr(node+'.overrideEnabled') and not mc.getAttr(node+'.overrideVisibility'):
return False
parent = mc.listRelatives(node, parent=True, pa=True)
if parent:
return isNodeVisible(parent[0])
return True
def toLocators(bakeOnOnes=False, space='world', spaceInt=None, constrainSource=False):
'''
Creates locators, and bakes their position to selection.
Creates connections to the source objects, so they can
be found later to bake back.
'''
if spaceInt and 0 <= spaceInt <= 2:
space = ['world', 'camera', 'last'][spaceInt]
sel = mc.ls(sl=True)
parent = None
if space == 'camera':
parent = utl.getCurrentCamera()
elif space == 'last':
parent = sel[-1]
sel = sel[:-1]
mc.select(sel)
matchBakeLocators(parent=parent, bakeOnOnes=bakeOnOnes, constrainSource=constrainSource)
def match_transform(src, dst):
"""Transform `src` to `dst`, taking worldspace into account
Arguments:
src (str): Absolute path to source transform
dst (str): Absolute path to destination transform
"""
try:
parent = cmds.listRelatives(src, parent=True)[0]
except Exception:
parent = None
node_decompose = cmds.createNode("decomposeMatrix")
node_multmatrix = cmds.createNode("multMatrix")
connections = {
dst + ".worldMatrix": node_multmatrix + ".matrixIn[0]",
node_multmatrix + ".matrixSum": node_decompose + ".inputMatrix",
node_decompose + ".outputTranslate": src + ".translate",
node_decompose + ".outputRotate": src + ".rotate",
node_decompose + ".outputScale": src + ".scale",
}
if parent:
connections.update({
parent + ".worldInverseMatrix": node_multmatrix + ".matrixIn[1]"
})
for s, d in connections.iteritems():
cmds.connectAttr(s, d, force=True)
cmds.refresh()
cmds.delete([node_decompose, node_multmatrix])
def parent_group(source, transferTransform=True):
"""Create and transfer transforms to parent group"""
assert cmds.objExists(source), "%s does not exist" % source
assert cmds.nodeType(source) == "transform", (
"%s must be transform" % source)
parent = cmds.listRelatives(source, parent=True)
if transferTransform:
group = cmds.createNode("transform", n="%s_parent" % source)
match_transform(group, source)
try:
cmds.parent(source, group)
except Exception:
cmds.warning("Failed to parent child under new parent")
cmds.delete(group)
if parent:
cmds.parent(group, parent[0])
else:
cmds.select(source)
group = cmds.group(n="%s_parent" % source)
return group
def enhanced_parent(child, parent):
if "shape" in cmds.nodeType(child, inherited=True):
cmds.parent(relative=True, shape=True)
else:
cmds.parent(child, parent)
def get_shape(node, intermediate=False):
"""Get the shape node of a tranform
This is useful if you don't want to have to check if a node is a shape node
or transform. You can pass in a shape node or transform and the function
will return the shape node.
:param node: node The name of the node.
:param intermediate: intermediate True to get the intermediate shape
:return: The name of the shape node.
"""
if cmds.nodeType(node) == 'transform':
shapes = cmds.listRelatives(node, shapes=True, path=True)
if not shapes:
shapes = []
for shape in shapes:
is_intermediate = cmds.getAttr('%s.intermediateObject' % shape)
if intermediate and is_intermediate and cmds.listConnections(shape, source=False):
return shape
elif not intermediate and not is_intermediate:
return shape
if shapes:
return shapes[0]
elif cmds.nodeType(node) in ['mesh', 'nurbsCurve', 'nurbsSurface']:
is_intermediate = cmds.getAttr('%s.intermediateObject' % node)
if is_intermediate and not intermediate:
node = cmds.listRelatives(node, parent=True, path=True)[0]
return get_shape(node)
else:
return node
return None
def __init__(self, parent=None):
self.children = []
self._parent = parent
if parent is not None:
parent.add_child(self)
def parent(self):
"""Get the parent of node"""
return self._parent
def row(self):
"""Get the index of the node relative to the parent"""
if self._parent is not None:
return self._parent.children.index(self)
return 0
def duplicate_chain(start, end, prefix='', suffix='', search_for='', replace_with=''):
""" Duplicates the transform chain starting at start and ending at end.
:param start: The start transform.
:param end: The end transform.
:return: A list of the duplicated joints, a list of the original joints that were duplicated
"""
joint = end
joints = []
original_joints = []
while joint:
name = '{0}{1}{2}'.format(prefix, joint, suffix)
if search_for or replace_with:
name = name.replace(search_for, replace_with)
original_joints.append(joint)
duplicate_joint = cmds.duplicate(joint, name=name, parentOnly=True)[0]
if joints:
cmds.parent(joints[-1], duplicate_joint)
joints.append(duplicate_joint)
if joint == start:
break
joint = cmds.listRelatives(joint, parent=True, path=True)
if joint:
joint = joint[0]
else:
raise RuntimeError('{0} is not a descendant of {1}'.format(end, start))
joints.reverse()
original_joints.reverse()
return joints, original_joints
def _unparent_children(joint):
"""Helper function to unparent any children of the given joint.
@param joint: Joint whose children to unparent.
@return: A list of the unparented children.
"""
children = cmds.listRelatives(joint, children=True, path=True) or []
return [cmds.parent(child, world=True)[0] for child in children]
def _reparent_children(joint, children):
"""Helper function to reparent any children of the given joint.
@param joint: Joint whose children to reparent.
@param children: List of transforms to reparent
"""
for child in children:
cmds.parent(child, joint)