def build(): ctrl = nurbsPlane(ax=[0, 1, 0], w=1, d=1, lr=1)[0] move(ctrl.cv, [0, 0.5, 0], r=1, os=1, wd=True) other = nurbsPlane(ax=[0, 1, 0], w=1, d=1, lr=1)[0] move(other.cv, [0, -0.5, 0], r=1, os=1, wd=True) points = [ (-0.5, 0, 0.5), (0.5, 0, 0.5), (0.5, 0, -0.5), (-0.5, 0, -0.5), (-0.5, 0, 0.5), ] line = curve(p=[(p[0], p[1] + .5, p[2]) for p in points] + [(p[0], p[1] - .5, p[2]) for p in points], d=1) line.rename('outline') other.getShape().setParent(ctrl, add=True, shape=True) line.getShape().setParent(ctrl, add=True, shape=True) delete(line, other) return ctrl
def test_clusterPlane(self): fr = FollowRibbon.FollowRibbon(name="blah") plane = pm.nurbsPlane(axis=[0, 1, 0], patchesU=8, patchesV=1, lengthRatio=0.1, ch=0)[0] ctrls = [] ctrls.append(pm.circle(n="blah_ctrl_01")[0].name()) ctrls.append(pm.circle(n="blah_ctrl_02")[0].name()) mainGrp = pm.group(em=1, name="main") result = fr._clusterPlane(plane=plane, controls=ctrls, mainGrp="main") self.testLib.assertListEqual(result, ["blah_cluster_01Handle", "blah_cluster_02Handle"]) self.assertTrue(pm.objExists("blah_cluster_01")) self.assertTrue(pm.objExists("blah_cluster_02")) self.assertTrue(pm.listRelatives(result[0], parent=True), "main") self.assertTrue(pm.listRelatives(result[1], parent=True), "main") self.assertTrue(pm.listRelatives(result[0], parent=1)[0], "blah_ctrlsGrp") self.assertTrue(pm.listRelatives(result[1], parent=1)[0], "blah_ctrlsGrp") hist = pm.listHistory(plane) hitA = 0 hitB = 0 for each in hist: if each.name() == "blah_cluster_01": hitA = 1 if each.name() == "blah_cluster_02": hitB = 1 self.assertTrue(hitA) self.assertTrue(hitB) self.assertTrue(pm.isConnected("blah_ctrl_01.translate", "blah_cluster_01Handle.translate")) self.assertTrue(pm.isConnected("blah_ctrl_02.translate", "blah_cluster_02Handle.translate"))
def camera_focus_plane_tool(): """sets up a focus plane for the selected camera """ camera = pm.ls(sl=1)[0] camera_shape = camera.getShape() frame = pm.nurbsPlane( n='focusPlane#', p=(0, 0, 0), ax=(0, 0, 1), w=1, lr=1, d=1, u=1, v=1, ch=0 )[0] frame_shape = frame.getShape() pm.parent(frame, camera, r=True) #transform the frame surface frame.tz.set(-10.0) exp = """float $flen = %(camera)s.focalLength; float $hfa = %(camera)s.horizontalFilmAperture * 25.4; %(frame)s.sx = -%(frame)s.translateZ * $hfa/ $flen; %(frame)s.sy = %(frame)s.sx / defaultResolution.deviceAspectRatio; %(camera)s.focusDistance = -%(frame)s.tz; %(camera)s.aiFocusDistance = %(camera)s.focusDistance; %(camera)s.aiApertureSize = %(camera)s.focalLength / %(camera)s.fStop * 0.1; """ % { 'camera': camera_shape.name(), 'frame': frame.name() } pm.expression(s=exp, ae=1, uc="all") # set material surface_shader = pm.shadingNode('surfaceShader', asShader=1) pm.select(frame) pm.hyperShade(a=surface_shader.name()) surface_shader.setAttr('outColor', (0.4, 0, 0)) surface_shader.setAttr('outTransparency', (0.5, 0.5, 0.5)) # prevent it from being rendered frame_shape.setAttr('castsShadows', 0) frame_shape.setAttr('receiveShadows', 0) frame_shape.setAttr('motionBlur', 0) frame_shape.setAttr('primaryVisibility', 0) frame_shape.setAttr('smoothShading', 0) frame_shape.setAttr('visibleInReflections', 0) frame_shape.setAttr('visibleInRefractions', 0) # Arnold attributes frame_shape.setAttr('aiSelfShadows', 0) frame_shape.setAttr('aiVisibleInDiffuse', 0) frame_shape.setAttr('aiVisibleInGlossy', 0) # hide unnecessary attributes frame.setAttr('tx', lock=True, keyable=False) frame.setAttr('ty', lock=True, keyable=False) frame.setAttr('rx', lock=True, keyable=False) frame.setAttr('ry', lock=True, keyable=False) frame.setAttr('rz', lock=True, keyable=False) frame.setAttr('sx', lock=True, keyable=False) frame.setAttr('sy', lock=True, keyable=False) frame.setAttr('sz', lock=True, keyable=False)
def control_grp_have_joint(name, object_type="plane", parent_node=None, jnt_vis=False): u"""包含子骨骼的控制器组 :param name: 控制器名 :param object_type: 控制器的样式 :param parent_node: 父节点 :return: 控制器组 """ grp = pm.createNode("transform", name="{}_Grp".format(name)) if object_type == "plane": pm.parent( pm.nurbsPlane(name=name, p=[0, 0, 0], ax=[0, 0, 1], w=1, lr=1, d=1, u=1, v=1, ch=0), grp) pm.select(cl=True) jnt = pm.joint(name="{}_Jnt".format(name)) jnt.visibility.set(jnt_vis) pm.parent(jnt, name) if parent_node is not None: pm.parent(grp, parent_node) grp.translate.set([0, 0, 0]) grp.rotate.set([0, 0, 0]) grp.scale.set([1, 1, 1]) return grp
def createNurbSurf(numJoints, name): """ From two selected objects will create a nurbs curve with follicle """ front, end = pm.selected() distance = getDistance(front, end) nurbsSurf = pm.nurbsPlane(p = [0,0,0], ax =[0,1,0], w=1, lr=distance, d=3,u=1, v=numJoints, ch=1, n = name + '_Sur') vCoord = 1.0/numJoints follicleList = [] # this section can also use CMuscleSurfAttach, # found that muscle surface attach is less efficient for i in range(numJoints): fol = pm.createNode('transform', n= name + '_fol#', ss=True) folShape = pm.createNode('follicle', n=fol.name() + 'Shape', p=fol, ss=True) nurbsSurf[0].local >> folShape.inputSurface nurbsSurf[0].worldMatrix[0] >> folShape.inputWorldMatrix folShape.outRotate >> fol.rotate folShape.outTranslate >> fol.translate fol.inheritsTransform.set(False) folShape.parameterU.set(0.5) folShape.simulationMethod.set(0) curV = vCoord * (i + 1) nextV = vCoord * (i) midV = (curV + nextV) * 0.5 logger.debug('The average of ' + str(curV) + ' and ' + str(nextV) + ' is ' + str(midV) + '. Setting follicle position to sum.') folShape.parameterV.set(midV) follicleList.append(fol) pm.group(follicleList, n = name + '_fol_GRP') return follicleList, nurbsSurf, front, end
def create_ribbon(self, ribbon_length, number_of_follicles): ribbon, ribbon_make_nurb = pm.nurbsPlane(p=[0, 0, 0], ax=[0, 0, 1], w=ribbon_length, lr=0.2, d=3, u=8, v=1, ch=1) ribbon_shape = ribbon.getShape() ribbon.rename(self.namespace + "ribbon_nurbs") follicle_percentage = 1.0 / (number_of_follicles - 1) follicle_list = [] for i in range(number_of_follicles): follicle = pm.createNode("follicle", n="{0}follicle_{1}".format( self.namespace, i), ss=True) follicle_list.append(follicle) follicle.parameterU.set(i * follicle_percentage) follicle.parameterV.set(0.5) follicle_transform = follicle.getParent() follicle.outRotate >> follicle_transform.rotate follicle.outTranslate >> follicle_transform.translate ribbon_shape.local >> follicle.inputSurface ribbon_shape.worldMatrix >> follicle.inputWorldMatrix return ribbon, follicle_list
def create_nurbs(self): self.nurbs = pm.nurbsPlane(name='geo_' + self.ribbon_name, pivot=[0, 0, 0], axis=[0, 1, 0], width=1, lengthRatio=self.ribbon_segment, degree=3, ch=False)[0] self.nurbs.setRotation([0, 90, 0], space='world') pm.makeIdentity(self.nurbs, a=True, rotate=True) # rebuild nurbs to reduce CVs pm.rebuildSurface(self.nurbs, replaceOriginal=True, rebuildType=0, endKnots=1, keepRange=0, keepControlPoints=0, keepCorners=0, spansU=1, degreeU=1, spansV=self.ribbon_segment, degreeV=3, ch=False)
def polyQuadToNurbs(f): pts = f.getPoints() # must rearrange pts - they come in in clockwise fashion, # indeces 2 and 3 must be swapped pts[2], pts[3] = pts[3], pts[2] pl = pmc.nurbsPlane(d=1, ch=0)[0] pl.setCVs(pts) pl.updateSurface() return pl
def createRibbonSpine(*args): jointChainLen = int(jointChainLenField.getText()) nurbsPlnName = nameField.getText() + '_ribbonPlane' nurbsPln = pm.nurbsPlane(u = 1, v = jointChainLen, lr = jointChainLen, n = nurbsPlnName, ax = [0,0,1]) pm.rebuildSurface(nurbsPln, ch = 1, rpo = 1, end = 1, kr = 0, kc = 0, su =1, du = 1, sv = 5, dv = 3, tol = .01, dir = 0) pm.select(nurbsPln, r = True) mNurbsPln = pm.ls(selection = True)[0]
def build(self): # make the nurbs plane self.ribbonIkPlane = pm.nurbsPlane( axis = (0,0,1), degree = 3, #cubic constructionHistory = False, name = self.name +'_'+d.PLANE, patchesU = 1, patchesV = self.numSpans, lengthRatio = self.numSpans)[0] pm.rebuildSurface(self.ribbonIkPlane, degreeU=1, spansU=1, direction=0) u.makeNonRendering(self.ribbonIkPlane) pm.setAttr('%s.%s'% (self.ribbonIkPlane.name(),'visibility'), 0) pm.setAttr('%s.%s'% (self.ribbonIkPlane.name(), 'inheritsTransform'), 0) # move the pivots to the top of the plane self.ribbonIkPlane.setPivots((0,(self.numSpans/2.0),0)) # place and scale the plane in 3d space pm.delete(pm.pointConstraint(self.startLoc,self.ribbonIkPlane)) pm.delete(pm.orientConstraint(self.startLoc,self.ribbonIkPlane)) #pm.delete(pm.aimConstraint(self.endLoc,self.ribbonIkPlane, # aimVector=(0,-1,0))) #skip =('x','z'))) height = u.distance(self.startLoc, self.endLoc) scale = (height / self.numSpans) self.ribbonIkPlane.scaleBy((scale,scale,scale)) # create and attach follicles follicles = [] for i in range(1,(self.numJoints+1)): follicle = self.createFollicle( shape = self.ribbonIkPlane.getShape(), posV = (i-1.0)/float(self.numJoints-1.0), posU = 0.5, name = self.name + "_%s%02d" % (d.FOLLICLE,i)) pm.setAttr(follicle.visibility, False) follicles.append(follicle) self.follicleGrp = pm.group(follicles, name='%s_%s_grp' % \ (self.name,d.FOLLICLE)) pm.setAttr('%s.%s'% (self.follicleGrp,'inheritsTransform'),0) # create the bind joints for i,f in enumerate(follicles): self.bindJoints.append(u.placeJoint( position = u.getWsLocation(f), name = '%s%s%02d_%s'%(self.name, d.JOINT.title(), i+1, self.jointPostfix), parent = f)) # parent self.ribbonIkPlane.setParent(self.parent)
def createPlane(): sel = pm.ls(sl = True)[0] selChild = sel.listRelatives(c = True, typ = 'joint')[0] planSize = selChild.translateX.get() onePlan = pm.nurbsPlane(ch = True, o = True, po = False, ax = [0,1,0], w = planSize, lr = 0.25, u = 3) onePlan[0].setParent(sel) onePlan[0].translate.set([planSize/2,0,0]) onePlan[0].rotate.set([0,0,0]) pm.parent(onePlan, w = True)
def test_createDriveControls(self): fr = FollowRibbon.FollowRibbon(name="blah") plane = pm.nurbsPlane(axis=[0, 1, 0], patchesU=8, patchesV=1, lengthRatio=0.1, ch=0)[0] grps, jnts, cposNodes = fr._createPlaneControls(plane=plane, direction="u", number=4) mainGrp, ctrls = fr._createDriveControls(grps=grps, cposNodes=cposNodes) self.assertEqual(mainGrp, "blah_ctrlsGrp") self.testLib.assertListEqual(ctrls, ["blah_ctrl_01", "blah_ctrl_02", "blah_ctrl_03", "blah_ctrl_04"]) for index in range(4): self.assertTrue(pm.objExists("blah_ctrlTopGrp_%s" % str(index + 1).zfill(2))) self.assertTrue(pm.objExists("blah_ctrlMidGrp_%s" % str(index + 1).zfill(2))) self.assertTrue(pm.objExists("blah_ctrlBtmGrp_%s" % str(index + 1).zfill(2))) self.assertTrue(pm.objExists("blah_InvertMdNode_%s" % str(index + 1).zfill(2))) self.assertTrue(pm.objExists("blah_ctrl_%s" % str(index + 1).zfill(2))) self.assertEqual( pm.listRelatives("blah_ctrlTopGrp_%s" % str(index + 1).zfill(2), parent=1)[0].name(), "blah_ctrlsGrp" ) self.testLib.assertConstrained( grps[index].name(), "blah_ctrlTopGrp_%s" % str(index + 1).zfill(2), type="parent" ) self.assertTrue( pm.isConnected( "blah_ctrl_%s.translate" % str(index + 1).zfill(2), "blah_InvertMdNode_%s.input1" % str(index + 1).zfill(2), ) ) self.assertTrue( pm.isConnected( "blah_InvertMdNode_%s.output" % str(index + 1).zfill(2), "blah_ctrlBtmGrp_%s.translate" % str(index + 1).zfill(2), ) ) self.assertTrue(pm.objExists("blah_ctrl_%s.uParam" % str(index + 1).zfill(2))) self.assertTrue(pm.objExists("blah_ctrl_%s.vParam" % str(index + 1).zfill(2))) self.assertTrue( pm.isConnected( "blah_ctrl_%s.uParam" % str(index + 1).zfill(2), "blah_drvCPOS_%s.parameterU" % str(index + 1).zfill(2), ) ) self.assertTrue( pm.isConnected( "blah_ctrl_%s.vParam" % str(index + 1).zfill(2), "blah_drvCPOS_%s.parameterV" % str(index + 1).zfill(2), ) )
def create_guide(self, parent): if self.options.use_nurbs: xform, _ = pm.nurbsPlane(p=[0, 0, 0], ax=[0, 0, 1], w=1, lr=1, d=3, u=1, v=1, ch=1) else: # -- Create the mesh xform, _ = pm.polyPlane( w=1, h=1, sx=1, sy=1, ax=[0, 1, 0], cuv=2, ch=1, ) # -- Clear all history pm.delete(xform, constructionHistory=True) # -- Re-get the surface, as we're not working with a polyPlane any longer # -- but instead a mesh shape surface = xform.getShape() # -- Parent the surface under guide root xform.setParent(parent) # -- Tag the surface so we can retrieve it later self.tag(xform, 'GuideSurface') # -- Now create the follicle follicle = self.create_follicle( description='Guide{}'.format(self.options.description), side=self.options.side, parent=parent, surface=surface, u=0.5, v=0.5, ) follicle.visibility.set(False) # -- Tag the surface so we can retrieve it later self.tag(follicle, 'GuideFollicle') return True
def build(): ctrl = nurbsPlane(axis=[0, 1, 0], u=2, d=1)[0] xform(ctrl.cv[2][0], ws=True, t=[0.5, 0, 0.2]) xform(ctrl.cv[0][0], ws=True, t=[-0.5, 0, 0.2]) line = curve(d=True, p=[(-0.5, 0, -0.5), (-0.5, 0, 0.2), (0, 0, 0.5), (0.5, 0, 0.2), (0.5, 0, -0.5), (-0.5, 0, -0.5)]) line.rename('outline') line.getShape().setParent(ctrl, add=True, shape=True) delete(line) return ctrl
def makeSimpleSurf(name="UNTITLED_SURF_RIG"): """Create a 2x3 span nurbs plane at the average position of selection with the average normal.""" sel = getSymSelection() if sel: vts = getConnectedCmpnts(sel, "Vertices") normal = getPolyAvgNormal(vts) pos = sum(v.getPosition("world") for v in vts) / len(vts) else: pmc.warning("No guide edges selected, surface created at origin.") normal = (1, 0, 0) pos = (0, 0, 0) return pmc.nurbsPlane(u=3, v=2, ch=0, axis=normal, p=pos, n=name)[0]
def create_plane(self, name, width=10, lengthratio=0.2): """ Create NURBS plane :param name: string :param width: :param lengthratio: :return: """ nurbs_plane = pm.nurbsPlane(name=name, width=width, lengthRatio=lengthratio, patchesU=width / 2, degree=3, axis=[0, 1, 0], constructionHistory=False) return nurbs_plane
def createPlane(): sel = pm.ls(sl=True)[0] selChild = sel.listRelatives(c=True, typ='joint')[0] planSize = selChild.translateX.get() onePlan = pm.nurbsPlane(ch=True, o=True, po=False, ax=[0, 1, 0], w=planSize, lr=0.25, u=3) onePlan[0].setParent(sel) onePlan[0].translate.set([planSize / 2, 0, 0]) onePlan[0].rotate.set([0, 0, 0]) pm.parent(onePlan, w=True)
def build_plane(self, *args): """ builds Nurb plane based on joint slider Args: None Returns (None) """ surface_name = self.flexiPlaneNameField.getText() + '_flexiPlane_SURF' num_nurb_patches = self.flexiPlaneNumSlider.getValue() nurb_plane_width = self.flexiPlaneNumSlider.getValue() * 2 nurb_plane_length_ratio = float(2) / nurb_plane_width surface = pm.nurbsPlane(p= (0, 0, 0), ax= (0, 1, 0), w= nurb_plane_width, lr= nurb_plane_length_ratio, d= 3, u= num_nurb_patches, v= 1, n= surface_name, ch= 0)[0] surface_shape = surface.getShape() attrs = ['castsShadows', 'receiveShadows', 'motionBlur', 'primaryVisibility', 'smoothShading', 'visibleInReflections', 'visibleInRefractions'] for attr in attrs: surface_shape.attr(attr).set(0) surface.setAttr('inheritsTransform', 0) return surface
def test_clusterPlane(self): fr = FollowRibbon.FollowRibbon(name='blah') plane = pm.nurbsPlane(axis=[0, 1, 0], patchesU=8, patchesV=1, lengthRatio=.1, ch=0)[0] ctrls = [] ctrls.append(pm.circle(n='blah_ctrl_01')[0].name()) ctrls.append(pm.circle(n='blah_ctrl_02')[0].name()) mainGrp = pm.group(em=1, name='main') result = fr._clusterPlane(plane=plane, controls=ctrls, mainGrp='main') self.testLib.assertListEqual( result, ['blah_cluster_01Handle', 'blah_cluster_02Handle']) self.assertTrue(pm.objExists('blah_cluster_01')) self.assertTrue(pm.objExists('blah_cluster_02')) self.assertTrue(pm.listRelatives(result[0], parent=True), 'main') self.assertTrue(pm.listRelatives(result[1], parent=True), 'main') self.assertTrue( pm.listRelatives(result[0], parent=1)[0], 'blah_ctrlsGrp') self.assertTrue( pm.listRelatives(result[1], parent=1)[0], 'blah_ctrlsGrp') hist = pm.listHistory(plane) hitA = 0 hitB = 0 for each in hist: if each.name() == 'blah_cluster_01': hitA = 1 if each.name() == 'blah_cluster_02': hitB = 1 self.assertTrue(hitA) self.assertTrue(hitB) self.assertTrue( pm.isConnected('blah_ctrl_01.translate', 'blah_cluster_01Handle.translate')) self.assertTrue( pm.isConnected('blah_ctrl_02.translate', 'blah_cluster_02Handle.translate'))
def nurbPlaneBetweenObjects(self, Object01, Object02): VP1 = om.MVector(pm.xform(Object01, a=True, ws=True, q=True, rp=True)) VP2 = om.MVector(pm.xform(Object02, a=True, ws=True, q=True, rp=True)) longitud = VP1 - VP2 plano = pm.nurbsPlane(ax=[0, 1, 0], p=[(longitud.length()) / 2, 0, 0], w=longitud.length(), lr=.05, d=3, u=8, v=1, ch=0, name="%sTo%sPlane" % (self.name_conv.get_a_short_name(Object01), self.name_conv.get_a_short_name(Object02))) self.name_conv.set_name_in_format(plano, useName=True) RMRigTools.RMAlign(Object01, plano[0], 3) return plano[0]
def nurbPlaneBetweenObjects(self, Object01, Object02): VP1 = om.MVector(pm.xform(Object01, a=True, ws=True, q=True, rp=True)) print VP1 VP2 = om.MVector(pm.xform(Object02, a=True, ws=True, q=True, rp=True)) print VP2 longitud = VP1 - VP2 plano = pm.nurbsPlane(ax=[0, 1, 0], p=[(longitud.length()) / 2, 0, 0], w=longitud.length(), lr=.05, d=3, u=8, v=1, ch=0, name="bendyPlane") self.name_conv.rename_name_in_format(plano, useName=True) pm.matchTransform(plano[0], Object01) return plano[0]
def nurb_plane_between_objects(self, object_a, object_b): vector_a = om.MVector( pm.xform(object_a, a=True, ws=True, q=True, rp=True)) vector_b = om.MVector( pm.xform(object_b, a=True, ws=True, q=True, rp=True)) length = vector_a - vector_b plano = pm.nurbsPlane(ax=[0, 1, 0], p=[(length.length()) / 2, 0, 0], w=length.length(), lr=.05, d=3, u=8, v=1, ch=0, name="bendyPlane") self.name_convention.rename_name_in_format(plano[0], useName=True) pm.matchTransform(plano[0], object_a) return plano[0]
def build(): #crv = curve( d=1, p=((0, 0, 0), (0, 0, .5))) #ctrl = revolve( crv, ch=False, ssw=0, esw=360, degree=3, ax=[0, 1, 0] )[0] line = curve(d=1, p=[ (-0.5, 0, 0.5), (0.5, 0, 0.5), (0.5, 0, -0.5), (-0.5, 0, -0.5), (-0.5, 0, 0.5), ] # noqa ) line.rename('outline') ctrl = nurbsPlane( ax=[0, 1, 0], w=1, d=1, lr=1 )[0] line.getShape().setParent( ctrl, add=True, shape=True ) delete(line) return ctrl
def make_chain_surface(cls, spans=10): count = 1 nurbs = pm.nurbsPlane(u=1, v=spans, lr=5, n="surface") geo = pm.PyNode(nurbs[0]) fols = [] fol_shapes = [] while count < spans: fol = pm.createNode('transform', n='follicle1', ss=True) fol_shape = pm.createNode('follicle', name="folicle_shape", p=fol, ss=True) pm.connectAttr(geo.local, fol_shape.inputSurface) pm.connectAttr(geo.worldMatrix[0], fol_shape.inputWorldMatrix) pm.connectAttr(fol_shape.outRotate, fol.rotate) pm.connectAttr(fol_shape.outTranslate, fol.translate) fol.inheritsTransform.set(False) fol_shape.parameterU.set(0.5) fol_shape.parameterV.set(0.1 * count) fols.append(fol) fol_shapes.append(fol_shapes) count += 1 nurbs_jnts = Chain.make_jnt_chain( fols, name_template="_surface_{number}_JNT") for nurbs_JNT, fol in zip(nurbs_jnts[0:], fols[:-1]): nurbs_JNT.setParent(fol) drivers = [] driver_a_jnt = pm.duplicate(nurbs_jnts[0], name="driver_A") driver_b_jnt = pm.duplicate(nurbs_jnts[(spans / 2) - 1], name="driver_B") driver_c_jnt = pm.duplicate(nurbs_jnts[-1], name="driver_C") drivers.append(driver_a_jnt) drivers.append(driver_b_jnt) drivers.append(driver_c_jnt) pm.parent(drivers, w=True) for driver in drivers: pm.setAttr(driver[0] + ".radius", 1.5) pm.bindSkin(nurbs, drivers)
def build_nurbs_between_points(xformA, xformB, ref_xform, spansUV=[1,4]): """ Build a simple nurbs surface between two points with a surface up third object Args: xformA (pm.nt.Transform): first point xformB (pm.nt.Transform): second point ref_xform (pm.nt.Transform): aim object Usage: Mesh.build_nurbs_between_points(pm.PyNode('locator1'),pm.PyNode('locator2'),pm.PyNode('locator3')) """ nurbs = pm.nurbsPlane(p=[0,0,0], ax=[0,1,0], w=1, lr=1, d=1, u=1, v=1, ch=0)[0] nurbs.scalePivot.set(0,0,0.5) nurbs.rotatePivot.set(0,0,0.5) pm.delete(pm.pointConstraint(xformA, nurbs, mo=False)) pm.delete(pm.aimConstraint(xformB, nurbs, worldUpType=1, aimVector=[0,0,-1], worldUpVector=[0,1,0], worldUpObject=ref_xform, mo=False)) cluster = pm.cluster(nurbs.getShape().cv[0:1][1]) pm.delete(pm.pointConstraint(xformB, cluster, mo=False)) pm.delete(nurbs, ch=True) u, v = spansUV pm.rebuildSurface(nurbs.getShape(), ch=False, rpo=1, rt=0, end=1, kr=0, kcp=0, kc=0, su=u, du=3, sv=v, dv=3, tol=0, fr=0, dir=2) return nurbs
def create_surface_plane(align_to=None, axis='x', width=0.5, freeze_tm=True): """Create surface plane and return transform pynode of the surface plane. :key align_to: Target align of the newly created surface. :type align_to: pm.nt.Transform :key axis: Surface normal direction in 'x', 'y', 'z'. Default 'x' :type axis: str :key width: The width of the plane. Default: 0.5 :type width: float :key freeze_tm: If True, freeze_transform operation will be applied to the newly created surface. :type freeze_tm: bool :rtype: pm.nt.Transform """ axis_dict = {'x': (1, 0, 0), 'y': (0, 1, 0), 'z': (0, 0, 1)} res = pm.nurbsPlane(axis=axis_dict[axis], width=width, degree=1, constructionHistory=False)[0] if align_to is not None: transformation.align(res, align_to) if freeze_tm: transformation.freeze_transform(res) return res
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
def test_createPlaneControls(self): fr = FollowRibbon.FollowRibbon(name="blah") plane = pm.nurbsPlane(axis=[0, 1, 0], patchesU=8, patchesV=1, lengthRatio=0.1, ch=0)[0] grps, jnts, cposNodes = fr._createPlaneControls(plane=plane, direction="u", number=6) self.testLib.assertListEqual( cposNodes, [ "blah_drvCPOS_01", "blah_drvCPOS_02", "blah_drvCPOS_03", "blah_drvCPOS_04", "blah_drvCPOS_05", "blah_drvCPOS_06", ], ) self.assertEqual(grps[0].name(), "blah_drvGrp_01") self.assertEqual(grps[1].name(), "blah_drvGrp_02") self.assertEqual(grps[2].name(), "blah_drvGrp_03") self.assertEqual(grps[3].name(), "blah_drvGrp_04") self.assertEqual(grps[4].name(), "blah_drvGrp_05") self.assertEqual(grps[5].name(), "blah_drvGrp_06") self.assertEqual(jnts[0].name(), "blah_drvJnt_01") self.assertEqual(jnts[1].name(), "blah_drvJnt_02") self.assertEqual(jnts[2].name(), "blah_drvJnt_03") self.assertEqual(jnts[3].name(), "blah_drvJnt_04") self.assertEqual(jnts[4].name(), "blah_drvJnt_05") self.assertEqual(jnts[5].name(), "blah_drvJnt_06") self.assertTrue(pm.objExists("blah_drvCPOS_01")) self.assertTrue(pm.objExists("blah_drvCPOS_02")) self.assertTrue(pm.objExists("blah_drvCPOS_03")) self.assertTrue(pm.objExists("blah_drvCPOS_04")) self.assertTrue(pm.objExists("blah_drvCPOS_05")) self.assertTrue(pm.objExists("blah_drvCPOS_06")) self.assertEqual(pm.getAttr("blah_drvCPOS_01.turnOnPercentage"), 1) self.assertEqual(pm.getAttr("blah_drvCPOS_01.parameterV"), 0.5) self.assertEqual(pm.getAttr("blah_drvCPOS_02.parameterV"), 0.5) self.assertEqual(pm.getAttr("blah_drvCPOS_03.parameterV"), 0.5) self.assertEqual(pm.getAttr("blah_drvCPOS_04.parameterV"), 0.5) self.assertEqual(pm.getAttr("blah_drvCPOS_05.parameterV"), 0.5) self.assertEqual(pm.getAttr("blah_drvCPOS_06.parameterV"), 0.5) self.assertAlmostEquals(pm.getAttr("blah_drvCPOS_01.parameterU"), 0) self.assertAlmostEquals(pm.getAttr("blah_drvCPOS_02.parameterU"), 0.2, 2) self.assertAlmostEquals(pm.getAttr("blah_drvCPOS_03.parameterU"), 0.4, 2) self.assertAlmostEquals(pm.getAttr("blah_drvCPOS_04.parameterU"), 0.6, 2) self.assertAlmostEquals(pm.getAttr("blah_drvCPOS_05.parameterU"), 0.8, 2) self.assertAlmostEquals(pm.getAttr("blah_drvCPOS_06.parameterU"), 1) self.assertTrue(pm.objExists("blah_drvGrp_01")) self.assertTrue(pm.objExists("blah_drvGrp_02")) self.assertTrue(pm.objExists("blah_drvGrp_03")) self.assertTrue(pm.objExists("blah_drvGrp_04")) self.assertTrue(pm.objExists("blah_drvGrp_05")) self.assertTrue(pm.objExists("blah_drvGrp_06")) self.assertTrue(pm.isConnected("blah_drvCPOS_01.position", "blah_drvGrp_01.translate")) self.assertTrue(pm.isConnected("blah_drvCPOS_02.position", "blah_drvGrp_02.translate")) self.assertTrue(pm.isConnected("blah_drvCPOS_03.position", "blah_drvGrp_03.translate")) self.assertTrue(pm.isConnected("blah_drvCPOS_04.position", "blah_drvGrp_04.translate")) self.assertTrue(pm.isConnected("blah_drvCPOS_05.position", "blah_drvGrp_05.translate")) self.assertTrue(pm.isConnected("blah_drvCPOS_06.position", "blah_drvGrp_06.translate")) self.assertTrue(pm.objExists("blah_drvJnt_01")) self.assertTrue(pm.objExists("blah_drvJnt_02")) self.assertTrue(pm.objExists("blah_drvJnt_03")) self.assertTrue(pm.objExists("blah_drvJnt_04")) self.assertTrue(pm.objExists("blah_drvJnt_05")) self.assertTrue(pm.objExists("blah_drvJnt_06")) self.assertEqual(pm.listRelatives("blah_drvJnt_01", parent=1)[0], "blah_drvGrp_01") self.assertEqual(pm.listRelatives("blah_drvJnt_02", parent=1)[0], "blah_drvGrp_02") self.assertEqual(pm.listRelatives("blah_drvJnt_03", parent=1)[0], "blah_drvGrp_03") self.assertEqual(pm.listRelatives("blah_drvJnt_04", parent=1)[0], "blah_drvGrp_04") self.assertEqual(pm.listRelatives("blah_drvJnt_05", parent=1)[0], "blah_drvGrp_05") self.assertEqual(pm.listRelatives("blah_drvJnt_06", parent=1)[0], "blah_drvGrp_06")
def create_ribbon(numJoints=10, prefix='testRibbon', numSpans=5, startObj=None, endObj=None): rigGrp = pm.group(empty=True, name='%s_rig_grp' %prefix) ctrlGrp = pm.group(empty=True, name="%s_ctrl_grp" %prefix) proxyGrp = pm.group(empty=True, name="%s_proxy_grp" %prefix) ctrlGrp.overrideDisplayType.set(1) #template proxyGrp.visibility >> ctrlGrp.overrideEnabled #=========================================================================== # proxy #=========================================================================== proxy_start = pm.spaceLocator(name='%s_root_start' %prefix) pm.parent( proxy_start.add_parent_group(suffix='const'), proxyGrp) proxy_end = pm.spaceLocator(name='%s_root_end' %prefix) proxy_end.tx.set(1) pm.parent( proxy_end.add_parent_group(suffix='const'), proxyGrp) #=========================================================================== # proxy #=========================================================================== rootCtrl = pm.spaceLocator(name='%s_root_ctrl' %prefix) pm.parent(pm.parentConstraint(proxy_start, rootCtrl, mo=False), proxyGrp) pm.parent(rootCtrl, ctrlGrp) proxy_up = pm.spaceLocator(name='%s_root_up' %prefix) proxy_up.ty.set(1) pm.parent( proxy_up.add_parent_group(suffix='const'), proxyGrp) proxy_mid = pm.spaceLocator(name='%s_root_mid' %prefix) proxy_mid.tx.set(1) proxy_mid_const = proxy_mid.add_parent_group(suffix='const') pm.parent( proxy_mid_const, proxyGrp) pm.pointConstraint(proxy_start, proxy_end, proxy_mid_const, mo=False) pm.aimConstraint(proxy_end, proxy_start, aimVector=[1,0,0], upVector=[0,1,0], worldUpType='object', worldUpObject=proxy_up.name()) pm.aimConstraint(proxy_start, proxy_end, aimVector=[-1,0,0], upVector=[0,1,0], worldUpType='object', worldUpObject=proxy_up.name()) pm.parentConstraint(rootCtrl, rigGrp, mo=False) #=========================================================================== # ribbon plane #=========================================================================== ribbonGrp = pm.group(empty=True, name="%s_ribbon_grp" %prefix) pm.parent(ribbonGrp, rigGrp) follicleGrp = pm.group(empty=True, name="%s_follicle_grp" %prefix) pm.parent(follicleGrp, rigGrp) follicleGrp.inheritsTransform.set(0) follicleGrp.overrideDisplayType.set(2) #reference proxyGrp.visibility >> follicleGrp.overrideEnabled ribbonName = "%s_ribbon" %prefix ribbon = pm.nurbsPlane(ax=[0,1,0], w=1, lr=0.05, d=3, u=10, v=1, ch=0, name=ribbonName)[0] ribbon.translateX.set(0.5) ribbon.rotateX.set(90) pm.makeIdentity(ribbon, apply=True, t=1 ,r=1 ,s=1, n=0 ,pn=1) ribbon.scalePivot.set(0,0,0) ribbon.rotatePivot.set(0,0,0) pm.parent(ribbon, ribbonGrp) ribbonGrp.visibility.set(0) #proxy_start.rotateX >> ribbon.rotateX #=========================================================================== # ribbon follicles / joints #=========================================================================== joints = [] proxyCubes = [] spacing = (1.0/(numJoints-1)) for i in range(numJoints): uPos = i * spacing jointName = "%s_%d" %(prefix, i+1) fol = create_follicle(ribbon, uPos, 0.5) fol_trans = fol.getParent() pm.select(clear=True) joint = pm.joint(name=jointName) #======================================================================= cube = pm.polyCube(w=spacing, h=spacing, d=spacing, ch=False)[0] pm.parentConstraint(joint, cube) pm.parent(cube, joint) # pm.parent(cube, proxyGrp) proxyCubes.append(cube) cube.overrideEnabled.set(1) cube.overrideDisplayType.set(2) #reference #======================================================================= pm.parent(joint, fol_trans, r=True) pm.parent(fol_trans, follicleGrp) joints.append(joint) #=========================================================================== # ribbon wires #=========================================================================== wireGrp = pm.group(empty=True, name="%s_wire_grp" %prefix) pm.parent(wireGrp, rigGrp) wireCtrlGrp = pm.group(empty=True, name='%s_wire_ctrl_grp' %prefix) pm.parent(wireCtrlGrp, rootCtrl) wireCtrlGrp.inheritsTransform.set(0) wireName = '%s_wire' %prefix wireCurve = pm.curve(d=2, p=[[0,0,0],[0.5,0,0],[1,0,0]], k=[0,0,1,1], name=wireName) mel.eval("rebuildCurve -ch 0 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 0 -kep 1 -kt 0 -s %d -d 2 %s" %(numSpans, wireCurve.name())) wire2, wireCurve, wireBaseCurve = wire_deformer( wireCurve, ribbon) pm.parent(wireCurve, wireBaseCurve, wireGrp) #pm.reorderDeformers(wire1, wire2, ribbon) #=========================================================================== # ribbon curve/ctrls #=========================================================================== curve = pm.curve(d=2, p=[[0,0,0],[0.5,0,0],[1,0,0]], k=[0,0,1,1], name="%s_curve"%prefix) pm.parent(curve, ribbonGrp) #wire1, curve, baseCurve = wire_deformer( curve, wireCurve) ctrls=[] for cv in curve.cv: clusterName = '%s_curve%d_cluster' %(prefix, cv.index()) ctrlName = "%s_curve%d_ctrl" %(prefix, cv.index()) cluster, clusterHandle = pm.cluster(cv, relative=True, name=clusterName) clusterHandle.visibility.set(0) ctrl = pm.spaceLocator(name=ctrlName) pm.delete(pm.pointConstraint(clusterHandle, ctrl, mo=False)) pm.parentConstraint(ctrl, clusterHandle) ctrls.append(ctrl) pm.parent(clusterHandle, ribbonGrp) startCtrl = ctrls[0] midCtrl = ctrls[1] endCtrl = ctrls[-1] startCtrlName = "%s_start_ctrl" %prefix endCtrlName = "%s_end_ctrl" %prefix startCtrl.rename("%s_start_ctrl" %prefix) startConst = startCtrl.add_parent_group(suffix='const') pm.parent(pm.parentConstraint(proxy_start, startConst, mo=False), proxyGrp) endCtrl.rename("%s_end_ctrl" %prefix) endConst = endCtrl.add_parent_group(suffix='const') pm.parent(pm.parentConstraint(proxy_end, endConst, mo=False), proxyGrp) midCtrl.rename("%s_mid_ctrl" %prefix) midConst = midCtrl.add_parent_group(suffix='const') pm.parent(pm.parentConstraint(proxy_mid, midConst, mo=False), proxyGrp) startCtrl.getShape().localPositionX.set(-1) endCtrl.getShape().localPositionX.set(1) pm.parent(startConst, endConst, midConst, rootCtrl) #=========================================================================== # ribbon wire cluster #=========================================================================== for cv in wireCurve.cv: #cluster / ctrl clusterName = '%s_wire%d_cluster' %(prefix, cv.index()) ctrlName = "%s_wire%d_ctrl" %(prefix, cv.index()) cluster, clusterHandle = pm.cluster(cv, relative=True, name=clusterName) ctrl = pm.spaceLocator(name=ctrlName) pm.delete(pm.pointConstraint(clusterHandle, ctrl, mo=False)) pm.parentConstraint(ctrl, clusterHandle) pm.scaleConstraint(ctrl, clusterHandle) #ctrl.t >> clusterHandle.t #ctrl.r >> clusterHandle.r #ctrl.s >> clusterHandle.s ctrls.append(ctrl) pm.parent(clusterHandle, wireGrp) #revit revit = pm.spaceLocator(name="%s_revit" %ctrl.name()) revit.getShape().localScale.set(0,0,0) pm.delete(pm.parentConstraint(ctrl, revit, mo=False)) pm.parent(ctrl, revit) revit_locator_to_curve(revit, curve) rootCtrl.r >> revit.r pm.parent(revit, wireCtrlGrp) wireGrp.visibility.set(0) #=========================================================================== # twist #=========================================================================== twistGrp = pm.group(empty=True, name="%s_twist_grp" %prefix) pm.parent(twistGrp, rigGrp) startTwist = pm.group(empty=True, name="%s_start_twist" %prefix) startTwistAim = startTwist.add_parent_group(suffix='aim') pm.pointConstraint(startCtrl, startTwistAim, mo=False) endTwist = pm.group(empty=True, name="%s_end_twist" %prefix) endTwistAim = endTwist.add_parent_group(suffix='aim') pm.pointConstraint(endCtrl, endTwistAim, mo=False) startTwistUp = pm.spaceLocator(name="%s_start_twistUp" %prefix) pm.delete(pm.parentConstraint(startCtrl, startTwistUp, mo=False)) startTwistUp.ty.set(1) pm.parentConstraint(startCtrl, startTwistUp, mo=True) endTwistUp = pm.spaceLocator(name="%s_end_twistUp" %prefix) pm.parentConstraint(endCtrl, endTwistUp, mo=False) endTwistUp.ty.set(1) const = pm.parentConstraint(endCtrl, endTwistUp, mo=True) pm.aimConstraint(endTwistAim, startTwistAim, aimVector=[1,0,0], upVector=[0,1,0], worldUpType='objectrotation', worldUpVector=[0,1,0], worldUpObject=startCtrl.name()) pm.aimConstraint(startTwistAim, endTwistAim, aimVector=[-1,0,0], upVector=[0,1,0], worldUpType='objectrotation', worldUpVector=[0,1,0], worldUpObject=endCtrl.name()) #pm.aimConstraint(endTwist, startTwist, aimVector=[1,0,0], upVector=[0,1,0], worldUpType='object', worldUpObject=startTwistUp.name()) #pm.aimConstraint(startTwist, endTwist, aimVector=[-1,0,0], upVector=[0,1,0], worldUpType='object', worldUpObject=endTwistUp.name()) twist, twistHdl = pm.nonLinear(ribbon , type='twist', foc=True, name='%s_twist'%prefix) twistHdl.rotateZ.set(90) startTwistAim.rx >> twist.endAngle endTwistAim.rx >> twist.startAngle #startTwist.rx >> twist.endAngle #endTwist.rx >> twist.startAngle pm.parent(startTwistUp, endTwistUp, twistHdl, startTwistAim, endTwistAim, twistGrp) twistGrp.visibility.set(0) #=========================================================================== # stretch and squash #=========================================================================== stretchGrp = pm.group(empty=True, name="%s_stretch_grp" %prefix) stretchGrp.addAttr('baseDistance', at='double') pm.parent(stretchGrp, rigGrp) stretchGrp.inheritsTransform.set(0) stretchPlane = pm.nurbsPlane(ax=[0,1,0], ch=False, w=2, lr=1, d=3, u=2, v=2, name='%s_stretch_plane'%prefix) squash, squashHdl = pm.nonLinear(stretchPlane, type='squash', foc=True, name="%s_squash"%prefix) squashHdl.rotateZ.set(90) for i in range(numJoints): spacing = i * (1.0/(numJoints-1)) pointOnSurface = pm.createNode('pointOnSurfaceInfo') stretchPlane[0].getShape().worldSpace[0] >> pointOnSurface.inputSurface pointOnSurface.parameterU.set(spacing) pointOnSurface.positionZ >> joints[i].sz pointOnSurface.positionZ >> joints[i].sy baseDistance = pm.createNode('distanceBetween', name="%s_base_distance" %prefix) proxy_start.getShape().worldPosition[0] >> baseDistance.point1 proxy_end.getShape().worldPosition[0] >> baseDistance.point2 stretchDistance = pm.createNode('distanceBetween', name="%s_stretch_distance" %prefix) stretchDistanceStart = pm.spaceLocator(name="%s_stretch_distance_start" %prefix) stretchDistanceStart.localScale.set(0,0,0) pm.parentConstraint(startCtrl, stretchDistanceStart, mo=False) stretchDistanceEnd = pm.spaceLocator(name="%s_stretch_distance_end" %prefix) stretchDistanceEnd.localScale.set(0,0,0) pm.parentConstraint(endCtrl, stretchDistanceEnd, mo=False) stretchDistanceStart.getShape().worldPosition[0] >> stretchDistance.point1 stretchDistanceEnd.getShape().worldPosition[0] >> stretchDistance.point2 strechFactor_md = pm.createNode('multiplyDivide', name='%s_stretch_distance_md' %prefix) strechFactor_md.operation.set(2) #divide baseDistance.distance >> stretchGrp.baseDistance stretchGrp.baseDistance >> strechFactor_md.input2X stretchDistance.distance >> strechFactor_md.input1X strechFactor_remap = pm.createNode('remapValue', name="%s_stretch_factor_remap" %prefix) strechFactor_md.outputX >> strechFactor_remap.inputValue strechFactor_remap.inputMin.set(0.5) strechFactor_remap.inputMax.set(1.5) strechFactor_remap.outputMin.set(-1) strechFactor_remap.outputMax.set(1) strechFactor_remap.outValue >> squash.factor pm.parent(stretchDistanceStart, stretchDistanceEnd, stretchPlane, squashHdl, stretchGrp) stretchGrp.visibility.set(0) #=========================================================================== for cube in proxyCubes: stretchGrp.baseDistance >> cube.sx stretchGrp.baseDistance >> cube.sy stretchGrp.baseDistance >> cube.sz stretchGrp.baseDistance >> ribbon.sz #=========================================================================== #=========================================================================== # Positioning #=========================================================================== if startObj and endObj: pm.delete(pm.parentConstraint(startObj, proxy_start, mo=False)) pm.delete(pm.parentConstraint(endObj, proxy_end, mo=False)) pm.delete(pm.parentConstraint(startObj, proxy_up, mo=False)) proxy_up.ty.set(proxy_up.ty.get() + 1)
def create_surface(self, name='Surface', epsilon=0.001, default_scale=1.0): """ Create a simple rig to deform a nurbsSurface, allowing the rigger to easily provide a surface for the influence to slide on. :param name: The suffix of the surface name to create. :return: A pymel.nodetypes.Transform instance of the created surface. """ nomenclature = self.get_nomenclature_rig().copy() nomenclature.add_tokens(name) root = pymel.createNode('transform') pymel.addAttr(root, longName='bendUpp', k=True) pymel.addAttr(root, longName='bendLow', k=True) pymel.addAttr(root, longName='bendSide', k=True) # Create Guide plane_transform, plane_make = pymel.nurbsPlane(patchesU=4, patchesV=4) # Create Bends bend_side_deformer, bend_side_handle = pymel.nonLinear(plane_transform, type='bend') bend_upp_deformer, bend_upp_handle = pymel.nonLinear(plane_transform, type='bend') bend_low_deformer, bend_low_handle = pymel.nonLinear(plane_transform, type='bend') plane_transform.r.set(0, -90, 0) bend_side_handle.r.set(90, 90, 0) bend_upp_handle.r.set(180, 90, 0) bend_low_handle.r.set(180, 90, 0) bend_upp_deformer.highBound.set(0) # create pymel warning bend_low_deformer.lowBound.set(0) # create pymel warning plane_transform.setParent(root) bend_side_handle.setParent(root) bend_upp_handle.setParent(root) bend_low_handle.setParent(root) pymel.connectAttr(root.bendSide, bend_side_deformer.curvature) pymel.connectAttr(root.bendUpp, bend_upp_deformer.curvature) pymel.connectAttr(root.bendLow, bend_low_deformer.curvature) # Rename all the things! root.rename(nomenclature.resolve('SurfaceGrp')) plane_transform.rename(nomenclature.resolve('Surface')) bend_upp_deformer.rename(nomenclature.resolve('UppBend')) bend_low_deformer.rename(nomenclature.resolve('LowBend')) bend_side_deformer.rename(nomenclature.resolve('SideBend')) bend_upp_handle.rename(nomenclature.resolve('UppBendHandle')) bend_low_handle.rename(nomenclature.resolve('LowBendHandle')) bend_side_handle.rename(nomenclature.resolve('SideBendHandle')) # Try to guess the desired position min_x = None max_x = None pos = pymel.datatypes.Vector() for jnt in self.jnts: pos += jnt.getTranslation(space='world') if min_x is None or pos.x < min_x: min_x = pos.x if max_x is None or pos.x > max_x: max_x = pos.x pos /= len(self.jnts) root.setTranslation(pos) # Try to guess the scale length_x = max_x - min_x if len(self.jnts) <= 1 or length_x < epsilon: log.debug("Cannot automatically resolve scale for surface. Using default value {0}".format(default_scale)) length_x = default_scale root.scaleX.set(length_x) root.scaleY.set(length_x * 0.5) root.scaleZ.set(length_x) pymel.select(root) # self.input.append(plane_transform) return plane_transform
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
def makeCard(jointCount=5, jointNames={'repeat': 'DEFAULT'}, rigInfo=None, size=(4, 6), suffix=''): ''' .. todo:: Do not use defaults. &&& names is really joints names, make it so. ''' if isinstance(jointNames, basestring): head, repeat, tail = util.parse(jointNames) jointNames = {'head': head, 'repeat': repeat, 'tail': tail} elif isinstance(jointNames, list): jointNames = {'head': jointNames} leadName = jointNames.get('head')[0] if jointNames.get( 'head') else jointNames.get('repeat', 'DEFAULT') joints = [] width, height = size # Base the card name off the lead joint cardName = leadName if not isinstance(cardName, basestring): cardName = cardName[0] #jointNames = ' '.join(jointNames) if not cardName.endswith('_card'): if cardName.endswith('_'): cardName += 'card' else: cardName += '_card' # Make the actual card and tag with attrs card = nurbsPlane(w=width, lr=height / float(width), ax=(1, 0, 0), n=cardName, d=1, u=1, v=1)[0] card.addAttr('moRigData', dt='string') card.addAttr('moRigState', dt='string') addOutputControlsAttrs(card) addJointArrayAttr(card) #card.addAttr( 'skeletonInfo', at='bool' ) #card.addAttr( 'buildOrder', at='long' ) #card.addAttr( 'nameInfo', dt='string' ) #card.addAttr( 'suffix', dt='string' ) # Reassign it so it gets the proper interface now that it has the attrs card = PyNode(card) rigData = { 'buildOrder': 10, 'mirrorCode': suffix, 'nameInfo': jointNames, } card.rigData = rigData #card.buildOrder.set( 10 ) #card.suffix.set( suffix ) #card.nameInfo.set( jointNames ) # &&& I hate how I handle the names, want to put in rigInfo (I think that's the json attr...) #card.rigParams = '' #card.rigOptions = '' arrow = makeArrow() arrow.setParent(card) arrow.rename('arrow') card.scale >> arrow.inverseScale arrow.t.set(0, 0, 0) arrow.r.set(0, 0, -90) hide(arrow) card.setParent(proxy.masterGroup()) # Place all the joints delta = height / float(jointCount - 1) if jointCount > 1 else 0 for i in range(jointCount): newJoint = card.addJoint() joints.append(newJoint) newJoint.ty.set(height / 2.0 - delta * i) if len(joints) > 1: for parentBpj, childBpj in zip(joints[0:-1], joints[1:]): proxy.pointer(parentBpj, childBpj) elif joints: proxy.makeProxy(joints[0], proxy.getProxyGroup()) joints[0].ty.set(0) if joints: card.setTempNames() pivToStart(card) return card
def create_ribbon(numJoints=5, prefix='testRibbon', degree=None, spans=None ): rigGrp = pm.group(empty=True, name='%s_rig_grp' %prefix) root = pm.spaceLocator(name='%s_root' %prefix) #=========================================================================== # ribbon plane #=========================================================================== ribbonName = "%s_ribbon" %prefix ribbon = pm.nurbsPlane(ax=[0,1,0], w=1, lr=0.05, d=3, u=10, v=1, ch=0, name=ribbonName)[0] ribbon.translateX.set(0.5) pm.makeIdentity(ribbon, apply=True, t=1 ,r=1 ,s=1, n=0 ,pn=1) pm.parent(ribbon, rigGrp) #=========================================================================== # ribbon follicles / joints #=========================================================================== for i in range(numJoints): spacing = i * (1.0/(numJoints-1)) jointName = "%s_%d" %(prefix, i+1) fol = create_follicle(ribbon, spacing, 0.5) fol_trans = fol.getParent() pm.select(clear=True) joint = pm.joint(name=jointName) pm.parent(joint, fol_trans, r=True) pm.parent(fol, rigGrp) #=========================================================================== # ribbon wires #=========================================================================== curveName = '%s_wire' %prefix curve = pm.curve(d=2, p=[[0,0,0],[0.5,0,0],[1,0,0]], k=[0,0,1,1], name=curveName) if spans and degree: mel.eval("rebuildCurve -ch 0 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 0 -kep 1 -kt 0 -s %d -d %d %s" %(spans, degree, curve.name())) wires = wire_deformer( curve.name(), ribbon.name()) pm.parent(wires, rigGrp) #=========================================================================== # ribbon wire control #=========================================================================== ctrls = [] for cv in curve.cv: clusterName = '%s_wire%d_cluster' %(prefix, cv.index()) ctrlName = "%s_wire%d_ctrl" %(prefix, cv.index()) cluster, clusterHandle = pm.cluster(cv, relative=True, name=clusterName) ctrl = pm.spaceLocator(name=ctrlName) pm.delete(pm.pointConstraint(clusterHandle, ctrl, mo=False)) pm.parentConstraint(ctrl, clusterHandle) ctrls.append(ctrl) pm.parent(clusterHandle, rigGrp) #=========================================================================== # ribbon start/end ctrls #=========================================================================== startCtrlName = "%s_start_ctrl" %prefix endCtrlName = "%s_end_ctrl" %prefix ctrls[0].rename(startCtrlName) startConst = ctrls[0].add_parentGroup(suffix='const') ctrls[-1].rename(endCtrlName) endConst = ctrls[-1].add_parentGroup(suffix='const') pm.parent(startConst, endConst, root) #=========================================================================== # mid ctrls #=========================================================================== for ctrl in ctrls[1:-1]: value = ctrl.translateX.get() ctrlConst = ctrl.add_parentGroup(suffix='const') pm.parentConstraint(ctrls[-1], ctrlConst, w=value) pm.parentConstraint(ctrls[0], ctrlConst, w=1-value) pm.parent(ctrlConst, root)
def create_surface(self, name='Surface'): """ Create a simple rig to deform a nurbsSurface, allowing the rigger to easily provide a surface for the influence to slide on. :param name: The suffix of the surface name to create. :return: A pymel.nodetypes.Transform instance of the created surface. """ nomenclature = self.get_nomenclature_rig().copy() nomenclature.add_tokens(name) root = pymel.createNode('transform') pymel.addAttr(root, longName='bendUpp', k=True) pymel.addAttr(root, longName='bendLow', k=True) pymel.addAttr(root, longName='bendSide', k=True) # Create Guide plane_transform, plane_make = pymel.nurbsPlane(patchesU=4, patchesV=4) # Create Bends bend_side_deformer, bend_side_handle = pymel.nonLinear(plane_transform, type='bend') bend_upp_deformer, bend_upp_handle = pymel.nonLinear(plane_transform, type='bend') bend_low_deformer, bend_low_handle = pymel.nonLinear(plane_transform, type='bend') plane_transform.r.set(0, -90, 0) bend_side_handle.r.set(90, 90, 0) bend_upp_handle.r.set(180, 90, 0) bend_low_handle.r.set(180, 90, 0) bend_upp_deformer.highBound.set(0) # create pymel warning bend_low_deformer.lowBound.set(0) # create pymel warning plane_transform.setParent(root) bend_side_handle.setParent(root) bend_upp_handle.setParent(root) bend_low_handle.setParent(root) pymel.connectAttr(root.bendSide, bend_side_deformer.curvature) pymel.connectAttr(root.bendUpp, bend_upp_deformer.curvature) pymel.connectAttr(root.bendLow, bend_low_deformer.curvature) # Rename all the things! root.rename(nomenclature.resolve('SurfaceGrp')) plane_transform.rename(nomenclature.resolve('Surface')) bend_upp_deformer.rename(nomenclature.resolve('UppBend')) bend_low_deformer.rename(nomenclature.resolve('LowBend')) bend_side_deformer.rename(nomenclature.resolve('SideBend')) bend_upp_handle.rename(nomenclature.resolve('UppBendHandle')) bend_low_handle.rename(nomenclature.resolve('LowBendHandle')) bend_side_handle.rename(nomenclature.resolve('SideBendHandle')) # Try to guess the desired position min_x = None max_x = None pos = pymel.datatypes.Vector() for jnt in self.jnts: pos += jnt.getTranslation(space='world') if min_x is None or pos.x < min_x: min_x = pos.x if max_x is None or pos.x > max_x: max_x = pos.x pos /= len(self.jnts) length_x = max_x - min_x root.setTranslation(pos) root.scaleX.set(length_x) root.scaleY.set(length_x * 0.5) root.scaleZ.set(length_x) pymel.select(root) #self.input.append(plane_transform) return plane_transform
def CreateSurface(pos1, pos2, Div=10): try: pm.select(pos1) tempPos = pm.cluster(n='Temp')[1] JntPos1 = pm.createNode('joint', n=(pos1 + '_Pos1Jnt')) pm.delete(pm.parentConstraint(tempPos, JntPos1)) pm.makeIdentity(JntPos1, a=1, t=1, r=1, s=1) pm.delete(tempPos) except: tempPos = pm.createNode('transform', n='Temp') pm.delete(pm.parentConstraint(pos1, tempPos)) JntPos1 = pm.createNode('joint', n=(pos1 + '_Pos1Jnt')) pm.delete(pm.parentConstraint(tempPos, JntPos1)) pm.makeIdentity(JntPos1, a=1, t=1, r=1, s=1) pm.delete(tempPos) try: pm.select(pos2) tempPos = pm.cluster(n='Temp')[1] JntPos2 = pm.createNode('joint', n=(pos2 + '_Pos2Jnt')) pm.delete(pm.parentConstraint(tempPos, JntPos2)) pm.makeIdentity(JntPos2, a=1, t=1, r=1, s=1) pm.delete(tempPos) except: tempPos = pm.createNode('transform', n='Temp') pm.delete(pm.parentConstraint(pos2, tempPos)) JntPos2 = pm.createNode('joint', n=(pos2 + '_Pos2Jnt')) pm.delete(pm.parentConstraint(tempPos, JntPos2)) pm.makeIdentity(JntPos2, a=1, t=1, r=1, s=1) pm.delete(tempPos) pm.parent(JntPos2, JntPos1) pm.joint(JntPos1, e=1, oj='xyz', secondaryAxisOrient='yup') pm.joint(JntPos2, e=1, oj='none', ch=1, zso=1) distanceND = pm.createNode('distanceBetween') JntPos1.worldMatrix[0] >> distanceND.inMatrix1 JntPos2.worldMatrix[0] >> distanceND.inMatrix2 Dist = distanceND.distance.get() surface = pm.nurbsPlane(w=Dist, lr=.01, u=Div, ax=(0, 1, 0), ch=0) print surface bsSurface = pm.duplicate(surface) print bsSurface pm.blendShape(bsSurface, surface, foc=1, n=(str(bsSurface[0]) + '_Blendshape'), w=(0, 1)) pm.delete(pm.parentConstraint(JntPos1, JntPos2, surface[0])) pm.delete(JntPos1, JntPos2) fols = [] ctrls = [] for i in range(0, Div): val = ((.5 / float(Div)) * (i + 1) * 2) - ((.5 / float(Div * 2)) * 2) fol = pm.createNode('transform', n=('Tst_' + str(i) + '_Follicle'), ss=1) folShape = pm.createNode('follicle', n=fol.name() + 'Shape', p=fol, ss=1) geo = surface[0] geo.local >> folShape.inputSurface geo.worldMatrix[0] >> folShape.inputWorldMatrix folShape.outRotate >> fol.rotate folShape.outTranslate >> fol.translate fol.inheritsTransform.set(False) folShape.parameterV.set(0.5) folShape.parameterU.set(val) fols.append(fol) Ctrl = mel.eval( "sphere -esw 360 -r 0.3 -d 1 -ut 0 -tol 0.01 -s 4 -nsp 2 -ch 0;") pm.PyNode(Ctrl[0]) Ctrl = pm.rename(Ctrl[0], 'Follicle_' + str(i) + '_Ctrl') pm.delete(pm.parentConstraint(fol, Ctrl)) Grp = ZeroOut(Ctrl) ctrls.append(Ctrl) try: Shaps = pm.listRelatives(Ctrl, s=1)[0] Shaps.overrideEnabled.set(1) Shaps.overrideShading.set(0) Shaps.overrideColor.set(4) Shaps.overrideEnabled.lock(True) Shaps.overrideShading.lock(True) Shaps.overrideColor.lock(True) except: pass pm.select(cl=1) pm.parent(Grp, fol) RevGrp = RevGroup(Ctrl) SknJnts = [] for i in range(0, Div): val = ((.5 / float(Div)) * (i + 1) * 2) - ((.5 / float(Div * 2)) * 2) fol = pm.createNode('transform', n=('Tst_' + str(i)), ss=1) folShape = pm.createNode('follicle', n=fol.name() + 'Shape', p=fol, ss=1) geo = bsSurface[0] geo.local >> folShape.inputSurface geo.worldMatrix[0] >> folShape.inputWorldMatrix folShape.outRotate >> fol.rotate folShape.outTranslate >> fol.translate fol.inheritsTransform.set(False) folShape.parameterV.set(0.5) folShape.parameterU.set(val) pm.select(cl=1) jnt = pm.joint(n=('Follicle_' + str(i) + '_Jnt')) SknJnts.append(jnt) pm.delete(pm.parentConstraint(fol, jnt)) #pm.delete(fol) ZeroOut(jnt) pm.makeIdentity(jnt, a=1, t=1, r=1, s=1) for i in range(0, Div): ctrls[i].t >> SknJnts[i].t ctrls[i].r >> SknJnts[i].r ctrls[i].s >> SknJnts[i].s pm.skinCluster(SknJnts, bsSurface, mi=3, omi=0, tsb=1, dr=10)
def super_ribbon(start='', end='', segments=5, ribbonName='ribbon'): ribbon_rootName = ribbonName #+'_RBN' ribbon_distance_measure = pm.shadingNode('distanceBetween', name=ribbon_rootName + '_distance', asUtility=True) start_matrix = pm.shadingNode('decomposeMatrix', name=ribbon_rootName + '_start_matrix', asUtility=True) end_matrix = pm.shadingNode('decomposeMatrix', name=ribbon_rootName + '_end_matrix', asUtility=True) pm.connectAttr(start + '.worldMatrix', start_matrix + '.inputMatrix') pm.connectAttr(start_matrix + '.outputTranslate', ribbon_distance_measure + '.point1') pm.connectAttr(end + '.worldMatrix', end_matrix + '.inputMatrix') pm.connectAttr(end_matrix + '.outputTranslate', ribbon_distance_measure + '.point2') ribbon_length = pm.getAttr(ribbon_distance_measure + '.distance') ribbon_length_ratio = ribbon_length / (ribbon_length * segments) ribbonGEO = pm.nurbsPlane(name=ribbon_rootName + '_GEO', axis=[0, 1, 0], width=ribbon_length, lengthRatio=ribbon_length_ratio, degree=3, patchesU=segments, patchesV=1, constructionHistory=0) ribbonGEO = ribbonGEO[0] pm.addAttr(ribbonGEO, longName='metaParent', attributeType='message') pm.addAttr(ribbonGEO, shortName='rbn', longName='ribbon', attributeType='message') ribbon_rootGRP = pm.group(name=ribbon_rootName + '_GRP') pm.addAttr(ribbon_rootGRP, longName='metaParent', attributeType='message') pm.addAttr(ribbon_rootGRP, shortName='rbn', longName='ribbon', attributeType='message') ##---- connect with tagger pm.addAttr(ribbon_rootGRP, longName='ribbonSegments', attributeType='long', defaultValue=segments) pm.addAttr(ribbon_rootGRP, longName='rigPart', attributeType='message') ribbon_rootGRP.metaParent >> ribbonGEO.metaParent print 'making ribbon drive joints' #connect to face rig or lower face, whatever is the closest rig part startJointTrans = pm.xform(start, q=True, ws=True, translation=True) endJointTrans = pm.xform(end, q=True, ws=True, translation=True) midJointTrans = uf.average_position(start, end) drive_joint_list = [] ##pm.setAttr(jointName + '.drawStyle' = 2) hide joints pm.select(clear=True) startJoint = pm.joint(name=ribbonName + '_RBN_start_DRV', relative=True, radius=2, position=startJointTrans) pm.addAttr(startJoint, longName='metaParent', attributeType='message') pm.addAttr(startJoint, shortName='rbn', longName='ribbon', attributeType='message') pm.makeIdentity(startJoint, apply=True, rotate=True) drive_joint_list = drive_joint_list + [startJoint] ribbon_rootGRP.metaParent >> startJoint.metaParent pm.select(clear=True) endJoint = pm.joint(name=ribbonName + '_RBN_end_DRV', relative=True, radius=2, position=endJointTrans) pm.addAttr(endJoint, longName='metaParent', attributeType='message') pm.addAttr(endJoint, longName='ribbon', attributeType='message') pm.makeIdentity(endJoint, apply=True, rotate=True) drive_joint_list = drive_joint_list + [endJoint] ribbon_rootGRP.metaParent >> endJoint.metaParent pm.select(clear=True) midJoint = pm.joint(name=ribbonName + '_RBN_mid_DRV', relative=True, radius=2, position=midJointTrans) pm.addAttr(midJoint, longName='metaParent', attributeType='message') pm.addAttr(midJoint, shortName='rbn', longName='ribbon', attributeType='message') drive_joint_list = drive_joint_list + [midJoint] ribbon_rootGRP.metaParent >> midJoint.metaParent driver_group = uf.nest_transform(name=ribbon_rootName + '_drivers_GRP', action='parent', target=midJoint, transformObj='group') driver_group | startJoint driver_group | endJoint pm.select(clear=True) for driver in drive_joint_list: current_group_name = str(driver).replace('_DRV', '_GRP') current_group = uf.nest_transform(name=current_group_name, action='parent', target=driver, transformObj='group') current_offset = uf.nest_transform(name=current_group_name.replace( 'GRP', 'OST'), action='parent', target=driver, transformObj='group') pm.select(clear=True) #move everything into position pm.xform(ribbon_rootGRP, translation=midJointTrans, worldSpace=True) ##---- skin to nurbs curve pm.select(drive_joint_list, ribbonGEO) pm.skinCluster(toSelectedBones=True, bindMethod=0, normalizeWeights=1, weightDistribution=0, maximumInfluences=2, obeyMaxInfluences=True, skinMethod=1, dropoffRate=2, removeUnusedInfluence=False) ##---- # Propagate follicles print('making follicles and skin joints') follicle_list = [] ribbon_locator_list = [] current_name = '' for i in range(segments): uPosition_factor = 1 / float(segments) currentUposition = uPosition_factor * (float(i) + 0.5) print 'follicle' last_follicle = create_follicle(oNurbs=ribbonGEO, uPos=currentUposition, vPos=0.5) print('last follicle = ' + last_follicle.getParent()) pm.addAttr(last_follicle, longName='metaParent', attributeType='message') pm.addAttr(last_follicle, shortName='rbn', longName='ribbon', attributeType='message') ribbon_rootGRP.metaParent >> last_follicle.metaParent follicle_list.append(last_follicle) if i == (segments / 2): currentSide = 'C_' elif i < (segments / 2): currentSide = 'R_' else: currentSide = 'L_' current_name = currentSide + ribbon_rootName #currentJointName = currentSide + current_name print(current_name) current_locator = uf.nest_transform(name=current_name + '_LOC', action='child', target=last_follicle.getParent(), transformObj='locator') current_group = uf.nest_transform(name=current_name + '_GRP', action='parent', target=current_locator, transformObj='group') pm.addAttr(current_locator, shortName='rbn', longName='ribbon', attributeType='message') ribbon_locator_list = ribbon_locator_list + [current_locator] ribbon_rootGRP.metaParent >> current_locator.metaParent ribbonRef = ribbon_rootGRP return ribbonRef
def create_vfk(self, name = "", numJoints=20.0, numControls=3.0, controlRadius = 4.0, jointRadius=0.25, jointPrefix = 'joint_', jointGroupPrefix ='vfk_grp_', controlPrefix = 'CTRL_vfk_', controlGroupPrefix = 'OFF_CTRL_vfk_', boneTranslateAxis = '.tx', boneUpAxis = [0,0,1]): ''' if self.close_on_create_chk.checkState() == qc.Qt.Checked: self.close ''' pmc.undoInfo(openChunk=True) ### Get top and end joints, check for parents/children sels = pmc.ls(sl=1) topJoint = sels[0] endJoint = sels[1] try: print topJoint, ' and ', endJoint, ' selected.' ### pmc.listRelatives(topJoint, children=True, type='joint') except IndexError: print 'Error: Select a joint and an immediate child joint.' endChild = pmc.listRelatives(endJoint, c=True) if endChild: linkJointEnd = pmc.duplicate(endJoint, parentOnly=True, n=endJoint + '_LINK') pmc.setAttr(linkJointEnd[0] + '.radius', jointRadius * 2) pmc.parent(endChild, linkJointEnd) pmc.parent(linkJointEnd, w=True) topParent = pmc.listRelatives(topJoint, p=True) if topParent: linkJointTop = pmc.duplicate(topJoint, parentOnly=True, n=topJoint + '_LINK') pmc.setAttr(linkJointTop[0] + '.radius', jointRadius * 2) pmc.parent(linkJointTop, topParent) pmc.parent(topJoint, linkJointTop) ### Check basic user-defined values if self.name_le.text() != "": name = self.name_le.text() else: name = str(topJoint) + '_' if self.joints_le.text() != "": numJoints = float(self.joints_le.text()) if self.controls_le.text() != "": numControls = float(self.controls_le.text()) ### Check advanced user-defined values if self.control_radius_le.text() != "": controlRadius = float(self.control_radius_le.text()) if self.joint_radius_le.text() != "": jointRadius = float(self.joint_radius_le.text()) if self.joint_prefix_le.text() != "": jointPrefix = self.joint_prefix_le.text() if self.joint_grp_prefix_le.text() != "": jointGroupPrefix = self.joint_grp_prefix_le.text() if self.control_prefix_le.text() != "": controlPrefix = self.control_prefix_le.text() if self.control_grp_prefix_le.text() != "": controlGroupPrefix = self.control_grp_prefix_le.text() if self.bone_trans_axis_radX.isChecked() == True and self.bone_up_axis_radX.isChecked() == True: print 'Warning: bone main axis and bone up axis cannot be same.' return if self.bone_trans_axis_radY.isChecked() == True and self.bone_up_axis_radY.isChecked() == True: print 'Warning: bone main axis and bone up axis cannot be same.' return if self.bone_trans_axis_radZ.isChecked() == True and self.bone_up_axis_radZ.isChecked() == True: print 'Warning: bone main axis and bone up axis cannot be same.' return if self.bone_trans_axis_radX.isChecked() == True: boneTranslateAxis = '.tx' if self.bone_trans_axis_radY.isChecked() == True: boneTranslateAxis = '.ty' if self.bone_trans_axis_radZ.isChecked() == True: boneTranslateAxis = '.tz' if self.bone_up_axis_radX.isChecked() == True: boneUpAxis = [1,0,0] if self.bone_up_axis_radY.isChecked() == True: boneUpAxis = [0,1,0] if self.bone_up_axis_radZ.isChecked() == True: boneUpAxis = [0,0,1] #### ACTUAL FUNCTION PART nurbsWidth = pmc.getAttr(endJoint + boneTranslateAxis) self._jointRes(topJoint, endJoint, boneTranslateAxis= boneTranslateAxis, add= numJoints-2) surface = pmc.nurbsPlane(pivot=[0,0,0], axis= boneUpAxis, width=nurbsWidth, lengthRatio=0.1, u=(numJoints-1), ch=0, n= name + 'vfk_surface') ## Uncomment to use as polyPlane instead of nurbsSurface ## surface = pmc.polyPlane(w=20, h=1, sx=20, sy=1, ax=[0,1,0], cuv=2, ch=0, n= name + 'vfk_surface') if boneTranslateAxis == '.ty': if boneUpAxis == [1,0,0]: pmc.setAttr(surface[0] + '.rx', -90) if boneUpAxis == [0,0,1]: pmc.setAttr(surface[0] + '.rz', -90) pmc.makeIdentity(surface[0], apply=True, t=0, r=1, s=0) if boneTranslateAxis == '.tz': if boneUpAxis == [0,1,0]: pmc.setAttr(surface[0] + '.ry', -90) pmc.makeIdentity(surface[0], apply=True, t=0, r=1, s=0) surface_off = pmc.group(surface, n= name + 'OFF_surface') pmc.parent(surface_off, topJoint) if boneTranslateAxis == '.tx': pmc.xform(surface_off, translation = [nurbsWidth/2, 0, 0], rotation=[0,0,0]) if boneTranslateAxis == '.ty': pmc.xform(surface_off, translation = [0, nurbsWidth/2, 0], rotation=[0,0,0]) if boneTranslateAxis == '.tz': pmc.xform(surface_off, translation = [0, 0, nurbsWidth/2], rotation=[0,0,0]) pmc.parent(surface_off, w=True) surface_mtx= pmc.xform(surface, q=True, ws=True, m=True) joints = pmc.listRelatives(topJoint, children=1, allDescendents=1) joints.append(topJoint) joints.reverse() for j in xrange(len(joints)): pmc.select(joints[j]) pmc.rename(joints[j], jointPrefix + str(j+1)) pmc.setAttr(joints[j] + '.radius', jointRadius) pmc.addAttr(joints[j], ln='position', min=0, max=1, dv=0, keyable=True) pmc.setAttr(joints[j] + '.position', j/(numJoints-1)) pmc.select(cl=1) jmtx = pmc.xform(joints[j], q=True, m=True, ws=True) if j == 0: off_vfk = pmc.group(em=True, n= name + 'OFF_vfk') pmc.xform(off_vfk, ws=True, m=jmtx) root = pmc.listRelatives(joints[0], parent=True) for c in xrange(int(numControls)): jparent = pmc.listRelatives(joints[j], parent=True) vfk_grp = pmc.group(em=True, n= name + jointGroupPrefix + 'j' + str(j+1) + '_c' + str(c+1)) pmc.xform(vfk_grp, ws=True, m=jmtx) pmc.parent(joints[j], vfk_grp) pmc.parent(vfk_grp, jparent) if c == 0: pmc.parent(vfk_grp, off_vfk) if root != None: pmc.parent(off_vfk, root) else: for c in xrange(int(numControls)): jparent = pmc.listRelatives(joints[j], parent=True) vfk_grp = pmc.group(em=True, n= name + jointGroupPrefix + 'j' + str(j+1) + '_c' + str(c+1)) pmc.xform(vfk_grp, ws=True, m=jmtx) pmc.parent(joints[j], vfk_grp) pmc.parent(vfk_grp, jparent) ctrlSpacing = (nurbsWidth/(numControls+1)) for i in xrange(int(numControls)): if boneTranslateAxis == '.tx': ctrl_normal = [1,0,0] if boneTranslateAxis == '.ty': ctrl_normal = [0,1,0] if boneTranslateAxis == '.tz': ctrl_normal = [0,0,1] ctrl = pmc.circle(normal=ctrl_normal, sw=360, r=controlRadius, ch=0, n= name + controlPrefix + str(i+1)) ctrl_off = pmc.group(ctrl, n= name + controlGroupPrefix + str(i+1)) pmc.xform(ctrl_off, ws=True, m=surface_mtx) pmc.parent(ctrl_off, surface) pmc.setAttr(ctrl[0] + boneTranslateAxis, ((nurbsWidth/-2) + (ctrlSpacing*(i+1)))) pmc.parent(ctrl_off, w=True) flcl = self._parentSurfaceFLCL(ctrl, surface[0]) ctrl_mtx = pmc.xform(ctrl, q=True, m=True, ws=True) pmc.xform(ctrl_off, ws=True, m=ctrl_mtx) pmc.parent(ctrl_off, flcl[0]) pmc.parent(ctrl, ctrl_off) min_falloff = 1/numJoints pmc.addAttr(ctrl[0], ln='position', min=0, max=10, dv=0, keyable=True) pmc.addAttr(ctrl[0], ln='falloff', min=min_falloff, max=1, dv=0.5, keyable=True) pmc.addAttr(ctrl[0], ln='numberOfJointsAffected', min=0, max=numJoints, dv=0, keyable=True) multD = pmc.createNode('multiplyDivide', n= name + 'multD_jAff_vfk_' + str(i+1)) setR = mc.createNode('setRange', n= name + 'setR_jAff_vfk_' + str(i+1)) pmc.connectAttr(ctrl[0] + '.falloff', multD + '.input1X') pmc.setAttr(multD + '.input2X', 2) pmc.setAttr(multD + '.operation', 1) pmc.connectAttr(multD + '.outputX', setR + '.valueX') pmc.setAttr(setR + '.oldMinX', 0) pmc.setAttr(setR + '.oldMaxX', 1) pmc.setAttr(setR + '.minX', 0) pmc.setAttr(setR + '.maxX', numJoints) pmc.connectAttr(setR + '.outValueX', ctrl[0] + '.numberOfJointsAffected') paramU = pmc.getAttr(flcl[0] + '.parameterU') div_ten = pmc.createNode('multiplyDivide', n="DIV_" + name + controlPrefix + str(i+1)) pmc.setAttr(div_ten.input2X, 10) pmc.setAttr(div_ten.operation, 2) pmc.connectAttr(ctrl[0] + '.position', div_ten.input1X) pmc.connectAttr(div_ten.outputX, flcl[0] + '.parameterU') pmc.setAttr(ctrl[0] + '.position', paramU * 10.0) fPos_plus = pmc.createNode('plusMinusAverage', n= name + 'fPosPlus_vfk_' + str(i+1)) pmc.connectAttr(div_ten.outputX, fPos_plus + '.input1D[0]', f=True) pmc.connectAttr(ctrl[0] + '.falloff', fPos_plus + '.input1D[1]', f=True) pmc.setAttr(fPos_plus + '.operation', 1) fPos_minus = pmc.createNode('plusMinusAverage', n= name + 'fPosMinus_vfk_' + str(i+1)) pmc.connectAttr(div_ten.outputX, fPos_minus + '.input1D[0]', f=True) pmc.connectAttr(ctrl[0] + '.falloff', fPos_minus + '.input1D[1]', f=True) pmc.setAttr(fPos_minus + '.operation', 2) for f in (fPos_plus, fPos_minus): for j in xrange(len(joints)): upperM = pmc.createNode('plusMinusAverage', n= (name + f + '_upperM_j' + str(j+1) + '_c' + str(i+1))) lowerM = pmc.createNode('plusMinusAverage', n= (name + f + '_lowerM_j' + str(j+1) + '_c' + str(i+1))) pmc.setAttr(upperM + '.operation', 2) pmc.setAttr(lowerM + '.operation', 2) pmc.connectAttr(joints[j] + '.position', upperM + '.input1D[0]') pmc.connectAttr(f + '.output1D', upperM + '.input1D[1]') pmc.connectAttr(div_ten.outputX, lowerM + '.input1D[0]') pmc.connectAttr(f + '.output1D', lowerM + '.input1D[1]') divA = pmc.createNode('multiplyDivide', n= f + '_divA_j' + str(j+1) + '_c' + str(i+1)) pmc.setAttr(divA + '.operation', 2) pmc.connectAttr(upperM + '.output1D', divA + '.input1X') pmc.connectAttr(lowerM + '.output1D', divA + '.input2X') multA = pmc.createNode('multiplyDivide', n= f + '_multA_j' + str(j+1) + '_c' + str(i+1)) pmc.setAttr(multA + '.operation', 1) pmc.connectAttr(divA + '.outputX', multA + '.input1X') pmc.setAttr(multA + '.input2X', 2) divB = pmc.createNode('multiplyDivide', n= f + '_divB_j' + str(j+1) + '_c' + str(i+1)) pmc.setAttr(divB + '.operation', 2) pmc.connectAttr(multA + '.outputX', divB + '.input1X') pmc.connectAttr(ctrl[0] + '.numberOfJointsAffected', divB + '.input2X') for j in xrange(len(joints)): cond = pmc.createNode('condition', n= name + 'cond_j' + str(j+1) + '_c' + str(i+1)) pmc.setAttr(cond + '.operation', 3) pmc.connectAttr(div_ten.outputX, cond + '.firstTerm') # then use minus pmc.connectAttr(joints[j] + '.position', cond + '.secondTerm') # then use plus pmc.connectAttr(fPos_minus + '_divB_j' + str(j+1) + '_c' + str(i+1) + '.outputX', cond + '.colorIfTrueR') pmc.connectAttr(fPos_minus + '_divB_j' + str(j+1) + '_c' + str(i+1) + '.outputX', cond + '.colorIfTrueG') pmc.connectAttr(fPos_minus + '_divB_j' + str(j+1) + '_c' + str(i+1) + '.outputX', cond + '.colorIfTrueB') pmc.connectAttr(fPos_plus + '_divB_j' + str(j+1) + '_c' + str(i+1) + '.outputX', cond + '.colorIfFalseR') pmc.connectAttr(fPos_plus + '_divB_j' + str(j+1) + '_c' + str(i+1) + '.outputX', cond + '.colorIfFalseG') pmc.connectAttr(fPos_plus + '_divB_j' + str(j+1) + '_c' + str(i+1) + '.outputX', cond + '.colorIfFalseB') cond_neg = pmc.createNode('condition', n= name + 'cond_neg_j' + str(j+1) + '_c' + str(i+1)) pmc.connectAttr(cond + '.outColorR', cond_neg + '.firstTerm') pmc.setAttr(cond_neg + '.secondTerm', 0) pmc.setAttr(cond_neg + '.operation', 2) pmc.connectAttr(cond + '.outColor', cond_neg + '.colorIfTrue') pmc.setAttr(cond_neg + '.colorIfFalse', [0,0,0]) multiFinalRot = pmc.createNode('multiplyDivide', n= name + 'multiFinalRot_j' + str(j+1) + '_c' + str(i+1)) pmc.setAttr(multiFinalRot + '.operation', 1) pmc.connectAttr(cond_neg + '.outColor', multiFinalRot + '.input1') pmc.connectAttr(ctrl[0] + '.rotate', multiFinalRot + '.input2') pmc.connectAttr(multiFinalRot + '.output', name + jointGroupPrefix + 'j' + str(j+1) + '_c' + str(i+1) + '.rotate') ''' multiFinalScl = pmc.createNode('multiplyDivide', n= name + 'multiFinalScl_j' + str(j+1) + '_c' + str(i+1)) pmc.setAttr(multiFinalScl + '.operation', 1) pmc.connectAttr(cond + '.outColor', multiFinalScl + '.input1') pmc.connectAttr(ctrl[0] + '.scale', multiFinalScl + '.input2') pmc.connectAttr(multiFinalScl + '.output', name + jointGroupPrefix + 'j' + str(j+1) + '_c' + str(i+1) + '.scale') ''' self._ctrlDBL(ctrl) if endChild: pmc.parent(linkJointEnd, endJoint) pmc.undoInfo(closeChunk=True) pmc.undoInfo(openChunk=True) pmc.skinCluster(joints, name + 'vfk_surface', mi=1) pmc.undoInfo(closeChunk=True)
def bdBuildRbnDT(self,name,start,end,segments): surfaceRbn = pm.nurbsPlane(ax = [0,0,22], d=3, u=1, v=segments , w=1, lr = segments)[0] surfaceRbn.rename(name) flcGrp = self.bdCreateFol(surfaceRbn,segments) surfaceRbn_BS = surfaceRbn.duplicate()[0] surfaceRbn_BS.rename(name + '_BS') surfaceRbn_BS.translateX.set(segments * 0.5 ) blendshapeNode = pm.blendShape(surfaceRbn_BS,surfaceRbn,name=surfaceRbn.name() + '_blendShape')[0] blendshapeNode.attr(surfaceRbn_BS.name()).set(1) locatorsRbn = [] topLocator = pm.spaceLocator() topLocator.rename(name + '_loc_top_CON') topLocator.translateY.set(segments * 0.5) pm.makeIdentity(topLocator,apply=True,t=True,r=True,s=True) midLocator = pm.spaceLocator() midLocator.rename(name + '_loc_mid_CON') midLocatorGrp = pm.group(midLocator,name=midLocator.name() + '_grp') pm.makeIdentity(midLocator,apply=True,t=True,r=True,s=True) botLocator = pm.spaceLocator() botLocator.rename(name + '_loc_bot_CON') botLocator.translateY.set(segments * -0.5) pm.makeIdentity(botLocator,apply=True,t=True,r=True,s=True) locatorsRbn.append(topLocator) locatorsRbn.append(midLocator) locatorsRbn.append(botLocator) pm.pointConstraint(topLocator,botLocator,midLocatorGrp) conGrp = pm.group([topLocator,midLocatorGrp,botLocator],n=name.replace('srf','CON_GRP')) curveDrv = pm.curve(d=2, p=[(0, segments * 0.5, 0), (0, 0, 0), (0, segments * -0.5, 0)],k=[0,0,1,1]) curveDrv.rename(name.replace('srf', 'wire_CRV')) curveDrv.translateX.set(segments * 0.5) wireDef = pm.wire(surfaceRbn_BS,w=curveDrv,en=1,gw=False,ce=0, li=0, dds = [0,20], n=name.replace('srf','wire')) #kind of a hack wireDefBase = wireDef[0].baseWire[0].listConnections(d=False,s=True) curveCLS,clsGrp = self.bdClustersOnCurve(curveDrv,segments) for i in range(3): locatorsRbn[i].translate.connect(curveCLS[i].translate) #organize a bit moveGrp = pm.group([conGrp,surfaceRbn],name=name.replace('srf','move_GRP')) extraGrp = pm.group([flcGrp,surfaceRbn_BS,clsGrp,curveDrv,wireDefBase],name = name.replace('srf','extra_GRP')) allGrp = pm.group([moveGrp,extraGrp],name = name.replace('srf','RBN')) self.bdFlcScaleCnstr(moveGrp,flcGrp) globalCon = pm.spaceLocator() globalCon.rename(name.replace("srf",'world_CON')) pm.parent(globalCon,allGrp) pm.parent(moveGrp,globalCon) self.bdCreateJoints(flcGrp) twistDef, twistDefTransform = self.bdAddTwist(surfaceRbn_BS) pm.parent(twistDefTransform, extraGrp) topLocator.rotateY.connect(twistDef.startAngle) botLocator.rotateY.connect(twistDef.endAngle) pm.reorderDeformers(wireDef[0],twistDef,surfaceRbn_BS)
def CreateSurface(pos1, pos2, Div=10): try: pm.select(pos1) tempPos = pm.cluster(n='Temp')[1] JntPos1 = pm.createNode('joint', n=(pos1 + '_Pos1Jnt')) pm.delete(pm.parentConstraint(tempPos, JntPos1)) pm.makeIdentity(JntPos1, a=1, t=1, r=1, s=1) pm.delete(tempPos) except: tempPos = pm.createNode('transform', n='Temp') pm.delete(pm.parentConstraint(pos1, tempPos)) JntPos1 = pm.createNode('joint', n=(pos1 + '_Pos1Jnt')) pm.delete(pm.parentConstraint(tempPos, JntPos1)) pm.makeIdentity(JntPos1, a=1, t=1, r=1, s=1) pm.delete(tempPos) try: pm.select(pos2) tempPos = pm.cluster(n='Temp')[1] JntPos2 = pm.createNode('joint', n=(pos2 + '_Pos2Jnt')) pm.delete(pm.parentConstraint(tempPos, JntPos2)) pm.makeIdentity(JntPos2, a=1, t=1, r=1, s=1) pm.delete(tempPos) except: tempPos = pm.createNode('transform', n='Temp') pm.delete(pm.parentConstraint(pos2, tempPos)) JntPos2 = pm.createNode('joint', n=(pos2 + '_Pos2Jnt')) pm.delete(pm.parentConstraint(tempPos, JntPos2)) pm.makeIdentity(JntPos2, a=1, t=1, r=1, s=1) pm.delete(tempPos) pm.parent(JntPos2, JntPos1) pm.joint(JntPos1, e=1, oj='xyz', secondaryAxisOrient='yup') pm.joint(JntPos2, e=1, oj='none', ch=1, zso=1) distanceND = pm.createNode('distanceBetween') JntPos1.worldMatrix[0] >> distanceND.inMatrix1 JntPos2.worldMatrix[0] >> distanceND.inMatrix2 Dist = distanceND.distance.get() surface = pm.nurbsPlane(w=Dist, lr=.01, u=Div, ax=(0, 1, 0), ch=0) print surface bsSurface = pm.duplicate(surface) pm.delete(pm.parentConstraint(JntPos1, JntPos2, surface[0])) pm.delete(JntPos1, JntPos2) fols = [] for i in range(0, Div): val = ((.5 / float(Div)) * (i + 1) * 2) - ((.5 / float(Div * 2)) * 2) fol = pm.createNode('transform', n=('Tst_' + str(i)), ss=1) folShape = pm.createNode('follicle', n=fol.name() + 'Shape', p=fol, ss=1) geo = surface[0] geo.local >> folShape.inputSurface geo.worldMatrix[0] >> folShape.inputWorldMatrix folShape.outRotate >> fol.rotate folShape.outTranslate >> fol.translate fol.inheritsTransform.set(False) folShape.parameterV.set(0.5) folShape.parameterU.set(val) fols.append(fol) SknJnts = [] for i in range(0, Div): val = ((.5 / float(Div)) * (i + 1) * 2) - ((.5 / float(Div * 2)) * 2) fol = pm.createNode('transform', n=('Tst_' + str(i)), ss=1) folShape = pm.createNode('follicle', n=fol.name() + 'Shape', p=fol, ss=1) geo = bsSurface geo.local >> folShape.inputSurface geo.worldMatrix[0] >> folShape.inputWorldMatrix folShape.outRotate >> fol.rotate folShape.outTranslate >> fol.translate fol.inheritsTransform.set(False) folShape.parameterV.set(0.5) folShape.parameterU.set(val) jnt = pm.joint(n='FollicleJnt' + i) pm.delete(pm.parentConstraint(fol, jnt))
def doRig(self): p1 = pm.xform(self.guide1, q=1, t=1) p2 = pm.xform(self.guide2, q=1, t=1) p3 = pm.xform(self.guide3, q=1, t=1) A = om.MVector(p1) B = om.MVector(p2) C = om.MVector(p3) AC = A - C nurbsLength = AC.length() # setup do nurbs plane e follicles nurbs = pm.nurbsPlane(w=nurbsLength / self.sections, lr=self.sections, v=self.sections)[0] nurbsShp = nurbs.getShape() pm.rebuildSurface(nurbs, ch=1, rpo=1, rt=0, end=1, kr=0, kcp=0, kc=0, su=1, du=1, dv=3, tol=0.01, fr=0, dir=0) pm.xform(nurbs, t=p1, ws=True) guide2Up = pm.duplicate(self.guide2, n=self.guide2 + '_up')[0] pm.delete(pm.pointConstraint(self.guide1, self.guide3, guide2Up)) pm.xform(guide2Up, r=True, t=(self.direction[0], self.direction[1], self.direction[2])) pm.delete( pm.aimConstraint(self.guide3, nurbs, w=1, o=(0, 0, 0), aim=(0, 1, 0), u=(-1, 0, 0), wut='object', wuo=guide2Up)) pm.delete(guide2Up) pm.delete(pm.pointConstraint(self.guide1, self.guide3, nurbs)) grpFol = pm.group(em=1, n=self.name + 'Foll_grp') grpScale = pm.group(em=1, n=self.name + 'Scale_grp') vValue = 0 vSections = 1.0 / self.sections vOffset = vSections / 2 id = 0 # medindo o comprimento do nurbs para o squash stretch arcLengthShp = pm.createNode('arcLengthDimension') arcLength = arcLengthShp.getParent() nurbsShp.worldSpace[0] >> arcLengthShp.nurbsGeometry arcLengthShp.vParamValue.set(1) arcLengthShp.uParamValue.set(0) arcLenValue = arcLengthShp.arcLengthInV.get() autoManualList = [] factorList = [] on_offList = [] skinJntsList = [] for follicle in range(self.sections): id += 1 # criando nodes para o stretch squash normalizeTo0 = pm.createNode('plusMinusAverage', n=self.name + 'RbbnNormalize0' + ` id ` + '_pma') scaleAux = pm.createNode('multiplyDivide', n=self.name + 'RbbnScaleAux0' + ` id ` + '_md') factor = pm.createNode('multiplyDivide', n=self.name + 'RbbnFactor0' + ` id ` + '_md') on_off = pm.createNode('multiplyDivide', n=self.name + 'RbbnOnOff0' + ` id ` + '_md') autoManual = pm.createNode('plusMinusAverage', n=self.name + 'RbbnAutoManual0' + ` id ` + '_pma') autoReverse = pm.createNode('reverse', n=self.name + 'RbbnReverse0' + ` id ` + '_rev') # ajustando valores dos nodes de stretch squash normalizeTo0.operation.set(2) scaleAux.input2.set((arcLenValue, arcLenValue, arcLenValue)) # conectando os nodes de stretch squash arcLength.arcLengthInV >> normalizeTo0.input3D[0].input3Dx arcLength.arcLengthInV >> normalizeTo0.input3D[0].input3Dy arcLength.arcLengthInV >> normalizeTo0.input3D[0].input3Dz scaleAux.output >> normalizeTo0.input3D[1] grpScale.scale >> scaleAux.input1 normalizeTo0.output3D >> factor.input2 factor.output >> on_off.input1 on_off.output >> autoReverse.input autoReverse.output >> autoManual.input3D[0] # criando nodes do rbbn folShp = pm.createNode('follicle') fol = folShp.getParent() # escondendo os follicles if self.visibility == 0: folShp.visibility.set(0) jnt = pm.joint(radius=nurbsLength * 0.2) skinJntsList.append(jnt) # conectando e ajustando nodes do rbbn autoManual.output3Dx >> jnt.scaleX autoManual.output3Dz >> jnt.scaleZ nurbsShp.local >> folShp.inputSurface nurbsShp.worldMatrix[0] >> folShp.inputWorldMatrix folShp.outRotate >> fol.rotate folShp.outTranslate >> fol.translate folShp.parameterU.set(0.5) vValue += vSections folShp.parameterV.set(vValue - vOffset) pm.parent(fol, grpFol) pm.scaleConstraint(grpScale, fol, mo=1) # listas para loops posteriores on_offList.append(on_off) factorList.append(factor) autoManualList.append(autoManual) # fk setup FKSIZE = (nurbsLength / 2) / self.sections topPosLoc = pm.spaceLocator() topAimLoc = pm.spaceLocator() topAimLoc.setParent(topPosLoc) topToSkin = pm.joint( radius=nurbsLength * 0.2, p=(0, 0, 0), ) pm.joint( radius=nurbsLength * 0.15, p=(0, -FKSIZE, 0), ) topUpLoc = pm.spaceLocator() topUpLoc.setParent(topPosLoc) pm.move(FKSIZE * 3 * self.upVector[0], FKSIZE * 3 * self.upVector[1], FKSIZE * 3 * self.upVector[2], topUpLoc) pm.delete(pm.pointConstraint(self.guide3, topPosLoc)) # pm.delete(pm.parentConstraint(guide3,topPosLoc)) midPosLoc = pm.spaceLocator() midAimLoc = pm.spaceLocator() midAimLoc.setParent(midPosLoc) midOffLoc = pm.spaceLocator() midOffLoc.setParent(midAimLoc) midToSkin = pm.joint(radius=nurbsLength * 0.2, p=(0, 0, 0)) midUpLoc = pm.spaceLocator() midUpLoc.setParent(midPosLoc) pm.move(FKSIZE * 3 * self.upVector[0], FKSIZE * 3 * self.upVector[1], FKSIZE * 3 * self.upVector[2], midUpLoc) lwrPosLoc = pm.spaceLocator() lwrAimLoc = pm.spaceLocator() lwrAimLoc.setParent(lwrPosLoc) lwrToSkin = pm.joint(radius=nurbsLength * 0.2, p=(0, 0, 0)) pm.joint(radius=nurbsLength * 0.15, p=(0, FKSIZE, 0)) lwrUpLoc = pm.spaceLocator() lwrUpLoc.setParent(lwrPosLoc) pm.move(FKSIZE * 3 * self.upVector[0], FKSIZE * 3 * self.upVector[1], FKSIZE * 3 * self.upVector[2], lwrUpLoc) pm.delete(pm.pointConstraint(self.guide1, lwrPosLoc)) topPosLocShp = topPosLoc.getShape() midPosLocShp = midPosLoc.getShape() lwrPosLocShp = lwrPosLoc.getShape() topAimLocShp = topAimLoc.getShape() midAimLocShp = midAimLoc.getShape() lwrAimLocShp = lwrAimLoc.getShape() topUpLocShp = topUpLoc.getShape() midUpLocShp = midUpLoc.getShape() lwrUpLocShp = lwrUpLoc.getShape() midOffLocShp = midOffLoc.getShape() topPosLocShp.localScale.set( (nurbsLength * 0.2, nurbsLength * 0.2, nurbsLength * 0.2)) topAimLocShp.localScale.set( (nurbsLength * 0.2, nurbsLength * 0.2, nurbsLength * 0.2)) topUpLocShp.localScale.set( (nurbsLength * 0.05, nurbsLength * 0.05, nurbsLength * 0.05)) midPosLocShp.localScale.set( (nurbsLength * 0.2, nurbsLength * 0.2, nurbsLength * 0.2)) midAimLocShp.localScale.set( (nurbsLength * 0.2, nurbsLength * 0.2, nurbsLength * 0.2)) midUpLocShp.localScale.set( (nurbsLength * 0.05, nurbsLength * 0.05, nurbsLength * 0.05)) midOffLocShp.localScale.set( (nurbsLength * 0.2, nurbsLength * 0.2, nurbsLength * 0.2)) lwrPosLocShp.localScale.set( (nurbsLength * 0.2, nurbsLength * 0.2, nurbsLength * 0.2)) lwrAimLocShp.localScale.set( (nurbsLength * 0.2, nurbsLength * 0.2, nurbsLength * 0.2)) lwrUpLocShp.localScale.set( (nurbsLength * 0.05, nurbsLength * 0.05, nurbsLength * 0.05)) pm.parent(topPosLoc, midPosLoc, lwrPosLoc, grpScale) # criando constraints para os locators do rbbn pm.aimConstraint(midToSkin, topAimLoc, aim=(0, -1, 0), u=(1, 0, 0), wut='object', wuo=topUpLoc) pm.aimConstraint(midToSkin, lwrAimLoc, aim=(0, 1, 0), u=(1, 0, 0), wut='object', wuo=lwrUpLoc) pm.aimConstraint(topPosLoc, midAimLoc, aim=(0, 1, 0), u=(1, 0, 0), wut='object', wuo=midUpLoc) pm.pointConstraint(topPosLoc, lwrPosLoc, midPosLoc) pm.pointConstraint(topUpLoc, lwrUpLoc, midUpLoc) # skin setup skin = pm.skinCluster(topToSkin, midToSkin, lwrToSkin, nurbs, tsb=1) if self.sections == 3: pm.skinPercent(skin, nurbs + '.cv[0:1][5]', tv=(topToSkin, 1)) pm.skinPercent(skin, nurbs + '.cv[0:1][4]', tv=[(topToSkin, 0.6), (midToSkin, 0.4)]) pm.skinPercent(skin, nurbs + '.cv[0:1][3]', tv=[(topToSkin, 0.2), (midToSkin, 0.8)]) pm.skinPercent(skin, nurbs + '.cv[0:1][2]', tv=[(topToSkin, 0.2), (midToSkin, 0.8)]) pm.skinPercent(skin, nurbs + '.cv[0:1][1]', tv=[(topToSkin, 0.6), (midToSkin, 0.4)]) pm.skinPercent(skin, nurbs + '.cv[0:1][0]', tv=(topToSkin, 1)) elif self.sections == 5: pm.skinPercent(skin, nurbs + '.cv[0:1][7]', tv=(topToSkin, 1)) pm.skinPercent(skin, nurbs + '.cv[0:1][6]', tv=[(topToSkin, 0.80), (midToSkin, 0.2)]) pm.skinPercent(skin, nurbs + '.cv[0:1][5]', tv=[(topToSkin, 0.5), (midToSkin, 0.5)]) pm.skinPercent(skin, nurbs + '.cv[0:1][4]', tv=[(topToSkin, 0.25), (midToSkin, 0.75)]) pm.skinPercent(skin, nurbs + '.cv[0:1][3]', tv=[(lwrToSkin, 0.25), (midToSkin, 0.75)]) pm.skinPercent(skin, nurbs + '.cv[0:1][2]', tv=[(lwrToSkin, 0.5), (midToSkin, 0.5)]) pm.skinPercent(skin, nurbs + '.cv[0:1][1]', tv=[(lwrToSkin, 0.8), (midToSkin, 0.2)]) pm.skinPercent(skin, nurbs + '.cv[0:1][0]', tv=(lwrToSkin, 1)) elif self.sections == 7: pm.skinPercent(skin, nurbs + '.cv[0:1][9]', tv=(topToSkin, 1)) pm.skinPercent(skin, nurbs + '.cv[0:1][8]', tv=[(topToSkin, 0.85), (midToSkin, 0.15)]) pm.skinPercent(skin, nurbs + '.cv[0:1][7]', tv=[(topToSkin, 0.6), (midToSkin, 0.4)]) pm.skinPercent(skin, nurbs + '.cv[0:1][6]', tv=[(topToSkin, 0.35), (midToSkin, 0.65)]) pm.skinPercent(skin, nurbs + '.cv[0:1][5]', tv=[(topToSkin, 0.25), (midToSkin, 0.75)]) pm.skinPercent(skin, nurbs + '.cv[0:1][4]', tv=[(lwrToSkin, 0.25), (midToSkin, 0.75)]) pm.skinPercent(skin, nurbs + '.cv[0:1][3]', tv=[(lwrToSkin, 0.35), (midToSkin, 0.65)]) pm.skinPercent(skin, nurbs + '.cv[0:1][2]', tv=[(lwrToSkin, 0.6), (midToSkin, 0.4)]) pm.skinPercent(skin, nurbs + '.cv[0:1][1]', tv=[(lwrToSkin, 0.85), (midToSkin, 0.15)]) pm.skinPercent(skin, nurbs + '.cv[0:1][0]', tv=(lwrToSkin, 1)) else: print "!!!There's skinning support for 3,5 and 7 sections only!!!" # posicionando o controle do meio pm.delete(pm.pointConstraint(self.guide2, midOffLoc)) # criando controles if self.createCtrls == 0: topCircle = pm.circle(r=nurbsLength * .2, nr=(self.ctrlNormal[0], self.ctrlNormal[1], self.ctrlNormal[2])) topCtrlGrp = pm.group() topCtrlGrp.setParent(grpScale) pm.delete(pm.parentConstraint(self.guide3, topCtrlGrp, mo=0)) pm.parentConstraint(topCircle[0], topPosLoc) midCircle = pm.circle(r=nurbsLength * .2, nr=(self.ctrlNormal[0], self.ctrlNormal[1], self.ctrlNormal[2])) midCtrlGrp = pm.group() midCtrlGrp.setParent(midOffLoc) pm.delete(pm.parentConstraint(midToSkin, midCtrlGrp)) midJointZerado = self.zeroOut(midToSkin, returnGrpName=1)[0] pm.parent(midJointZerado, grpScale) pm.parentConstraint(midCircle[0], midJointZerado, mo=1) lwrCircle = pm.circle(r=nurbsLength * .2, nr=(self.ctrlNormal[0], self.ctrlNormal[1], self.ctrlNormal[2])) lwrCtrlGrp = pm.parent(pm.group(), grpScale) pm.delete(pm.parentConstraint(self.guide1, lwrCtrlGrp, mo=0)) pm.parentConstraint(lwrCircle[0], lwrPosLoc) else: midCircle = pm.circle(r=nurbsLength * .2, nr=(self.ctrlNormal[0], self.ctrlNormal[1], self.ctrlNormal[2])) midCtrlGrp = pm.parent(pm.group(), midOffLoc) pm.delete(pm.parentConstraint(midToSkin, midCtrlGrp)) midJointZerado = self.zeroOut(midToSkin, returnGrpName=1)[0] pm.parent(midJointZerado, grpScale) pm.parentConstraint(midCircle[0], midJointZerado, mo=1) id = 0 midCircle[0].addAttr('autoSS', k=1, dv=0.0, at='double', min=0, max=1) midCircleShp = midCircle[0].getShape() if self.createCtrls: midCircleShp.v.set(0) for autoManualAuxNodes in autoManualList: id += 1 # criando e ajustando nodes para stretch squash manualNormalize = pm.createNode( 'plusMinusAverage', n=self.name + 'RbbnManualNormalize0' + str(id) + '_pma') manualFactor = pm.createNode('multiplyDivide', n=self.name + 'RbbnManualFactor0' + str(id) + '_md') ratioScale = pm.createNode('multiplyDivide', n=self.name + 'RbbnRatioScale0' + str(id) + 'md') zRatio = pm.createNode('multiplyDivide', n=self.name + 'RbbnSsManualZratio' + str(id) + '_md') manualFactor.output >> autoManualAuxNodes.input3D[1] midCircle[0].scale >> manualNormalize.input3D[0] manualNormalize.output3D >> manualFactor.input2 manualNormalize.operation.set(2) manualNormalize.input3D[1].input3D.set((1, 1, 1)) ratioScale.operation.set(2) # adicionando atributos de squash midCircleShp.addAttr('manualFactorX0' + str(id), k=1, at='float', dv=1) midCircleShp.addAttr('manualRatioZ0' + str(id), k=1, at='float') midCircleShp.addAttr('autoFactorX0' + str(id), k=1, at='float') midCircleShp.addAttr('autoRatioZ0' + str(id), k=1, at='float') # conectando os atributos acima midCircleShp.attr('manualRatioZ0' + str(id)) >> zRatio.input1Z midCircleShp.attr('autoRatioZ0' + str(id)) >> zRatio.input1X midCircle[0].autoSS >> on_offList[id - 1].input2X # on_off midCircle[0].autoSS >> on_offList[id - 1].input2Z # on_off midCircleShp.attr('manualFactorX0' + str(id)) >> manualFactor.input1X midCircleShp.attr('manualFactorX0' + str(id)) >> zRatio.input2Z ratioScale.outputX >> zRatio.input2X zRatio.outputZ >> manualFactor.input1Z ratioScale.outputX >> factorList[id - 1].input1X # factor zRatio.outputX >> factorList[id - 1].input1Z # factor grpScale.scale >> ratioScale.input2 midCircleShp.attr('autoFactorX0' + str(id)) >> ratioScale.input1X # ajustando os atributos midCircleShp.attr('manualRatioZ0' + str(id)).set(1) midCircleShp.attr('autoRatioZ0' + str(id)).set(1) # ajustando valores iniciais para os factores de squash if self.sections == 3: midCircleShp.autoFactorX02.set(0.08) elif self.sections == 5: midCircleShp.autoFactorX01.set(0.02) midCircleShp.autoFactorX02.set(0.25) midCircleShp.autoFactorX03.set(0.22) midCircleShp.autoFactorX04.set(0.25) midCircleShp.autoFactorX05.set(0.02) elif self.sections == 7: midCircleShp.autoFactorX01.set(0) midCircleShp.autoFactorX02.set(0.11) midCircleShp.autoFactorX03.set(0.1) midCircleShp.autoFactorX04.set(0.16) midCircleShp.autoFactorX05.set(0.1) midCircleShp.autoFactorX06.set(0.11) midCircleShp.autoFactorX07.set(0) # toggles displays if self.visibility == 0: pm.toggle(nurbs, g=1, te=1) pm.toggle(arcLength, te=1) arcLength.visibility.set(0) topPosLoc.visibility.set(0) midPosLocShp = midPosLoc.getShape() midPosLocShp.visibility.set(0) midAimLocShp = midAimLoc.getShape() midAimLocShp.visibility.set(0) midOffLocShp = midOffLoc.getShape() midOffLocShp.visibility.set(0) lwrPosLoc.visibility.set(0) midUpLoc.visibility.set(0) grpScale.visibility.set(0) grpFol.visibility.set(0) # agrupando tudo finalRbbnGrp = pm.group(em=1, n=self.name + 'finalRbbn_grp') pm.parent(nurbs, grpFol, grpScale, arcLength, finalRbbnGrp)
def doRig(self): anchorList = [] cntrlList = [] locList = [] offCtrlLoc=[] offAuxLoc = [] dummyCrv = self.ribbonDict['moveallSetup']['nameTempl']+'_dummy_crv' pm.hide(pm.polyCube(n=dummyCrv)) if pm.objExists(self.ribbonDict['moveallSetup']['nameTempl']): pm.delete(self.ribbonDict['moveallSetup']['nameTempl']) if pm.objExists(self.ribbonDict['noMoveSetup']['nameTempl']): pm.delete(self.ribbonDict['noMoveSetup']['nameTempl']) ###Estrutura que nao deve ter transformacao noMoveSpace = pm.group(empty=True, n=self.ribbonDict['noMoveSetup']['nameTempl']) if not pm.objExists('NOMOVE'): pm.group(self.ribbonDict['noMoveSetup']['nameTempl'], n='NOMOVE') else: pm.parent(self.ribbonDict['noMoveSetup']['nameTempl'], 'NOMOVE') pm.parent(self.ribbonDict['moveallSetup']['nameTempl']+'_dummy_crv', noMoveSpace) noMoveSpace.visibility.set(0) noMoveSpace.translate.set(self.size * -0.5, 0, 0) noMoveBend1 = pm.nurbsPlane(p=(self.size * -0.25, 0, 0), ax=(0, 0, 1), w=self.size * 0.5, lr=.1, d=3, u=5, v=1) noMoveBend2 = pm.nurbsPlane(p=(self.size * 0.25, 0, 0), ax=(0, 0, 1), w=self.size * 0.5, lr=.1, d=3, u=5, v=1) noMoveCrvJnt = pm.curve(bezier=True, d=3, p=[(self.size * -0.50, 0, 0), (self.size * -0.499, 0, 0), (self.size * -0.496, 0, 0), (self.size * -0.495, 0, 0), (self.size * -0.395, 0, 0), (self.size * -0.10, 0, 0), (0, 0, 0), (self.size * 0.10, 0, 0), (self.size * 0.395, 0, 0), (self.size * 0.495, 0, 0), (self.size * 0.496, 0, 0), (self.size * 0.499, 0, 0), (self.size * 0.50, 0, 0)], k=[0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10]) noMoveCrvTweak1 = pm.curve(d=2, p=[(self.size * -0.5, 0, 0), (self.size * -0.25, 0, 0), (self.size * 0, 0, 0)], k=[0, 0, 1, 1]) noMoveCrvTweak2 = pm.curve(d=2, p=[(self.size * 0.0, 0, 0), (self.size * 0.25, 0, 0), (self.size * 0.50, 0, 0)], k=[0, 0, 1, 1]) # Deformers das superficies noMove twist1 = pm.nonLinear(noMoveBend1[0], type='twist') # twist das superficies noMove twist2 = pm.nonLinear(noMoveBend2[0], type='twist') twist1[1].rotateZ.set(90) twist2[1].rotateZ.set(90) wireTweak1 = pm.wire(noMoveBend1[0], w=noMoveCrvTweak1, dds=[(0, 50)]) wireTweak2 = pm.wire(noMoveBend2[0], w=noMoveCrvTweak2, dds=[(0, 50)]) wireDef = pm.wire(noMoveBend1[0], noMoveBend2[0], w=noMoveCrvJnt, dds=[(0, 50)]) # Wire das superficies noMove wireDef[0].rotation.set(1) # seta wire controlando rotacao baseWire = [x for x in wireDef[0].connections() if 'BaseWire' in x.name()] baseWireTweak1 = [x for x in wireTweak1[0].connections() if 'BaseWire' in x.name()] baseWireTweak2 = [x for x in wireTweak2[0].connections() if 'BaseWire' in x.name()] pm.group(baseWire, baseWireTweak1, baseWireTweak2, noMoveCrvJnt, noMoveCrvTweak1, noMoveCrvTweak2, noMoveBend1[0], noMoveBend2[0], p=noMoveSpace, n=self.name + 'Deforms') pm.parent(twist1[1], twist2[1], noMoveSpace) ###Estrutura que pode ser movida cntrlsSpace = pm.group(empty=True, n=self.ribbonDict['moveallSetup']['nameTempl']) cntrlsSpace.translate.set(self.size * -0.5, 0, 0) bendSurf1 = pm.nurbsPlane(p=(self.size * -0.25, 0, 0), ax=(0, 0, 1), w=self.size * 0.5, lr=.1, d=3, u=5, v=1) bendSurf2 = pm.nurbsPlane(p=(self.size * 0.25, 0, 0), ax=(0, 0, 1), w=self.size * 0.5, lr=.1, d=3, u=5, v=1) # blendShape transferindo as deformaacoes para a superficie move blend1 = pm.blendShape(noMoveBend1[0], bendSurf1[0]) blend2 = pm.blendShape(noMoveBend2[0], bendSurf2[0]) pm.blendShape(blend1, e=True, w=[(0, 1)]) pm.blendShape(blend2, e=True, w=[(0, 1)]) pm.parent(bendSurf1[0], bendSurf2[0], cntrlsSpace) ##Cntrls tweak1Cls = pm.cluster(noMoveCrvTweak1.name()+'.cv[1]') tweak2Cls = pm.cluster(noMoveCrvTweak2.name() + '.cv[1]') displaySetup = self.ribbonDict['ctrlTweakSetup'].copy() cntrlName = displaySetup['nameTempl'] + '1' cntrlTweak1 = controlTools.cntrlCrv(name=cntrlName, obj=tweak1Cls[1], connType='connection', align='pivot', offsets=1, **displaySetup) cntrlName = displaySetup['nameTempl'] + '2' cntrlTweak2 = controlTools.cntrlCrv(name=cntrlName, obj=tweak2Cls[1], connType='connection', align='pivot', offsets=1, **displaySetup) controlTools.addMultiply([cntrlTweak1.getParent(), cntrlTweak2.getParent()]) tweakFoll1 = self.attachObj(obj=cntrlTweak1.getParent(3), mesh=bendSurf1[0], u=0.5, v=0.5, mode=4) tweakFoll2 = self.attachObj(obj=cntrlTweak2.getParent(3), mesh=bendSurf2[0], u=0.5, v=0.5, mode=4) tweakGrp = pm.group(tweak1Cls[1], tweak2Cls[1], n=self.name+'TweakCls_grp') pm.parent(tweakGrp, noMoveSpace) pm.parent(cntrlTweak1.getParent(3), cntrlTweak2.getParent(3), cntrlsSpace) for i in range(0, 7): anchor = pm.cluster(noMoveCrvJnt.name() + '.cv[' + str(i + 3) + ']') pm.cluster(anchor[1], e=True, g=dummyCrv) clsHandle = anchor[1] anchorGrp = pm.group(em=True, n=self.name+'clusterGrp' + str(i)) anchorDrn = pm.group(em=True, n=self.name+'clusterDrn' + str(i), p=anchorGrp) pos = pm.xform(anchor[1], q=True, ws=True, rp=True) pm.xform(anchorGrp, t=pos, ws=True) pm.parent(anchor[1], anchorDrn) anchorList.append(anchor[1]) if i == 0 or i == 6: displaySetup = self.ribbonDict['cntrlSetup'].copy() cntrlName = displaySetup['nameTempl'] + str(i) cntrl = controlTools.cntrlCrv(name=cntrlName, obj=anchor[1], **displaySetup) elif i == 3: displaySetup = self.ribbonDict['midCntrlSetup'].copy() cntrlName = displaySetup['nameTempl'] + str(i) cntrl = controlTools.cntrlCrv(name=cntrlName, obj=anchor[1], **displaySetup) else: displaySetup = self.ribbonDict['cntrlTangSetup'].copy() cntrlName = displaySetup['nameTempl'] + str(i) cntrl = controlTools.cntrlCrv(name=cntrlName, obj=anchor[1], **displaySetup) offCtrlLoc.append(pm.spaceLocator(n=cntrlName+'off_loc')) offCtrlLoc[-1].localScale.set(0.2, 0.2, 0.2) pm.parent(offCtrlLoc[-1], cntrl, r=True) if i in [1, 2, 4, 5]: offCtrlLoc[-1].getShape().visibility.set(False) # Nao pode fazer conexao na criacao do controle, pois tera conexao direta pm.xform(cntrl.getParent(), t=pos, ws=True) # estrutura de buffers para conexao direta auxLocGrp = pm.group(em=True, n=self.name + 'Aux_grp') auxLoc = pm.group(em=True, p=auxLocGrp, n=self.name + str(i)+ 'Aux_loc') pm.xform(auxLocGrp, t=pos, ws=True) loc = pm.PyNode(auxLoc) if i==0 or i==3 or i==6: tmpOffAuxLoc = pm.group(em=True, n=self.name + str(i) + 'AuxOff_loc') offAuxLoc.append(tmpOffAuxLoc) pm.parent(tmpOffAuxLoc, auxLoc, r=True) offCtrlLoc[-1].translate >> offAuxLoc[-1].translate offCtrlLoc[-1].rotate >> offAuxLoc[-1].rotate if i == 1 or i == 4: pm.xform(anchorGrp, s=(-1, 1, 1), r=True) pm.xform(cntrl.getParent(), s=(-1, 1, 1), r=True) pm.xform(loc.getParent(), s=(-1, 1, 1), r=True) # Conexoes dos buffers cm os clusters e com os controles pm.parentConstraint(cntrl, loc, mo=True) loc.translate >> anchorDrn.translate loc.rotate >> anchorDrn.rotate cntrlList.append(cntrl) locList.append(loc) # workaround do flip do inicio do wire(adicao de mais pontos) startCls = pm.cluster(noMoveCrvJnt.name() + '.cv[0:2]') endCls = pm.cluster(noMoveCrvJnt.name() + '.cv[10:14]') pm.cluster(startCls[1], e=True, g=dummyCrv) pm.cluster(endCls[1], e=True, g=dummyCrv) pm.parent(startCls[1], anchorList[0]) pm.parent(endCls[1], anchorList[6]) cntrlsSpace.addAttr('midCtrlViz', at='double', dv=1, max=1, min=0, k=True, h=False) cntrlsSpace.addAttr('bezierCtrlViz', at='double', dv=1,max=1, min=0, k=True, h=False) cntrlsSpace.addAttr('bendExtraCtrlViz', at='double',max=1, min=0, dv=1, k=True, h=False) cntrlsSpace.addAttr('extraCtrlsVis', at='double', dv=0,max=1, min=0, k=True, h=False) cntrlList[0].addAttr('twist', at='double', dv=0, k=True) cntrlList[0].addAttr('stretchDist', at='double', dv=0, k=True) cntrlList[0].addAttr('autoVolumStregth', at='double', dv=0, k=True) cntrlList[3].addAttr('twist', at='double', dv=0, k=True) cntrlList[3].addAttr('autoVolume', at='double', dv=0, k=True) cntrlList[6].addAttr('twist', at='double', dv=0, k=True) cntrlList[6].addAttr('stretchDist', at='double', dv=0, k=True) cntrlList[6].addAttr('autoVolumStregth', at='double', dv=0, k=True) cntrlList[0].twist >> twist1[0].endAngle cntrlList[3].twist >> twist1[0].startAngle cntrlList[3].twist >> twist2[0].endAngle cntrlList[6].twist >> twist2[0].startAngle # cria sistema do tweak pra compensar twist da ribbon tweak1Twist1Multi = pm.createNode('multDoubleLinear', name='tweak1Twist1Multi') tweak1Twist2Multi = pm.createNode('multDoubleLinear', name='tweak1Twist1Multi') tweak1Add = pm.createNode('addDoubleLinear', name='tweak1Add') tweak2Twist1Multi = pm.createNode('multDoubleLinear', name='tweak1Twist1Multi') tweak2Twist2Multi = pm.createNode('multDoubleLinear', name='tweak1Twist1Multi') tweak2Add = pm.createNode('addDoubleLinear', name='tweak1Add') cntrlList[0].twist >> tweak1Twist1Multi.input1 tweak1Twist1Multi.input2.set(-0.5) cntrlList[3].twist >> tweak1Twist2Multi.input1 tweak1Twist2Multi.input2.set (-0.5) tweak1Twist1Multi.output >> tweak1Add.input1 tweak1Twist2Multi.output >> tweak1Add.input2 tweak1Add.output >> cntrlTweak1.getParent(2).rotate.rotateX cntrlList[6].twist >> tweak2Twist1Multi.input1 tweak2Twist1Multi.input2.set(-0.5) cntrlList[3].twist >> tweak2Twist2Multi.input1 tweak2Twist2Multi.input2.set(-0.5) tweak2Twist1Multi.output >> tweak2Add.input1 tweak2Twist2Multi.output >> tweak2Add.input2 tweak2Add.output >> cntrlTweak2.getParent(2).rotate.rotateX # hierarquia pm.parent(anchorList[1].getParent(2), anchorList[0]) pm.parent(anchorList[5].getParent(2), anchorList[6]) pm.parent(anchorList[2].getParent(2), anchorList[4].getParent(2), anchorList[3]) pm.parent(cntrlList[1].getParent(), offCtrlLoc[0]) pm.parent(cntrlList[5].getParent(), offCtrlLoc[6]) pm.parent(cntrlList[2].getParent(), cntrlList[4].getParent(), offCtrlLoc[3]) pm.parent(cntrlList[3].getParent(), cntrlList[0].getParent(), cntrlList[6].getParent(), cntrlsSpace) pm.parent(locList[1].getParent(), offAuxLoc[0]) pm.parent(locList[5].getParent(), offAuxLoc[2]) pm.parent(locList[2].getParent(), locList[4].getParent(), offAuxLoc[1]) pm.parent(locList[3].getParent(), locList[0].getParent(), locList[6].getParent(), cntrlsSpace) pm.parent(anchorList[3].getParent(2), anchorList[0].getParent(2), anchorList[6].getParent(2), noMoveSpace) for i, j in zip([1, 2, 4, 5], [0, 3, 3, 6]): crv = pm.curve(d=1, p=[(1, 0, 0), (-1, 0, 0)], k=[0, 1]) crv.inheritsTransform.set(False) crv.template.set(True) offCtrlLoc[i].worldPosition[0] >> crv.getShape().controlPoints[0] offCtrlLoc[j].worldPosition[0] >> crv.getShape().controlPoints[1] pm.parent(crv, offCtrlLoc[i], r=True) # Skin joints do ribbon skinJntsGrp = pm.group(em=True, n=self.name + 'SkinJnts') follGrp = pm.group(em=True, n=self.name + 'Foll_grp') pm.parent(tweakFoll1, tweakFoll2, follGrp) # cria ramps para controlar o perfil de squash e stretch ramp1 = pm.createNode('ramp', n=self.name+'SquashRamp1') ramp1.attr('type').set(1) ramp2 = pm.createNode('ramp', n=self.name+'SquashRamp2') ramp2.attr('type').set(1) expre1 = "float $dummy = " + ramp1.name() + ".outAlpha;float $output[];float $color[];" expre2 = "float $dummy = " + ramp2.name() + ".outAlpha;float $output[];float $color[];" extraCntrlsGrp = pm.group(em=True, r=True, p=cntrlsSpace, n=self.name + 'ExtraCntrls') # loop pra fazer os colocar o numero escolhido de joints ao longo do ribbon. # cria tmb node tree pro squash/stretch # e controles extras vIncrement = float((1.0 - (self.offsetStart + self.offsetEnd)) / ((self.numJnts - 2) / 2.0)) for i in range(1, (self.numJnts / 2) + 1): # cria estrutura pra superficie 1 pm.select(cl=True) jntName = self.ribbonDict['jntSetup']['nameTempl'] + 'A' + str(i) + self.jntSulfix jnt1 = pm.joint(p=(0, 0, 0), n=jntName) self.skinJoints.append(jnt1) displaySetup = self.ribbonDict['cntrlExtraSetup'].copy() cntrlName = displaySetup['nameTempl'] + 'A' + str(i) cntrl1 = controlTools.cntrlCrv(name=cntrlName, obj=jnt1, connType='constraint', **displaySetup) # node tree blend1A = pm.createNode('blendTwoAttr', n=self.name+'VolumeBlend1A') blend1B = pm.createNode('blendTwoAttr', n=self.name+'VolumeBlend1B') gammaCorr1 = pm.createNode('gammaCorrect', n=self.name+'VolumeGamma1') cntrlList[0].attr('autoVolumStregth') >> gammaCorr1.gammaX cntrlList[0].attr('stretchDist') >> gammaCorr1.value.valueX blend1A.input[0].set(1) gammaCorr1.outValueX >> blend1A.input[1] blend1B.input[0].set(1) blend1A.output >> blend1B.input[1] cntrlList[3].attr ('autoVolume') >> blend1B.attributesBlender blend1B.output >> cntrl1.getParent().scaleY blend1B.output >> cntrl1.getParent().scaleZ # expressao que le a rampa para setar valores da escala de cada joint quando fizer squash/stretch expre1 = expre1 + "$color = `colorAtPoint -o RGB -u " + str( self.offsetStart + (i - 1) * vIncrement) + " -v 0.5 " + ramp1.name() + " `;$output[" + str( i) + "] = $color[0];" + blend1A.name() + ".attributesBlender=$output[" + str(i) + "];" # cria estrutura pra superficie 2 pm.select(cl=True) jntName = self.ribbonDict['jntSetup']['nameTempl'] + 'B' + str(i) + self.jntSulfix jnt2 = pm.joint(p=(0, 0, 0), n=jntName) self.skinJoints.append(jnt2) displaySetup = self.ribbonDict['cntrlExtraSetup'].copy() cntrlName = displaySetup['nameTempl'] + 'B' + str(i) cntrl2 = controlTools.cntrlCrv(name=cntrlName, connType='constraint', obj=jnt2, **displaySetup) # node tree blend2A = pm.createNode('blendTwoAttr', n=self.name+'VolumeBlend2A') blend2B = pm.createNode('blendTwoAttr', n=self.name+'VolumeBlend2B') gammaCorr2 = pm.createNode('gammaCorrect', n=self.name+'VolumeGamma2') cntrlList[6].attr('autoVolumStregth') >> gammaCorr2.gammaX cntrlList[6].attr('stretchDist') >> gammaCorr2.value.valueX blend2A.input[0].set(1) gammaCorr2.outValueX >> blend2A.input[1] blend2B.input[0].set(1) blend2A.output >> blend2B.input[1] cntrlList[3].attr('autoVolume') >> blend2B.attributesBlender blend2B.output >> cntrl2.getParent().scaleY blend2B.output >> cntrl2.getParent().scaleZ # expressao que le a rampa para setar valores da escala de cada joint quando fizer squash/stretch expre2 = expre2 + "$color = `colorAtPoint -o RGB -u " + str( self.offsetStart + (i - 1) * vIncrement) + " -v 0.5 " + ramp2.name() + " `;$output[" + str( i) + "] = $color[0];" + blend2A.name() + ".attributesBlender=$output[" + str(i) + "];" # prende joints nas supeficies com follicules foll1 = self.attachObj(cntrl1.getParent(), bendSurf1[0], self.offsetStart + (i - 1) * vIncrement, 0.5, 4) foll2 = self.attachObj(cntrl2.getParent(), bendSurf2[0], self.offsetStart + (i - 1) * vIncrement, 0.5, 4) pm.parent(cntrl1.getParent(), cntrl2.getParent(), extraCntrlsGrp) pm.parent(jnt1, jnt2, skinJntsGrp) pm.parent(foll1, foll2, follGrp) pm.select (cl=True) jntName = self.ribbonDict['jntSetup']['nameTempl'] +'Elbow' + self.jntSulfix elbowJnt = pm.joint(p=(0, 0, 0), n=jntName) pm.parent(elbowJnt, skinJntsGrp) elbowAuxFoll1 = self.createFoll(bendSurf1[0], 0.999, 0.5) elbowAuxFoll2 = self.createFoll(bendSurf2[0], 0.001, 0.5) pm.parent(elbowAuxFoll1, elbowAuxFoll2, follGrp) orientConstraint = pm.PyNode(pm.orientConstraint(elbowAuxFoll1, elbowAuxFoll2, elbowJnt, mo=False)) orientConstraint.interpType.set(2) pm.pointConstraint(cntrlList[3], elbowJnt, mo=False) # seta expressoes para so serem avaliadas por demanda pm.expression(s=expre1, ae=False, n=self.name+'Expression1') pm.expression(s=expre2, ae=False, n=self.name+'Expression2') pm.parent(skinJntsGrp, cntrlsSpace) pm.parent(follGrp, noMoveSpace) # hideCntrls pm.toggle(bendSurf1[0], bendSurf2[0], g=True) bendSurf1[0].visibility.set(0) bendSurf2[0].visibility.set (0) # skinJntsGrp.visibility.set(0) cntrlsSpace.extraCtrlsVis >> extraCntrlsGrp.visibility cntrlsSpace.bezierCtrlViz >> cntrlList[0].getParent().visibility cntrlsSpace.midCtrlViz >> cntrlList[3].getParent().visibility cntrlsSpace.bezierCtrlViz >> cntrlList[4].getParent().visibility cntrlsSpace.bezierCtrlViz >> cntrlList[2].getParent().visibility cntrlsSpace.bezierCtrlViz >> cntrlList[6].getParent().visibility cntrlsSpace.bendExtraCtrlViz >> cntrlTweak1.getParent().visibility cntrlsSpace.bendExtraCtrlViz >> cntrlTweak2.getParent().visibility # povoa ribbon Dict self.ribbonDict['name'] = 'bezierRibbon' self.ribbonDict['ribbonMoveAll'] = cntrlsSpace for i in range(0, 7): self.ribbonDict['cntrl' + str(i)] = cntrlList[i]
def construction(self): self.folList = [] #create burbs plane ribbonGeo = pm.nurbsPlane(p = (0,0,0),ax = (0,1,0),w = self.Width,lr = self.Length, d = 3,u = self.UVal,v = self.segment,ch = 1,n = (self.side + '_' + self.RibbonName + '_Rbbn01_geo_01_')) #rebuild ribbon geo if self.VVal > self.UVal: pm.rebuildSurface(ribbonGeo[0],ch = 1,rpo = 1,rt = 0,end = 1,kr = 0,kcp = 0,kc = 0,su = self.UVal,du = 1,sv = self.VVal,dv = 3,tol = 0.000155,fr = 0,dir = 2) if self.UVal > self.VVal: pm.rebuildSurface(ribbonGeo[0],ch = 1,rpo = 1,rt = 0,end = 1,kr = 0,kcp = 0,kc = 0,su = self.UVal,du = 3,sv = self.VVal,dv = 1,tol = 0.000155,fr = 0,dir = 2) #clear history of ribbonGeometry pm.select(ribbonGeo[0],r = 1) pm.delete(ch = 1) #CREATE THE HAIR FOLLICLES self.folGrp = pm.group(em = 1,n = getUniqueName(self.side,self.RibbonName + 'Fol','grp')) for fol in range(self.segment): #createNodeName follicleTransName = getUniqueName(self.side,self.RibbonName,'fol') follicleShapeName = getUniqueName(self.side,self.RibbonName,'folShape') #createNode follicleShape = pm.createNode('follicle',n = follicleShapeName) follicleTrans = pm.listRelatives(follicleShape, parent=True)[0] follicleTrans = pm.rename(follicleTrans, follicleTransName) # connect the surface to the follicle if ribbonGeo[0].getShape().nodeType() == 'nurbsSurface': pm.connectAttr((ribbonGeo[0] + '.local'), (follicleShape + '.inputSurface')) #Connect the worldMatrix of the surface into the follicleShape pm.connectAttr((ribbonGeo[0] + '.worldMatrix[0]'), (follicleShape + '.inputWorldMatrix')) #Connect the follicleShape to it's transform pm.connectAttr((follicleShape + '.outRotate'), (follicleTrans + '.rotate')) pm.connectAttr((follicleShape + '.outTranslate'), (follicleTrans + '.translate')) #Set the uValue and vValue for the current follicle pm.setAttr((follicleShape + '.parameterU'), 0.5) pm.setAttr((follicleShape + '.parameterV'), float(1.0 / self.segment) * fol + (1.0 / (self.segment * 2))) #Lock the translate/rotate of the follicle pm.setAttr((follicleTrans + '.translate'), lock=True) pm.setAttr((follicleTrans + '.rotate'), lock=True) #parent self.folList.append(follicleTrans) follicleTrans.setParent(self.folGrp) #CREATE JOINTS SNAPPED AND PARENTED TO THE FOLLICLE--- for num,fol in enumerate(self.folList): jJoint = pm.joint(n = self.side + '_' + self.RibbonName + '_Rbbn0' + str(num) + '_jj',p = (0,0,0),rad = min(self.Width,self.Length) * .25) pm.parent(jJoint,fol) jJoint.translate.set(0,0,0) self.jj.append(jJoint) #CREATE SOME TEMPORARY CLUSTERS TO PLACE THE POS LOCATORS--- if self.UVal > self.VVal: vNo = self.UVal + 2 pm.select(self.side + '_' + self.RibbonName + '_Rbbn01_geo_01_.cv[' + str(vNo) + '][0:1]',r = 1) startCls = pm.cluster(n = 'spCltr') pm.select(self.side + '_' + self.RibbonName + '_Rbbn01_geo_01_.cv[0][0:1]',r = 1) endCls = pm.cluster(n = 'epCltr') if self.VVal > self.UVal: vNo = self.VVal + 2 pm.select(self.side + '_' + self.RibbonName + '_Rbbn01_geo_01_.cv[0:1][' + str(vNo) + ']',r = 1) startCls = pm.cluster(n = 'spCltr') pm.select(self.side + '_' + self.RibbonName + '_Rbbn01_geo_01_.cv[0:1][0]',r = 1) endCls = pm.cluster(n = 'epCltr') #CREATE SOME LOCATORS--- #CREATE START POINT LOCATORS AND PARENT THEM PROPERLY--- spLocPos = pm.spaceLocator(p = (0,0,0), n = self.side + '_' + self.RibbonName + '_RbbnSp01_pos') spLocAim = pm.spaceLocator(p = (0,0,0), n = self.side + '_' + self.RibbonName + '_RbbnSp01_aim') self.startUploc = pm.spaceLocator(p = (0,0,0), n = self.side + '_' + self.RibbonName + '_RbbnSp01_up') #hide shape # spLocPos.getShape().v.set(0) # spLocAim.getShape().v.set(0) # spLocUp.getShape().v.set(0) self.startLoc = spLocPos pm.parent(spLocAim,spLocPos) pm.parent(self.startUploc,spLocPos) #CREATE MID POINT LOCATORS AND PARENT THEM PROPERLY--- mpLocPos = pm.spaceLocator(p = (0,0,0), n = self.side + '_' + self.RibbonName + '_RbbnMp01_pos') self.mpLocAim = pm.spaceLocator(p = (0,0,0), n = self.side + '_' + self.RibbonName + '_RbbnMp01_aim') mpLocUp = pm.spaceLocator(p = (0,0,0), n = self.side + '_' + self.RibbonName + '_RbbnMp01_up') #hide shape # mpLocPos.getShape().v.set(0) # self.mpLocAim.getShape().v.set(0) # mpLocUp.getShape().v.set(0) self.midloc = mpLocPos pm.parent(self.mpLocAim,mpLocPos) pm.parent(mpLocUp,mpLocPos) #CREATE END POINT LOCATORS AND PARENT THEM PROPERLY--- epLocPos = pm.spaceLocator(p = (0,0,0), n = self.side + '_' + self.RibbonName + '_RbbnEp01_pos') epLocAim = pm.spaceLocator(p = (0,0,0), n = self.side + '_' + self.RibbonName + '_RbbnEp01_aim') self.epUploc = pm.spaceLocator(p = (0,0,0), n = self.side + '_' + self.RibbonName + '_RbbnEp01_up') #hide shape # epLocPos.getShape().v.set(0) # epLocAim.getShape().v.set(0) # self.epUploc.getShape().v.set(0) self.endLoc = epLocPos pm.parent(epLocAim,epLocPos) pm.parent(self.epUploc,epLocPos) #CONSTRAINT EACH LOCATORS PROPERLY--- pm.pointConstraint('spCltrHandle',spLocPos,o = (0,0,0),w = 1) pm.delete(self.side + '_' + self.RibbonName + '_RbbnSp01_pos_pointConstraint1') pm.pointConstraint('epCltrHandle',epLocPos,o = (0,0,0),w = 1) pm.delete(self.side + '_' + self.RibbonName + '_RbbnEp01_pos_pointConstraint1') pm.pointConstraint(spLocPos,epLocPos,mpLocPos,o = (0,0,0),w = 1) pm.pointConstraint(self.startUploc,self.epUploc,mpLocUp,o = (0,0,0),w = 1) #OFFSET THE POSITION OF THE UP LOCATOR--- pm.setAttr(self.startUploc.ty,min(self.Width,self.Length) * .5) pm.setAttr(self.epUploc.ty,min(self.Width,self.Length) * .5) #CREATE CTRL JOINTS pm.select(cl = 1) tx = tz = 0.0 if self.VVal > self.UVal: tz = self.Length * .2 if self.UVal > self.VVal: tx = self.Width * .2 ############# #transmit Jc joint info--- #FOR START POINT JOINT--- self.startJc = pm.joint(p = (0,0,0),rad = min(self.Width,self.Length) * .5,n = self.side + '_' + self.RibbonName + '_RbbnSp01_jc') pm.joint(p = (tx * .6,0,tz * .6),rad = min(self.Width,self.Length) * .5,n = self.side + '_' + self.RibbonName + '_RbbnSp02_jc') pm.joint(e = 1,zso = 1,oj = 'xyz',sao = 'yup',n = self.side + '_' + self.RibbonName + '_RbbnSp02_jc') #FOR MIDDLE POINT JOINT--- pm.select(cl = 1) self.midJc = pm.joint(p = (0,0,0),rad = min(self.Width,self.Length) * .5,n = self.side + '_' + self.RibbonName + '_RbbnMp01_jc') pm.joint(e = 1,zso = 1,oj = 'xyz',sao = 'yup',n = self.side + '_' + self.RibbonName + '_RbbnMp01_jc') #FOR END POINT JOINT--- pm.select(cl = 1) self.endJc = pm.joint(p = (0,0,0),rad = min(self.Width,self.Length) * .5,n = self.side + '_' + self.RibbonName + '_RbbnEp01_jc') pm.joint(p = (tx * -0.6,0,tz * -0.6),rad = min(self.Width,self.Length) * .5,n = self.side + '_' + self.RibbonName + '_RbbnEp02_jc') pm.joint(e = 1,zso = 1,oj = 'xyz',sao = 'yup',n = self.side + '_' + self.RibbonName + '_RbbnEp02_jc') #PARENT THE CONTROL JOINTS APPROPRIATLY--- pm.parent(self.side + '_' + self.RibbonName + "_RbbnSp01_jc",spLocAim,r = 1) pm.parent(self.side + '_' + self.RibbonName + "_RbbnMp01_jc",self.mpLocAim,r = 1) pm.parent(self.side + '_' + self.RibbonName + "_RbbnEp01_jc",epLocAim,r = 1) #APPLY THE AIM CONSTRINTS--- aTz = 0 if self.VVal > self.UVal: aTz = 1 aTx = 0 if self.UVal > self.VVal: aTx = 1 #FOR MIDDLE POINT--- pm.aimConstraint(self.side + '_' + self.RibbonName + "_RbbnSp01_pos",self.side + '_' + self.RibbonName + "_RbbnMp01_aim",o = (0,0,0),w = 1,aim = (aTx * -1,0,aTz * -1),u = (0,1,0),wut = 'object',wuo = self.side + '_' + self.RibbonName + '_RbbnMp01_up') #FOR START POINT--- pm.aimConstraint(self.side + '_' + self.RibbonName + "_RbbnMp01_jc",self.side + '_' + self.RibbonName + "_RbbnSp01_aim",o = (0,0,0),w = 1,aim = (aTx,0,aTz),u = (0,1,0),wut = 'object',wuo = self.side + '_' + self.RibbonName + '_RbbnSp01_up') #FOR END POINT--- pm.aimConstraint(self.side + '_' + self.RibbonName + "_RbbnMp01_jc",self.side + '_' + self.RibbonName + "_RbbnEp01_aim",o = (0,0,0),w = 1,aim = (aTx * -1,0,aTz * -1),u = (0,1,0),wut = 'object',wuo = self.side + '_' + self.RibbonName + '_RbbnEp01_up') #APPLY SKINCLUSTER--- pm.select(cl = 1) pm.skinCluster(self.side + '_' + self.RibbonName + "_RbbnSp01_jc",self.side + '_' + self.RibbonName + "_RbbnMp01_jc",self.side + '_' + self.RibbonName + "_RbbnEp01_jc",self.side + '_' + self.RibbonName + "_Rbbn01_geo_01_",tsb = 1,ih = 1,mi = 3,dr = 4,rui = 1) #CLEAN UP pm.delete(startCls) pm.delete(endCls) pm.rename(self.side + '_' + self.RibbonName + '_Rbbn01_geo_01_',self.side + '_' + self.RibbonName + '_Rbbn01_geo_01') #GROUP THEM ALL self.main = pm.group(self.folGrp,self.side + '_' + self.RibbonName + '_Rbbn01_geo_01',self.side + '_' + self.RibbonName + '_RbbnSp01_pos',self.side + '_' + self.RibbonName + '_RbbnMp01_pos',self.side + '_' + self.RibbonName + '_RbbnEp01_pos',n = self.side + '_' + self.RibbonName + "_Rbbn01_grp") pm.xform(os = 1,piv = (0,0,0)) if self.subMid == 1: self.__midCC()
def addOffset(node): ''' - add a grp above node - add a nurbs plane under grp's parent (get the same local space) - unparent nurbs plane to world space (or whichever deformer space - e.g. headLattice) - add pointOnSurfaceInfo to get position and orientation for grp - use aimconstraint to convert vectors to orientation - return grp as offset example use for mathilda: import rigger.modules.surfOffset as surfOffset reload(surfOffset) nodes = pm.ls(sl=True) offsets = [] for n in nodes: offsetGrp = surfOffset.addOffset(n) offsets.append(offsetGrp[1]) pm.select(offsets) ''' nodeMatrix = node.getMatrix(worldSpace=True) offsetGrp = pm.group(em=True, n=node+'_surfOffset_grp') offsetGrp.setMatrix(nodeMatrix, worldSpace=True) # hierarchy # also check for sibling nodes, such as scaleX/Y xfos siblings = node.getSiblings() for sibling in siblings: offsetGrp | sibling parentNode = node.getParent() parentNode | offsetGrp | node # nurbs plane plane = pm.nurbsPlane(n=node+'_surfOffset_srf', ch=False, degree=1, axis=(0,1,0))[0] # parentNode | plane # don't # use separate hierachy planeGrp = pm.group(plane, n=node+'_surfOffsetSrf_grp') planeHm = pm.group(planeGrp, n=node+'_surfOffsetSrf_hm') planeHm.setMatrix(nodeMatrix, worldSpace=True) parentNode | planeHm # point on surface info posi = pm.createNode('pointOnSurfaceInfo', n=node+'_surfOffset_posi') plane.local >> posi.inputSurface posi.parameterU.set(0.5) posi.parameterV.set(0.5) ''' # convert vectors to orientation using aim constraint aimc = pm.createNode('aimConstraint', n=node+'_surfOffset_aimc') offsetGrp | aimc posi.normal >> aimc.tg[0].tt posi.tangentU >> aimc.worldUpVector aimc.aimVector.set((0,1,0)) aimc.upVector.set((1,0,0)) ''' ''' # use cross products instead of aim constraint vpZ = pm.createNode('vectorProduct', n=node+'_surfOffsetZVec_vp') posi.normal >> vpZ.input1 # Y posi.tangentU >> vpZ.input2 vpZ.operation.set(2) vpX = pm.createNode('vectorProduct', n=node+'_surfOffsetXVec_vp') posi.normal >> vpZ.input1 # Y posi.tangentU >> vpZ.input2 vpZ.operation.set(2)''' # just use vectors from posi to construct matrix! mat = pm.createNode('fourByFourMatrix', n=node+'_surfOffset_fbfm') # x-vector posi.tangentUx >> mat.in00 posi.tangentUy >> mat.in01 posi.tangentUz >> mat.in02 # y-vector posi.normalX >> mat.in10 posi.normalY >> mat.in11 posi.normalZ >> mat.in12 # z-vector posi.tangentVx >> mat.in20 posi.tangentVy >> mat.in21 posi.tangentVz >> mat.in22 # position posi.positionX >> mat.in30 posi.positionY >> mat.in31 posi.positionZ >> mat.in32 # drive grp dcm = pm.createNode('decomposeMatrix', n=node+'_surfOffset_dcm') mat.output >> dcm.inputMatrix dcm.outputTranslate >> offsetGrp.t dcm.outputRotate >> offsetGrp.r return offsetGrp, plane
def create_nurbs_plane_from_joints(jnts, degree=1, width=1): """ Create a nurbsPlane following a provided joint chain. Note that the plane is oriented in the up axis (Y) of each joint. """ # Create nurbsPlane num_patches_u = (len(jnts)-1) plane = pymel.nurbsPlane(d=degree, u=num_patches_u)[0] pos_upp_local = pymel.datatypes.Point(0,0,width) pos_dwn_local = pymel.datatypes.Point(0,0,-width) # Define how much in-between we need to compute. num_patches_v = 2 num_inbetweens_outside = 0 num_inbetweens_inside = 0 add_inside_edges = True if degree == 1: # Linear pass elif degree == 2: # Quadratic num_inbetweens_outside = 1 num_inbetweens_inside = 1 add_inside_edges = False num_patches_v = 3 elif degree == 3: # Cubic num_inbetweens_outside = 1 num_patches_v = 4 else: # TODO: Support missing degrees! Exception("Unexpected value for parameter degree, got {0}.".format(degree)) # Resolve ratios to compute v positions more easily. v_ratios = [v / float(num_patches_v-1) for v in range(num_patches_v)] # Resolve positions for edges edges_positions_upp = [] edges_positions_dwn = [] for i, jnt in enumerate(jnts): jnt_tm_world = jnt.getMatrix(worldSpace=True) pos_upp = pos_upp_local * jnt_tm_world pos_dwn = pos_dwn_local * jnt_tm_world edges_positions_upp.append(pos_upp) edges_positions_dwn.append(pos_dwn) # Resolve all positions including in-between all_positions = [] num_edges = len(edges_positions_upp) for i in range(num_edges-1): pos_upp_inn = edges_positions_upp[i] pos_dwn_inn = edges_positions_dwn[i] is_first = i == 0 is_before_last = i == num_edges - 2 is_last = i == num_edges - 1 # Add edge (note that we always add the first and last edge edge). if is_first or is_last or add_inside_edges: all_positions.append(interp_linear_multiple(v_ratios, pos_upp_inn, pos_dwn_inn)) # Add in-betweens if is_last: # For obvious reasons, we don't want to add any points after the last edge. continue num_inbetweens = num_inbetweens_outside if is_first or is_before_last else num_inbetweens_inside if num_inbetweens: pos_upp_out = edges_positions_upp[i+1] pos_dwn_out = edges_positions_dwn[i+1] for j in range(num_inbetweens_outside): ratio = float(j+1)/(num_inbetweens_outside+1) pos_upp = interp_linear(ratio, pos_upp_inn, pos_upp_out) pos_dwn = interp_linear(ratio, pos_dwn_inn, pos_dwn_out) all_positions.append(interp_linear_multiple(v_ratios, pos_upp, pos_dwn)) # Add last edge all_positions.append(interp_linear_multiple(v_ratios, edges_positions_upp[-1], edges_positions_dwn[-1])) # Model the plane for u in range(len(all_positions)): for v in range(len(all_positions[u])): pos = all_positions[u][v] plane.setCV(u, v, pos) return plane
def doRig(self): anchorList = [] cntrlList = [] locList = [] dummyCrv = self.ribbonDict['moveallSetup']['nameTempl'] + '_dummy_crv' pm.hide(pm.polyCube(n=dummyCrv)) if pm.objExists(self.ribbonDict['noMoveSetup']['nameTempl']): pm.delete(self.ribbonDict['noMoveSetup']['nameTempl']) if pm.objExists(self.ribbonDict['moveallSetup']['nameTempl']): pm.delete(self.ribbonDict['moveallSetup']['nameTempl']) logger ###Estrutura que nao deve ter transformacao noMoveSpace = pm.group(empty=True, n=self.ribbonDict['noMoveSetup']['nameTempl']) if not pm.objExists('NOMOVE'): pm.group(self.ribbonDict['noMoveSetup']['nameTempl'], n='NOMOVE') else: pm.parent(self.ribbonDict['noMoveSetup']['nameTempl'], 'NOMOVE') pm.parent(self.ribbonDict['moveallSetup']['nameTempl'] + '_dummy_crv', noMoveSpace) noMoveSpace.visibility.set(0) noMoveBend1 = pm.nurbsPlane(p=(self.size * 0.5, 0, 0), ax=(0, 0, 1), w=self.size, lr=0.1, d=3, u=5, v=1) # noMoveCrvJnt = pm.curve ( bezier=True, d=3, p=[(self.size*-0.5,0,0),(self.size*-0.4,0,0),(self.size*-0.1,0,0),(0,0,0),(self.size*0.1,0,0),(self.size*0.4,0,0),(self.size*0.5,0,0)], k=[0,0,0,1,1,1,2,2,2]) noMoveCrvJnt = pm.curve( bezier=True, d=3, p=[(self.size * -0.50, 0, 0), (self.size * -0.499, 0, 0), (self.size * -0.496, 0, 0), (self.size * -0.495, 0, 0), (self.size * -0.395, 0, 0), (self.size * -0.10, 0, 0), (0, 0, 0), (self.size * 0.10, 0, 0), (self.size * 0.395, 0, 0), (self.size * 0.495, 0, 0), (self.size * 0.496, 0, 0), (self.size * 0.499, 0, 0), (self.size * 0.50, 0, 0)], k=[0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10]) noMoveCrvJnt.translate.set(self.size * 0.5, 0, 0) # Deformers das superficies noMove twist1 = pm.nonLinear(noMoveBend1[0], type='twist') # twist das superficies noMove twist1[1].rotateZ.set(90) # IMPLEMENTAR O TWIST DO MEIO twist2 = pm.nonLinear(noMoveBend1[0].name() + '.cv[0:3][0:3]', type='twist') # twist das superficies noMove twist2[1].rotateZ.set(90) twist3 = pm.nonLinear(noMoveBend1[0].name() + '.cv[4:7][0:3]', type='twist') # twist das superficies noMove twist3[1].rotateZ.set(90) wireDef = pm.wire(noMoveBend1[0], w=noMoveCrvJnt, dds=[(0, 50)]) # Wire das superficies noMove wireDef[0].rotation.set(1) # seta rotacao pra acontecer baseWire = [ x for x in wireDef[0].connections() if 'BaseWire' in x.name() ] pm.group(baseWire, noMoveCrvJnt, noMoveBend1[0], p=noMoveSpace, n=self.name + 'Deforms_grp') pm.parent(twist1[1], twist2[1], twist3[1], noMoveSpace) ###Estrutura que pode ser movida cntrlsSpace = pm.group(empty=True, n=self.ribbonDict['moveallSetup']['nameTempl']) bendSurf1 = pm.nurbsPlane(p=(self.size * -0.5, 0, 0), ax=(0, 0, 1), w=self.size * 0.5, lr=.1, d=3, u=5, v=1) blend1 = pm.blendShape(noMoveBend1[0], bendSurf1[0]) pm.blendShape(blend1, e=True, w=[(0, 1)]) pm.parent(bendSurf1[0], cntrlsSpace) ##Cntrls for i in range(0, 7): anchor = pm.cluster(noMoveCrvJnt.name() + '.cv[' + str(i + 3) + ']') pm.cluster(anchor[1], e=True, g=dummyCrv) clsHandle = anchor[1] anchorGrp = pm.group(em=True, n='clusterGrp' + str(i)) anchorDrn = pm.group(em=True, n='clusterDrn' + str(i), p=anchorGrp) pos = pm.xform(anchor, q=True, ws=True, rp=True) pm.xform(anchorGrp, t=pos, ws=True) pm.parent(anchor[1], anchorDrn) anchorList.append(anchor[1]) if i == 0 or i == 6: displaySetup = self.ribbonDict['cntrlSetup'].copy() cntrlName = displaySetup['nameTempl'] + str(i) cntrl = controlTools.cntrlCrv(name=cntrlName, obj=anchor[1], **displaySetup) elif i == 3: displaySetup = self.ribbonDict['midCntrlSetup'].copy() cntrlName = displaySetup['nameTempl'] + str(i) cntrl = controlTools.cntrlCrv(name=cntrlName, obj=anchor[1], **displaySetup) else: displaySetup = self.ribbonDict['cntrlTangSetup'].copy() cntrlName = displaySetup['nameTempl'] + str(i) cntrl = controlTools.cntrlCrv(name=cntrlName, obj=anchor[1], **displaySetup) # Nao pode fazer conexao na criacao do controle, pois tera conexao direta pm.xform(cntrl.getParent(), t=pos, ws=True) # estrutura de buffers para conexao direta auxLocGrp = pm.group(em=True, n=self.name + 'auxLoc_grp') auxLoc = pm.group(em=True, p=auxLocGrp, n=self.name + 'aux_loc') pm.xform(auxLocGrp, t=pos, ws=True) loc = pm.PyNode(auxLoc) if i == 1 or i == 4: pm.xform(anchorGrp, s=(-1, 1, 1), r=True) pm.xform(cntrl.getParent(), s=(-1, 1, 1), r=True) pm.xform(loc.getParent(), s=(-1, 1, 1), r=True) # Conexoes dos buffers cm os clusters e com os controles pm.parentConstraint(cntrl, loc) loc.translate >> anchorDrn.translate loc.rotate >> anchorDrn.rotate cntrlList.append(cntrl) locList.append(loc) startCls = pm.cluster(noMoveCrvJnt.name() + '.cv[0:2]') endCls = pm.cluster(noMoveCrvJnt.name() + '.cv[10:14]') pm.cluster(startCls[1], e=True, g=dummyCrv) pm.cluster(endCls[1], e=True, g=dummyCrv) pm.parent(startCls, anchorList[0]) pm.parent(endCls, anchorList[6]) cntrlsSpace.addAttr('cntrlsVis', at='double', dv=1, k=True, h=False) cntrlsSpace.addAttr('extraCntrlsVis', at='double', dv=0, k=True, h=False) cntrlList[0].addAttr('twist', at='double', dv=0, k=True) cntrlList[0].addAttr('stretchDist', at='double', dv=0, k=True) cntrlList[0].addAttr('autoVolumStregth', at='double', dv=0, k=True) cntrlList[3].addAttr('twist', at='double', dv=0, k=True) cntrlList[3].addAttr('autoVolume', at='double', dv=0, k=True) cntrlList[6].addAttr('twist', at='double', dv=0, k=True) cntrlList[6].addAttr('stretchDist', at='double', dv=0, k=True) cntrlList[6].addAttr('autoVolumStregth', at='double', dv=0, k=True) cntrlList[0].twist >> twist1[0].endAngle cntrlList[3].twist >> twist2[0].startAngle cntrlList[3].twist >> twist3[0].endAngle cntrlList[6].twist >> twist1[0].startAngle # hierarquia pm.parent(anchorList[1].getParent(2), anchorList[0]) pm.parent(anchorList[5].getParent(2), anchorList[6]) pm.parent(anchorList[2].getParent(2), anchorList[4].getParent(2), anchorList[3]) pm.parent(cntrlList[1].getParent(), cntrlList[0]) pm.parent(cntrlList[5].getParent(), cntrlList[6]) pm.parent(cntrlList[2].getParent(), cntrlList[4].getParent(), cntrlList[3]) pm.parent(cntrlList[3].getParent(), cntrlList[0].getParent(), cntrlList[6].getParent(), cntrlsSpace) pm.parent(locList[1].getParent(), locList[0]) pm.parent(locList[5].getParent(), locList[6]) pm.parent(locList[2].getParent(), locList[4].getParent(), locList[3]) pm.parent(locList[3].getParent(), locList[0].getParent(), locList[6].getParent(), cntrlsSpace) pm.parent(anchorList[3].getParent(2), anchorList[0].getParent(2), anchorList[6].getParent(2), noMoveSpace) # Skin joints do ribbon skinJntsGrp = pm.group(em=True, n=self.name + 'SkinJnts_grp') follGrp = pm.group(em=True, n=self.name + 'Foll_grp') # cria ramps para controlar o perfil de squash e stretch ramp1 = pm.createNode('ramp', n=self.name + 'SquashRamp1') ramp1.attr('type').set(1) # ramp2 = pm.createNode ('ramp') # ramp2.attr('type').set(1) expre1 = "float $dummy = " + ramp1.name( ) + ".outAlpha;float $output[];float $color[];" # expre2 = "float $dummy = "+ramp2.name()+".outAlpha;float $output[];float $color[];" extraCntrlsGrp = pm.group(em=True, r=True, p=cntrlsSpace, n=self.name + 'extraCntrls_grp') # loop pra fazer os colocar o numero escolhido de joints ao longo do ribbon. # cria tmb node tree pro squash/stretch # e controles extras vIncrement = float( (1.0 - (self.offsetStart + self.offsetEnd)) / (self.numJnts - 1)) for i in range(1, self.numJnts + 1): # cria estrutura pra superficie 1 pm.select(cl=True) jntName = self.ribbonDict['jntSetup']['nameTempl'] + str( i) + self.jntSulfix jnt1 = pm.joint(p=(0, 0, 0), n=jntName) self.skinJoints.append(jnt1) displaySetup = self.ribbonDict['cntrlExtraSetup'].copy() cntrlName = displaySetup['nameTempl'] + 'A' + str(i) cntrl1 = controlTools.cntrlCrv(name=cntrlName, obj=jnt1, connType='parentConstraint', **displaySetup) # node tree blend1A = pm.createNode('blendTwoAttr', n=self.name + 'VolumeBlend1A') blend1B = pm.createNode('blendTwoAttr', n=self.name + 'VolumeBlend1B') gammaCorr1 = pm.createNode('gammaCorrect', n=self.name + 'VolumeGamma1') cntrlList[0].attr('autoVolumStregth') >> gammaCorr1.gammaX cntrlList[0].attr('stretchDist') >> gammaCorr1.value.valueX blend1A.input[0].set(1) gammaCorr1.outValueX >> blend1A.input[1] blend1B.input[0].set(1) blend1A.output >> blend1B.input[1] cntrlList[3].attr('autoVolume') >> blend1B.attributesBlender blend1B.output >> cntrl1.getParent().scaleY blend1B.output >> cntrl1.getParent().scaleZ # expressao que le a rampa para setar valores da escala de cada joint quando fizer squash/stretch expre1 = expre1 + "$color = `colorAtPoint -o RGB -u " + str( self.offsetStart + (i - 1) * vIncrement) + " -v 0.5 " + ramp1.name( ) + " `;$output[" + str(i) + "] = $color[0];" + blend1A.name( ) + ".attributesBlender=$output[" + str(i) + "];" # prende joints nas supeficies com follicules foll1 = self.attachObj(cntrl1.getParent(), bendSurf1[0], self.offsetStart + (i - 1) * vIncrement, 0.5, 4) pm.parent(cntrl1.getParent(), extraCntrlsGrp) pm.parent(jnt1, skinJntsGrp) pm.parent(foll1, follGrp) # seta expressoes para so serem avaliadas por demanda pm.expression(s=expre1, ae=False) pm.parent(skinJntsGrp, cntrlsSpace) pm.parent(follGrp, noMoveSpace) # hideCntrls pm.toggle(bendSurf1[0], g=True) bendSurf1[0].visibility.set(0) # skinJntsGrp.visibility.set(0) cntrlsSpace.extraCntrlsVis >> extraCntrlsGrp.visibility cntrlsSpace.cntrlsVis >> cntrlList[0].getParent().visibility cntrlsSpace.cntrlsVis >> cntrlList[3].getParent().visibility cntrlsSpace.cntrlsVis >> cntrlList[6].getParent().visibility # povoa ribbon Dict self.ribbonDict['name'] = 'bezierRibbon' self.ribbonDict['ribbonMoveAll'] = cntrlsSpace for i in range(0, 7): self.ribbonDict['cntrl' + str(i)] = cntrlList[i] self.startCntrl = cntrlList[0] self.midCntrl = cntrlList[3] self.endCntrl = cntrlList[6] self.moveall = cntrlsSpace
def __createNurbs__(self): # check if plugin decompose matrix is present pmc.loadPlugin('decomposeMatrix', quiet=True) # create groups folGrp = pmc.createNode('transform', name=self.name+'_fol_NXF', parent=self.grp, skipSelect=True) self.strucGrp = pmc.createNode('transform', name=self.name+'_struc_NXF', parent=self.grp, skipSelect=True) folGrp.inheritsTransform.set(0) self.strucGrp.inheritsTransform.set(0) # create plane plan = pmc.nurbsPlane(name=self.name+'_plane', axis=[0,1,0], width=self.length, lengthRatio=(1.0/self.length)/2.0, degree=3, patchesU=4, patchesV=1, constructionHistory=0, pivot=[self.length/2.0,0,0])[0] plan.inheritsTransform.set(0) plan.setParent(folGrp) pmc.rebuildSurface( plan, constructionHistory=False, replaceOriginal=True, rebuildType=0, endKnots=1, keepRange=0, keepControlPoints=0, keepCorners=0, spansV=1, degreeV=1, fitRebuild=0, direction=1 ) # create follicle + control + bones self.subCtrlGrp = [] self.subCtrl = [] self.bones2SK = [] for i in range(self.nbItem): fol = pmc.createNode('transform', name=self.name+'_fol'+str(i+1), parent=folGrp, skipSelect=True) folShape = pmc.createNode('follicle', name=self.name+'_fol'+str(i+1)+'Shape', parent=fol, skipSelect=True) # connections plan.worldMatrix[0] >> folShape.inputWorldMatrix plan.local >> folShape.inputSurface folShape.outRotate >> fol.rotate folShape.outTranslate >> fol.translate # u and v setting folShape.parameterV.set(0.5) folShape.parameterU.set((1.0/(self.nbItem-1.0))*i) folShape.visibility.set(False) clean.__lockHideTransform__(fol, channel=['t', 'r', 's', 'v']) # sub control self.subCtrlGrp.append( pmc.createNode('transform', name=self.name+'_sub'+str(i+1)+'_grp') ) self.subCtrl.append( shapesBiblio.rhombusX(name=self.name+'_sub'+str(i+1), color=self.colorTwo) ) # add attributs pmc.addAttr(self.subCtrl[i], longName='posU', attributeType='float', defaultValue=((1.0/(self.nbItem-1.0))*i) ) pmc.addAttr(self.subCtrl[i], longName='negU', attributeType='float', defaultValue=1-((1.0/(self.nbItem-1.0))*i) ) self.subCtrl[-1].setParent(self.subCtrlGrp[-1]) self.subCtrlGrp[-1].setParent(fol) self.subCtrlGrp[-1].setTranslation([0,0,0], space='object') xfm.__xfm__(self.subCtrlGrp[-1]) # bones self.bones2SK.append( bn.create2SK(self.name+'_sub'+str(i+1), self.subCtrl[-1]) ) # pickwalk arPickwalk.setPickWalk(self.subCtrl, type='UD') # create structure strucJnt = [] self.strucCtrl = {} for i in range(len(self.ctrlName)): strucTmp = [] if i == 1: # ctrl strucTmp.append( shapesBiblio.circleX(name=self.name+'_'+self.ctrlName[i], parent=self.strucGrp, color=self.colorOne) ) clean.__lockHideTransform__(strucTmp[-1], channel=['s']) strucJnt.append( pmc.createNode('joint', name=self.name+'_'+self.ctrlName[i]+'_RIGjnt', parent=strucTmp[-1], skipSelect=True) ) # aim strucTmp.append( pmc.createNode('transform', name=self.name+'_'+self.ctrlName[i]+'_pos', parent=self.strucGrp, skipSelect=True) ) # rot strucTmp.append( pmc.createNode('transform', name=self.name+'_'+self.ctrlName[i]+'_aim', parent=strucTmp[-1], skipSelect=True) ) strucTmp[0].setParent(strucTmp[-1]) # up strucTmp.append( pmc.createNode('transform', name=self.name+'_'+self.ctrlName[i]+'_up', parent=strucTmp[-2], skipSelect=True) ) strucTmp[-1].setTranslation([0,self.length/2.0,0], space='world') else: # ctrl strucTmp.append( shapesBiblio.circleX(name=self.name+'_'+self.ctrlName[i], parent=self.strucGrp, color=self.colorOne) ) clean.lockHideTransform(strucTmp[-1], channel=['rotateOrder']) # aim strucTmp.append( pmc.createNode('transform', name=self.name+'_'+self.ctrlName[i]+'_aim', parent=strucTmp[-1], skipSelect=True) ) strucJnt.append( pmc.createNode('joint', name=self.name+'_'+self.ctrlName[i]+'_RIGjnt', parent=strucTmp[-1], skipSelect=True) ) # scale strucTmp.append( pmc.createNode('transform', name=self.name+'_'+self.ctrlName[i]+'_scl', parent=strucTmp[-1], skipSelect=True) ) strucTmp.append( pmc.createNode('transform', name=self.name+'_'+self.ctrlName[i]+'_locScl', parent=strucTmp[-1], skipSelect=True) ) # local scale connection strucTmp[0].scale >> strucTmp[-1].scale # up strucTmp.append( pmc.createNode('transform', name=self.name+'_'+self.ctrlName[i]+'_up', parent=strucTmp[-4], skipSelect=True) ) strucTmp[-1].setTranslation([0,self.length/2.0,0], space='world') # put info into dico self.strucCtrl[self.ctrlName[i]] = strucTmp # place structure end self.strucCtrl[self.ctrlName[2]][0].setTranslation([self.length,0,0], space='world') # pickwalk arPickwalk.setPickWalk([self.strucCtrl[self.ctrlName[0]][0], self.strucCtrl[self.ctrlName[1]][0], self.strucCtrl[self.ctrlName[2]][0]], type='UD') arPickwalk.setPickWalk([self.strucCtrl[self.ctrlName[0]][0], self.subCtrl[0]], type='LR') arPickwalk.setPickWalk([self.strucCtrl[self.ctrlName[2]][0], self.subCtrl[-1]], type='LR') # create constrain group self.strucCtrlGrp = [] self.strucCtrlGrp.append( xfm.__xfm__(self.strucCtrl[self.ctrlName[0]][0], suffix='_cst_grp', lock=False) ) self.strucCtrlGrp.append( xfm.__xfm__(self.strucCtrl[self.ctrlName[1]][0], suffix='_cst_grp', lock=False) ) self.strucCtrlGrp.append( xfm.__xfm__(self.strucCtrl[self.ctrlName[2]][0], suffix='_cst_grp', lock=False) ) # constrain between structure tmp = [] tmp.append( pmc.pointConstraint(self.strucCtrl[self.ctrlName[0]][0], self.strucCtrl[self.ctrlName[2]][0], self.strucCtrl[self.ctrlName[1]][1], name=self.strucCtrl[self.ctrlName[1]][1]+'_ptCst', maintainOffset=False ) ) tmp.append( pmc.pointConstraint(self.strucCtrl[self.ctrlName[0]][4], self.strucCtrl[self.ctrlName[2]][4], self.strucCtrl[self.ctrlName[1]][3], name=self.strucCtrl[self.ctrlName[1]][3]+'_ptCst', maintainOffset=False ) ) tmp.append( pmc.aimConstraint(self.strucCtrl[self.ctrlName[2]][0], self.strucCtrl[self.ctrlName[0]][1], name=self.strucCtrl[self.ctrlName[0]][1]+'_aimCst', maintainOffset=False, worldUpType='object', worldUpObject=self.strucCtrl[self.ctrlName[0]][4], aimVector=[1,0,0], upVector=[0,1,0]) ) tmp.append( pmc.aimConstraint(self.strucCtrl[self.ctrlName[0]][0], self.strucCtrl[self.ctrlName[2]][1], name=self.strucCtrl[self.ctrlName[2]][1]+'_aimCst', maintainOffset=False, worldUpType='object', worldUpObject=self.strucCtrl[self.ctrlName[2]][4], aimVector=[-1,0,0], upVector=[0,1,0]) ) tmp.append( pmc.aimConstraint(self.strucCtrl[self.ctrlName[2]][0], self.strucCtrl[self.ctrlName[1]][2], name=self.strucCtrl[self.ctrlName[1]][2]+'_aimCst', maintainOffset=False, worldUpType='object', worldUpObject=self.strucCtrl[self.ctrlName[1]][3], aimVector=[1,0,0], upVector=[0,1,0]) ) clean.lockHideTransform(tmp, channelBox=True) # skinning nurbs plane skinNode = pmc.skinCluster( strucJnt[0], strucJnt[1], strucJnt[2], plan, name=plan.name()+'_skn', ignoreSelected=0, maximumInfluences=3, dropoffRate=12.0, normalizeWeights=1) weights = [] weights.extend([1, 0, 0]) weights.extend([1, 0, 0]) weights.extend([0.8, 0.2, 0]) weights.extend([0.8, 0.2, 0]) weights.extend([0.4, 0.6, 0]) weights.extend([0.4, 0.6, 0]) weights.extend([0, 1, 0]) weights.extend([0, 1, 0]) weights.extend([0, 0.6, 0.4]) weights.extend([0, 0.6, 0.4]) weights.extend([0, 0.2, 0.8]) weights.extend([0, 0.2, 0.8]) weights.extend([0, 0, 1]) weights.extend([0, 0, 1]) # set weights skinNode[0].setWeights(plan, [0,1,2], weights, normalize=True) # delete useless bindpose bindPose = strucJnt[0].bindPose.outputs()[0] pmc.delete(bindPose) # inverse scale for bones for i in range(len(self.ctrlName)): multMat = pmc.createNode('multMatrix', name=self.strucCtrl[self.ctrlName[i]][0]+'_invScl_multMat', skipSelect=True) decoMat = pmc.createNode('decomposeMatrix', name=self.strucCtrl[self.ctrlName[i]][0]+'_invScl_decoMat', skipSelect=True) self.strucGrp.inverseMatrix >> multMat.matrixIn[0] self.strucCtrl[self.ctrlName[i]][0].worldMatrix[0] >> multMat.matrixIn[1] multMat.matrixSum >> decoMat.inputMatrix decoMat.outputScale >> strucJnt[i].inverseScale # connect scale from controlors to sub decoMatS = pmc.createNode('decomposeMatrix', name=self.strucCtrl[self.ctrlName[0]][0]+'_decoMat', skipSelect=True) decoMatE = pmc.createNode('decomposeMatrix', name=self.strucCtrl[self.ctrlName[2]][0]+'_decoMat', skipSelect=True) self.strucCtrl[self.ctrlName[0]][3].worldMatrix[0] >> decoMatS.inputMatrix self.strucCtrl[self.ctrlName[2]][3].worldMatrix[0] >> decoMatE.inputMatrix # connect scale to sub control for i in range(1, self.nbItem-1): # create blend to progressively pass from the start to the end scale bld = pmc.createNode('blendColors', name=self.subCtrl[i].name()+str(i)+'_bld') decoMatS.outputScale >> bld.color1 decoMatE.outputScale >> bld.color2 # connect the sub control attribut neg U self.subCtrl[i].negU >> bld.blender # connect into the scale bld.output >> self.subCtrlGrp[i].scale # no point to create a blend node for the first and the last sub control decoMatS.outputScale >> self.subCtrlGrp[0].scale decoMatE.outputScale >> self.subCtrlGrp[-1].scale # hide and lock channels plan.visibility.set(False) clean.__lockHideTransform__(plan, channel=['t', 'r', 's', 'v']) clean.__lockHideTransform__(folGrp, channel=['t', 'r', 's', 'v']) for jnt in strucJnt: jnt.overrideEnabled.set(1) jnt.overrideColor.set(3) jnt.radius.set(0.5) jnt.visibility.set(False) clean.__lockHideTransform__(jnt, channel=['t', 'r', 's', 'v', 'radius']) # unselect pmc.select(clear=True) # return, in order # 0 the main group PyNode # 1 the main structure group this last can receive constrain to place the ribbon PyNode # 2 groups of each structure controls in order (start offset end) PyNode List # 3 structure controls in order (start offset end) PyNode List) # 4 groups wich can receive a scale information in order (start end) PyNode List # 5 position groups which give the default position in order (offset) PyNode # 6 groups of sub controls PyNode List # 7 sub controls PyNode List # 8 2SKjnt PyNode List return [self.grp, self.strucGrp, self.strucCtrlGrp, [self.strucCtrl[self.ctrlName[0]][0], self.strucCtrl[self.ctrlName[1]][0], self.strucCtrl[self.ctrlName[2]][0]], [self.strucCtrl[self.ctrlName[0]][2], self.strucCtrl[self.ctrlName[2]][2]], self.strucCtrl[self.ctrlName[1]][1], self.subCtrlGrp, self.subCtrl, self.bones2SK]