def clustersOnCurve(self): curveCVs = self.rbnWireCrv.cv topClusterTransform = pm.cluster([curveCVs[0], curveCVs[1]], rel=True)[1] topClusterTransform.rename(self.rbnWireCrv.name() + '_cls_01') topClusterTransform.getShape().originX.set(self.start[0]) pivot = curveCVs[0].getPosition(space='world') topClusterTransform.setPivots(pivot) self.rbnCls.append(topClusterTransform) midClusterTransform = pm.cluster(curveCVs[1], rel=True)[1] midClusterTransform.rename(self.rbnWireCrv.name() + '_cls_02') pivot = curveCVs[1].getPosition(space='world') midClusterTransform.setPivots(pivot) self.rbnCls.append(midClusterTransform) botClusterTransform = pm.cluster([curveCVs[1], curveCVs[2]], rel=True)[1] botClusterTransform.rename(self.rbnWireCrv.name() + '_cls_02') botClusterTransform.getShape().originX.set(self.end[0]) pivot = curveCVs[2].getPosition(space='world') botClusterTransform.setPivots(pivot) self.rbnCls.append(botClusterTransform) topCluster = topClusterTransform.listConnections(type='cluster')[0] botCluster = botClusterTransform.listConnections(type='cluster')[0] pm.percent(topCluster, curveCVs[1], v=0.5) pm.percent(botCluster, curveCVs[1], v=0.5) clsGrp = pm.group(self.rbnCls, n=self.rbnWireCrv.name() + '_cls_grp') clsGrp.hide() pm.parent(clsGrp, self.rbnNoTransformGrp)
def getSurfUvAndWeight(c, tol=0.1): """Given a cluster, return a list of tuples for each surface containing the surface weight, the surf, and the average and weighted UV position""" objSet = c.message.outputs(type="objectSet")[0] cpos = pmc.nt.ClosestPointOnSurface() uvs = [] totalWt = sum(pmc.percent(c, objSet, q=True, v=True)) for surf in objSet: shape = surf.node().getTransform() shape.local >> cpos.inputSurface surfWt = sum(pmc.percent(c, surf, q=True, v=True)) if uvs and surfWt < (totalWt * tol): # if surface consists of less than 10% (default) of total # weight, forget about it (as long as UVs isn't empty) continue pos = pmc.dt.Vector() for cv in surf: cvWt = pmc.percent(c, cv, q=True, v=True)[0] ind = cv.indices()[0] cpos.inPosition.set(shape.getCV(*ind)) pos += cpos.position.get() * cvWt avgPos = pos / surfWt cpos.inPosition.set(avgPos) uvs.append((surfWt, shape, cpos.u.get(), cpos.v.get())) pmc.delete(cpos) return sortAndPruneUvs(uvs)
def bdClustersOnCurve(self,curveDrv,segments): clusters = [] curveCVs = curveDrv.cv topClusterTransform= pm.cluster([curveCVs[0],curveCVs[1]],rel=True)[1] topClusterTransform.rename(curveDrv.name() + '_top_CLS') topClusterTransform.getShape().originY.set(segments * 0.5) pivot = curveCVs[0].getPosition(space='world') topClusterTransform.setPivots(pivot) clusters.append(topClusterTransform) midClusterTransform = pm.cluster(curveCVs[1],rel=True)[1] midClusterTransform.rename(curveDrv.name() + '_mid_CLS') pivot = curveCVs[1].getPosition(space='world') midClusterTransform.setPivots(pivot) clusters.append(midClusterTransform) botClusterTransform = pm.cluster([curveCVs[1],curveCVs[2]],rel=True)[1] botClusterTransform.rename(curveDrv.name() + '_bot_CLS') botClusterTransform.getShape().originY.set(segments * - 0.5 ) pivot = curveCVs[2].getPosition(space='world') botClusterTransform.setPivots(pivot) clusters.append(botClusterTransform) topCluster = topClusterTransform.listConnections(type='cluster')[0] botCluster = botClusterTransform.listConnections(type='cluster')[0] pm.percent(topCluster,curveCVs[1],v=0.5) pm.percent(botCluster,curveCVs[1],v=0.5) clsGrp = pm.group(clusters,n=curveDrv.name() + '_CLS_GRP') return clusters,clsGrp
def cluster_curve(self, curve, name): """ adds clusters to 3 cv curve :param curve: curve node to be affected :param name: string for cluster names :return: new clusters """ cl_a = self.make_cluster(target=curve.cv[0:1], name='%s_a_CL' % name, origin=-6, pos_x=-5, pos_z=-5) cl_b = self.make_cluster(target=curve.cv[1:2], name='%s_b_CL' % name, origin=6, pos_x=5, pos_z=-5) cl_mid = self.make_cluster(target=curve.cv[1], name='%s_mid_CL' % name) # redistributes cluster weight pm.percent(cl_a[0], curve.cv[1], v=0.5) pm.percent(cl_b[0], curve.cv[1], v=0.5) return cl_a, cl_b, cl_mid
def createCluster(vertexs, name): mesh = vertexs[0].node() cluster = pm.cluster(mesh, name="{0}_Clu".format(name)) pm.percent(cluster[0], mesh.vtx, v=0) pm.percent(cluster[0], vertexs, v=1) cluster[-1].visibility.set(0) return cluster
def createCluster(vertexs, name): mesh = vertexs[0].node() cluster = pm.cluster(mesh, name = "{0}_Clu".format(name)) pm.percent(cluster[0], mesh.vtx, v=0) pm.percent(cluster[0], vertexs, v=1) cluster[-1].visibility.set(0) return cluster
def build_cluster_crv(self, *args): """ builds a curve with 3 cv's controled by clusters Args: None Returns (None) """ crv_name = self.flexiPlaneNameField.getText() + '_flexiPlane_wire_CRV' surf_bShp_name = self.flexiPlaneNameField.getText() + '_flexiPlane_bShp_SURF' clusterA_name = self.flexiPlaneNameField.getText() + '_flexiPlane_clustA_CL' clusterB_name = self.flexiPlaneNameField.getText() + '_flexiPlane_clustB_CL' clusterC_name = self.flexiPlaneNameField.getText() + '_flexiPlane_clustC_CL' clusterGRP_name = self.flexiPlaneNameField.getText() + '_flexiPlane_CLSTR_GRP' surf_bShpGRP_name = self.flexiPlaneNameField.getText() + '_flexiPlane_bShp_GRP' num_jnts_slider = self.flexiPlaneNumSlider.getValue() cvA_pos = num_jnts_slider * -1 cvC_pos = num_jnts_slider pm.curve( n = crv_name, d = 2, p = [( cvA_pos, 0, 0 ), ( 0, 0, 0 ), ( cvC_pos, 0, -0 )], k = [0, 0, 1, 1] ) pm.select( crv_name +'.cv[0:1]', r = True ) pm.cluster( n = clusterA_name, en = 1, rel = True ) pm.setAttr( clusterA_name + 'Handle.originX', cvA_pos ) pm.move( cvA_pos, 0, 0, clusterA_name + 'Handle.scalePivot', clusterA_name + 'Handle.rotatePivot', ws = True ) pm.select( crv_name +'.cv[1:2]', r = True ) pm.cluster( n = clusterC_name, en = 1, rel = True ) pm.setAttr( clusterC_name + 'Handle.originX', cvC_pos ) pm.move( cvC_pos, 0, 0, clusterC_name + 'Handle.scalePivot', clusterC_name + 'Handle.rotatePivot', ws = True ) pm.select( crv_name +'.cv[1]', r = True ) pm.cluster( n = clusterB_name, en = 1, rel = True ) pm.select( crv_name +'.cv[1]', r = True ) pm.percent( clusterA_name, crv_name +'.cv[1]', v = 0.5 ) pm.percent( clusterC_name, crv_name +'.cv[1]', v = 0.5 ) pm.group( em = True, name = clusterGRP_name ) pm.parent(clusterA_name + 'Handle', clusterGRP_name ) pm.parent(clusterB_name + 'Handle', clusterGRP_name ) pm.parent(clusterC_name + 'Handle', clusterGRP_name ) pm.parent(clusterGRP_name, surf_bShpGRP_name )
def soft_cluster(): ''' Converts a soft selection into a cluster Args: None Returns (pm.nt.Cluster): generated cluster Usage: soft_cluster() ''' selection = pm.ls(sl=True) # Rich selection list includes soft selection richSel = om.MRichSelection() om.MGlobal.getRichSelection(richSel) richSelList = om.MSelectionList() richSel.getSelection(richSelList) # Setup the pointers for the paths path = om.MDagPath() component = om.MObject() cluster = pm.cluster( rel=True ) clusterSet = pm.listConnections( cluster, type="objectSet" )[0] richSelList.getDagPath(1, path) for o_index in range(0, richSelList.length()): object_path = om.MDagPath() richSelList.getDagPath(o_index, object_path) shape = pm.PyNode(object_path.fullPathName()) richSelList.getDagPath(o_index, path, component) # Get the components componentFn = om.MFnSingleIndexedComponent(component) for i in range(0,componentFn.elementCount()): weight = componentFn.weight(i) v = componentFn.element(i) w = weight.influence() #print "The selection weight of vertex %d is %f." % (v, w) vtx = (shape.name()+'.vtx[%d]') % v pm.sets(clusterSet, add=vtx) pm.percent(cluster[0], vtx, v=w) pm.select(cluster) return cluster
def create_soft_cluster(): """Create cluster from current soft selection. Code based on https://gist.github.com/jhoolmans/9195634, modify to use pymel and new Maya api. :return: Cluster transform node. :rtype: pm.PyNode """ # node, index_component, inf_val = general.get_soft_selection() soft_element_data = general.get_soft_selection() selection = [vtx_component for vtx_component, inf_val in soft_element_data] pm.select(selection, r=True) cluster = pm.cluster(relative=True) for vtx_component, inf_val in soft_element_data: pm.percent(cluster[0], vtx_component, v=inf_val) pm.select(cluster[1], r=True) return cluster
def allClustersOnVert(vert, clusters=None): ''' Using the percent query we really quickly get all of the clusters that affect the geo for the given vert. This greatly reduces the number of clusters we have to process for scenes that have multriple pieces of geometry. ''' if clusters is None: clusters = pm.ls(type="cluster") print len(clusters ), " is the length of all the clusters. Should be about 300" result = list() for i, cluster in enumerate(clusters): vals = pm.percent(cluster, vert, v=True, q=True) if vals is not None: result.append(cluster) # print i, ": ", vals return result
def interpolate(self): clust = pm.ls(self.clusterMenu.getValue())[0] vertList = self.vertList if not "Point Number" == self.interpolationAxis.getValue(): edgeLengths = computeEdgeLengths(vertList, self.interpolationAxis.getValue()) minWeight = self.minWeight.getText() maxWeight = self.maxWeight.getText() if not minWeight == "" and not maxWeight == "": val1 = float(minWeight) val2 = float(maxWeight) else: val1 = pm.percent(clust, self.vert1, v=True, q=True)[0] val2 = pm.percent(str(clust), str(self.vert2), v=True, q=True)[0] print "START INTERPOLATING THIS VERT LIST: " + str(vertList) isReversed = self.invert.getValue() == 'invert' if isReversed: temp = val1 val1 = val2 val2 = temp print "Here is the updated one" for i, vert in enumerate(vertList): print "We are working on the " + str(i) + "th vert in the list." if "Point Number" == self.interpolationAxis.getValue(): percent = i / float((len(vertList) - 1)) else: percent = edgeLengths[i] ratio = function(self.functionMenu.getValue(), percent) value = val1 * compliment(ratio) + val2 * ratio oldValue = pm.percent(str(clust), str(vert), v=True, q=True) print "vert " + str(vert) + " is getting the value " + str( value) + ". Old value was: " + str(oldValue) print "we are assigning it to this cluster: " + str(clust) pm.percent(clust, vert, v=value) actualValue = pm.percent(str(clust), str(vert), v=True, q=True)[0] print "actual value recieved: " + str(actualValue) print "FINSIH" print ""
def SkinToClust ( joints=None, sourceGeometry=None, finalGeometry=None ): #============================================================================ # user inputs if sourceGeometry==None or finalGeometry==None or joints==None: geoAndJnts = pm.ls(sl=True) sourceGeometry = geoAndJnts[ len (geoAndJnts) -2 ] finalGeometry = geoAndJnts[ len (geoAndJnts) -1 ] joints = geoAndJnts[:len (geoAndJnts) -2 ] #============================================================================ # find the skinCluster node on given objects skinClust = pm.ls ( pm.listHistory (sourceGeometry ) , type = "skinCluster" )[0] if skinClust == []: pm.error( "Source Object is not skinned." ) #============================================================================ # create a list per selected influence containing # all the vertices and their weights # find shape of sourceShape sourceShape = sourceGeometry.getShape() # find shape of finalShape finalShape = finalGeometry.getShape() # find the number of vertices of sourceGeometry numOfVtxs = pm.polyEvaluate(finalGeometry) ["vertex"] jnt = joints[0] for jnt in joints: # start progress window amount = 0 pm.progressWindow( title= str(jnt), progress=0, status=(" find " + str(jnt) + " weights:"), isInterruptable=True ) # create a dictionary containing all the values #================== tempDic = {} zeroVtxs = [] # create counter for amount for status present if numOfVtxs != 0: counter = 100.0 / numOfVtxs vtx = 1 for vtx in range(numOfVtxs): # get values from skinCluster tempVal = pm.skinPercent ( skinClust , sourceShape.vtx[vtx] ,q =True , value=True , transform = jnt ) # if the value is not 0 then add it to dictionary if not ( tempVal == 0 ): tempDic [vtx] = tempVal # else create a list containing 0 valued vertices else: zeroVtxs.append ( finalGeometry.vtx[vtx] ) # change progress window # pm.progressWindow ( edit=True, progress= int (amount), status=(" find " + str(jnt) + " weights:") ) # change amount for status present amount += counter # end progress window pm.progressWindow(endProgress=1) # create a cluster in the position of the joint #================== currentClustAndHandle = pm.cluster( finalShape , rel=True , n = (str(jnt)+"clust") ) currentClust = pm.ls( currentClustAndHandle[0] )[0] currentClustHandle = pm.ls( currentClustAndHandle[1] )[0] # change membership of cluster #================== # start progress window amount = 0 pm.progressWindow( title= str(jnt), progress=0, status=(" change " + str(jnt) + " membership:"), isInterruptable=True ) # create counter for amount for status present if len(zeroVtxs) != 0: counter = 100.0 / len(zeroVtxs) pm.sets ( currentClust+"Set" , rm = zeroVtxs ) # end progress window pm.progressWindow(endProgress=1) # positioning the clusters #================== # get position from current joint clustPos = pm.xform (jnt , q =True , ws=True , t=True ) # set cluster origin values currentClustHandle.origin.set( clustPos ) # center pivot of cluster pm.xform( currentClustHandle , centerPivots=True) # start progress window #==================== # create a new progress window amount = 0 pm.progressWindow( title= str(jnt), progress=0, status=(" apply " + str(jnt) + " weights:") , isInterruptable=True ) # create counter for amount for status present if len(tempDic) != 0: counter = 100.0 / len(tempDic) # get the values from dictionary we've created and use them as cluster weights #================== for vtx in tempDic: # applying values pm.percent ( currentClust , finalShape.vtx[vtx] , v = tempDic [vtx] ) # change progress window #pm.progressWindow ( edit=True, progress= int (amount), status=(" apply " + str(jnt) + " weights:") ) # change amount for status present amount += counter # end progress window pm.progressWindow(endProgress=1)
import pymel.core as pm jnt = pm.PyNode('Joint2') sel = pm.ls(sl=1)[0] his = pm.listHistory(sel) Skin = pm.ls(his, type='skinCluster')[0] jnts = pm.skinCluster(Skin, q=1, inf=1) vtxCnt = pm.polyEvaluate(sel, v=1) pm.select(cl=1) pm.skinCluster(Skin, siv=jnt, e=1) vtx = pm.ls(sl=1, fl=1) pos = pm.xform(jnt, q=1, ws=1, t=1) cl = pm.cluster(n=jnt + 'CL') cl[1].origin.set(pos) cl[1].rotatePivot.set(pos) cl[1].scalePivot.set(pos) clSet = pm.listConnections(cl[0], t='objectSet') for i in vtx: skinData = pm.skinPercent(Skin, i, q=1, t=jnt, v=1) pm.percent(cl[0], i, v=skinData) print skinData
def mirror_cluster_on_lattice(): # 最後に選択を復元するために保存する selected = pm.selected() # 選択しているノードから clusterHandle をリストアップする target_cluster_handles = pm.ls(selection=True, type=u'clusterHandle') # 選択している transform の shape を確認して clusterHandle なら格納する is_cluster_only = True for transform in pm.ls(selection=True, type=u'transform'): for shape in transform.getShapes(): if pm.nt.ClusterHandle == type(shape): target_cluster_handles.append(shape) else: is_cluster_only = False # 初めに選択していたリストと数が合わなかったら # clusterHandle 以外を選択していたとみなして終了 if is_cluster_only and len(selected) == len(target_cluster_handles): message = u'These are not clusterHandle. ' \ u'Please select the clusterHandle only.' OpenMaya.MGlobal.displayError(message) sys.exit() # clusterHandle を一つも選択していなければ終了 if 0 == len(target_cluster_handles): message = u'Not found clusterHandle from selection list, ' \ u'Please select more clusterHandle before execute.' OpenMaya.MGlobal.displayError(message) sys.exit() # clusterHandle のコネクションを追って cluster をリストアップする target_clusters = pm.listConnections(target_cluster_handles, destination=True, type=u'cluster') # いったん無効化するデフォーマのセットを格納する変数を宣言 deformers = set() # mesh か lattice 以外を対象にしている cluster があれば格納する ignore_deformers = [] for target_cluster in target_clusters: # cluster のデフォーム対象を getGeometry で取得: 名前の配列が返る output_geometries = target_cluster.getGeometry() # type を調べるために一度 PyNode にする output_geometries = [pm.PyNode(g) for g in output_geometries] # フィルタリングする前の数を保存 output_num = len(output_geometries) # デフォーム対象を mesh か lattice だけにする output_geometries = filter(lambda g: pm.nodetypes.Mesh == type(g) or pm.nodetypes.Lattice == type(g), output_geometries) # mesh か lattice 以外にもセットされてる cluster ならスキップする if output_num is not len(output_geometries): ignore_deformers.append(target_cluster) continue # デフォーム対象のヒストリをリストアップする histories = pm.listHistory(output_geometries) # 継承している nodeType を調べて geometryFilter が含まれていたらデフォーマと確定 [deformers.add(d) for d in histories if u'geometryFilter' in pm.nodeType(d, inherited=True)] # mesh か lattice 以外にアタッチしている cluster があれば選択して処理を止める if 0 < len(ignore_deformers): ignore_handles = [d.matrix.listConnections()[0] for d in ignore_deformers] pm.select(ignore_handles) message = u'These are the cluster that are not supported. ' \ u'It must be attached only to the mesh or lattice. => ' \ + ' '.join([c.name() for c in ignore_handles]) OpenMaya.MGlobal.displayError(message) sys.exit() # あとで復元する envelope を保存。デフォーマをキーにしつつ envelope を保存する envelopes = {d: d.getEnvelope() for d in deformers} # デフォーマを無効化し元の形状にする [d.setEnvelope(0) for d in deformers] for target_cluster in target_clusters: # target_cluster のデフォーム対象を格納する members = [] [members.extend(x) for x in pm.listSets(object=target_cluster)] # lattice1.pt[0:9][0:9][0:9] みたいにまとめられてる配列を全部バラバラに扱う members = pm.ls(members, flatten=True) # node をキーにして ポイント を値に格納する member_dict = {} # node の全ポイントの座標を pm.dt.Point 型で格納する all_points_dict = {} for member in members: # ポイントの node 部分を摘出する node = member.node() # すでに node がキーに存在するなら if node in member_dict: # ポイントを格納して次へ進む member_dict[node].append(member) continue # ポイントを list でラッピングして値を初期化 member_dict[node] = [member] # さらに mesh や lattice の全ポイント座標を格納する if pm.nt.Mesh == type(node): all_points_dict[node] = vtx2pointsDict(node.vtx) elif pm.nt.Lattice == type(node): all_points_dict[node] = pt2pointsDict(node.pt) mirror_point_and_weights = {} for node in member_dict.iterkeys(): all_points = all_points_dict[node] if pm.nt.Mesh == type(node): for member in member_dict[node]: # vtx の world 座標を取得する。pm.dt.Point 型で返ってくる p = member.getPosition(space='world') # x を反転して p = pm.dt.Point(p.x * -1, p.y, p.z) # p に一番近いポイントを摘出 v = distanceMin(p, all_points) # member のウェイトをコピーするため、保存している mirror_point_and_weights[v] = pm.percent(target_cluster, member, query=True, value=True)[0] elif pm.nt.Lattice == type(node): # ここでは負荷軽減のため . (ドットシンタックス)無しで、 # 関数を呼び出せるようにキャッシュしている xform = pm.xform point = pm.dt.Point for member in member_dict[node]: # pt の world 座標を取得する。list of double 型で返ってくる p = xform(member, query=True, translation=True, worldSpace=True) # x を反転しつつ pm.dt.Point 型にする p = point(p[0] * -1, p[1], p[2]) # p に一番近いポイントを摘出 v = distanceMin(p, all_points) # member のウェイトをコピーするため、保存している mirror_point_and_weights[v] = pm.percent(target_cluster, member, query=True, value=True)[0] # 反転した点を選択する pm.select(mirror_point_and_weights.keys()) # cluster を作成する new_cluster, new_cluster_handle = pm.cluster() # 新しい cluster に元のアトリビュートの値をセットする new_cluster.attr('relative') \ .set(target_cluster.attr('relative').get()) new_cluster.attr('usePartialResolution') \ .set(target_cluster.attr('usePartialResolution').get()) new_cluster.attr('angleInterpolation') \ .set(target_cluster.attr('angleInterpolation').get()) new_cluster.attr('percentResolution') \ .set(target_cluster.attr('percentResolution').get()) new_cluster.setEnvelope(envelopes[target_cluster]) # 処理が完了した時に選択するリストに新しい clusterHandle も含める selected.append(new_cluster_handle) # envelope を復元 [d.setEnvelope(envelopes[d]) for d in envelopes.iterkeys()] # 初めに選択していたリスト + 新たな clusterHandle リストを選択する pm.select(selected)
def doRig(self): nurbsSurf = pm.nurbsPlane(p=(0, 0, 0), ax=(0, 1, 0), w=self.width, lr=0.1, d=3, u=self.div, v=1, ch=0, n=self.flexName + 'FlexNurbsSrf')[0] nurbsSurf.visibility.set(False) nurbsSurf.translate.set(self.width / 2, 0, 0) spacing = 1.0 / float(self.div) start = spacing / 2.0 grp1 = pm.group(n=self.flexName + 'Folicules_grp', empty=True) grp2 = pm.group(em=True, n=self.flexName + 'ribbonGlobalMove') grp3 = pm.group(em=True, n=self.flexName + 'FlexNoMove') for i in range(int(self.div)): foll = self.createFoll(self.flexName + 'Follicle' + str('%02d' % i), nurbsSurf, start + spacing * i, 0.5) jnt1 = pm.joint(p=(0, 0, 0), n=self.flexName + str('%02d' % i) + '_jnt') pm.move(0, 0, 0, jnt1, ls=True) pm.parent(foll, grp1) nurbsSurfBlend = pm.nurbsPlane(p=(0, 0, 0), ax=(0, 1, 0), w=self.width, lr=0.1, d=3, u=self.div, v=1, ch=0, n=self.flexName + 'FlexBlendNurbsSrf')[0] nurbsSurfBlend.translate.set(self.width / 2, 0, 0) pm.blendShape(nurbsSurfBlend, nurbsSurf, frontOfChain=True, tc=0, w=(0, 1)) crv = pm.curve(d=2, p=[((self.width * -0.5), 0, 0), (0, 0, 0), ((self.width * 0.5), 0, 0)], k=[0, 0, 1, 1], n=self.flexName + 'Crv') crv.translate.set(self.width / 2, 0, 0) cls1 = pm.cluster(crv + '.cv[0]', crv + '.cv[1]', rel=True, n=self.flexName + 'Cls1') pm.move((self.width * -0.5), 0, 0, cls1[1] + '.scalePivot', cls1[1] + '.rotatePivot') cls2 = pm.cluster(crv + '.cv[2]', crv + '.cv[1]', rel=True, n=self.flexName + 'Cls2') pm.move((self.width * 0.5), 0, 0, cls2[1] + '.scalePivot', cls2[1] + '.rotatePivot') cls3 = pm.cluster(crv + '.cv[1]', rel=True, n=self.flexName + 'Cls3') pm.percent(cls1[0], crv + '.cv[1]', v=0.5) pm.percent(cls2[0], crv + '.cv[1]', v=0.5) twist = pm.nonLinear(nurbsSurfBlend, type='twist', n=self.flexName + 'Twist') twist[1].rotate.set(0, 0, 90) wir = pm.wire(nurbsSurfBlend, gw=False, en=1.000000, ce=0.000000, li=0.000000, w=crv, dds=(0, 20)) wireNode = pm.PyNode(wir[0]) baseWire = [x for x in wireNode.connections() if 'BaseWire' in x.name()] cntrl1 = controlTools.cntrlCrv(name=self.flexName + 'aux1', icone='grp') cntrl2 = controlTools.cntrlCrv(name=self.flexName + 'aux2', icone='grp') cntrl3 = controlTools.cntrlCrv(name=self.flexName + 'aux3', icone='grp') pos = pm.pointOnSurface(nurbsSurfBlend, u=0.0, v=0.5) cntrl1.getParent().translate.set(pos) pos = pm.pointOnSurface(nurbsSurfBlend, u=1.0, v=0.5) cntrl2.getParent().translate.set(pos) pos = pm.pointOnSurface(nurbsSurfBlend, u=0.5, v=0.5) cntrl3.getParent().translate.set(pos) cntrl1.addAttr('twist', at='float', dv=0, k=1) cntrl2.addAttr('twist', at='float', dv=0, k=1) pm.pointConstraint(cntrl1, cntrl2, cntrl3.getParent()) cntrl1.translate >> cls1[1].translate cntrl2.translate >> cls2[1].translate cntrl3.translate >> cls3[1].translate cntrl2.twist >> twist[0].startAngle cntrl1.twist >> twist[0].endAngle pm.parent(nurbsSurf, cntrl1.getParent(), cntrl2.getParent(), cntrl3.getParent(), grp2) pm.parent(grp1, nurbsSurfBlend, cls1[1], cls2[1], cls3[1], baseWire, crv, twist[1], grp3) pm.setAttr(grp3 + '.visibility', 0) # pm.group (grp1,grp2,grp3,n=self.flexName+'Flex_grp') # implementar squash/stretch # implementar o connect to limb
def softMod_to_cluster(self): # sels = pm.ls(sl=1) # if sels: for sel in sels : l = pm.spaceLocator() pm.select(sel,tgl=1) pm.mel.eval('align -atl -x Mid -y Mid -z Mid') pm.select(l,r=1) pos_locator = pm.xform(q=1,ws=1,t=1) softMod_handle = sel.translate.connections(p=0,d=1)[0].constraintTranslateX.connections(p=0,d=1)[0] print softMod_handle # get handle shape softMod_handle_shape = pm.PyNode(softMod_handle).getShape() if softMod_handle_shape: print softMod_handle_shape softMod_handle = softMod_handle_shape.getParent() softMods = softMod_handle_shape.softModTransforms.connections(p=0,s=1) if softMods: softMod = softMods[0] if softMod : deform_sets = softMod.message.connections(p=0,s=1) #TODO radius*0.5 self.Radius = softMod.falloffRadius.get() #pvt = softMod.falloffCenter.get() print deform_sets if deform_sets: deform_set = deform_sets[0] geometrys = deform_set.memberWireframeColor.connections(p=0,s=1) print geometrys pm.select(geometrys[0],r=1) pm.polySelectConstraint(m=3,t=1,d=1,db=(0,self.Radius),dp=pos_locator) vtxs = pm.ls(sl=1,fl=1) pm.polySelectConstraint(m=0) # mags = [] pos_0_list = [] pos_1_list = [] pm.move(1,0,0,softMod_handle,r=1,ws=1) for vtx in vtxs: pos = pm.xform(vtx,q=1,ws=1,t=1) pos_0_list.append( pos ) pm.move(-1,0,0,softMod_handle,r=1,ws=1) for vtx in vtxs: pos = pm.xform(vtx,q=1,ws=1,t=1) pos_1_list.append( pos ) for (p0,p1) in zip(pos_0_list,pos_1_list): print 'p0:',p0 print 'p1:',p1 length = self.get_length(p0,p1) print 'length:',length mags.append(length) pm.mel.eval('newCluster \" -envelope 1\"') cluster_handle = pm.ls(sl=1)[0] cluster_shape = pm.ls(sl=1,dag=1,lf=1)[0] # Get cluster self.Cluster = cluster = cluster_shape.clusterTransforms.connections(p=0,d=1)[0] print 'cluster:',cluster cluster.relative.set(1) cluster_shape.originX.set(0) cluster_shape.originY.set(0) cluster_shape.originZ.set(0) pm.select(cluster_handle,r=1) pm.move(pos_locator,r=1) pm.move(cluster_handle.scalePivot,pos_locator) pm.move(cluster_handle.rotatePivot,pos_locator) cluster_handle.tx.set(0) cluster_handle.ty.set(0) cluster_handle.tz.set(0) cluster_shape.originX.set(pos_locator[0]) cluster_shape.originY.set(pos_locator[1]) cluster_shape.originZ.set(pos_locator[2]) pm.move(cluster_handle.scalePivot,pos_locator) pm.move(cluster_handle.rotatePivot,pos_locator) #select $vtxs; #sets -add $deformSet; pm.select(vtxs,r=1) pm.sets(deform_set,add=1) #$posSoftMod=`xform -q -ws -piv $softModHandle`; #move -r -ws 1 0 0 $softModHandle; print 'softMod_handle:',softMod_handle pos_softMod = pm.xform(softMod_handle,q=1,ws=1,piv=1) #pm.move(1,0,0,softMod_handle,r=1,ws=1) print '\na' min = pm.datatypes.min(mags) max = pm.datatypes.max(mags) print 'min:',min print 'max:',max for (vtx,m) in zip(vtxs,mags): try: mag = pm.datatypes.smoothstep(min,max,m) except: mag = 1 #print 'mags[i]:],',mags[i] #mag = 0.1 #print 'mag: ',mag pm.select(vtx,r=1) # set vtx weight pm.percent(cluster,v=mag) pm.select(sel,r=1) pm.select(cluster_handle,add=1) pm.parentConstraint(mo=1,weight=1) sel_parent = sel.getParent() print type(sel_parent) sel_parent = pm.PyNode( sel_parent ).getParent() sel_parent = pm.PyNode( sel_parent ).getParent() sel_parent = pm.PyNode( sel_parent ).getParent() sel_parent = pm.PyNode( sel_parent ).getParent() print 'sel_parent:',sel_parent pm.select(cluster_handle,r=1) pm.select( cluster_handle,sel_parent ) pm.parent() try: pm.delete(softMod_handle) except: pm.error('can not delete softMod handle') pm.delete(l)