def rebuildFromIsoparms(surface,spansU=0,spansV=0,degree=3,keepHistory=False): ''' Build a new nurbs surface from an existing surfaces isoparms @param surface: Surface to build from @type surface: str @param direction: Surface direction to build from @type direction: str @param degree: Degree to build new surface to @type degree: int @param keepHistory: Keep loft surface history @type keepHistory: bool ''' # Check surface if not mc.objExists(surface): raise Exception('Surface "'+surface+'" does not exist!!') if not isSurface(surface): raise Exception('Object "'+surface+'" is not a valid nurbs surface!!') # Initialize function pointers uMinPtr = OpenMaya.MScriptUtil().asDoublePtr() uMaxPtr = OpenMaya.MScriptUtil().asDoublePtr() vMinPtr = OpenMaya.MScriptUtil().asDoublePtr() vMaxPtr = OpenMaya.MScriptUtil().asDoublePtr() # Get surface details surfFn = getSurfaceFn(surface) surfFn.getKnotDomain(uMinPtr,uMaxPtr,vMinPtr,vMaxPtr) uMin = OpenMaya.MScriptUtil(uMinPtr).asDouble() uMax = OpenMaya.MScriptUtil(uMaxPtr).asDouble() vMin = OpenMaya.MScriptUtil(vMinPtr).asDouble() vMax = OpenMaya.MScriptUtil(vMaxPtr).asDouble() uDif = uMax - uMin vDif = vMax - vMin # Get surface form closeU = bool(mc.getAttr(surface+'.formU')) closeV = bool(mc.getAttr(surface+'.formV')) # Check spans if not spansU: spansU = surfFn.numKnotsInU() if not spansV: spansV = surfFn.numKnotsInV() # Get new knot values uList = [] vList = [] uInc = uDif/(spansU-int(not closeU)) vInc = vDif/(spansV-int(not closeV)) for u in range(spansU): uList.append(uMin+(uInc*u)) for v in range(spansV): vList.append(vMin+(vInc*v)) # Rebuild in U uLoft = mc.loft([surface+'.u['+str(i)+']' for i in uList],close=closeU,degree=degree) uSurface = uLoft[0] # Rebuld in V vLoft = mc.loft([uSurface+'.v['+str(i)+']' for i in vList],close=closeV,degree=degree) rebuildSurface = vLoft[0] # Return result return rebuildSurface
def axisPanelCreate(self , planeName , cur , axis): CurveEps = mc.ls(cur + '.ep[:]',fl = True) CurveCvs = mc.ls(cur + '.cv[:]',fl = True) cvworlds = [] if axis == 'auto': for i in range(len(CurveCvs)): cv = CurveCvs[i] cvworld = mc.xform(cv,q = True,ws = True,t = True) cvworlds.append(cvworld) axisFacet = mc.polyCreateFacet(p = cvworlds,ch = False,name = planeName + '_axis_Facet')[0] else: curOffsetGrp = mc.group(em = True,name = planeName + '_axisPanelOffset') curOffsetZero = mc.group(curOffsetGrp,name = curOffsetGrp + '_zero') axisCurve01 = mc.duplicate(cur)[0] axisCurve02 = mc.duplicate(cur)[0] mc.parent(axisCurve01,curOffsetGrp) mc.setAttr(curOffsetGrp + '.t' + axis,1) mc.parent(axisCurve01,w = True) mc.parent(axisCurve02,curOffsetGrp) mc.setAttr(curOffsetGrp + '.t' + axis,0) mc.parent(axisCurve02,w = True) axisFacet = mc.loft(axisCurve01,axisCurve02,ch = 1,u = 1,c = 0,ar = 1,d = 3,ss = 1,rn = 0,po = 1,rsn = True,name = planeName + '_axis_Facet')[0] mc.select(axisFacet) mc.DeleteHistory() mc.setAttr(curOffsetGrp + '.t' + axis,1) mc.delete(curOffsetZero,axisCurve01,axisCurve02) return axisFacet
def buildNurbsRibbon(self): if self.guideSpline: guideDeg = cmds.getAttr(self.guideSpline + '.degree' ) guideSpan = cmds.getAttr(self.guideSpline + '.spans' ) oneCurvePoints = [] otherCurvePoints = [] for i in xrange(guideDeg + guideSpan): cvPos = cmds.pointPosition(self.guideSpline + '.cv[' + str(i) + "]", w=True ) newPara = cmds.closestPointOnCurve(self.guideSpline, ip=cvPos, paramU=True) #Find the parameter Value newParaVal = cmds.getAttr(newPara + ".paramU") cmds.delete(newPara) infoNode = cmds.pointOnCurve(self.guideSpline, ch=True, pr=newParaVal) #Now find the Position and tangent! posy = (cmds.getAttr(infoNode + ".position"))[0] # returns the position posy = MVector(posy[0],posy[1],posy[2]) normy = (cmds.getAttr(infoNode + ".tangent"))[0] normy = MVector(normy[0],normy[1],normy[2]) #Use MVector from maya.openMaya normy = normy.normal() vertVect = MVector(0,1,0) sideMove = normy^vertVect #This is the notation for a cross product. Pretty cool. Should be a normal movement sideMove = sideMove.normal() * 0.5 sideMovePos = posy + sideMove otherSideMovePos = posy - sideMove oneCurvePoints.append([sideMovePos[0],sideMovePos[1],sideMovePos[2]]) otherCurvePoints.append([otherSideMovePos[0],otherSideMovePos[1],otherSideMovePos[2]]) oneSideCurve = cmds.curve(editPoint = oneCurvePoints, degree=3) OtherSideCurve = cmds.curve(editPoint = otherCurvePoints, degree=3) self.tempConstructionParts.append(oneSideCurve) self.tempConstructionParts.append(OtherSideCurve) #Now we loft the surface between the two Curves! nameStart = nameBase(self.totalMarkerList[0].getName(), self.searchString, "loc", "nbs") nameStart += "ribbonSurface" self.guideNurbsRibbon = cmds.loft(oneSideCurve, OtherSideCurve, name = nameStart, constructionHistory = True, uniform = True, close = False, autoReverse = True, degree = 3, sectionSpans = 1, range = False, polygon = 0, reverseSurfaceNormals = True) self.guideNurbsRibbon = self.guideNurbsRibbon[0] self.ribbonParts.append(self.guideNurbsRibbon)
def makePipe(circle, pipeCurve): pipeSweep = sweepPipe(circle, pipeCurve) nurbsPipe = cmds.loft(pipeSweep, degree=1, reverseSurfaceNormals=True) polyPipe = cmds.nurbsToPoly(nurbsPipe[0], name="fastPipe", format=3, matchNormalDir=True, polygonType=1) cmds.polyMergeVertex(polyPipe[0], d=0.1, alwaysMergeTwoVertices=True) cmds.delete(pipeSweep[0], nurbsPipe[0], circle[0], pipeCurve[0]) cmds.select(polyPipe)
def surfaceFromNodes(nodes, name='jntsSrf', upAxis=0, doubleEndPoints=False): """ Create a 2-degree nurbs surface from the position of a list of node (generally, the IK controls) @param nodes: controls that will dictate the CV positions @type nodes: list of strings @param name: the name of the surface @type name: str @param upAxis: the direction of the width of the surface @type upAxis: int representing x(0), y(1) or z(2) """ inPos = [0,0,0] outPos = [0,0,0] inPos[upAxis] = -1 outPos[upAxis] = 1 crv1 = curveFromNodes(nodes, doubleEndPoints=doubleEndPoints) crv2 = curveFromNodes(nodes, doubleEndPoints=doubleEndPoints) MC.xform(crv1, t=outPos) MC.xform(crv2, t=inPos) srf = MC.loft(crv1, crv2, u=1, c=0, ch=0, ar=1, d=1, ss=1, rn=0, po=0, rsn=True)[0] srf = MC.rename(srf, name) MC.delete(crv1, crv2) return srf
def draw(self): circle1 = cmds.circle( nr=(1, 0, 0), c=(0, 0, 0), sw=self.sweep, r=self.start_radius ) circle2 = cmds.circle( nr=(1, 0, 0), c=(0, 0, 0), sw=self.sweep, r=self.end_radius ) l1 = cmds.loft(circle1, circle2) # curves crv = cmds.curve(p=[(0, self.start_radius, 0), (0, self.end_radius, 0)], degree=1) crv2 = cmds.duplicate(crv) cmds.rotate(str(self.sweep) + 'deg', 0, 0, r=True) extrusions = [] for e in [circle1, circle2, crv, crv2]: extrusions.append(cmds.extrude(e, et=0, d=(1,0,0), l=self.height)) cmds.delete(e) pieces = extrusions + [l1] group = cmds.group(*[e[0] for e in pieces]) cmds.move(0,0,0, group+".scalePivot",group+".rotatePivot", absolute=True) cmds.setKeyframe(group, attribute='rotateX', t='0sec', value=self.rotation) return (pieces, group)
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 loftFacePart(self, facePart): """ making poligon map """ crvSel = cmds.ls(os=1, fl=1, type = 'transform') loft_suf = cmds.loft(crvSel, n = facePart + 'Tip_map', ch =1, u=1, c=0, ar= 1, d=1, ss= 1, rn= 0, po= 1, rsn = 1) suf_inputs = cmds.listHistory( loft_suf[0]) tessel = [x for x in suf_inputs if cmds.nodeType(x) == 'nurbsTessellate'] cmds.setAttr(tessel[0]+".format", 3) cmds.delete(loft_suf[0], ch =1) wide_suf = cmds.duplicate(loft_suf[0], n = facePart + 'Wide_map')
def _createNurbs(self): """Create the nurbs curves that will act as our bendy/twist curves.""" for crv in [["hip", "knee"], ["knee", "foot"]]: limb_points = self._getCurvePositions(crv[0], crv[1]) limb_crv = mc.curve(n=self.guides[crv[0]][0].replace("guide", "crv"), p=limb_points, d=3) limb_crv_offset = mc.offsetCurve(limb_crv, d=.3, ugn=0) limb_crv_inv = mc.offsetCurve(limb_crv, d=-.3, ugn=0) limb_loft = mc.loft(limb_crv_inv, limb_crv_offset, n=self.guides[crv[0]][0].replace("guide", "nrb"), ch=0) mc.delete(limb_crv, limb_crv_offset, limb_crv_inv) self.nurbs[crv[0]] = limb_loft[0] mc.parent(limb_loft, self.mod_dict["noTransform"])
def rebuildFromExistingIsoparms(surface, direction='u', degree=3, close=False, keepHistory=False): """ Build a new nurbs surface from an existing surfaces isoparms @param surface: Surface to build from @type surface: str @param direction: Surface direction to build from @type direction: str @param degree: Degree to build new surface to @type degree: int @param close: Close lofted surface @type close: bool @param keepHistory: Keep loft surface history @type keepHistory: bool """ # Check surface if not cmds.objExists(surface): raise Exception('Surface "' + surface + '" does not exist!!') if not isSurface(surface): raise Exception('Object "' + surface + '" is not a valid nurbs surface!!') # Check direction direction = direction.lower() if not direction == 'u' and not direction == 'v': raise Exception('Invalid surface direction! Accepted values are "u" and "v"!') # Get surface details surfFn = getSurfaceFn(surface) spans = cmds.getAttr(surface + '.spans' + direction.upper()) degree = cmds.getAttr(surface + '.degree' + direction.upper()) form = cmds.getAttr(surface + '.form' + direction.upper()) knots = OpenMaya.MDoubleArray() if direction == 'u': surfFn.getKnotsInU(knots) if direction == 'v': surfFn.getKnotsInV(knots) # Build iso list for surface rebuild if degree > 1: knots = knots[(degree - 1):-(degree - 1)] isoList = [surface + '.' + direction + '[' + str(i) + ']' for i in knots] if not close and form: # isoList.append(isoList[0]) isoList[-1] = isoList[-1] - 0.0001 # Loft new rebuild surface rebuild = cmds.loft(isoList, ch=keepHistory, u=True, c=close, ar=False, d=degree, ss=1, rn=False, po=False, rsn=(direction == 'v')) rebuild = cmds.rename(rebuild[0], surface + '_rebuild') # Return result return rebuild
def create_plane(self , planeName , CvNumOfSpans , cur): selCurve = mc.rebuildCurve(cur,ch=1,rpo=0,rt=0,end=1,kr=0,kcp=0,kep=0,kt=0,s=CvNumOfSpans,d=3,tol=0.01)[0] mc.select(selCurve) mc.DeleteHistory() CurveEps = mc.ls(selCurve + '.ep[:]',fl = True) worlds = [] txs = [] tys = [] tzs = [] jnts = [] for ep in CurveEps: world = mc.xform(ep,q = True,ws = True,t = True) mc.select(cl = True) jnt = mc.joint(p = world) worlds.append(world) tx = ('%.3f'%world[0]) ty = ('%.3f'%world[0]) tz = ('%.3f'% world[0]) jnts.append(jnt) #print txs,tys,tzs mc.select(cl = True) axisLocateJnt = mc.joint(name = planeName + 'axisLocateJnt') #mc.group() mc.delete(mc.parentConstraint(jnts,axisLocateJnt,mo = False)) Facet = mc.polyCreateFacet(p = worlds,ch = False)[0] FacetShape = mc.listRelatives(Facet,s = True)[0] UV = self.closestPointOnModel(FacetShape,axisLocateJnt) U = UV[0] V = UV[1] follic = self.follicCreate(FacetShape,planeName,U,V) offsetGrp = mc.group(em = True,name = planeName + '_cv_offset') offsetZero = mc.group(offsetGrp,name = offsetGrp + '_zero') mc.delete(mc.parentConstraint(follic,offsetZero,mo = False)) Curve01 = mc.duplicate(selCurve)[0] Curve02 = mc.duplicate(selCurve)[0] mc.parent(Curve01,offsetGrp) mc.setAttr(offsetGrp + '.tz',1) mc.parent(Curve01,w = True) mc.parent(Curve02,offsetGrp) mc.setAttr(offsetGrp + '.tz',0) mc.parent(Curve02,w = True) mc.delete(jnts,axisLocateJnt,Facet,follic,offsetZero) Plane = mc.loft(Curve01,Curve02,ch = True,u = True,c = False,ar = True,d = 3,ss = True,rn = False,po = False,rsn = True,name = planeName) mc.select(Plane) mc.DeleteHistory() mc.delete(selCurve,Curve01,Curve02) return Plane
def create_loft(jts,name='loftedSurface'): """ Create skins a surface along a series of profile curves. """ pts=[cmds.xform(j,q=True,ws=True,t=True) for j in jts] cuR = cmds.curve( p=pts) cmds.move(0,0,.5,cuR,ls=True) cuL = cmds.duplicate(cuR) cmds.move(0,0,-.5,cuL,ls=True) Nurbs=cmds.loft( cuR, cuL, ch=False, rn=True, n='%s#' %name)[0] cmds.setAttr('%s.template' %Nurbs, 1) sc_cl=cmds.skinCluster(jts[0],Nurbs,mi=1,sm=1)[0] #delete bindpose bind=cmds.listConnections('%s.bindPose' %sc_cl,c=0,d=1,p=0) if bind:cmds.delete(bind) cmds.delete(cuR,cuL) return Nurbs
def tubeFromCurve(curve,spans=6,radius=1,upVector=(0,1,0),prefix=''): ''' Project a tubular surface from the specified path curve to the target geometry. @param curve: Path curve used to build the tube surface @type curve: str @param spans: Number of radial spans around the surface @type spans: int @param radius: Circular radius of the tube surface @type radius: float @param upVector: Up vector used to calculate the radial orientation of the tube surface @type upVector: tuple @param prefix: Name prefix for all created nodes @type prefix: str ''' # Check curve if not isCurve(curve): raise Exception('Object "'+curve+'" is not a valid nurbs curve!!') # Check prefix if not prefix: prefix = glTools.utils.stringUtils.stripSuffix(curve) # Get curve info crvMin = mc.getAttr(curve+'.minValue') crvMax = mc.getAttr(curve+'.maxValue') crvSpan = mc.getAttr(curve+'.spans') crvInc = (crvMax - crvMin) / (crvSpan + 1) # Increment over curve edit points crvList = [] crvGrpList = [] for i in range(crvSpan + 2): strInd = glTools.utils.stringUtils.stringIndex(i+1,2) crvPrefix = prefix+'crv'+strInd crvCirc = mc.circle(r=radius,s=spans,degree=3,n=crvPrefix+'_curve') crvGrp = mc.group(crvCirc[0],n=crvPrefix+'_group') snapToCurve(curve,crvGrp,(crvInc*i),False,False) orientToCurve(curve,crvGrp,(crvInc*i),False,upVector,'z','y') crvList.append(crvCirc[0]) crvGrpList.append(crvGrp) # Loft surface between curves surface = mc.loft(crvList,ch=1,u=1,c=0,ar=1,d=3,ss=1,rn=0,po=0,rsn=True,n=prefix+'_surface')[0] # Return result return[surface,crvList,crvGrpList]
def doCreate(*args): sl = api2.MGlobal.getActiveSelectionList() if sl.length() == 0L: return dag,obj = sl.getComponent(0) sic = api2.MFnSingleIndexedComponent(obj) ids = sic.getElements() faceIter = api2.MItMeshPolygon(dag) srfs = [] fullPath = dag.fullPathName() for i in xrange(len(ids)): faceIter.setIndex(ids[i]) intArray = faceIter.getEdges() patch = cmds.loft('%s.e[%d]' %(fullPath,intArray[2]),'%s.e[%d]' %(fullPath,intArray[0]),d=1,ch=False) cmds.rebuildSurface(patch,ch=False,rpo=1,rt=0,end=1,kr=0,kcp=1,kc=0,su=0,du=1,sv=0,dv=1,fr=0,dir=2) srfs.append(patch[0]) cmds.select(srfs) return 0
def buildRibbonSurface(locators,name = '',close = False,vector = [1,0,0],width = 10): lineCrvs = [] for locator in locators: pos = cmds.xform(locator,q = True,ws = True,rp = True) posVector = om.MVector(pos[0],pos[1],pos[2]) inverseWidth = width * -1 translateVectorForward = om.MVector(vector[0] * width,vector[1] * width,vector[2] * width) translateVectorBackward = om.MVector((vector[0] * inverseWidth),(vector[1] * inverseWidth),(vector[2] * inverseWidth)) startTransformationMatrix = om.MTransformationMatrix() startTransformationMatrix.setTranslation(posVector,om.MSpace.kWorld) startTransformationMatrix.addTranslation(translateVectorForward,om.MSpace.kObject) startPosVector = startTransformationMatrix.getTranslation(om.MSpace.kWorld) endTransformationMatrix = om.MTransformationMatrix() endTransformationMatrix.setTranslation(posVector,om.MSpace.kWorld) endTransformationMatrix.addTranslation(translateVectorBackward,om.MSpace.kObject) endPosVector = endTransformationMatrix.getTranslation(om.MSpace.kWorld) startPos = [startPosVector.x,startPosVector.y,startPosVector.z] endPos = [endPosVector.x,endPosVector.y,endPosVector.z] lineCrv = cmds.curve(d = 1,p = (startPos,endPos)) lineCrvs.append(lineCrv) ribbonOrig = cmds.loft(lineCrvs,ch = 1,u = 1,c = close,ar = 1,d = 3,ss = 1,rn = 0 ,po = 0, rsn = True,n = '%s_Surface'%name) ribbonRebuild = cmds.rebuildSurface(ribbonOrig[0],ch = 1,rpo = 1,rt = 0,end = 1,kr = 0,kcp = 1,kc = 0,su = 8,du = 1,sv = 2,dv = 3,tol = 0.01,fr = 0, dir = 2) ribbon = [] shape = cmds.listRelatives(ribbonRebuild[0], type = 'shape')[0] ribbon.append(ribbonRebuild[0]) ribbon.append(shape) cmds.delete(ribbonOrig[0],ch = True) cmds.delete(lineCrvs) return ribbon
def j_MakeSecondContrl(): j_sndcontrls = []; j_surface = [] j_edges = mc.ls(os=1,fl=1); #loft -ch 1 -u 1 -c 0 -ar 1 -d 3 -ss 1 -rn 0 -po 0 -rsn true "MOBBodyAA.e[6450]" "MOBBodyAA.e[7030]"; for i in (range(1,len(j_edges),2)): j_sndcontrls = mc.loft(j_edges[i-1],j_edges[i],ch=1,rn =0,ar =1,) j_surface.append(j_sndcontrls[0]) mc.select(cl=1) j_grp = 'grp_loftSurface01'; if not mc.objExists(j_grp): mc.group(n= "grp_loftSurface01",empty =1) mc.parent(j_surface,j_grp,); for j in j_surface: j_pnd = pm.pointOnSurface(j,ch=1,u=0.5, v = 0.1, top =1,) j_position = pm.getAttr(j_pnd + ".position") j_loc = mc.spaceLocator( p = (j_position[0], j_position[1] , j_position[2])) j_circle = pm.circle(ch = 0) j_pnt = pm.group(em = 1 , ) pm.parentConstraint() return j_surface;
def __init__(self): xPos= 10 #joints loftCircles = self.limbCircles limbJoints = self.limbJoints loftBone = self.limbLoftBones for i in range(0,2,1): limbJnt = cmds.sphere(n='joint_'+str(i)) limbJoints.append(limbJnt[0]) cmds.move(i*xPos,0,0,limbJnt) circleJnt = cmds.circle(n='circlelJnt_' + str(i),radius=0.4) cmds.move(i*xPos,0,0,circleJnt) cmds.rotate(0,-90,0,circleJnt) loftCircles.append(circleJnt[0]) cmds.parent(circleJnt[0],limbJnt[0]) loftBone = cmds.loft(loftCircles[0],loftCircles[1],n='loftBone') cmds.setAttr(loftBone[0] + '.inheritsTransform',0) cmds.aimConstraint(limbJoints[1],loftCircles[0],mo=True) cmds.aimConstraint(limbJoints[0],loftCircles[1],mo=True) cmds.group(limbJoints[0],limbJoints[1],loftBone[0],n='limb')
def projectToSurface(surface,targetSurface,direction='u',keepOriginal=False,prefix=''): ''' Project the edit points of the specified nurbs surface to another nurbs or polygon object @param surface: Surface to project @type surface: str @param targetSurface: Surface to project onto @type targetSurface: str @param direction: Surface direction to extract isoparm curves from @type direction: str @param keepOriginal: Create new surface or replace original @type keepOriginal: bool @param prefix: Name prefix for all created nodes @type prefix: str ''' # Check surface if not mc.objExists(surface): raise UserInputError('Surface "'+surface+'" does not exist!!') if not isSurface(surface): raise UserInputError('Object "'+surface+'" is not a valid nurbs surface!!') # Check target surface if not mc.objExists(targetSurface): raise UserInputError('Target surface "'+targetSurface+'" does not exist!!') # Check prefix if not prefix: prefix = glTools.utils.stringUtils.stripSuffix(surface) # Check direction direction = direction.upper() if (direction != 'U') and (direction != 'V'): raise UserInputError('Invalid surface direction specified! Must specify either "u" or "v"!!') # Get surface information spans = mc.getAttr(surface+'.spans'+direction) minVal = mc.getAttr(surface+'.minValue'+direction) maxVal = mc.getAttr(surface+'.maxValue'+direction) # Create main surface group mainGrp = mc.createNode('transform',n=prefix+'_grp') # Extract curves curveList = [] curveGrpList = [] curveLocList = [] geomConstraintList = [] spanInc = (maxVal - minVal)/spans for i in range(spans+1): # Curve prefix strInd = glTools.utils.stringUtils.stringIndex(i,2) crvPrefix = prefix+'_crv'+strInd # Create curve group curveGrp = crvPrefix+'_grp' curveGrp = mc.createNode('transform',n=curveGrp) curveGrp = mc.parent(curveGrp,mainGrp)[0] curveGrpList.append(curveGrp) # Get surface curve srfCurveName = crvPrefix+'_crv' srfCurve = mc.duplicateCurve(surface+'.'+direction.lower()+'['+str(i*spanInc)+']',ch=0,rn=0,local=0,n=srfCurveName) srfCurve = mc.parent(srfCurve[0],curveGrp)[0] curveList.append(srfCurve) # Generate curve locators curveLocatorList = glTools.utils.curve.locatorEpCurve(srfCurve,locatorScale=0.05,prefix=crvPrefix) curveLocatorList = mc.parent(curveLocatorList,curveGrp) curveLocList.append(curveLocatorList) # Create geometry constraints for loc in curveLocatorList: geomConstraint = crvPrefix+'_geometryConstraint' geomConstraint = mc.geometryConstraint(targetSurface,loc,n=geomConstraint) geomConstraintList.append(geomConstraint[0]) # Center group pivot mc.xform(curveGrp,cp=True) # Delete original surface surfaceName = prefix+'_surface' if not keepOriginal: surfaceName = surface mc.delete(surface) # Loft new surface surfaceLoft = mc.loft(curveList,ch=1,u=1,c=0,ar=1,d=3,ss=1,rn=0,po=0,rsn=True) surface = mc.rename(surfaceLoft[0],surface) surface = mc.parent(surface,mainGrp)[0] mc.reorder(surface,f=True) loft = mc.rename(surfaceLoft[1],prefix+'_loft') # Return result return[surface,loft,curveList,curveGrpList,curveLocList,geomConstraintList]
def rebuild_old(surface,spansU=0,spansV=0,fullRebuildU=False,fullRebuildV=False,replaceOrig=False): ''' Do brute force surface rebuild for even parameterization @param surface: Nurbs surface to rebuild @type surface: str @param spansU: Number of spans along U. If 0, keep original value. @type spansU: int @param spansV: Number of spans along V. If 0, keep original value. @type spansV: int @param replaceOrig: Replace original surface, or create new rebuilt surface. @type replaceOrig: bool ''' # Check surface if not isSurface(surface): raise Exception('Object "'+surface+'" is not a valid surface!') # Check spans if not spansU: spansU = mc.getAttr(surface+'.spansU') if not spansV: spansV = mc.getAttr(surface+'.spansV') # ------------- # - Rebuild V - # Get V range minu = mc.getAttr(surface+'.minValueU') maxu = mc.getAttr(surface+'.maxValueU') u = minu + (maxu - minu) * 0.5 # Extract isoparm curve iso_crv = mc.duplicateCurve(surface+'.u['+str(u)+']',ch=0,rn=0,local=0)[0] iso_len = mc.arclen(iso_crv) iso_inc = iso_len / spansV curveFn = glTools.utils.curve.getCurveFn(iso_crv) iso_list = [surface+'.v['+str(curveFn.findParamFromLength(iso_inc*i))+']' for i in range(spansV+1)] mc.delete(iso_crv) # Check full rebuild if fullRebuildU: # Extract isoparm curves iso_crv_list = [mc.duplicateCurve(iso,ch=False,rn=False,local=False)[0] for iso in iso_list] # Rebuild isoparm curves for iso_crv in iso_crv_list: mc.rebuildCurve(iso_crv,ch=False,rpo=True,rt=0,end=1,kr=0,kcp=0,kep=1,kt=1,s=0,d=3,tol=0) # Loft final surface int_surface = mc.loft(iso_crv_list,ch=0,u=1,c=0,ar=1,d=3,ss=1,rn=0,po=0,rsn=True)[0] # Delete intermediate curves mc.delete(iso_crv_list) else: # Loft intermediate surface int_surface = mc.loft(iso_list,ch=0,u=1,c=0,ar=1,d=3,ss=1,rn=0,po=0,rsn=True)[0] # ------------- # - Rebuild U - # Get V range (intermediate surface) minv = mc.getAttr(int_surface+'.minValueV') maxv = mc.getAttr(int_surface+'.maxValueV') v = minv + (maxv - minv) * 0.5 # Extract isoparm curve (intermediate surface) iso_crv = mc.duplicateCurve(int_surface+'.v['+str(v)+']',ch=0,rn=0,local=0)[0] iso_len = mc.arclen(iso_crv) iso_inc = iso_len / spansU curveFn = glTools.utils.curve.getCurveFn(iso_crv) iso_list = [int_surface+'.u['+str(curveFn.findParamFromLength(iso_inc*i))+']' for i in range(spansU+1)] mc.delete(iso_crv) # Check full rebuild if fullRebuildV: # Extract isoparm curves iso_crv_list = [mc.duplicateCurve(iso,ch=False,rn=False,local=False)[0] for iso in iso_list] # Rebuild isoparm curves for iso_crv in iso_crv_list: mc.rebuildCurve(iso_crv,ch=False,rpo=True,rt=0,end=1,kr=0,kcp=0,kep=1,kt=1,s=0,d=3,tol=0) # Loft final surface rebuild_surface = mc.loft(iso_crv_list,ch=0,u=1,c=0,ar=1,d=3,ss=1,rn=0,po=0,rsn=True)[0] # Delete intermediate curves mc.delete(iso_crv_list) else: # Loft final surface rebuild_surface = mc.loft(iso_list,ch=0,u=1,c=0,ar=1,d=3,ss=1,rn=0,po=0,rsn=True)[0] rebuild_surface = mc.rename(rebuild_surface,surface+'_rebuild') rebuild_surfaceShape = mc.listRelatives(surface,s=True,ni=True)[0] mc.delete(int_surface) # Initialize return value outputShape = rebuild_surfaceShape # -------------------- # - Replace Original - if replaceOrig: """ # Get original shape shapes = glTools.utils.shape.getShapes(surface,nonIntermediates=True,intermediates=False) if not shapes: # Find Intermediate Shapes shapes = glTools.utils.shape.listIntermediates(surface) # Check shapes if not shapes: raise Exception('Unable to determine shape for surface "'+surface+'"!') # Check connections if mc.listConnections(shapes[0]+'.create',s=True,d=False): # Find Intermediate Shapes shapes = glTools.utils.shape.findInputShape(shapes[0]) """ # Check history shapes = mc.listRelatives(surface,s=True,ni=True) if not shapes: raise Exception('Unable to determine shape for surface "'+surface+'"!') shape = shapes[0] shapeHist = mc.listHistory(shape) if shapeHist.count(shape): shapeHist.remove(shape) if shapeHist: print('Surface "" contains construction history, creating new shape!') # Override shape info and delete intermediate mc.connectAttr(rebuild_surfaceShape+'.local',shape+'.create',f=True) outputShape = shape # Return result return outputShape
def buildSplash(self): objectName = str(self.getObject.text()) if self.checkWake.isChecked()==True: wakeEmitter = str(self.getWake.text()) else: wakeEmitter = "OceanWakeEmitter1" if self.checkOcean.isChecked()==True: oceanShader = str(self.getOcean.text()) else: oceanShader = "oceanShader1" ###Bcreating Splash Disc objectNameAxis = generator.getMaxAndMinAxis(objectName) #generator_Return: 0-maxX, 1-minX, 2-maxY, 3-minY, 4-maxZ, 5-minZ avrgX = objectNameAxis[0] - objectNameAxis[1] avrgZ = objectNameAxis[4] - objectNameAxis[5] avrgY = objectNameAxis[2] - objectNameAxis[3] if avrgX > avrgZ: SplashCurve = avrgX else: SplashCurve = avrgZ baseCurve = cmds.circle(name="base",normal=[0,1,0],radius=SplashCurve/1.5) headCurve = cmds.circle(name="head",normal=[0,1,0],radius=SplashCurve/2) cmds.move(0,(avrgY/4),0,headCurve) cmds.rebuildCurve ("base", ch=1, rpo=1, rt=0, end=1, kr=0, kcp=0, kep=0, kt=0, s=100, d=7, tol=0.01) cmds.rebuildCurve ("head", ch=1, rpo=1, rt=0, end=1, kr=0, kcp=0, kep=0, kt=0, s=100, d=7, tol=0.01) splashDisc = cmds.loft ("base", "head",name="%s_SplashDisc"%objectName, ch=1, u=1, c=0, ar=1, d=3, ss=int(avrgY+1), rn=0, po=0, rsn=True) #Return: 0-SplashDisc, 1-loft1 cmds.delete(baseCurve,headCurve) cmds.setAttr("%s.visibility"%splashDisc[0], False ) objectPosition = cmds.xform(objectName, query=True, translation=True, worldSpace=True ) cmds.move(objectPosition[0], 0, objectPosition[2], splashDisc[0]) ###adding emitter and particle to Object objectNameEmitter = cmds.emitter(objectName,type='surface',rate=0,scaleRateByObjectSize=False,needParentUV=False,cycleEmission="none", cycleInterval=1,speed=1,speedRandom=0,normalSpeed=1,tangentSpeed=0,maxDistance=0,minDistance=0, directionX=1,directionY=0,directionZ=0,spread=0,name="%s_emitter"%objectName) #Return: 0-objectName, 1-objectName_emitter objectNameParticle = cmds.particle(name="%s_particle"%objectName) cmds.connectDynamic(objectNameParticle[0],emitters=objectNameEmitter[0]) ###adding emitter and particle to Splash Disc splashDiscEmitter = cmds.emitter(splashDisc[0],type='surface',rate=0,scaleRateByObjectSize=False,needParentUV=False,cycleEmission="none", cycleInterval=1,speed=1,speedRandom=1.5,normalSpeed=1,tangentSpeed=0,maxDistance=0,minDistance=0, directionX=1,directionY=0,directionZ=0,spread=0,name="%s_emitter"%splashDisc[0]) #Return: 0-SplashDisc, 1-SplashDisc_emitter splashDiscParticle = cmds.particle(name="%s_particle"%splashDisc[0]) cmds.connectDynamic(splashDiscParticle[0],emitters=splashDiscEmitter[0]) #connecting the X and Z object position to Splash Disc to follow cmds.connectAttr("%s.translate.translateZ"%objectName, "%s.translate.translateZ"%splashDisc[0]) cmds.connectAttr("%s.translate.translateX"%objectName, "%s.translate.translateX"%splashDisc[0]) #setting up the splash Disc particle Setting cmds.setAttr("%s.lifespanMode"%splashDiscParticle[1],3) cmds.setAttr("%s.lifespanRandom"%splashDiscParticle[1],0.5) cmds.setAttr("%s.conserve"%splashDiscParticle[1],0.983) cmds.setAttr("%s.inheritFactor"%splashDiscParticle[1],0.2) cmds.setAttr("%s.particleRenderType"%splashDiscParticle[1],5) cmds.addAttr(splashDiscParticle[1], keyable=True, ln="useLighting", at="bool", dv=False) cmds.addAttr(splashDiscParticle[1], ln="spriteScaleYPP", dt="doubleArray") cmds.addAttr(splashDiscParticle[1], ln="spriteScaleYPP0", dt="doubleArray") cmds.addAttr(splashDiscParticle[1], ln="spriteScaleXPP", dt="doubleArray") cmds.addAttr(splashDiscParticle[1], ln="spriteScaleXPP0", dt="doubleArray") cmds.addAttr(splashDiscParticle[1], ln="spriteTwistPP", dt="doubleArray") cmds.addAttr(splashDiscParticle[1], ln="spriteTwistPP0", dt="doubleArray") #creating Ramp for Splash Disc particle splashDiscParticle_spriteScaleXPP = cmds.arrayMapper(target=splashDiscParticle[1], destAttr="spriteScaleXPP", inputV="ageNormalized", type="ramp") ramp_spriteScaleXPP = cmds.listConnections(splashDiscParticle_spriteScaleXPP, type="ramp") ramp_spriteScaleXPP = cmds.rename(ramp_spriteScaleXPP[1], "%s_spriteScaleXPP_Rampe"%splashDiscParticle[1]) cmds.setAttr("%s.colorEntryList[2].color"%ramp_spriteScaleXPP, 0,0,0) cmds.setAttr("%s.colorEntryList[2].position"%ramp_spriteScaleXPP, 1) cmds.setAttr("%s.colorEntryList[1].color"%ramp_spriteScaleXPP, 0.5,0.5,0.5) cmds.setAttr("%s.colorEntryList[1].position"%ramp_spriteScaleXPP, 0.165) cmds.setAttr("%s.colorEntryList[0].color"%ramp_spriteScaleXPP, 1,1,1) cmds.setAttr("%s.colorEntryList[0].position"%ramp_spriteScaleXPP, 0) splashDiscParticle_spriteScaleYPP = cmds.arrayMapper(target=splashDiscParticle[1], destAttr="spriteScaleYPP", inputV="ageNormalized", type="ramp") ramp_spriteScaleYPP = cmds.listConnections(splashDiscParticle_spriteScaleYPP, type="ramp") ramp_spriteScaleYPP = cmds.rename(ramp_spriteScaleYPP[1], "%s_SpriteScaleYPP_Rampe"%splashDiscParticle[1]) cmds.setAttr("%s.colorEntryList[2].color"%ramp_spriteScaleYPP, 0,0,0) cmds.setAttr("%s.colorEntryList[2].position"%ramp_spriteScaleYPP, 1) cmds.setAttr("%s.colorEntryList[1].color"%ramp_spriteScaleYPP, 0.5,0.5,0.5) cmds.setAttr("%s.colorEntryList[1].position"%ramp_spriteScaleYPP, 0.165) cmds.setAttr("%s.colorEntryList[0].color"%ramp_spriteScaleYPP, 1,1,1) cmds.setAttr("%s.colorEntryList[0].position"%ramp_spriteScaleYPP, 0) #setting up the object particle Setting cmds.setAttr("%s.lifespanMode"%objectNameParticle[1],3) cmds.setAttr("%s.particleRenderType"%objectNameParticle[1],7) cmds.addAttr(objectNameParticle[1], keyable=True, ln="threshold", at="float", min=0, max=10, dv=0.7) cmds.addAttr(objectNameParticle[1], keyable=True, ln="radius", at="float", min=0, max=10, dv=0.5) cmds.addAttr (objectNameParticle[1], ln="radiusPP", dt="doubleArray") #creating Ramp for object particle objectNameParticle_radiusPP = cmds.arrayMapper(target=objectNameParticle[1], destAttr="radiusPP", inputV="ageNormalized", type="ramp") ramp_radiusPP = cmds.listConnections(objectNameParticle_radiusPP, type="ramp") ramp_radiusPP = cmds.rename(ramp_radiusPP[1], "%s_RadiusPP_Rampe"%objectNameParticle[1]) cmds.setAttr("%s.colorEntryList[3].color"%ramp_radiusPP, 0.056,0.056,0.056) cmds.setAttr("%s.colorEntryList[3].position"%ramp_radiusPP, 1) cmds.setAttr("%s.colorEntryList[2].color"%ramp_radiusPP, 0.223,0.223,0.223) cmds.setAttr("%s.colorEntryList[2].position"%ramp_radiusPP, 0.690) cmds.setAttr("%s.colorEntryList[1].color"%ramp_radiusPP, 0.178,0.178,0.178) cmds.setAttr("%s.colorEntryList[1].position"%ramp_radiusPP, 0.455) cmds.setAttr("%s.colorEntryList[0].color"%ramp_radiusPP, 0,0,0) cmds.setAttr("%s.colorEntryList[0].position"%ramp_radiusPP, 0) #adding gravity to SplashDisc splashDiscGravity = cmds.gravity(name="%s_GravityField"%splashDiscParticle[0], pos=[0,0,0], m=9.8, att=0, dx=0, dy=-1, dz=0, mxd=-1, vsh="none", vex=0, vof=[0,0,0], vsw=360, tsr=0.5) cmds.connectDynamic(splashDiscParticle[0], fields=splashDiscGravity) #adding gravity to Object objectNameGravity = cmds.uniform(name="%s_UniformField"%objectNameParticle[0], pos=[0,0,0], m=5, att=1, dx=1, dy=-1, dz=0, mxd=-1, vsh="none", vex=0, vof=[0,0,0], vsw=360, tsr=0.5) cmds.connectDynamic(objectNameParticle[0], fields=objectNameGravity) print objectNameGravity cmds.setAttr("%s.directionX"%objectNameGravity[0],0) cmds.setAttr("%s.directionY"%objectNameGravity[0],1) cmds.setAttr("%s.directionZ"%objectNameGravity[0],0) cmds.setAttr("%s.magnitude"%objectNameGravity[0],28) #adding Expression for Object and SplashDisc generator.objectNameParticleExpressionBeforeDynamics(objectNameParticle[1], oceanShader) generator.splashDiscParticleExpressionBeforeDynamics(splashDiscParticle[1], oceanShader) generator.splashDiscParticleExpressionAfterDynamics(splashDiscParticle[1]) generator.splashDiscParticleExpressionCreation(splashDiscParticle[1]) if "ocean_MainExpression" not in cmds.ls() : generator.createMainExpression(objectNameEmitter[1]) if "ocean_MainExpression" in cmds.ls() : generator.editMainExpression(objectName, splashDiscEmitter[0], oceanShader, objectNameEmitter[1], wakeEmitter, splashDiscEmitter[1]) # num=0 if "mainSplashDisc_Shader" not in cmds.ls(): generator.shaderSetup() # cmds.select(splashDiscEmitter[0], replace=True) # cmds.sets(edit=True,forceElement="mainSplashDisc_ShaderSG") cmds.sets(splashDiscParticle, edit = True, forceElement = 'mainSplashDisc_ShaderSG') else: cmds.sets(splashDiscParticle, edit = True, forceElement = 'mainSplashDisc_ShaderSG') # while cmds.connectionInfo("mainSplashDisc_ShaderSG.dagSetMembers[%s]"%num,getExactDestination=True) != "": # num+=1 # cmds.connectAttr(splashDiscEmitter[1] + ".instObjGroups[0]", "mainSplashDisc_Shader.dagSetMembers[%s]"%num, force = True) # else: # while cmds.connectionInfo("mainSplashDisc_ShaderSG.dagSetMembers[%s]"%num,getExactDestination=True) != "": # num+=1 # cmds.connectAttr(splashDiscEmitter[1] + ".instObjGroups[0]", "mainSplashDisc_Shader.dagSetMembers[%s]"%num, force = True) # pSphere1_SplashDisc.translateX = pSphere1.translateX; # pSphere1_SplashDisc.translateZ = pSphere1.translateZ; return
def buildRibbonSpine(startJoint,endJoint,ribbonJoints,spans=0,ikSwitchCtrl='',ikSwitchAttr='spineIk',ctrlScale=1.0,prefix='cn_spine'): ''' ''' # ========== # - Checks - # ========== # Ribbon Joints for jnt in ribbonJoints: if not mc.objExists(jnt): raise Exception('Ribbon joint "'+jnt+'" does not exist!') # ==================== # - Build Spine Base - # ==================== # Get Joint List spineJnts = glTools.utils.joint.getJointList(startJoint,endJoint) spine = build(startJoint,endJoint,ikSwitchCtrl,ikSwitchAttr,ctrlScale,prefix) spine_module = spine[0] spine_attach = spine[1] spine_rig_grp = prefix+'_rig_grp' # ========================= # - Process Ribbon Joints - # ========================= for ribbonJoint in ribbonJoints: # Delete incoming connections mc.delete(mc.listConnections(ribbonJoint,s=True,d=False)) # ====================== # - Build Spine Ribbon - # ====================== locList = [] lfLocList = [] rtLocList = [] # Create Ribbon Locators for i in range(len(spineJnts)): pt = glTools.utils.base.getPosition(spineJnts[i]) strInd = glTools.utils.stringUtils.alphaIndex(i) loc = mc.spaceLocator(p=(0,0,0),n=prefix+strInd+'_loc')[0] lfLoc = mc.spaceLocator(p=(0.5,0,0),n=prefix+'_lf'+strInd+'_loc')[0] rtLoc = mc.spaceLocator(p=(-0.5,0,0),n=prefix+'_rt'+strInd+'_loc')[0] # Parent and position locators mc.parent([lfLoc,rtLoc],loc) mc.move(pt[0],pt[1],pt[2],loc,ws=True,a=True) mc.parent(loc,spineJnts[i]) mc.setAttr(loc+'.v',0) # Append Lists locList.append(loc) lfLocList.append(lfLoc) rtLocList.append(rtLoc) # Create Loft Curves lfCurve = glTools.utils.curve.createFromLocators(lfLocList,degree=1,attach=True,prefix=prefix+'A') rtCurve = glTools.utils.curve.createFromLocators(rtLocList,degree=1,attach=True,prefix=prefix+'B') lfCurveShape = mc.listRelatives(lfCurve,s=True,pa=True)[0] rtCurveShape = mc.listRelatives(rtCurve,s=True,pa=True)[0] glTools.utils.shape.createIntermediate(lfCurveShape) glTools.utils.shape.createIntermediate(rtCurveShape) # Rebuild Loft Curves if not spans: spans = len(spineJnts) - 1 lfRebuildCrv = mc.rebuildCurve(lfCurve,ch=1,rpo=1,rt=0,end=1,kr=0,kcp=0,kep=1,kt=1,s=spans,d=3,tol=0) rtRebuildCrv = mc.rebuildCurve(rtCurve,ch=1,rpo=1,rt=0,end=1,kr=0,kcp=0,kep=1,kt=1,s=spans,d=3,tol=0) lfRebuildCrv = mc.rename(lfRebuildCrv[1],prefix+'A_rebuildCurve') rtRebuildCrv = mc.rename(rtRebuildCrv[1],prefix+'B_rebuildCurve') # Generate Loft Surface loft = mc.loft([lfCurve,rtCurve],d=1,n=prefix+'_surface') loftNode = mc.rename(loft[1],prefix+'_loft') spineSurface = loft[0] rebuildSrf = mc.rebuildSurface(spineSurface,ch=True,rpo=True,end=True,rt=0,kr=0,kcp=True,dir=2,du=1,dv=3) rebuildSrf = mc.rename(rebuildSrf[1],prefix+'_rebuildSurface') # Parent to rig group ribbonParts = [lfCurve,rtCurve,spineSurface] for ribbonPart in ribbonParts: mc.setAttr(ribbonPart+'.v',0) mc.parent(ribbonPart,spine_rig_grp) # ======================== # - Attach Ribbon Joints - # ======================== inc = 1.0 / (len(ribbonJoints) - 1) ribbonJointGrps = [] for i in range(len(ribbonJoints)): # Create Joint Buffer Group strInd = glTools.utils.stringUtils.alphaIndex(i) prefix = glTools.utils.stringUtils.stripSuffix(ribbonJoints[i]) mc.select(cl=True) ribbonJointGrp = mc.joint(n=prefix+'ConA_jnt') mc.delete(mc.pointConstraint(ribbonJoints[i],ribbonJointGrp)) ribbonJointGrps.append(ribbonJointGrp) # Attach Joint Buffer Group glTools.utils.attach.attachToSurface(spineSurface,ribbonJointGrp,useClosestPoint=True,orient=True,uAxis='y',vAxis='x',uAttr='uCoord',vAttr='vCoord',alignTo='v',prefix=prefix+strInd) # Parent Ribbon Joint mc.parent(ribbonJoints[i],ribbonJointGrp) mc.parent(ribbonJointGrp,spine_rig_grp) # Connect Module Scale mc.connectAttr(spine_module+'.uniformScale',ribbonJoints[i]+'.sx',f=True) mc.connectAttr(spine_module+'.uniformScale',ribbonJoints[i]+'.sy',f=True) mc.connectAttr(spine_module+'.uniformScale',ribbonJoints[i]+'.sz',f=True) # ====================== # - Set Channel States - # ====================== chStateUtil = glTools.utils.channelState.ChannelState() chStateUtil.setFlags([2,2,2,2,2,2,2,2,2,1],objectList=locList) chStateUtil.setFlags([2,2,2,2,2,2,2,2,2,1],objectList=lfLocList) chStateUtil.setFlags([2,2,2,2,2,2,2,2,2,1],objectList=rtLocList) chStateUtil.setFlags([2,2,2,2,2,2,2,2,2,1],objectList=[lfCurve,rtCurve,spineSurface]) chStateUtil.setFlags([2,2,2,2,2,2,2,2,2,1],objectList=ribbonJoints) chStateUtil.setFlags([2,2,2,2,2,2,2,2,2,1],objectList=ribbonJointGrps) # ================= # - Return Result - # ================= return [spine_module,spine_attach]
def rebuild(surface, spansU=0, spansV=0, fullRebuildU=False, fullRebuildV=False, rebuildUfirst=True, replaceOrig=False): """ Do brute force surface rebuild for even parameterization @param surface: Nurbs surface to rebuild @type surface: str @param spansU: Number of spans along U. If 0, keep original value. @type spansU: int @param spansV: Number of spans along V. If 0, keep original value. @type spansV: int @param replaceOrig: Replace original surface, or create new rebuilt surface. @type replaceOrig: bool """ # ========== # - Checks - # ========== # Check surface if not isSurface(surface): raise Exception('Object "' + surface + '" is not a valid surface!') # Check spans if not spansU: spansU = cmds.getAttr(surface + '.spansU') if not spansV: spansV = cmds.getAttr(surface + '.spansV') # ============= # - Rebuild U - # ============= # Get V range if rebuildUfirst: dir = 'u' opp = 'v' spans = spansU min = cmds.getAttr(surface + '.minValueV') max = cmds.getAttr(surface + '.maxValueV') else: dir = 'v' opp = 'u' spans = spansV min = cmds.getAttr(surface + '.minValueU') max = cmds.getAttr(surface + '.maxValueU') val = min + (max - min) * 0.5 # Caluculate surface length iso_crv = cmds.duplicateCurve(surface + '.' + opp + '[' + str(val) + ']', ch=0, rn=0, local=0)[0] iso_len = cmds.arclen(iso_crv) iso_inc = iso_len / spans # Get spaced isoparm list curveFn = glTools.utils.curve.getCurveFn(iso_crv) iso_list = [surface + '.' + dir + '[' + str(curveFn.findParamFromLength(iso_inc * i)) + ']' for i in range(spans + 1)] cmds.delete(iso_crv) # Check full rebuild if fullRebuildV: # Extract isoparm curves iso_crv_list = [cmds.duplicateCurve(iso, ch=False, rn=False, local=False)[0] for iso in iso_list] # Rebuild isoparm curves for iso_crv in iso_crv_list: cmds.rebuildCurve(iso_crv, ch=False, rpo=True, rt=0, end=1, kr=0, kcp=0, kep=1, kt=1, s=0, d=3, tol=0) # Loft final surface int_surface = cmds.loft(iso_crv_list, ch=0, u=1, c=0, ar=1, d=3, ss=1, rn=0, po=0, rsn=True)[0] # Delete intermediate curves cmds.delete(iso_crv_list) else: # Loft intermediate surface int_surface = cmds.loft(iso_list, ch=0, u=1, c=0, ar=1, d=3, ss=1, rn=0, po=0, rsn=True)[0] # ============= # - Rebuild V - # ============= # Get V range (intermediate surface) if rebuildUfirst: dir = 'u' opp = 'v' spans = spansV min = cmds.getAttr(int_surface + '.minValueU') max = cmds.getAttr(int_surface + '.maxValueU') else: dir = 'v' opp = 'u' spans = spansU min = cmds.getAttr(int_surface + '.minValueV') max = cmds.getAttr(int_surface + '.maxValueV') val = min + (max - min) * 0.5 # Caluculate surface length (intermediate surface) iso_crv = cmds.duplicateCurve(int_surface + '.' + opp + '[' + str(val) + ']', ch=0, rn=0, local=0)[0] iso_len = cmds.arclen(iso_crv) iso_inc = iso_len / spans # Get spaced isoparm list curveFn = glTools.utils.curve.getCurveFn(iso_crv) iso_list = [int_surface + '.' + dir + '[' + str(curveFn.findParamFromLength(iso_inc * i)) + ']' for i in range(spans + 1)] cmds.delete(iso_crv) # Check full rebuild if fullRebuildU: # Extract isoparm curves iso_crv_list = [cmds.duplicateCurve(iso, ch=False, rn=False, local=False)[0] for iso in iso_list] # Rebuild isoparm curves for iso_crv in iso_crv_list: cmds.rebuildCurve(iso_crv, ch=False, rpo=True, rt=0, end=1, kr=0, kcp=0, kep=1, kt=1, s=0, d=3, tol=0) # Loft final surface rebuild_surface = cmds.loft(iso_crv_list, ch=0, u=1, c=0, ar=1, d=3, ss=1, rn=0, po=0, rsn=True)[0] # Delete intermediate curves cmds.delete(iso_crv_list) else: # Loft final surface rebuild_surface = cmds.loft(iso_list, ch=0, u=1, c=0, ar=1, d=3, ss=1, rn=0, po=0, rsn=True)[0] # Rename rebuilt surface rebuild_surface = cmds.rename(rebuild_surface, surface + '_rebuild') rebuild_surfaceShape = cmds.listRelatives(surface, s=True, ni=True, pa=True)[0] cmds.delete(int_surface) # Re-parameterize 0-1 cmds.rebuildSurface(rebuild_surface, ch=False, rpo=True, dir=2, rt=0, end=1, kr=0, kcp=1, kc=1, tol=0, fr=0) # Initialize return value outputShape = rebuild_surfaceShape # ==================== # - Replace Original - # ==================== if replaceOrig: """ # Get original shape shapes = glTools.utils.shape.getShapes(surface,nonIntermediates=True,intermediates=False) if not shapes: # Find Intermediate Shapes shapes = glTools.utils.shape.listIntermediates(surface) # Check shapes if not shapes: raise Exception('Unable to determine shape for surface "'+surface+'"!') # Check connections if cmds.listConnections(shapes[0]+'.create',s=True,d=False): # Find Intermediate Shapes shapes = glTools.utils.shape.findInputShape(shapes[0]) """ # Check history shapes = cmds.listRelatives(surface, s=True, ni=True, pa=True) if not shapes: raise Exception('Unable to determine shape for surface "' + surface + '"!') shape = shapes[0] shapeHist = cmds.listHistory(shape) if shapeHist.count(shape): shapeHist.remove(shape) if shapeHist: print('Surface "" contains construction history, creating new shape!') # Override shape info and delete intermediate cmds.connectAttr(rebuild_surfaceShape + '.local', shape + '.create', f=True) outputShape = shape # ================= # - Return Result - # ================= return outputShape
def CurveToCreateJnt(self , planeName , CvNumOfSpans , curv , reCurve , degree , aimVector = (0,1,0) , upVector = (0,0,1) , axis = 'auto'): #move -r -os -wd #mc.move(0.01,0.011,0.012,curv + '.cv[0]',r = True,wd = True) #axis = 'x' if axis == 'auto': axis1 = 'z' upTranslate = 'translateY' else: axis1 = 'y' upTranslate = 'translateZ' jntsuffix = '_jnt' if reCurve == 'yes': selCurve = mc.rebuildCurve(curv,ch=1,rpo=0,rt=0,end=1,kr=0,kcp=0,kep=1,kt=0,s=CvNumOfSpans,d=degree,tol=0.01)[0] mc.select(selCurve) mc.DeleteHistory() else: selCurve = curv #selCurve = mc.ls(sl = True)[0] CurveEps = mc.ls(selCurve + '.ep[:]',fl = True) CurveCvs = mc.ls(selCurve + '.cv[:]',fl = True) worlds = [] cvworlds = [] jnts = [] for i in range(len(CurveEps)): ep = CurveEps[i] world = mc.xform(ep,q = True,ws = True,t = True) mc.select(cl = True) jnt = mc.joint(p = world,name = planeName + str(i + 1) + jntsuffix) worlds.append(world) jnts.append(jnt) for i in range(len(CurveCvs)): cv = CurveCvs[i] cvworld = mc.xform(cv,q = True,ws = True,t = True) cvworlds.append(cvworld) mc.select(cl = True) axisLocate = mc.joint(name = planeName + '_axisLocate') axisLocateZero = mc.group(axisLocate,em = False,name = axisLocate + '_zero') mc.delete(mc.pointConstraint(jnts,axisLocateZero,mo = False)) #if CvNumOfSpans >= 2: #axisFacet = mc.polyCreateFacet(p = worlds,ch = False)[0] #elif CvNumOfSpans == 1: #axisFacet = mc.polyCreateFacet(p = cvworlds,ch = False)[0] axisFacet = self.axisPanelCreate(planeName,curv,axis) FacetShape = mc.listRelatives(axisFacet,s = True)[0] UV = self.closestPointOnModel(FacetShape,axisLocate) U = UV[0] V = UV[1] follic = self.follicCreate(FacetShape,planeName + '_axis_follic',U,V) #----------------------------------orient joint------------------------------------- mc.delete(mc.parentConstraint(follic,axisLocateZero,mo = False)) axisLocateZeroRx = mc.getAttr(axisLocateZero + '.rotateX') mc.setAttr(axisLocateZero + '.rotateX',abs(axisLocateZeroRx)) mc.setAttr(axisLocate + '.' + upTranslate,1) wut = 'object' wuo = axisLocate for i in range(len(jnts)-1): jnt = jnts[i] nextJnt = jnts[i+1] mc.delete(mc.pointConstraint(jnt,axisLocateZero,mo = False,w = 1)) mc.delete(mc.aimConstraint(nextJnt,jnt,offset = (0,0,0),w = 1,aim = aimVector,u = upVector,wut = wut,wuo = wuo)) mc.delete(mc.orientConstraint(jnts[-2],jnts[-1],mo = False,w = 1)) mc.makeIdentity(jnts,apply = True,r = 1,n = 0) #----------------------------------create plane------------------------------------------ offsetGrp = mc.group(em = True,name = planeName + '_cv_offset') offsetZero = mc.group(offsetGrp,name = offsetGrp + '_zero') mc.delete(mc.parentConstraint(follic,offsetZero,mo = False)) Curve01 = mc.duplicate(selCurve)[0] Curve02 = mc.duplicate(selCurve)[0] mc.parent(Curve01,offsetGrp) mc.setAttr(offsetGrp + '.t' + axis1,1) mc.parent(Curve01,w = True) mc.parent(Curve02,offsetGrp) mc.setAttr(offsetGrp + '.t' + axis1,0) mc.parent(Curve02,w = True) mc.delete(axisFacet,axisLocateZero,follic,offsetZero) Plane = mc.loft(Curve01,Curve02,ch = True,u = True,c = False,ar = True,d = 3,ss = True,rn = False,po = False,rsn = True,name = planeName)[0] mc.select(Plane) mc.DeleteHistory() mc.delete(Curve01,Curve02) if reCurve == 'yes': mc.delete(selCurve) return Plane,jnts
def _buildSideSplashEmitter(name = '', boatName = '', splashParticleName = [], boatIntersectCurveShape = '', sideAnimatable = '', presetName = None): """ New builder for sideSplash nParticle Emitter Checks if the NPARTICLE_EMITTLERS_hrc exists or not too @param name: The name of the new emitter @param splashParticleName: List of the names of nParticleShape nodes to connect to the emitter @param boatIntersectCurveShape: The name of the intersection curve to emit from. @type name: String @type splashParticleName: List @type boatIntersectCurveShape: String """ if not cmds.objExists('nPARTICLE_EMITTERS_hrc'): cmds.group(n = 'nPARTICLE_EMITTERS_hrc', em = True) debug(None, method = '_buildSideSplashEmitter', message = 'name: %s' % name, verbose = False) # Get base flat surface lineCurve = cmds.curve( name = '%s_extrudeCurve' % name, degree = 1, point = [(-0.01, 0, 0), (0.01, 0, 0)] ) flatSurface = cmds.extrude(lineCurve, boatIntersectCurveShape, name = '%s_flatSurface' % name, constructionHistory = True, range = False, polygon = 0, useComponentPivot = 1, fixedPath = True, useProfileNormal = True, extrudeType = 2, reverseSurfaceIfPathReversed = True)[0] cmds.rebuildSurface(flatSurface, constructionHistory = True, replaceOriginal = True, rebuildType = 0, endKnots = 1, keepCorners = False, spansU = 1, degreeU = 1, spansV = 100, degreeV = 3) # Offset upwards curve from surface offsetUp = cmds.offsetCurve('%s.u[0.5]' % flatSurface, name = '%s_offsetUp' % name, distance = 0, constructionHistory = True, range = 0, subdivisionDensity = 1)[0] cmds.rebuildCurve(offsetUp, constructionHistory = False, replaceOriginal = True, end = 1, keepRange = 0, keepControlPoints = True, degree = 1) cmds.setAttr('%s.translateY' % offsetUp, 0.01) # Offset from upwards curve with distance and translate down to get the 45 degree angle offset_distance = -0.01 offsetOut = cmds.offsetCurve(offsetUp, name = '%s_offsetOut' % name, distance = offset_distance, constructionHistory = True, range = 0, subdivisionDensity = 1)[0] cmds.setAttr('%s.translateY' % offsetOut, offset_distance) # Finally, loft a non-flipping surface solution (45 degree angle of the boat) noFlipSurface = cmds.loft(offsetUp, offsetOut, degree = 1, constructionHistory = True, range = 0, polygon = 0, sectionSpans = 1)[0] noFlipSurface = cmds.rename(noFlipSurface, '%s_noFlipSurface' % name) ## Build the emitter emitter = cmds.emitter(noFlipSurface, name = '%s_emitter' % name, type = 'surface') # Create closestPointOnSurface for acceleration expression where front more acceleration cPoS = cmds.createNode('closestPointOnSurface', name = '%s_cPoS' % name) cmds.connectAttr('%s.worldSpace' % noFlipSurface, '%s.inputSurface' % cPoS) ## Build the emitter group if it doesn't already exist emitterGroup = '%s_hrc' % name if not cmds.objExists(emitterGroup): cmds.group(lineCurve, flatSurface, offsetUp, offsetOut, noFlipSurface, emitter[0], n = emitterGroup) debug(None, method = '_buildSideSplashEmitter', message = 'emitterName: %s' % emitter[1], verbose = False) ## Check if a custom preset has been assigned via the func flags for the emitter, if not use the default preset... if presetName: pathToPreset = '%s/%s' %(CONST.EMITTERBASEPRESETPATH, presetName) debug(None, method = '_buildSideSplashEmitter', message = 'pathToPreset: %s' % pathToPreset, verbose = False) mel.eval( 'applyPresetToNode "%s" "" "" "%s" 1;' %(emitter[1], pathToPreset) ) ## Now parent it try: cmds.parent(emitterGroup, 'nPARTICLE_EMITTERS_hrc') except: pass ## Connect the emitter to the particles debug(None, method = '_buildSideSplashEmitter', message = 'Connected %s: %s' % (splashParticleName, emitter[1]), verbose = False) for each in splashParticleName: _connect_NParticleShape_to_NParticleEmitter(particleShapeNode = each, emitter = emitter[1]) ## Now do the expression for the side emitter if 'IntersectCurveRight' in emitter[1]: direction = 'R' else: direction = 'L' expStringList = [ 'float $minSpeed = %s.minSpeed;\n' % sideAnimatable, 'float $maxSpeed = %s.maxSpeed;\n' % sideAnimatable, 'float $speed = %s:world_ctrl.speed;\n' % boatName, 'float $curve = smoothstep($minSpeed, $maxSpeed, $speed);\n', 'float $rateMuliplier = %s.rateMultiplier%s;\n' %(sideAnimatable, direction), 'float $splashMaxSpeed = %s.splashMaxSpeed%s;\n' %(sideAnimatable, direction), '\n', 'if (%s.useSpeed == 1)\n' % sideAnimatable, '{\n\t', '%s.rate = $rateMuliplier * $curve;\n' % emitter[1], '\n\t\t', 'float $emitterSpeed = $splashMaxSpeed * $curve;\n\t\t', 'if ($emitterSpeed == 0)\n\t\t', '{\n\t\t\t', '$emitterSpeed = 0.1;\n\t\t', '}\n\t\t', '%s.speed = $emitterSpeed;\n' % emitter[1], '}\n', 'else\n', '{\n\t', '%s.rate = $rateMuliplier;\n\t' % emitter[1], '%s.speed = $splashMaxSpeed;\n' % emitter[1], '}\n', ] ## Check if the expression already exists in the scene, if so delete it utils.checkExpressionExists('%s_sideSplashEmitter' % boatName) ## Build new expression cmds.expression(emitter[1], n = '%s_sideSplashEmitter' % emitter[1], string = utils.processExpressionString(expStringList)) ## Connect some attributes if not cmds.isConnected('%s.normalSpeed%s' %(sideAnimatable, direction), '%s.normalSpeed' % emitter[1]): cmds.connectAttr('%s.normalSpeed%s' %(sideAnimatable, direction), '%s.normalSpeed' % emitter[1]) if not cmds.isConnected('%s.randomSpeed%s' %(sideAnimatable, direction), '%s.speedRandom' % emitter[1]): cmds.connectAttr('%s.randomSpeed%s' %(sideAnimatable, direction), '%s.speedRandom' % emitter[1]) return cPoS
def create_basic(length=10.0,width=0.5,mainCtrls=4,subCtrls=10,surface=True,curve=False,prefix=''): ''' Create a basic ribbon rig with a single base control @param length: Ribbon length @type length: float @param width: Ribbon width @type width: float @param mainCtrls: Number of main ribbon controls @type mainCtrls: int @param subCtrls: Number of ribbon sub controls @type subCtrls: int @param surface: Output ribbon surface @type surface: bool @param curve: Output ribbon curve @type curve: bool @param prefix: Name prefix for created nodes @type prefix: str ''' # Check prefix if not prefix: prefix = 'ribbon' # ----------------- # - Create Groups - # ----------------- ctrl_grp = mc.group(em=True,n=prefix+'_ctrl_grp') hist_grp = mc.group(em=True,n=prefix+'_hist_grp') out_grp = mc.group(em=True,n=prefix+'_out_grp') rig_grp = mc.group([ctrl_grp,hist_grp,out_grp],n=prefix+'_grp') mc.setAttr(hist_grp+'.v',0) # ---------------------- # - Create Base Ribbon - # ---------------------- base_pts = [] base_inc = length / (mainCtrls-1) for i in range(mainCtrls): base_pts.append([width*.5,base_inc*i,0.0]) # Curve 0 base_crv_0 = mc.curve(d=1,p=base_pts,k=range(len(base_pts)),n=prefix+'_base0_crv') mc.rebuildCurve(base_crv_0,ch=0,rpo=1,rt=0,end=1,kr=0,kcp=1,kep=1,kt=1,s=0,d=3,tol=0) base_crv_0_locs = glTools.utils.curve.locatorCurve(base_crv_0,prefix=prefix+'_base0') glTools.utils.shape.createIntermediate(base_crv_0) mc.rebuildCurve(base_crv_0,ch=1,rpo=1,rt=0,end=1,kr=0,kcp=0,kep=1,kt=1,s=(mainCtrls-1),d=3,tol=0) # Flip CV array base_pts = [(-i[0],i[1],i[2]) for i in base_pts] # Curve 1 base_crv_1 = mc.curve(d=1,p=base_pts,k=range(len(base_pts)),n=prefix+'_base1_crv') mc.rebuildCurve(base_crv_1,ch=0,rpo=1,rt=0,end=1,kr=0,kcp=1,kep=1,kt=1,s=0,d=3,tol=0) base_crv_1_locs = glTools.utils.curve.locatorCurve(base_crv_1,prefix=prefix+'_base1') glTools.utils.shape.createIntermediate(base_crv_1) mc.rebuildCurve(base_crv_1,ch=1,rpo=1,rt=0,end=1,kr=0,kcp=0,kep=1,kt=1,s=(mainCtrls-1),d=3,tol=0) # Loft base_loft = mc.loft([base_crv_0,base_crv_1],d=1,n=prefix+'_base_surface') base_surface = base_loft[0] base_loft = mc.rename(base_loft[1],prefix+'_base_loft') # Rebuild base_rebuild = mc.rebuildSurface(base_surface,ch=1,rpo=1,rt=0,end=1,kr=0,kcp=1,kc=1,su=0,du=0,sv=0,dv=0,tol=0,fr=0,dir=2,n=prefix+'_base_rebuildSurface') mc.parent([base_crv_0,base_crv_1,base_surface],hist_grp) # ----------------------- # - Create Base Control - # ----------------------- ctrlBuilder = glTools.tools.controlBuilder.ControlBuilder() mc.select(cl=True) base_jnt = mc.joint(n=prefix+'_base_jnt',radius=0.0) base_grp = mc.group(base_jnt,n=prefix+'_base_grp') mc.parent(base_grp,ctrl_grp) ctrlBuilder.controlShape(base_jnt,'circle',rotate=(90,0,0),scale=0.2*length) # ------------------------ # - Create Main Controls - # ------------------------ main_ctrl_list = [] main_grp_list = [] main_ctrl_grp = mc.group(em=True,n=prefix+'_mainCtrl_grp') for i in range(mainCtrls): # Clear selection mc.select(cl=True) # Create main control joint index = glTools.utils.stringUtils.alphaIndex(int(math.floor(i)),True) jnt = mc.joint(n=prefix+'_main'+index+'_jnt',radius=0.0) grp = mc.group(jnt,n=prefix+'_main'+index+'_grp') ctrlBuilder.controlShape(jnt,'square',rotate=(90,0,0),scale=0.125*length) # Position main control joint locs = [base_crv_0_locs[i],base_crv_1_locs[i]] mc.delete( mc.pointConstraint(locs,grp) ) mc.parent(locs,jnt) mc.makeIdentity(locs,apply=True,t=1,r=1,s=1,n=0) for loc in locs: mc.setAttr(loc+'.v',0) # Append list main_ctrl_list.append(jnt) main_grp_list.append(grp) mc.parent(main_grp_list,main_ctrl_grp) mc.parent(main_ctrl_grp,base_jnt) # ---------------------- # - Build Sub Controls - # ---------------------- sub_ctrl_list = [] sub_grp_list = [] sub_ctrl_grp = mc.group(em=True,n=prefix+'_subCtrl_grp') sub_inc = length / (subCtrls - 1) for i in range(subCtrls): # Clear selection mc.select(cl=True) # Create sub control joint index = glTools.utils.stringUtils.alphaIndex(i,True) sub_jnt = mc.joint(n=prefix+'_sub'+index+'_jnt',radius=0.0) sub_grp = mc.group(sub_jnt,n=prefix+'_sub'+index+'_grp') ctrlBuilder.controlShape(sub_jnt,'box',scale=0.025*length) # Position and attach sub controls mc.setAttr(sub_grp+'.t',0.0,(sub_inc*i),0.0) glTools.utils.attach.attachToSurface(base_surface,sub_grp,uValue=0.0,vValue=0.0,useClosestPoint=True,orient=True,uAxis='y',vAxis='x',uAttr='uCoord',vAttr='vCoord',alignTo='v',prefix=prefix+'_sub'+index) # Connect scale mc.connectAttr(base_jnt+'.scale',sub_grp+'.scale') # Append list sub_ctrl_list.append(sub_jnt) sub_grp_list.append(sub_grp) mc.parent(sub_grp_list,sub_ctrl_grp) mc.parent(sub_ctrl_grp,ctrl_grp) # ---------------- # - Build Output - # ---------------- # Build point array sub_inc = length / (subCtrls - 1) pts = [[0,(sub_inc*i),0] for i in range(subCtrls)] # ----- # Curve if curve: # Build curve ribbon_crv = mc.curve(d=1,p=pts,n=prefix+'_ribbon_curve') mc.rebuildCurve(ribbon_crv,ch=0,rpo=1,rt=0,end=1,kr=0,kcp=1,kep=1,kt=1,s=0,d=3,tol=0) # Create curve locators crv_locs = glTools.utils.curve.locatorCurve(ribbon_crv,prefix=prefix) glTools.utils.shape.createIntermediate(ribbon_crv) # Rebuild ribbon curve mc.rebuildCurve(ribbon_crv,ch=1,rpo=1,rt=0,end=1,kr=0,kcp=0,kep=1,kt=1,s=(subCtrls-1),d=3,tol=0,n=prefix+'_ribbon_rebuildCurve') # Parent curve locators for i in range(len(crv_locs)): mc.parent(crv_locs[i],sub_ctrl_list[i]) mc.setAttr(crv_locs[i]+'.v',0) mc.parent(ribbon_crv,out_grp) # ----------- # - Surface - if surface: # Offset CV array pts = [(width*.5,i[1],i[2]) for i in pts] # Sub Curve 0 sub_crv_0 = mc.curve(d=1,p=pts,k=range(len(pts)),n=prefix+'_sub0_crv') mc.rebuildCurve(sub_crv_0,ch=0,rpo=1,rt=0,end=1,kr=0,kcp=1,kep=1,kt=1,s=0,d=3,tol=0) sub_crv_0_locs = glTools.utils.curve.locatorCurve(sub_crv_0,prefix=prefix+'_sub0') glTools.utils.shape.createIntermediate(sub_crv_0) mc.rebuildCurve(sub_crv_0,ch=1,rpo=1,rt=0,end=1,kr=0,kcp=0,kep=1,kt=1,s=(subCtrls-1),d=3,tol=0,n=prefix+'_sub0_rebuildCurve') # Flip CV array pts = [(-i[0],i[1],i[2]) for i in pts] # Curve 1 sub_crv_1 = mc.curve(d=1,p=pts,k=range(len(pts)),n=prefix+'_sub1_crv') mc.rebuildCurve(sub_crv_1,ch=0,rpo=1,rt=0,end=1,kr=0,kcp=1,kep=1,kt=1,s=0,d=3,tol=0) sub_crv_1_locs = glTools.utils.curve.locatorCurve(sub_crv_1,prefix=prefix+'_sub1') glTools.utils.shape.createIntermediate(sub_crv_1) mc.rebuildCurve(sub_crv_1,ch=1,rpo=1,rt=0,end=1,kr=0,kcp=0,kep=1,kt=1,s=(subCtrls-1),d=3,tol=0,n=prefix+'_sub1_rebuildCurve') # Loft ribbon_loft = mc.loft([sub_crv_0,sub_crv_1],d=1,n=prefix+'_ribbon_surface') ribbon_surface = ribbon_loft[0] ribbon_loft = mc.rename(ribbon_loft[1],prefix+'_ribbon_loft') # Parent curve locators for i in range(len(pts)): locs = [sub_crv_0_locs[i],sub_crv_1_locs[i]] mc.parent(locs,sub_ctrl_list[i]) mc.makeIdentity(locs,apply=True,t=1,r=1,s=1,n=0) for loc in locs: mc.setAttr(loc+'.v',0) mc.parent([sub_crv_0,sub_crv_1],hist_grp) mc.parent(ribbon_surface,out_grp)
def create(length=10.0,width=0.5,mainCtrls=4,subCtrls=10,surface=True,curve=False,prefix=''): ''' Create a ribbon rig with a primary base and tip controls @param length: Ribbon length @type length: float @param width: Ribbon width @type width: float @param mainCtrls: Number of main ribbon controls @type mainCtrls: int @param subCtrls: Number of ribbon sub controls @type subCtrls: int @param surface: Output ribbon surface @type surface: bool @param curve: Output ribbon curve @type curve: bool @param prefix: Name prefix for created nodes @type prefix: str ''' # Check prefix if not prefix: prefix = 'ribbon' # ----------------- # - Create Groups - # ----------------- ctrl_grp = mc.group(em=True,n=prefix+'_ctrl_grp') hist_grp = mc.group(em=True,n=prefix+'_hist_grp') out_grp = mc.group(em=True,n=prefix+'_out_grp') rig_grp = mc.group([ctrl_grp,hist_grp,out_grp],n=prefix+'_grp') mc.setAttr(hist_grp+'.v',0) # ---------------------- # - Create Base Ribbon - # ---------------------- # Generate point array base_inc = float(length) / (mainCtrls-1) base_pts = [(width*.5,base_inc*i,0.0) for i in range(mainCtrls)] # Curve 0 base_crv_0 = mc.curve(d=1,p=base_pts,k=range(len(base_pts)),n=prefix+'_base0_crv') mc.rebuildCurve(base_crv_0,ch=0,rpo=1,rt=0,end=1,kr=0,kcp=1,kep=1,kt=1,s=0,d=3,tol=0) base_crv_0_locs = glTools.utils.curve.locatorCurve(base_crv_0,prefix=prefix+'_base0') glTools.utils.shape.createIntermediate(base_crv_0) mc.rebuildCurve(base_crv_0,ch=1,rpo=1,rt=0,end=1,kr=0,kcp=0,kep=1,kt=1,s=(mainCtrls-1),d=3,tol=0) # Flip CV array base_pts = [(-i[0],i[1],i[2]) for i in base_pts] # Curve 1 base_crv_1 = mc.curve(d=1,p=base_pts,k=range(len(base_pts)),n=prefix+'_base1_crv') mc.rebuildCurve(base_crv_1,ch=0,rpo=1,rt=0,end=1,kr=0,kcp=1,kep=1,kt=1,s=0,d=3,tol=0) base_crv_1_locs = glTools.utils.curve.locatorCurve(base_crv_1,prefix=prefix+'_base1') glTools.utils.shape.createIntermediate(base_crv_1) mc.rebuildCurve(base_crv_1,ch=1,rpo=1,rt=0,end=1,kr=0,kcp=0,kep=1,kt=1,s=(mainCtrls-1),d=3,tol=0) # Loft base_loft = mc.loft([base_crv_0,base_crv_1],d=1,n=prefix+'_base_surface') base_surface = base_loft[0] base_loft = mc.rename(base_loft[1],prefix+'_base_loft') # Rebuild base_rebuild = mc.rebuildSurface(base_surface,ch=1,rpo=1,rt=0,end=1,kr=0,kcp=1,kc=1,su=0,du=0,sv=0,dv=0,tol=0,fr=0,dir=2,n=prefix+'_base_rebuildSurface') mc.parent([base_crv_0,base_crv_1,base_surface],hist_grp) # ------------------------------- # - Create Base and Tip Control - # ------------------------------- # Base Control mc.select(cl=True) base_jnt = mc.joint(n=prefix+'_baseA_jnt',radius=0.0) base_grp = mc.group(base_jnt,n=prefix+'_baseA_grp') mc.parent(base_grp,ctrl_grp) ctrlBuilder.controlShape(base_jnt,'circle',rotate=(90,0,0),scale=0.2*length) # Tip Control mc.select(cl=True) tip_jnt = mc.joint(n=prefix+'_tipA_jnt',radius=0.0) tip_grp = mc.group(tip_jnt,n=prefix+'_tipA_grp') mc.parent(tip_grp,ctrl_grp) # Position Tip mc.move(0,length,0,tip_grp,ws=True,a=True) ctrlBuilder.controlShape(tip_jnt,'circle',rotate=(90,0,0),scale=0.2*length) # ------------------------ # - Create Main Controls - # ------------------------ # Check mid control mid = False if (float(mainCtrls)/2) % 1: mid = True # Determine mid point if mid: split = int(math.ceil(float(mainCtrls)/2))-1 else : split = int(mainCtrls/2) # Create controls for i in range(mainCtrls): # Clear selection mc.select(cl=True) # Create main control joint index = glTools.utils.stringUtils.alphaIndex(int(math.floor(i)),True) jnt = mc.joint(n=prefix+'_main'+index+'_jnt',radius=0.0) grp = mc.group(jnt,n=prefix+'_main'+index+'_grp') ctrlBuilder.controlShape(jnt,'square',rotate=(90,0,0),scale=0.125*length) # Position main control joint locs = [base_crv_0_locs[i],base_crv_1_locs[i]] mc.delete( mc.pointConstraint(locs,grp) ) mc.parent(locs,jnt) mc.makeIdentity(locs,apply=True,t=1,r=1,s=1,n=0) for loc in locs: mc.setAttr(loc+'.v',0) # Constrain to base/tip control connBlend = glTools.utils.constraint.blendConstraint([base_jnt,tip_jnt],grp,jnt,blendAttr='bias',maintainOffset=True,prefix='') # Set constraint weights if mid and i == split: mc.setAttr(connBlend,0.5) else: if i < split: mc.setAttr(connBlend,0.0) else: mc.setAttr(connBlend,1.0) # Parent to main control group mc.parent(grp,ctrl_grp) # ---------------------- # - Build Sub Controls - # ---------------------- sub_ctrl_list = [] sub_grp_list = [] sub_ctrl_grp = mc.group(em=True,n=prefix+'_subCtrl_grp') # Turn off inheritTransform mc.setAttr(sub_ctrl_grp+'.inheritsTransform',0) # Build point array sub_inc = float(length) / (subCtrls - 1) pts = [[0,(sub_inc*i),0] for i in range(subCtrls)] for i in range(subCtrls): # Clear selection mc.select(cl=True) # Create sub control joint index = glTools.utils.stringUtils.alphaIndex(i,True) sub_jnt = mc.joint(n=prefix+'_sub'+index+'_jnt',radius=0.0) sub_grp = mc.group(sub_jnt,n=prefix+'_sub'+index+'_grp') ctrlBuilder.controlShape(sub_jnt,'box',scale=0.025*length) # Position and attach sub controls mc.setAttr(sub_grp+'.t',pts[i][0],pts[i][1],pts[i][2]) glTools.utils.attach.attachToSurface(base_surface,sub_grp,uValue=0.0,vValue=0.0,useClosestPoint=True,orient=True,uAxis='-x',vAxis='y',uAttr='uCoord',vAttr='vCoord',alignTo='v',prefix=prefix+'_sub'+index) # Append list sub_ctrl_list.append(sub_jnt) sub_grp_list.append(sub_grp) mc.parent(sub_grp_list,sub_ctrl_grp) mc.parent(sub_ctrl_grp,ctrl_grp) # ---------------- # - Build Output - # ---------------- # ----- # Curve if curve: # Build curve ribbon_crv = mc.curve(d=1,p=pts,n=prefix+'_ribbon_curve') mc.rebuildCurve(ribbon_crv,ch=0,rpo=1,rt=0,end=1,kr=0,kcp=1,kep=1,kt=1,s=0,d=3,tol=0) # Create curve locators crv_locs = glTools.utils.curve.locatorCurve(ribbon_crv,prefix=prefix) glTools.utils.shape.createIntermediate(ribbon_crv) # Rebuild ribbon curve mc.rebuildCurve(ribbon_crv,ch=1,rpo=1,rt=0,end=1,kr=0,kcp=0,kep=1,kt=1,s=(subCtrls-1),d=3,tol=0,n=prefix+'_ribbon_rebuildCurve') # Parent curve locators for i in range(len(crv_locs)): mc.parent(crv_locs[i],sub_ctrl_list[i]) mc.setAttr(crv_locs[i]+'.v',0) mc.parent(ribbon_crv,out_grp) # ----------- # - Surface - if surface: # Offset CV array pts = [(width*.5,i[1],i[2]) for i in pts] # Sub Curve 0 sub_crv_0 = mc.curve(d=1,p=pts,k=range(len(pts)),n=prefix+'_sub0_crv') mc.rebuildCurve(sub_crv_0,ch=0,rpo=1,rt=0,end=1,kr=0,kcp=1,kep=1,kt=1,s=0,d=3,tol=0) sub_crv_0_locs = glTools.utils.curve.locatorCurve(sub_crv_0,prefix=prefix+'_sub0') glTools.utils.shape.createIntermediate(sub_crv_0) mc.rebuildCurve(sub_crv_0,ch=1,rpo=1,rt=0,end=1,kr=0,kcp=0,kep=1,kt=1,s=(subCtrls-1),d=3,tol=0,n=prefix+'_sub0_rebuildCurve') # Flip CV array pts = [(-i[0],i[1],i[2]) for i in pts] # Curve 1 sub_crv_1 = mc.curve(d=1,p=pts,k=range(len(pts)),n=prefix+'_sub1_crv') mc.rebuildCurve(sub_crv_1,ch=0,rpo=1,rt=0,end=1,kr=0,kcp=1,kep=1,kt=1,s=0,d=3,tol=0) sub_crv_1_locs = glTools.utils.curve.locatorCurve(sub_crv_1,prefix=prefix+'_sub1') glTools.utils.shape.createIntermediate(sub_crv_1) mc.rebuildCurve(sub_crv_1,ch=1,rpo=1,rt=0,end=1,kr=0,kcp=0,kep=1,kt=1,s=(subCtrls-1),d=3,tol=0,n=prefix+'_sub1_rebuildCurve') # Loft ribbon_loft = mc.loft([sub_crv_0,sub_crv_1],d=1,n=prefix+'_ribbon_surface') ribbon_surface = ribbon_loft[0] ribbon_loft = mc.rename(ribbon_loft[1],prefix+'_ribbon_loft') # Parent curve locators for i in range(len(pts)): locs = [sub_crv_0_locs[i],sub_crv_1_locs[i]] mc.parent(locs,sub_ctrl_list[i]) mc.makeIdentity(locs,apply=True,t=1,r=1,s=1,n=0) for loc in locs: mc.setAttr(loc+'.v',0) mc.parent([sub_crv_0,sub_crv_1],hist_grp) mc.parent(ribbon_surface,out_grp)
def spine_ribbon(ptList,spans=0,joints=6,prefix='cn_spine'): ''' ''' # ========== # - Checks - # ========== if not ptList: raise Exception('Invalid point list!') if not prefix: prefix = 'cn_spine' # ======================== # - Build Spine Locators - # ======================== pointList = [glTools.utils.base.getPosition(pt) for pt in ptList] locList = [] lfLocList = [] rtLocList = [] for pt in range(len(pointList)): strInd = glTools.utils.stringUtils.alphaIndex(pt) loc = mc.spaceLocator(p=(0,0,0),n=prefix+strInd+'_loc')[0] lfLoc = mc.spaceLocator(p=(0.5,0,0),n=prefix+strInd+'_loc')[0] rtLoc = mc.spaceLocator(p=(-0.5,0,0),n=prefix+strInd+'_loc')[0] mc.parent([lfLoc,rtLoc],loc) mc.move(pointList[pt][0],pointList[pt][1],pointList[pt][2],loc,ws=True,a=True) locList.append(loc) lfLocList.append(lfLoc) rtLocList.append(rtLoc) # =========================== # - Build Spine Loft Curves - # =========================== # Build Curves lfCurve = glTools.utils.curve.createFromLocators(lfLocList,degree=1,attach=True,prefix=prefix+'A') rtCurve = glTools.utils.curve.createFromLocators(rtLocList,degree=1,attach=True,prefix=prefix+'B') # Get Curve Shapes lfCurveShape = mc.listRelatives(lfCurve,s=True,pa=True)[0] rtCurveShape = mc.listRelatives(rtCurve,s=True,pa=True)[0] glTools.utils.shape.createIntermediate(lfCurveShape) glTools.utils.shape.createIntermediate(rtCurveShape) # Rebuild Curves if not spans: spans = len(ptList) - 1 lfRebuildCrv = mc.rebuildCurve(lfCurve,ch=1,rpo=1,rt=0,end=1,kr=0,kcp=0,kep=1,kt=1,s=spans,d=3,tol=0) rtRebuildCrv = mc.rebuildCurve(rtCurve,ch=1,rpo=1,rt=0,end=1,kr=0,kcp=0,kep=1,kt=1,s=spans,d=3,tol=0) lfRebuildCrv = mc.rename(lfRebuildCrv[1],prefix+'A_rebuildCurve') rtRebuildCrv = mc.rename(rtRebuildCrv[1],prefix+'B_rebuildCurve') # ========================= # - Generate Loft Surface - # ========================= loft = mc.loft([lfCurve,rtCurve],d=1,n=prefix+'_surface') loftSurface = loft[0] loftNode = mc.rename(loft[1],prefix+'_loft') # ============================ # - Create and Attach Joints - # ============================ jointList = [] inc = 1.0 / (joints - 1) for i in range(joints): mc.select(cl=1) strInd = glTools.utils.stringUtils.alphaIndex(i) joint = mc.joint(n=prefix+strInd+'_jnt') glTools.utils.attach.attachToSurface(loftSurface,joint,uValue=.5,vValue=inc*i,orient=True,uAxis='y',vAxis='x',uAttr='uCoord',vAttr='vCoord',alignTo='v',prefix=prefix+strInd) jointList.append(joint) # =========== # - Cleanup - # =========== jntGrp = mc.group(jointList,n=prefix+'_jnt_grp') rigGrp = mc.group([lfCurve,rtCurve,loftSurface],n=prefix+'_rig_grp') locGrp = mc.group(locList,n=prefix+'_loc_grp') # ================= # - Return Result - # ================= return [jntGrp,rigGrp,locGrp]
def createChalkLine(projectName, objectName,surfaceName): #Initializing Variables nodeName = cmds.createNode('pfxToon', name = '%s_PaintFXToon'%projectName) mesh = objectName myPlane = surfaceName #PaintFXToon setting cmds.setAttr('%s.profileLines' % nodeName, False) cmds.setAttr('%s.borderLines' % nodeName, False) cmds.setAttr('%s.creaseLines' % nodeName, False) cmds.setAttr('%s.intersectionLines' % nodeName, True) cmds.setAttr('%s.resampleIntersection' % nodeName, True) cmds.setAttr('%s.displayPercent' % nodeName, 100) #Connecting mesh to PaintFXToon cmds.connectAttr("%s.outMesh"%mesh,"%s.inputSurface[0].surface"%nodeName) cmds.connectAttr("%s.worldMatrix[0]"%mesh,"%s.inputSurface[0].inputWorldMatrix"%nodeName) #Create NurbsTessellate and Connecting it to NurbSurface apple = cmds.createNode("nurbsTessellate", name="%s_nurbsTessellate"%projectName) cmds.connectAttr("%s.chordHeight"%myPlane,"%s.chordHeight"%apple) cmds.connectAttr("%s.chordHeightRatio"%myPlane,"%s.chordHeightRatio"%apple) cmds.connectAttr("%s.curvatureTolerance"%myPlane,"%s.curvatureTolerance"%apple) cmds.connectAttr("%s.edgeSwap"%myPlane,"%s.edgeSwap"%apple) cmds.connectAttr("%s.explicitTessellationAttributes"%myPlane,"%s.explicitTessellationAttributes"%apple) cmds.connectAttr("%s.local"%myPlane,"%s.inputSurface"%apple) cmds.connectAttr("%s.modeU"%myPlane,"%s.uType"%apple) cmds.connectAttr("%s.modeV"%myPlane,"%s.vType"%apple) cmds.connectAttr("%s.numberU"%myPlane,"%s.uNumber"%apple) cmds.connectAttr("%s.numberV"%myPlane,"%s.vNumber"%apple) cmds.connectAttr("%s.smoothEdge"%myPlane,"%s.smoothEdge"%apple) cmds.connectAttr("%s.smoothEdgeRatio"%myPlane,"%s.smoothEdgeRatio"%apple) cmds.connectAttr("%s.uDivisionsFactor"%myPlane,"%s.uDivisionsFactor"%apple) cmds.connectAttr("%s.useChordHeight"%myPlane,"%s.useChordHeight"%apple) cmds.connectAttr("%s.useChordHeightRatio"%myPlane,"%s.useChordHeightRatio"%apple) cmds.connectAttr("%s.vDivisionsFactor"%myPlane,"%s.vDivisionsFactor"%apple) #Connecting NurbsTessellate and NurbSurface to PaintFXToon cmds.connectAttr("%s.outputPolygon"%apple,"%s.inputSurface[1].surface"%nodeName) cmds.connectAttr("%s.worldMatrix[0]"%myPlane,"%s.inputSurface[1].inputWorldMatrix"%nodeName) #Creating Curve and connecting it to PaintFXToon mainOffSet = cmds.createNode("offsetCurve",name="%s_main_offsetCurve"%projectName) topOffSet = cmds.createNode("offsetCurve",name="%s_top_offsetCurve"%projectName) midOffSet = cmds.createNode("offsetCurve",name="%s_mid_offsetCurve"%projectName) bottomOffSet = cmds.createNode("offsetCurve",name="%s_buttom_offsetCurve"%projectName) cmds.setAttr("%s.distance"%mainOffSet, 0) cmds.setAttr("%s.useGivenNormal"%mainOffSet, 0) cmds.setAttr("%s.subdivisionDensity"%mainOffSet, 10) cmds.setAttr("%s.tolerance"%mainOffSet, 0.5) cmds.setAttr("%s.distance"%topOffSet, 0) cmds.setAttr("%s.useGivenNormal"%topOffSet, 0) cmds.setAttr("%s.subdivisionDensity"%topOffSet, 10) cmds.setAttr("%s.tolerance"%topOffSet, 0.5) cmds.setAttr("%s.distance"%midOffSet, -0.1) cmds.setAttr("%s.useGivenNormal"%midOffSet, 0) cmds.setAttr("%s.subdivisionDensity"%midOffSet, 10) cmds.setAttr("%s.tolerance"%midOffSet, 0.5) cmds.setAttr("%s.distance"%bottomOffSet, 0) cmds.setAttr("%s.useGivenNormal"%bottomOffSet, 0) cmds.setAttr("%s.subdivisionDensity"%bottomOffSet, 10) cmds.setAttr("%s.tolerance"%bottomOffSet, 0.5) cmds.connectAttr("%s.outMainCurves[0]"%nodeName,"%s.inputCurve"%mainOffSet) cmds.connectAttr("%s.outputCurve[0]"%mainOffSet,"%s.inputCurve"%topOffSet) cmds.connectAttr("%s.outputCurve[0]"%mainOffSet,"%s.inputCurve"%midOffSet) cmds.connectAttr("%s.outputCurve[0]"%mainOffSet,"%s.inputCurve"%bottomOffSet) cmds.setAttr("%s.displayPercent"%nodeName, 0) #Creating 3 Curve chalkLine1 = cmds.circle(nr=(0, 1, 0), c=(0, 0, 0), r=1,name="%s_Bottom"%projectName) chalkLine2 = cmds.circle(nr=(0, 1, 0), c=(0, 0, 0), r=1,name="%s_Mid"%projectName) chalkLine3 = cmds.circle(nr=(0, 1, 0), c=(0, 0, 0), r=1,name="%s_Top"%projectName) curveGroups =cmds.group(chalkLine1[0],chalkLine2[0],chalkLine3[0],name="%s_CurvesList"%projectName) cmds.group(curveGroups, name="%s_CurvesControl"%projectName) # cmds.xform(chalkLine1[0],cp=True) # cmds.xform(chalkLine2[0],cp=True) # cmds.xform(chalkLine3[0],cp=True) cmds.move(0.2,chalkLine2[0],moveY=True) cmds.move(0.3,chalkLine3[0],moveY=True) # cmds.scale(1.2,1.2,1.2,chalkLine2[0],scaleXYZ=True) cmds.delete(chalkLine1[0],constructionHistory=True) cmds.delete(chalkLine2[0],constructionHistory=True) cmds.delete(chalkLine3[0],constructionHistory=True) cmds.connectAttr("%s.outputCurve[0]"%topOffSet,"%sShape.create"%chalkLine3[0]) cmds.connectAttr("%s.outputCurve[0]"%midOffSet,"%sShape.create"%chalkLine2[0]) cmds.connectAttr("%s.outputCurve[0]"%bottomOffSet,"%sShape.create"%chalkLine1[0]) objectLoft = cmds.loft(chalkLine3[0], chalkLine2[0], chalkLine1[0],name="%s_Loft"%projectName, constructionHistory=True, uniform=True, close=False, autoReverse=True, d=3, sectionSpans=1, range=False, polygon=0,rsn=True) return objectLoft, [chalkLine1[0],chalkLine2[0],chalkLine3[0]],[mainOffSet,topOffSet,midOffSet,bottomOffSet]
def createNrb(): #Get all name from UI# nameObj = mc.textField( Name , q = True , tx = True ) sideObj = mc.textField( Side , q = True , tx = True ) ParentObj1 = mc.textField( Parent1 , q = True, tx = True ) ParentObj2 = mc.textField( Parent2 , q = True, tx = True ) # Create Locator # baseLoc = mc.spaceLocator(p=(0, 0, 0), n = ( nameObj + 'Base'+ sideObj +'_loc' ))[0] tipLoc = mc.spaceLocator(p=(0, 0, 0), n = ( nameObj + 'Tip'+ sideObj +'_loc' ))[0] midLoc = mc.spaceLocator(p=(0, 0, 0), n = ( nameObj + 'Mid'+ sideObj +'_loc' ))[0] mc.setAttr((tipLoc + '.ty') , 5) mc.setAttr((midLoc + '.ty') , 2.5) # Get Position Attr # posBaseLoc = mc.xform(baseLoc,q=True,ws=True,rp=True) posTipLoc = mc.xform(tipLoc,q=True,ws=True,rp=True) # get position for arcLen # if len(ParentObj1) > 0 : arcLenCurve1 = mc.xform(ParentObj1,q=True,ws=True,rp=True) arcLenCurve2 = mc.xform(ParentObj2,q=True,ws=True,rp=True) elif len(ParentObj1) == 0 : arcLenCurve1 = posBaseLoc arcLenCurve2 = posTipLoc # Create Nurb # crv1 = mc.curve(d=1,p=(posTipLoc,posBaseLoc),n="rbn1_crv") mc.rename('curveShape1',crv1+'Shape') crv2 = mc.curve(d=1,p=(posTipLoc,posBaseLoc),n="rbn2_crv") mc.rename('curveShape1',crv2+'Shape') crvGlobal = mc.curve(d=1,p=(arcLenCurve1,arcLenCurve2),n= nameObj + 'rbnGlobal'+ sideObj +'_crv') mc.rename('curveShape1',crvGlobal+'Shape') crvMaster = mc.curve(d=1,p=(arcLenCurve1,arcLenCurve1),n=nameObj + 'rbn'+ sideObj +'_crv') mc.rename('curveShape1',crvMaster+'Shape') mc.setAttr(crvGlobal+'.v',0) mc.setAttr(crvMaster+'.v',0) mc.setAttr(crv1 + ".tx" , 1) mc.setAttr(crv2 + ".tx" , -1) RibbonNrb = mc.loft(crv2,crv1,u=True,ch=False,ss=1,rn=False,po=0,rsn=True,n = (nameObj + 'Ribbon'+ sideObj +'_nrb'))[0] mc.rebuildSurface(RibbonNrb,su=5,sv=0) mc.setAttr(RibbonNrb+'.visibility',0) mc.delete(crv1,crv2) paraU = 0.1 allposi = [] allDetailjnt = [] allDetailGrp = [] for i in range(1,6) : # Create pointOnSurfaceInfo & Group # Posi = mc.createNode('pointOnSurfaceInfo' , n = (nameObj + str(i) +'Rbn' + sideObj + '_posi')) RbnPos = mc.createNode('transform', n = (nameObj + str(i) +'RbnPos' + sideObj + '_grp' )) mc.connectAttr( RibbonNrb + 'Shape.worldSpace' , Posi + '.inputSurface' ) mc.setAttr(Posi + '.parameterU' , paraU ) mc.setAttr(Posi + '.parameterV' , 0.5 ) mc.select(cl=True) paraU += 0.2 # Connect pointOnSurfaceInfo to Group # mc.connectAttr(Posi + '.position' , RbnPos + '.translate') AimRbnPos = mc.createNode('aimConstraint' , n = (nameObj + str(i) +'RbnPosGrp' + sideObj + '_aimCons')) mc.parent(AimRbnPos , RbnPos) mc.setAttr(AimRbnPos + '.t' , 0 , 0 , 0 ) mc.setAttr(AimRbnPos + '.r' , 0 , 0 , 0 ) mc.connectAttr(Posi + '.normal' , AimRbnPos + '.worldUpVector') mc.connectAttr(Posi + '.tangentU' , AimRbnPos + '.target[0].targetTranslate') mc.connectAttr(AimRbnPos + '.constraintRotate' , RbnPos + '.rotate' ) mc.setAttr(AimRbnPos + '.upVectorY' , 0) mc.setAttr(AimRbnPos + '.upVectorZ' , 1) allposi.append(RbnPos) mc.select(cl=True) # create detail joint # posiPosition = mc.xform(RbnPos,q=True,ws=True,rp=True) detailJnt = mc.joint(p = posiPosition, n = (nameObj + str(i) + 'Detail' + sideObj + '_jnt')) #testCube = mc.polyCube(w=.5,h=.5,d=1) allDetailjnt.append(detailJnt) #mc.parentConstraint(detailJnt,testCube) #mc.scaleConstraint(detailJnt,testCube) mc.select(cl=True) # create deetail control # detailCtrlPosi = mc.xform(detailJnt,q=True,ws=True,rp=True) detailCtrl = mc.curve(d = 1, p =[(-1.25, 0, 0), (-1.004121, 0, 0), (-0.991758, 0, -0.157079), (-0.954976, 0, -0.31029), (-0.894678, 0, -0.455861),(-0.812351, 0, -0.590207), (-0.710021, 0, -0.710021), (-0.590207, 0, -0.812351), (-0.455861, 0, -0.894678), (-0.31029, 0, -0.954976),(-0.157079, 0, -0.991758), (0, 0, -1.004121), (0, 0, -1.25), (0, 0, -1.004121), (0.157079, 0, -0.991758), (0.31029, 0, -0.954976),(0.455861, 0, -0.894678),(0.590207, 0, -0.812351), (0.710021, 0, -0.710021), (0.812351, 0, -0.590207), (0.894678, 0, -0.455861),(0.954976, 0, -0.31029), (0.991758, 0, -0.157079), (1.004121, 0, 0), (1.25, 0, 0), (1.004121, 0, 0), (0.991758, 0, 0.157079), (0.954976, 0, 0.31029), (0.894678, 0, 0.455861), (0.812351, 0, 0.590207), (0.710021, 0, 0.710021), (0.590207, 0, 0.812351), (0.455861, 0, 0.894678), (0.31029, 0, 0.954976),(0.157079, 0, 0.991758),(0, 0, 1.004121), (0, 0, 1.25), (0, 0, 1.004121), (-0.157079, 0, 0.991758), (-0.31029, 0, 0.954976), (-0.455861, 0, 0.894678), (-0.590207, 0, 0.812351), (-0.710021, 0, 0.710021), (-0.812351, 0, 0.590207), (-0.894678, 0, 0.455861), (-0.954976, 0, 0.31029),(-0.991758,0,0.157079),(-1.004121,0,0)], n = (nameObj + str(i) + 'Rbn' + sideObj + '_ctrl')) mc.rename('curveShape1' , (nameObj + str(i) + 'Rbn' + sideObj + '_ctrlShape')) mc.addAttr(detailCtrl,ln='squash',at='float',dv=0,k=True) mc.setAttr(detailCtrl+'.sx', l = True , keyable = False ) mc.setAttr(detailCtrl+'.sy', l = True , keyable = False ) mc.setAttr(detailCtrl+'.sz', l = True , keyable = False ) mc.setAttr(detailCtrl+'.v', l = True , k = False ) mc.setAttr(detailCtrl + 'Shape.overrideEnabled' , 1) mc.setAttr(detailCtrl + 'Shape.overrideColor' , 18) detailRotGrp = mc.group(detailCtrl, n = (nameObj + str(i) +'DetailRot' + sideObj + '_grp' )) detailGrp = mc.group(detailRotGrp, n = (nameObj + str(i) +'DetailCtrlZro' + sideObj + '_grp' )) mc.parentConstraint(detailJnt,detailGrp) mc.delete( (nameObj + str(i) + 'DetailCtrlZro' + sideObj + '_grp_parentConstraint1')) allDetailGrp.append(detailGrp) mc.select(cl=True) mc.parentConstraint(RbnPos,detailGrp,mo = True) mc.parentConstraint(detailCtrl,detailJnt,mo = True) # Base Control # baseJnt = mc.joint(n = (nameObj + 'Base' + sideObj + '_jnt')) baseJntAimGrp = mc.group(n = (nameObj + 'RbnBaseAim' + sideObj + '_grp')) baseCtrl = mc.curve( d = 1 , p = [(1,0,0),(-1,0,0),(0,0,0),(0,0,-1),(0,0,1),(0,0,0),(0,1,0),(0,-1,0),(0,0,0)] , n = (nameObj + 'Base' + sideObj + '_ctrl')) mc.rename('curveShape1' , (nameObj + 'Base' + sideObj + '_ctrlShape')) mc.setAttr(baseCtrl+'.rx', l = True , keyable = False ) mc.setAttr(baseCtrl+'.ry', l = True , keyable = False ) mc.setAttr(baseCtrl+'.rz', l = True , keyable = False ) mc.setAttr(baseCtrl+'.sx', l = True , keyable = False ) mc.setAttr(baseCtrl+'.sy', l = True , keyable = False ) mc.setAttr(baseCtrl+'.sz', l = True , keyable = False ) mc.setAttr(baseCtrl+'.v',0, l = True , k = False ) mc.setAttr(baseCtrl + 'Shape.overrideEnabled' , 1) mc.setAttr(baseCtrl + 'Shape.overrideColor' , 17) baseJntZroGrp = mc.group(n = (nameObj + 'RbnBaseZro' + sideObj + '_grp')) mc.parent(baseJntAimGrp,baseCtrl) parCon = mc.parentConstraint(baseLoc,baseJntZroGrp) mc.delete(parCon) mc.select(cl=True) # Middle Control # midJnt = mc.joint(n = (nameObj + 'RbnMid' + sideObj + '_jnt')) midCtrl = mc.curve( d = 1 , p = [(-1, 0, -1),(-1, 0, 0),(-1.25, 0, 0),(-1, 0, 0),(-1, 0, 1),(0, 0, 1),(0, 0, 1.25),(0, 0, 1),(1, 0, 1),(1, 0, 0),(1.25, 0, 0),(1, 0, 0),(1, 0, -1),(0, 0, -1),(0, 0, -1.25),(0, 0, -1),(-1, 0, -1)] , n = (nameObj + 'RbnMid' + sideObj + '_ctrl')) midCtrlList = mc.listRelatives(midCtrl, shapes = True)[0] midCtrlShape = mc.rename(midCtrlList , (nameObj + 'RbnMid' + sideObj + '_ctrlShape')) mc.setAttr(midCtrl + 'Shape.overrideEnabled' , 1) mc.setAttr(midCtrl + 'Shape.overrideColor' , 17) mc.addAttr(midCtrl,ln='autoTwist',at='long',min=0,max=1,dv=0,k=True) mc.addAttr(midCtrl,ln='rootTwist',at='float',dv=0,k=True) mc.addAttr(midCtrl,ln='endTwist',at='float',dv=0,k=True) mc.addAttr(midCtrl,ln='autoSquash',at='long',min=0,max=1,dv=0,k=True) mc.addAttr(midCtrl,ln='squash',at='float',dv=0,k=True) mc.addAttr(midCtrlShape,ln='detailControl',at='bool',dv=0,k=True) mc.addAttr(midCtrlShape,ln='rootTwist',at='float',dv=0,k=True) mc.addAttr(midCtrlShape,ln='endTwist',at='float',dv=0,k=True) mc.setAttr(midCtrl+'.sx', l = True , keyable = False ) mc.setAttr(midCtrl+'.sy', l = True , keyable = False ) mc.setAttr(midCtrl+'.sz', l = True , keyable = False ) mc.setAttr(midCtrl+'.v',1, l = True , k = False ) midJntAimGrp = mc.group(n = (nameObj + 'RbnMidAim' + sideObj + '_grp')) midJntZroGrp = mc.group(n = (nameObj + 'RbnMidZro' + sideObj + '_grp')) mc.parent(midJnt,midCtrl) parCon = mc.parentConstraint(midLoc,midJntZroGrp) mc.delete(parCon) mc.select(cl=True) # Tip Control # tipCtrl = mc.curve( d = 1 , p = [(1,0,0),(-1,0,0),(0,0,0),(0,0,-1),(0,0,1),(0,0,0),(0,1,0),(0,-1,0),(0,0,0)] , n = (nameObj + 'Tip' + sideObj + '_ctrl')) mc.rename('curveShape1' , (nameObj + 'Tip' + sideObj + '_ctrlShape')) mc.setAttr(tipCtrl+'.rx', l = True , keyable = False ) mc.setAttr(tipCtrl+'.ry', l = True , keyable = False ) mc.setAttr(tipCtrl+'.rz', l = True , keyable = False ) mc.setAttr(tipCtrl+'.sx', l = True , keyable = False ) mc.setAttr(tipCtrl+'.sy', l = True , keyable = False ) mc.setAttr(tipCtrl+'.sz', l = True , keyable = False ) mc.setAttr(tipCtrl+'.v',0, l = True , k = False ) mc.setAttr(tipCtrl + 'Shape.overrideEnabled' , 1) mc.setAttr(tipCtrl + 'Shape.overrideColor' , 17) tipJntZroGrp = mc.group(n = (nameObj + 'RbnTipZro' + sideObj + '_grp')) tipJnt = mc.joint(n = (nameObj + 'Tip' + sideObj + '_jnt') , p = (0,0,0)) tipJntAimGrp = mc.group(n = (nameObj + 'RbnTipAim' + sideObj + '_grp')) mc.parent(tipJntAimGrp,tipCtrl) parCon = mc.parentConstraint(tipLoc,tipJntZroGrp) mc.delete(parCon) mc.delete(baseLoc,midLoc,tipLoc) mc.select(cl=True) # Create Twist # rbnTwistMdv = mc.createNode('multiplyDivide', n = (nameObj + 'RbnTwist' + sideObj + '_mdv')) rbnAutoTwistMdv = mc.createNode('multiplyDivide', n = (nameObj + 'RbnAutoTwist' + sideObj + '_mdv')) rbnAutoTwistPma = mc.createNode('plusMinusAverage', n = (nameObj + 'RbnAutoTwist' + sideObj + '_pma')) mc.setAttr(rbnAutoTwistMdv+'.input2X',-1) mc.connectAttr(midCtrl+'.autoTwist',rbnTwistMdv+'.input2Y') mc.connectAttr(midCtrl+'.autoTwist',rbnTwistMdv+'.input2X') mc.connectAttr(midCtrl+'Shape.rootTwist',rbnAutoTwistMdv+'.input1X') mc.connectAttr(midCtrl+'Shape.endTwist',rbnAutoTwistMdv+'.input1Y') mc.connectAttr(midCtrl+'.rootTwist',rbnAutoTwistPma+'.input3D[0].input3Dx') mc.connectAttr(midCtrl+'.endTwist',rbnAutoTwistPma+'.input3D[0].input3Dy') mc.connectAttr(rbnTwistMdv+'.output',rbnAutoTwistPma+'.input3D[1]') mc.connectAttr(rbnAutoTwistMdv+'.output',rbnTwistMdv+'.input1') for i in range(1,6) : detailRotGrp = (nameObj + str(i) +'DetailRot' + sideObj + '_grp' ) rbnTwistMdv = mc.createNode('multiplyDivide', n = (nameObj + str(i) + 'DetailTwist' + sideObj + '_mdv')) rbnTwistPma = mc.createNode('plusMinusAverage', n = (nameObj + str(i) + 'DetailTwist' + sideObj + '_pma')) mc.setAttr(rbnTwistMdv+'.input2Y',(0.25*(i-1))) mc.setAttr(rbnTwistMdv+'.input2X',(1-(0.25*(i-1)))) mc.connectAttr(rbnAutoTwistPma+'.output3Dx',rbnTwistMdv+'.input1.input1Y') mc.connectAttr(rbnAutoTwistPma+'.output3Dy',rbnTwistMdv+'.input1.input1X') mc.connectAttr(rbnTwistMdv+'.output.outputX',rbnTwistPma+'.input2D[0].input2Dx') mc.connectAttr(rbnTwistMdv+'.output.outputY',rbnTwistPma+'.input2D[1].input2Dx') mc.connectAttr(rbnTwistPma+'.output2D.output2Dx',detailRotGrp+'.rotate.rotateY') if len(ParentObj1) > 0 : mc.connectAttr(ParentObj1 +'.rotate.rotateY',midCtrl+'Shape.rootTwist') mc.connectAttr(ParentObj2 +'.rotate.rotateY',midCtrl+'Shape.endTwist') mc.setAttr(midCtrl+'Shape.rootTwist', l = True ) mc.setAttr(midCtrl+'Shape.endTwist', l = True ) # Create Squash # cfs = mc.createNode('curveFromSurfaceIso',n = (nameObj + 'Rbn' + sideObj + '_cfs')) mc.connectAttr(RibbonNrb + 'Shape.worldSpace' ,cfs + '.inputSurface') mc.setAttr(cfs+'.isoparmValue',0.5) mc.connectAttr(cfs + '.outputCurve' ,crvMaster + 'Shape.create') CurveGlobalInfo = mc.arclen(crvGlobal, ch=True ) rbnCurveGlobalInfo = mc.rename(CurveGlobalInfo,(nameObj + 'RbnGlobal' + sideObj + '_cif')) CurveMasterInfo = mc.arclen(crvMaster, ch=True ) rbnCurveMasterInfo = mc.rename(CurveMasterInfo,(nameObj + 'Rbn' + sideObj + '_cif')) rbnAutoSquashMdv = mc.createNode('multiplyDivide', n = (nameObj + 'RbnAutoSquash' + sideObj + '_mdv')) rbnAutoSquashPma = mc.createNode('plusMinusAverage', n = (nameObj + 'RbnAutoSquash' + sideObj + '_pma')) rbnAutoSquashPowMdv = mc.createNode('multiplyDivide', n = (nameObj + 'RbnAutoSquashPow' + sideObj + '_mdv')) rbnAutoSquashDivMdv = mc.createNode('multiplyDivide', n = (nameObj + 'RbnAutoSquashDiv' + sideObj + '_mdv')) rbnAutoSquashGlobalMdv = mc.createNode('multiplyDivide', n = (nameObj + 'RbnAutoSquashGlobal' + sideObj + '_mdv')) mc.setAttr(rbnAutoSquashPma+'.input2D[1].input2Dx',-1) mc.setAttr(rbnAutoSquashPma+'.input2D[1].input2Dy',-1) mc.setAttr(rbnAutoSquashPowMdv+'.input2X',0.5) mc.setAttr(rbnAutoSquashPowMdv+'.operation',3) mc.setAttr(rbnAutoSquashDivMdv+'.operation',2) mc.setAttr(rbnAutoSquashGlobalMdv+'.operation',2) mc.setAttr(rbnAutoSquashDivMdv+'.input1X',1) mc.connectAttr(rbnCurveMasterInfo + '.arcLength',rbnAutoSquashGlobalMdv + '.input1X') mc.connectAttr(rbnCurveGlobalInfo + '.arcLength',rbnAutoSquashGlobalMdv + '.input2X') mc.connectAttr(rbnAutoSquashGlobalMdv +'.outputX',rbnAutoSquashDivMdv + '.input2X') mc.connectAttr(rbnAutoSquashDivMdv +'.outputX',rbnAutoSquashPowMdv + '.input1X') mc.connectAttr(midCtrl +'.autoSquash',rbnAutoSquashMdv + '.input2X') mc.connectAttr(rbnAutoSquashPma +'.output2Dx',rbnAutoSquashMdv + '.input1X') mc.connectAttr(rbnAutoSquashPowMdv +'.outputX',rbnAutoSquashPma + '.input2D[0].input2Dx') amp = 0.3333 for i in range(1,6) : detailCtrl = (nameObj + str(i) + 'Rbn' + sideObj + '_ctrl') rbnStSqMdv = mc.createNode('multiplyDivide', n = (nameObj + str(i) + 'RbnCtrlStSq' + sideObj + '_mdv')) rbnStSqPma = mc.createNode('plusMinusAverage', n = (nameObj + str(i) + 'RbnCtrlStSq' + sideObj + '_pma')) mc.setAttr(rbnStSqPma+'.input2D[0].input2Dy',1) mc.connectAttr(detailCtrl +'.squash',rbnStSqMdv + '.input1Y') mc.connectAttr(rbnStSqMdv +'.outputX',rbnStSqPma + '.input2D[1].input2Dy') mc.connectAttr(rbnStSqMdv +'.outputY',rbnStSqPma + '.input2D[2].input2Dy') mc.connectAttr(rbnStSqMdv +'.outputZ',rbnStSqPma + '.input2D[3].input2Dy') mc.connectAttr(rbnAutoSquashMdv+'.outputX' ,rbnStSqMdv +'.input1X' ) mc.connectAttr(midCtrl+'.squash' ,rbnStSqMdv +'.input1Z' ) detailJnt = (nameObj + str(i) + 'Detail' + sideObj + '_jnt') mc.connectAttr(rbnStSqPma+'.output2Dy',detailJnt+'.scaleX') mc.connectAttr(rbnStSqPma+'.output2Dy',detailJnt+'.scaleZ') if i < 3 : mc.setAttr(rbnStSqMdv+'.input2X' , amp) mc.setAttr(rbnStSqMdv+'.input2Z' , amp) amp += 0.3333 if i > 3 : amp -= 0.3333 mc.setAttr(rbnStSqMdv+'.input2X' , amp) mc.setAttr(rbnStSqMdv+'.input2Z' , amp) mc.aimConstraint(baseJntAimGrp,tipJntAimGrp, wuo = tipJntZroGrp ,aim = [0,-1,0] , u = [0,1,0] , wut = 'objectrotation' , wu = [0,1,0]) mc.aimConstraint(tipJntAimGrp,baseJntAimGrp, wuo = baseJntZroGrp ,aim = [0,1,0] , u = [0,1,0] , wut = 'objectrotation' , wu = [0,1,0]) mc.aimConstraint(tipJntAimGrp,midJntAimGrp, wuo = midJntZroGrp ,aim = [0,1,0] , u = [0,1,0] , wut = 'objectrotation' , wu = [0,1,0]) mc.pointConstraint( baseJnt, tipJnt, midJntZroGrp ) #skin nurb# NurbsSkin = mc.skinCluster( baseJnt, midJnt, tipJnt , RibbonNrb , dr=16, nw=2 , n = (nameObj + 'RbnNrb' + sideObj + '_skc') , tsb = True) mc.skinPercent (NurbsSkin[0], (RibbonNrb + '.cv[0][0:3]'), tv = (tipJnt, 1)) mc.skinPercent (NurbsSkin[0], (RibbonNrb + '.cv[1][0:3]'), tv = (midJnt, .13)) mc.skinPercent (NurbsSkin[0], (RibbonNrb + '.cv[2][0:3]'), tv = (midJnt, .4)) mc.skinPercent (NurbsSkin[0], (RibbonNrb + '.cv[3][0:3]'), tv = (midJnt, .8)) mc.skinPercent (NurbsSkin[0], (RibbonNrb + '.cv[4][0:3]'), tv = (midJnt, .8)) mc.skinPercent (NurbsSkin[0], (RibbonNrb + '.cv[5][0:3]'), tv = (midJnt, .4)) mc.skinPercent (NurbsSkin[0], (RibbonNrb + '.cv[6][0:3]'), tv = (midJnt, .13)) mc.skinPercent (NurbsSkin[0], (RibbonNrb + '.cv[7][0:3]'), tv = (baseJnt, 1)) detailZroGrp = mc.group(allDetailGrp , n = (nameObj + 'RbnDetailZro' + sideObj + '_grp')) mc.select( clear=True ) rbnCtrlGrp = mc.group(detailZroGrp,baseJntZroGrp,midJntZroGrp,tipJntZroGrp,crvGlobal, n = (nameObj + 'RbnCtrl' + sideObj + '_grp')) mc.select( clear=True ) rbnStillGrp = mc.group(allposi,RibbonNrb ,crvMaster, n = (nameObj + 'RbnStill' + sideObj + '_grp')) mc.select(cl=True) rbnSkinGrp = mc.group(allDetailjnt , n = (nameObj + 'RbnSkin' + sideObj + '_grp')) mc.select(cl=True) mc.connectAttr(midCtrlShape+'.detailControl',detailZroGrp+'.v') mc.parentConstraint( rbnCtrlGrp, rbnSkinGrp , mo=0 ) if len(ParentObj1) > 0 : mc.pointConstraint( ParentObj1, baseJntZroGrp , mo=0 ) mc.pointConstraint( ParentObj2, tipJntZroGrp , mo=0 ) mc.parentConstraint( ParentObj1, rbnCtrlGrp , mo=0 )
def create(surface, spansU=0, spansV=0, prefix=None): """ """ # Load Plugins loadPlugin() # ========== # - Checks - # ========== # Check Surface if not glTools.utils.surface.isSurface(surface): raise Exception('Object "' + surface + '" is not a valid nurbs surface!') # Check Prefix if not prefix: prefix = glTools.utils.stringUtils.stripSuffix(surface) # Get Surface Details if not spansU: spansU = cmds.getAttr(surface + ".spansU") if not spansV: spansV = cmds.getAttr(surface + ".spansV") minU = cmds.getAttr(surface + ".minValueU") maxU = cmds.getAttr(surface + ".maxValueU") minV = cmds.getAttr(surface + ".minValueV") maxV = cmds.getAttr(surface + ".maxValueV") incU = (maxU - minU) / spansU incV = (maxV - minV) / spansV # ============= # - Rebuild U - # ============= crvU = [] for i in range(spansU + 1): # Duplicate Surface Curve dupCurve = cmds.duplicateCurve(surface + ".u[" + str(incU * i) + "]", ch=True, rn=False, local=False) dupCurveNode = cmds.rename(dupCurve[1], prefix + "_spanU" + str(i) + "_duplicateCurve") dupCurve = cmds.rename(dupCurve[0], prefix + "_spanU" + str(i) + "_crv") crvU.append(dupCurve) # Set Curve Length arcLen = cmds.arclen(dupCurve) setLen = cmds.createNode("setCurveLength", n=prefix + "_spanU" + str(i) + "_setCurveLength") crvInfo = cmds.createNode("curveInfo", n=prefix + "_spanU" + str(i) + "_curveInfo") blendLen = cmds.createNode("blendTwoAttr", n=prefix + "_spanU" + str(i) + "length_blendTwoAttr") cmds.addAttr(dupCurve, ln="targetLength", dv=arcLen, k=True) cmds.connectAttr(dupCurveNode + ".outputCurve", crvInfo + ".inputCurve", f=True) cmds.connectAttr(dupCurveNode + ".outputCurve", setLen + ".inputCurve", f=True) cmds.connectAttr(crvInfo + ".arcLength", blendLen + ".input[0]", f=True) cmds.connectAttr(dupCurve + ".targetLength", blendLen + ".input[1]", f=True) cmds.connectAttr(blendLen + ".output", setLen + ".length", f=True) cmds.connectAttr(setLen + ".outputCurve", dupCurve + ".create", f=True) # Add Control Attributes cmds.addAttr(dupCurve, ln="lockLength", min=0, max=1, dv=1, k=True) cmds.addAttr(dupCurve, ln="lengthBias", min=0, max=1, dv=0, k=True) cmds.connectAttr(dupCurve + ".lockLength", blendLen + ".attributesBlender", f=True) cmds.connectAttr(dupCurve + ".lengthBias", setLen + ".bias", f=True) # Loft New Surface srfU = cmds.loft(crvU, ch=True, uniform=True, close=False, autoReverse=False, degree=3) srfUloft = cmds.rename(srfU[1], prefix + "_rebuildU_loft") srfU = cmds.rename(srfU[0], prefix + "_rebuildU_srf") # Rebuild 0-1 rebuildSrf = cmds.rebuildSurface(srfU, ch=True, rpo=True, rt=0, end=1, kr=0, kcp=1, su=0, du=3, sv=0, dv=3, tol=0) rebuildSrfNode = cmds.rename(rebuildSrf[1], prefix + "_rebuildU_rebuildSurface") # Add Control Attributes cmds.addAttr(srfU, ln="lockLength", min=0, max=1, dv=1, k=True) cmds.addAttr(srfU, ln="lengthBias", min=0, max=1, dv=0, k=True) for crv in crvU: cmds.connectAttr(srfU + ".lockLength", crv + ".lockLength", f=True) cmds.connectAttr(srfU + ".lengthBias", crv + ".lengthBias", f=True) # ============= # - Rebuild V - # ============= crvV = [] for i in range(spansV + 1): # Duplicate Surface Curve dupCurve = cmds.duplicateCurve(srfU + ".v[" + str(incV * i) + "]", ch=True, rn=False, local=False) dupCurveNode = cmds.rename(dupCurve[1], prefix + "_spanV" + str(i) + "_duplicateCurve") dupCurve = cmds.rename(dupCurve[0], prefix + "_spanV" + str(i) + "_crv") crvV.append(dupCurve) # Set Curve Length arcLen = cmds.arclen(dupCurve) setLen = cmds.createNode("setCurveLength", n=prefix + "_spanV" + str(i) + "_setCurveLength") crvInfo = cmds.createNode("curveInfo", n=prefix + "_spanV" + str(i) + "_curveInfo") blendLen = cmds.createNode("blendTwoAttr", n=prefix + "_spanV" + str(i) + "length_blendTwoAttr") cmds.addAttr(dupCurve, ln="targetLength", dv=arcLen, k=True) cmds.connectAttr(dupCurveNode + ".outputCurve", crvInfo + ".inputCurve", f=True) cmds.connectAttr(dupCurveNode + ".outputCurve", setLen + ".inputCurve", f=True) cmds.connectAttr(crvInfo + ".arcLength", blendLen + ".input[0]", f=True) cmds.connectAttr(dupCurve + ".targetLength", blendLen + ".input[1]", f=True) cmds.connectAttr(blendLen + ".output", setLen + ".length", f=True) cmds.connectAttr(setLen + ".outputCurve", dupCurve + ".create", f=True) # Add Control Attribute cmds.addAttr(dupCurve, ln="lockLength", min=0, max=1, dv=1, k=True) cmds.addAttr(dupCurve, ln="lengthBias", min=0, max=1, dv=0, k=True) cmds.connectAttr(dupCurve + ".lockLength", blendLen + ".attributesBlender", f=True) cmds.connectAttr(dupCurve + ".lengthBias", setLen + ".bias", f=True) # Loft New Surface srfV = cmds.loft(crvV, ch=True, uniform=True, close=False, autoReverse=False, degree=3) srfVloft = cmds.rename(srfV[1], prefix + "_rebuildV_loft") srfV = cmds.rename(srfV[0], prefix + "_rebuildV_srf") # Rebuild 0-1 rebuildSrf = cmds.rebuildSurface(srfV, ch=True, rpo=True, rt=0, end=1, kr=0, kcp=1, su=0, du=3, sv=0, dv=3, tol=0) rebuildSrfNode = cmds.rename(rebuildSrf[1], prefix + "_rebuildV_rebuildSurface") # Add Control Attribute cmds.addAttr(srfV, ln="lockLength", min=0, max=1, dv=1, k=True) cmds.addAttr(srfV, ln="lengthBias", min=0, max=1, dv=0, k=True) for crv in crvV: cmds.connectAttr(srfV + ".lockLength", crv + ".lockLength", f=True) cmds.connectAttr(srfV + ".lengthBias", crv + ".lengthBias", f=True) # =================== # - Build Hierarchy - # =================== rebuildUGrp = cmds.group(em=True, n=prefix + "_rebuildU_grp") cmds.parent(crvU, rebuildUGrp) cmds.parent(srfU, rebuildUGrp) rebuildVGrp = cmds.group(em=True, n=prefix + "_rebuildV_grp") cmds.parent(crvV, rebuildVGrp) cmds.parent(srfV, rebuildVGrp) rebuildGrp = cmds.group(em=True, n=prefix + "_lockLength_grp") cmds.parent(rebuildUGrp, rebuildGrp) cmds.parent(rebuildVGrp, rebuildGrp) # ================= # - Return Result - # ================= return rebuildGrp
def build(attachments=4, sections=9, sectionsSpans=8, minRadius=0.0, maxRadius=1.0, startPt=[0.0, 0.0, 6.0], endPt=[0.0, 0.0, -6.0], prefix='muscle'): """ Build muscle primitive based on the input argument values between the start and end points @param attachments: Number of attachments points @type attachments: int @param sections: Number of profile curves @type sections: int @param sectionSpans: Number of spans for profile curves @type sectionSpans: int @param minRadius: Minimum radius for muscle profile curves @type minRadius: float @param maxRadius: Maximum radius for muscle profile curves @type maxRadius: float @param startPt: Start point of the muscle @type startPt: list @param endPt: End point of the muscle @type endPt: list @param prefix: Name prefix for muscle primitive @type prefix: str @return: Muscle mesh @returnType: str """ # Checks # Get start, end and distance values startPoint = glTools.utils.base.getMPoint(startPt) endPoint = glTools.utils.base.getMPoint(endPt) startEndOffset = endPoint - startPoint startEndDist = startEndOffset.length() startEndInc = startEndDist / (attachments - 1) # Calculate attachment point positions attachPoints = [] for i in range(attachments): attachPoints.append(startPoint + (startEndOffset.normal() * startEndInc * i)) # Start Tangent if not i: attachPoints.append(startPoint + (startEndOffset.normal() * startEndInc * 0.5)) # End Tangent if i == (attachments - 2): attachPoints.append(startPoint + (startEndOffset.normal() * startEndInc * (i + 0.5))) attachPts = [[pt.x, pt.y, pt.z] for pt in attachPoints] # Resize attachments value to accomodate for tangent points attachments = len(attachPts) # ------------------------ # - Build base hierarchy - # ------------------------ # Create groups muscleGrp = cmds.createNode('transform', n=prefix + '_group') muscleAttachGrp = cmds.createNode('transform', n=prefix + '_attachment_group') muscleProfileGrp = cmds.createNode('transform', n=prefix + '_profile_group') # Build hierarchy cmds.parent(muscleAttachGrp, muscleGrp) cmds.parent(muscleProfileGrp, muscleGrp) # ---------------------- # - Build Muscle Curve - # ---------------------- # Build muscle base curve muscleCurve = cmds.rename(cmds.curve(d=1, p=attachPts, k=range(len(attachPts))), prefix + '_curve') cmds.rebuildCurve(muscleCurve, ch=0, rpo=1, rt=0, end=1, kr=0, kcp=1, kep=1, kt=1, s=0, d=1) muscleCurveShape = cmds.listRelatives(muscleCurve, s=True)[0] cmds.parent(muscleCurve, muscleAttachGrp) # Add muscle attributes cmds.addAttr(muscleCurve, ln='muscle', at='message') cmds.addAttr(muscleCurve, ln='muscleObjectType', dt='string') cmds.setAttr(muscleCurve + '.muscleObjectType', 'spline', type='string', l=True) # Connect curve to attachment locators attachLocators = glTools.utils.curve.locatorCurve(muscleCurve, locatorScale=0.1, freeze=False, prefix=prefix) # Rename attachment locators and add muscle attibutes for i in range(len(attachLocators)): # Add muscle attibutes cmds.addAttr(attachLocators[i], ln='muscle', at='message') cmds.addAttr(attachLocators[i], ln='muscleObjectType', dt='string') cmds.setAttr(attachLocators[i] + '.muscleObjectType', 'attachment', type='string', l=True) # Rename attachment locators if not i: attachLocators[i] = cmds.rename(attachLocators[i], prefix + '_attachStart_locator') elif i == 1: attachLocators[i] = cmds.rename(attachLocators[i], prefix + '_attachStartTangent_locator') cmds.setAttr(attachLocators[i] + '.muscleObjectType', l=False) cmds.setAttr(attachLocators[i] + '.muscleObjectType', 'attachmentTangent', type='string', l=True) elif i == (attachments - 2): attachLocators[i] = cmds.rename(attachLocators[i], prefix + '_attachEndTangent_locator') cmds.setAttr(attachLocators[i] + '.muscleObjectType', l=False) cmds.setAttr(attachLocators[i] + '.muscleObjectType', 'attachmentTangent', type='string', l=True) elif i == (attachments - 1): attachLocators[i] = cmds.rename(attachLocators[i], prefix + '_attachEnd_locator') else: attachLocators[i] = cmds.rename(attachLocators[i], prefix + '_attachMid' + str(i - 1) + '_locator') # Group attachment locators attachLocGroup = [] [attachLocGroup.append(glTools.utils.base.group(loc)) for loc in attachLocators] cmds.parent(attachLocGroup, muscleAttachGrp) # Create spline rebuild curve splineCurve = cmds.rebuildCurve(muscleCurve, ch=1, rpo=0, rt=0, end=1, kr=0, kcp=0, kep=1, kt=1, s=5, d=3) splineRebuild = cmds.rename(splineCurve[1], prefix + '_spline_rebuildCurve') splineCurveShape = cmds.rename(cmds.listRelatives(splineCurve[0], s=True)[0], prefix + '_spline_curveShape') cmds.parent(splineCurveShape, muscleCurve, s=True, r=True) cmds.delete(splineCurve[0]) # Create tangent rebuild curve tangentCurve = cmds.rebuildCurve(muscleCurve, ch=1, rpo=0, rt=0, end=1, kr=0, kcp=0, kep=1, kt=1, s=2, d=3) tangentRebuild = cmds.rename(tangentCurve[1], prefix + '_tangent_rebuildCurve') tangentCurveShape = cmds.rename(cmds.listRelatives(tangentCurve[0], s=True)[0], prefix + '_tangent_curveShape') cmds.parent(tangentCurveShape, muscleCurve, s=True, r=True) cmds.delete(tangentCurve[0]) # Create curve visibility attributes cmds.addAttr(muscleCurve, ln='attachment', at='enum', en='Off:On:') cmds.setAttr(muscleCurve + '.attachment', k=False, cb=True) cmds.connectAttr(muscleCurve + '.attachment', muscleCurveShape + '.v') cmds.addAttr(muscleCurve, ln='spline', at='enum', en='Off:On:') cmds.setAttr(muscleCurve + '.spline', k=False, cb=True) cmds.connectAttr(muscleCurve + '.spline', splineCurveShape + '.v') cmds.addAttr(muscleCurve, ln='tangent', at='enum', en='Off:On:') cmds.setAttr(muscleCurve + '.tangent', k=False, cb=True) cmds.connectAttr(muscleCurve + '.tangent', tangentCurveShape + '.v') cmds.setAttr(muscleCurve + '.attachment', 0) cmds.setAttr(muscleCurve + '.spline', 1) cmds.setAttr(muscleCurve + '.tangent', 1) # Setup start tangent toggle cmds.addAttr(attachLocators[0], ln='tangentControl', at='enum', en='Off:On:') cmds.setAttr(attachLocators[0] + '.tangentControl', k=False, cb=True) cmds.connectAttr(attachLocators[0] + '.tangentControl', attachLocGroup[1] + '.v', f=True) startTangentBlend = cmds.createNode('blendColors', n=prefix + '_startTangent_blendColors') cmds.connectAttr(attachLocators[1] + '.worldPosition[0]', startTangentBlend + '.color1', f=True) cmds.connectAttr(attachLocators[2] + '.worldPosition[0]', startTangentBlend + '.color2', f=True) cmds.connectAttr(attachLocators[0] + '.tangentControl', startTangentBlend + '.blender', f=True) cmds.connectAttr(startTangentBlend + '.output', muscleCurve + '.controlPoints[1]', f=True) # Setup end tangent toggle cmds.addAttr(attachLocators[-1], ln='tangentControl', at='enum', en='Off:On:') cmds.setAttr(attachLocators[-1] + '.tangentControl', k=False, cb=True) cmds.connectAttr(attachLocators[-1] + '.tangentControl', attachLocGroup[-2] + '.v', f=True) endTangentBlend = cmds.createNode('blendColors', n=prefix + '_endTangent_blendColors') cmds.connectAttr(attachLocators[-2] + '.worldPosition[0]', endTangentBlend + '.color1', f=True) cmds.connectAttr(attachLocators[-3] + '.worldPosition[0]', endTangentBlend + '.color2', f=True) cmds.connectAttr(attachLocators[-1] + '.tangentControl', endTangentBlend + '.blender', f=True) cmds.connectAttr(endTangentBlend + '.output', muscleCurve + '.controlPoints[' + str(attachments - 2) + ']', f=True) # ------------------------------- # - Build Muscle Profile Curves - # ------------------------------- # Initialize profile list profileList = [] profileGrpList = [] profileFollowList = [] # Iterate through profiles profileInc = 1.0 / (sections - 1) for i in range(sections): # Create profile curve profile = cmds.circle(ch=0, c=(0, 0, 0), nr=(0, 0, 1), sw=360, r=1, d=3, ut=0, tol=0.01, s=sectionsSpans, n=prefix + '_profile' + str(i + 1) + '_curve')[0] profileList.append(profile) # Add muscle profile attribute cmds.addAttr(profile, ln='muscle', at='message') cmds.addAttr(profile, ln='muscleObjectType', dt='string') cmds.setAttr(profile + '.muscleObjectType', 'profile', type='string', l=True) # Group profile curve profileGrp = glTools.utils.base.group(profile) profileGrpList.append(profileGrp) # Skip start/end profiles if (not i) or (i == (sections - 1)): continue # Add curve parameter attribute cmds.addAttr(profile, ln='uValue', min=0.0, max=1.0, dv=profileInc * i) cmds.setAttr(profile + '.uValue', k=False, cb=True) # Create profile pointOnCurveInfo node profileCurveInfo = cmds.createNode('pointOnCurveInfo', n=prefix + '_profile' + str(i + 1) + '_pointOnCurveInfo') # Attach profile group to point on muscle spline curve cmds.connectAttr(splineCurveShape + '.worldSpace[0]', profileCurveInfo + '.inputCurve', f=True) cmds.connectAttr(profile + '.uValue', profileCurveInfo + '.parameter', f=True) cmds.connectAttr(profileCurveInfo + '.position', profileGrp + '.translate', f=True) # Create profile follow group profileFollowGrp = cmds.createNode('transform', n=prefix + '_profileFollow' + str(i + 1) + '_group') profileFollowList.append(profileFollowGrp) cmds.connectAttr(profileCurveInfo + '.position', profileFollowGrp + '.translate', f=True) cmds.parent(profileGrpList, muscleProfileGrp) cmds.parent(profileFollowList, muscleProfileGrp) # ------------------------------------ # - Create profile orientation setup - # ------------------------------------ oddProfile = sections % 2 intProfile = int(sections * 0.5) midProfile = intProfile + oddProfile intIncrement = 1.0 / intProfile # Create mid profile orientConstraint if oddProfile: midPointObject = profileFollowList[midProfile - 2] else: midPointObject = cmds.createNode('transform', n=prefix + '_midPointFollow_group') cmds.parent(midPointObject, muscleProfileGrp) midOrientCon = cmds.orientConstraint([attachLocators[0], attachLocators[-1]], midPointObject, n=prefix + '_midPoint_orientConstraint') # Create intermediate profile orientConstraints for i in range(intProfile): # Skip start/end profiles if not i: continue # Create orientConstraints startMidOriCon = cmds.orientConstraint([attachLocators[0], midPointObject], profileFollowList[i - 1])[0] endMidOriCon = cmds.orientConstraint([attachLocators[-1], midPointObject], profileFollowList[-(i)])[0] startMidOriWt = cmds.orientConstraint(startMidOriCon, q=True, weightAliasList=True) endMidOriWt = cmds.orientConstraint(endMidOriCon, q=True, weightAliasList=True) # Set constraint weights cmds.setAttr(startMidOriCon + '.' + startMidOriWt[0], 1.0 - (intIncrement * i)) cmds.setAttr(startMidOriCon + '.' + startMidOriWt[1], (intIncrement * i)) cmds.setAttr(endMidOriCon + '.' + endMidOriWt[0], 1.0 - (intIncrement * i)) cmds.setAttr(endMidOriCon + '.' + endMidOriWt[1], (intIncrement * i)) # Add constraint weight attribute to profile cmds.addAttr(profileList[i], ln='twist', min=0, max=1, dv=1.0 - (intIncrement * i), k=True) cmds.addAttr(profileList[-(i + 1)], ln='twist', min=0, max=1, dv=1.0 - (intIncrement * i), k=True) # Connect twist attribite to constraint weights startMidOriRev = cmds.createNode('reverse', n=profileList[i].replace('_curve', '_reverse')) endMidOriRev = cmds.createNode('reverse', n=profileList[-(i + 1)].replace('_curve', '_reverse')) cmds.connectAttr(profileList[i] + '.twist', startMidOriRev + '.inputX', f=True) cmds.connectAttr(profileList[i] + '.twist', startMidOriCon + '.' + startMidOriWt[0], f=True) cmds.connectAttr(startMidOriRev + '.outputX', startMidOriCon + '.' + startMidOriWt[1], f=True) cmds.connectAttr(profileList[-(i + 1)] + '.twist', endMidOriRev + '.inputX', f=True) cmds.connectAttr(profileList[-(i + 1)] + '.twist', endMidOriCon + '.' + endMidOriWt[0], f=True) cmds.connectAttr(endMidOriRev + '.outputX', endMidOriCon + '.' + endMidOriWt[1], f=True) # Create Profile tangent constraints tangentConList = [] for i in range(len(profileGrpList)): # Determine world up object if not i: # start profile worldUpObject = attachLocators[0] elif i == (len(profileGrpList) - 1): # end profile worldUpObject = attachLocators[-1] else: worldUpObject = profileFollowList[i - 1] # Create constraint tangentCon = cmds.tangentConstraint(tangentCurveShape, profileGrpList[i], aim=[0, 0, -1], u=[0, 1, 0], wu=[0, 1, 0], wut='objectrotation', wuo=worldUpObject) tangentConList.append(tangentCon) # ----------------------------- # - Set profile radius values - # ----------------------------- # Set default profile radius values radiusList = glTools.utils.mathUtils.distributeValue(midProfile, rangeStart=minRadius, rangeEnd=maxRadius) radiusList = [glTools.utils.mathUtils.smoothStep(i, minRadius, maxRadius, 0.5) for i in radiusList] for i in range(midProfile): cmds.setAttr(profileList[i] + '.scale', radiusList[i], radiusList[i], radiusList[i]) cmds.setAttr(profileList[-(i + 1)] + '.scale', radiusList[i], radiusList[i], radiusList[i]) # ---------------------------- # - Generate Muscle Geometry - # ---------------------------- # Loft mesh between profile curves loft = cmds.loft(profileList, u=0, c=0, d=3, ch=1, po=1) muscleMesh = cmds.rename(loft[0], prefix) muscleLoft = cmds.rename(loft[1], prefix + '_loft') muscleTess = cmds.listConnections(muscleLoft + '.outputSurface', s=False, d=True, type='nurbsTessellate')[0] muscleTess = cmds.rename(muscleTess, prefix + '_nurbsTessellate') cmds.parent(muscleMesh, muscleGrp) # Set nurbsTessellate settings cmds.setAttr(muscleTess + '.format', 2) cmds.setAttr(muscleTess + '.polygonType', 1) cmds.setAttr(muscleTess + '.uType', 1) cmds.setAttr(muscleTess + '.vType', 1) cmds.setAttr(muscleTess + '.uNumber', 20) cmds.setAttr(muscleTess + '.vNumber', 10) # Add muscle mesh attributes cmds.addAttr(muscleMesh, ln='precision', at='long', min=1, dv=5) cmds.setAttr(muscleMesh + '.precision', k=False, cb=True) cmds.addAttr(muscleMesh, ln='tangentPrecision', at='long', min=1, dv=2) cmds.setAttr(muscleMesh + '.tangentPrecision', k=False, cb=True) cmds.addAttr(muscleMesh, ln='uDivisions', at='long', min=4, dv=20) cmds.setAttr(muscleMesh + '.uDivisions', k=False, cb=True) cmds.addAttr(muscleMesh, ln='vDivisions', at='long', min=3, dv=10) cmds.setAttr(muscleMesh + '.vDivisions', k=False, cb=True) cmds.addAttr(muscleMesh, ln='restLength', at='float', min=0, dv=startEndDist) cmds.setAttr(muscleMesh + '.restLength', k=False, cb=True) cmds.addAttr(muscleMesh, ln='currentLength', at='float', min=0, dv=startEndDist) cmds.setAttr(muscleMesh + '.currentLength', k=True) cmds.addAttr(muscleMesh, ln='lengthScale', at='float', min=0, dv=1) cmds.setAttr(muscleMesh + '.lengthScale', k=True) cmds.addAttr(muscleMesh, ln='muscleMessage', at='message') cmds.addAttr(muscleMesh, ln='muscleSpline', at='message') cmds.addAttr(muscleMesh, ln='attachment', at='message', m=True) cmds.addAttr(muscleMesh, ln='profile', at='message', m=True) cmds.addAttr(muscleMesh, ln='muscleObjectType', dt='string') cmds.setAttr(muscleMesh + '.muscleObjectType', 'geo', type='string', l=True) # Connect muscle mesh attributes cmds.connectAttr(muscleCurve + '.message', muscleMesh + '.muscleSpline', f=True) for i in range(len(attachLocators)): cmds.connectAttr(attachLocators[i] + '.message', muscleMesh + '.attachment[' + str(i) + ']', f=True) cmds.connectAttr(muscleMesh + '.message', attachLocators[i] + '.muscle', f=True) for i in range(len(profileList)): cmds.connectAttr(profileList[i] + '.message', muscleMesh + '.profile[' + str(i) + ']', f=True) cmds.connectAttr(muscleMesh + '.message', profileList[i] + '.muscle', f=True) # Connect muscle mesh attributes to curve rebuild settings cmds.connectAttr(muscleMesh + '.precision', splineRebuild + '.spans', f=True) musclePreCondition = cmds.createNode('condition', n=prefix + '_precision_condition') cmds.setAttr(musclePreCondition + '.operation', 4) # Less Than cmds.connectAttr(muscleMesh + '.precision', musclePreCondition + '.firstTerm', f=True) cmds.connectAttr(muscleMesh + '.tangentPrecision', musclePreCondition + '.secondTerm', f=True) cmds.connectAttr(muscleMesh + '.precision', musclePreCondition + '.colorIfTrueR', f=True) cmds.connectAttr(muscleMesh + '.tangentPrecision', musclePreCondition + '.colorIfFalseR', f=True) cmds.connectAttr(musclePreCondition + '.outColorR', tangentRebuild + '.spans', f=True) # Connect musle mesh attributes to nurbsTessellate settings cmds.connectAttr(muscleMesh + '.uDivisions', muscleTess + '.uNumber', f=True) cmds.connectAttr(muscleMesh + '.vDivisions', muscleTess + '.vNumber', f=True) # Setup length calculation muscleLenCurveInfo = cmds.createNode('curveInfo', n=prefix + '_length_curveInfo') cmds.connectAttr(splineCurveShape + '.worldSpace[0]', muscleLenCurveInfo + '.inputCurve', f=True) cmds.connectAttr(muscleLenCurveInfo + '.arcLength', muscleMesh + '.currentLength', f=True) muscleLenDiv = cmds.createNode('multiplyDivide', n=prefix + '_length_multiplyDivide') cmds.setAttr(muscleLenDiv + '.operation', 2) # Divide cmds.setAttr(muscleLenDiv + '.input1', 1, 1, 1) cmds.setAttr(muscleLenDiv + '.input2', 1, 1, 1) cmds.connectAttr(muscleLenCurveInfo + '.arcLength', muscleLenDiv + '.input1X', f=True) cmds.connectAttr(muscleMesh + '.restLength', muscleLenDiv + '.input2X', f=True) cmds.connectAttr(muscleLenDiv + '.outputX', muscleMesh + '.lengthScale', f=True) # ----------- # - Cleanup - # ----------- # Parent start/end tangent locators cmds.parent(attachLocGroup[1], attachLocators[0]) cmds.parent(attachLocGroup[-2], attachLocators[-1]) # Parent start/end profiles cmds.parent(profileGrpList[0], attachLocators[0]) cmds.setAttr(profileGrpList[0] + '.t', 0.0, 0.0, 0.0) cmds.setAttr(profileGrpList[0] + '.r', 0.0, 0.0, 0.0) cmds.setAttr(profileGrpList[0] + '.s', 1.0, 1.0, 1.0) cmds.parent(profileGrpList[-1], attachLocators[-1]) cmds.setAttr(profileGrpList[-1] + '.t', 0.0, 0.0, 0.0) cmds.setAttr(profileGrpList[-1] + '.r', 0.0, 0.0, 0.0) cmds.setAttr(profileGrpList[-1] + '.s', 1.0, 1.0, 1.0) # Setup start/end profile scale compensation attachStartScaleCompNode = cmds.createNode('multiplyDivide', n=prefix + '_attachStart_multiplyDivide') cmds.setAttr(attachStartScaleCompNode + '.input1', 1, 1, 1) cmds.setAttr(attachStartScaleCompNode + '.operation', 2) cmds.connectAttr(attachLocators[0] + '.scale', attachStartScaleCompNode + '.input2', f=True) cmds.connectAttr(attachStartScaleCompNode + '.output', profileGrpList[0] + '.scale', f=True) attachEndScaleCompNode = cmds.createNode('multiplyDivide', n=prefix + '_attachEnd_multiplyDivide') cmds.setAttr(attachEndScaleCompNode + '.input1', 1, 1, 1) cmds.setAttr(attachEndScaleCompNode + '.operation', 2) cmds.connectAttr(attachLocators[-1] + '.scale', attachEndScaleCompNode + '.input2', f=True) cmds.connectAttr(attachEndScaleCompNode + '.output', profileGrpList[-1] + '.scale', f=True) # Lock transforms cmds.setAttr(muscleGrp + '.inheritsTransform', 0) cmds.setAttr(muscleGrp + '.t', l=True, cb=True) cmds.setAttr(muscleGrp + '.r', l=True, cb=True) cmds.setAttr(muscleGrp + '.s', l=True, cb=True) # Return result return muscleMesh