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
python类listRelatives()的实例源码
def shape_from_element(element):
"""Return shape of given 'element'
Supports components, meshes, and surfaces
"""
try:
# Get either shape or transform, based on element-type
node = cmds.ls(element, objectsOnly=True)[0]
except Exception:
cmds.warning("Could not find node in %s" % element)
return None
if cmds.nodeType(node) == 'transform':
try:
return cmds.listRelatives(node, shapes=True)[0]
except Exception:
cmds.warning("Could not find shape in %s" % element)
return None
else:
return node
def clone_special(*args):
"""Clone in localspace, and preserve user-defined attributes"""
for transform in cmds.ls(selection=True, long=True):
if cmds.nodeType(transform) != "transform":
cmds.warning("Skipping '%s', not a `transform`" % transform)
continue
shape = _find_shape(transform)
type = cmds.nodeType(shape)
if type not in ("mesh", "nurbsSurface", "nurbsCurve"):
cmds.warning("Skipping '{transform}': cannot clone nodes "
"of type '{type}'".format(**locals()))
continue
cloned = commands.clone(shape, worldspace=False)
new_transform = cmds.listRelatives(cloned,
parent=True,
fullPath=True)[0]
new_transform = cmds.rename(new_transform,
new_transform.rsplit(":", 1)[-1])
for attr in cmds.listAttr(transform,
userDefined=True) or list():
try:
cmds.addAttr(new_transform, longName=attr, dataType="string")
except Exception:
continue
value = cmds.getAttr(transform + "." + attr)
cmds.setAttr(new_transform + "." + attr, value, type="string")
# Connect visibility
cmds.connectAttr(transform + ".visibility",
new_transform + ".visibility")
def _clone(worldspace=False):
"""Clone selected objects in viewport
Arguments:
worldspace (bool): Whether or not to append a transformGeometry to
resulting clone.
"""
clones = list()
for node in cmds.ls(selection=True, long=True):
shape = _find_shape(node)
type = cmds.nodeType(shape)
if type not in ("mesh", "nurbsSurface", "nurbsCurve"):
cmds.warning("Skipping '{node}': cannot clone nodes "
"of type '{type}'".format(**locals()))
continue
cloned = commands.clone(shape, worldspace=worldspace)
clones.append(cloned)
if not clones:
return
# Select newly created transform nodes in the viewport
transforms = list()
for clone in clones:
transform = cmds.listRelatives(clone, parent=True, fullPath=True)[0]
transforms.append(transform)
cmds.select(transforms, replace=True)
def _find_shape(element):
"""Return shape of given 'element'
Supports components, meshes, and surfaces
Arguments:
element (str): Path to component, mesh or surface
Returns:
str of path if found, None otherwise
"""
# Get either shape or transform, based on element-type
node = cmds.ls(element, objectsOnly=True, long=True)[0]
if cmds.nodeType(node) == "transform":
try:
return cmds.listRelatives(node, shapes=True, fullPath=True)[0]
except IndexError:
return cmds.warning("Could not find shape in %s" % element)
else:
return node
def on_save(_):
"""Automatically add IDs to new nodes
Any transform of a mesh, without an exising ID,
is given one automatically on file save.
"""
avalon.logger.info("Running callback on save..")
nodes = (set(cmds.ls(type="mesh", long=True)) -
set(cmds.ls(long=True, readOnly=True)) -
set(cmds.ls(long=True, lockedNodes=True)))
transforms = cmds.listRelatives(list(nodes), parent=True) or list()
# Add unique identifiers
for node in transforms:
_set_uuid(node)
def getObjects(self, model, includeShapes=True):
"""Get the objects of the component.
Args:
model(dagNode): The root of the component.
includeShapes (boo): If True, will include the shapes.
Returns:
list of dagNode: The list of the objects.
"""
objects = {}
if includeShapes:
children = pm.listRelatives(model, ad=True)
else:
children = pm.listRelatives(model, ad=True, typ='transform')
pm.select(children)
for child in pm.ls(self.fullName + "_*", selection=True):
objects[child[child.index(
self.fullName + "_") + len(self.fullName + "_"):]] = child
return objects
def getObjects2(self, model, includeShapes=True):
"""Get the objects of the component.
Args:
model(dagNode): The root of the component.
includeShapes (boo): If True, will include the shapes.
Returns:
list of dagNode: The list of the objects.
"""
objects = {}
if includeShapes:
children = [pm.PyNode(x) for x in cmds.listRelatives(
model.longName(), ad=True, fullPath=True)]
else:
children = [pm.PyNode(x) for x in cmds.listRelatives(
model.longName(), ad=True, typ='transform', fullPath=True)]
for child in children:
cName = child.longName()
if cName.startswith(self.fullName):
objects[cName.split("_")[-1]] = child
return objects
def __findChildren(node, name, firstOnly=False, partialName=False):
if partialName:
children = [item for item
in node.listRelatives(allDescendents=True,
type="transform")
if item.name().split("|")[-1].split("_")[-1] == name]
else:
children = [item for item
in node.listRelatives(allDescendents=True,
type="transform")
if item.name().split("|")[-1] == name]
if not children:
return False
if firstOnly:
return children[0]
return children
def __findChild(node, name):
"""This find children function will stop search after firs child found.child
This is a faster version of __findchildren
Arguments:
node (dagNode): The input node to search
name (str): The name to search
Returns:
dagNode: Children node
"""
try:
for item in cmds.listRelatives(node.name(),
allDescendents=True,
type="transform"):
if item.split("|")[-1] == name:
return pm.PyNode(item)
except pm.MayaNodeError:
for item in node.listRelatives(allDescendents=True,
type="transform"):
if item.split("|")[-1] == name:
return item
return False
def make_planar(joints):
for joint in joints:
parent = cmds.listRelatives(joint, parent=True, path=True)
if not parent:
log.warning('Cannot make %s planar because it does not have a parent.', joint)
continue
children = _unparent_children(joint)
if not children:
log.warning('Cannot make %s planar because it does not have any children.', joint)
continue
cmds.delete(cmds.aimConstraint(children[0], joint, aim=(1, 0, 0), u=(0, 1, 0), worldUpType='object', worldUpObject=parent[0]))
cmds.makeIdentity(joint, apply=True)
_reparent_children(joint, children)
if joints:
cmds.select(joints)
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 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_skin_clusters(nodes):
"""Get the skinClusters attached to the specified node and all nodes in descendents.
:param nodes: List of dag nodes.
@return A list of the skinClusters in the hierarchy of the specified root node.
"""
if isinstance(nodes, basestring):
nodes = [nodes, ]
all_skins = []
for node in nodes:
relatives = cmds.listRelatives(node, ad=True, path=True) or []
relatives.insert(0, node)
relatives = [shortcuts.get_shape(node) for node in relatives]
for relative in relatives:
history = cmds.listHistory(relative, pruneDagObjects=True, il=2) or []
skins = [x for x in history if cmds.nodeType(x) == 'skinCluster']
if skins:
all_skins.append(skins[0])
return list(set(all_skins))
def test_set_transform_stack(self):
loc = cmds.spaceLocator(name='spine_ctrl')[0]
nulls = control.create_transform_stack(loc, 2)
self.assertEqual(2, len(nulls))
parent = cmds.listRelatives(loc, parent=True, path=True)[0]
self.assertEqual('spine_1nul', parent)
parent = cmds.listRelatives(parent, parent=True, path=True)[0]
self.assertEqual('spine_2nul', parent)
nulls = control.create_transform_stack(loc, 3)
self.assertEqual(3, len(nulls))
parent = cmds.listRelatives(loc, parent=True, path=True)[0]
self.assertEqual('spine_1nul', parent)
parent = cmds.listRelatives(parent, parent=True, path=True)[0]
self.assertEqual('spine_2nul', parent)
parent = cmds.listRelatives(parent, parent=True, path=True)[0]
self.assertEqual('spine_3nul', parent)
def assert_hierarachies_match(self):
self.assertEqual(7, len(cmds.ls(type='joint')))
# Make sure the joint orients are the same
translates = [cmds.getAttr('{0}.t'.format(x))[0] for x in cmds.ls(type='joint')]
rotates = [cmds.getAttr('{0}.r'.format(x))[0] for x in cmds.ls(type='joint')]
orients = [cmds.getAttr('{0}.jo'.format(x))[0] for x in cmds.ls(type='joint')]
for orient, new_orient in zip(self.orients, orients):
self.assertListAlmostEqual(orient, new_orient)
for translate, new_translate in zip(self.translates, translates):
self.assertListAlmostEqual(translate, new_translate)
for rotate, new_rotate in zip(self.rotates, rotates):
self.assertListAlmostEqual(rotate, new_rotate)
# The geometry should not have been exported
self.assertFalse(cmds.objExists(self.cube))
self.assertTrue(cmds.objExists(self.group))
self.assertEqual('joint1', cmds.listRelatives(self.group, children=True)[0])
def to_curve_fn(curve):
shape = None
if cmds.nodeType(curve, 'nurbsCurve'):
shape = curve
else:
child = cmds.listRelatives(curve, shapes=True, noIntermediate=True)
if child:
shape = child[0]
else:
cmds.warning('Not a proper nurbsCurve: {}'.format(curve))
raise Exception('Not a proper nurbsCurve: {}'.format(curve))
sel = om.MSelectionList()
sel.add(shape)
dep = sel.getDagPath(0)
fn = om.MFnNurbsCurve(dep)
return fn
def curve_between(a, b, num_points=24, degree=3, name='curve#'):
'''Create a nurbsCurve between two MVectors
:param a: start of curve
:param b: end of curve
:param num_points: number of points on curve
:param degree: degree of curve
'''
v = b - a
cvs = []
for t in linspace(0, 1, num_points):
cvs.append(a + v * t)
knots = compute_knots(num_points, degree)
curve = cmds.curve(point=cvs, degree=degree, knot=knots)
curve = cmds.rename(curve, name)
curve_shape = cmds.listRelatives(curve, shapes=True)[0]
return curve, curve_shape
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 getShape(self, node):
"""
Gets the shape node from the input node.
:param node (str): string name of input node
Raises:
`RuntimeError` if no shape node.
Returns:
(str) shape node name
"""
if cmds.nodeType(node) == 'transform':
shapes = cmds.listRelatives(node, shapes=True)
if not shapes:
raise RuntimeError('%s has no shape' % node)
return shapes[0]
elif cmds.nodeType(node) == "mesh":
return node
def insertGroupAbove(obj, *args):
par = cmds.listRelatives(obj, p=True)
grp = cmds.group(em=True, n="{}_Grp".format(obj))
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 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 selectComponents(*args):
sel = cmds.ls(sl=True)
if sel:
for obj in sel:
shape = cmds.listRelatives(obj, s=True)[0]
if cmds.objectType(shape) == "nurbsCurve":
cmds.select(cmds.ls("{}.cv[*]".format(obj), fl=True))
elif cmds.objectType(shape) == "mesh":
cmds.select(cmds.ls("{}.vtx[*]".format(obj), fl=True))
else:
return
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 positionsAlongCurve(crv="", numPts = 3, *args):
"""
returns list of numPts evenly distributed world positions along given nurbs crv
"""
if not crv:
return
if isType(crv, "nurbsCurve"):
posList = []
shp = cmds.listRelatives(crv, s=True)[0]
poc = cmds.shadingNode("pointOnCurveInfo", asUtility=True, name="tmpPOCInfo")
cmds.connectAttr("{}.local".format(shp), "{}.inputCurve".format(poc))
cmds.setAttr("{}.turnOnPercentage".format(poc), 1)
lineLen = cmds.arclen(crv, ch=False)
dist = float(numPts)/lineLen
for x in range(0, numPts+1):
perc = 1.0/numPts
cmds.setAttr("{}.parameter".format(poc),x*perc)
print x*perc
pos = cmds.getAttr("{}.position".format(poc))[0]
posList.append(pos)
cmds.delete(poc)
return(posList)
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 options_pass(*args):
xfersDo, shpsDo = cmds.checkBoxGrp(widgets["shapeCBG"], q=True, valueArray2=True)
inputs, outputs = cmds.checkBoxGrp(widgets["inOutCBG"], q=True, valueArray2=True)
sel = cmds.ls(sl=True)
if len(sel) != 2:
cmds.warning("You don't have two things selected! (source, then target)")
return()
srcX = sel[0]
tgtX = sel[1]
if xfersDo:
transfer_connections_do(srcX, tgtX, inputs, outputs)
if shpsDo:
# options for checkbox would go here. . .
srcShp = cmds.listRelatives(srcX, s=True)[0]
tgtShp = cmds.listRelatives(tgtX, s=True)[0]
transfer_connections_do(srcShp, tgtShp, inputs, outputs)
def toggle_sel_shape_vis(*args):
"""toggles the selected transforms' shape visibility"""
sel = cmds.ls(sl=True, type="transform")
if sel:
for obj in sel:
shp = cmds.listRelatives(obj, s=True)
if not shp:
return ()
for s in shp:
currVal = cmds.getAttr("{0}.visibility".format(s))
newVal = 0
if currVal == 0:
newVal = 1
elif currVal == 1:
newVal = 0
cmds.setAttr("{0}.visibility".format(s), newVal)