示例#1
0
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
示例#2
0
 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)
示例#4
0
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)
示例#5
0
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
示例#6
0
    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!")
示例#8
0
文件: Func.py 项目: darkuress/arFace
 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')
示例#9
0
    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"])
示例#10
0
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
示例#11
0
 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
示例#13
0
文件: curve.py 项目: auqeyjf/glTools
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
示例#15
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
示例#16
0
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;  
示例#17
0
    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')
示例#18
0
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]
示例#19
0
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
示例#20
0
    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  
示例#21
0
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]
示例#22
0
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
示例#23
0
        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
示例#24
0
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
示例#25
0
文件: ribbon.py 项目: auqeyjf/glTools
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)
示例#26
0
文件: ribbon.py 项目: auqeyjf/glTools
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)
示例#27
0
文件: ribbon.py 项目: auqeyjf/glTools
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]
示例#29
0
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 )
示例#30
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
示例#31
0
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