def rig_makeJointsAlongCurve(module, curve, numJoints): '''Create joints along a curve in the same direction as the curve Args: module (string): what the name of the joint module should be curve (pm.PyNode): the curve transform to be used numJoints (int): the number of joints to be created Returns: [pm.nt.Joint]: list of joints Usage: rig_makeJointsAlongCurve("petalA", pm.ls(sl=True)[0], 15) rig_makeJointsAlongCurve("seatbeltDrive", pm.ls(sl=True)[0], 160) ''' #Creating a curve between them #pm.curve (d=1, n= 'curve_body', p=[(startPos[0],startPos[1],startPos[2]),(endPos[0],endPos[1],endPos[2])]) curve = pm.duplicate(curve)[0] pm.rebuildCurve(curve, ch=0, rpo=1, rt=0, end=1, kr=1, kcp=0, kep=1, kt=0, s=numJoints, d=1, tol=0.01) #Evenly spacing joints according to the curve joints=[] for k in range(0,numJoints+1): cvPos = pm.pointPosition( '%s.cv[%s]'%(curve,str(k)), w = 1) joints.append( pm.joint( n = '%s_0%s_JNT'%(module, str(k+1)), p = cvPos) ) #Set the rotation order for joint in joints[:-1]: joint.secondaryAxisOrient('yup', oj='xyz') pm.delete(curve) return joints
def build(self): self.joints = u.placeJointChain( startLoc = self.startLoc, endLoc = self.endLoc, numJoints = self.numJoints, parent = None, name = self.name) self.joints[0].setAttr('visibility', False) self.ikHandle, self.ikEffector, self.ikCrv = pm.ikHandle( startJoint = self.joints[0], endEffector = self.joints[-1], name = self.name + '_' + d.IK_HANDLE, solver = 'ikSplineSolver') self.ikCrv = pm.PyNode(self.ikCrv) self.ikHandle = pm.PyNode(self.ikHandle) self.ikHandle.inheritsTranform = False self.ikHandle.setAttr('visibility',False) self.ikCrv.rename(self.name + '_' + d.CURVE) self.ikCrv.setAttr('visibility',False) pm.rebuildCurve(self.ikCrv, degree = 3, spans = self.numSpans, keepRange = 0, constructionHistory = False)
def prebuild(self): temp_outputs = ["start_OUTPUT", "end_OUTPUT"] for i in xrange(self.model.how_many_jnts): temp_output = "jnt_{0}_OUTPUT".format(i) temp_outputs.append(temp_output) self.create_temporary_outputs(temp_outputs) self.guide_name = "{0}_GUIDE".format(self.model.module_name) d = 3 nb_points = self.model.how_many_ctrls - 2 if self.model.how_many_ctrls < 4: d = 3 + self.model.how_many_ctrls - 4 nb_points = 2 if self.guide_check(self.guide_name): self.guide = pmc.ls(self.guide_name)[0] if d != 2 and ( self.guide.getShape().getAttr("spans") != nb_points - 1 or self.guide.getShape().getAttr("degree") != d): self.guide = pmc.rebuildCurve(self.guide_name, rpo=0, rt=0, end=1, kr=0, kep=1, kt=0, s=(nb_points - 1), d=d, ch=0, replaceOriginal=1)[0] elif self.guide.getShape().getAttr( "spans") != nb_points - 1 or self.guide.getShape().getAttr( "degree") != d: self.guide = pmc.rebuildCurve(self.guide_name, rpo=0, rt=0, end=1, kr=0, kep=1, kt=0, s=3, d=d, ch=0, replaceOriginal=1)[0] pmc.delete(self.guide.cv[-2]) pmc.delete(self.guide.cv[1]) self.guides_grp = pmc.ls("{0}_guides".format( self.model.module_name))[0] self.guides_grp.setAttr("visibility", 1) self.view.refresh_view() pmc.select(cl=1) return self.guide = rig_lib.create_curve_guide(d=d, number_of_points=nb_points, name=self.guide_name, hauteur_curve=3) self.guides_grp = self.group_guides(self.guide) self.guide.setAttr("translate", (0, 20, 0)) self.view.refresh_view() pmc.select(cl=1)
def _createCurves(self, objs=None, axis=None, num=None): ''' Create two curves using .getTranslation() of passed in objects ''' _name = '_createCurves' pymelLogger.info('Started: %s' % _name) positions = [] for obj in objs: loc = pm.spaceLocator() pm.parentConstraint(obj, loc, mo=0) positions.append(pm.PyNode(loc).getTranslation()) pm.delete(loc) crv1 = pm.PyNode(pm.curve(p=positions, d=1)) crv2 = pm.PyNode(pm.curve(p=positions, d=1)) move = 0.05 if axis == 1: pm.move(crv1, move, r=1, moveX=1) pm.move(crv2, -move, r=1, moveX=1) elif axis == 2: pm.move(crv1, move, r=1, moveY=1) pm.move(crv2, -move, r=1, moveY=1) elif axis == 3: pm.move(crv1, move, r=1, moveZ=1) pm.move(crv2, -move, r=1, moveZ=1) pm.rebuildCurve( crv1, rt=0, s=num ) pm.rebuildCurve( crv2, rt=0, s=num ) pymelLogger.info('Ended: %s' % _name) return crv1, crv2
def curve_base(self, curve, **kwargs): super(Curve, self).curve_base(curve, **kwargs) spans = kwargs.pop('spans', 4) rebuild_type = kwargs.pop('rebuildType', 0) keep_range = kwargs.pop('keepRange', 2) curve = dataValidators.as_pymel_nodes(curve) if curve.form() == 'periodic': if spans >= 3: curve = pm.rebuildCurve(curve, rebuildType=rebuild_type, spans=spans, keepRange=keep_range, **kwargs)[0] return curve else: return None else: if spans >= 1: curve = pm.rebuildCurve(curve, rebuildType=rebuild_type, spans=spans, keepRange=keep_range, **kwargs)[0] return curve else: return None return curve
def rebuildCurve(self, spans): # Rebuild the curveNode pm.rebuildCurve(self.curveNode, rpo = 1, rt = 0, end = 1, kr = 0, kcp = 0, kep = 1, kt = 0, s = spans, d = 3, tol = 0.01) del self._cvPositions[:] for j in range (0, self.numCVs): self._cvPositions.append(pm.pointPosition(self.curveNode.cv[j], w = 1))
def trapeziumCtrlShape(name, normalDirection=[0, 0, 0], scale=1): pm.mel.eval('softSelect -sse off;') bottomSquare = pm.nurbsSquare(c=[0, 0, 0], nr=[0, 1, 0], d=1, ch=False) topSquare = pm.nurbsSquare(c=[0, 1, 0], nr=[0, 1, 0], d=1, ch=False) leftSquare = pm.nurbsSquare(c=[-0.5, 0.5, 0], nr=[1, 0, 0], d=1, ch=False) rightSquare = pm.nurbsSquare(c=[0.5, 0.5, 0], nr=[1, 0, 0], d=1, ch=False) squareList = [bottomSquare, topSquare, leftSquare, rightSquare] for square in squareList: segmentList = pm.listRelatives(square, ad=1, type='transform') pm.attachCurve(segmentList[0], segmentList[1], ch=False, rpo=True, kmk=False, m=0, bb=0, bki=False, p=0.1) pm.attachCurve(segmentList[2], segmentList[3], ch=False, rpo=True, kmk=False, m=0, bb=0, bki=False, p=0.1) pm.attachCurve(segmentList[0], segmentList[2], ch=False, rpo=True, kmk=False, m=0, bb=0, bki=False, p=0.1) pm.delete(segmentList[1:]) cubePartsShape = [pm.listRelatives(square, ad=1, type='transform')[0].getShape() for square in squareList] for shape in cubePartsShape: pm.parent(shape, cubePartsShape[0].getParent(), r=1, s=1) # scale upper Box ctrl = pm.listRelatives(bottomSquare, ad=1, type='transform')[0] pm.parent(ctrl, w=True) pm.delete(squareList) ctrlShapesList = ctrl.getShapes() for shape in ctrlShapesList: pm.rebuildCurve(shape, ch=False, rpo=True, rt=1, end=1, kr=0, kcp=False, kep=True, kt=False, s=0, d=1, tol=0.01) vertSelection = pm.select(ctrlShapesList[3].cv[0:1], ctrlShapesList[1].cv[0:3], ctrlShapesList[2].cv[0:1]) pm.scale(vertSelection, [0.5, 0.5, 0.5], r=True) allVertSelection = pm.select([shape.cv[:] for shape in ctrlShapesList]) pm.scale(allVertSelection, [4, 1, 1], r=True) pm.select(cl=True) if normalDirection[0] == 1: pm.rotate(ctrl, [90, 0, 0]) elif normalDirection[0] == -1: pm.rotate(ctrl, [-90, 0, 0]) if normalDirection[1] == 1: pm.rotate(ctrl, [0, 90, 0]) elif normalDirection[1] == -1: pm.rotate(ctrl, [0, -90, 0]) if normalDirection[2] == 1: pm.rotate(ctrl, [0, 0, 90]) elif normalDirection[2] == -1: pm.rotate(ctrl, [0, 0, -90]) pm.rename(ctrl, name) ctrl.scale.set(scale, scale, scale) common.freezeTranform(ctrl) return ctrl
def controlShapeAdaptive(controlList, geoList, ctrlSmooth=6, scaleConstant=1.5, rebuildCV=32): adaptiveShapeBuildGrp = pm.group(n='daptiveShapeBuild_GRP', em=True) geoList = pm.ls(geoList) dupliGeo = pm.duplicate(geoList) geoCombined = pm.polyUnite(dupliGeo, ch=False, name='tmpAdaptiveRef_GEO')[0] pm.parent(geoCombined, adaptiveShapeBuildGrp) ctrlList = pm.ls(controlList) for ctrl in ctrlList: ctrlShapeBuildGrp = pm.group(n=ctrl.name() + '_GRP', em=True, p=adaptiveShapeBuildGrp) dupliCtrl = pm.duplicate(ctrl, n='tmpCtrl')[0] pm.delete(pm.ls(dupliCtrl, dagObjects=True, exactType='transform')[1:]) pm.rebuildCurve(dupliCtrl, ch=False, s=rebuildCV) pm.parent(dupliCtrl, ctrlShapeBuildGrp) # extrusion extrudeCircle = pm.circle(r=0.1, ch=0)[0] pm.parent(extrudeCircle, ctrlShapeBuildGrp) motionPathNode = \ pm.ls(pm.pathAnimation(extrudeCircle, curve=dupliCtrl, fractionMode=True, follow=True, followAxis='z', upAxis='y', worldUpType='vector', worldUpVector=[0, 1, 0], inverseUp=False, inverseFront=False, bank=False))[0] pm.disconnectAttr(extrudeCircle.tx) pm.disconnectAttr(extrudeCircle.ty) pm.disconnectAttr(extrudeCircle.tz) pm.disconnectAttr(extrudeCircle.rx) pm.disconnectAttr(extrudeCircle.ry) pm.disconnectAttr(extrudeCircle.rz) pm.disconnectAttr(motionPathNode.u) pm.delete(motionPathNode) extrudedSurface = \ pm.extrude(extrudeCircle, dupliCtrl, ch=False, rn=False, po=0, et=2, ucp=0, fpt=1, upn=0, rotation=0, scale=1, rsp=1)[0] pm.parent(extrudedSurface, ctrlShapeBuildGrp) nurbsToPoly = pm.nurbsToPoly(extrudedSurface, ch=False, polygonType=1, chr=0.9) pm.parent(nurbsToPoly, ctrlShapeBuildGrp) # add deformer wrapNode = deform.wrapDeformer(dupliCtrl, nurbsToPoly) shrinkWrapNode = deform.shrinkWrapDeformer(nurbsToPoly, geoCombined) shrinkWrapNode.projection.set(4) shrinkWrapNode.targetSmoothLevel.set(ctrlSmooth) # delete history common.deleteHistory(nurbsToPoly) common.deleteHistory(dupliCtrl) pm.scale(dupliCtrl.cv[:], [scaleConstant, scaleConstant, scaleConstant]) copyShape(dupliCtrl, ctrl) pm.delete(adaptiveShapeBuildGrp)
def IK_createAveObj(cur, number, s="group"): newCur = pm.duplicate(cur, rr=1, n=cur + "_copyCurve1") curInfo = pm.arclen(cur, ch=1) ns = int(curInfo.arcLength.get()) pm.delete(curInfo) pm.rebuildCurve(newCur, ch=1, rpo=1, rt=0, end=1, kr=0, kcp=0, kep=1, kt=0, s=ns * 100, d=3, tol=0.01) allNewInfo = [] aimObj = [] p = 1.0 / float((number - 1)) prF = 0.0 if s == "position": allPoistion = [] for i in range(number): if i == number - 1: NewInfo = pm.pointOnCurve(newCur, ch=1, top=1, pr=1) else: NewInfo = pm.pointOnCurve(newCur, ch=1, top=1, pr=prF) prF += p allNewInfo.append(NewInfo) t = pm.getAttr(NewInfo + ".position") if s == "position": allPoistion.append(t) if s == "group": obj = pm.group(em=1, n=cur + "_AimGrp" + str(i + 1)) aimObj.append(obj) pm.setAttr(obj + ".translate", t) cmds.select(cl=1) pm.delete(allNewInfo, newCur) if s == "position": return allPoistion if s == "group": return aimObj
def jntOnCrv(self, numOfJnts=5, crv=None, *args): try: # if in UI mode, get number of joints from UI numOfJnts = pm.intSliderGrp(self.slider, q=True, value=True) except: pass if crv == None: try: crv = pm.ls(sl=True)[0] except: pm.warning( 'ehm_tools...JntOnCrv: Select a curve to create joints on it.' ) return None if numOfJnts < 2: pm.warning("number of joints must be greater than 1.") return None try: curveShape = crv.getShape().type() except: pm.warning("specified object is not a curve.") return None if curveShape != 'nurbsCurve': pm.warning("specified object is not a curve.") return None crv = pm.duplicate(crv)[0] pm.rebuildCurve(crv, ch=False, rpo=True, rt=0, end=1, kr=0, kcp=False, kep=True, kt=0, s=200, d=1, tol=0.01) crvShape = crv.getShape() pm.select(clear=True) segSize = 1.0 / (numOfJnts - 1) for i in range(numOfJnts): pos = crvShape.getPointAtParam(segSize * i, 'world') self.newJnts.append(pm.joint(p=pos)) pm.delete(crv)
def addCurves(self, crv_root, plane): t = getTransform(self.root) gen = curve.createCurveFromOrderedEdges gen2 = curve.createCurveFromCurve planeNode = pm.PyNode(plane.fullPathName()) # ------------------------------------------------------------------- edgeList = ["{}.e[{}]".format(plane.fullPathName(), 0)] for i in range(1, self.num_uplocs + 1): edgeList.append("{}.e[{}]".format(plane.fullPathName(), i * 2 + 1)) edgeList = [pm.PyNode(x) for x in edgeList] # upEyelid = meshNavigation.edgeRangeInLoopFromMid(edgeList, upPos, inPos, outPos) self.upCrv = gen(edgeList, planeNode.verts[1], self.getName("upperEyelid"), parent=crv_root, m=t) self.upCrv_ctl = gen(edgeList, planeNode.verts[1], self.getName("upCtl_crv"), parent=crv_root, m=t) pm.rebuildCurve(self.upCrv_ctl, s=2, rt=0, rpo=True, ch=False) # ------------------------------------------------------------------- edgeList = [] for i in reversed(range(self.num_uplocs + 1, self.num_uplocs + self.num_lowlocs + 2)): edgeList.append("{}.e[{}]".format(plane.fullPathName(), i * 2 + 1)) edgeList = [pm.PyNode(x) for x in edgeList] self.lowCrv = gen(edgeList, planeNode.verts[1], self.getName("lowerEyelid"), parent=crv_root, m=t) self.lowCrv_ctl = gen(edgeList, planeNode.verts[1], self.getName("lowCtl_crv"), parent=crv_root, m=t) pm.rebuildCurve(self.lowCrv_ctl, s=2, rt=0, rpo=True, ch=False) # ------------------------------------------------------------------- self.upBlink = gen2(self.upCrv, self.getName("upblink_crv"), nbPoints=30, parent=crv_root) self.lowBlink = gen2(self.lowCrv, self.getName("lowBlink_crv"), nbPoints=30, parent=crv_root) self.upTarget = gen2(self.upCrv, self.getName("upblink_target"), nbPoints=30, parent=crv_root) self.lowTarget = gen2(self.lowCrv, self.getName("lowBlink_target"), nbPoints=30, parent=crv_root) self.midTarget = gen2(self.lowCrv, self.getName("midBlink_target"), nbPoints=30, parent=crv_root) self.midTargetLower = gen2(self.lowCrv, self.getName("midBlinkLower_target"), nbPoints=30, parent=crv_root) rigCrvs = [self.upCrv, self.lowCrv, self.upCrv_ctl, self.lowCrv_ctl, self.upBlink, self.lowBlink, self.upTarget, self.lowTarget, self.midTarget, self.midTargetLower] for crv in rigCrvs: crv.attr("visibility").set(False)
def curveThroughPoints(name, positions=None, degree=3, bezier=0, rebuild=1): if not positions: positions = [pm.xform(p, q=1, ws=1, t=1) for p in pmc.selected()] if len(positions) < (degree + 1): return 'Please supply at least 4 points' # create the curve knots = range(len(positions) + degree - 1) crv = pm.curve(p=positions, k=knots, d=degree, name=name) if rebuild: pm.rebuildCurve(crv, ch=0, rpo=1, kr=0, kcp=1, d=degree) return crv
def create_jnts(self): guide_rebuilded = pmc.rebuildCurve(self.guide, rpo=0, rt=0, end=1, kr=0, kep=1, kt=0, s=self.model.how_many_jnts, d=1, ch=0, replaceOriginal=0)[0] if self.model.how_many_jnts == 2: pmc.delete(guide_rebuilded.cv[-2]) pmc.delete(guide_rebuilded.cv[1]) guide_rebuilded.rename("{0}_temp_rebuilded_GUIDE".format( self.model.module_name)) vertex_list = guide_rebuilded.cv[:] self.created_jnts = rig_lib.create_jnts_from_cv_list_and_return_jnts_list( vertex_list, self.model.module_name) pmc.parent(self.created_jnts[0], self.jnt_input_grp, r=0) rig_lib.change_jnt_chain_suffix(self.created_jnts[0:-1], new_suffix="SKN") pmc.delete(guide_rebuilded) self.jnts_to_skin = self.created_jnts[:-1]
def create_point_base(self, *points, **kwargs): super(DynamicHair, self).create_point_base(*points, **kwargs) self.nucleus.name_conv = self.name_conv controls_number = kwargs.pop('controls_number', None) keepRange = kwargs.pop('keepRange', 2) periodic = kwargs.pop('periodic', False) rebuildType = kwargs.pop('rebuildType', 0) ep = kwargs.pop('ep', True) curve = self.rig_create.nurbs_curve.point_base(*points, periodic=periodic, ep=ep) if controls_number: if controls_number < 4: controls_number = 4 if controls_number: # base_curve = self.rig_create.nurbs_curve.curve_base(curve, spans=controls_number, keepRange=keepRange, # rebuildType=rebuildType) base_curve = pm.rebuildCurve(curve, rebuildType=rebuildType, spans=controls_number, keepRange=keepRange)[0] else: base_curve = curve self.original_curves.append(base_curve) # self.original_curve.setParent(self.dynamics) self._create_dynamic_curve(self.original_curves[-1], **kwargs)
def createCurveRig(name, numOfControls): """ Create curve rig with selected edge loop Parameters: name: Rig name numOfControls: Number of local controls """ # Convert edges to curve rawCurve = pm.PyNode(pm.polyToCurve(n=name + '_crv', form=2, degree=1)[0]) # Create joints with rawCurve jnts = [] for cv in rawCurve.cv: pm.select(cl=True) jnts.append(pm.joint(p=cv.getPosition(space='world'), radius=0.1)) jnts = renameByPosition(name, jnts) # Rebuild curve and delete history newCrv = pm.rebuildCurve(rawCurve, spans=numOfControls - 3, degree=3)[0] pm.delete(newCrv, ch=True) # Attach cluster to the curve cvs clusters = [pm.cluster(cv)[1] for cv in newCrv.cv] clusters = renameByPosition(name, clusters, suffix='clst') locators = [] for clst in clusters: pm.select(clst, r=True) locators.append(tak_misc.locGrp()) # Cleanup outliner jntGrp = pm.group(jnts, n=name + '_jnt_grp') locGrp = pm.group(locators, n=name + '_loc_grp') pm.group(jntGrp, locGrp, newCrv, n=name + '_system_grp')
def createJntChain(self): print 'creating joint chain' jntList = [] crv = pm.ls(self.crv)[0] crv = pm.rebuildCurve(crv,rpo=1,rt=0,end=1, kr=0,kcp=0,kep=1,kt=0, s=0,d=3,tol=0)[0] numCvs = crv.getShape().numCVs() #jnt pos is calculated by sampling a closest point on crv in order to same length segments no matter the cv num and position pociNode = pm.shadingNode('pointOnCurveInfo',asUtility = 1) pociNode.turnOnPercentage.set(1) crv.getShape().worldSpace[0] >> pociNode.inputCurve tempLoc = pm.spaceLocator() pociNode.position >> tempLoc.translate segmentLength = 1.0 /( self.numJnt - 1) pm.select(cl=1) for i in range(self.numJnt): pociNode.parameter.set(i*segmentLength) jntPos = tempLoc.getTranslation(space='world') jnt = pm.joint(p=jntPos,name = self.name + '_ik_jnt_' + (str(i)).zfill(2) ) jntList.append(jnt) pm.joint(jntList[0],e=True, oj='xyz',secondaryAxisOrient='yup',ch= True,zso=True) jntList[-1].jointOrient.set([0,0,0]) pm.delete([tempLoc,pociNode]) self.jntList = jntList
def createJntChain(self): print 'creating joint chain' jntList = [] crv = pm.ls(self.crv)[0] crv = pm.rebuildCurve(crv,rpo=1,rt=0,end=1, kr=0,kcp=0,kep=1,kt=0, s=0,d=3,tol=0)[0] numCvs = crv.getShape().numCVs() #jnt pos is calculated by sampling a closest point on crv in order to same length segments no matter the cv num and position pociNode = pm.shadingNode('pointOnCurveInfo',asUtility = 1) pociNode.turnOnPercentage.set(1) crv.getShape().worldSpace[0] >> pociNode.inputCurve tempLoc = pm.spaceLocator() pociNode.position >> tempLoc.translate segmentLength = 1.0 /( self.numJnt - 1) pm.select(cl=1) for i in range(self.numJnt): pociNode.parameter.set(i*segmentLength) jntPos = tempLoc.getTranslation(space='world') jnt = pm.joint(p=jntPos,name = self.name + '_vfk_jnt_' + (str(i)).zfill(2) ) jntList.append(jnt) pm.joint(jntList[0],e=True, oj='xyz',secondaryAxisOrient='yup',ch= True,zso=True) jntList[-1].jointOrient.set([0,0,0]) pm.delete([tempLoc,pociNode]) self.jntList = jntList
def _create_curve(ctrl_selection, master_ctrl, delegate_envelope, setup_name=None): """part one of the spring creation. Creates a curve and sets the attr on the master ctrl. Also gives a new parent to the ctrl.""" curve_name = "{}_curve".format(setup_name) data_point = [] _prepare_ctrl(master_ctrl, master=True) _prepare_ctrl(delegate_envelope, delegate=True) for each in ctrl_selection: _prepare_ctrl(each, needs_parent=True) point_data = pm.xform(each, q=1, t=1, ws=1) data_point.append(point_data) if curve_name == None: curve = pm.curve(points=data_point, degree=1) else: curve = pm.curve(point=data_point, name=curve_name, degree=1) new_curve = pm.rebuildCurve( curve, degree=1, keepControlPoints=True, constructionHistory=False, keepRange=0)[0].getShape( ) # I need to rebuild the dam thing so it has a range between 0-1 return new_curve
def rebuild_curve(crvs, spans): for crv in crvs: name = crv.name() pm.rebuildCurve(crv, ch=False, rpo=True, rt=0, end=1, kr=0, kcp=0, kep=1, kt=0, s=spans, d=2, tol=0.01, name=name)
def createIk(self): #create the curve for the ik ikCrv = pm.duplicate(self.crv) ikCrv = pm.rebuildCurve(ikCrv[0], ch=0, rpo=1, rt=0, end=1, kr=0, kcp=0, kep=1, kt=0, s=self.numCtrl - 1, d=3, tol=0)[0] ikCrv.rename(self.name + '_ik_crv') self.ikCrv = ikCrv #create the ik self.ikHandle = pm.ikHandle(sj=self.ikJntList[0], ee=self.ikJntList[-1], c=ikCrv, ccv=False, sol='ikSplineSolver', name=self.name + '_crv_ik')[0] pm.select(cl=1) pm.parent(self.ikHandle, self.mainGrp) pm.parent(self.ikCrv, self.mainGrp) pm.select(cl=1)
def create_jnts(self): guide_rebuilded = pmc.rebuildCurve(self.guides[1], rpo=0, rt=0, end=1, kr=0, kep=1, kt=0, s=self.model.how_many_jnts, d=1, ch=0, replaceOriginal=0)[0] if self.model.how_many_jnts == 2: pmc.delete(guide_rebuilded.cv[-2]) pmc.delete(guide_rebuilded.cv[1]) guide_rebuilded.rename("{0}_temp_rebuilded_GUIDE".format(self.model.module_name)) vertex_list = guide_rebuilded.cv[:] self.created_spine_jnts = rig_lib.create_jnts_from_cv_list_and_return_jnts_list(vertex_list, self.model.module_name, forward_axis="z") pmc.parent(self.created_spine_jnts[0], self.jnt_input_grp, r=0) rig_lib.change_jnt_chain_suffix(self.created_spine_jnts, new_suffix="SKN") pmc.delete(guide_rebuilded) pmc.select(cl=1) self.created_pelvis_jnt = pmc.joint(p=(pmc.xform(self.guides[0], q=1, ws=1, translation=1)), n="{0}_pelvis_SKN".format(self.model.module_name)) self.created_pelvis_jnt.setAttr("rotateOrder", 2) pmc.parent(self.created_pelvis_jnt, self.jnt_input_grp) self.jnts_to_skin = self.created_spine_jnts[:] self.jnts_to_skin.append(self.created_pelvis_jnt)
def createCurveFrom(selection = pm.selected(), curve_name = 'curve'): """ Creates a curve from the position values of the selection """ def createLocs(subject): loc_align = pm.spaceLocator() pm.matchTransform(loc_align,subject, rot=True, pos=True) return loc_align starting_locs = [createLocs(x) for x in selection] pos = [pm.xform(x, ws=True, q=True, t=True) for x in starting_locs] knot = [] for i in range(len(selection)): knot.append(i) _curve = pm.curve(p = pos, k =knot, d=1, n=curve_name) pm.rebuildCurve(_curve, rt=0, ch=0, end=1, d=3, kr=0, s=len(selection), kcp=0, tol=0.1, kt=0, rpo=1, kep=1) pm.delete(starting_locs) return(_curve)
def evenly_spaced_crv(self, *args): """ Rebuilds selected curve number of cv's based on jntNumSlider Args: None Returns (None) """ crv_name = self.crvNameField.getText() new_crv_name = self.jntNameFeild.getText() + '_CRV' num_crv_cvs = self.jntNumSlider.getValue() -1 if pm.objExists( crv_name ): crv = pm.PyNode( crv_name ) pm.rebuildCurve( crv, rt=0, s=num_crv_cvs, kep=True, ch=True ) pm.delete( crv.getShape().cv[1] ) pm.delete( crv.getShape().cv[-2] ) self.model.refresh_curve() pm.rename(crv_name, new_crv_name)
def curve_base(self, *args, **kwargs): control_points = kwargs.pop('control_points', None) if not self.node: self.point_base(*args, **kwargs) dynamic_curve_base = args[0] new_motion = self.motion_path.node_base(self.transform, curve=args[0]) pm.delete(new_motion) if not control_points: rebuild_curve = pm.rebuildCurve(dynamic_curve_base, constructionHistory=True, replaceOriginal=0, rebuildType=0, endKnots=1, keepRange=0, keepControlPoints=1, keepEndPoints=1, keepTangents=0, spans=0, degree=1, tolerance=0.1)[0] else: rebuild_curve = pm.rebuildCurve(dynamic_curve_base, constructionHistory=True, replaceOriginal=0, rebuildType=0, endKnots=0, keepRange=0, keepControlPoints=0, keepEndPoints=0, keepTangents=1, spans=control_points, degree=1, tolerance=0.1)[0] shapes = rebuild_curve.getShapes() shapes[0].intermediateObject.set(True) pm.parent(shapes, dynamic_curve_base, r=True, s=True) shapes[0].local >> self.node.startPosition dynamic_curve_base.worldMatrix >> self.node.startPositionMatrix pm.parent(args[0], self.transform) pm.delete(rebuild_curve) self.create_output_curve() return self._node, self.output_curve
def create(self, curveType, spans, selOnly): sel = pm.selected() cmds.CreateCurveFromPoly() curve = pm.selected() pm.rebuildCurve(curve, spans=spans) # set UI curve self.uiObj.setCurrentCurve(curve[0].shortName()) if curveType == 1: pm.nurbsCurveToBezier() pm.delete(curve, ch=True) # Deform if selOnly: sel = pm.polyListComponentConversion(sel, fe=True, tv=True) self.wire = pm.wire(sel, w=curve) else: #Object self.wire = pm.wire(sel[0].node(), w=curve)
def makeNiceCurveFromEdges(sel, symVec=None, numSpans=None): """Take selection of poly edges and turn into nice nurbs curve with seam along axis of sym (if relevant)""" # how many spans? if not numSpans: # clamp it to 1-8; over 8 is excessive and numSpans arg of 0 is ignored #numSpans = max(1, min(8, (len(sel) / 8) * 2)) numSpans = max(1, min(8, len(sel) / 4)) # form 2 is "best guess", pretty reliable for # distinguishing periodic vs open crv = pmc.PyNode(pmc.polyToCurve(dg=3, f=2, ch=0)[0]) pmc.xform(crv, centerPivots=True) if symVec and crv.form() != "open": # move seam to along axis, so that # rebuilding the curve doesn't result in unexpected asymmetry intPt = getMirrorParam(crv, symVec) # IF it actually crosses the axis try: intPt = float(intPt.split(" ")[0]) pmc.select(crv.u[intPt]) pmc.mel.eval("moveNurbsCurveSeam") except (AttributeError, pmc.MelError): # AttributeError means there is no good mnirror seam. # could be intentional, so no warning. # MelError means seam is already at the best point. pass # rebuilding surface instead of curve keeps weird all-0-cv bugs away # # try rebuild curve instead of surface to help w/ recurring asym issue # or wait wasn't that solved by kc=0? # pmc.rebuildCurve(crv, rebuildType=0, keepRange=0, spans=numSpans, ch=0, rpo=True) return crv
def rigIk(self): crvPoints = [] for jnt in self.spineIkJnt: pos = jnt.getTranslation(space='world') crvPoints.append(pos) ikCrv = pm.curve(n='spine_ikSpline_Crv', d=1, p=crvPoints) ikCrv = pm.rebuildCurve(ikCrv, rpo=1, rt=0, end=1, kr=0, kcp=1, kep=1, kt=0, d=3, tol=0)[0] self.spineIkHandle = pm.ikHandle(sj=self.spineIkJnt[0], ee=self.spineIkJnt[-1], c=ikCrv, ccv=False, sol='ikSplineSolver', name='spine_ikSpline')[0]
def curveThroughPoints(positions=None, name='', degree=3, bezier=0, rebuild=1): if not positions: positions = [pmc.xform(p, q=1, ws=1, t=1) for p in pmc.selected()] if len(positions) < (degree + 1): return 'Please supply at least 4 points' # create the curve numKnots = degree + len(positions) - 1 knots = [0 for i in range(degree)] for i in range(numKnots - (degree * 2)): knots.append(i + 1) knotsMax = knots[-1] for i in range(degree): knots.append(knotsMax + 1) crv = pmc.curve(p=positions, k=knots, d=degree, name='%s_CRV' % name) if rebuild: pmc.rebuildCurve(crv, ch=0, rpo=1, kr=0, kcp=1, d=degree) return crv
def prebuild(self): temp_outputs = ["pelvis_OUTPUT", "start_OUTPUT", "end_OUTPUT"] for i in xrange(self.model.how_many_jnts): temp_output = "jnt_{0}_OUTPUT".format(i) temp_outputs.append(temp_output) self.create_temporary_outputs(temp_outputs) self.guide_names = ["{0}_pelvis_GUIDE".format(self.model.module_name), "{0}_spine_GUIDE".format(self.model.module_name)] d = 3 nb_points = self.model.how_many_ctrls - 2 if self.model.how_many_ctrls < 4: d = 3 + self.model.how_many_ctrls - 4 nb_points = 2 if self.guide_check(self.guide_names): self.guides = pmc.ls(self.guide_names) if d != 2 and (self.guides[1].getShape().getAttr("spans") != nb_points - 1 or self.guides[1].getShape().getAttr("degree") != d): self.guides[1] = pmc.rebuildCurve(self.guide_names[1], rpo=0, rt=0, end=1, kr=0, kep=1, kt=0, s=(nb_points - 1), d=d, ch=0, replaceOriginal=1)[0] elif self.guides[1].getShape().getAttr("spans") != nb_points - 1 or self.guides[1].getShape().getAttr("degree") != d: self.guides[1] = pmc.rebuildCurve(self.guide_names[1], rpo=0, rt=0, end=1, kr=0, kep=1, kt=0, s=3, d=d, ch=0, replaceOriginal=1)[0] pmc.delete(self.guides[1].cv[-2]) pmc.delete(self.guides[1].cv[1]) self.guides_grp = pmc.ls("{0}_guides".format(self.model.module_name))[0] self.guides_grp.setAttr("visibility", 1) self.view.refresh_view() pmc.select(cl=1) return pelvis_guides = pmc.spaceLocator(p=(0, 0, 0), n=self.guide_names[0]) spine_guide = rig_lib.create_curve_guide(d=d, number_of_points=nb_points, name=self.guide_names[1], hauteur_curve=8, front_axe="z") self.guides = [pelvis_guides, spine_guide] self.guides_grp = self.group_guides(self.guides) self.guides[0].setAttr("translate", (0, 7, -1)) self.guides[1].setAttr("translate", (0, 8, 0)) self.view.refresh_view() pmc.select(cl=1)
def createIk(self): #create the curve for the ik ikCrv = pm.duplicate(self.crv) ikCrv = pm.rebuildCurve(ikCrv[0],ch=0, rpo=1, rt=0, end=1, kr=0, kcp=0, kep=1, kt=0, s=self.numCtrl-1, d=3, tol=0)[0] ikCrv.rename(self.name + '_ik_crv') self.ikCrv = ikCrv #create the ik self.ikHandle = pm.ikHandle(sj = self.ikJntList[0], ee = self.ikJntList[-1], c=ikCrv, ccv=False, sol='ikSplineSolver',name = self.name + '_crv_ik')[0] pm.select(cl=1) pm.parent(self.ikHandle,self.mainGrp) pm.parent(self.ikCrv,self.mainGrp) pm.select(cl=1)
def jointChainToDynamicChain( nodes=[] ): if nodes: pm.select(nodes) nodes = pm.ls(sl=True) # get joints joints = pm.ls(sl=True, type='joint') if not joints: raise crv = findSplineIKCrv( joints )[0] hdl = findIKHandle( joints )[0] pocs = crv.getShape().listHistory( future=True, type='pointOnCurveInfo' ) # # makeDymicChain # outputCurve, follicle, hairSystem, nucleus = makeCurvesDynamic( crv ) # # ์ผ์ ๊ฐ๊ฒฉ ์ ์ง๋ฅผ ์ํด ์ปค๋ธ ๋ฆฌ๋น๋ # rdbCrv, rbd = pm.rebuildCurve( outputCurve, ch=True, replaceOriginal=False, rebuildType=0, # uniform endKnots=1, # 0 - uniform end knots, 1 - multiple end knots keepRange=0, # 0 - reparameterize the resulting curve from 0 to 1, 1 - keep the original curve parameterization, 2 - reparameterize the result from 0 to number of spans keepControlPoints=False, keepEndPoints=True, keepTangents=True, spans=100, degree=3, tol=0.001 ) # # ikํธ๋ค ์ปค๋ธ ๋ณ๊ฒฝ # pm.ikHandle( hdl, e=True, curve=outputCurve ) # # pointOnCurveInfo ๋ณ๊ฒฝ # for poc in pocs: rdbCrv.worldSpace[0] >> poc.inputCurve pm.select(outputCurve)
def rig_curve(self, selection=None): if selection is None: selection = self.curves_to_rig self.created_locs = [] self.created_ctrls = [] degree = selection.getShape().getAttr("degree") curve = pmc.rebuildCurve(selection, rpo=0, rt=0, end=1, kr=0, kep=1, kt=0, s=self.model.how_many_ctrls, d=degree, ch=0, replaceOriginal=1)[0] ik_spline_cv_list = [] for i, cv in enumerate(curve.cv): ik_spline_cv_list.append(cv) ik_spline_cv_for_ctrls = ik_spline_cv_list del ik_spline_cv_for_ctrls[1] del ik_spline_cv_for_ctrls[-2] ik_spline_controlpoints_list = [] for i, cv in enumerate(curve.controlPoints): ik_spline_controlpoints_list.append(cv) ik_spline_controlpoints_for_ctrls = ik_spline_controlpoints_list[:] del ik_spline_controlpoints_for_ctrls[1] del ik_spline_controlpoints_for_ctrls[-2] for i, cv in enumerate(ik_spline_cv_for_ctrls): cv_loc = self.create_locators(i, cv, ik_spline_controlpoints_for_ctrls, selection.name()) ctrl = self.create_ctrls(i, cv_loc, curve, selection.name()) self.created_locs.append(cv_loc) self.created_ctrls.append(ctrl) self.constrain_ikspline_tan_to_ctrls(ik_spline_controlpoints_list, curve, selection.name()) for i, ctrl in enumerate(self.created_ctrls): pmc.parent(self.created_locs[i], ctrl, r=0) curve.setAttr("translate", (0, 0, 0)) curve.setAttr("rotate", (0, 0, 0)) curve.setAttr("scale", (1, 1, 1))
def distributeCrv( transformNodes, curve=None, uniform=True ): nodes = [pm.PyNode(node) for node in transformNodes] crv = pm.PyNode(curve) crvShape = crv.getShape() nodeNums = len(nodes) contMembers = [] if uniform: rebCrv, reb = pm.rebuildCurve( crvShape, ch=True, rpo=False, rt=4, end=1, kr=0, kcp=0, kep=1, kt=0, s=4, d=3, tol=0.001 ) crvShape = rebCrv.getShapes( type='nurbsCurve' )[0] rebCrv.rename( crv+'_rebCrv' ) reb.rename( crv+'_rebuildCrv' ) contMembers.append( pm.parentConstraint( crv, rebCrv ) ) contMembers.append( pm.scaleConstraint( crv, rebCrv ) ) contMembers.append( rebCrv ) contMembers.append( reb ) unit = None if crv.form() == 'periodic': unit = (1.0/nodeNums) else: unit = (1.0/(nodeNums-1)) for i, node in enumerate( nodes ): pointOnCurve = pm.PyNode( pm.pointOnCurve( crvShape, ch=True ) ) pointOnCurve.rename( node+'_POC' ) pointOnCurve.turnOnPercentage.set(True) pointOnCurve.parameter.set( unit*i ) pointOnCurve.p >> node.t pointOnCurve.setAttr('parameter', keyable=True) contMembers.append( pointOnCurve ) cont = pm.container( type='dagContainer', addNode=contMembers, n=crv+'_distributeCrv#' ) cont.v.set(False) return cont
def createJntChains(self): print 'creating joint chains' ikJntList = [] rigJntList = [] crv = pm.ls(self.crv)[0] crv = pm.rebuildCurve(crv,rpo=1,rt=0,end=1, kr=0,kcp=0,kep=1,kt=0, s=0,d=3,tol=0)[0] numCvs = crv.getShape().numCVs() #jnt pos is calculated by sampling a closest point on crv in order to same length segments no matter the cv num and position pociNode = pm.shadingNode('pointOnCurveInfo',asUtility = 1) pociNode.turnOnPercentage.set(1) crv.getShape().worldSpace[0] >> pociNode.inputCurve tempLoc = pm.spaceLocator() pociNode.position >> tempLoc.translate segmentLength = 1.0 /( self.numJnt - 1) pm.select(cl=1) for i in range(self.numJnt): pociNode.parameter.set(i*segmentLength) jntPos = tempLoc.getTranslation(space='world') ikJnt = pm.joint(p=jntPos,name = self.name + '_ik_jnt_' + (str(i)).zfill(2) ) ikJntList.append(ikJnt) pm.joint(ikJntList[0],e=True, oj='xyz',secondaryAxisOrient='yup',ch= True,zso=True) ikJntList[-1].jointOrient.set([0,0,0]) rigJntStart = pm.duplicate(ikJntList[0],n=ikJntList[0].name().replace('ik','rig')) pm.pointConstraint(ikJntList[0],rigJntStart) rigJntList = pm.listRelatives(rigJntStart,ad=1,type='joint') rigJntList.reverse() rigJntList = [rigJntStart] + rigJntList for i in range(1,self.numJnt): rigJntList[i].rename(rigJntList[i].name().replace('ik','rig')) self.ikJntList = ikJntList self.rigJntList = rigJntList pm.delete([tempLoc,pociNode]) pm.select(cl=1)
def createJntChains(self): print 'creating joint chains' ikJntList = [] rigJntList = [] crv = pm.ls(self.crv)[0] crv = pm.rebuildCurve(crv, rpo=1, rt=0, end=1, kr=0, kcp=0, kep=1, kt=0, s=0, d=3, tol=0)[0] # jnt pos is calculated by sampling a closest point on crv in order to same length segments no matter the cv num and position pociNode = pm.shadingNode('pointOnCurveInfo', asUtility=1) pociNode.turnOnPercentage.set(1) crv.getShape().worldSpace[0] >> pociNode.inputCurve tempLoc = pm.spaceLocator() pociNode.position >> tempLoc.translate segmentLength = 1.0 / (self.numJnt - 1) pm.select(cl=1) for i in range(self.numJnt): pociNode.parameter.set(i * segmentLength) jntPos = tempLoc.getTranslation(space='world') ikJnt = pm.joint(p=jntPos, name=self.name + '_ik_jnt_' + (str(i)).zfill(2)) ikJntList.append(ikJnt) pm.joint(ikJntList[0], e=True, oj='xyz', secondaryAxisOrient='yup', ch=True, zso=True) ikJntList[-1].jointOrient.set([0, 0, 0]) rigJntStart = pm.duplicate(ikJntList[0], n=ikJntList[0].name().replace('ik', 'rig')) pm.pointConstraint(ikJntList[0], rigJntStart) rigJntList = pm.listRelatives(rigJntStart, ad=1, type='joint') rigJntList.reverse() rigJntList = [rigJntStart] + rigJntList for i in range(1, self.numJnt): rigJntList[i].rename(rigJntList[i].name().replace('ik', 'rig')) self.ikJntList = ikJntList self.rigJntList = rigJntList pm.delete([tempLoc, pociNode]) pm.select(cl=1)
def rebuild_curve(self, target, degree, cv, replace=False): target = pm.PyNode(target) spans = cv - degree rebuild = pm.rebuildCurve( target, ch = 1, replaceOriginal = replace, rebuildType = 0, endKnots = 1, keepRange = 1, keepControlPoints = 0, keepEndPoints = 1, keepTangents = 1, spans = spans, degree = degree, tolerance = 0.01, ) return(rebuild[0])
def makeCurveFromJoints(jointList, name='C_spine_crv', rebuild=True, divisions=3): tLoc = pm.spaceLocator(name="skeletonizeTemp_loc") curveStr = "curve -d 3" for i in range(0, len(jointList)): snap(jointList[i], tLoc) aTrans = pm.xform(tLoc, q=1, ws=1, t=1) curveStr += " -p " + str(aTrans[0]) + " " + str(aTrans[1]) + " " + str( aTrans[2]) curveStr += " -n " + name spineCurve = str(pm.mel.eval(curveStr)) # parent curve pm.delete(tLoc) pm.select(clear=1) if rebuild: aStr = pm.rebuildCurve(spineCurve, rt=0, ch=1, end=1, d=3, kr=0, s=divisions, kcp=0, tol=0.01, kt=0, rpo=1, kep=0) # create spine joints # pm.delete(spineCurve) spineCurve = pm.rename(aStr[0], name) return spineCurve
def create_clusters(self): self.ik_drv_crv = pm.rebuildCurve(self.ik_crv, ch=1, rpo=0, rt=0, end=1, kr=2, kcp=0, kep=1, kt=0, s=2, d=3, tol=0.01, name=self.ik_crv.name().replace( 'crv', 'drv_crv'))[0] self.ik_drv_crv.attr('v').set(0) pm.delete(self.ik_drv_crv, ch=1) wire_def = pm.wire(self.ik_crv, w=self.ik_drv_crv, en=1, gw=False, ce=0, li=0, dds=[(0, 20)], n=self.ik_crv.name() + '_wire') wire_transform = pm.listConnections( (wire_def[0].name() + '.baseWire[0]'))[0] # pm.parent(self.ik_drv_crv, self.rigGrp) # pm.parent(wire_transform , self.rigGrp) for i, cv in enumerate(['.cv[0:1]', '.cv[2]', '.cv[3:4]']): cluster = pm.cluster(self.ik_drv_crv.name() + cv) name = join_name(self.ik_crv.name(), 'cls', str(i)) cluster[1].rename(name) cluster[1].attr('v').set(0) self.clusters.append(cluster[1]) pm.parent(cluster[1], self.ik_ctrl[i])
def crvToJnt( objs=[], div=None, ep=True ): ''' update : 2015-04-27 curve, upMesh ์์ผ๋ก ์ ํํ๊ณ ์คํ div ๋ฅผ ๋ช ์ํ๋ฉด ์ผ์ ๊ฐ๊ฒฉ์ ์กฐ์ธํธ๋ฅผ ์ป์. import rig.joint as jnt jnt.crvToJnt() jnt.crvToJnt(ep=False) # ํด๋น ์์. ์ปค๋ธ cv ์์น์ ์กฐ์ธํธ๊ฐ ์๊น jnt.crvToJnt(div=10) jnt.crvToJnt(ep=True) # ํด๋น ์์. ์ปค๋ธ ep ์์น์ ์กฐ์ธํธ๊ฐ ์๊น jnt.crvToJnt(ep=False) # ํด๋น ์์. ์ปค๋ธ cv ์์น์ ์กฐ์ธํธ๊ฐ ์๊น jnt.crvToJnt(div=10, ep=True) # ํด๋น ์์. ์ปค๋ธ cv ์์น์ ์กฐ์ธํธ๊ฐ ์๊น jnt.crvToJnt(div=10, ep=False) # ํด๋น ์์. ์ปค๋ธ cv ์์น์ ์กฐ์ธํธ๊ฐ ์๊น ''' # args if objs: pm.selec(objs) objs = pm.selected() if not objs: raise curves = [pm.PyNode(c) for c in pm.filterExpand(sm=9) ] if not curves: raise upMeshs = [] if pm.filterExpand(sm=12): upMeshs = [pm.PyNode(c) for c in pm.filterExpand(sm=12) ] # ์ ์ถ์ผ๋ก ์ฌ์ฉํ ๋ฉ์ฌ node = curves[-1] nodeType = node.nodeType() #cv = True #ep = True transform = None crvShape = None if nodeType == 'nurbsCurve': crvShape = node transform = crvShape.getParent() elif nodeType == 'transform': transform = node crvShape = transform.getShapes( type='nurbsCurve' )[0] if div: rebCrv, rebuild = pm.rebuildCurve( crvShape, ch=True, rpo=False, rt=4, end=1, kr=0, kcp=0, kep=1, kt=0, s=4, d=3, tol=0.001 ) # curvature type transform = rebCrv crvShape = transform.getShapes( type='nurbsCurve' )[0] # ์์น๊ฐ ์ฑ๊น. p=[] if div: if ep: for i in range(div+1): # ์ปค๋ธ๋ฅผ ์ผ์ ํ๊ฒ ๋๋ ์์น ๊ฐ์ ๊ฐ์ ธ์ด p.append( pm.pointOnCurve( crvShape, turnOnPercentage=True, parameter=(1.0/div)*i ) ) else: rebuild.rebuildType.set(0) # uniform rebuild.spans.set(div+1) for i in range( len( rebCrv.getCVs() ) ): p.append( crvShape.cv[i].getPosition() ) else: if ep: # editPoint์ ์์น๊ฐ์ ๊ฐ์ ธ์ด for i in range( crvShape.numEPs() ): p.append( pm.xform( crvShape.ep[i], q=True, ws=True, t=True) ) else: # cv์ ์์น๊ฐ์ ๊ฐ์ ธ์ด for i in range( len( crvShape.getCVs() ) ): p.append( crvShape.cv[i].getPosition() ) if div: pm.delete( transform ) JNTs = [] pm.select(cl=True) for pos in p: JNTs.append( pm.joint( p=pos) ) # ์กฐ์ธํธ ์ค๋ฆฌ์ํธ ์กฐ์ : ๋ฉ์ฌ์ ๊ฐ์ฅ ๊ฐ๊น์ด ์ ์ ๋ ธ๋ง์ ์กฐ์ธํธ์ up์ผ๋ก ์ค์ if upMeshs: for jnt in JNTs: parentJnt = jnt.getParent() if parentJnt: # point์์ ๊ฐ์ฅ ๊ฐ๊น์ด Vertex์ Normal์ up์ผ๋ก ์ค์ pos = parentJnt.getTranslation( ws=True) vtx = getClosestVertexOnMesh( upMeshs[0], pos ) pos = vtx.getPosition() norm = vtx.getNormal() upPos = pos + norm * 1000000 # ๋ ธ๋ง ์์น๊ฐ ๊ฐ๊น์ฐ๋ฉด ๋ฐฉํฅ์ด ํ์ด์ ธ ๋ฒ๋ฆผ.. ๊ทธ๋์ ํฐ ์๋ฅผ ๊ณฑํจ. upLoc = pm.spaceLocator(n='parentJnt_upLoc#') upLoc.t.set( upPos ) jntOrient( [parentJnt, jnt, upLoc] ) #pm.joint( parentJnt, edit=True, zso=True, oj='xyz', sao='yup' ) pm.delete( upLoc ) else: for jnt in JNTs: parentJnt = jnt.getParent() if parentJnt: up = pm.spaceLocator() grandParent = parentJnt.getParent() if grandParent: pm.delete( pm.parentConstraint( grandParent, up ) ) else: pm.delete( pm.parentConstraint( parentJnt, up ) ) jntOrient( [parentJnt, jnt, up], worldUpType='objectrotation' ) pm.refresh() pm.select(jnt) pm.delete(up) # ๋ ์กฐ์ธํธ ์ค๋ฆฌ์ํธ ์กฐ์ pm.joint( JNTs[-1], edit=True, oj='none' ) pm.select( JNTs ) return JNTs
def crvToJnt( curves=[], div=None, ep=True ): ''' update : 2015-04-29 ''' # args if curves: pm.selec(curves) curves = [pm.PyNode(c) for c in pm.filterExpand(sm=9) ] if not curves: raise node = curves[-1] nodeType = node.nodeType() transform = None crvShape = None if nodeType == 'nurbsCurve': crvShape = node transform = crvShape.getParent() elif nodeType == 'transform': transform = node crvShape = transform.getShapes( type='nurbsCurve' )[0] if div: rebCrv, rebuild = pm.rebuildCurve( crvShape, ch=True, rpo=False, rt=4, end=1, kr=0, kcp=0, kep=1, kt=0, s=4, d=3, tol=0.001 ) # curvature type transform = rebCrv crvShape = transform.getShapes( type='nurbsCurve' )[0] # ์์น๊ฐ ์ฑ๊น. p=[] if div: if ep: for i in range(div+1): # ์ปค๋ธ๋ฅผ ์ผ์ ํ๊ฒ ๋๋ ์์น ๊ฐ์ ๊ฐ์ ธ์ด p.append( pm.pointOnCurve( crvShape, turnOnPercentage=True, parameter=(1.0/div)*i ) ) else: rebuild.rebuildType.set(0) # uniform rebuild.spans.set(div+1) for i in range( len( rebCrv.getCVs() ) ): p.append( crvShape.cv[i].getPosition() ) else: if ep: # editPoint์ ์์น๊ฐ์ ๊ฐ์ ธ์ด for i in range( crvShape.numEPs() ): p.append( pm.xform( crvShape.ep[i], q=True, ws=True, t=True) ) else: # cv์ ์์น๊ฐ์ ๊ฐ์ ธ์ด for i in range( len( crvShape.getCVs() ) ): p.append( crvShape.cv[i].getPosition() ) if div: pm.delete( transform ) JNTs = [] pm.select(cl=True) for pos in p: JNTs.append( pm.joint( p=pos) ) # ์กฐ์ธํธ ์ค๋ฆฌ์ํธ ๋ํดํธ pm.joint( JNTs[0], e=True, oj='xyz', secondaryAxisOrient='yup', ch=True, zso=True ) pm.select( JNTs ) return JNTs
def rig_createDynamicChain(self, topNode=None): # Returns: [DynJoints], [DynControl], Transform(DynTopNode) ''' Create dynamic joint chain ''' # Get the root locators rootLocs = pm.listRelatives('HairRig_MainCnt',children=True)[1:] # Per chain index = 0 for chainName, numJnts in zip(self.chainNames, self.chainNumJnts): index = index + 1 # Chain grp chainGrp = pm.group(n=chainName+'_dyn_grp', parent=topNode, em=True) pm.delete(pm.parentConstraint(rootLocs[index-1],chainGrp,mo=0)) # Get locator names locNames = ['%s_loc%s'%(chainName,num) for num in range(int(numJnts)) if num != 0] locNames.insert(0,'%s_rootLoc'%chainName) # Get locator positions positions = [] for loc in locNames: positions.append( pm.xform(loc,q=1,ws=1,t=1) ) # Draw dynamic joint chain dynJnts = [] pm.select(chainGrp,replace=True) for i in range(len(positions)): dynJnts.append(pm.joint(name=chainName+'_hr_dynJnt_%s'%i, p=positions[i])) # Draw curve along dynamic chain positions = [] for jnt in dynJnts: positions.append(pm.xform(jnt,q=1,ws=1,rp=1)) crv = pm.curve( name='chain%s_crv'%index, p=positions, d=1 ) pm.rebuildCurve( crv, s=5 ) pm.xform( crv, rp=positions[0], ws=True ) pm.delete( crv, ch=True ) pm.parent( crv, topNode ) # Create root nurbs plane plane = pm.nurbsPlane( name='dynPlane_%s'%index, d=3, u=2, v=2, ax=[0,-1,0] )[0] pm.move(plane, float(positions[0][0]), float(positions[0][1]), float(positions[0][2]), a=1) pm.parent( plane, chainGrp ) #Get data for current limb startJnt = pm.listRelatives( chainGrp, children=True )[0] pm.select(pm.listRelatives( chainGrp, children=True )[0], hi=True ) endJnt = pm.ls(sl=1)[-1] # Make curve dynamic pm.select( plane, r=True ) pm.select( crv, add=True ) pm.mel.eval( 'makeCurvesDynamicHairs %d %d %d' % (1, 0, 1) ) # Get names for hair system temp = pm.pickWalk( crv, d='up' ) hairSystemName = 'hairSystem%s'%index dynCrv = pm.listRelatives( '%sOutputCurves'%hairSystemName, children=True)[0] pm.rename(dynCrv,'dynCrv_%s'%index) dynCrv = 'dynCrv_%s'%index pm.parent( hairSystemName, chainGrp ) # Make ik spline using dynamic curve handle, effector = pm.ikHandle( sj=startJnt, ee=endJnt, sol='ikSplineSolver', c=dynCrv, ccv=False ) pm.parent( handle, chainGrp ) # Clean up follicle = pm.listRelatives( crv, parent=True )[0] pm.parent( crv, 'HairRig_MainCnt' ) pm.parent( follicle, chainGrp ) pm.delete( '%sOutputCurves'%hairSystemName ) pm.setAttr( '%s.visibility'%follicle, 0 ) pm.setAttr( '%s.visibility'%crv, 0 ) pm.setAttr( '%s.visibility'%dynCrv, 0 ) pm.setAttr( '%s.visibility'%handle, 0 ) pm.setAttr( '%s.visibility'%plane, 0 ) pm.setAttr( '%s.visibility'%hairSystemName, 0 ) # Create attributes on main control return dynJnts
# for each CV of curves create Locators # ========================================================================= uppLocs = locatorOnCurveCVs(size=estimatedEyeSize/5, crv=uppCurve, prefix=prefix+"_upp_lid") lowLocs = locatorOnCurveCVs(size=estimatedEyeSize/5, crv=lowCurve, prefix=prefix+"_low_lid") # aimConstraint joints to locators # ========================================================================= for jnt,loc in zip(uppJnts,uppLocs): pm.aimConstraint( loc, jnt, aimVector=(1,0,0), upVector=(0,1,0), worldUpObject=upVec, worldUpType="object" ) for jnt,loc in zip(lowJnts,lowLocs): pm.aimConstraint( loc, jnt, aimVector=(1,0,0), upVector=(0,1,0), worldUpObject=upVec, worldUpType="object" ) # lower the resolution of the curves # ========================================================================= pm.rebuildCurve(uppCurve, ch=0, rpo=1, rt=0, end=1, kr=0, kcp=0, kep=1, kt=0, s=4, d=3, tol=10) pm.rebuildCurve(lowCurve, ch=0, rpo=1, rt=0, end=1, kr=0, kcp=0, kep=1, kt=0, s=4, d=3, tol=10) # attach locators to curves # ========================================================================= for loc in uppLocs: locPos = pm.xform( loc, q=True, t=True, ws=True ) AttachToCurve( createNewLocator=False, objectToConnect=loc, worldPos=locPos, crv=uppCurve ) for loc in lowLocs: locPos = pm.xform( loc, q=True, t=True, ws=True ) AttachToCurve( createNewLocator=False, objectToConnect=loc, worldPos=locPos, crv=lowCurve ) # create control objects for each cv of the curves # ========================================================================= # control joints uppControlJnts = jointOnCurveCVs(size=estimatedEyeSize/5, crv=uppCurve, prefix=prefix+"_upp_lidControl")
def spine_pack ( self , size=5.0 , limbName='spine' , mode='biped' , numOfJnts=4 , mainCtrl=None , midCtrl=False , ss=True , stretchSwitch=True , volume=True , numOfFKctrl=None , numOfSpans=3 , *args ): try:# if in UI mode, get number of joints from UI size = pm.floatSliderGrp( self.spineSizeF, q=True, value=True) limbName = pm.textField( self.limbNameTF, q=True, text=True) selectedMode = pm.radioCollection( self.characterModeRC, q=True, select=True) mode = pm.radioButton( selectedMode, q=True, label=True ).lower() numOfJnts = pm.intSliderGrp( self.numOfJntsIS, q=True, value=True) numOfFKctrl = pm.intSliderGrp( self.numOfFKctrlIS, q=True, value=True ) ss = pm.checkBox( self.ssCB, q=True, value=True ) volume = pm.checkBox( self.volumeCB, q=True, value=True ) stretchSwitch = pm.checkBox( self.stretchSwitchCB, q=True, value=True ) midCtrl = pm.checkBox( self.midCtrlCB, q=True, value=True ) except: pass # create spine curve and it's joints crv = pm.duplicate( self.tmpCrv, name=('%s_crv'%limbName) )[0] crv.getShape().template.set(False) pm.rebuildCurve( crv, ch=False, s=numOfSpans ) jnts = (JntOnCrv( numOfJnts=numOfJnts, crv=crv )).newJnts Renamer( objs=jnts , name="%s_###_jnt"%limbName ) # orient spine joints pm.joint( jnts[0], e=True, oj='xzy', secondaryAxisOrient='xup', ch=True, zso=True ) # create joints which will drive the spine curve if not midCtrl: # create base and end control joints controlJnts = (JntOnCrv( crv=crv , numOfJnts=2 )).newJnts startJnt = pm.rename(controlJnts[0],'hip_ctrl' ) endJnt = pm.rename(controlJnts[1],'torso_ctrl' ) pm.parent( endJnt , world=True ) else: # create base, end and middle control joint controlJnts = (JntOnCrv( crv=crv , numOfJnts=3 )).newJnts startJnt = pm.rename(controlJnts[0],'hip_ctrl' ) midJnt = pm.rename(controlJnts[1],'mid_ctrl' ) endJnt = pm.rename(controlJnts[2],'torso_ctrl' ) pm.parent( midJnt, endJnt , world=True ) # orient control joints for jnt in controlJnts: if mode=='biped': jnt.jointOrient.set(90,0,90) elif mode=='quadruped': jnt.jointOrient.set(180,-90,0) # remove init joints and curve pm.delete( self.tmpCrv, self.spine_initJnts ) # create body control body_ctrl = (pm.curve ( d = 1 , p = [ (0, -size*.3 , size*.3) , (0, -size*.3 , -size*.3) , (0, size*.3 , -size*.3) , (0, size*.3 , size*.3) , (0, -size*.3 , size*.3) ] , k = [ 0 , 1 , 2 , 3 , 4 ] , name = 'body_ctrl' ) ) body_ctrl.getShape().overrideEnabled.set(True) body_ctrl.getShape().overrideColor.set(17) pm.xform( body_ctrl, ws=True, t=pm.xform(startJnt, q=True, ws=True, t=True) ) pm.xform( body_ctrl, ws=True, ro=pm.xform(startJnt, q=True, ws=True, ro=True) ) # create IK controls JntToCrv( jnts=controlJnts, shape='circle', size=size*0.25 ) for jnt in controlJnts: jnt.overrideEnabled.set(True) jnt.overrideColor.set(17) IKzeroGrps = ZeroGrp( objs=controlJnts ) # create FK controls if numOfFKctrl : fkCtrls = [] for i in range(numOfFKctrl): fkCtrls.append( (pm.circle( c=(0,0,0), nr=(1,0,0), r=size*0.25, name = "%s_FK_%s)ctrl"%(limbName,i) ) )[0] ) fkCtrls[i].getShape().overrideEnabled.set(True) fkCtrls[i].getShape().overrideColor.set(18) pm.xform( fkCtrls[i], ws=True, t=pm.xform(startJnt, q=True, ws=True, t=True) ) moveAmount = size*0.07+(size/float(numOfFKctrl)*i) if mode=='biped': pm.move( fkCtrls[i], (0,moveAmount,0), r=True ) pm.rotate( fkCtrls[i], (90,0,90) , r=True ) elif mode=='quadruped': pm.move( fkCtrls[i], (0,0,moveAmount), r=True ) pm.rotate( fkCtrls[i], (180,-90,0), r=True ) pm.parent ( IKzeroGrps[0][-1] , fkCtrls[-1] ) for i in range(numOfFKctrl-1): fkCtrls[i+1].setParent( fkCtrls[i] ) fkCtrlsZeroGrps = ZeroGrp( objs=fkCtrls[0] ) # keep mid control between first and last joints if midCtrl: startNull= pm.group(em=True,name='%s_start_null'%limbName) endNull= pm.group(em=True,name='%s_end_null'%limbName) startNull.setParent( startJnt ) endNull.setParent( endJnt ) pm.xform( startNull, t=(size*.3,0,0), ro=(0,0,0), os=True ) pm.xform( endNull, t=(-size*.3,0,0), ro=(0,0,0), os=True ) pm.pointConstraint( startNull, endNull, IKzeroGrps[0][1] ) midOriNull= pm.group(em=True,name='%s_midOrient_null'%limbName) pm.pointConstraint( startJnt, midOriNull ) pm.aimConstraint( endJnt, midOriNull, aimVector=(1,0,0), worldUpType="none") midOriNull.rotate >> IKzeroGrps[0][1].rotate # parent FK, IK and mid cotrol to body if midCtrl and numOfFKctrl: pm.parent( fkCtrlsZeroGrps[0], midOriNull, IKzeroGrps[0][:-1], body_ctrl ) elif numOfFKctrl: pm.parent( fkCtrlsZeroGrps[0], IKzeroGrps[0][:-1], body_ctrl ) elif midCtrl: pm.parent( midOriNull, IKzeroGrps[0], body_ctrl ) else: pm.parent( IKzeroGrps[0], body_ctrl ) bodyCtrlZeroGrp = ZeroGrp( objs=body_ctrl ) # lock and hide extra attributes if numOfFKctrl: for i in range(numOfFKctrl): LockHideAttr(objs=fkCtrls[i],attr='t') LockHideAttr(objs=fkCtrls[i],attr='s') LockHideAttr(objs=fkCtrls[i],attr='v') # create ik spline handle ikhStuff = pm.ikHandle ( solver = "ikSplineSolver" , startJoint = jnts[0] , endEffector = jnts[-1] , curve=crv, freezeJoints=True, simplifyCurve = True, numSpans=numOfSpans ) #, createCurve = False, rootOnCurve = True if midCtrl: skinClust = pm.skinCluster( ikhStuff[2], startJnt , midJnt , endJnt) else: skinClust = pm.skinCluster( ikhStuff[2], startJnt , endJnt) # set skin weights for ik spline curve if midCtrl and numOfSpans==3: pm.skinPercent( skinClust , crv.cv[1], transformValue=[(startJnt, 0.8),(midJnt, 0.2)] ) pm.skinPercent( skinClust , crv.cv[3], transformValue=[(midJnt, 0.8),(endJnt, 0.2)] ) # rename IK stuff pm.rename (ikhStuff[0], "%s_ikh"%limbName ) pm.rename (ikhStuff[1], "%s_eff"%limbName ) ikCrv = pm.rename (ikhStuff[2], "%s_crv"%limbName ) # outliner cleaup and hide extra objects pm.group( ikhStuff[::2],jnts[0], name='%s_skinJnts_grp'%limbName ) pm.setAttr ( ikhStuff[2] + ".inheritsTransform" , 0 ) LockHideAttr( objs=ikhStuff[::2],attr='vv') # stretchable back if ss in ON if ss : MakeSplineStretchy( ikCrv=crv, volume=True, stretchSwitch=True, thicknessPlace="mid" ) pm.select (clear=True) # clean memory del ( self.spine_initJnts ) del ( self.tmpCrv )
def jointChain( joints=[], prefix='chain', ctrlNum=3 ): if joints: pm.select(joints) joints = pm.ls(sl=True, type='joint') if not joints: raise if ctrlNum < 2: raise jointNum = len(joints) degree = 3 if ctrlNum == 3: degree = 2 # ============================= # # ์ปจํธ๋กค๋ฌ # # ============================= crv = jntToCrv(joints, degree=3, ep=True ) ctrlRbd_crv, ctrlRbd_rbd = pm.rebuildCurve( crv, ch=True, replaceOriginal=False, rebuildType=0, endKnots=1, keepRange=0, keepControlPoints=0, keepEndPoints=1, keepTangents=0, spans=ctrlNum-degree, degree=degree, tol=0.01 ) # create curve cv clusters anims = [] pm.select( ctrlRbd_crv.cv ) for cv in pm.ls(sl=True, fl=True): anims.append( pm.cluster( cv )[0] ) #anim = pm.cluster( cv, wn=(self.start_T_anim,self.start_T_anim) )[0] # # # ikHandle # HDL, EFF = pm.ikHandle( solver='ikSplineSolver', startJoint=joints[0], endEffector=joints[-1], createCurve=False, curve=ctrlRbd_crv, parentCurve=False ) HDL.rename( prefix+'_HDL') EFF.rename( prefix+'_EFF') # # # ๊ทธ๋ฃจํ # rigGrp = pm.group(n=prefix+'_jointChain_grp#',em=True) rigGrp.v.set(False) pm.parent( HDL, crv, ctrlRbd_crv, rigGrp) # ============================= # # spline IK, Stretch & Distribute Joint # # ============================= # # ์ปค๋ธ ๋ฆฌ๋น๋, ์ต์คํ ๋ # rdbCrv, rbd = pm.rebuildCurve( ctrlRbd_crv, ch=True, replaceOriginal=False, rebuildType=0, # uniform endKnots=1, # 0 - uniform end knots, 1 - multiple end knots keepRange=0, # 0 - reparameterize the resulting curve from 0 to 1, 1 - keep the original curve parameterization, 2 - reparameterize the result from 0 to number of spans keepControlPoints=False, keepEndPoints=True, keepTangents=True, spans=len(joints), degree=3, tol=0.001 ) # # Locators on Curve # unit = 1.0 / (len(joints)-1) locOnCrvs = [] for i in range(len(joints)): param = unit * i xformOnCrv = pm.spaceLocator( n='xformOnCrv#') xformOnCrv.addAttr( 'parameter', sn='pr', dv=param, keyable=True ) xformOnCrv.addAttr( 'turnOnPercentage', sn='top', dv=False, at='bool', keyable=True ) xformOnCrv.addAttr( 'revRotation', sn='rot', keyable=True ) xformOnCrv.it.set(False) xformOnCrv.rename( 'xformOnCrv%02d'%i ) pntOnCrv = pm.PyNode( pm.pointOnCurve( rdbCrv.getShape(), parameter=param, ch=True ) ) pntOnCrv.turnOnPercentage.set(True) pntOnCrv.setAttr('parameter', keyable=True) pntOnCrv.setAttr('turnOnPercentage', keyable=True) pntOnCrv.rename( xformOnCrv+'_POC' ) xformOnCrv.parameter >> pntOnCrv.parameter xformOnCrv.turnOnPercentage >> pntOnCrv.turnOnPercentage pntOnCrv.position >> xformOnCrv.t locOnCrvs.append(xformOnCrv) # # distance Rig # distNodes = [] for i in range(len(locOnCrvs)-1): dist = pm.createNode( 'distanceDimShape' ) locOnCrvs[i].worldPosition[0] >> dist.startPoint locOnCrvs[i+1].worldPosition[0] >> dist.endPoint distNodes.append( dist ) # # ikํธ๋ค ์ปค๋ธ ๋ณ๊ฒฝ # pm.ikHandle( HDL, e=True, curve=rdbCrv ) # # connect To Joint # for dist, jnt in zip(distNodes, joints[1:]): dist.distance >> jnt.tx # # ๊ทธ๋ฃจํ # pm.parent(rdbCrv, locOnCrvs, [dist.getParent() for dist in distNodes], rigGrp)
def make_joints_along_curve(cls, curve, name, num_joints=0, rebuild=False, parent=None): '''Create joints along a curve in the same direction as the curve Args: curve (pm.PyNode): the curve transform to be used num_joints (int): the number of joints to be created, if 0 will use CVs rebuild (bool): whether we rebuild and normalize the curve or not parent (pm.nt.Transform): final parent of the joints Returns: [pm.nt.Joint]: list of joints Usage: rig_makeJointsAlongCurve("petalA", pm.ls(sl=True)[0], 15) rig_makeJointsAlongCurve("seatbeltDrive", pm.ls(sl=True)[0], 160) ''' poci = None #Creating a curve between them curve = pm.duplicate(curve)[0] if rebuild: pm.rebuildCurve(curve, ch=0, rpo=1, rt=0, end=1, kr=1, kcp=0, kep=1, kt=0, s=num_joints, d=1, tol=0.01) # Detecting if we're doing cv based or not if not num_joints: cvs = True num_joints = curve.getShape().numCVs() - 1 else: cvs = False poci = pm.createNode('pointOnCurveInfo') curve.getShape().worldSpace[0].connect(poci.inputCurve) poci.turnOnPercentage.set(1) #Evenly spacing joints according to the curve joints=[] cls.namer.set(name) cls.namer.var.set('A') cls.namer.type.set('joint') names = cls.namer.get_chain(num_joints) # Clear the selection since the stupid joint command sucks at parenting pm.select(cl=True) for joint_index, name in enumerate(names): jnt_pos = [0,0,0] if cvs: jnt_pos = pm.pointPosition( curve.getShape().cv[joint_index], w = 1) else: poci.parameter.set(float(joint_index)/float(num_joints)) jnt_pos = poci.position.get() joints.append(pm.joint(n = name, p = jnt_pos)) #Set the rotation order for joint in joints[:-1]: joint.secondaryAxisOrient('yup', oj='xyz') # if parent is set, do it. if parent: pm.setParent(joints[0], parent) # Cleanup pm.delete(curve) if cvs: pm.delete(poci) return joints
def build(name=None, crv=None, loc=None, num_jnts=None, num_cnts=None, order=None, reg_node=None, log=False): '''Create advnced IK spine rig Attributes: name -- Prefix name used for the rig. Str crv -- Nurbs curve used as guide. nt.Transform loc -- SpaceLocator used to determine "up" vector. Str num_jnts -- Number of spine joints. Int num_cnts -- Number of controls to make. Int order -- Joint order. Str reg_node -- Registration node. nt.Transform log -- Output log messages. Bool ''' general.check_type(name, 'name', [str]) general.check_type(crv, 'crv', [pm.nt.Transform]) general.check_type(loc, 'loc', [pm.nt.Transform]) general.check_type(num_jnts, 'num_jnts', [int]) general.check_type(num_cnts, 'num_cnts', [int]) general.check_type(order, 'order', [str]) if reg_node: general.check_type(reg_node, 'reg_node', [pm.nt.Transform]) general.check_type(log, 'log', [bool]) if num_jnts < 5 or num_jnts > 50: raise errors.InputError('num_jnts', num_jnts, 'Value Range: 5 - 50') if num_cnts < 2 or num_jnts > 20: raise errors.InputError('num_cnts', num_cnts, 'Value Range: 2 - 20') if order not in ['xyz', 'xzy', 'yxz', 'yzx', 'zxy', 'zyx']: raise errors.InputError('order', order, 'String: xyz, ...') if not reg_node: reg_node = control.create_register_node(name) # -Make joint chain # -- Duplicate loc and call build script dup_loc = loc.duplicate()[0] reg_node, chain = utils.build_joint_chain(name, crv, order, num_jnts, dup_loc, reg_node) pm.delete(dup_loc) # -Make curve (duplicate / rebuild) ik_crv = crv.duplicate(name='%s_ik_curve' % name)[0] pm.rebuildCurve(ik_crv, s=20) # -Make spline IK handle = pm.ikHandle(name='%s_ikHandle' % name, sj=chain[0], ee=chain[-1], c=ik_crv, ccv=False, rtm=False, sol='ikSplineSolver')[0] # -Ik curve jnts dup_loc = loc.duplicate()[0] temp, ikCrvJnts = utils.build_joint_chain('%s_ikCrv' % name, crv, order, num_cnts, dup_loc) pm.delete(dup_loc) pm.delete(temp) for j in ikCrvJnts: try: pm.parent(j, w=1) except: pass # -Make controls count = 1 cnts = [] for j in ikCrvJnts: # Create curve reg_node, cnt_crv = control.\ create_curve(name='%s%s_ik_cnt' % (name, count), typ='circle', scale=1.0, color='yellow', reg_node=reg_node) # Match curve to object control.match_object(cnt_crv, j) # Setup heirarchy pm.parent(j, cnt_crv) # Create heirarchy control.create_heirarchy(name='%s_%s' % (name, count), obj=cnt_crv, num=3) cnts.append(cnt_crv) count += 1 # Build plane for follicles, for controls plane = utils.build_plane('%s_ik_' % name, crv, 20, 'v', 'x', 0.5) # Create follicles follicles = [] incr = 1/float(num_cnts) param = incr for c in cnts[1:-1]: fol = pm.createNode('transform', n='%s_fol' % c.name(), ss=True) folShape = pm.createNode('follicle', n=fol.name()+'Shape', p=fol, ss=True) plane.local >> folShape.inputSurface plane.worldMatrix[0] >> folShape.inputWorldMatrix folShape.outRotate >> fol.rotate folShape.outTranslate >> fol.translate fol.inheritsTransform.set(False) folShape.parameterU.set(0.5) folShape.parameterV.set(param) param += incr follicles.append(fol) # -Setup controls cnts_grp = pm.group(name='%s_cnts_grp' % name, em=1) count = 0 for cnt in cnts[1:-1]: prnt = cnt.getParent() mid = prnt.getParent() top = mid.getParent() # --Grouping pm.parent(top, follicles[count]) count += 1 count = 0 for cnt in [cnts[0], cnts[-1]]: prnt = cnt.getParent() mid = prnt.getParent() top = mid.getParent() # --Grouping pm.parent(top, cnts_grp) count += 1 # Skin ik curve to control joints pm.skinCluster(ikCrvJnts, ik_crv, tsb=True, name='%s_ikCrv_sc' % name) # Skin plane curve to top/btm control joints pm.skinCluster(ikCrvJnts[0], ikCrvJnts[-1], plane, tsb=True, name='%s_ikPlane_sc' % name) # -Make Advance Spline ik_crv.inheritsTransform.set(0) # Enable Adv Ik / Set: Up Object (start/end) handle.dTwistControlEnable.set(1) handle.dWorldUpType.set(2) up_loc1 = pm.spaceLocator(name='%s_AdvIkUpObj1_loc' % name) up_loc2 = pm.spaceLocator(name='%s_AdvIkUpObj2_loc' % name) pm.parent(up_loc1, cnts[0]) pm.parent(up_loc2, cnts[-1]) for loc in [up_loc1, up_loc2]: loc.setTranslation(0) loc.setRotation([0, 0, 0]) attr = getattr(loc, 't%s' % order[1].lower()) attr.set(5) loc.visibility.set(0) up_loc1.worldMatrix >> handle.dWorldUpMatrix up_loc2.worldMatrix >> handle.dWorldUpMatrixEnd # Create poly planes to aid in skinning nurbs plane and curve polyPlane = pm.nurbsToPoly(plane, mnd=1, ch=0, f=0, pt=1, pc=20, chr=0.9, ft=0.01, mel=0.001, d=0.1, ut=1, un=3, vt=1, vn=3, uch=0, ucr=0, cht=0.2, es=0, ntr=0, mrt=0, uss=1)[0] polyCrvPlane = pm.nurbsToPoly(plane, mnd=1, ch=0, f=0, pt=1, pc=20, chr=0.9, ft=0.01, mel=0.001, d=0.1, ut=1, un=3, vt=1, vn=3, uch=0, ucr=0, cht=0.2, es=0, ntr=0, mrt=0, uss=1)[0] p1 = pm.PyNode(polyPlane) p1.rename('%s_nurbsPlaneAide' % name) p2 = pm.PyNode(polyCrvPlane) p2.rename('%s_ikCrvAide' % name) pm.skinCluster(ikCrvJnts, p2, tsb=1, name='%s_ikCrvAide_sc' % name) pm.skinCluster(ikCrvJnts[0], ikCrvJnts[-1], p1, tsb=1, name='%s_nurbsPlaneAide_sc' % name) # Clean up for j in ikCrvJnts: j.hide() fol_grp = pm.group(n='%s_follicle_grp' % name, em=1) dont_mov_grp = pm.group(n='%s_dont_move_grp' % name, em=1) skin_jnts_grp = pm.group(n='%s_ik_skin_jnts_grp' % name, em=1) dont_mov_grp.translate.lock() dont_mov_grp.rotate.lock() dont_mov_grp.hide() pm.parent(follicles, fol_grp) pm.parent(chain[0], skin_jnts_grp) pm.parent(handle, plane, ik_crv, p1, p2, dont_mov_grp) main_grp = pm.group(n='%s_ik_rig_grp' % name, em=1) pm.parent(fol_grp, dont_mov_grp, skin_jnts_grp, cnts_grp, main_grp) # Register joint chain and ik_crv control.register_object(reg_node, 'ik_top_node', main_grp) control.register_object(reg_node, 'ik_crv', ik_crv) return reg_node
def create(self): self.nodes = [] #------------------------------ # # Create Ctrler # #------------------------------ self.root_grp = pm.group( n='TwistHelper_grp', em=True) self.constMe_to_parent = pm.group( n='constMe_to_parent', em=True) self.constMe_to_start = pm.group( n='constMe_to_start', em=True) self.constMe_to_mid = pm.group( n='constMe_to_mid', em=True ) self.constMe_to_end = pm.group( n='constMe_to_end', em=True) self.doNotTouch_grp = pm.group( n='doNotTouch_grp', em=True) pm.parent( self.constMe_to_start, self.constMe_to_mid, self.constMe_to_end, self.constMe_to_parent) pm.parent( self.constMe_to_parent, self.doNotTouch_grp, self.root_grp ) self.start_T_anim = pm.group( n='start_T_anim', em=True) self.end_T_anim = pm.group( n='end_T_anim', em=True) pm.parent( self.start_T_anim, self.constMe_to_start ) pm.parent( self.end_T_anim, self.constMe_to_end ) self.mid_T_anim = pm.group( n='mid_T_anim', em=True ) self.mid1_T_anim = pm.group( n='mid1_T_anim', em=True ) self.mid2_T_anim = pm.group( n='mid2_T_anim', em=True ) pm.parent( self.mid1_T_anim, self.mid2_T_anim, self.mid_T_anim ) pm.parent( self.mid_T_anim, self.constMe_to_mid ) self.start_R_result = pm.group( n='start_R_result', em=True) self.start_up_anim = pm.group( n='start_up_anim', em=True) pm.parent( self.start_R_result, self.start_up_anim, self.start_T_anim ) self.end_R_result = pm.group( n='end_R_result', em=True) self.end_up_anim = pm.group( n='end_up_anim', em=True) pm.parent( self.end_R_result, self.end_up_anim, self.end_T_anim ) self.doNotTouch_grp.v.set(False) # ์ดํธ๋ฆฌ๋ทฐํธ ์ ๊ธ self._lockAndHideAttr([self.start_up_anim, self.end_up_anim],['rx','ry','rz','sx','sy','sz']) self._lockAndHideAttr([self.constMe_to_start, self.constMe_to_mid, self.constMe_to_end, self.mid_T_anim, self.constMe_to_parent],['sx','sy','sz','v']) self._lockAndHideAttr([self.start_R_result, self.end_R_result],['sx','sy','sz','v']) self._lockAndHideAttr([self.start_T_anim, self.end_T_anim, self.mid1_T_anim, self.mid2_T_anim],['rx','ry','rz','sx','sy','sz','v']) self._lockAndHideAttr([self.doNotTouch_grp, self.root_grp],['tx','ty','tz','rx','ry','rz','sx','sy','sz']) self.nodes.extend([self.root_grp, self.constMe_to_parent, self.constMe_to_start, self.constMe_to_mid, self.constMe_to_end, self.doNotTouch_grp, self.start_T_anim, self.end_T_anim, self.mid_T_anim, self.mid1_T_anim, self.mid2_T_anim, self.start_R_result, self.start_up_anim]) self.nodes.extend([self.end_R_result, self.end_up_anim]) #------------------------------ # # config Attribute # #------------------------------ ctrl = self.root_grp ctrl.addAttr('aimAxis', at='enum', en='PositiveX:NegativeX:', keyable=False) # IKํธ๋ค์ Advanced Twist Controls ์ธํ ์ด -x์ถ์ ๊ณ ๋ ค๋์ด ์์ง ์์. ์๋ฏธ ์์. ctrl.addAttr('aimVector', at='double3') ctrl.addAttr('aimVectorX', at='double', p='aimVector', keyable=False) ctrl.addAttr('aimVectorY', at='double', p='aimVector', keyable=False) ctrl.addAttr('aimVectorZ', at='double', p='aimVector', keyable=False) ctrl.addAttr('upAxis', at='enum', en='PositiveY:NegativeY:ClosetY:PositiveZ:NegativeZ:ClosetZ:', keyable=True) ctrl.addAttr('upVector', at='double3') ctrl.addAttr('upVectorX', at='double', p='upVector', keyable=True) ctrl.addAttr('upVectorY', at='double', p='upVector', keyable=True) ctrl.addAttr('upVectorZ', at='double', p='upVector', keyable=True) ctrl.addAttr('startWorldUpVector', at='double3') ctrl.addAttr('startWorldUpVectorX', at='double', p='startWorldUpVector', keyable=True) ctrl.addAttr('startWorldUpVectorY', at='double', p='startWorldUpVector', keyable=True) ctrl.addAttr('startWorldUpVectorZ', at='double', p='startWorldUpVector', keyable=True) ctrl.addAttr('endWorldUpVector', at='double3') ctrl.addAttr('endworldUpVectorX', at='double', p='endWorldUpVector', keyable=True) ctrl.addAttr('endworldUpVectorY', at='double', p='endWorldUpVector', keyable=True) ctrl.addAttr('endworldUpVectorZ', at='double', p='endWorldUpVector', keyable=True) ctrl.aimVector.set(self.aimVector) ctrl.upVector.set(self.upVector) ctrl.startWorldUpVector.set(self.startWorldUpVector) ctrl.endWorldUpVector.set(self.endWorldUpVector) pm.setDrivenKeyframe( ctrl.aimVectorX, value= 1, currentDriver=ctrl.aimAxis, driverValue=0 ) # positiveX pm.setDrivenKeyframe( ctrl.aimVectorY, value= 0, currentDriver=ctrl.aimAxis, driverValue=0 ) # positiveX pm.setDrivenKeyframe( ctrl.aimVectorZ, value= 0, currentDriver=ctrl.aimAxis, driverValue=0 ) # positiveX pm.setDrivenKeyframe( ctrl.aimVectorX, value=-1, currentDriver=ctrl.aimAxis, driverValue=1 ) # negativeX pm.setDrivenKeyframe( ctrl.aimVectorY, value= 0, currentDriver=ctrl.aimAxis, driverValue=1 ) # negativeX pm.setDrivenKeyframe( ctrl.aimVectorZ, value= 0, currentDriver=ctrl.aimAxis, driverValue=1 ) # negativeX pm.setDrivenKeyframe( ctrl.upVectorX, value= 0, currentDriver=ctrl.upAxis, driverValue=0 ) # positiveY pm.setDrivenKeyframe( ctrl.upVectorY, value= 1, currentDriver=ctrl.upAxis, driverValue=0 ) # positiveY pm.setDrivenKeyframe( ctrl.upVectorZ, value= 0, currentDriver=ctrl.upAxis, driverValue=0 ) # positiveY pm.setDrivenKeyframe( ctrl.upVectorX, value= 0, currentDriver=ctrl.upAxis, driverValue=1 ) # negativeY pm.setDrivenKeyframe( ctrl.upVectorY, value=-1, currentDriver=ctrl.upAxis, driverValue=1 ) # negativeY pm.setDrivenKeyframe( ctrl.upVectorZ, value= 0, currentDriver=ctrl.upAxis, driverValue=1 ) # negativeY pm.setDrivenKeyframe( ctrl.upVectorX, value= 0, currentDriver=ctrl.upAxis, driverValue=3 ) # positiveZ pm.setDrivenKeyframe( ctrl.upVectorX, value= 0, currentDriver=ctrl.upAxis, driverValue=2 ) # negativeY pm.setDrivenKeyframe( ctrl.upVectorY, value= 1, currentDriver=ctrl.upAxis, driverValue=2 ) # negativeY pm.setDrivenKeyframe( ctrl.upVectorZ, value= 0, currentDriver=ctrl.upAxis, driverValue=2 ) # negativeY pm.setDrivenKeyframe( ctrl.upVectorX, value= 0, currentDriver=ctrl.upAxis, driverValue=3 ) # positiveZ pm.setDrivenKeyframe( ctrl.upVectorY, value= 0, currentDriver=ctrl.upAxis, driverValue=3 ) # positiveZ pm.setDrivenKeyframe( ctrl.upVectorZ, value= 1, currentDriver=ctrl.upAxis, driverValue=3 ) # positiveZ pm.setDrivenKeyframe( ctrl.upVectorX, value= 0, currentDriver=ctrl.upAxis, driverValue=4 ) # negativeZ pm.setDrivenKeyframe( ctrl.upVectorY, value= 0, currentDriver=ctrl.upAxis, driverValue=4 ) # negativeZ pm.setDrivenKeyframe( ctrl.upVectorZ, value=-1, currentDriver=ctrl.upAxis, driverValue=4 ) # negativeZ pm.setDrivenKeyframe( ctrl.upVectorX, value= 0, currentDriver=ctrl.upAxis, driverValue=5 ) # negativeZ pm.setDrivenKeyframe( ctrl.upVectorY, value= 0, currentDriver=ctrl.upAxis, driverValue=5 ) # negativeZ pm.setDrivenKeyframe( ctrl.upVectorZ, value= 1, currentDriver=ctrl.upAxis, driverValue=5 ) # negativeZ ctrl.setAttr('upVectorX', keyable=False ) ctrl.setAttr('upVectorY', keyable=False ) ctrl.setAttr('upVectorZ', keyable=False ) # # # base Curve # # crv = pm.curve( n='base_crv', d=3, p=[(0,0,0),(0,0,0),(0,0,0),(0,0,0)], k=[0,0,0,1,1,1] ) pm.parent( crv, self.doNotTouch_grp ) crv.it.set(False) self.nodes.append(crv) # create curve cv clusters start_crv_clst = pm.cluster( crv.cv[0], wn=(self.start_T_anim,self.start_T_anim) )[0] mid1_crv_clst = pm.cluster( crv.cv[1], wn=(self.mid1_T_anim, self.mid1_T_anim) )[0] mid2_crv_clst = pm.cluster( crv.cv[2], wn=(self.mid2_T_anim, self.mid2_T_anim) )[0] end_crv_clst = pm.cluster( crv.cv[3], wn=(self.end_T_anim, self.end_T_anim) )[0] self.nodes.extend([start_crv_clst,mid1_crv_clst,mid2_crv_clst,end_crv_clst]) # # ์ด๊ธฐ์์น # self.start_up_anim.t.set( self.upVector * 10) self.end_up_anim .t.set( self.upVector * 10) self.constMe_to_end.t.set( self.aimVector * 10) pm.delete( pm.pointConstraint(self.start_T_anim, self.end_T_anim, self.constMe_to_mid) ) pm.delete( pm.pointConstraint(self.mid_T_anim, self.start_T_anim, self.mid1_T_anim) ) pm.delete( pm.pointConstraint(self.mid_T_anim, self.end_T_anim, self.mid2_T_anim) ) # # # rebuild curve for distribute # # # ์ปค๋ธ ๋ฆฌ๋น๋, ์ต์คํ ๋ rbdCrv, rbd = pm.rebuildCurve( crv, ch=True, replaceOriginal=False, rebuildType=0, # uniform endKnots=1, # 0 - uniform end knots, 1 - multiple end knots keepRange=0, # 0 - reparameterize the resulting curve from 0 to 1, 1 - keep the original curve parameterization, 2 - reparameterize the result from 0 to number of spans keepControlPoints=False, keepEndPoints=True, keepTangents=True, spans=100, degree=3, tol=0.001 ) rdbCrv, extCrv = pm.extendCurve( rbdCrv, cos=0, ch=1, jn=True, rmk=True, rpo=True, distance = 1, start=0, # 0 - end, 1 - start, 2 - both extendMethod=0, # 0 - based on distance, 2 - to a 3D point extensionType=0, # 0 - Linear, 1 - Circular, 2 - Extrapolate ) rdbCrv.rename('rbdExtnd_crv') pm.parent( rdbCrv, self.doNotTouch_grp ) rdbCrv.it.set(False) # extend crv Locator crvEnd_loc = pm.spaceLocator(n='extCrvEnd_loc') pntOnCrv = pm.PyNode( pm.pointOnCurve( rdbCrv.getShape(), parameter=2.0, ch=True ) ) pntOnCrv.position >> crvEnd_loc.t pm.parent( crvEnd_loc, self.doNotTouch_grp ) self.nodes.extend([ rbdCrv, rbd,extCrv, crvEnd_loc]) # # Cluster & Constraint # # constraint Rig start_aimConst = pm.aimConstraint( self.end_T_anim, self.start_R_result, aim=self.aimVector, u=self.upVector, wu=self.startWorldUpVector, wut='object', wuo=self.start_up_anim) mid_pointConst = pm.pointConstraint( self.start_T_anim, self.end_T_anim, self.constMe_to_mid) mid_aimConst = pm.aimConstraint( self.end_T_anim, self.constMe_to_mid, aim=self.aimVector, u=self.upVector, wu=self.startWorldUpVector, wut='objectrotation', wuo=self.start_R_result) end_aimConst = pm.aimConstraint( crvEnd_loc, self.end_R_result, aim=self.aimVector, u=self.upVector, wu=self.startWorldUpVector, wut='object', wuo=self.end_up_anim) self.nodes.extend([ start_aimConst, mid_pointConst, mid_aimConst, end_aimConst ]) ctrl.aimVector >> start_aimConst.aimVector ctrl.aimVector >> mid_aimConst.aimVector ctrl.upVector >> start_aimConst.upVector ctrl.upVector >> mid_aimConst.upVector ctrl.startWorldUpVector >> start_aimConst.worldUpVector ctrl.startWorldUpVector >> mid_aimConst.worldUpVector # # Locators on Curve # unit = 1.0 / self.div locOnCrvs = [] for i in range(self.div+1): param = unit * i #xformOnCrv = pm.group( n='xformOnCrv#', em=True) xformOnCrv = pm.spaceLocator( n='xformOnCrv#') xformOnCrv.addAttr( 'parameter', sn='pr', dv=param, keyable=True ) xformOnCrv.addAttr( 'turnOnPercentage', sn='top', dv=False, at='bool', keyable=True ) xformOnCrv.addAttr( 'revRotation', sn='rot', keyable=True ) xformOnCrv.it.set(False) xformOnCrv.rename( 'xformOnCrv%02d'%i ) pntOnCrv = pm.PyNode( pm.pointOnCurve( rdbCrv.getShape(), parameter=param, ch=True ) ) pntOnCrv.turnOnPercentage.set(True) pntOnCrv.setAttr('parameter', keyable=True) pntOnCrv.setAttr('turnOnPercentage', keyable=True) pntOnCrv.rename( xformOnCrv+'_POC' ) xformOnCrv.parameter >> pntOnCrv.parameter xformOnCrv.turnOnPercentage >> pntOnCrv.turnOnPercentage pntOnCrv.position >> xformOnCrv.t locOnCrvs.append(xformOnCrv) pm.parent( locOnCrvs, self.doNotTouch_grp ) self.nodes.extend( locOnCrvs ) # # distance Rig # distNodes = [] for i in range(len(locOnCrvs)-1): dist = pm.createNode( 'distanceDimShape' ) locOnCrvs[i].worldPosition[0] >> dist.startPoint locOnCrvs[i+1].worldPosition[0] >> dist.endPoint distNodes.append( dist ) pm.parent( [dist.getParent() for dist in distNodes], self.doNotTouch_grp ) self.nodes.extend( [dist.getParent() for dist in distNodes] ) # # # Joint # # pm.select(cl=True) self.jnts = [] for i in range(self.div+1): self.jnts.append( pm.joint( n='bind%d'%i, p=self.aimVector*i ) ) if self.stretch: # ์ปจํธ๋กค๋ฌ์ ์ดํธ๋ฆฌ๋ทฐํธ ์ถ๊ฐํ๊ณ , ๋ฆฌ๊น ๊น์ง ๋ง์นจ. #ctrl = pm.group( em=True) ctrl = self.root_grp ctrl.addAttr( 'initialDistance', multi=True, readable=True, indexMatters=False ) ctrl.addAttr( 'currentDistance', multi=True, readable=True, indexMatters=False ) ctrl.addAttr( 'scaleOutput', multi=True, readable=True, indexMatters=False ) for i in range(len(distNodes)): ctrl.initialDistance[i].set( distNodes[i].distance.get() ) distNodes[i].distance >> ctrl.currentDistance[i] md = pm.createNode('multiplyDivide') md.operation.set(2) # divide ctrl.currentDistance[i] >> md.input1X ctrl.initialDistance[i] >> md.input2X md.outputX >> ctrl.scaleOutput[i] for i in range(len( ctrl.scaleOutput.get() )): ctrl.scaleOutput[i] >> self.jnts[i].sx else: for dist, jnt in zip(distNodes, self.jnts[1:]): #if ctrl.aimAxis==1: # ์์์ถ์ด -์ผ๊ฒฝ์ฐ. md = pm.createNode('multiplyDivide') dist.distance >> md.input1X ctrl.aimVectorX >> md.input2X md.outputX >> jnt.tx #else: # dist.distance >> jnt.tx self.nodes.extend(self.jnts) # # # spline IK Handle # # ikHandle, endEff = pm.ikHandle(sol='ikSplineSolver', ccv=False, roc=True, pcv=False, ns=4, sj=self.jnts[0], ee=self.jnts[-1], curve=rdbCrv ) pm.parent(ikHandle, self.doNotTouch_grp ) # Enable Twist Controls : start, end Sample OBJ sampleObj_start = self.start_R_result sampleObj_end = self.end_R_result ikHandle.dTwistControlEnable.set(True) # Enable Twist Controls ikHandle.dWorldUpType.set(4) # 4:Object Rotation Up (Start/End) #sampleObj_start.xformMatrix.connect( foreArm_HDL.dWorldUpMatrix ) # << ์๋ ๊ฒ ํ๋ฉด ์ข๋จ #sampleObj_end.xformMatrix.connect( foreArm_HDL.dWorldUpMatrixEnd ) # << ์๋ ๊ฒ ํ๋ฉด ์ข๋จ sampleObj_start.worldMatrix >> ikHandle.dWorldUpMatrix # << ์๋ ๊ฒ ํด์ผํจ. sampleObj_end .worldMatrix >> ikHandle.dWorldUpMatrixEnd # << ์๋ ๊ฒ ํด์ผํจ. ikHandle.dWorldUpAxis. set(0) # 0:PositiveY, 1:Positive Z ikHandle.dWorldUpVector. set(self.upVector) ikHandle.dWorldUpVectorEnd.set(self.upVector) ctrl.aimAxis >> ikHandle.dWorldUpAxis ctrl.startWorldUpVector >> ikHandle.dWorldUpVector ctrl.endWorldUpVector >> ikHandle.dWorldUpVectorEnd self.nodes.extend([ikHandle,endEff])
def createIkCrv(self): ikCrv = pm.duplicate(self.crv) ikCrv = pm.rebuildCurve(ikCrv[0],ch=0, rpo=1, rt=0, end=1, kr=0, kcp=0, kep=1, kt=0, s=self.numCtrl-1, d=3, tol=0)[0] ikCrv.rename(self.name + '_ik_crv') self.ikCrv = ikCrv
def hairJiggle( nodes=[], prefix='jiggle', stretchable=True ): ''' update : 2015-04-27 # # ๋ง์ผ์์ ๊ธฐ๋ณธ์ผ๋ก ๊ฐ์ ๊ธฐ๋ฅ์ ํ๋ MakeCurvesDynamic ์คํฌ๋ฆฝํธ๊ฐ ์์ผ๋ # ๋ฆฌํด ๊ฐ์ด ์์ด ์ฌ์ฉ์ด ๋ถ๊ฐ # pm.runtime.MakeCurvesDynamic('curve1') # # makeCurvesDynamic 2 { "0", "1", "0", "1", "0"}; # $args[0] = surfaceAttach If true then connect the hairs to a surface(also selected) basing the uv on the nearest point to the first curve cv # $args[1] = snapToSurface If true and attaching to a surface then also snap the curve to the surface. # $args[2] = matchPosition If true then make the input curve a degree one so resulting output curve exactly matches the position. # $args[3] = createOutCurves If true then output curves are created # $args[4] = createPfxHair If true then hair is created. # ''' if nodes: pm.select(nodes) # get joints joints = pm.ls(sl=True, type='joint') if not joints: raise # get hairSystem hairSystem=None hairSystems = pm.ls(sl=True, dag=True, type='hairSystem') if hairSystems: hairSystem = hairSystems[-1] # get nucleus nucleus=None nucleuss = pm.ls(sl=True, dag=True, type='nucleus') if nucleuss: nucleus = nucleuss[-1] # store current state currentToolMode = pm.currentCtx() pm.setToolTo( 'selectSuperContext' ) sel = pm.selected() # # nucleus # if not nucleus and not hairSystem: nucleus = pm.createNode( 'nucleus' ) nucleus.rename( prefix+'_nucleus' ) pm.PyNode('time1').outTime >> nucleus.currentTime # # hairSystem # hairSystemTr = None if hairSystem: hairSystemTr = hairSystem.getParent() else: hairSystem = pm.createNode( 'hairSystem' ) hairSystemTr = hairSystem.getParent() hairSystemTr.rename( prefix+'_hairSys' ) # ์๋ก ์์ฑ๋ ํค์ด์ ๋ดํด๋ฆฌ์ด์ค ์ฐ๊ฒฐ << connectAttr nextAvailableํ๋๊ทธ๋ก ํด๊ฒฐํด๋ณด๋ คํ์ผ๋.. ๋ณต์ก.. ๋ฉ์ ์ฌ์ฉํ๋๊ฒ ์ ์ผ ํธํจ. #pm.PyNode('time1').outTime >> hairSystem.currentTime #hairSystem.currentState >> nucleus.inputActive[0] #hairSystem.startState >> nucleus.inputActiveStart[0] #nucleus.outputObjects[0] >> hairSystem.nextState #nucleus.startFrame >> hairSystem.startFrame # ์๋ก ์์ฑ๋ ํค์ด์ ๋ดํด๋ฆฌ์ด์ค ์ฐ๊ฒฐ pm.mel.assignNSolver( nucleus ) # default Value hairSystem.active.set( True ) # # follicle ์์ฑ # follicle = pm.createNode( 'follicle' ) follicleTr = follicle.getParent() follicleTr.rename( prefix+'_follicle' ) # follicle ์์น์กฐ์ pm.delete( pm.pointConstraint( joints[0], follicleTr ) ) pm.delete( pm.orientConstraint( joints[0], follicleTr, offset=(0, 90, 0) ) ) # follicle์ด ์กฐ์ธํธ, parent๋ฅผ ๋ฐ๋ผ๊ฐ๋๋ก์ค์ # Start Joint์ Parent๊ฐ ์์ผ๋ฉด ํ์ฌ Start์ ํ์ด๋ฐํธ ๊ฒ. parent = joints[0].getParent() const = None if parent: const = pm.parentConstraint( parent, follicleTr, mo=True) else: const = pm.parentConstraint( joints[0], follicleTr, mo=True) # ๊ธฐ๋ณธ๊ฐ follicle.restPose.set(1) # same as start follicle.startDirection.set(1) # start Curve base follicle.degree.set(2) follicle.clumpWidth.set(5) # ํด๋ฆฌํด ๋์คํ๋ ์ด ํฌ๊ธฐ # # curve Setting # # startCurve ์์ฑ startCurve = jntToCrv( joints, degree=3, ep=True ) startCurve.setParent( follicleTr ) startCurve.rename( prefix+'_startCurve' ) # outputCurve ์์ฑ outputCurveShape = pm.createNode( 'nurbsCurve' ) outputCurve = outputCurveShape.getParent() outputCurve.rename( prefix+'_outputCurve' ) # # DG # settableNum = 0 while True: if hairSystem.inputHair[ settableNum ].isSettable(): break settableNum +=1 startCurve.getShape().worldSpace >> follicle.startPosition follicle.outHair >> hairSystem.inputHair[ settableNum ] hairSystem.outputHair[ settableNum ] >> follicle.currentPosition pm.connectAttr( follicle+'.outCurve', outputCurveShape+'.create' ) # follicle.outCurve >> outputCurveShape.create # ์ด๋ถ๋ถ์์ ๋ค์ ๊ฒฝ๊ณ ๋ฐ์: Warning: pymel.core.general : Could not create desired MFn. Defaulting to MFnDagNode. # # # # ikHandle # HDL, EFF = pm.ikHandle( solver='ikSplineSolver', startJoint=joints[0], endEffector=joints[-1], createCurve=False, curve=outputCurveShape, parentCurve=False ) HDL.rename( prefix+'_HDL') EFF.rename( prefix+'_EFF') # # # ๊ทธ๋ฃจํ # rigGrp = pm.group(n=prefix+'_jointChainRig_grp#',em=True) rigGrp.v.set(False) pm.parent(follicleTr, HDL, outputCurve, rigGrp) # # # ์คํธ๋ ์น ์ธํ # if stretchable: # # ์ปค๋ธ ๋ฆฌ๋น๋, ์ต์คํ ๋ # rdbCrv, rbd = pm.rebuildCurve( outputCurveShape, ch=True, replaceOriginal=False, rebuildType=0, # uniform endKnots=1, # 0 - uniform end knots, 1 - multiple end knots keepRange=0, # 0 - reparameterize the resulting curve from 0 to 1, 1 - keep the original curve parameterization, 2 - reparameterize the result from 0 to number of spans keepControlPoints=False, keepEndPoints=True, keepTangents=True, spans=len(joints), degree=3, tol=0.001 ) # # Locators on Curve # unit = 1.0 / (len(joints)-1) locOnCrvs = [] for i in range(len(joints)): param = unit * i xformOnCrv = pm.spaceLocator( n='xformOnCrv#') xformOnCrv.addAttr( 'parameter', sn='pr', dv=param, keyable=True ) xformOnCrv.addAttr( 'turnOnPercentage', sn='top', dv=False, at='bool', keyable=True ) xformOnCrv.addAttr( 'revRotation', sn='rot', keyable=True ) xformOnCrv.it.set(False) xformOnCrv.rename( 'xformOnCrv%02d'%i ) pntOnCrv = pm.PyNode( pm.pointOnCurve( rdbCrv.getShape(), parameter=param, ch=True ) ) pntOnCrv.turnOnPercentage.set(True) pntOnCrv.setAttr('parameter', keyable=True) pntOnCrv.setAttr('turnOnPercentage', keyable=True) pntOnCrv.rename( xformOnCrv+'_POC' ) xformOnCrv.parameter >> pntOnCrv.parameter xformOnCrv.turnOnPercentage >> pntOnCrv.turnOnPercentage pntOnCrv.position >> xformOnCrv.t locOnCrvs.append(xformOnCrv) # # distance Rig # distNodes = [] for i in range(len(locOnCrvs)-1): dist = pm.createNode( 'distanceDimShape' ) locOnCrvs[i].worldPosition[0] >> dist.startPoint locOnCrvs[i+1].worldPosition[0] >> dist.endPoint distNodes.append( dist ) # # ikํธ๋ค ์ปค๋ธ ๋ณ๊ฒฝ # pm.ikHandle( HDL, e=True, curve=rdbCrv ) # # connect To Joint # for dist, jnt in zip(distNodes, joints[1:]): dist.distance >> jnt.tx # # ๊ทธ๋ฃจํ # pm.parent(rdbCrv, locOnCrvs, [dist.getParent() for dist in distNodes], rigGrp) # # # restore state # pm.setToolTo( currentToolMode ) if sel: pm.select(sel) else: pm.select(cl=True)