def listNodeConnections(*args,**keywords): s=True d=True sn=False sel=[] if len(args)==0: sel=mc.ls(sl=True) for a in args: if isIterable(a): sel.extend(a) else: sel.append(a) for k in keywords: if k=='s' or k=='source': s=keywords[k] if k=='d' or k=='destination': d=keywords[k] if k=='sn' or k=='shortName': sn=keywords[k] elif k in locals(): exec(k+'=keywords[k]') connections=[] for conn in removeDuplicates(mc.listConnections(sel[0],s=s,d=d,p=True)): if len(sel)==1 or mc.ls(conn,o=True)[0]==sel[1]: if mc.connectionInfo(conn,isSource=True): for dfs in mc.connectionInfo(conn,dfs=True): if mc.ls(dfs,o=True)[0]==sel[0]: if sn: connections.append\ ( [ mc.ls(conn,o=True)[0]+'.'+mc.listAttr(conn,sn=True)[0], mc.ls(dfs,o=True)[0]+'.'+mc.listAttr(dfs,sn=True)[0] ] ) else: connections.append([conn,dfs]) if mc.connectionInfo(conn,id=True): sfd=mc.connectionInfo(conn,sfd=True) if mc.ls(sfd,o=True)[0]==sel[0]: if sn: connections.append\ ( [ mc.ls(sfd,o=True)[0]+'.'+mc.listAttr(sfd,sn=True)[0], mc.ls(conn,o=True)[0]+'.'+mc.listAttr(conn,sn=True)[0] ] ) else: connections.append([sfd,conn]) return removeDuplicates(connections)
def getBindPoses(*args): sel=[] if len(args)==0: sel=iterable(mc.ls(sl=True)) for a in args: sel.extend(iterable(a)) if len(sel)==0: return trs=iterable(mc.listConnections(iterable(mc.ls(mc.listHistory(sel))),type='transform'))+sel return removeDuplicates(mc.dagPose(trs,q=True,bp=True))
def goToDagPose(*args,**keywords): bindPose=False shortNames={'bp':'bindPose'} for k in keywords: if k in locals(): exec(k+'=keywords[k]') if k in shortNames: exec(shortNames[k]+'=keywords[k]') sel=[] if len(args)==0: sel=mc.ls(sl=True) for a in args: if isIterable(a): sel.extend(a) else: sel.append(a) if len(iterable(mc.ls(sel,type='dagPose')))==0 or bindPose: sel=removeDuplicates(mc.dagPose(mc.listConnections(mc.ls(mc.listHistory(sel)),type='transform'),q=True,bp=True)) if len(sel)==0: return mel.eval('DisableAll') success=True err=True for i in range(0,10): try: mc.dagPose(sel[0],r=True) err=False break except: err=True mel.eval('EnableAll') if err and len(iterable(mc.dagPose(q=True,ap=True))): success=False if success: return sel[0] else: return
def hierarchyOrder(*args, **keywords): reverse = False shortNames = {"r": "reverse"} for k in keywords: if k in locals(): exec(k + "=keywords[k]") elif k in shortNames: exec(shortNames[k] + "=keywords[k]") if len(args) == 0: args = mc.ls(sl=True) sel = [] for a in args: sel.extend(iterable(a)) sel = removeDuplicates(mc.ls(sel, type="dagNode")) if len(sel) < 2: return sel sorted = [] unsorted = list(sel) i = 0 while len(unsorted) > 0: used = [] for x in unsorted: if len(x.split("|")) == i: sorted.append(x) used.append(x) unsorted = removeAll(used, unsorted) i += 1 if reverse: return getReversed(sorted) else: return sorted
def mkControlObjects(self): if not mc.objExists(self.handles[-1]): self.handles[-1]=mc.createNode('transform',n=uniqueNames(self.name[-1])) mc.xform(self.handles[-1],ws=True,a=True,m=mc.xform(self.ArcCtrl.handles[-1],q=True,ws=True,m=True)) mc.xform(self.handles[-1],ws=True,a=True,piv=mc.xform(self.ArcCtrl.handles[-1],q=True,a=True,ws=True,piv=True)[:3]) if 'type' not in self.handleOptions[-1]: self.handleOptions[-1]['type']=self.handleType[-1] if 'radius' not in self.handleOptions[-1]: self.handleOptions[-1]['radius']=self.radius self.handleShape[-1]=Handle(self.handles[-1],**self.handleOptions[-1]) if mc.objExists(self.parent[-1]): mc.parent(self.handles[-1],self.parent[-1]) if mc.objExists(self.softParent[-1]): self.parentSpace[-1]=ParentSpace(self.handles[-1],self.softParent[-1]) for bp in getBindPoses(self.jointHierarchy): mc.dagPose(self.parentSpace[-1],a=True,n=bp) mc.makeIdentity(self.handles[-1],apply=True,t=True)#,r=True) mc.addAttr(self.handles[-1],ln='stretch',at='float',min=0,k=1,dv=self.stretch) mc.addAttr(self.handles[-1],ln='squash',at='float',min=0,max=1,k=1,dv=self.squash) mc.addAttr(self.handles[-1],ln='arcWeight',at='float',min=0,max=1,k=1,dv=self.arcWeight) mc.addAttr(self.handles[-1],ln='width',at='float',min=0.0001,k=1,dv=self.width) mc.connectAttr(self.handles[-1]+'.stretch',self.ArcCtrl.handles[-1]+'.stretch',f=True) mc.connectAttr(self.handles[-1]+'.squash',self.ArcCtrl.handles[-1]+'.squash',f=True) mc.connectAttr(self.handles[-1]+'.arcWeight',self.ArcCtrl.handles[-1]+'.arcWeight',f=True) mc.connectAttr(self.handles[-1]+'.width',self.ArcCtrl.handles[0]+'.width',f=True) if self.curl: mc.addAttr(self.handles[-1],ln='curl',at='doubleAngle',k=1,dv=0) for r in removeAll(self.jointHierarchy,self.rivet): axis='x' longestAxisLen=0 for a in ['x','y','z']: axisLen=abs(mc.getAttr(r+'.t'+a)) if axisLen>longestAxisLen: longestAxisLen=axisLen axis=a behaviorMirrored=False try: parentJoint=mc.listRelatives(r,p=True)[0] oppositeJoint=removeAll(r,mc.listRelatives(parentJoint,c=True,type='joint'))[0] for a in ['x','y','z']: if\ ( abs(180-abs(abs(mc.getAttr(r+'.jo'+a))-abs(mc.getAttr(oppositeJoint+'.jo'+a))))<5 ): behaviorMirrored=True break except: pass pcr=mc.listConnections(r+'.rx',type='parentConstraint')[0] pcTargets=mc.parentConstraint(pcr,q=True,tl=True) pcIDs=[] nsc=listNodeConnections(pcr,s=False,d=True) for n in range(0,len(nsc)): if len(nsc[n])==2 and mc.objExists(nsc[n][-1]): pcID=getIDs(nsc[n][-1]) if isinstance(pcID,int): pcIDs.append(pcID) pcIDs=removeDuplicates(pcIDs) pcIDs.sort() pcID=pcIDs[-1] pma=mc.createNode('plusMinusAverage') if mc.getAttr(r+'.uPos')>50: mc.setAttr(pma+'.op',2) if\ ( (behaviorMirrored and parentJoint!=self.jointHierarchy[-1]) ): mc.setAttr(pma+'.op',1) if mc.getAttr(r+'.uPos')<50: mc.setAttr(pma+'.op',1) if\ ( behaviorMirrored ): mc.setAttr(pma+'.op',2) mc.setAttr(pma+'.i1[0]',mc.getAttr(pcr+'.tg['+str(pcID)+'].tor'+axis)) mc.setAttr(pcr+'.tg['+str(pcID)+'].tor'+axis,lock=False) mc.connectAttr(self.handles[-1]+'.curl',pma+'.i1[1]') mc.connectAttr(pma+'.o1',pcr+'.tg['+str(pcID)+'].tor'+axis) mc.parentConstraint(self.handles[-1],self.ArcCtrl.handles[-1],mo=True) mc.scaleConstraint(self.handles[-1],self.ArcCtrl.handles[-1],sk=('x','y'),mo=True) for bp in getBindPoses(self.jointHierarchy): mc.dagPose(self.handles[-1],a=True,n=bp) mc.setAttr(self.handles[-1]+'.sy',k=False,lock=True) mc.setAttr(self.handles[-1]+'.sx',k=False,lock=True) if not self.spread: mc.setAttr(self.handles[-1]+'.sz',k=False,lock=True) mc.setAttr(self.handles[-1]+'.v',k=False,cb=True) for bp in getBindPoses(self.jointHierarchy): mc.dagPose(self.handles[-1],a=True,n=bp)
def addTargets(self,*args,**keywords): targets=[] goals=[] goalRange=[[0,10]] deleteTargets=False base=self.base baseIndex=0 controlObjects=[] controlAttributes=[] prune=self.prune baseIndex=0 weights=[0] control=True shortNames=\ { 't':'targets', 'g':'goals', 'r':'goalRange', 'range':'goalRange', 'dt':'deleteTargets', 'b':'base', 'co':'controlObjects', 'ca':'controlAttributes', 'goal':'goals', 'p':'prune', 'w':'weights', 'c':'control' } for k in keywords: if k in shortNames: exec(shortNames[k]+'=keywords[k]') elif k in locals() and k!='shortNames': exec(k+'=keywords[k]') targets.extend(args) controlObjects=iterable(controlObjects) controlAttributes=iterable(controlAttributes) weights=iterable(weights) targetTrs=[] for i in range(0,len(targets)): targets[i]=iterable(targets[i]) targetTrs.append([]) for n in range(0,len(targets[i])): targets[i][n]=shape(targets[i][n]) targetTrs[-1].append(mc.listRelatives(targets[i][n],p=True)[0]) if len(targets)==0: raise Exception('BlendShape.addTargets() requires target(s).') return #double-check base index in case of changes to indexing geometry=iterable(mc.blendShape(self[0],q=True,g=True)) if shape(base[baseIndex]) in geometry: baseIndex=geometry.index(shape(base[baseIndex])) elif base[baseIndex] in geometry: baseIndex=geometry.index(base[baseIndex]) else: raise Exception('Shape '+shape(base[baseIndex])+' is not used by '+self[0]+'.') return while len(goals)<len(targets): goals.append([]) while len(weights)<len(targets): weights.append(weights[-1]) while len(goalRange)<len(targets): goalRange.append(goalRange[-1]) for i in range(0,len(targets)): t=iterable(targets[i]) g=iterable(goals[i]) r=iterable(goalRange[i]) if len(base)>1: matchingBases=[] tvs=len(mc.ls(t[-1]+'.vtx[*]',fl=True)) tfs=len(mc.ls(t[-1]+'.f[*]',fl=True)) tes=len(mc.ls(t[-1]+'.e[*]',fl=True)) for b in base: if\ ( tvs==len(mc.ls(b+'.vtx[*]',fl=True)) and tfs==len(mc.ls(b+'.f[*]',fl=True)) and tes==len(mc.ls(b+'.e[*]',fl=True)) ): matchingBases.append(b) if base[baseIndex] not in matchingBases and len(matchingBases)>0: baseIndex=base.index(matchingBases[-1]) index=firstOpenPlug(self[0]+'.it['+str(baseIndex)+'].itg') if len(g)>0 and g[-1]<g[0]: g.reverse() t.reverse() if len(g)>=len(t): r=[g[0],g[-1]] if len(r)==1 and isinstance(r[0],(float,long,int)): r=[r[0],r[0]+10] elif len(r)>2 and isinstance(r[0],(float,long,int)) and isinstance(r[-1],(float,long,int)): r=[r[0],r[-1]] elif len(r)==0 or not isinstance(r[0],(float,long,int)) or not isinstance(r[-1],(float,long,int)): r=[0,10] if r[-1]<r[0]: r.reverse() t.reverse() if t[-1] not in mc.blendShape(self[0],q=True,t=True): n=0 if len(g)==0: g.append(r[0]+(r[-1]-r[0])/len(t)) while len(g)<len(t): g.append(g[-1]+(r[-1]-g[-1])/(len(t)-len(g))) n+=1 for n in range(0,len(t)): mc.blendShape\ ( self[0], e=True, t=(base[baseIndex],index,t[n],g[n]), w=(index,weights[i]) ) goals[i]=g targets[i]=t goalRange[i]=r # if we don't have all the control attributes or we don't have a control object, make some up if len(controlObjects)==0 and len(targets)>0: controlObjects.append(mc.listRelatives(base[baseIndex],p=True)[0]) if len(controlObjects)>0: while len(controlObjects)<len(targets): controlObjects.append(controlObjects[-1]) n=0 while len(controlAttributes)<len(targetTrs): controlAttributes.append(targetTrs[n][-1].replace(base[baseIndex],'')) if controlAttributes[-1][0] in ['_','|']: controlAttributes[-1]=controlAttributes[-1][1:] controlAttributes[-1]=controlAttributes[-1][0].lower()+controlAttributes[-1][1:] n=+1 if control: for i in range(0,len(targets)): if mc.objExists(controlObjects[i]) and controlAttributes[i] not in removeDuplicates(mc.listAttr(controlObjects[i])): mc.addAttr\ ( controlObjects[i], ln=controlAttributes[i], at='double', dv=weights[i], k=True, smx=goalRange[i][-1], smn=goalRange[i][0] ) if not mc.isConnected(controlObjects[i]+'.'+controlAttributes[i],self[0]+'.'+targets[i][-1]): mc.connectAttr(controlObjects[i]+'.'+controlAttributes[i],self[0]+'.'+targets[i][-1],f=True) self.controlObjects.extend(controlObjects) self.targets.extend(targets) self.range.extend(goalRange) self.goals.extend(goals) self.base.extend(base) self.controlObjects.extend(controlObjects) self.controlAttributes.extend(controlAttributes)
def create(self): worldMatrixNode=mc.createNode('fourByFourMatrix') wm=\ [ [1,0,0,0], [0,1,0,0], [0,0,1,0], [0,0,0,1] ] for a in range(0,4): for b in range(0,4): mc.setAttr( worldMatrixNode+'.in'+str(a)+str(b), wm[a][b] ) self.worldMatrix=worldMatrixNode+'.o' wsMatrices=[] cleanup=[] lattices=[] uvPos=[] antipodes=[] cpos=mc.createNode('closestPointOnSurface') if 'surfaceAttr' not in self.__dict__ or len(self.surfaceAttr)==0 and len(self.edges)>0: mc.select(self.edges) rebuildNode,surfaceNodeTr=mel.eval('zenLoftBetweenEdgeLoopPathRings(2)')[:2] self.surfaceAttr=rebuildNode+'.outputSurface' children=mc.listRelatives(surfaceNodeTr,c=True,s=True,ni=True,type='nurbsSurface') if isIterable(children) and len(children)>0: self.uSpans=mc.getAttr(children[0]+'.spansU') self.vSpans=mc.getAttr(children[0]+'.spansV') mc.disconnectAttr(self.surfaceAttr,surfaceNodeTr+'.create') mc.delete(surfaceNodeTr) if self.uSpans<0 or self.vSpans<0: tempTr=mc.createNode('transform') tempCurve=mc.createNode('nurbsCurve',p=tempTr) mc.connectAttr(self.surfaceAttr,tempCurve+'.create') self.uSpans=mc.getAttr(tempCurve+'.spansU') self.vSpans=mc.getAttr(tempCurve+'.spansV') mc.disconnectAttr(self.surfaceAttr,tempCurve+'.create') mc.delete(tempTr) orderedTrs=[] orderedCtrls=[] if self.distribute not in ['u','v']: #calculate the axis of distribution if len(self.trs)!=0: mc.connectAttr(self.surfaceAttr,cpos+'.inputSurface') uMin=100 vMin=100 uMax=0 vMax=0 uPosList=[] vPosList=[] for i in range(0,self.number): orderedTrs.append('') orderedCtrls.append('') t=self.trs[i] if mc.objExists(t): # find the closest point if self.hasGeometry: center=mc.objectCenter(t) mc.setAttr(cpos+'.ip',*center) posCenter,uCenter,vCenter=mc.getAttr(cpos+'.p')[0],mc.getAttr(cpos+'.u'),mc.getAttr(cpos+'.v') rp=mc.xform(t,ws=True,q=True,rp=True) mc.setAttr(cpos+'.ip',*rp) posRP,uRP,vRP=mc.getAttr(cpos+'.p')[0],mc.getAttr(cpos+'.u'),mc.getAttr(cpos+'.v') # see which is closer - object center or rotate pivot if self.hasGeometry: distCenter=distanceBetween(posCenter,center) distRP=distanceBetween(posRP,rp) if self.hasGeometry==False or abs(distCenter)>abs(distRP) : uPosList.append(uRP) vPosList.append(vRP) if uRP<uMin: uMin=uRP if uRP>uMax: uMax=uRP if vRP<vMin: vMin=vRP if vRP>vMax: vMax=vRP else: uPosList.append(uCenter) vPosList.append(vCenter) if uCenter<uMin: uMin=uCenter if uCenter>uMax: uMax=uCenter if vCenter<vMin: vMin=vCenter if vCenter>vMax: vMax=vCenter cfsi=mc.createNode('curveFromSurfaceIso') mc.connectAttr(self.surfaceAttr,cfsi+'.is') mc.setAttr(cfsi+'.idr',0) mc.setAttr(cfsi+'.iv',.5) mc.setAttr(cfsi+'.r',True) mc.setAttr(cfsi+'.rv',True) if len(self.trs)!=0: mc.setAttr(cfsi+'.min',uMin) mc.setAttr(cfsi+'.max',uMax) ci=mc.createNode('curveInfo') mc.connectAttr(cfsi+'.oc',ci+'.ic') uLength=mc.getAttr(ci+'.al') mc.setAttr(cfsi+'.idr',1) if len(self.trs)!=0: mc.setAttr(cfsi+'.min',vMin) mc.setAttr(cfsi+'.max',vMax) vLength=mc.getAttr(ci+'.al') mc.delete(cfsi,ci) if uLength>vLength: self.distribute='u' if len(self.trs)!=0: searchList=uPosList orderedList=uPosList[:] orderedList.sort() else: self.distribute='v' if len(self.trs)!=0: searchList=vPosList orderedList=vPosList[:] orderedList.sort() reverseTrs=False orderIDList=[] for n in range(0,self.number): s=searchList[n] for i in range(0,self.number): if s==orderedList[i] and i not in orderIDList: orderIDList.append(i) orderedTrs[i]=self.trs[n] orderedCtrls[i]=self.ctrls[n] if n==0 and i>len(self.trs)/2: reverseTrs=True break if reverseTrs: orderedTrs.reverse() self.trs=orderedTrs orderedCtrls.reverse() self.ctrls=orderedCtrls else: self.trs=orderedTrs self.ctrls=orderedCtrls if self.rebuild: # interactive rebuild, maintains even parameterization over the rivet surface, use with caution if self.distribute=='u': self.surfaceAttr=mel.eval('zenUniformSurfaceRebuild("'+self.surfaceAttr+'",'+str(self.uSpans*2)+',-1)')+'.outputSurface' else: self.surfaceAttr=mel.eval('zenUniformSurfaceRebuild("'+self.surfaceAttr+'",-1,'+str(self.vSpans*2)+')')+'.outputSurface' if not mc.isConnected(self.surfaceAttr,cpos+'.inputSurface'): mc.connectAttr(self.surfaceAttr,cpos+'.inputSurface',f=True) if self.taper=='distance' or self.createAimCurve or self.closestPoint=='geometry': # find the closest points ( and antipodes ) for i in range(0,self.number): t=self.trs[i] cp=ClosestPoints(self.surfaceAttr,t) self.ClosestPoints.append(cp) if self.taper=='distance' or self.createAimCurve: # antipodes are used for lattice allignment and curve calculations antipodes.append(cp.getAntipodes(1)) if self.taper!='none' or self.scale!='none': # measures scale with scaling cfsiLength=mc.createNode('curveFromSurfaceIso') ciLength=mc.createNode('curveInfo') lengthMultiplierNode=mc.createNode('multDoubleLinear') mc.setAttr(cfsiLength+'.relative',True) mc.setAttr(cfsiLength+'.relativeValue',True) if self.distribute=='u': mc.setAttr(cfsiLength+'.isoparmDirection',0) else: mc.setAttr(cfsiLength+'.isoparmDirection',1) mc.setAttr(cfsiLength+'.minValue',0) mc.setAttr(cfsiLength+'.maxValue',1) mc.setAttr(cfsiLength+".isoparmValue",.5) mc.connectAttr(self.surfaceAttr,cfsiLength+'.inputSurface') if mc.objExists(self.spaceTr): lengthCurve=mc.createNode('nurbsCurve',p=self.spaceTr) lengthCurveTG=mc.createNode('transformGeometry') mc.connectAttr(self.spaceTr+'.worldMatrix[0]',lengthCurveTG+'.txf') mc.connectAttr(cfsiLength+'.outputCurve',lengthCurveTG+'.ig') mc.connectAttr(lengthCurveTG+'.og',lengthCurve+'.create') mc.connectAttr(lengthCurve+'.worldSpace',ciLength+'.inputCurve') mc.setAttr(lengthCurve+'.intermediateObject',True) cleanup.extend([lengthCurveTG,cfsiLength]) else: mc.connectAttr(cfsiLength+'.outputCurve',ciLength+'.inputCurve') mc.connectAttr(ciLength+'.al',lengthMultiplierNode+'.i1') mc.setAttr(lengthMultiplierNode+'.i2',1.0/float(mc.getAttr(ciLength+'.al'))) lengthMultiplier=lengthMultiplierNode+'.o' uvPos=[] closestDistanceToCenter=Decimal('infinity') centerMostRivetID=0 closestDistancesToCenter=[Decimal('infinity'),Decimal('infinity')] centerMostRivetIDs=[0,0] uvMultipliers=[] aimGroups=[] for i in range(0,self.number): pTrs=mc.listRelatives(self.trs[i],p=True) parentTr='' if len(iterable(pTrs))>0: parentTr=pTrs[0] t=self.trs[i] c=self.ctrls[i] r=mc.createNode('transform',n='Rivet#') wsMatrices.append(mc.xform(t,q=True,ws=True,m=True)) if self.constraint: mc.setAttr(r+'.inheritsTransform',False) if not mc.objExists(c): c=t if not mc.objExists(t): c=r if not mc.objExists(c+'.zenRivet'): mc.addAttr(c,at='message',ln='zenRivet',sn='zriv') mc.connectAttr(r+'.message',c+'.zriv',f=True) if not mc.objExists(c+'.uPos'): mc.addAttr(c,k=True,at='double',ln='uPos',dv=50) if not mc.objExists(c+'.vPos'): mc.addAttr(c,k=True,at='double',ln='vPos',dv=50) if self.closestPoint=='geometry': up,vp=self.ClosestPoints[i].uvs[0] else: if mc.objExists(t): if self.hasGeometry: center=mc.objectCenter(t) mc.setAttr(cpos+'.ip',*center) posCenter,uCenter,vCenter=mc.getAttr(cpos+'.p')[0],mc.getAttr(cpos+'.u'),mc.getAttr(cpos+'.v') rp=mc.xform(t,ws=True,q=True,rp=True) mc.setAttr(cpos+'.ip',*rp) posRP,uRP,vRP=mc.getAttr(cpos+'.p')[0],mc.getAttr(cpos+'.u'),mc.getAttr(cpos+'.v') if self.hasGeometry: distCenter=distanceBetween(posCenter,center) distRP=distanceBetween(posRP,rp) if self.hasGeometry==False or abs(distCenter)>abs(distRP): up=uRP vp=vRP else: up=uCenter vp=vCenter elif len(distribute)>0: if self.distribute=='u': up=(i+1)/self.number vp=.5 else: up=.5 vp=(i+1)/self.number if up>float(self.uSpans)-.01: up=float(self.uSpans)-.01 if vp>float(self.vSpans)-.01: vp=float(self.vSpans)-.01 if up<.01: up=.01 if vp<.01: vp=.01 uvPos.append((up,vp)) if up<.5 and self.distribute=='u' and Decimal(str(abs(.5-up)))<Decimal(str(closestDistancesToCenter[0])): closestDistancesToCenter[0]=abs(.5-up) centerMostRivetIDs[0]=i if up>.5 and self.distribute=='u' and Decimal(str(abs(.5-up)))<Decimal(str(closestDistancesToCenter[1])): closestDistancesToCenter[1]=abs(.5-up) centerMostRivetIDs[1]=i if up<.5 and self.distribute=='v' and Decimal(str(abs(.5-vp)))<Decimal(str(closestDistancesToCenter[0])): closestDistancesToCenter[0]=abs(.5-vp) centerMostRivetIDs[0]=i if up>.5 and self.distribute=='v' and Decimal(str(abs(.5-vp)))<Decimal(str(closestDistancesToCenter[1])): closestDistancesToCenter[1]=abs(.5-vp) centerMostRivetIDs[1]=i mc.setAttr(c+'.uPos',up*100) mc.setAttr(c+'.vPos',vp*100) posi=mc.createNode('pointOnSurfaceInfo') mc.setAttr((posi+".caching"),True) #mc.setAttr((posi+".top"),True) multiplyU=mc.createNode('multDoubleLinear') mc.connectAttr(c+".uPos",multiplyU+".i1") mc.setAttr(multiplyU+'.i2',.01) multiplyV=mc.createNode('multDoubleLinear') mc.connectAttr(c+".vPos",multiplyV+".i1") mc.setAttr(multiplyV+'.i2',.01) uvMultipliers.append([multiplyU,multiplyV]) mc.connectAttr(self.surfaceAttr,posi+".inputSurface"); mc.connectAttr(multiplyU+".o",posi+".parameterU") mc.connectAttr(multiplyV+".o",posi+".parameterV") dm=mc.createNode('decomposeMatrix') mc.setAttr(dm+'.caching',True) fbfm=mc.createNode('fourByFourMatrix') mc.setAttr(fbfm+'.caching',True) mc.connectAttr(posi+'.nnx',fbfm+'.in00') mc.connectAttr(posi+'.nny',fbfm+'.in01') mc.connectAttr(posi+'.nnz',fbfm+'.in02') mc.connectAttr(posi+'.nux',fbfm+'.in10') mc.connectAttr(posi+'.nuy',fbfm+'.in11') mc.connectAttr(posi+'.nuz',fbfm+'.in12') mc.connectAttr(posi+'.nvx',fbfm+'.in20') mc.connectAttr(posi+'.nvy',fbfm+'.in21') mc.connectAttr(posi+'.nvz',fbfm+'.in22') mc.connectAttr(posi+'.px',fbfm+'.in30') mc.connectAttr(posi+'.py',fbfm+'.in31') mc.connectAttr(posi+'.pz',fbfm+'.in32') if self.constraint:# and not self.parent: mc.connectAttr(fbfm+'.output',dm+'.inputMatrix') else: multMatrix=mc.createNode('multMatrix') mc.connectAttr(r+'.parentInverseMatrix',multMatrix+'.i[1]') mc.connectAttr(fbfm+'.output',multMatrix+'.i[0]') mc.connectAttr(multMatrix+'.o',dm+'.inputMatrix') mc.connectAttr(dm+'.outputTranslate',r+'.t') mc.connectAttr(dm+'.outputRotate',r+'.r') if t!=r: if self.createAimCurve: aimGroup=mc.createNode('transform',n='rivetAimGrp#') mc.parent(aimGroup,t,r=True) mc.parent(aimGroup,r) if self.keepPivot or self.closestPoint=='pivot': mc.xform(aimGroup,ws=True,piv=mc.xform(t,q=True,ws=True,rp=True)) else: mc.xform(aimGroup,ws=True,piv=self.ClosestPoints[i][1]) self.aimGroups.append(aimGroup) if self.constraint: if self.parent: # parent and constraint == ParentSpace self.parentSpaces.append(ParentSpace(t,r)) pc=self.parentSpaces[i].parentConstraint sc=self.parentSpaces[i].scaleConstraint skip=['x'] if\ ( (self.distribute=='v' and 'length' in self.scaleDirection) or (self.distribute=='u' and 'width' in self.scaleDirection) or t in self.skipScaleObjects ): skip.append('y') if\ ( (self.distribute=='u' and 'length' in self.scaleDirection) or (self.distribute=='v' and 'width' in self.scaleDirection) or t in self.skipScaleObjects ): skip.append('z') mc.scaleConstraint(sc,e=True,sk=skip) if t in self.skipRotateObjects: mc.parentConstraint(pc,e=True,sr=('x','y','z')) if t in self.skipTranslateObjects: mc.parentConstraint(pc,e=True,st=('x','y','z')) else: #just constraint if t in self.skipRotateObjects: pc=mc.parentConstraint(r,t,sr=('x','y','z'),mo=True)[0]# if t in self.skipTranslateObjects: pc=mc.parentConstraint(r,t,st=('x','y','z'),mo=self.mo)[0] if t not in self.skipRotateObjects and t not in self.skipTranslateObjects: pc=mc.parentConstraint(r,t,mo=self.mo)[0] pcTargets=mc.parentConstraint(pc,q=True,tl=True) pcIDs=[] nsc=listNodeConnections(r,pc,s=False,d=True) for n in range(0,len(nsc)): if len(nsc[n])==2 and mc.objExists(nsc[n][-1]): pcID=getIDs(nsc[n][-1]) if isinstance(pcID,int): pcIDs.append(pcID) pcIDs=removeDuplicates(pcIDs) for pcID in pcIDs: mc.connectAttr(self.worldMatrix,pc+'.tg['+str(pcID)+'].tpm',f=True) mc.connectAttr(dm+'.outputTranslate',pc+'.tg['+str(pcID)+'].tt',f=True) mc.connectAttr(dm+'.outputRotate',pc+'.tg['+str(pcID)+'].tr',f=True) cleanup.append(r) if self.parent: scTargets=mc.scaleConstraint(sc,q=True,tl=True) scIDs=[] nsc=listNodeConnections(r,sc,s=False,d=True) for n in range(0,len(nsc)): if len(nsc[n])==2 and mc.objExists(nsc[n][-1]): scIDs.append(getIDs(nsc[n][-1])) scIDs=removeDuplicates(scIDs) scMD=mc.createNode('multiplyDivide') mc.setAttr(scMD+'.i1',1,1,1) mc.setAttr(scMD+'.i2',1,1,1) for scID in scIDs: mc.connectAttr(self.worldMatrix,sc+'.tg['+str(scID)+'].tpm',f=True) #mc.connectAttr(scMD+'.o',sc+'.tg['+str(scID)+'].ts',f=True) mc.connectAttr(scMD+'.ox',sc+'.tg['+str(scID)+'].tsx',f=True) mc.connectAttr(scMD+'.oy',sc+'.tg['+str(scID)+'].tsy',f=True) mc.connectAttr(scMD+'.oz',sc+'.tg['+str(scID)+'].tsz',f=True) r=self.parentSpaces[i][0] #xfm=mc.xform(r,q=True,ws=True,m=True) #mc.setAttr(r+'.inheritsTransform',False) #mc.xform(r,m=xfm) #mc.connectAttr(self.surfaceMatrix,multMatrix+'.i[1]',f=True)#self.parentSpaces[i][0]+'.parentInverseMatrix' elif self.createAimCurve: mc.parent(t,w=True) mc.setAttr(t+'.inheritsTransform',False) mc.parent(t,r,r=True) else: mc.parent(t,r) if mc.objExists(parentTr) and (self.parent or self.createAimCurve) and not self.constraint: if not (parentTr in iterable(mc.listRelatives(r,p=True))): if mc.getAttr(r+'.inheritsTransform')==True: mc.parent(r,parentTr,r=True) else: mc.parent(r,parentTr) if mc.getAttr(r+'.inheritsTransform')==False: dm=mc.createNode('decomposeMatrix') mc.connectAttr(parentTr+'.worldMatrix',dm+'.inputMatrix') mc.connectAttr(dm+'.os',t+'.s',f=True) if self.taper!='none' or self.scale!='none': cfsiU=mc.createNode('curveFromSurfaceIso') mc.setAttr(cfsiU+'.relative',True) mc.setAttr(cfsiU+'.relativeValue',True) mc.setAttr(cfsiU+'.isoparmDirection',0) mc.setAttr(cfsiU+'.minValue',0) mc.setAttr(cfsiU+'.maxValue',1) mc.connectAttr(multiplyV+".o",cfsiU+".isoparmValue") mc.connectAttr(self.surfaceAttr,cfsiU+'.inputSurface') cfsiV=mc.createNode('curveFromSurfaceIso') mc.setAttr(cfsiV+'.relative',True) mc.setAttr(cfsiV+'.relativeValue',True) mc.setAttr(cfsiV+'.isoparmDirection',1) mc.setAttr(cfsiV+'.minValue',0) mc.setAttr(cfsiV+'.maxValue',1) mc.connectAttr(multiplyV+".o",cfsiV+".isoparmValue") mc.connectAttr(self.surfaceAttr,cfsiV+'.inputSurface') subtractNode=mc.createNode('addDoubleLinear') mc.setAttr(subtractNode+'.i1',-(1/(self.number*2))) addNode=mc.createNode('addDoubleLinear') mc.setAttr(addNode+'.i1',1/(self.number*2)) addSubClampNode=mc.createNode('clamp') mc.setAttr(addSubClampNode+'.min',0,0,0) mc.setAttr(addSubClampNode+'.max',1,1,1) mc.connectAttr(subtractNode+'.o',addSubClampNode+'.inputR') mc.connectAttr(addNode+'.o',addSubClampNode+'.inputG') if self.distribute=='u': mc.connectAttr(multiplyU+".o",subtractNode+".i2") mc.connectAttr(multiplyU+".o",addNode+".i2") mc.connectAttr(addSubClampNode+'.outputR',cfsiU+'.minValue') mc.connectAttr(addSubClampNode+'.outputG',cfsiU+'.maxValue') else: mc.connectAttr(multiplyV+".o",subtractNode+".i2") mc.connectAttr(multiplyV+".o",addNode+".i2") mc.connectAttr(addSubClampNode+'.outputR',cfsiV+'.minValue') mc.connectAttr(addSubClampNode+'.outputG',cfsiV+'.maxValue') ciU=mc.createNode('curveInfo') mc.connectAttr(cfsiU+'.outputCurve',ciU+'.inputCurve') ciV=mc.createNode('curveInfo') mc.connectAttr(cfsiV+'.outputCurve',ciV+'.inputCurve') mdlU=mc.createNode('multDoubleLinear') mc.connectAttr(ciU+'.al',mdlU+'.i1') mc.setAttr(mdlU+'.i2',1/float(mc.getAttr(ciU+'.al'))) mdlV=mc.createNode('multDoubleLinear') mc.connectAttr(ciV+'.al',mdlV+'.i1') mc.setAttr(mdlV+'.i2',1/float(mc.getAttr(ciV+'.al'))) if not mc.objExists(c+'.minScaleWidth'): mc.addAttr(c,ln='minScaleWidth',at='double',k=True,min=0,dv=self.minScaleWidth) if not mc.objExists(c+'.maxScaleWidth'): mc.addAttr(c,ln='maxScaleWidth',at='double',k=True,min=0,dv=self.maxScaleWidth) if not mc.objExists(c+'.minScaleLength'): mc.addAttr(c,ln='minScaleLength',at='double',k=True,min=0,dv=self.minScaleLength) if not mc.objExists(c+'.maxScaleLength'): mc.addAttr(c,ln='maxScaleLength',at='double',k=True,min=0,dv=self.maxScaleLength) clampNode=mc.createNode('clamp') minScaleLengthNode=mc.createNode('multDoubleLinear') maxScaleLengthNode=mc.createNode('multDoubleLinear') minScaleWidthNode=mc.createNode('multDoubleLinear') maxScaleWidthNode=mc.createNode('multDoubleLinear') mc.connectAttr(c+'.minScaleLength',minScaleLengthNode+'.i1') mc.connectAttr(lengthMultiplier,minScaleLengthNode+'.i2') mc.connectAttr(c+'.maxScaleLength',maxScaleLengthNode+'.i1') mc.connectAttr(lengthMultiplier,maxScaleLengthNode+'.i2') mc.connectAttr(c+'.minScaleWidth',minScaleWidthNode+'.i1') mc.connectAttr(lengthMultiplier,minScaleWidthNode+'.i2') mc.connectAttr(c+'.maxScaleWidth',maxScaleWidthNode+'.i1') mc.connectAttr(lengthMultiplier,maxScaleWidthNode+'.i2') if self.distribute=='u': mc.connectAttr(minScaleLengthNode+'.o',clampNode+'.minR') mc.connectAttr(maxScaleLengthNode+'.o',clampNode+'.maxR') mc.connectAttr(minScaleWidthNode+'.o',clampNode+'.minG') mc.connectAttr(maxScaleWidthNode+'.o',clampNode+'.maxG') else: mc.connectAttr(minScaleWidthNode+'.o',clampNode+'.minR') mc.connectAttr(maxScaleWidthNode+'.o',clampNode+'.maxR') mc.connectAttr(minScaleLengthNode+'.o',clampNode+'.minG') mc.connectAttr(maxScaleLengthNode+'.o',clampNode+'.maxG') mc.connectAttr(mdlU+'.o',clampNode+'.ipr') mc.connectAttr(mdlV+'.o',clampNode+'.ipg') if self.scale=='relative' and self.parent:#or len(self.scaleDirection)<2:# if\ ( (self.distribute=='u' and 'length' in self.scaleDirection) or (self.distribute=='v' and 'width' in self.scaleDirection) ): if self.constraint: mc.connectAttr(clampNode+'.opr',scMD+'.i1y') else: mc.connectAttr(clampNode+'.opr',r+'.sy',f=True) if\ ( (self.distribute=='v' and 'length' in self.scaleDirection) or (self.distribute=='u' and 'width' in self.scaleDirection) ): if self.constraint: mc.connectAttr(clampNode+'.opg',scMD+'.i1z') else: mc.connectAttr(clampNode+'.opg',r+'.sz',f=True) elif self.taper!='none' and self.parent: #self.autoFlexGroups mc.setAttr(t+'.sx',lock=True) mc.setAttr(t+'.sy',lock=True) mc.setAttr(t+'.sz',lock=True) mc.setAttr(t+'.tx',lock=True) mc.setAttr(t+'.ty',lock=True) mc.setAttr(t+'.tz',lock=True) mc.setAttr(t+'.rx',lock=True) mc.setAttr(t+'.ry',lock=True) mc.setAttr(t+'.rz',lock=True) aimTr=mc.createNode('transform',p=t) mc.xform(aimTr,ws=True,t=antipodes[i]) #mc.setAttr(db+'.p1',*self.ClosestPoints[i][0]) #mc.setAttr(db+'.p2',*antipodes[i]) axisLength=distanceBetween(self.ClosestPoints[i][0],antipodes[i])#mc.getAttr(db+'.d') ffd,lattice,latticeBase=mc.lattice(t,divisions=(2,2,2),objectCentered=True,ol=1) latticeLowEndPoints=mc.ls(lattice+'.pt[0:1][0:0][0:1]',fl=True) latticeHighEndPoints=mc.ls(lattice+'.pt[0:1][1:1][0:1]',fl=True) mc.parent(latticeBase,lattice) mc.setAttr(lattice+'.sy',axisLength) lattices.append([ffd,lattice,latticeBase]) mc.parent(lattice,t) mc.xform(lattice,ws=True,a=True,t=mc.xform(r,q=True,ws=True,a=True,rp=True)) mc.xform(lattice,os=True,a=True,ro=(0,0,0)) mc.move(0,axisLength/2,0,lattice,r=True,os=True,wd=True) xSum,ySum,zSum=0,0,0 for p in latticeLowEndPoints: px,py,pz=mc.pointPosition(p,w=True) xSum+=px ySum+=py zSum+=pz mc.xform(lattice,ws=True,piv=(xSum/len(latticeLowEndPoints),ySum/len(latticeLowEndPoints),zSum/len(latticeLowEndPoints))) mc.xform(latticeBase,ws=True,piv=(xSum/len(latticeLowEndPoints),ySum/len(latticeLowEndPoints),zSum/len(latticeLowEndPoints))) ac=mc.aimConstraint(aimTr,lattice,aim=(0,1,0),wut='objectrotation',wuo=r,u=(0,0,1),mo=False) mc.delete(ac) ac=mc.aimConstraint(aimTr,aimGroup,aim=(0,1,0),wut='objectrotation',wuo=r,u=(0,0,1),mo=False) mc.delete(ac,aimTr) lowEndCluster,lowEndClusterHandle=mc.cluster(latticeLowEndPoints)[:2] highEndCluster,highEndClusterHandle=mc.cluster(latticeHighEndPoints)[:2] lowEndClusterHandleShape=mc.listRelatives(lowEndClusterHandle,c=True)[0] highEndClusterHandleShape=mc.listRelatives(highEndClusterHandle,c=True)[0] #mc.parent(highEndClusterHandle,t) if mc.isConnected(lowEndClusterHandleShape+'.clusterTransforms[0]',lowEndCluster+'.clusterXforms'): mc.disconnectAttr(lowEndClusterHandleShape+'.clusterTransforms[0]',lowEndCluster+'.clusterXforms') if mc.isConnected(highEndClusterHandleShape+'.clusterTransforms[0]',highEndCluster+'.clusterXforms'): mc.disconnectAttr(highEndClusterHandleShape+'.clusterTransforms[0]',highEndCluster+'.clusterXforms') self.autoFlexGroups.append\ ( ( mc.createNode('transform',n='rivetBaseAutoFlex#',p=r), mc.createNode('transform',n='rivetEndAutoFlex#',p=aimGroup) ) ) self.handles.append\ ( ( mc.createNode('transform',n='rivetBaseCtrl#',p=self.autoFlexGroups[i][0]), mc.createNode('transform',n='rivetEndCtrl#',p=self.autoFlexGroups[i][1]) ) ) self.handleShapes.append\ ( ( mc.createNode('locator',p=self.handles[i][0]), mc.createNode('locator',p=self.handles[i][1]) ) ) mc.setAttr(self.handleShapes[i][0]+'.los',.5,.5,.5) mc.setAttr(self.handleShapes[i][1]+'.los',.5,.5,.5) mc.xform(self.autoFlexGroups[i][0],ws=True,a=True,t=mc.xform(t,q=True,ws=True,rp=True)) mc.xform(self.autoFlexGroups[i][0],ws=True,a=True,piv=mc.xform(t,q=True,ws=True,rp=True)) for bp in self.bindPoses: mc.dagPose((self.handles[i][0],self.handles[i][1]),a=True,n=bp) mc.xform(self.autoFlexGroups[i][1],ws=True,t=antipodes[i]) mc.hide(lattice) mc.connectAttr(self.handles[i][0]+'.worldInverseMatrix[0]',lowEndCluster+'.bindPreMatrix',f=True) mc.disconnectAttr(self.handles[i][0]+'.worldInverseMatrix[0]',lowEndCluster+'.bindPreMatrix') mc.connectAttr(self.handles[i][0]+'.worldMatrix[0]',lowEndCluster+'.matrix',f=True) mc.connectAttr(self.handles[i][1]+'.worldInverseMatrix[0]',highEndCluster+'.bindPreMatrix',f=True) mc.disconnectAttr(self.handles[i][1]+'.worldInverseMatrix[0]',highEndCluster+'.bindPreMatrix') mc.connectAttr(self.handles[i][1]+'.worldMatrix[0]',highEndCluster+'.matrix',f=True) aimGroups.append(aimGroup) if self.distribute=='u': mc.connectAttr(clampNode+'.opr',self.autoFlexGroups[i][0]+'.sy') else: mc.connectAttr(clampNode+'.opg',self.autoFlexGroups[i][0]+'.sz') mc.delete([lowEndClusterHandle,highEndClusterHandle]) self.rivets.append(r) if self.createAimCurve and self.parent: pmm=mc.createNode('pointMatrixMult') arcPoints=[] ids=[0,centerMostRivetIDs[0],centerMostRivetIDs[1],-1] for id in ids: measureTr=mc.createNode('transform') aimTr=mc.createNode('transform',p=self.trs[id]) mc.parent(measureTr,self.trs[id]) mc.xform(aimTr,ws=True,t=antipodes[id]) mc.xform(measureTr,ws=True,t=mc.xform(self.rivets[id],q=True,ws=True,a=True,rp=True)) #mc.xform(measureTr,os=True,a=True,ro=(0,0,0),s=(1,1,1)) ac=mc.aimConstraint(aimTr,measureTr,aim=(0,1,0),wut='objectrotation',wuo=self.rivets[id],u=(0,0,1),mo=False) mc.delete(ac,aimTr) mc.connectAttr(measureTr+'.worldInverseMatrix',pmm+'.inMatrix',f=True) maxYID=-1 maxY=0.0 yVal=0.0 for i in range(0,self.number): mc.setAttr(pmm+'.ip',*antipodes[i]) yVal=mc.getAttr(pmm+'.oy') if yVal>maxY: maxY=yVal maxYID=i mc.setAttr(pmm+'.ip',*antipodes[maxYID]) oy=mc.getAttr(pmm+'.oy') mc.setAttr(pmm+'.ip',*antipodes[id]) ox=mc.getAttr(pmm+'.ox') oz=mc.getAttr(pmm+'.oz') mc.connectAttr(measureTr+'.worldMatrix',pmm+'.inMatrix',f=True) mc.setAttr(pmm+'.ip',ox,oy,oz) ap=mc.getAttr(pmm+'.o')[0] arcPoints.append(ap) mc.disconnectAttr(measureTr+'.worldMatrix',pmm+'.inMatrix') mc.delete(measureTr) mc.delete(pmm) arcCtrlArg=arcPoints arcCtrlKeys={'arcWeight':self.arcWeight,'p':self.parents,'sp':self.softParents} for k in arcCtrlKeys: if type(arcCtrlKeys[k]).__name__=='NoneType': del(arcCtrlKeys[k]) self.ArcCtrl=ArcCtrl(*arcCtrlArg,**arcCtrlKeys) mc.addAttr(self.ArcCtrl[0],at='bool',ln='showHandles',k=True,dv=False) mc.setAttr(self.ArcCtrl[0]+'.showHandles',k=False,cb=True) mc.setAttr(self.ArcCtrl[0]+'.v',k=False,cb=True) mc.setAttr(self.ArcCtrl[1]+'.v',k=False,cb=True) for h in self.handles: mc.connectAttr(self.ArcCtrl[0]+'.showHandles',h[0]+'.v') mc.connectAttr(self.ArcCtrl[0]+'.showHandles',h[1]+'.v') for bp in self.bindPoses: mc.dagPose(self.ArcCtrl,a=True,n=bp) cpoc=mc.createNode('closestPointOnCurve') mc.connectAttr(self.ArcCtrl.outputCurve,cpoc+'.inCurve') for i in range(0,self.number): aimTr=mc.createNode('transform') poci=mc.createNode('pointOnCurveInfo') dm=mc.createNode('decomposeMatrix') fbfm=mc.createNode('fourByFourMatrix') mc.connectAttr(poci+'.nnx',fbfm+'.in00') mc.connectAttr(poci+'.nny',fbfm+'.in01') mc.connectAttr(poci+'.nnz',fbfm+'.in02') mc.connectAttr(poci+'.ntx',fbfm+'.in10') mc.connectAttr(poci+'.nty',fbfm+'.in11') mc.connectAttr(poci+'.ntz',fbfm+'.in12') mc.connectAttr(self.ArcCtrl.outputNormal+'X',fbfm+'.in20') mc.connectAttr(self.ArcCtrl.outputNormal+'Y',fbfm+'.in21') mc.connectAttr(self.ArcCtrl.outputNormal+'Z',fbfm+'.in22') mc.connectAttr(poci+'.px',fbfm+'.in30') mc.connectAttr(poci+'.py',fbfm+'.in31') mc.connectAttr(poci+'.pz',fbfm+'.in32') mc.connectAttr(fbfm+'.output',dm+'.inputMatrix') mc.connectAttr(dm+'.outputTranslate',aimTr+'.t') mc.connectAttr(dm+'.outputRotate',aimTr+'.r') mc.setAttr(cpoc+'.ip',*antipodes[i]) cpu=mc.getAttr(cpoc+'.u') mc.setAttr(poci+'.parameter',cpu) mc.connectAttr(self.ArcCtrl.outputCurve,poci+'.inputCurve') ac=mc.aimConstraint(aimTr,self.aimGroups[i],aim=(0,1,0),wut='objectrotation',wuo=aimTr,u=(0,0,1),mo=not(self.realign))[0] disconnectNodes(aimTr,ac) mc.connectAttr(fbfm+'.output',ac+'.worldUpMatrix',f=True) mc.connectAttr(dm+'.ot',ac+'.target[0].targetTranslate',f=True) mc.delete(aimTr) sc=mc.createNode('subCurve') mc.setAttr(sc+'.relative',True) mc.setAttr(sc+'.minValue',0) mc.setAttr(sc+'.maxValue',1) mc.connectAttr(self.ArcCtrl.outputCurve,sc+'.ic') if self.distribute=='u': uMultAttr=uvMultipliers[i][0]+".o" else: uMultAttr=uvMultipliers[i][1]+".o" #adjust for offset multOffsetCalc=mc.createNode('multDoubleLinear') mc.setAttr(multOffsetCalc+'.i1',1/mc.getAttr(uMultAttr)) mc.connectAttr(uMultAttr,multOffsetCalc+'.i2') multOffset=mc.createNode('multDoubleLinear') mc.setAttr(multOffset+'.i1',cpu) mc.connectAttr(multOffsetCalc+'.o',multOffset+'.i2') mc.connectAttr(multOffset+'.o',poci+'.parameter',f=True) subtractNode=mc.createNode('addDoubleLinear') mc.setAttr(subtractNode+'.i1',-(1.0/(self.number*2))) addNode=mc.createNode('addDoubleLinear') mc.setAttr(addNode+'.i1',1.0/(self.number*2)) addSubClampNode=mc.createNode('clamp') mc.setAttr(addSubClampNode+'.min',0,0,0) mc.setAttr(addSubClampNode+'.max',1,1,1) mc.connectAttr(subtractNode+'.o',addSubClampNode+'.inputR') mc.connectAttr(addNode+'.o',addSubClampNode+'.inputG') mc.connectAttr(multOffset+".o",subtractNode+".i2") mc.connectAttr(multOffset+".o",addNode+".i2") mc.connectAttr(addSubClampNode+'.outputR',sc+'.minValue') mc.connectAttr(addSubClampNode+'.outputG',sc+'.maxValue') ciU=mc.createNode('curveInfo') mc.connectAttr(sc+'.outputCurve',ciU+'.inputCurve') mdlU=mc.createNode('multDoubleLinear') mc.connectAttr(ciU+'.al',mdlU+'.i1') mc.setAttr(mdlU+'.i2',1/float(mc.getAttr(ciU+'.al'))) clampNode=mc.createNode('clamp') if not mc.objExists(c+'.minScaleEnd'): mc.addAttr(self.ctrls[i],ln='minScaleEnd',at='double',k=True,min=0,max=1,dv=0) if not mc.objExists(c+'.maxScaleEnd'): mc.addAttr(self.ctrls[i],ln='maxScaleEnd',at='double',k=True,min=0,dv=1) mc.connectAttr(self.ctrls[i]+'.minScaleEnd',clampNode+'.minR') mc.connectAttr(self.ctrls[i]+'.maxScaleEnd',clampNode+'.maxR') mc.connectAttr(mdlU+'.o',clampNode+'.ipr') if self.distribute=='u': mc.connectAttr(clampNode+'.opr',self.autoFlexGroups[i][1]+'.sz') else: mc.connectAttr(clampNode+'.opr',self.autoFlexGroups[i][1]+'.sy') mc.delete(cpoc) if self.parent: self[:]=self.rivets else: self[:]=self.trs #if self.mo: # #for i in len(self.trs): # #try: mc.xform(t,q=True,ws=True,m=wsMatrices[i])) # #except: pass cleanup.append(cpos) for c in cleanup: if mc.objExists(c): disconnectNodes(c) mc.delete(c) if self.snapToSurface: if self.createAimCurve or self.taper: for i in range(0,self.number): mc.xform(self.handles[i][0],ws=True,t=mc.xform(self.rivets[i],q=True,ws=True,rp=True)) mc.xform(self.trs[i],ws=True,rp=mc.xform(self.rivets[i],q=True,ws=True,rp=True)) else: for i in range(0,self.number): mc.xform(self.trs[i],ws=True,t=mc.xform(self.rivets[i],q=True,ws=True,rp=True)) mc.xform(self.trs[i],ws=True,ro=mc.xform(self.rivets[i],q=True,ws=True,ro=True))
def __init__(self,*args,**keywords): #check to make sure unique names are used in scene uniqueNames(iterable(mc.ls(type='dagNode')),re=True) #default options self.number=1 #if there are no transforms, create this many rivets self.distribute='' self.parents=['',''] self.rebuild=False self.taper='none' # none, normal, distance self.scale='none' # none, uniform, or relative self.scaleDirection=['length','width'] # length, width self.createAimCurve=False self.aimCurve='' self.handles=[] self.handleShapes=[] self.autoFlexGroups=[] self.mo=True # maintain offset self.ctrls=[] #by default control attributes are placed on given transforms self.keepPivot=True self.snapToSurface=False self.realign=False self.rivets=[] self.ClosestPoints=[] self.aimGroups=[] self.softParents=[] self.ArcCtrl=[] self.arcWeight=.5 self.closestPoint='' # geometry, pivot self.organize=True self.constraint=False # use a parent constraint self.parent=False # create a transform and parent objects to it self.spaceTr='' self.surfaceAttr='' self.bindPoses=[] self.parentSpaces=[] self.hasGeometry=True self.skipRotate=[] self.skipTranslate=[] self.skipScale=[] self.skipScaleObjects=[] self.skipRotateObjects=[] self.skipTranslateObjects=[] self.minScaleWidth=0 self.maxScaleWidth=1 self.minScaleLength=0 self.maxScaleLength=1 self.surfaceMatrix='' self.surfaceInverseMatrix='' self.worldMatrix='' self.trs=[] self.uSpans=-1 self.vSpans=-1 self.skins=[] self.shortNames=\ { 'sd':'scaleDirection', 'p':'parents', 'sp':'softParents' } sel=[] if len(args)==0: sel=mc.ls(sl=True) for a in args: sel.extend(iterable(a)) self.bindPoses=iterable(getBindPoses(sel)) if len(self.bindPoses)>0: goToDagPose(self.bindPoses[0]) self.edges=PolyEdgeList(sel,f=True) self.trs=removeDuplicates(mc.ls(self.edges.etcObj,tr=True)) if len(self.edges)==0: #look for a surface or surface attribute reversedObjList=getReversed(self.edges.etcObj) for obj in reversedObjList: if len(obj.split('.'))>1 and mc.getAttr(obj,type=True)=='nurbsSurface': self.surfaceAttr=obj obj=mc.ls(self.surfaceAttr,o=True)[0] if mc.nodeType(obj)=='nurbsSurface': self.uSpans=mc.getAttr(obj+'.spansU') self.vSpans=mc.getAttr(obj+'.spansV') self.spaceTr=mc.listRelatives(obj,p=True)[0] break elif mc.nodeType(obj)=='nurbsSurface': self.surfaceAttr=obj+'.worldSpace[0]' self.spaceTr=mc.listRelatives(obj,p=True)[0] self.uSpans=mc.getAttr(obj+'.spansU') self.vSpans=mc.getAttr(obj+'.spansV') self.trs.remove(obj) break else: children=mc.listRelatives(obj,c=True,s=True,ni=True,type='nurbsSurface') if isIterable(children) and len(children)>0: self.spaceTr=mc.ls(obj)[0] self.surfaceAttr=children[0]+'.worldSpace[0]' self.uSpans=mc.getAttr(children[0]+'.spansU') self.vSpans=mc.getAttr(children[0]+'.spansV') self.trs.remove(obj) break else: self.spaceTr=self.edges.getTr() for k in keywords: if k in self.__dict__: exec('self.'+k+'=keywords[k]') elif k in self.shortNames: exec('self.'+self.shortNames[k]+'=keywords[k]') if len(iterable(self.parents))==1: self.parents=[iterable(self.parents)[0],iterable(self.parents)[0]] if len(iterable(self.softParents))==1: self.softParents=[iterable(self.softParents)[0],iterable(self.softParents)[0]] if len(self.ctrls)==0: self.ctrls=self.trs while len(self.ctrls)<len(self.trs): self.ctrls.append(self.ctrls[-1]) if len(self.skipRotate)>0: for i in self.skipRotate: self.skipRotateObjects.append(self.trs[self.skipRotate[i]]) if len(self.skipTranslate)>0: for i in self.skipTranslate: self.skipTranslateObjects.append(self.trs[self.skipTranslate[i]]) if len(self.skipScale)>0: for i in self.skipScale: self.skipScaleObjects.append(self.trs[self.skipScale[i]]) if len(self.trs)>0: for t in self.trs: shCount=len\ ( removeDuplicates(mc.listRelatives(t,c=True,type='nurbsSurface'))+ removeDuplicates(mc.listRelatives(t,c=True,type='nurbsCurve'))+ removeDuplicates(mc.listRelatives(t,c=True,type='mesh')) ) if shCount==0: self.hasGeometry=False self.closestPoint='pivot' break if self.closestPoint=='' and self.hasGeometry: # default to pivot if using snap to surface, otherwise defualts to geometry if self.snapToSurface: self.closestPoint='pivot' else: self.closestPoint='geometry' if len(self.trs)!=0: self.number=len(self.trs) if len(self.ctrls)<len(self.trs): self.ctrls=self.trs if not self.parent and not self.constraint: self.parent=True if self.createAimCurve: self.parent=True #self.constraint=False #find the root joint if present try: joints=removeDuplicates(mc.listConnections(iterable(mc.ls(iterable(mc.listHistory(self.surfaceAttr)))),type='joint')) if len(joints)>0: self.spaceTr=hierarchyOrder(joints)[0] except: pass self.create()
def geoConnect(*args,**keywords): """ Connects shapes and worldSpace transforms of one shape to another, or all shapes in one file or namespace to another. Accepts an input of 2 or more file names, 2 or more name spaces, or any even number of objects. """ # default options driverNameSpace='' drivenNameSpace='' drivers=[] driven=[] hide=[] recursive=False maintainOffset=False output='' returnVal=[] shortNames=\ { 'r':'recursive', 'mo':'maintainOffset', 'o':'output', 'rv':'returnVal', 'h':'hide' } for k in keywords: if k in locals(): exec(k+'=keywords[k]') elif k in shortNames: exec(shortNames[k]+'=keywords[k]') if len(args)==0 and driverNameSpace=='' and drivenNameSpace=='': sel=iterable(mc.ls(sl=True)) sel=[] for a in args: sel.extend(iterable(a)) for i in range(0,len(sel)): if sel[i]=='': sel[i]=':' fromFiles=True for i in range(0,len(sel)): if len(sel[i].split('.'))>1: if not os.path.isfile(sel[i]): filePath=findFile(sel[i]) if os.path.isfile(filePath): sel[i]=filePath else: fromFiles=False break else: fromFiles=False break hide=iterable(hide) while len(hide)<len(sel): hide.append(False) matchByNameSpace=True if fromFiles: if len(sel)==1: sel.append(sel[0]) sel[0]=mc.file(q=True,l=True)[0] else: if mc.file(q=True,l=True)[0]!=sel[0]: mc.file(sel[0],o=True,f=True) driverNameSpace=mc.namespaceInfo(cur=True) drivenNameSpace=os.path.basename(sel[1].split('.')[0]) mc.file(sel[1],i=True,ra=True,namespace=drivenNameSpace,pr=True,loadReferenceDepth='all',options='v=1') else: nameSpaces=[':']+iterable(mc.namespaceInfo(lon=True)) for s in sel: if s not in nameSpaces: matchByNameSpace=False break if not matchByNameSpace: sel=iterable(mc.ls(sel)) matchNames=False if matchByNameSpace: currentNameSpace=mc.namespaceInfo(cur=True) if not fromFiles: if len(sel)>1: driverNameSpace=sel[0] if len(sel)==1: driverNameSpace=':' drivenNameSpace=sel[1] mc.namespace(set=driverNameSpace) for d in iterable(mc.ls(mc.namespaceInfo(ls=True),type=('mesh','nurbsCurve','nurbsSurface'))): if mc.getAttr(d+'.io')==False: drivers.append(d) mc.namespace(set=drivenNameSpace) for d in iterable(mc.ls(mc.namespaceInfo(ls=True),type=('mesh','nurbsCurve','nurbsSurface'))): if mc.getAttr(d+'.io')==False: driven.append(d) mc.namespace(set=currentNameSpace) drivers.sort() driven.sort() matchNames=True elif len(sel)>1: driven=sel[int(len(sel)/2):int(len(sel)/2)*2] drivers=sel[:int(len(sel)/2)] if recursive: matchNames=True drs=drivers dns=driven if len(drs)<=len(dns): r=len(drs) else: r=len(dns) for i in range(0,r): dr=drs[i] dn=dns[i] if shape(dr)!=dr or shape(dn)!=dn: drivers.remove(dr) driven.remove(dn) if shape(dr)!=dr and shape(dn)!=dn: drc=[] for dr in iterable(mc.listRelatives(dr,ad=True,type=('mesh','nurbsCurve','nurbsSurface'))): if mc.getAttr(dr+'.io')==False: drc.append(dr) drc.sort() dnc=[] for dn in iterable(mc.listRelatives(dn,ad=True,type=('mesh','nurbsCurve','nurbsSurface'))): if mc.getAttr(dn+'.io')==False: dnc.append(dn) dnc.sort() drivers.extend(drc) driven.extend(dnc) else: #check to see if we can match by name spaces if len(drivers[0].split(':'))>1 or len(driven[0].split(':'))>1: if len(drivers[0].split(':'))>1: driverNameSpace=':'.join(drivers[0].split(':')[:-1]) if len(driven[0].split(':'))>1: drivenNameSpace=':'.join(driven[0].split(':')[:-1]) matchNames=True if len(drivers)<=len(driven): r=len(drivers) else: r=len(driven) for i in range(0,r): if\ ( ( (driverNameSpace=='' and len(drivers[i].split(':'))<2) or ':'.join(drivers[i].split(':')[:-1])==driverNameSpace ) and ( (drivenNameSpace=='' and len(driven[i].split(':'))<2) or ':'.join(driven[i].split(':')[:-1])==drivenNameSpace ) and ( drivers[i].split(':')[-1]==driven[i].split(':')[-1] ) ): pass else: matchNames=False break driversHold=drivers drivenHold=driven drivers=[] driven=[] if len(drivers)<=len(driven): r=len(drivers) else: r=len(driven) for i in range(0,r): if shape(driversHold[i])!='' and shape(drivenHold[i])!='': drivers.append(shape(drivers[i])) drivers.append(shape(driven[i])) else: return if matchNames: # match names driverParents=[] driverHasSiblings=[] driversBN=[] for i in range(0,len(drivers)): driversBN.append(drivers[i].split('|')[-1].split(':')[-1]) driverParents.append(mc.listRelatives(drivers[i],p=True)[0].split('|')[-1].split(':')[-1]) sib=False for c in mc.listRelatives(driverParents[-1],c=True,type=mc.nodeType(drivers[i])): if c!=drivers[i] and mc.getAttr(c+'.io')==False: sib=True driverHasSiblings.append(sib) drivenParents=[] drivenParentLists=[] drivenBN=[] for i in range(0,len(driven)): #if driven[i].split(':')>1: drivenBN.append(driven[i].split('|')[-1].split(':')[-1]) drivenParentLists.append(iterable(mc.ls(driven[i],l=True)[0].split('|')[:-1])) for n in range(0,len(drivenParentLists[-1])): drivenParentLists[-1][n]=drivenParentLists[-1][n].split(':')[-1] drivenParents.extend(drivenParentLists[-1]) driversHold=drivers drivenHold=driven driven=[] drivers=[] for i in range(0,len(driversBN)): matched=False if (driverParents[i] in drivenParents) and not driverHasSiblings[i]: # match by transform names for n in range(0,len(drivenParentLists)): if driverParents[i] in drivenParentLists[n]: drivers.append(driversHold[i]) driven.append(drivenHold[n]) elif driversBN[i] in drivenBN: # match by shape names drivers.append(driversHold[i]) driven.append(drivenHold[drivenBN.index(driversBN[i])]) for i in range(0,len(drivers)): driverSh=drivers[i] drivenSh=driven[i] driverTr=mc.listRelatives(driverSh,p=True)[0] drivenTr=mc.listRelatives(drivenSh,p=True)[0] #drive shape if maintainOffset==False: shapeMatch=True else: shapeMatch=False if shapeMatch and mc.nodeType(driverSh)!=mc.nodeType(drivenSh): shapeMatch=False if shapeMatch and mc.nodeType(driverSh)=='nurbsCurve' or mc.nodeType(driverSh)=='nurbsSurface': if mc.ls(driverSh+'.cv[*]')!=mc.ls(drivenSh+'.cv[*]'): shapeMatch=False if shapeMatch and mc.nodeType(driverSh)=='mesh': if\ ( len(mc.ls(driverSh+'.vtx[*]',fl=True))!=len(mc.ls(drivenSh+'.vtx[*]',fl=True)) or len(mc.ls(driverSh+'.f[*]',fl=True))!=len(mc.ls(drivenSh+'.f[*]',fl=True)) or len(mc.ls(driverSh+'.e[*]',fl=True))!=len(mc.ls(drivenSh+'.e[*]',fl=True)) ): shapeMatch=False # try to connect with blendShape if shapeMatch: try: bs=BlendShape(driverSh,drivenSh,w=10,c=False)[0] returnVal.append(bs) except: shapeMatch=False # connect transforms mm=mc.createNode('multMatrix') dm=mc.createNode('decomposeMatrix') mc.connectAttr(driverTr+'.wm[0]',mm+'.i[1]') mc.connectAttr(drivenTr+'.pim',mm+'.i[0]') mc.connectAttr(mm+'.o',dm+'.imat') mc.connectAttr(dm+'.os',drivenTr+'.s') mc.connectAttr(dm+'.osh',drivenTr+'.sh') if shapeMatch: mc.parentConstraint(driverTr,drivenTr,mo=False) else: mc.parentConstraint(driverTr,drivenTr,mo=True) for attr in ['rp','rpt','sp','spt','ra','ro','it','rq']: for a in mc.listAttr(driverTr+'.'+attr): mc.connectAttr(driverTr+'.'+a,drivenTr+'.'+a,f=True) if not shapeMatch: # connect with wrap if mc.nodeType(driverSh)=='mesh' and mc.nodeType(drivenSh)=='mesh': driverArea=mc.polyEvaluate(driverSh,a=True) drivenArea=mc.polyEvaluate(drivenSh,a=True) areaPercDiff=(driverArea-drivenArea)/drivenArea if mc.nodeType(driverSh)=='mesh' and mc.nodeType(drivenSh)=='mesh' and areaPercDiff>.1: cpom=mc.createNode('closestPointOnMesh') mc.connectAttr(driverSh+'.worldMesh[0]',cpom+'.im') driverFaces=[] drivenFaces=iterable(mc.ls(drivenSh+'.f[*]',fl=True)) mc.progressWindow(st='Analyzing mesh...',title='Working',max=len(drivenFaces)/20,ii=True) n=0 for f in drivenFaces: mc.setAttr(cpom+'.ip',*midPoint(f)) driverFaces.append(driverSh+'.f['+str(mc.getAttr(cpom+'.f'))+']') if float(n)/20.0==int(n/20): mc.progressWindow(e=True,s=1) if mc.progressWindow(q=True,ic=True): if mc.objExists(cpom): mc.delete(cpom) mc.progressWindow(e=True,ep=True) raise Exception('User interupt.') n+=1 mc.progressWindow(e=True,ep=True) driverFaces=removeDuplicates(driverFaces) wrap=Wrap(driverFaces,drivenSh) if mc.objExists(cpom): mc.delete(cpom) else: wrap=Wrap(driverSh,drivenSh) returnVal.append(wrap) if hide[0]: mc.hide(driverSh) if hide[1]: mc.hide(drivenSh) if (fromFiles or matchByNameSpace) and len(sel)>2: return geoConnect(o=output,r=recursive,mo=maintainOffset,rv=returnVal,h=(hide[0]+hide[2:]),*(sel[0]+sel[2:])) elif output!='': # save if len(output.split('.'))<2: output=output+'.'+sel[0].split('.')[-1] if not os.path.isdir(os.path.dirname(output)): output=os.path.dirname(sel[0])+'/'+output if output.split('.')[-1]=='.ma': outputType='mayaAscii' else: outputType='mayaBinary' mc.file(rename=output) mc.file(f=True,save=True,type=outputType) else: return returnVal
def create(self): # arguments and list options are reversed before and after creation to conform context with IK Handle creation for lo in self.__dict__: if isinstance(self.__dict__[lo],list): exec('self.'+lo+'.reverse()') self.arcCheck() trSpaces=[] cleanup=[] curveShapes=[] keep=[] loft='' if self.createSurface: xs=[0,1] else: xs=[0] for i in [0,1]: self.handles.append(mc.createNode('transform',n=self.names[i])) trSpaces.append(self.handles[-1]) mc.addAttr(self.handles[1],ln='arcNormal',at='float3') mc.addAttr(self.handles[1],ln='arcNormalX',at='float',p='arcNormal') mc.addAttr(self.handles[1],ln='arcNormalY',at='float',p='arcNormal') mc.addAttr(self.handles[1],ln='arcNormalZ',at='float',p='arcNormal') blendCurveShapes=[] arc=[] bs=[] bn=[] mdlWidth=[] origShape=[] ci=[] spans=0 ext=[] measureCurves=[] if len(xs)>1: mdlWidth.append(mc.createNode('multDoubleLinear')) mc.setAttr(mdlWidth[0]+'.i2',-.5) mdlWidth.append(mc.createNode('multDoubleLinear')) mc.setAttr(mdlWidth[1]+'.i2',.5) for x in xs: #align handles arc.append([]) arc[x].append(mc.createNode('makeThreePointCircularArc',n='arc#')) arc[x].append(mc.createNode('makeThreePointCircularArc',n='arc#')) #mc.setAttr(arc[x][0]+'.sections',16) #mc.setAttr(arc[x][1]+'.sections',16) n=0 for i in range(0,2)+[-1]: mc.setAttr(arc[x][0]+'.point'+str(n+1),*self.arcPoints[i]) n+=1 n=0 for i in [0]+range(-2,0): mc.setAttr(arc[x][1]+'.point'+str(n+1),*self.arcPoints[i]) n+=1 bn.append(mc.createNode('blendColors')) mc.connectAttr(arc[x][0]+'.nr',bn[x]+'.c1') mc.connectAttr(arc[x][1]+'.nr',bn[x]+'.c2') if x==0: mc.connectAttr(bn[x]+'.op',self.handles[1]+'.arcNormal') self.outputNormal=self.handles[1]+'.arcNormal' if x==0: fbfm=mc.createNode('fourByFourMatrix') dm=mc.createNode('decomposeMatrix') cpoc=['',''] bcN=mc.createNode('blendColors') bcT=mc.createNode('blendColors') bcP=mc.createNode('blendColors') mc.setAttr(bn[x]+'.b',self.arcWeight) mc.setAttr(bcN+'.b',self.arcWeight) mc.setAttr(bcT+'.b',self.arcWeight) mc.setAttr(bcP+'.b',self.arcWeight) mc.connectAttr(bcN+'.opr',fbfm+'.in00') mc.connectAttr(bcN+'.opg',fbfm+'.in01') mc.connectAttr(bcN+'.opb',fbfm+'.in02') mc.connectAttr(bcT+'.opr',fbfm+'.in10') mc.connectAttr(bcT+'.opg',fbfm+'.in11') mc.connectAttr(bcT+'.opb',fbfm+'.in12') mc.connectAttr(bcP+'.opr',fbfm+'.in30') mc.connectAttr(bcP+'.opg',fbfm+'.in31') mc.connectAttr(bcP+'.opb',fbfm+'.in32') mc.connectAttr(bn[x]+'.opr',fbfm+'.in20') mc.connectAttr(bn[x]+'.opg',fbfm+'.in21') mc.connectAttr(bn[x]+'.opb',fbfm+'.in22') mc.connectAttr(fbfm+'.output',dm+'.inputMatrix') for i in [0,1]: cpoc[i]=mc.createNode('closestPointOnCurve') mc.connectAttr(arc[x][i]+'.oc',cpoc[i]+'.ic') mc.connectAttr(cpoc[i]+'.nx',bcN+'.c'+str(i+1)+'r') mc.connectAttr(cpoc[i]+'.ny',bcN+'.c'+str(i+1)+'g') mc.connectAttr(cpoc[i]+'.nz',bcN+'.c'+str(i+1)+'b') mc.connectAttr(cpoc[i]+'.tx',bcT+'.c'+str(i+1)+'r') mc.connectAttr(cpoc[i]+'.ty',bcT+'.c'+str(i+1)+'g') mc.connectAttr(cpoc[i]+'.tz',bcT+'.c'+str(i+1)+'b') mc.connectAttr(cpoc[i]+'.px',bcP+'.c'+str(i+1)+'r') mc.connectAttr(cpoc[i]+'.py',bcP+'.c'+str(i+1)+'g') mc.connectAttr(cpoc[i]+'.pz',bcP+'.c'+str(i+1)+'b') for i in [0,-1]: mc.setAttr(cpoc[0]+'.ip',*self.arcPoints[i]) mc.setAttr(cpoc[1]+'.ip',*self.arcPoints[i]) mc.setAttr(trSpaces[i]+'.t',*mc.getAttr(dm+'.ot')[0]) mc.setAttr(trSpaces[i]+'.r',*mc.getAttr(dm+'.or')[0]) for i in [0,-1]: mc.disconnectAttr(arc[x][i]+'.oc',cpoc[i]+'.ic') mc.disconnectAttr(bn[x]+'.opr',fbfm+'.in20') mc.disconnectAttr(bn[x]+'.opg',fbfm+'.in21') mc.disconnectAttr(bn[x]+'.opb',fbfm+'.in22') mc.delete(fbfm,dm,cpoc,bcN,bcT,bcP) if len(xs)>1: loft=mc.createNode('loft') mc.setAttr(loft+'.autoReverse',False) mc.setAttr(loft+'.uniform',True) poci=mc.createNode('pointOnCurveInfo') i=0 for f in [.01,.99]: pmm=mc.createNode('pointMatrixMult') if len(xs)>1: mc.connectAttr(mdlWidth[x]+'.o',pmm+'.ipz') mc.connectAttr(trSpaces[i]+'.wm[0]',pmm+'.im') mc.connectAttr(pmm+'.o',arc[x][0]+'.point'+str([1,3][i])) mc.connectAttr(pmm+'.o',arc[x][1]+'.point'+str([1,3][i])) mc.connectAttr(arc[x][i]+'.outputCurve',poci+'.inputCurve',f=True) mc.setAttr(poci+'.top',True) mc.setAttr(poci+'.parameter',f) pmm=mc.createNode('pointMatrixMult') mc.connectAttr(trSpaces[i]+'.worldInverseMatrix',pmm+'.inMatrix') mc.setAttr(pmm+'.ip',*mc.getAttr(poci+'.p')[0]) ap=mc.getAttr(pmm+'.o')[0] mc.connectAttr(trSpaces[i]+'.worldMatrix',pmm+'.inMatrix',f=True) mc.setAttr(pmm+'.ip',*ap) if len(xs)>1: mc.connectAttr(mdlWidth[x]+'.o',pmm+'.ipz') mc.connectAttr(pmm+'.o',arc[x][i]+'.point2',f=True) i+=1 self.curveShapes.append(mc.createNode('nurbsCurve',p=trSpaces[1],n=self.names[1]+'Shape#')) blendCurveShapes.append(mc.createNode('nurbsCurve',p=trSpaces[1],n=self.names[1]+'Shape#')) mc.connectAttr(arc[x][0]+'.outputCurve',self.curveShapes[x]+'.create') mc.connectAttr(arc[x][1]+'.outputCurve',blendCurveShapes[x]+'.create') spans=mc.getAttr(self.curveShapes[x]+'.spans') bs.append(mc.blendShape(blendCurveShapes[x],self.curveShapes[x],o='local',w=(0,1))[0]) origShape.append(mc.listConnections(arc[x][0]+'.outputCurve',d=True,s=False,sh=True)[0]) blendConnectAttrs=mc.listConnections(origShape[x]+'.worldSpace',p=True,sh=True) for b in blendConnectAttrs: mc.connectAttr(arc[x][0]+'.outputCurve',b,f=True) mc.connectAttr(arc[x][1]+'.outputCurve',bs[x]+'.it[0].itg[0].iti[6000].igt',f=True) rc=mc.createNode('rebuildCurve') mc.setAttr(rc+'.kcp',False) mc.connectAttr(arc[x][0]+'.sections',rc+'.spans',f=True) mc.setAttr(rc+'.kr',0) reverseCurve=mc.createNode('reverseCurve') mc.connectAttr(rc+'.oc',reverseCurve+'.ic') tg=mc.createNode('transformGeometry') mc.connectAttr(tg+'.og',self.curveShapes[x]+'.create',f=True) mc.connectAttr(reverseCurve+'.oc',tg+'.ig') mc.connectAttr(trSpaces[1]+'.worldInverseMatrix',tg+'.transform',f=True) if self.stretch<0 or self.squash<0: mc.connectAttr(bs[x]+'.og[0]',rc+'.ic') else: rc2=mc.createNode('rebuildCurve') mc.connectAttr(arc[x][0]+'.sections',rc2+'.spans',f=True) mc.setAttr(rc2+'.kr',0) mc.connectAttr(bs[x]+'.og[0]',rc2+'.ic',f=True) sub=mc.createNode('subCurve') mc.setAttr(sub+'.r',True) mc.setAttr(sub+'.min',0) mc.setAttr(sub+'.max',1) ext='' ext=mc.createNode('extendCurve') mc.setAttr(ext+'.rmk',True) mc.setAttr(ext+'.d',.00001) mc.connectAttr(sub+'.oc',ext+'.ic1',f=True) mc.connectAttr(ext+'.oc',rc+'.ic',f=True) mc.connectAttr(rc2+'.oc',sub+'.ic',f=True) if not mc.objExists(self.handles[0]+'.stretch'): mc.addAttr(self.handles[0],ln='stretch',at='float',min=0,dv=self.stretch,k=True) if not mc.objExists(self.handles[0]+'.squash'): mc.addAttr(self.handles[0],ln='squash',at='float',min=0,max=100,dv=self.squash,k=True) if not mc.objExists(self.handles[1]+'.length'): mc.addAttr(self.handles[1],ln='length',at='float',min=0,k=True) if not mc.objExists(self.handles[1]+'.overSquash'): mc.addAttr(self.handles[1],ln='overSquash',at='float',min=0,dv=100,k=False) if not mc.objExists(self.handles[1]+'.overStretch'): mc.addAttr(self.handles[1],ln='overStretch',at='float',min=0,dv=100,k=False) ci.append(mc.createNode('curveInfo')) mc.connectAttr(rc+'.oc',ci[x]+'.ic',f=True) mc.connectAttr(rc2+'.oc',ci[x]+'.ic',f=True) measureAttr=ci[x]+'.al' if x==0 and len(xs)>1: pma=mc.createNode('plusMinusAverage') mc.setAttr(pma+'.op',3) overStretchPMA=mc.createNode('plusMinusAverage') mc.setAttr(overStretchPMA+'.op',3) mc.connectAttr(overStretchPMA+'.o1',self.handles[1]+'.overStretch') overSquashPMA=mc.createNode('plusMinusAverage') mc.setAttr(overSquashPMA+'.op',3) mc.connectAttr(overSquashPMA+'.o1',self.handles[1]+'.overSquash') if len(xs)>1: mc.connectAttr(ci[x]+'.al',pma+'.i1['+str(x)+']') measureAttr=pma+'.o1' mc.setAttr(self.handles[1]+'.length',float(mc.getAttr(measureAttr))) if x==0: stretchADL=mc.createNode('plusMinusAverage') mc.setAttr(stretchADL+'.op',2)# subtract mc.connectAttr(measureAttr,stretchADL+'.i1[0]') mc.connectAttr(self.handles[1]+'.length',stretchADL+'.i1[1]') stretchMD=mc.createNode('multiplyDivide') mc.setAttr(stretchMD+'.op',2)# divide mc.connectAttr(stretchADL+'.o1',stretchMD+'.i1x') mc.connectAttr(self.handles[1]+'.length',stretchMD+'.i2x') stretch=stretchMD+'.ox' mc.connectAttr(self.handles[0]+'.stretch',stretchMD+'.i1y') mc.setAttr(stretchMD+'.i2y',100) stretchMax=stretchMD+'.oy' stretchMDClamp=mc.createNode('clamp') mc.connectAttr(stretchMax,stretchMDClamp+'.mxr')#stretchMD+'.oy' mc.setAttr(stretchMDClamp+'.mnr',0.0001) mc.connectAttr(stretchMax,stretchMDClamp+'.ipr') stretchMax=stretchMDClamp+'.opr' mc.connectAttr(stretchMax,stretchMDClamp+'.mxg') mc.setAttr(stretchMDClamp+'.mng',0.0001) mc.connectAttr(stretch,stretchMDClamp+'.ipg') stretchClamped=stretchMDClamp+'.opg' mc.connectAttr(stretch,stretchMDClamp+'.mxb') mc.setAttr(stretchMDClamp+'.mnb',0.0001) mc.connectAttr(stretch,stretchMDClamp+'.ipb') stretchClampedLo=stretchMDClamp+'.opb' stretchGapPMA=mc.createNode('plusMinusAverage')# difference between max stretch and current stretch mc.setAttr(stretchGapPMA+'.op',2)# subtract mc.connectAttr(stretchMax,stretchGapPMA+'.i1[0]') mc.connectAttr(stretchClampedLo,stretchGapPMA+'.i1[1]') stretchGAP=stretchGapPMA+'.o1' stretchGapPercMD=mc.createNode('multiplyDivide')# %difference between max stretch and current stretch mc.setAttr(stretchGapPercMD+'.op',2)# divide mc.connectAttr(stretchGAP,stretchGapPercMD+'.i1x') mc.connectAttr(stretchMax,stretchGapPercMD+'.i2x') stretchGapPerc=stretchGapPercMD+'.ox' stretchPlusOneNode=mc.createNode('addDoubleLinear') mc.connectAttr(stretchClampedLo,stretchPlusOneNode+'.i1') mc.setAttr(stretchPlusOneNode+'.i2',1) stretchPlusOne=stretchPlusOneNode+'.o' overStretchSubNode=mc.createNode('plusMinusAverage') mc.setAttr(overStretchSubNode+'.op',2)# subtract mc.connectAttr(stretchClampedLo,overStretchSubNode+'.i1[0]')#stretchMinusFallOff mc.connectAttr(stretchClamped,overStretchSubNode+'.i1[1]')#stretchClampedMinusFallOff overStretchDivNode=mc.createNode('multiplyDivide') mc.setAttr(overStretchDivNode+'.op',2)# divide mc.connectAttr(overStretchSubNode+'.o1',overStretchDivNode+'.i1x') mc.connectAttr(stretchPlusOne,overStretchDivNode+'.i2x') overStretch=overStretchDivNode+'.ox' if len(xs)>1: mc.connectAttr(overStretch,overStretchPMA+'.i1['+str(x)+']') #squash squashPMA=mc.createNode('plusMinusAverage') mc.setAttr(squashPMA+'.op',2)# subtract mc.connectAttr(self.handles[1]+'.length',squashPMA+'.i1[0]') mc.connectAttr(measureAttr,squashPMA+'.i1[1]') squashDist=squashPMA+'.o1' squashDistClamp=mc.createNode('clamp') mc.connectAttr(squashDist,squashDistClamp+'.mxr')#stretchMD+'.oy' mc.setAttr(squashDistClamp+'.mnr',0.00001) mc.connectAttr(squashDist,squashDistClamp+'.ipr') squashDistClamped=squashDistClamp+'.opr' squashMD=mc.createNode('multiplyDivide') mc.setAttr(squashMD+'.op',2)# divide mc.connectAttr(squashDistClamped,squashMD+'.i1x') mc.connectAttr(self.handles[1]+'.length',squashMD+'.i2x') squash=squashMD+'.ox' mc.connectAttr(self.handles[0]+'.squash',squashMD+'.i1y') mc.setAttr(squashMD+'.i2y',100) squashMax=squashMD+'.oy' squashMDClamp=mc.createNode('clamp') mc.connectAttr(squashMax,squashMDClamp+'.mxr') mc.setAttr(squashMDClamp+'.mnr',0.00001) mc.connectAttr(squashMax,squashMDClamp+'.ipr') squashMax=squashMDClamp+'.opr' mc.connectAttr(squashMax,squashMDClamp+'.mxg') mc.setAttr(squashMDClamp+'.mng',0.0001) mc.connectAttr(squash,squashMDClamp+'.ipg') squashClamped=squashMDClamp+'.opg' mc.connectAttr(squash,squashMDClamp+'.mxb') mc.setAttr(squashMDClamp+'.mnb',0.0001) mc.connectAttr(squash,squashMDClamp+'.ipb') squashClampedLo=squashMDClamp+'.opb' squashGapPMA=mc.createNode('plusMinusAverage')# difference between max squash and current squash mc.setAttr(squashGapPMA+'.op',2)# subtract mc.connectAttr(squashMax,squashGapPMA+'.i1[0]') mc.connectAttr(squashClampedLo,squashGapPMA+'.i1[1]') squashGAP=squashGapPMA+'.o1' squashGapPercMD=mc.createNode('multiplyDivide')# %difference between max squash and current squash mc.setAttr(squashGapPercMD+'.op',2)# divide mc.connectAttr(squashGAP,squashGapPercMD+'.i1x') mc.connectAttr(squashMax,squashGapPercMD+'.i2x') squashGapPerc=squashGapPercMD+'.ox' overSquashSubNode=mc.createNode('plusMinusAverage') mc.setAttr(overSquashSubNode+'.op',2)# subtract mc.connectAttr(squashClampedLo,overSquashSubNode+'.i1[0]')#squashMinusFallOff mc.connectAttr(squashClamped,overSquashSubNode+'.i1[1]')#squashClampedMinusFallOff overSquash=overSquashSubNode+'.o1'#overSquashDivNode+'.ox' overSquashDistanceMDL=mc.createNode('multDoubleLinear') mc.connectAttr(self.handles[1]+'.length',overSquashDistanceMDL+'.i1') mc.connectAttr(overSquash,overSquashDistanceMDL+'.i2') overSquashDistanceClamp=mc.createNode('clamp') mc.connectAttr(overSquashDistanceMDL+'.o',overSquashDistanceClamp+'.mxr')#stretchMD+'.oy' mc.setAttr(overSquashDistanceClamp+'.mnr',0.00001) mc.connectAttr(overSquashDistanceMDL+'.o',overSquashDistanceClamp+'.ipr') overSquashDistance=overSquashDistanceClamp+'.opr' if len(xs)>1: mc.connectAttr(overSquash,overSquashPMA+'.i1['+str(x)+']') if mc.objExists(ext+'.d'): mc.connectAttr(overSquashDistance,ext+'.d') mc.connectAttr(overStretch,sub+'.min') disconnectNodes(origShape[x]) mc.delete(origShape[x]) disconnectNodes(blendCurveShapes[x]) mc.delete(blendCurveShapes[x]) if x==len(xs)-1: if 'spans' not in mc.listAttr(self.handles[1]): mc.addAttr(self.handles[1],ln='spans',at='long',min=0,dv=spans,k=True) mc.connectAttr(self.handles[1]+'.spans',arc[0][0]+'.sections') mc.connectAttr(self.handles[1]+'.spans',arc[0][1]+'.sections') if len(xs)>1: mc.connectAttr(tg+'.og',loft+'.ic['+str(x)+']') disconnectNodes(self.curveShapes[x]) if x==1: mc.delete(self.curveShapes[x]) self.outputSurface=loft+'.os' if self.createSurface: self.surface=mc.createNode('nurbsSurface',p=trSpaces[1]) mc.connectAttr(self.outputSurface,self.surface+'.create',f=True) if not self.createSurface or ( self.scaleLength and mc.objExists(self.handles[1]+'.length') ): self.curveShapes[0]=mc.createNode('nurbsCurve',p=trSpaces[1]) cfsi=mc.createNode('curveFromSurfaceIso') mc.setAttr(cfsi+'.r',True) mc.setAttr(cfsi+'.rv',True) mc.setAttr(cfsi+'.min',0) mc.setAttr(cfsi+'.max',1) mc.setAttr(cfsi+'.idr',1) mc.setAttr(cfsi+'.idr',1) mc.setAttr(cfsi+'.iv',.5) mc.connectAttr(self.outputSurface,cfsi+'.is',f=True) mc.connectAttr(cfsi+'.oc',self.curveShapes[0]+'.create',f=True) self.outputCurve=cfsi+'.oc' for i in [0,-1]: if self.handleType[i]=='none': self.handleShapes.append(['']) else: if 'type' not in self.handleOptions[i]: self.handleOptions[i]['type']=self.handleType[i-1] self.handleShapes.append(Handle(self.handles[i],**self.handleOptions[i])) keep=keep+[self.surface]+self.handleShapes[0]+self.handleShapes[-1] if not self.createSurface or self.scaleLength: keep.append(self.curveShapes[0]) cleanup.extend\ ( removeAll\ ( keep, ( removeDuplicates(mc.listRelatives(trSpaces[1],c=True,type='nurbsSurface'))+ removeDuplicates(mc.listRelatives(trSpaces[1],c=True,type='nurbsCurve')) ) ) ) if self.createSurface: self.outputSurface=self.surface+'.worldSpace' else: self.outputCurve=self.curveShapes[0]+'.worldSpace' mc.addAttr(self.handles[0],ln='arcWeight',at='double',k=True,min=0,max=1,dv=self.arcWeight) if self.createSurface: mc.addAttr(self.handles[1],ln='width',at='double',k=True,min=.001,dv=self.width) mc.connectAttr(self.handles[1]+'.width',mdlWidth[0]+'.i1') mc.connectAttr(self.handles[1]+'.width',mdlWidth[1]+'.i1') rev=mc.createNode('reverse') mc.connectAttr(self.handles[0]+'.arcWeight',rev+'.ix') mc.connectAttr(rev+'.ox',bn[0]+'.b') if self.createSurface: mc.connectAttr(rev+'.ox',bn[1]+'.b') mc.connectAttr(rev+'.ox',bs[0]+'.en') if self.createSurface: mc.connectAttr(rev+'.ox',bs[1]+'.en') for i in [0,-1]: if self.parents[i]=='.': mc.parent(self.handles[i],self.handles[[-1,0][i]]) elif mc.objExists(self.parents[i]): mc.parent(self.handles[i],self.parents[i]) if self.softParents[i]=='.': self.parentSpaces[i]=ParentSpace(self.handles[i],self.handles[[-1,0][i]]) elif mc.objExists(self.softParents[i]): self.parentSpaces[i]=ParentSpace(self.handles[i],self.softParents[i]) for c in cleanup: if mc.objExists(c): disconnectNodes(c) mc.delete(c) if self.scaleLength and mc.objExists(self.handles[1]+'.length'): measureCurve=mc.createNode('nurbsCurve',p=self.handles[1],n=self.names[1]+'Shape#') mc.connectAttr(self.curveShapes[0]+'.local',measureCurve+'.create') ciOrig=mc.createNode('curveInfo') mc.connectAttr(measureCurve+'.worldSpace[0]',ciOrig+'.ic',f=True) #mc.connectAttr(ciOrig+'.al',self.handles[1]+'.length',f=True) divLength=mc.createNode('multiplyDivide') mc.setAttr(divLength+'.op',2) mc.connectAttr(self.handles[1]+'.length',divLength+'.i1x') mc.setAttr(divLength+'.i2x',mc.getAttr(self.handles[1]+'.length')) multLength=mc.createNode('multiplyDivide') mc.setAttr(multLength+'.op',1) mc.connectAttr(ciOrig+'.al',multLength+'.i1x') mc.connectAttr(divLength+'.ox',multLength+'.i2x') for attr in [overSquashDistanceMDL+'.i1',stretchADL+'.i1[1]',stretchMD+'.i2x',squashPMA+'.i1[0]',squashMD+'.i2x']: mc.connectAttr(multLength+'.ox',attr,f=True) mc.addAttr(self.handles[1],ln='globalLength',at='double') mc.connectAttr(multLength+'.ox',self.handles[1]+'.globalLength',f=True) mc.addAttr(self.handles[1],ln='lengthScale',at='double') mc.connectAttr(divLength+'.ox',self.handles[1]+'.lengthScale',f=True) mc.disconnectAttr(self.curveShapes[0]+'.local',measureCurve+'.create') mc.setAttr(measureCurve+'.intermediateObject',True) #mc.setAttr(self.handles[1]+'.length',k=False,cb=False) if self.createSurface: mc.delete(self.curveShapes[0]) # put lists back in input order for lo in self.__dict__: if isinstance(self.__dict__[lo],list): exec('self.'+lo+'.reverse()') self[:]=list(self.handles)
def constrainShape(shape): parentTr = mc.listRelatives(shape, p=True) while isIterable(parentTr): parentTr = parentTr[0] objCenter = mc.objectCenter(shape, gl=True) objCenterLocal = mc.objectCenter(shape, l=True) obj = mc.ls(parentTr, o=True)[0] constraintAttrs = mc.listConnections(parentTr, p=True, s=True, d=True, type="constraint") constraints = [] for c in mc.ls(constraintAttrs, o=True): if c not in constraints: constraints.append(c) if not isIterable(constraintAttrs) or len(constraintAttrs) == 0: raise Exception, (shape + " is not under a constrained transform.") tgNode = mc.createNode("transformGeometry") type = mc.nodeType(shape) base = mc.listRelatives(mc.duplicate(parentTr, rc=True)[0], c=True, type=type, s=True, ni=True)[0] mel.eval('zenParentShape {"' + base + '","' + parentTr + '"}') creationAttr = "" creationIn = "" creationOut = "" if type == "mesh": creationIn = ".inMesh" creationOut = ".outMesh" elif type in ("nurbsCurve", "nurbsSurface"): creationIn = ".create" creationOut = ".local" dummyTr = mc.createNode("unknownTransform", p=parentTr, n="dummyTr#") for c in constraints: mc.connectAttr(dummyTr + ".t", c + ".restTranslate", f=True) mc.xform(dummyTr, ws=True, t=objCenter) mc.connectAttr(base + creationOut, tgNode + ".inputGeometry") mc.connectAttr(tgNode + ".outputGeometry", shape + creationIn, f=True) mc.setAttr(base + ".intermediateObject", True) constraintAttrs = removeDuplicates(constraintAttrs) for c in constraintAttrs: connectedFrom = removeDuplicates(mc.listConnections(c, p=True, s=False, d=True)) connectedTo = removeDuplicates(mc.listConnections(c, p=True, s=True, d=False)) for cf in connectedFrom: if mc.ls(cf, o=True)[0] == obj: if mc.isConnected(c, cf): mc.disconnectAttr(c, cf) mc.connectAttr(c, dummyTr + "." + mc.listAttr(cf)[0], f=True) for ct in connectedTo: if mc.ls(ct, o=True)[0] == obj: attr = mc.listAttr(ct)[0] if mc.isConnected(ct, c): mc.disconnectAttr(ct, c) mc.connectAttr(dummyTr + "." + attr, c, f=True) mc.xform(parentTr, ws=True, piv=objCenter) for c in constraints: mc.xform(c, ws=True, piv=objCenter) for c in constraints: mc.disconnectAttr(dummyTr + ".t", c + ".restTranslate") mc.connectAttr(dummyTr + ".matrix", tgNode + ".transform", f=True) mel.eval('rigZenMakeNodesNonKeyable({"' + dummyTr + '"})') return dummyTr
def __init__(self,*args,**keywords): #check to make sure unique names are used in scene uniqueNames(iterable(mc.ls(type='dagNode')),re=True) self.tol=.001 for k in keywords: if k in self.__dict__: if type(eval('self.'+k)).__name__==type(keywords[k]).__name__: exec('self.'+k+'=keywords[k]') sel=[] for a in args: if isIterable(a): sel.extend(a) else: sel.append(a) sel=removeDuplicates(mc.ls(sel)+mc.ls(sl=True,o=True)) if len(sel)<2: raise Exception("Procedure requires two polygon meshes, nurbs surfaces, or nurbs curves.") else: sel=sel[:2] oo=Decimal('Infinity') self[:]=[[oo,oo,oo],[oo,oo,oo]] noo=Decimal('-Infinity') self.antipodes=[[noo,noo,noo],[noo,noo,noo]] self.uvs=[(-1,-1),(-1,-1)] self.closestFaces=['',''] self.closestFaceIDs=[-1,-1] self.closestVertexIDs=[-1,-1] self.antipodeFaces=['',''] self.antipodeFaceIDs=[-1,-1] self.antipodeUVs=[(-1,-1),(-1,-1)] self.antipodeVertexIDs=[-1,-1] self.trs,self.types,self.shapes,self.shAttr,self.knots,self.roughAPIDs,self.roughCPIDs,self.uv=[],[],[],[],[],[],[],[] density,maxDensity,cpID,searchID,i=0,0,0,0,0 ci,si='','' for s in sel: # find shapes and node types and determine which is denser if len(s.split('.'))>1: sha=s nt=mc.getAttr(sha,type=True) if nt=='nurbsCurve' or nt=='nurbsSurface' or nt=='mesh': self.shapes.append('') self.trs.append('') self.shAttr.append(sha) self.types.append(nt) else: raise Exception("Arguments must be polygon meshes, nurbs surfaces, or nurbs curves.") elif len(mc.ls(s,tr=True))>0: sh=[] for c in \ ( mc.listRelatives(s,c=True,s=True,ni=True,type='nurbsCurve'), mc.listRelatives(s,c=True,s=True,ni=True,type='nurbsSurface'), mc.listRelatives(s,c=True,s=True,ni=True,type='mesh') ): if isIterable(c) and len(c)>0: sh=c[0] if isinstance(sh,basestring) and mc.objExists(sh): nt=mc.nodeType(sh) self.shapes.append(sh) self.trs.append(s) self.types.append(nt) if nt=='mesh': sha=s+'.outMesh' if nt=='nurbsSurface' or nt=='nurbsCurve': sha=s+'.local' self.shAttr.append(sha) elif mc.objExists(s): nt=mc.nodeType(s) if nt=='nurbsCurve' or nt=='nurbsSurface' or nt=='mesh': self.shapes.append(s) self.trs.append(mc.listRelatives(s,p=True)[0]) self.types.append(nt) if nt=='mesh': sha=s+'.worldMesh[0]' if nt=='nurbsSurface' or nt=='nurbsCurve': sha=s+'.local' self.shAttr.append(sha) else: raise Exception("Arguments must be polygon meshes, nurbs surfaces, or nurbs curves.") else: raise Exception("Arguments must be polygon meshes, nurbs surfaces, or nurbs curves.") if nt=='mesh': self.knots.append({}) density=len(mc.ls(sh+'.vtx[*]',fl=True)) elif nt=='nurbsCurve': if not mc.objExists(ci): ci=mc.createNode('curveInfo') mc.connectAttr(sha,ci+'.ic',f=True) ku=[] kuq=removeDuplicates(mc.getAttr(ci+'.knots')[0]) for u in kuq: if u>=0: ku.append(float(u)) else: kuq.pop() k={'u':tuple(ku)} self.knots.append(k) density=len(k['u']) elif nt=='nurbsSurface': if not mc.objExists(si): si=mc.createNode('surfaceInfo') mc.connectAttr(sha,si+'.is',f=True) ku=[] kuq=removeDuplicates(mc.getAttr(ci+'.knotsU')[0]) for u in kuq: if u>=0: ku.append(float(u)) else: kuq.pop() kv=[] kvq=removeDuplicates(mc.getAttr(ci+'.knotsV')[0]) for v in kvq: if v>=0: kv.append(float(v)) else: kvq.pop() k={'u':tuple(ku),'v':tuple(kv)} self.knots.append(k) density=len(k['u'])*len(k['v']) self.uv.append([-1.0,-1.0]) self.roughAPIDs.append([-1.0,-1.0]) self.roughCPIDs.append([-1.0,-1.0]) if density>maxDensity: maxDensity=density cpID=i else: searchID=i i+=1 if self.types[searchID]=='mesh' and self.types[cpID]!='mesh': temp=cpID cpID=searchID searchID=temp if mc.objExists(ci): mc.delete(ci) if mc.objExists(si): mc.delete(si) self.lookup(cpID)
def uniqueNames(*args,**keywords): """ With no keywords, returns a unique version of the given name(s). With re=True or raiseException=True : Ensures unique names are used in the scene and raises an error if there are duplicates present. With rn=True or rename=True : renames any object which have duplicate names. """ rename=False raiseException=False validate=False shortNames=\ { 'rn':'rename', 'v':'validate', 're':'raiseException' } for k in keywords: if k in locals(): exec(k+'=keywords[k]') elif k in shortNames: exec(shortNames[k]+'=keywords[k]') if len(args)==0: args=mc.ls(sl=True) if len(args)==0: args=mc.ls() sel=[] for a in args: sel.extend(iterable(a)) shapes=[] for s in sel: if mc.objExists(s) and shape(s)==s: shapes.append(s) sel=removeAll(shapes,sel)+shapes if validate: rename=False raiseException=False if rename: raiseException=False validate=False if raiseException: rename=False validate=False max=0 if rename or validate or raiseException: max=1 names=[] nonUnique=[] newNames={} baseNameRE=re.compile('(^[^0-9].*[^0-9])') for s in sel: sn=iterable(s.split('|'))[-1] ln=hierarchyOrder(removeDuplicates(mc.ls(sn,l=True)),r=True) if len(ln)>max: try: baseName=baseNameRE.match(sn).group(0) except: baseName=sn i=1 rn=s un=[] while mc.objExists(rn) or len(un)<len(ln): rn=baseName+str(i) if not mc.objExists(rn): un.append(rn) i+=1 names.append(un[0]) for i in range(0,len(ln)): if validate or rename: newNames[ln[i]]=un[i] if rename: mc.rename(ln[i],un[i]) else: nonUnique.append(ln[i]) else: names.append(s) if raiseException: if len(nonUnique)>0: print('##Non-unique names:##\n'+str(nonUnique)) raise Exception('Non-unique names found.') return nonUnique elif validate or rename: return newNames else: if len(sel)==1 and len(names)==1: return names[0] else: return names