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)
python类duplicate()的实例源码
def modelSequenceUI(*args):
if (cmds.window("modSeq", exists=True)):
cmds.deleteUI("modSeq")
widgets["win"] = cmds.window("modSeq", w = 300, h = 220, t = "zbw_modelSequence")
widgets["mainCLO"] = cmds.columnLayout(w = 300,h = 220)
cmds.separator(h=10)
cmds.text("Select ONE object to be duplicated \nThis will duplicate it for frames selected and group", al="left")
cmds.separator(h=20)
#textFieldGRP - name of objs
widgets["sufTFG"] = cmds.textFieldGrp(l="Sequence Suffix:", cw = [(1, 100), (2,200)], cal = [(1, "left"),(2, "right")])
#radioButtonGrp - timeslider or frame range
widgets["frmRBG"] = cmds.radioButtonGrp(l="Get Frames From:", nrb=2, sl=2, l1="Time Slider", l2="Frame Range", cw = [(1, 120), (2,80), (3,80)], cal = [(1, "left"),(2, "left")], cc=enableFR)
#textFieldGrp - framerange (enable)
widgets["frmRngIFG"] = cmds.intFieldGrp(l="Range:", nf=2, en=True, v1=0, v2 = 9, cw = [(1, 120), (2,80), (3,80)], cal = [(1, "left"),(2, "left")])
#int = by frame step
widgets["stepIFG"] = cmds.intFieldGrp(l="Step By (frames):", v1 = 1, cw = [(1, 120), (2,80)], cal = [(1, "left"),(2, "right")])
cmds.separator(h=30)
widgets["doBut"] = cmds.button(l="Create duplicates of objects!", w= 300, h=40, bgc = (0,.8, 0), c=getValues)
cmds.showWindow(widgets["win"])
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 snap(node, snapTo):
#duplicate the node we want snap
dup = mc.duplicate(node, parentOnly=True)[0]
#unlock translates and rotates
for a in ('.t','.r'):
for b in 'xyz':
mc.setAttr(dup+a+b, lock=False)
mc.parentConstraint(snapTo, dup)
for a in ('.t','.r'):
for b in ('x','y','z'):
try:
mc.setAttr(node+a+b, mc.getAttr(dup+a+b))
except StandardError:
pass
mc.delete(dup)
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 createMush(self):
mesh = self.sourceField.text()
if not mesh:
return
if cmds.objExists(mesh + '_Mush'):
print(mesh + '_Mush already exists!')
return
cmds.currentTime(cmds.playbackOptions(q=True, min=True))
dup = cmds.duplicate(mesh, inputConnections=True, n=mesh + '_Mush')
cmds.deltaMush(dup, smoothingIterations=20, smoothingStep=0.5, pinBorderVertices=True, envelope=1)
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 dupeIt(*args):
"""uses the first selection and duplicates it to the transforms of the rest of the selected objects, with or without connections"""
sel=cmds.ls(sl=True, type="transform", l=True)
inputs = cmds.radioButtonGrp("inputsRBG", q=True, sl=True)
if sel:
base=sel[0]
if len(sel)>1:
objs=sel[1:]
transforms = {}
x=0
for obj in objs:
#get pos, rot, scale
pos = cmds.xform(obj, ws=True, q=True, t=True)
rot = cmds.xform(obj, ws=True, q=True, ro=True)
scal = cmds.getAttr("%s.scale"%obj)[0]
transforms[x] = [pos, rot, scal]
#delete the obj
cmds.delete(obj)
x=x+1
for key in transforms.keys():
if inputs == 1:
dupe = cmds.duplicate(base)[0]
elif inputs == 3:
dupe = cmds.duplicate(base, un=True, rr=True)[0]
elif inputs == 2:
dupe = cmds.duplicate(base, ic=True)[0]
print dupe
cmds.xform(dupe, ws=True, t=transforms[key][0])
cmds.xform(dupe, ws=True, ro=transforms[key][1])
cmds.setAttr("%s.scale"%dupe, transforms[key][2][0], transforms[key][2][1], transforms[key][2][2])
#TODO - checkbox to copy inputs on orig objects to corresponding inputs on top level of duplicates
else:
cmds.warning("You need to select more than one object in order to swap!")
else:
cmds.warning("Please select some transform nodes to dupe!")
def testAllRotateOrdersForGimbal(obj):
#duplicate node without children
dup = mc.duplicate(obj, name='temp#', parentOnly=True)[0]
tolerences = list()
for roo in ROTATE_ORDERS:
mc.xform(dup, preserve=True, rotateOrder=roo)
tolerences.append(gimbalTolerence(dup))
#delete node
mc.delete(dup)
return tolerences
def __init__(self, curve_sel, vertex_list):
self.curve_sel = curve_sel
self.verts = vertex_list
self.find_length = Find_Out()
self.link_length = self.find_length.edge_length(self.verts)
self.chain_length = self.find_length.curve_length(self.curve_sel)
self.link_total = int(self.chain_length/self.link_length)
cmds.duplicate(self.curve_sel, n = 'buildCurve')
cmds.rebuildCurve('buildCurve', ch = 1, rpo = 1, rt = 0, end = 1, kr = 2, kep = 1, kt = 0, kcp = 0, s = self.link_total/2, d = 3, tol = 0.01 )
self.num_cv = int(cmds.getAttr ('buildCurve.degree'))+ (cmds.getAttr ('buildCurve.spans'))
for dummy_cv in range(self.num_cv):
dummy_cv_pos = (cmds.getAttr ('buildCurve.cv['+ str(dummy_cv) +']'))
if dummy_cv == 0:
cmds.joint(n=self.curve_sel+'_jointRoot',p = dummy_cv_pos[0])
elif dummy_cv == self.num_cv - 1:
cmds.joint(n=self.curve_sel+'_jointEnd', p = dummy_cv_pos[0])
else:
cmds.joint(n=self.curve_sel+'_joint_'+(str(dummy_cv)),p = dummy_cv_pos[0])
cmds.delete('buildCurve')
cmds.ikHandle( sj = (self.curve_sel+'_jointRoot'), ee = (self.curve_sel+'_jointEnd'), c = self.curve_sel,
sol = 'ikSplineSolver', scv = 0, pcv = 0, ccv = 0, ns = 4)
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 smartClose(*args):
name = cmds.textFieldGrp(widgets["nameTFG"], q=True, tx=True)
upSuf = cmds.textFieldGrp(widgets["upNameTFG"], q=True, tx=True)
dwnSuf = cmds.textFieldGrp(widgets["downNameTFG"], q=True, tx=True)
topMidCtrl = ctrlsUp[len(ctrlsUp)/2]
downMidCtrl = ctrlsUp[len(ctrlsDown)/2]
if len(lowResCurves)==2 and len(highResCurves)==2:
tmpCloseLow = cmds.duplicate(lowResCurves[0], n="{0}_closeLowTmpCrv".format(name))[0]
cmds.parent(tmpCloseLow, w=True)
tmpLowBS = cmds.blendShape(lowResCurves[0], lowResCurves[1], tmpCloseLow)[0]
tmpLowUpAttr = "{0}.{1}".format(tmpLowBS, lowResCurves[0])
tmpLowDwnAttr = "{0}.{1}".format(tmpLowBS, lowResCurves[1])
cmds.setAttr(tmpLowUpAttr, 0.5)
cmds.setAttr(tmpLowDwnAttr, 0.5)
closeLow = cmds.duplicate(tmpCloseLow, n="{0}_CLOSE_LOW_CRV".format(name))[0]
cmds.delete([tmpCloseLow, tmpLowBS])
lowBS = cmds.blendShape(lowResCurves[0], lowResCurves[1], closeLow)[0]
lowUpAttr = "{0}.{1}".format(lowBS, lowResCurves[0])
lowDwnAttr = "{0}.{1}".format(lowBS, lowResCurves[1])
#---------------- connect up down into reverse setup that drives lowclosecrv to go up/down
cmds.addAttr(topMidCtrl, ln="__xtraAttrs__", )
cmds.setAttr(lowUpAttr, 1)
cmds.setAttr(lowDwnAttr, 0)
closeUpHigh = cmds.duplicate(highResCurves[0], n="{0}_HI_{1}_CLOSE_CRV".format(name, upSuf.upper() ))[0]
cmds.parent(closeUpHigh, w=True)
upHighWire = cmds.wire(closeUpHigh, en=1, gw=True, ce=0, li=0, w=closeLow, name = "{0}_CLS_UP_WIRE".format(name))[0]
wireUpBaseCrv = "{0}BaseWire".format(closeLow)
cmds.setAttr("{0}.scale[0]".format(upHighWire), 0)
#---------------- set up blend shape on high res curve (drive high res with wire driven curve)
#---------------- set up the center ctrl to drive this BS
cmds.setAttr(lowUpAttr, 0)
cmds.setAttr(lowDwnAttr, 1)
closeDwnHigh = cmds.duplicate(highResCurves[1], n="{0}_HI_{1}_CLOSE_CRV".format(name, dwnSuf.upper() ))[0]
cmds.parent(closeDwnHigh, w=True)
dwnHighWire = cmds.wire(closeDwnHigh, en=1, gw=True, ce=0, li=0, w=closeLow, name = "{0}_CLS_DWN_WIRE".format(name))[0]
wireDwnBase = "{0}BaseWire".format(closeLow)
cmds.setAttr("{0}.scale[0]".format(dwnHighWire), 0)
#---------------- set up blend shape on high res curve (drive high res with wire driven curve)
#---------------- set up the center ctrl to drive this BS
def swapAnimation(fromNode, toNode):
if not mc.keyframe(fromNode, query=True, name=True):
mc.cutKey(toNode, clear=True)
return
attrs = mc.listAttr(fromNode, keyable=True)
if not attrs:
return
for attr in attrs:
if not mc.attributeQuery(attr, node=toNode, exists=True):
mc.cutKey(fromNode, attribute=attr, clear=True)
continue
fromPlug = '{}.{}'.format(fromNode, attr)
toPlug = '{}.{}'.format(toNode, attr)
srcCurve = mc.listConnections(fromPlug, source=True, destination=False, type='animCurve')
dstCurve = mc.listConnections(toPlug, source=True, destination=False, type='animCurve')
copySrc=None
copyDst=None
if srcCurve:
copySrc = mc.duplicate(srcCurve[0])[0]
if dstCurve:
copyDst = mc.duplicate(dstCurve[0])[0]
if copySrc:
try:
mc.cutKey(copySrc)
mc.pasteKey(toNode, attribute=attr, option='replaceCompletely')
except:pass
if copyDst:
try:
mc.cutKey(copyDst)
mc.pasteKey(fromNode, attribute=attr, option='replaceCompletely')
except:pass
for axis in getMirrorAxis(toNode):
mc.scaleKey(toNode, attribute=axis, valueScale=-1)
mc.scaleKey(fromNode, attribute=axis, valueScale=-1)