def mirrorSepratedShapes(self,*args): # Select good shape then bad shape, run the script geo = pm.ls(sl=1,fl=1) Lgeo=[] Rgeo=[] if len(geo)==2: for x in geo: oc=pm.objectCenter(x) if oc>0: Lgeo.append(x) elif oc<0: Rgeo.append(x) Lshape=Lgeo.getShape() Rshape=Rgeo.getShape() Lvert=pm.polyEvaluate(Lshape[0], v=True) Rvert=pm.polyEvaluate(Rshape[0], v=True) if not Lvert==Rvert: print 'Vertex count not matching between the two sides' if geo[0]==Lgeo[0]: base=Lgeo[0] target=Rgeo[0] if geo[0]==Rgeo[0]: base=Rgeo[0] target=Lgeo[0] for i in range(0,Lvert): #print('%s.vtx[%d]'%(Lgeo,i)) pos=cmds.xform(('%s.vtx[%d]'%(base,i)), q=True, ws=True, t=True) cmds.xform(('%s.vtx[%d]'%(target,i)), t=((pos[0]*-1),pos[1],pos[2]), ws=True)
def getUVShell(self, geo): shellNumber = pm.polyEvaluate(geo, uvShell=True) shellList = [] for i in range(shellNumber): shellFaces = pm.polyListComponentConversion(pm.polyEvaluate(geo, uvsInShell=i), toFace=True) shellList.append(shellFaces) return shellList
def addObjMorphs(self): morphPath = os.path.join( os.path.split(self.fbxFile)[0], 'blendshapes/') morphFiles = [ f for f in os.listdir(morphPath) if f.endswith('.obj') and 'default' not in f ] meshesVtxCount = {} meshes = pm.ls(type='mesh') for m in meshes: if 'Orig' not in m.name() and 'rg' not in m.name(): meshesVtxCount[m.name()] = pm.polyEvaluate(m, v=1) print meshesVtxCount if morphFiles: self.hasMorphs = 1 bsNode = '' bsCreated = 0 bsEntry = 0 for obj in morphFiles: speakName = obj.split('.')[0] speakName = 'speak_' + speakName pm.importFile(morphPath + obj, namespace='morph') morph = pm.ls('morph:*', type='mesh')[0] morph.rename(speakName) morphVtxCount = pm.polyEvaluate(morph, v=1) for mesh, count in meshesVtxCount.iteritems(): print mesh, count if count == morphVtxCount: rigMesh = [pm.ls(mesh, type='mesh')[0].getParent()] skinCls = pm.listConnections('%s.inMesh' % rigMesh[0].getShape())[0] if not bsCreated: print 'creating blendshape' bsNode = pm.blendShape(rigMesh, name='speak_BS')[0].name() pm.reorderDeformers(skinCls.name(), bsNode, rigMesh[0].name()) pm.blendShape(bsNode, e=1, t=(rigMesh[0].name(), bsEntry, morph.name(), 1)) bsCreated = 1 else: print 'adding blendshape' pm.blendShape(bsNode, e=1, t=(rigMesh[0].name(), bsEntry, morph.name(), 1)) pm.delete(morph) bsEntry += 1 removeNamespace()
def getModelingSurfaceAreaUsingPymel(): surfaceArea = 0 if pm.system.sceneName(): surfaceArea = sum((pm.polyEvaluate(shape, wa=True) for shape in pm.ls(type='mesh', noIntermediate=True))) surfaceArea = int(surfaceArea) return surfaceArea
def isCompatible(_set): try: return pc.polyEvaluate(_set, f=True) ==\ pc.PyNode(_set).forCache.outputs()[0] except Exception as ex: pc.warning(str(ex)) return True
def getPoyCountGroupByContainerUsingPymel2(*args, **kwargs): scenePolyCount = {'Verts':0, 'Edges':0, 'Faces':0, 'UVs':0, 'Tris':0, 'surface area':0, 'hierarchy':{}} Verts = Edges = Faces = UVs = Tris = 0 if pm.system.sceneName(): for shape in pm.ls(type='mesh', noIntermediate=True): instanceCount = len(shape.getAllPaths()) Verts = shape.numVertices() * instanceCount Edges = shape.numEdges() * instanceCount Faces = shape.numFaces() * instanceCount UVs = shape.numUVs() * instanceCount Tris = int(pm.mel.eval('polyEvaluate -triangle {0}'.format(shape.name()))[0]) * instanceCount surfaceArea = pm.polyEvaluate(shape, wa=True) scenePolyCount['Verts'] += Verts scenePolyCount['Edges'] += Edges scenePolyCount['Faces'] += Faces scenePolyCount['UVs'] += UVs scenePolyCount['Tris'] += Tris scenePolyCount['surface area'] += int(surfaceArea) container = pm.container(shape, query=True, findContainer=shape.name()) if container is not None: containerStack = getContainerStackUsingPymel(container) _buildHierarchy(scenePolyCount, containerStack, **{'container':container.name(), 'Verts':Verts, 'Edges':Edges, 'Faces':Faces, 'UVs':UVs, 'Tris':Tris, 'surface area': int(surfaceArea)}) return scenePolyCount
def createEmitter(self, mesh, name="particleEmitter_msh"): # Create boundingBox of the mesh bbx = pm.polyEvaluate(mesh, b=True) cube = pm.polyCube( w=abs(bbx[0][1] - bbx[0][0]), h=abs(bbx[1][1] - bbx[1][0]), d=abs(bbx[2][1] - bbx[2][0]), sx=1, sy=1, sz=1, ax=(0, 1, 0), cuv=4, ch=0, name=name, ) cube = cube[0] cube.setAttr("t", ((bbx[0][1] + bbx[0][0]) / 2, (bbx[1][1] + bbx[1][0]) / 2, (bbx[2][1] + bbx[2][0]) / 2)) # Keep only face 1 for emit pm.delete([cube + ".f[2:6]", cube + ".f[0]"]) # Connection of mesh and the emitter self.connectOriginaleMesh(mesh, cube) # Move emitter in y in a percentage of area of face. face = pm.PyNode(cube + ".f[1]") area = face.getArea(space="world") pm.select(cube) y = pow(area, 0.1) * 100 pm.move(0, y, 0, r=1, os=1, wd=1) return cube
def __areaSkin(self,*args): geo = pm.ls(sl = 1)[0] skinCluster = mel.eval('findRelatedSkinCluster ' + geo) vertex = pm.polyEvaluate(geo,v = 1) joints = pm.skinCluster(skinCluster,q = 1,inf = 1) skinList = {} for num in range(0,vertex): vertex = geo + '.vtx[' + str(num) + ']' vertPos = pm.xform(vertex,q = 1,t = 1,ws = 1) tempDict = {} for joint in joints: jntPos = pm.xform(joint,q = 1,t = 1,ws = 1) dist = math.sqrt(pow(vertPos[0] - jntPos[0],2) + pow(vertPos[1] - jntPos[1],2) + pow(vertPos[2] - jntPos[2],2)) tempDict.setdefault(joint,dist) minDistVal = min(distVal for distVal in tempDict.values()) for joint in tempDict.keys(): if minDistVal == tempDict[joint]: if joint not in skinList: skinList[joint] = [] skinList[joint].append(vertex) for item in skinList.items(): joint = item[0] vertex = item[1] for vert in vertex: pm.skinPercent(skinCluster,vert,transformValue = (joint,1))
def _check_indiv_vertexPos(self,chkNode=None): u""" >>Start Pipeline Check: check the object's vertex position 检查mesh 的 cv 点是否归0 注意:如果当前有选择物体,将仅作用于选择的物体 """ msgAttr = '_iffyMsg_dags' chk_trns = self.get_chk_nodes(chkNode) for trnsNode in chk_trns: vtx = pm.polyEvaluate(trnsNode, v=True) for n in range(vtx): vtx_nm = "{}.vtx[{}]".format(trnsNode.name(), n) pnt_nm = "{}.pnts[{}]".format(trnsNode.name(), n) pntx_nm = "{}.pntx".format(pnt_nm) pnty_nm = "{}.pnty".format(pnt_nm) pntz_nm = "{}.pntz".format(pnt_nm) pntx_v = pm.getAttr(pntx_nm) pnty_v = pm.getAttr(pnty_nm) pntz_v = pm.getAttr(pntz_nm) if pntx_v or pnty_v or pntz_v: self.iffyVtxs[vtx_nm] = [pntx_v, pnty_v, pntz_v] if self.iffyVtxs: self.update_msgs(msgAttr,">>IFFY--Vertex Position not 0",self.iffyVtxs) return self.iffyVtxs else: om.MGlobal.displayInfo(u">>>mesh的vtx的位移值已经为0 ")
def get_empty_mesh(): """Collect empty mesh in current scene. :rtype: list of pm.nt.Mesh """ all_mesh = pm.ls(type='mesh', editable=True) return [o for o in all_mesh if not pm.polyEvaluate(o, face=True)]
def createEmitter(self, mesh, name="particleEmitter_msh"): #Create boundingBox of the mesh bbx = pm.polyEvaluate(mesh, b=True) cube = pm.polyCube(w=abs(bbx[0][1] - bbx[0][0]), h=abs(bbx[1][1] - bbx[1][0]), d=abs(bbx[2][1] - bbx[2][0]), sx=1, sy=1, sz=1, ax=(0, 1, 0), cuv=4, ch=0, name=name) cube = cube[0] cube.setAttr("t", ((bbx[0][1] + bbx[0][0]) / 2, (bbx[1][1] + bbx[1][0]) / 2, (bbx[2][1] + bbx[2][0]) / 2)) #Keep only face 1 for emit pm.delete([cube + ".f[2:6]", cube + ".f[0]"]) #Connection of mesh and the emitter self.connectOriginaleMesh(mesh, cube) #Move emitter in y in a percentage of area of face. face = pm.PyNode(cube + ".f[1]") area = face.getArea(space="world") pm.select(cube) y = pow(area, 0.1) * 100 pm.move(0, y, 0, r=1, os=1, wd=1) return cube
def get_bounds(self): self.bounds = pm.polyEvaluate(self.uvs, bc2=True) self.xMin = self.bounds[0][0] self.xMax = self.bounds[0][1] self.yMin = self.bounds[1][0] self.yMax = self.bounds[1][1] return self.bounds
def getBoundingBoxCenterShell(self, *args, **kwargs): """Get the center point of the UV shell's bounding box""" self.grabShell() uvBB = pm.polyEvaluate(boundingBoxComponent2d=True) uvCenter = [((uvBB[0][1] + uvBB[0][0]) / 2), ((uvBB[1][1] + uvBB[1][0]) / 2)] return uvCenter
def bBoxData(obj=None, yZero=False, *args): """Get bounding box data of a mesh object Arguments: obj (dagNode): Mesh object yZero (bool): If True, sets the Y axis value to 0 in world space args: Returns: list: center, radio, bounding box full data """ volCenter = False if not obj: obj = pm.selected()[0] shapes = pm.listRelatives(obj, ad=True, s=True) if shapes: bb = pm.polyEvaluate(shapes, b=True) volCenter = [(axis[0] + axis[1]) / 2 for axis in bb] if yZero: volCenter[1] = bb[1][0] radio = max([bb[0][1] - bb[0][0], bb[2][1] - bb[2][0]]) / 1.7 return volCenter, radio, bb
def CalcOffsets(source, dest, fTolerance=0.0001): numOfVtxs = pm.polyEvaluate(source, v=True) movedVtxs = [] vtxOffs = [] for v in range(numOfVtxs): vtxNum = v sourceTempPosX, sourceTempPosY, sourceTempPosZ = pm.xform( source.vtx[v], q=True, objectSpace=True, t=True) destTempPosX, destTempPosY, destTempPosZ = pm.xform(dest.vtx[v], q=True, objectSpace=True, t=True) if (abs(sourceTempPosX - destTempPosX) < fTolerance and abs(sourceTempPosY - destTempPosY) < fTolerance and abs(sourceTempPosZ - destTempPosZ) < fTolerance): continue else: movedVtxs.append(v) pos = (destTempPosX - sourceTempPosX, destTempPosY - sourceTempPosY, destTempPosZ - sourceTempPosZ) vtxOffs.append(pos) return movedVtxs, vtxOffs
def scale_to_uv_bounding_box(xy=False, xz=True, yz=False): if xy: w_attr = 'scaleX' h_attr = 'scaleY' elif xz: w_attr = 'scaleX' h_attr = 'scaleZ' elif yz: w_attr = 'scaleZ' h_attr = 'scaleY' else: pm.warning('You need to specify which axis to scale in.') return objs = pm.ls(sl=True, transforms=True) for obj in objs: uv_bounds = pm.polyEvaluate(obj, boundingBox2d=True) uv_w = abs(uv_bounds[0][0] - uv_bounds[0][1]) uv_h = abs(uv_bounds[1][0] - uv_bounds[1][1]) ratio = uv_w / uv_h if uv_w < uv_h: # change the width obj_w = obj.attr(h_attr).get() * ratio obj.attr(w_attr).set(obj_w) else: # change the height obj_h = obj.attr(w_attr).get() / ratio obj.attr(h_attr).set(obj_h)
def create_nodes(* args): ''' creates polyMoveUV nodes for currently selected objects ''' objects = pm.ls(selection= True) for obj in objects: num_uvs = pm.polyEvaluate(obj, uvcoord= True) # getting all the uvs obj_uvs = '%s.map[0:%i]' % (obj, num_uvs) # just in case the wrong object type is selected try: my_node = pm.mel.eval("polyMoveUV -constructionHistory 1 \ -random 0 %s" % (obj_uvs))[0] # renaming the node based on the object my_node = pm.rename(my_node, '%s_uvNode' % (obj)) pm.setKeyframe('%s' % (my_node), attribute='translateU', t=['0sec','0.5sec'] ) pm.setKeyframe('%s' % (my_node), attribute='translateV', t=['0sec','0.5sec'] ) pm.setKeyframe('%s' % (my_node), attribute='rotationAngle', t=['0sec','0.5sec'] ) pm.setKeyframe('%s' % (my_node), attribute='pivotU', t=['0sec','0.5sec'] ) pm.setKeyframe('%s' % (my_node), attribute='pivotV', t=['0sec','0.5sec'] ) pm.setKeyframe('%s' % (my_node), attribute='scaleU', t=['0sec','0.5sec'] ) pm.setKeyframe('%s' % (my_node), attribute='scaleV', t=['0sec','0.5sec'] ) pm.setKeyframe('%s' % (my_node), attribute='random', t=['0sec','0.5sec'] ) except: print '# error' list_nodes()
def multi_polyQuad(): args,counter = pm.ls(sl=True),1 w=400 window = pm.window(w=w,h=40) pm.columnLayout() progressMessage=pm.text(l='Running through Objects...',w=w) argName=pm.text(l='',w=w) progressControl = pm.progressBar(isInterruptable=True, beginProgress=True, maxValue=len(args), width=w) window.show() for arg in args: if pm.progressBar(progressControl, query=True, isCancelled=True ) : break progressMessage.setLabel('Cleaning up then Quadding object '+str(counter)+'/'+str(len(args))+':') argName.setLabel(arg) pm.select(arg,r=True) #cleanup mesh mel.eval('polyCleanupArgList 3 { "0","1","0","0","0","0","0","0","0","1e-05","0","1e-05","0","1e-05","0","1","0" };') #quad all polies pm.polyQuad(arg, a=30, kgb=False, ktb=False,khe=False,ws=True,ch=False) #merge all verts pm.polyMergeVertex((arg+'.vtx[0:'+str(pm.polyEvaluate(arg,v=True))+']'), d=.001,am=True,ch=0) pm.polyNormalPerVertex(arg,ufn=True) pm.polySoftEdge(arg,angle=68, ch=0) pm.progressBar(progressControl, edit=True, step=1) counter+=1 pm.progressBar(progressControl, edit=True, endProgress=True) pm.select(args, r=True) pm.selectMode(o=True) window.delete()
def create_background_sphere(name): '''Create a sphere aligned to aiSkyDomeLight shape''' xform, _ = pmc.polySphere(radius=995) shape = xform.getShape() xform.rename('HDR_Reflector') # align sphere to aiSkyDomeLight xform.rotateY.set(71.5) uv_count = pmc.polyEvaluate(shape, uv=True) pmc.polyFlipUV( '{}.map[0:{}]'.format(str(shape), uv_count), flipType=0, local=True ) pmc.delete(xform, ch=True) pmc.makeIdentity(xform, apply=True) # set defaults shape.doubleSided.set(False) shape.castsShadows.set(False) shape.receiveShadows.set(False) shape.opposite.set(True) shape.aiSelfShadows.set(0) shape.aiOpaque.set(0) shape.aiVisibleInDiffuse.set(0) shape.aiVisibleInGlossy.set(0) return xform, shape
def get_vertex_info(sel): baseVerts = [] shape = pm.listRelatives(sel[0], p=True) baseObj = pm.listRelatives(shape, p=True) skC = str(sel[0].listHistory(type='skinCluster')[0]) baseCount = pm.polyEvaluate(baseObj, v=True) vtxInf = pm.skinPercent(skC, v, query=True, ib=0.0000001, t=None) vtxVal = pm.skinPercent(skC, v, query=True, ib=0.0000001, v=True) for vtx in sel: print vtx for v in vtx: print skC vtxNum = v.replace(str(shape) + '.vtx', '') print vtxNum '''Query vertex influence name''' '''Query vertex influence value''' all = (vtxNum, vtxInf, vtxVal) baseVerts.append(all) return baseVerts, baseObj, baseCount
def fill(self, times ): self.transform() selected = pm.ls(sl = 1) pm.select(cl = 1) if len(selected) >= 1: haircap = self.capName.getText() if len(selected) > 1: allNewHairs = [] for n in range(len(selected)-1): hair1 = selected[n] hair2 = selected[n+1] grp = pm.group(empty = True, name = 'HairGrp') selfMatrix = selected[n].getMatrix() hair2Matrix = selected[n+1].getMatrix() grpMatrix = (selfMatrix + hair2Matrix)/2 grpMatrix = grpMatrix.homogenize() grp.setMatrix(grpMatrix) pm.parent([hair1, hair2], grp) newHairs = [] for x in range(times-1): newHair = pm.duplicate(hair1)[0] newHair.setMatrix((selfMatrix*grpMatrix.inverse()).blend((hair2Matrix*grpMatrix.inverse()), weight = (x+1)*(1.0/times))) #set blendshapes connecting new hair with the original hair pm.blendShape( hair1 ,newHair , w = ( 0 , 1-( (x+1)*(1.0/times) ) ) ) #if hairs are the same connect the last one as well if pm.polyEvaluate(hair1, v=1) == pm.polyEvaluate(hair2, v=1): pm.blendShape( hair2 ,newHair , w = ( 0 , (x+1)*(1.0/times) ) ) if pm.objExists(haircap) and self.transferCheckBox.getValue() == 1 : pm.transferAttributes(haircap, newHair, sampleSpace=0,transferUVs=1, transferColors=0, sourceUvSet = 'map1',targetUvSet = 'map1') newHairs.append(newHair) pm.ungroup(grp) allNewHairs.append(newHairs) if self.randSliderT.getValue() or self.randSliderR.getValue() > 0: self.randomize(allNewHairs, transRot = 2) pm.select(allNewHairs) else: hair1 = selected[0] newHairs = [] for x in range(times-1): newHair = pm.duplicate(hair1)[0] selfTrans = newHair.getTranslation() selfRot = newHair.getRotation() newHairs.append(newHair) if self.randSliderT.getValue() or self.randSliderR.getValue() > 0: self.randomize(newHairs, transRot = 2) pm.select(newHairs) else: pm.error( "select something")
def addObjMorphs(self): morphPath = os.path.join(os.path.split(self.fbxFile)[0], 'blendshapes/') morphFiles = [f for f in os.listdir(morphPath) if f.endswith('.obj') and 'default' not in f ] meshesVtxCount = {} meshes = pm.ls(type='mesh') for m in meshes: if 'Orig' not in m.name() and 'rg' not in m.name(): meshesVtxCount[m.name()] = pm.polyEvaluate(m,v=1) print meshesVtxCount if morphFiles: self.hasMorphs = 1 bsNode = '' bsCreated = 0 bsEntry =0 for obj in morphFiles: speakName = obj.split('.')[0] speakName = 'speak_' + speakName pm.importFile(morphPath + obj,namespace= 'morph') morph = pm.ls('morph:*',type='mesh')[0] morph.rename(speakName) morphVtxCount = pm.polyEvaluate(morph,v=1) for mesh, count in meshesVtxCount.iteritems(): print mesh, count if count == morphVtxCount: rigMesh = [pm.ls(mesh,type='mesh')[0].getParent()] skinCls = pm.listConnections('%s.inMesh'%rigMesh[0].getShape())[0] if not bsCreated: print 'creating blendshape' bsNode = pm.blendShape(rigMesh,name='speak_BS')[0].name() pm.reorderDeformers(skinCls.name(),bsNode,rigMesh[0].name()) pm.blendShape(bsNode,e=1,t=(rigMesh[0].name(), bsEntry , morph.name(), 1)) bsCreated = 1 else: print 'adding blendshape' pm.blendShape(bsNode,e=1,t=(rigMesh[0].name(), bsEntry , morph.name(), 1)) pm.delete(morph) bsEntry += 1 removeNamespace()
def shadowMesh(triCount=10000): meshArg = pm.ls(sl=True) meshList = pm.duplicate(meshArg, rr=True) shadowGeo = pm.polyUnite(meshList, ch=False, name='ShadowGeo')[0] pm.delete(meshList) #deleting leftover garbage transform nodes pm.parent(shadowGeo, 'CharaA') newSkinClust = pm.skinCluster( shadowGeo, pm.listRelatives('CharaA', ad=True, type='joint')) #skinning begins pm.select(meshArg) pm.select(shadowGeo, add=True) pm.copySkinWeights( noMirror=True, surfaceAssociation='closestPoint', influenceAssociation='closestJoint') #copying skin weights pm.selectMode(o=True) #shadowmesh starts here pm.select(shadowGeo) mel.eval( 'polyCleanupArgList 3 { "0","1","1","0","0","0","0","0","0","1e-005","0","1e-005","0","1e-005","0","1","0" };' ) #clean up before reduction pm.selectMode(o=True) #reduce polycount to fall under budget pm.polyReduce(shadowGeo, ver=1, trm=2, triangleCount=triCount, sharpness=0, keepBorder=1, keepColorBorder=1, keepFaceGroupBorder=1, keepHardEdge=1, keepCreaseEdge=1, keepBorderWeight=0.5, keepMapBorderWeight=0, keepColorBorderWeight=0, keepFaceGroupBorderWeight=0, keepHardEdgeWeight=0.25, keepCreaseEdgeWeight=0, useVirtualSymmetry=0, symmetryTolerance=0.01, sx=0, sy=1, sz=0, sw=0, preserveTopology=1, keepQuadsWeight=1, vertexMapName="", replaceOriginal=1, cachingReduce=1, constructionHistory=1) pm.select(deselect=True) pm.bakePartialHistory(shadowGeo, prePostDeformers=True, preDeformers=True) pm.select(shadowGeo) print('EKKO shadowMesh successful!\nShadow Mesh specs:') print(pm.polyEvaluate(shadowGeo, fmt=True))
def updateInitialStates(): """ update initialState meshes. The input can be two groups (qlCloth mesh group and initialState mesh group) where meshes are matched by vertex count, or two mesh objects. :return: """ sel = pm.ls(sl=True, type="transform") if len(sel) < 2: pm.warning("Please select two groups/objects.") return False matchDict = {} if not sel[0].getShape() and not sel[1].getShape(): # groups # match initial state mesh by vertex count # skip the mesh when the match is not uniqe initMeshes = sel[0].getChildren() outMeshes = sel[1].getChildren() vCountDict = {} for initMesh in initMeshes: vertCount = pm.polyEvaluate(initMesh, vertex=True) vCountDict[vertCount] = [initMesh] for outMesh in outMeshes: vertCount = pm.polyEvaluate(outMesh, vertex=True) if vCountDict.has_key(vertCount): vCountDict[vertCount].append(outMesh) else: vCountDict[vertCount] = [outMesh] for vCount, match in vCountDict.iteritems(): if len(match) == 2: matchDict[match[0]] = match[1] else: print "No match or more than one match exists for {0}. " \ "Skipped.".format(match[0]) print matchDict elif sel[0].getShape() and sel[1].getShape(): # meshes matchDict[sel[0]] = sel[1] else: pm.warning("Please select two groups/objects.") return False for initM, outM in matchDict.iteritems(): pm.select(initM,r=True) pm.select(outM,add=True) pm.mel.qlUpdateInitialPose()
def blendshape_get_weight(self, mesh_shape, blendshape): mesh_shape = pm.PyNode(mesh_shape) blendshape = pm.PyNode(blendshape) vertex_no = pm.polyEvaluate(mesh_shape, vertex = True) # bsn_base_weight = list(blendshape.inputTarget[0].baseWeights.get()) bsn_base_weight = mc.getAttr('{0}.inputTarget[0].baseWeights[0:{1}]'.format(blendshape, vertex_no)) # bsn_iTarget_weight = list(blendshape.inputTarget[0].inputTargetGroup[0].targetWeights.get()) bsn_iTarget_weight = mc.getAttr('{0}.inputTarget[0].inputTargetGroup[0].targetWeights[0:{1}]'.format(blendshape, vertex_no)) return(bsn_base_weight, bsn_iTarget_weight, vertex_no)
def transfer(self): haircap = self.capName.getText() oldSel = pm.ls(sl = 1) pm.select(pm.ls(o=1, sl=1)) selected = pm.ls(sl = 1) pm.select(cl = 1) myCurrentUvSet = pm.polyUVSet(selected[0], q = True , currentUVSet = True )[0] if pm.objExists(haircap) and self.transferCheckBox.getValue() == 1: for object in selected: pm.transferAttributes(haircap, object, sampleSpace=0,transferUVs=1, transferColors=0, sourceUvSet = 'map1',targetUvSet = 'map1') elif len(selected) > 1 and self.transferCheckBox.getValue() == 0: last = selected.pop(-1) for object in selected: if pm.polyEvaluate(object, v = 1) == pm.polyEvaluate(last, v = 1): pm.select([last, object]) pm.transferAttributes(sampleSpace=5,transferUVs=1, transferColors=0,sourceUvSet = myCurrentUvSet, targetUvSet = myCurrentUvSet ) else: pm.error( "assign hair cap geo, or select more than one object with same topology") pm.select(oldSel)
def Get_UVBB(obj, uv): uvbb = pc.polyEvaluate(obj, boundingBox2d=True) if uv == "+U": return uvbb[0][1] elif uv == "-U": return uvbb[0][0] elif uv == "+V": return uvbb[1][1] elif uv == "-V": return uvbb[1][0]
def vSphereinfo(mesh, vertSphere): ''' Return the distance, radius that the user set from the sphere and world position. ''' wPosition = pm.xform(vertSphere, q = True, rp = True, ws = True) bb = pm.polyEvaluate(vertSphere, b = True) dist = (bb[1][1] - bb[1][0]) /2 return [dist, wPosition]
def get_sel(): if pymel.polyEvaluate(sel[0], v=True) == 2076: head = sel[0] body = sel[1] else: head = sel[1] body = sel[0] return head, body
def selectRandomFaces(obj, amount=100): import pymel.core as pm import random obj = pm.ls(obj)[0] numberOfFaces = pm.polyEvaluate(pm.selected()[0], face=1) pm.select(clear=1) for i in range(amount): randFace = random.randint(0, numberOfFaces) print randFace pm.select('%s.f[%s]' % (obj, randFace), add=1)
def blendshape_set_weight(self, mesh_shape, blendshape, bsn_base_weight, bsn_iTarget_weight, src_vertex_no): mesh_shape = pm.PyNode(mesh_shape) blendshape = pm.PyNode(blendshape) vertex_no = pm.polyEvaluate(mesh_shape, vertex = True) if src_vertex_no != vertex_no: pm.warning('... Source total vertices and target total vertices not match, you might get unexpected result') if bsn_base_weight: pm.setAttr('{0}.inputTarget[0].baseWeights[0:{1}]'.format(blendshape, vertex_no), *bsn_base_weight, size = len(bsn_base_weight)) if bsn_iTarget_weight: pm.setAttr('{0}.inputTarget[0].inputTargetGroup[0].targetWeights[0:{1}]'.format(blendshape, vertex_no, *bsn_iTarget_weight, size = len(bsn_iTarget_weight)))
def cbsTrans(*args, **kwargs): sculptTrans = kwargs.setdefault('sculptTrans', pm.ls(sl=True)[0])# (string) The mesh to get the tweak edits extracted from shape = kwargs.setdefault('shape') # (string) The shape node of the sculptTrans node tweak = kwargs.setdefault('tweak') # (string) The tweak node that is going to be cleared skin = kwargs.setdefault('skin') # (string) The skinCluster node that drives the base mesh base = kwargs.setdefault('base') # (string) The base mesh for the character #get some info sculptTrans, shape, tweak, skin = gatherInfo(sculptTrans, shape, tweak, skin) if not 'baseTransform' in pm.listAttr(sculptTrans, ud=True): pm.error('This model has not been prepared for sculpting. If you accidentally started, simply run Clear Tweaks to extract what has been done') if not base: base = sculptTrans.baseTransform.get() baseRef = sculptTrans.baseReference.get() #turn off a couple things that might mess with things pm.symmetricModelling(e=True, symmetry= False) pm.softSelect(e=True, softSelectEnabled=False) #first, let's unlock the guys from the old function pm.lockNode(base, l=False) pm.lockNode(sculptTrans, l=False) pm.setAttr('%s.v'%base, True) #extract from the sculpted shape newShape = clearTweaks(base=base, tweak=tweak) pm.delete(sculptTrans) newOrig = pm.duplicate(base, n='%s_editReference'%base)[0] pm.connectAttr(('%s.outMesh' %newOrig.getShapes()[1]), ('%s.inMesh' %newOrig.getShape())) pm.select(cl=True) deviation = False for v in range(pm.polyEvaluate(base, v=True)): refPos = pm.xform('%s.vtx[%i]'%(baseRef, v), q=True, t=True) adjPos = pm.xform('%s.vtx[%i]'%(newOrig, v), q=True, t=True) if not refPos == adjPos: deviation=True pm.move('%s.vtx[%i]' %(newShape, v), (refPos[0]-adjPos[0], refPos[1]-adjPos[1], refPos[2]-adjPos[2]), r=True) pm.move('%s.vtx[%i]'%(base, v), (refPos[0]-adjPos[0], refPos[1]-adjPos[1], refPos[2]-adjPos[2]), os=True, r=True) pm.select('%s.vtx[%i]' %(base, v), add=True) if deviation: pm.warning('It appears there were issues extracting from the mesh, steps have been taken to try and remedy, but unexpected results may occur') #apply a texture to the new shape. pm.select(newShape, r=True) pm.sets('initialShadingGroup', e=True, forceElement=True) pm.delete(newOrig, baseRef) return newShape
def model_screenshot(selected=True, debug=False, centerCam=False): meshes = pm.ls(sl=True) cam = pm.camera(n='tempCam') hfv=cam[1].getHorizontalFieldOfView() vfv=cam[1].getVerticalFieldOfView() grp = pm.group(em=True, n='tempCamOffset_GRP') #Determine the selection if selected==False: meshes = [mesh.getParent() for mesh in pm.ls(type=pm.nt.Mesh)] print meshes boundingBox = pm.polyEvaluate(meshes, b=True) #Determine the positions of the bounding box as variables xmin=boundingBox[0][0] xmax=boundingBox[0][1] ymin=boundingBox[1][0] ymax=boundingBox[1][1] zmin=boundingBox[2][0] zmax=boundingBox[2][1] #get the midpoints (these are also the object center!) zmid=(zmin+zmax)/2 ymid=(ymin+ymax)/2 xmid=(xmin+xmax)/2 # Create locators to visualize the bounding box locators=[] locators.append(pm.spaceLocator(n='xmin',p=[xmin,ymid,zmid])) locators.append(pm.spaceLocator(n='xmax',p=[xmax,ymid,zmid])) locators.append(pm.spaceLocator(n='ymin',p=[xmid,ymin,zmid])) locators.append(pm.spaceLocator(n='ymax',p=[xmid,ymax,zmid])) locators.append(pm.spaceLocator(n='zmin',p=[xmid,ymid,zmin])) locators.append(pm.spaceLocator(n='zmax',p=[xmid,ymid,zmax])) #Determine the furthest distance needed from the object h_dist=(math.tan(hfv)*abs(xmin-xmax)) + abs(zmin-zmax) zh_dist=(math.tan(vfv)*abs(zmin-zmax)) + abs(zmin-zmax) zv_dist=(math.tan(vfv)*abs(zmin-zmax)) + abs(zmin-zmax) v_dist=(math.tan(vfv)*abs(ymin-ymax)) + abs(zmin-zmax) #this will never be used, always going to be shortest. #set the camera distance etc for the bounding box. print h_dist,v_dist,zh_dist, zv_dist print max(h_dist,v_dist,zh_dist, zv_dist) cam[0].translateZ.set(max(h_dist,zh_dist,v_dist,zv_dist)) cam[0].translateY.set(ymid) cam[0].setParent(grp) if debug: pm.delete(locators) if centerCam: grp.translate.set([zmid,0,xmid]) pm.setKeyframe(grp.rotateY, t=pm.playbackOptions(q=True,ast=True), v=0) pm.setKeyframe(grp.rotateY, t=pm.playbackOptions(q=True,aet=True), v=360)
def main(): lowAngle = 30 highAngle = 150 sels = pm.selected() for sel in sels: selEdge = pm.polyEvaluate(e=True) edge = selEdge - 1 pm.select(sel + '.e[0:' + str(edge) + ']', add=True) pm.polySelectConstraint(a=1, m=3, t=0x8000, ab=(lowAngle, highAngle)) pm.polySelectConstraint(m=0)
def _get_bounds(sel): if sel > 1 and isinstance(sel[0], pm.Component): transform = sel[0].node().getTransform() t = pm.polyEvaluate(bc=True) bb = pm.dt.BoundingBox(pm.dt.Point(t[0][0], t[1][0], t[2][0]), pm.dt.Point(t[0][1], t[1][1], t[2][1])) verts = [i.getPosition() for i in pm.ls(pm.polyListComponentConversion(sel, tv=True), fl=True)] center = sum(verts) / len(verts) else: transform = sel[0] bb = sel[0].getBoundingBox() center = pm.objectCenter(sel[0]) return bb, center, transform
def importSkin(filePath=None, *args): if not filePath: startDir = pm.workspace(q=True, rootDirectory=True) filePath = pm.fileDialog2(dialogStyle=2, fileMode=1, startingDirectory=startDir, fileFilter='mGear Skin (*%s)' % FILE_EXT) if not filePath: return if not isinstance(filePath, basestring): filePath = filePath[0] # Read in the file fh = open(filePath, 'rb') dataPack = pickle.load(fh) fh.close() for data in dataPack["objDDic"]: try: skinCluster = False objName = data["objName"] objNode = pm.PyNode(objName) meshVertices = pm.polyEvaluate(objNode, vertex=True) importedVertices = len(data['blendWeights']) if meshVertices != importedVertices: pm.displayWarning('Vertex counts do not match. %d != %d' % (meshVertices, importedVertices)) continue if getSkinCluster(objNode): skinCluster = getSkinCluster(objNode) else: try: joints = data['weights'].keys() skinCluster = pm.skinCluster(joints, objNode, tsb=True, nw=2, n=data['skinClsName']) except: notFound = data['weights'].keys() sceneJoints = set([pm.PyNode(x).name() for x in pm.ls(type='joint')]) for j in notFound: if j in sceneJoints: notFound.remove(j) pm.displayWarning("Object: " + objName + " Skiped. Can't found corresponding deformer for the following joints: " + str(notFound)) continue if skinCluster: setData(skinCluster, data) print 'Imported skin for: %s' % objName except: pm.displayWarning("Object: " + objName + " Skiped. Can NOT be found in the scene" )
def __init__(self, geoList=pm.ls(sl=True), mapRes=1024, texelDensity=16, autoSeamAngle=0, autoProject=True, autoSeam=True, autoCutUV=True): """ :param geoList: :param mapRes: :param texelDensity: :param autoSeamAngle: :param autoProject: :param autoSeam: :param autoCutUV: """ area = 0 for geo in geoList: print 'Current Geo: ', geo.name() # fi non Manifold UV self.fixNonManifoldUV(geo) # Automatic Projection UV if autoProject: pm.polyAutoProjection(geo.f[:], lm=0, pb=0, ibd=1, cm=0, l=0, sc=0, o=0, p=6, ps=0.2, ws=0) # Auto Seam 1 if autoSeam: self.autoSeamUV(geo, autoSeamAngle) # Unfold3D Optimize self.unfoldOptimizeUV(geo) # set Texel Density self.setTexelDensity(geo, texelDensity, mapRes) # Layout self.uvLayoutFast(geo) # check UV boundaries if autoCutUV: self.recursiveCutUV(geo) # delete history pm.delete(geo, ch=1) area = area + pm.polyEvaluate(geo, uvArea=True) print 'Total Area: ', area, ' -- RoundUp: ', math.ceil(area) # Layout with TexelDensity self.finalLayoutUV(geoList, area) # pm.select(geoList) print 'Auto UV Complete!'
def deleteVertex(self, joint, newShape, threshold=0.45): verts = [] for x in range(pm.polyEvaluate(newShape, v=1)): v = pm.skinPercent(self.skin, '%s.vtx[%d]' % (newShape, x), transform=joint, q=1) if v > threshold: verts.append('%s.vtx[%d]' % (newShape, x)) pm.select(verts) faces = pm.polyListComponentConversion(verts, fromVertex=True, toFace=True) #pm.select(faces) toDelete = invertSelection(newShape, faces) pm.polyDelFacet(toDelete, ch=False)
def get_target_meshes(baseCount, baseObject): mesh = pm.ls(type='transform') targets = [] for i in mesh: if pm.polyEvaluate(i, v=True) == baseCount: '''Exclude baseObject from targets list''' if i.find(str(baseObject[0])) == -1: targets.append(i) return targets
def copyMinionSkin(skin1, skin2): srcSkin = pm.ls(skin1)[0] destSkin = pm.ls(skin2)[0] srcSkinTransform = pm.listConnections('%s.outputGeometry[0]' % srcSkin)[0] srcSkinInfluence = pm.skinCluster(srcSkin, q=True, influence=True) srcSkinShape = srcSkinTransform.getShape() srcVtx = pm.polyEvaluate(srcSkinTransform, v=1) print srcSkinInfluence destSkinTransform = pm.listConnections('%s.outputGeometry[0]' % destSkin)[0] destSkinInfluence = pm.skinCluster(srcSkin, q=True, influence=True) destSkinShape = destSkinTransform.getShape() destVtx = pm.polyEvaluate(destSkinTransform, v=1) print destSkinInfluence pairs = {} for jnt in srcSkinInfluence: val = jnt.find('Meanie01') if val > 0: tmp = jnt.replace('Meanie01', 'Meanie02') if tmp: pairs[jnt] = tmp pairs['Pelvis'] = 'Spine_Meanie02Pelvis' pairs['Chest'] = 'Spine_Meanie02Chest' pairs['Head'] = 'Neck_Meanie02Head' for jnt in srcSkinInfluence: for i in range(srcVtx): val = pm.skinPercent(srcSkin, srcSkinTransform.name() + '.vtx[' + str(i) + ']', transform=jnt, query=True) if val > 0: pm.skinPercent(destSkin, destSkinTransform.name() + '.vtx[' + str(i) + ']', transformValue=[(pairs[jnt], val)])
def cbsStart(*args, **kwargs): base = kwargs.setdefault('base', pm.ls(sl=True)[0]) # (string) The base model for the character shape = kwargs.setdefault('shape') # (string) The shape node of the base model tweak = kwargs.setdefault('tweak') # (string) The tweak node of the base model that is being skinned skin = kwargs.setdefault('skin') # (string) The skinCluster node that is driving the base model #gather some info base, shape, tweak, skin = gatherInfo(base, shape, tweak, skin) verts = pm.polyEvaluate(base, v=True) #do a quick check to make sure this part hasn't been done before if base.hasAttr('baseTransform'): pm.error('You have already run the "Start" function on this model, so it is already ready to go.' + 'If corrections have already been made, click "Extract Shape to finish the process"') for i in pm.listHistory(base, lv=1): if i.type() == 'polySmoothFace': pm.error('The selected shape is connected to a smooth modifier. This hinders the ability to track edits. %s must be deleted.' % i) #turn off a couple things that might mess with things pm.symmetricModelling(e=True, symmetry= False) pm.softSelect(e=True, softSelectEnabled=False) for i in range(verts): x = pm.getAttr(('%s.vlist[0].vertex[%i].xVertex'%(tweak, i))) y = pm.getAttr(('%s.vlist[0].vertex[%i].yVertex'%(tweak, i))) z = pm.getAttr(('%s.vlist[0].vertex[%i].zVertex'%(tweak, i))) if not (x+y+z) == 0: pm.error('You have used the tweak node. No me gusta. If you really wanna clear it, run clearTweaks and try again. It will save what you have') #ok, let's get started, first instance the original mesh sculptTrans = pm.instance(base, n=('%s_corrective_sculpt'%base))[0] pm.reorderDeformers(skin, tweak, base) pm.setAttr('%s.v'%base, False) #Here, we'll make a duplicate of the base to look back on later if need be (for instance, using sculpt geometry tends to not register on tweak) baseRef = pm.duplicate(base, n='%s_editReference'%base)[0] pm.connectAttr(('%s.outMesh' %baseRef.getShapes()[1]), ('%s.inMesh' %baseRef.getShape())) #We'll also hook up the original so we can get it later pm.addAttr(sculptTrans, ln='baseTransform', at='message') pm.addAttr(sculptTrans, ln='baseReference', at='message') pm.connectAttr('%s.message'%base, '%s.baseTransform'%sculptTrans) pm.connectAttr('%s.message'%baseRef, '%s.baseReference'%sculptTrans) #now to keep things from changing between functions, we'll lock the three nodes involved in the #other script so our pesky little user won't delete or rename anything pm.lockNode(base, l=True) pm.lockNode(sculptTrans, l=True)
def save_weight(self): """ Function to save the skin weight of the selected mesh """ directory_path = self.get_directory() if directory_path is None: return selected_objects = pm.ls(sl=True) for i in selected_objects: vertex = dict() skin_cluster = utilities.find_skin_cluster(i) if skin_cluster is not None: pm.select(i) no_of_vertices = pm.polyEvaluate(v=True) shape_node = i.getShape() g_main_progress_bar = pm.mel.eval('$tmp = $gMainProgressBar') pm.progressBar(g_main_progress_bar, edit=True, beginProgress=True, isInterruptable=True, status='"Getting skin info ...', maxValue=no_of_vertices) for vertex_no in range(0, no_of_vertices): vertex_skin_info = dict() if pm.progressBar(g_main_progress_bar, query=True, isCancelled=True): break vertices_selection = '{}.vtx[{}]'.format( shape_node, str(vertex_no)) joint_list = list() weight_list = list() weight_list = utilities.get_weights_inf_from_vertices( skin_cluster=skin_cluster, vertices=vertices_selection) joint_list = utilities.get_joints_inf_from_vertices( skin_cluster=skin_cluster, vertices=vertices_selection) vertex_skin_info['joint_list'] = joint_list vertex_skin_info['weight_list'] = weight_list vertex[vertices_selection] = vertex_skin_info pm.progressBar(g_main_progress_bar, edit=True, step=1) pm.progressBar(g_main_progress_bar, edit=True, endProgress=True) path = '{}/{}.skindata'.format(directory_path, i.name()) with open(path, mode='w') as f: f.write(json.dumps(vertex, indent=4, separators=(',', ': '))) logging.info('{} skin saved'.format(i.name()))
def faceLocators(): """ Iterates through faces on surface, attaches locators and objects """ aimLoc = pm.spaceLocator(n="aimLoc") # Selects all faces, puts average center coordinates in a list pm.select(nameOfSurface) fc = pm.polyEvaluate(face=True) faceLocCount = 0 for x in range(0, fc): numGen = r.random() bBox = pm.xform(nameOfSurface + '.f[' + str(x) + ']', ws=True, q=True, bb=True) transX = (bBox[0] + bBox[3]) / 2 transY = (bBox[1] + bBox[4]) / 2 transZ = (bBox[2] + bBox[5]) / 2 # Creates locators if (numGen <= num): faceLoc = pm.spaceLocator(n="faceLoc{0}".format(1), p=(transX, transY, transZ)) pm.xform(centerPivots=True) pm.delete( pm.aimConstraint(aimLoc, faceLoc, aimVector=[0, -1, 0], upVector=[0, 1, 0], worldUpVector=[0, 1, 0])) duplicatedObject = pm.instance(selectedObject, lf=True) rotVal = pm.getAttr(faceLoc + '.rotate') pm.setAttr(duplicatedObject[0] + '.translate', transX, transY, transZ) pm.setAttr(duplicatedObject[0] + '.rotate', rotVal[0], rotVal[1], rotVal[2]) if setToNormals is False: pm.setAttr(duplicatedObject[0] + '.rotate', 0, 0, 0) pm.setAttr(faceLoc + '.rotate', 0, 0, 0) pm.parent(faceLoc, duplicatedObject[0], duplicateGroup) faceLocCount += 1 pm.delete(aimLoc) totalFace = round(float(faceLocCount) / fc * 100.0, 2) _logger.debug("Generated " + str(faceLocCount) + " locators at faces for " + str(fc) + " possible surfaces.(" + str(totalFace) + "%) ")
def check(self): nodes = [pm.listRelatives(n, parent=True) for n in pm.ls(type="mesh")] for node in nodes: num_components = pm.polyEvaluate(node, vertex=True, uvcoord=True) if num_components['uvcoord'] < num_components['vertex']: self.selection.append(node) if self.selection: names = ", ".join([str(node) for node in self.selection]) msg = self.fail_msg.format(len(self.selection), names) return False, msg return True, self.pass_msg
def create(quads=True, it=1): name = pm.polyPlatonicSolid(n="geoSphere", st=1) for i in xrange(0, it): pm.polySmooth(name, mth=int(not quads), dv=1) vertices = pm.polyEvaluate(name, v=True) def make_vtxname(index): return str(name[0]) + ".vtx[" + str(index) + "]" for vtxname in (make_vtxname(vert) for vert in xrange(0, vertices)): p = pm.xform(vtxname, q=True, t=True) p = dt.Vector(p).normal() pm.move(p.x, p.y, p.z, vtxname)
def afUnfoldUDIM(): #select UV shells curSelUVs = pm.ls(sl=True) mm.eval("PolySelectConvert 1") UVBbox = pm.polyEvaluate(curSelUVs, bc2 = True) UPos = int(math.floor(UVBbox[0][0])) VPos = int(math.floor(UVBbox[1][0])) #udim = int(VPos*10 + UPos + 1001) mm.eval("RoadkillProOrganic") pm.polyEditUV(u=UPos,v=VPos,r=True) mm.eval("PolySelectConvert 4")
def selectTarget(self, *args): """Called when the select target button is pressed""" self.targetObjs = pm.ls(sl=True, tr=True) if len(self.targetObjs) < 1: self.targetObjsTf.setText('Please select at least one object') return targetsTx = ', '.join([str(x) for x in self.targetObjs]) self.targetObjsTf.setText(targetsTx) self.targetVertNumList = [] targetVerts = 0 for obj in self.targetObjs: targetVertNum = pm.polyEvaluate(obj, v=True) self.targetVertNumList.append(targetVertNum) targetVerts += targetVertNum self.vertIndexList = [v for v in range(targetVerts)]
def _export_individual_weights_(self): vertices = pm.polyEvaluate(self.target, vertex=True) # Itererate through all target deformer for self.target_deformer in self.target_deformers: weightMap = {} # Iterate through shapes. for index, niceName in zip(self.target_deformer.weightIndexList(), self.target_deformer.getTarget()): # Get the weights weight_cmd = '%s.inputTarget[0].inputTargetGroup[%i].targetWeights[0:%d]' % ( self.target_deformer, index, vertices - 1) weights = cmds.getAttr(weight_cmd) # Check if there are any painted weights. if len(list(set(weights))) > 1: weightMap[niceName] = weights # Export out the weights map information if len(weightMap): #Save the xml file libXml.write_xml(self.weight_file, {"WeightMap": weightMap})
def clearTweaks(*args, **kwargs): base = kwargs.setdefault('base', pm.ls(sl=True)[0]) # (string) The mesh to get the tweak edits extracted from tweak = kwargs.setdefault('tweak') # (string) The tweak node that is going to be cleared #gathering info just in case it wasn't provided baseRep, notUsed, tweakRep, notUsed = gatherInfo(base, None, tweak, None) #assigning the variables if needed, finishing the gathering of info if not base: base = baseRep if not tweak: tweak = tweakRep verts= pm.polyEvaluate(base, v=True) #setting up the output shape outputShape = pm.duplicate(base, n='%s_corrective'%base)[0] outputShape.getShape().rename('%sShape'%outputShape) pm.delete(outputShape.getShapes()[1:]) #deleting any other shape nodes for at in 'trs': for vec in 'xyz': pm.setAttr('%s.%s%s'%(outputShape, at, vec), l=False) #moving the output shape over and getting the shape right outputShape.tx.set(outputShape.boundingBoxSizeX.get()) pm.connectAttr(('%s.outMesh' %base.getShapes()[1]), ('%s.inMesh' %outputShape.getShape())) #copying the values in the tweak node to the output shape for i in range(verts): x = pm.getAttr(('%s.vlist[0].vertex[%i].xVertex'%(tweak, i))) y = pm.getAttr(('%s.vlist[0].vertex[%i].yVertex'%(tweak, i))) z = pm.getAttr(('%s.vlist[0].vertex[%i].zVertex'%(tweak, i))) pm.move('%s.vtx[%i]' %(outputShape, i), (x, y, z), r=True) pm.setAttr(('%s.vlist[0].vertex[%i].xVertex'%(tweak, i)), 0) pm.setAttr(('%s.vlist[0].vertex[%i].yVertex'%(tweak, i)), 0) pm.setAttr(('%s.vlist[0].vertex[%i].zVertex'%(tweak, i)), 0) #apply a texture to the new shape. pm.select(outputShape, r=True) pm.sets('initialShadingGroup', e=True, forceElement=True) return outputShape
def pivot(self): oldSel = pm.selected() self.transform() selected = pm.selected() pm.delete(selected, constructionHistory = 1) pm.select(clear = 1) for s in selected: #remove previous transformation data pm.makeIdentity(s, apply = 1) ###get root faces from root edges root = self.root(s) rootFaces = pm.ls(pm.polyListComponentConversion(root, fe =1, tf =1), fl = True) pm.select(cl = 1) #get list of vertices contained in the faces points = [] for face in rootFaces: point = face.getPoints() for p in point: if p not in points: points.append(p) #get average from point list and put it on the surface of the geo faceAvg = s.getClosestPoint(self.vecAvg(points)) #move pivots to face average pm.xform(s, piv = faceAvg[0], ws = 1) #move geo to origin to restore transformations pm.move( 0,0,0, s, rpr=1 ) pos = pm.xform( s, q=1, t=1 ) pm.makeIdentity(s, apply = 1 ) #build matrix out of normal and side vectors faceNormal = self.getFaceNormals(rootFaces) rootVerts = pm.ls(pm.polyListComponentConversion(root, fe =1, tv =1), fl = True) rotVertCoords = [x.getPosition(space = 'object') for x in rootVerts] avgBasePos = self.vecAvg(rotVertCoords) mat = self.matrix_from_normal ( faceNormal, avgBasePos) #rotate to align to scene axis pm.xform(s, matrix = mat.asMatrixInverse()) pm.makeIdentity(s, apply = 1) pm.xform(s, matrix = mat) pm.setAttr( '%s.t' % s, pos[0]*-1,pos[1]*-1,pos[2]*-1) if pm.polyEvaluate(s, f = True)<2: pm.xform( s, piv = ( avgBasePos ), ws = 0 ) pm.select(oldSel)
def CalcOffsets( source , dest, fTolerance = 0.0001): numOfVtxs = pm.polyEvaluate( source , v = True ) movedVtxs = [] vtxOffs = [] for v in range( numOfVtxs ) : vtxNum = v sourceTempPosX , sourceTempPosY , sourceTempPosZ = pm.xform ( source.vtx[v] , q=True, objectSpace=True ,t=True ) destTempPosX , destTempPosY , destTempPosZ = pm.xform ( dest.vtx[v] , q=True, objectSpace=True ,t=True ) if ( abs(sourceTempPosX - destTempPosX) < fTolerance and abs(sourceTempPosY - destTempPosY) < fTolerance and abs(sourceTempPosZ - destTempPosZ) < fTolerance ): continue else : movedVtxs.append ( v ) pos = ( destTempPosX-sourceTempPosX , destTempPosY-sourceTempPosY , destTempPosZ-sourceTempPosZ ) vtxOffs.append ( pos ) return movedVtxs, vtxOffs
def RandomVertex( objs = None, displace = 0.5 ): if objs==None: objs = pm.ls( sl=True ) else: objs = pm.ls( objs ) for obj in objs: shape = obj.getShape() numOfVtxs = pm.polyEvaluate( shape, vertex=True ) for i in range( numOfVtxs ): currentDisp = random.uniform( -displace , displace ) axis = random.randint( 0 , 2 ) if axis == 0: shape.vtx[i].translateBy( (currentDisp,0,0) ) if axis == 1: shape.vtx[i].translateBy( (0,currentDisp,0) ) if axis == 2: shape.vtx[i].translateBy( (0,0,currentDisp) )
def poisson_cleanup(verbose=False): face = pm.ls(sl=True, fl=True)[0] indexComp = face.currentItemIndex() areaComp = round( face.getArea(space='world'), 3) if verbose: print 'First index: %d, area to compare: %f'%(indexComp, areaComp) transform = face.node().getParent() numFaces = pm.polyEvaluate(face.node(), f=True) deleteList=[] for faceIndex in range(0, numFaces): if faceIndex != indexComp: faceUnicode = '{OBJ}.f[{INDEX}]'.format(OBJ=transform, INDEX=faceIndex) if verbose: print faceUnicode faceTgt = pm.MeshFace(faceUnicode) faceTgtArea = round(faceTgt.getArea(space='world'), 3) if faceTgtArea > areaComp: if verbose: print 'Face target index %d has an area of %f, which is bigger than %f...deleting' % (faceIndex, faceTgtArea, areaComp) deleteList.append(faceUnicode) else: if verbose: print 'Face target index %d is fine at %f' % (faceIndex, faceTgtArea) else: if verbose: print 'Repeating target face which is index %d'% faceIndex if verbose: print deleteList pm.delete(deleteList)
def aw_deleteHalf(): '''Takes the current selection and deletes the negative X faces Args: none Returns: (pm.PyNode) ''' #Get current selection curSel=pm.ls(sl=1)[0] #Create list of all faces in object faceIndex=pm.polyEvaluate(curSel,face=1) #Empty list negativeFaces=[] #loop through faces for i in xrange(faceIndex): curFace = curSel + '.f[%d]' % i #If the exactWorldBoundingBox is negative in X append that face to the empty list if pm.exactWorldBoundingBox (curSel + ".f [%d]" %i)[0] < -.0001 : negativeFaces.append(curFace) #Delete the faces that were put into the empty list + history pm.delete(negativeFaces) pm.delete(curSel, ch=1) return curSel
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)
def startSimulation(self): if len(self.surface) == 0: self.printErr("No surface select!") return if len(self.listInstanceOrig) == 0: self.printErr("No instance select!") return pm.currentTime(100) if self.IsFirstStart: self.IsFirstStart = False # Delete the root group if exists if pm.objExists(self.worldParent): pm.delete(self.worldParent) if pm.objExists("forestGenerator_exp"): pm.delete("forestGenerator_exp") # Create root group self.worldParent = pm.group(em=1, w=1, name=self.worldParent) # Duplicate instance pm.select(cl=1) self.listInstance = [] for inst in self.listInstanceOrig: tmp = pm.duplicate(inst, name=inst.name() + "_inst")[0] self.connectOriginaleMesh(inst, tmp) pm.select(tmp, add=True) # Instance radius computation bbx = pm.polyEvaluate(tmp, b=True) ltmp = [abs(bbx[0][1] - bbx[0][0]), abs(bbx[2][1] - bbx[2][0])] self.listInstanceInfo[str(tmp)] = {"meshOriginal": inst, "radius": min(ltmp) / 2} self.listInstance = pm.ls(sl=1) grpInstance = pm.group(n="instance_grp") pm.parent(grpInstance, self.worldParent) pm.select(cl=1) self.meshCollider = self.createCollider(self.surface) if self.ui.surfaceSmooth_cb.isChecked(): pm.polySmooth(self.meshCollider, dv=self.meshCollider.getAttr("displaySmoothMesh"), method=0) pm.parent(self.meshCollider, self.worldParent) self.meshCollider.setAttr("v", 0) self.meshEmitter = self.createEmitter(self.meshCollider) pm.parent(self.meshEmitter, self.worldParent) self.meshEmitter.setAttr("v", 0) self.createParticleEmitter(self.meshEmitter, collider=self.meshCollider) # Init expresionn at Creation self.updateDynExpressionCreation(self.partShape) # Play Interractive playback pm.playbackOptions(aet=20000, max=20000) self.simulate()
def CopySkinPolyToNurbs( source=None , dest=None, searchTolerance=0.005 ): if source==None or dest==None : source, dest = pm.ls(sl=True) # find shapes and skin nodes sourceShape = source.getShape() sourceSkin = FindDeformers( sourceShape , 'skinCluster' ) if not sourceSkin: pm.error("source object doesn't have a skin deformer") sourceSkin = sourceSkin[0] destShape = dest.getShape() destSkin = FindDeformers( destShape , 'skinCluster' ) if not destSkin: pm.error("target object doesn't have a skin deformer") destSkin = destSkin[0] # find joints affection the skin sourceJnts = pm.skinCluster(sourceSkin, q=True, influence=True) destJnts = pm.skinCluster(destSkin, q=True, influence=True) if sourceJnts != destJnts: pm.error("SkinClusters must have the same joint.") Us = destShape.numCVsInU() Vs = destShape.numCVsInV() numVtxs= pm.polyEvaluate( sourceShape, v=True ) # unlock all joint for jnt in destJnts: jnt.liw.set(0) #=============================== pm.select(cl=True) for U in range(Us): for V in range(Vs): pm.select( destShape.cv[U][V], add=True ) pos = destShape.getCV( U, V, space='world' ) # find vertex by position pm.select( source.vtx[0:numVtxs-1]) pm.polySelectConstraint( mode=2, type=1, dist=1, distbound=(0,searchTolerance), distpoint=pos ) vtx = pm.ls(sl=True)[0] pm.polySelectConstraint( dist=0 ) # find wieghts from found vertex wtList = [] rawWts = pm.skinPercent( sourceSkin, vtx, q=True, value=True ) # find joints affection the vertex jntList = [] for i in range(len(rawWts)): if rawWts[i] > 0.0: jntList.append(sourceJnts[i]) wtList.append(rawWts[i]) # set weights to nurbs point opt = [] for j in range(len(jntList)): tmp= [] tmp.append( str(jntList[j]) ) tmp.append( wtList[j] ) opt.append( tmp ) pm.skinPercent( str(destSkin), destShape.cv[U][V] , transformValue=( opt ) )
dst.append(element) else: pm.error('ERROR') print('src', src) print('dst', dst) # Make instances. group = [] for target in dst: # group.append(pm.instance(src)) clone = pm.instance(src) # getPosition works only with vertices if isinstance(target, pm.MeshVertex): move_to = target.getPosition(space='world') if isinstance(target, (pm.MeshFace, pm.MeshEdge)): pm.select(target, replace=True) faceBox = pm.polyEvaluate(boundingBoxComponent=True) centerX = 0.5 * (faceBox[0][0] + faceBox[0][1]) centerY = 0.5 * (faceBox[1][0] + faceBox[1][1]) centerZ = 0.5 * (faceBox[2][0] + faceBox[2][1]) move_to = pm.datatypes.Point(centerX, centerY, centerZ) print(repr(move_to)) pm.move(move_to.x, move_to.y, move_to.z, clone, absolute=True) rotate_to = pm.angleBetween(v1=(0.0, 1.0, 0.0), v2=target.getNormal(), euler=True) pm.rotate(clone, rotate_to) # pm.group(group)