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类rename()的实例源码
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 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 NamespaceClean():
# Get a list of bones
boneList = cmds.ls(type = 'joint')
# Loop
for bone in boneList:
# Check if it has a namespace
if bone.find(":") > -1:
# We got one, prepare to clean
resultSplit = bone.split(":")
# Get the last one
newName = resultSplit[len(resultSplit)-1]
# Rename it
try:
# Do it
cmds.rename(bone, newName)
except:
# Continue
pass
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 nameFix(name):
"""
for xforms - this will take a base name (ie.'pCube') and find all instances of that and rename by appending a
number, starting with the deepest instances in the DAG hier, so as not to bollocks up the later searches by
changing items on top of obj
"""
mayaObjs = cmds.ls(name)
print "---------\nI'm in nameFix for: {0}, and there are --{1}-- instances of this clash".format(name,
len(mayaObjs))
mayaObjs.sort(key=lambda a: a.count("|"), reverse=True) # this sorts by greatest number of "|"
if mayaObjs:
if len(mayaObjs) > 1:
for x in range(0, len(mayaObjs) - 1):
cmds.rename(mayaObjs[x], "{0}_{1}".format(mayaObjs[x].rpartition("|")[2], x))
print "zbw_clash.nameFix: Changed name of {0} --> {1}".format(mayaObjs[x], "{0}_{1}".format(
mayaObjs[x].rpartition("|")[2], x))
def _cleanup(name):
"""Removes un-used nodes on import of obj
"""
# Don't delete the old mesh if gozbruh_delete option var exists and is set to
# false, simply rename it
if cmds.optionVar(ex='gozbruh_delete') and not cmds.optionVar(q='gozbruh_delete'):
if cmds.objExists(name):
cmds.rename(name, name + '_old')
else:
if cmds.objExists(name):
cmds.delete(name)
for node in GARBAGE_NODES:
node = name + '_' + node
if cmds.objExists(node):
cmds.delete(node)
#------------------------------------------------------------------------------
# Helpers
#------------------------------------------------------------------------------
def create_ncloth():
selection = cmds.ls(selection=True)[0]
input_mesh = cmds.listRelatives(selection, shapes=True)[0]
current_mesh = commands.create_ncloth(input_mesh)
# Optionally append suffix
comp = selection.rsplit("_", 1)
suffix = ("_" + comp[-1]) if len(comp) > 1 else ""
cmds.rename(current_mesh, "currentMesh%sShape" % suffix)
# Mimic default nCloth command
cmds.hide(selection)
def _createInsideSphere(name, radius, parent):
node = cmds.sphere(r=radius * .999)[0]
cmds.parent(node, parent)
cmds.rename(node, name)
return node
def _createCurve(name, angle, cvs, parent):
node = cmds.curve(d=1, p=cvs)
cmds.parent(node, parent)
name += '_n%03d' if angle < 0. else '_p%03d'
cmds.rename(node, name % abs(round(angle)))
return node
def PlaceNote():
# Notetrack number
note_tracks = 0
# We need to ask for a name
if not (cmds.objExists("SENotes")):
# We need to make the SENotes parent first
base_track = cmds.spaceLocator()
# Rename
cmds.rename(base_track, "SENotes")
# Notetrack name
noteName = "new_notetrack" + str(note_tracks)
# Now we can make the child (if you have > 50000 notetracks, we got a problem...)
for npos in xrange(note_tracks, 50000):
# Setup
noteName = "new_notetrack" + str(npos)
# Check
if not (cmds.objExists(noteName)):
# Exit
break
# Now make it and parent it
notetrack = cmds.spaceLocator()
# Rename
cmds.rename(notetrack, noteName)
# Parent it
mel.eval("parent " + noteName + " SENotes")
# Get current time
currentFrame = cmds.currentTime(query = True)
# Key it
cmds.setKeyframe(noteName, time = currentFrame)
# Log it
print("A new notetrack was created")
# Selects all bones
def remNS(*args):
"""removes namespaces . . . """
rem = ["UI", "shared"]
ns = cmds.namespaceInfo(lon=True, r=True)
for y in rem:
ns.remove(y)
ns.sort(key = lambda a: a.count(":"), reverse=True)
for n in ns:
ps = cmds.ls("{}:*".format(n), type="transform")
for p in ps:
cmds.rename(p, p.rpartition(":")[2])
cmds.namespace(rm=n)
def swapDupe(obj, target, delete = True, name="", *args):
"""
replaces an target with a duplicate of the obj
select the object you want to duplicate, then the target(s), delete bool, name optional
[obj] is the object to duplicate
[target] is the target to match and delete(?)
[delete] is bool to tell whether to delete the target or not
[name] is string to rename to
"""
if not name:
name = obj
# get pos, rot, scale of target
pos = cmds.xform(target, q=True, ws=True, rp=True)
rot = cmds.xform(target, q=True, ws=True, ro=True)
scl = cmds.getAttr("{0}.scale".format(target))
# duplicate the object and rename to name, if no name just use unique names
dupe = cmds.duplicate(obj, name=name, returnRootsOnly=True, renameChildren=True)
cmds.xform(dupe, ws=True, t=pos)
cmds.xform(dupe, ws=True, ro=rot)
cmds.xform(dupe, ws=True, s=scl[0])
parent = cmds.listRelatives(target, parent=True)
if parent:
cmds.parent(dupe, parent[0])
if delete:
cmds.delete(target)
return(dupe[0])
def rename_prompt(obj, goz_id, objs):
"""Confirm object rename, trigger create or relink then revise
objlist
"""
gui_message = """%s has a old ZBrush ID, of %s, try to relink?
NOTE! relinking will
remove objects named "%s"
selected mesh as the new one!!
""" % (obj,
goz_id,
goz_id)
choice = pm.confirmDialog(title="ZBrush Name Conflict",
message=gui_message,
button=['Relink', 'Create', 'Skip'])
if choice == 'Relink':
# relink to past gozbruhBrushID
if obj not in objs:
return
new_obj = relink(obj, goz_id)
objs.remove(obj)
if new_obj not in objs:
objs.append(new_obj)
elif choice == 'Create':
# new object for zbrush
create(obj)
def relink(obj, goz_id):
"""Relink object name with existing gozbruhBrushID.
"""
# manages re linking gozbruhBrush IDs, checks for attribute on shape/xform
# in the case of a object being duplicated this removes the duplicate
# to prevent deletion, the 'create' option is prefered
# is only happens when an object was duplicated and merged (original
# still exists)
if cmds.objExists(goz_id):
cmds.delete(goz_id)
cmds.rename(obj, goz_id)
return create(goz_id)
def change_hierarchy_and_animate():
"""
Function modifies the hierarchy of scene and creates some final animations, that ware not possible to create earlier.
It also creates cameras and lights.
"""
cmds.lookThru( 'perspView', 'RenderCamera1') # Change the perspective viewport to the render camera.
top_locator = cmds.spaceLocator() # Parent for all the elemements that will rotate together
objects_list = ['land', 'water', 'cloud', 'shark', ]
for obj in objects_list:
cmds.parent(obj, top_locator)
cmds.setKeyframe(top_locator, attribute='rotateY', v=20, time=260, itt="plateau", ott="plateau")
cmds.setKeyframe(top_locator, attribute='rotateY', v=0, time=0, itt="linear", ott="linear")
dome_light = cmds.polySphere(r=500) # This sphere is a substitute of a skylight in 3Ds Max
cmds.polyNormal(dome_light, normalMode=0) # The normals have to point to inside
cmds.setAttr(dome_light[0]+".miDeriveFromMaya", 0) # Enable changes in object render settings
cmds.setAttr(dome_light[0]+".miVisible", 0) # This object will be invisible to camera
cmds.setAttr(dome_light[0]+".miShadow", 0) # And will not affect shadows
cmds.rename(dome_light[0], "dome_light")
area_light = cmds.shadingNode('areaLight', asLight=True)
cmds.scale(25, 25, 25, area_light, absolute=True)
cmds.move(-230.59, 178.425, 99.192, area_light)
cmds.rotate(0, -68.929, -37.987, area_light)
cmds.setAttr(area_light+".intensity", 120000.0)
cmds.setAttr(area_light+".areaLight", 1)
cmds.setAttr(area_light+".areaType", 1)
cmds.setAttr(area_light+".decayRate", 2)
cmds.setAttr(area_light+".areaHiSamples", 64)
def follicle(*args):
supported = ["mesh", "nurbsSurface"]
selection = cmds.ls(sl=1)
new_follicles = []
for sel in selection:
uv = lib.uv_from_element(sel)
geometry_shape = lib.shape_from_element(sel)
geometry_transform = cmds.listRelatives(geometry_shape, parent=True)[0]
# Figure out output connection
inputs = [".inputMesh", ".inputSurface"]
outputs = [".outMesh", ".local"]
failed = False
type = cmds.nodeType(geometry_shape)
if type not in supported:
failed = True
shapes = cmds.listRelatives(geometry_shape, shapes=True)
if shapes:
geometry_shape = shapes[0]
type = cmds.nodeType(geometry_shape)
if type in supported:
failed = False
if failed:
cmds.error("Skipping '%s': Type not accepted" % type)
return
input = inputs[supported.index(type)]
output = outputs[supported.index(type)]
# Make follicle
follicle = cmds.createNode("follicle",
name=geometry_transform + "_follicleShape1")
follicle_transform = cmds.listRelatives(follicle, parent=True)[0]
follicle_transform = cmds.rename(follicle_transform,
geometry_transform + "_follicle1")
# Set U and V value
cmds.setAttr(follicle + ".parameterU", uv[0])
cmds.setAttr(follicle + ".parameterV", uv[1])
# Make the connections
cmds.connectAttr(follicle + ".outTranslate",
follicle_transform + ".translate")
cmds.connectAttr(follicle + ".outRotate",
follicle_transform + ".rotate")
cmds.connectAttr(geometry_shape + output,
follicle + input)
# Select last
new_follicles.append(follicle_transform)
# Select newly created follicles
if new_follicles:
cmds.select(new_follicles, r=1)
return new_follicles
def create_spine(start_joint, end_joint, lower_control, upper_control, name='spine'):
spline_chain, original_chain = shortcuts.duplicate_chain(start_joint, end_joint, prefix='ikSpine_')
# Create the spline ik
ikh, effector, curve = cmds.ikHandle(
name='{0}_ikh'.format(name), solver='ikSplineSolver',
startJoint=spline_chain[0], endEffector=spline_chain[-1], parentCurve=False,
simplifyCurve=False)
effector = cmds.rename(effector, '{0}_eff'.format(name))
curve = cmds.rename(curve, '{0}_crv'.format(name))
# Create the joints to skin the curve
curve_start_joint = cmds.duplicate(start_joint, parentOnly=True, name='{0}CurveStart_jnt'.format(name))
cmds.parent(curve_start_joint, lower_control)
curve_end_joint = cmds.duplicate(end_joint, parentOnly=True, name='{0}CurveEnd_jnt'.format(name))
cmds.parent(curve_end_joint, upper_control)
# Skin curve
cmds.skinCluster(curve_start_joint, curve_end_joint, curve, name='{0}_scl'.format(name), tsb=True)
# Create stretch network
curve_info = cmds.arclen(curve, constructionHistory=True)
mdn = cmds.createNode('multiplyDivide', name='{0}Stretch_mdn'.format(name))
cmds.connectAttr('{0}.arcLength'.format(curve_info), '{0}.input1X'.format(mdn))
cmds.setAttr('{0}.input2X'.format(mdn), cmds.getAttr('{0}.arcLength'.format(curve_info)))
cmds.setAttr('{0}.operation'.format(mdn), 2) # Divide
# Connect to joints
for joint in spline_chain[1:]:
tx = cmds.getAttr('{0}.translateX'.format(joint))
mdl = cmds.createNode('multDoubleLinear', name='{0}Stretch_mdl'.format(joint))
cmds.setAttr('{0}.input1'.format(mdl), tx)
cmds.connectAttr('{0}.outputX'.format(mdn), '{0}.input2'.format(mdl))
cmds.connectAttr('{0}.output'.format(mdl), '{0}.translateX'.format(joint))
# Setup advanced twist
cmds.setAttr('{0}.dTwistControlEnable'.format(ikh), True)
cmds.setAttr('{0}.dWorldUpType'.format(ikh), 4) # Object up
cmds.setAttr('{0}.dWorldUpAxis'.format(ikh), 0) # Positive Y Up
cmds.setAttr('{0}.dWorldUpVectorX'.format(ikh), 0)
cmds.setAttr('{0}.dWorldUpVectorY'.format(ikh), 1)
cmds.setAttr('{0}.dWorldUpVectorZ'.format(ikh), 0)
cmds.setAttr('{0}.dWorldUpVectorEndX'.format(ikh), 0)
cmds.setAttr('{0}.dWorldUpVectorEndY'.format(ikh), 1)
cmds.setAttr('{0}.dWorldUpVectorEndZ'.format(ikh), 0)
cmds.connectAttr('{0}.worldMatrix[0]'.format(lower_control), '{0}.dWorldUpMatrix'.format(ikh))
cmds.connectAttr('{0}.worldMatrix[0]'.format(upper_control), '{0}.dWorldUpMatrixEnd'.format(ikh))
# Constrain original chain back to spline chain
for ik_joint, joint in zip(spline_chain, original_chain):
if joint == end_joint:
cmds.pointConstraint(ik_joint, joint, mo=True)
cmds.orientConstraint(upper_control, joint, mo=True)
else:
cmds.parentConstraint(ik_joint, joint)
def create_line(uniform = True, *args):
"""
gets info from win to create nurbs curve along an axis
Args:
uniform (bool): whether the parameterization should be uniform (even), which makes the points not even
"""
axis = cmds.radioButtonGrp(widgets["lineAxisRBG"], q=True, sl=True)
length = cmds.floatFieldGrp(widgets["lineLenFFG"], q=True, v1=True)
density = cmds.floatFieldGrp(widgets["lineDenFFG"], q=True, v1=True)
numCvs = length * density
if numCvs < 3.0: # curve needs 3 cvs (for 3 dg curve)
numCvs = 3.0
cvDist = length/numCvs
# make a list of pt dist along some axis
axisList = []
for x in range(0,int(numCvs)+1):
axisList.append(x)
pts = []
if axis == 1:
for y in range(0, int(numCvs)+1):
pt = [axisList[y]*cvDist, 0, 0]
pts.append(pt)
if axis == 2:
for y in range(0, int(numCvs)+1):
pt = [0, axisList[y]*cvDist, 0]
pts.append(pt)
if axis == 3:
for y in range(0, int(numCvs)+1):
pt = [0, 0, axisList[y]*cvDist]
pts.append(pt)
line = cmds.curve(name = "line_01", d=3, p=pts)
shp = cmds.listRelatives(line, s=True)[0]
cmds.rename(shp, "{0}Shape".format(line))
if uniform:
line = cmds.rebuildCurve(line, rebuildType = 0, spans = 0, keepRange = 0, replaceOriginal=True, end=1, keepControlPoints=0)[0]
cmds.select(line, r=True)
def extendPoly(*args):
"""does the polyextension by grabbing the curve, offsetting it and then lofting. Then converts the nurbs surface to polys"""
#make sure a curve is selected
selection = cmds.ls(sl=True)
if selection:
sel = selection[0]
shape = cmds.listRelatives(sel, s=True)[0]
type = cmds.objectType(shape)
name = cmds.textFieldGrp("name", q=True, tx=True)
hisGrp = cmds.checkBox("history", q=True, v=True)
hisPoly = cmds.checkBox("polyHistory", q=True, v=True)
if type== "nurbsCurve":
#offset the curb
distance = cmds.floatFieldGrp("curbFFG", q=True, v1=True)
# bump = cmds.checkBox("bumpCB", q=True, v=True)
pos = cmds.checkBox("curbCB", q=True, v=True)
if pos == 0:
dist = distance * -1
else:
dist = distance
U = cmds.intFieldGrp("UDivIFG", q=True, v1=True)
V = cmds.intFieldGrp("VDivIFG", q=True, v1=True)
origCrv = cmds.rename(sel, "%s_inner_CRV"%name)
outCurve = cmds.offsetCurve(origCrv, d=dist, n="%s_outer_CRV"%name)
midCurve = cmds.offsetCurve(origCrv, d=dist/2, n="%s_mid_CRV"%name)
# if bump:
# cmds.xform(midCurve, ws=True, r=True, t=(0,5,0))
cmds.select(cl=True)
lofted = cmds.loft(origCrv, midCurve, outCurve)[0]
loft = cmds.rename(lofted, "%s_lofted"%name)
polygon = cmds.nurbsToPoly(loft, pt=1, ch=hisPoly, f=2, un=U, vn=V)[0]
poly = cmds.rename(polygon, "%s_poly"%name)
curbGrp = cmds.group(empty=True)
grp = cmds.rename(curbGrp, "%s_History_GRP"%name)
# cmds.rename(poly, "polyCurb")
cmds.parent(loft, outCurve, midCurve, origCrv, grp)
cmds.setAttr("%s.v"%grp, 0)
if not hisGrp:
cmds.delete(grp)
else:
cmds.warning("That's not a curve! You need to select a curve!")
else:
cmds.warning("You haven't selected anything!")
def follicle(surface="none", folName="none", u=0.5, v=0.5, *args):
"""
creates a follicle on a surface based on the uv input.
Args are: surface, folName, u, v
"""
#------------do a bit more checking here to make sure the shapes, numbers etc work out
if surface=="none":
#decide if surface is polymesh or nurbsSurface
surfaceXform = cmds.ls(sl=True, dag=True, type="transform")[0]
surfaceShape = cmds.listRelatives(surfaceXform, shapes=True)[0]
else:
surfaceXform = surface
surfaceShape = cmds.listRelatives(surfaceXform, shapes=True)[0]
if folName == "none":
folShapeName = "myFollicleShape"
folXformName = "myFollicle"
else:
folShapeName = "%sShape"%folName
folXformName = folName
#------------test if follicle exists
#create the follicle
folShape = cmds.createNode("follicle", n=folShapeName)
folXform = cmds.listRelatives(folShape, p=True, type="transform")[0]
cmds.rename(folXform, folXformName)
#connect up the follicle!
#connect the matrix of the surface to the matrix of the follicle
cmds.connectAttr("%s.worldMatrix[0]"%surfaceShape, "%s.inputWorldMatrix"%folShape)
#check for surface type, poly or nurbs and connect the matrix into the follicle
if (cmds.nodeType(surfaceShape)=="nurbsSurface"):
cmds.connectAttr("%s.local"%surfaceShape, "%s.inputSurface"%folShape)
elif (cmds.nodeType(surfaceShape)=="mesh"):
cmds.connectAttr("%s.outMesh"%surfaceShape, "%s.inputMesh"%folShape)
else:
cmds.warning("not the right kind of selection. Need a poly or nurbs surface")
#connect the transl, rots from shape to transform of follicle
cmds.connectAttr("%s.outTranslate"%folShape, "%s.translate"%folXform)
cmds.connectAttr("%s.outRotate"%folShape, "%s.rotate"%folXform)
cmds.setAttr("%s.parameterU"%folShape, u)
cmds.setAttr("%s.parameterV"%folShape, v)
cmds.setAttr("%s.translate"%folXform, l=True)
cmds.setAttr("%s.rotate"%folXform, l=True)
return(folXform, folShape)
def _get_gozid_mismatches(objs):
"""Return objects from `objs` whose gozbruhBrushID does not match their name
Checks object history for instances of gozbruhBrushID,
returns a list ofgozbruhBrushID/name conflicts
gozbruhBrushID is created by ZBrush on export and is used to track
name changes that can occur in maya
this function compares object current name against the ID
and returns a list of conflicts
this list is handled by the gui to allow for dialog boxes
"""
goz_list = []
for obj in objs:
has_attr = cmds.attributeQuery(
'gozbruhBrushID', node=obj, exists=True)
if has_attr:
# check for 'rename'
goz_id = cmds.getAttr(obj + '.gozbruhBrushID')
if obj != goz_id:
goz_list.append((obj, goz_id))
else:
# check for old ID in history
for old_obj in cmds.listHistory(obj):
has_attr = cmds.attributeQuery('gozbruhBrushID',
node=old_obj,
exists=True)
if has_attr:
goz_id = cmds.getAttr(old_obj + '.gozbruhBrushID')
if obj != goz_id:
goz_list.append((obj, goz_id))
# resulting mismatches to be handled
return goz_list
#------------------------------------------------------------------------------
# Sending / Exporting
#------------------------------------------------------------------------------
def addMarksToScene(marks):
'''
This is temp and will possibly be rolled into future releases.
'''
start,end = utl.frameRange()
camera = utl.getCurrentCamera()
camShape = mc.listRelatives(camera, shapes=True)[0]
aov = mc.getAttr(camShape+'.horizontalFilmAperture')
name = 'ml_stopwatch_'
numStopwatches = len(mc.ls(name+'*', type='locator'))
top = mc.spaceLocator(name=name+'#')
ename = ':'.join([str(x) for x in marks])
mc.addAttr(top, longName='keyTimes', at='enum', enumName=ename, keyable=True)
markRange = float(marks[-1]-marks[0])
viewWidth = aov*2
viewHeight = -0.4*aov+(numStopwatches*aov*0.08)
depth = 5
for mark in marks[1:-1]:
ann = mc.annotate(top, text=str(mark))
mc.setAttr(ann+'.displayArrow', 0)
#parent
annT = mc.parent(mc.listRelatives(ann, parent=True, path=True), top)[0]
annT = mc.rename(annT, 'mark_'+str(round(mark)))
ann = mc.listRelatives(annT, shapes=True, path=True)[0]
#set the position
normalX = float(mark-marks[0])/markRange-0.5
mc.setAttr(annT+'.translateX', viewWidth*normalX*2)
mc.setAttr(annT+'.translateY', viewHeight)
mc.setAttr(annT+'.translateZ', -depth)
#keyframe for color
mc.setAttr(ann+'.overrideEnabled', 1)
mc.setKeyframe(ann, attribute='overrideColor', value=17, time=(int(marks[0]-1),int(mark+1)))
mc.setKeyframe(ann, attribute='overrideColor', value=13, time=(int(mark),))
mc.keyTangent(ann+'.overrideColor', ott='step')
mc.select(clear=True)
mc.parentConstraint(camera, top)
def parentShape(child=None, parent=None, maintainOffset=True):
'''
Parent a child shape node to a parent transform. The child node can be a shape,
or a transform which has any number of shapes.
'''
if not child or not parent:
sel = mc.ls(sl=True)
if sel and len(sel) > 1:
child = sel[:-1]
parent = sel[-1]
else:
OpenMaya.MGlobal.displayWarning('Please make a selection.')
return
parentNodeType = mc.nodeType(parent)
if not parentNodeType in ('transform', 'joint', 'ikHandle'):
OpenMaya.MGlobal.displayWarning('Parent must be a transform node.')
return
if not isinstance(child, (list, tuple)):
child = [child]
newChild = unparentShape(child)
shapes = list()
for each in newChild:
thisChild = mc.parent(each, parent)[0]
mc.makeIdentity(thisChild, apply=True)
for s in mc.listRelatives(thisChild, shapes=True, noIntermediate=True, path=True):
shape = mc.parent(s, parent, shape=True, relative=True)[0]
#move to bottom
mc.reorder(shape, back=True)
#rename
parentName = mc.ls(parent, shortNames=True)[0]
shapes.append(mc.rename(shape, parentName+'Shape#'))
mc.delete(newChild)
for each in child:
if not mc.listRelatives(each):
#if it doesn't have any kids, delete it
mc.delete(each)
return shapes