def check_non_manifold_geometry(self): self.result_message = '' geometry = pm.ls(geometry=True) transforms = pm.listRelatives(geometry, p=True, path=True) result_objects = [] for it in transforms: nmv = pm.polyInfo(it, nmv=True) nme = pm.polyInfo(it, nme=True) lf = pm.polyInfo(it, lf=True) is_vertex = self.check_null_list(nmv, 'non-manifold vertex') is_edge = self.check_null_list(nme, 'non-manifold edges') is_face = self.check_null_list(lf, 'lamina faces') if (is_vertex or is_edge or is_face) is True: result_objects.append(it) pm.select(result_objects) return self.result_message
def mesh_check(): logger.debug("Mesh Check") all_shapes = pmc.ls(shapes=True) check_results = [] for shape in all_shapes: inv_edges = pmc.polyInfo(shape, ie=True) inv_verts = pmc.polyInfo(shape, iv=True) lamina_faces = pmc.polyInfo(shape, lf=True) nonm_edges = pmc.polyInfo(shape, nme=True) nonm_verts = pmc.polyInfo(shape, nmv=True) error_list = [ shape, inv_edges, inv_verts, lamina_faces, nonm_edges, nonm_verts ] if error_list.count(None) < 5: check_results.append(error_list) return True
def selectNonManifold(*args): geos = pm.ls(type='mesh') for geo in geos: if geo.isIntermediate(): continue obj = geo.listRelatives(p=True, type='transform') p = pm.polyInfo(obj, nme=True, nmv=True) if p: pm.select(p) return 'select'
def noNonManifold(): geos = pm.ls(type='mesh') hasNMfold = False for geo in geos: if geo.isIntermediate(): continue obj = geo.listRelatives(p=True, type='transform') p = pm.polyInfo(obj, nme=True, nmv=True) if p: hasNMfold = True break return hasNMfold
def noLaminaFaces(): geos = pm.ls(type='mesh') hasLamina = False for geo in geos: if geo.isIntermediate(): continue obj = geo.listRelatives(p=True, type='transform') p = pm.polyInfo(obj, lf=True) if p: hasLamina = True break return hasLamina
def place_objects(): cmds.select(mesh_name) number_of_faces = cmds.polyEvaluate(f=True) # we're comparing with up comparisonVector = OpenMaya.MVector(0, 1, 0) if len(tree_list) != 0: increment_age(tree_list) global seeds #print(seeds) for x in range(seeds): place = random.randint(0, number_of_faces) face = pm.MeshFace("{}.f[{}]".format(mesh_name, place)) # check normal of face pm.select(face) polyInfo = pm.polyInfo(fn=True) polyInfoArray = re.findall(r"[\w.-]+", polyInfo[0]) # convert the string to array with regular expression polyInfoX = float(polyInfoArray[2]) polyInfoY = float(polyInfoArray[3]) polyInfoZ = float(polyInfoArray[4]) face_normal = OpenMaya.MVector(polyInfoX, polyInfoY, polyInfoZ) deltaAngle = math.degrees(face_normal.angle(comparisonVector)) # the angle is in degrees so the result is # "if the difference between this normal and 'up' is more then 20 degrees, turn the point off" global angle angle = cmds.intSliderGrp('input_angle', query=True, value=True) if abs(deltaAngle) > angle: continue # Get center of face pt = face.__apimfn__().center(OpenMaya.MSpace.kWorld) centerPoint = pm.datatypes.Point(pt) plant = cmds.textField(plant_name, query=True, text=True) cmds.select(plant) tree_list.append(TreeInfo(cmds.instance(plant))) cmds.move(centerPoint[0], centerPoint[1], centerPoint[2]) tree_list[-1].update_fitness
def find_non_manifold_objects(): """ Print if there are objects with non-manifold geometry in the scene :return: """ print("Finding objects with non-manifold geometry...") geometry_list = pm.ls( geometry=True) # get a list of all geometry nodes in the scene nm_list = [] # check each mesh for non-manifold edges or vertices for mesh in geometry_list: nm_geom = pm.polyInfo(mesh, nme=True, nmv=True) # only keep those that have non-manifold geometry if nm_geom: nm_list.extend(nm_geom) # select the actual geometry # Print Result if nm_list: print("Found: ", nm_list) else: print("No non-manifold edges or vertices in the scene.") pass
def createShape(self, i_isGroup, i_mesh): """create voxels Keyword arguments: i_isGroup: if the result is one object or each voxel seperated i_mesh: the voxel """ distanceLimit = math.sqrt(self._voxelSize*self._voxelSize*3) for p in self._voxelsPosList: r = self._oriMdl.getClosestPointAndNormal((p[0], p[1], p[2])) closestPoint = r[0] + self._oriMdl.getTranslation() # when the cube is far from the surface if distanceLimit < getLength((p[0]-closestPoint[0], p[1]-closestPoint[1], p[2]-closestPoint[2])): continue dp = dotProduct(normalize([p[0]-closestPoint[0], p[1]-closestPoint[1], p[2]-closestPoint[2]]), normalize(r[1])) # doc product > 0 means two vectors angle is from 0~90 if dp < 0: mesh = pm.duplicate(i_mesh, name='Voxel1') pm.move(p[0], p[1], p[2], mesh, ws=True) self._voxelsList.append(mesh) # print "Create Voxel @ "+str(p[0])+","+str(p[1])+","+str(p[2])+" "+str(mesh) voxelGrp = pm.group(self._voxelsList, name='VoxelGrp1') if i_isGroup ==True: if len(self._voxelsList)>1: pm.polyUnite(voxelGrp, name='V1') pm.polyMergeVertex(distance=0.0) pm.delete(pm.polyInfo(laminaFaces=True)) pm.delete(self._oriMdl)
def createCurveFromEdge(name='spline_loca', step=1): sel = pm.selectedNodes() if len(sel) != 1: cmds.error('Trabaje en un objeto y sus edge') edges = pm.filterExpand(sm=32) if len(edges) == 1: cmds.error('Seleccione edges continuos') #Guardo el nombre del objeto nameObj = sel[0].split('|')[1] #Cantidad de edges cant = len(edges) infoVerts = [] fVerts = [] lVerts = [] #Recorro los edge y spliteo para conseguir el principio y final de cada edge for i in range(0, cant, step): infoVerts = pm.polyInfo(edges[i], ev=1) infoVerts = infoVerts[0].split(" ") fVerts.append(infoVerts[8]) lVerts.append(infoVerts[12]) #ordeno y compongo la seleccion de vertices vertexNum = [] [vertexNum.append(x) for x in fVerts + lVerts if x not in vertexNum] #si tiene step diferente a 1, agrego el primero y el ultimo if step != 1: if not fVerts in vertexNum: vertexNum.insert(-1, lVerts) if not lVerts in vertexNum: vertexNum.insert(0, fVerts) vertexSel = [] [vertexSel.append(nameObj + '.vtx[' + str(x) + ']') for x in vertexNum] #saco la posicion de cada vertice xOrig = mc.xform(vertexSel, q=True, ws=True, t=True) #Formateo las posicions de vertices origPts = zip(xOrig[0::3], xOrig[1::3], xOrig[2::3]) #Cuento la cantidad de puntos para la curva vertCount = len(vertexSel) #Creo la curva crv = mc.curve(n=name, p=origPts, degree=2) #Limpio la curva try: mc.rebuildCurve(crv, ch=False, rpo=True, rt=False, end=True, kr=False, kcp=False, kep=True, kt=True, s=vertCount, d=3, tol=0.01) mc.rebuildCurve(crv, ch=True, rpo=True, rt=False, end=True, kr=False, kcp=False, kep=True, kt=False, s=0, d=3, tol=0.01) except: pass return crv
getSel = pm.ls(os=1) vtxGrp = pm.ls(pm.polyListComponentConversion(getSel,fe=1,tv=1),fl=1) vtxNum = len(vtxGrp) vtxPosGrp = [pm.xform(vtx, q=True, ws=True, t=True)for vtx in vtxGrp] tmpPoly = mc.polyCreateFacet(p=[tuple(vec) for vec in vtxPosGrp ])[0] pm.xform(tmpPoly,cp=1) centerPos = mc.xform(tmpPoly, q=True, ws=True, rp=True) distGrp = [((vec[0] - centerPos[0]) ** 2 + (vec[1] - centerPos[1]) ** 2 + (vec[2] - centerPos[2]) ** 2) ** 0.5 for vec in vtxPosGrp] dist = sum(distGrp)/vtxNum circle = pm.circle(s=vtxNum, r=dist, c=(0, 0, 0), d=3, ch=False)[0] pm.xform(circle, ws=True, t=tuple(centerPos)) wu = (vtxPosGrp[0][0] - centerPos[0]),(vtxPosGrp[0][1] - centerPos[1]),(vtxPosGrp[0][2] - centerPos[2]) pm.normalConstraint(tmpPoly,circle,aim=[0,0,1],u=[0,1,0],wu=(0,1,0)) e2vInfos= pm.polyInfo(getSel,ev=1) e2vDict = {} for info in e2vInfos: evList = [ int(i) for i in re.findall('\\d+', info) ] e2vDict.update(dict([(evList[0], evList[1:])])) # average normal vtxGrp = pm.mel.eval("PolySelectConvert 3;") avNmGrp = pm.polyNormalPerVertex(getSel,q=1,xyz=1)
# # # A tool to copy and paste normal data via the polyNormalPerVertex command and exporting that data out # to a text file and pasting it somewhere else. # ############################################################################################################################## import pymel.core as pm import maya.OpenMayaAnim as animAPI import maya.mel as mel pm.ls(sl = True) 175, 350 159 149 340 pm.select(ball.f[159]) pm.select(ball.f[350]) pm.polyInfo(pm.ls(sl = True).f[350], vf = True) pm.polyNormalPerVertex(ball.vtxFace[175][159], q = True, xyz = True) pm.polyNormalPerVertex(ball.vtxFace[175][350], xyz = pm.polyNormalPerVertex(ball.vtxFace[175][159], q = True, xyz = True)) pm.polyNormalPerVertex(ball.vtxFace[175][340], xyz = pm.polyNormalPerVertex(ball.vtxFace[175][159], q = True, xyz = True)) def moriToolUI(mayaFalse = False): windowID = 'moritool'#checking if window already exists if pm.window(windowID, exists = True): pm.deleteUI(windowID) pm.windowPref( 'moritool', remove=True ) pm.window(windowID, title = u'Prism 森ツール') moriToolLayout = pm.columnLayout( 'moriToolLayout', width = 400) vertexFrame = pm.frameLayout(label = u'頂点関連', labelIndent = 5, marginHeight = 5, parent = moriToolLayout, nch = 5)
def run(): # validate that we selected 1 skinned mesh and 1 non-skinned mesh sel = pm.ls(sl=True) if len(sel)!=2: raise Exception("copyWeightsToFurCards: select skin mesh, shift select fur cards. Aborted.") # src_mesh_trans = sel[0] src_mesh_shape = pm.listRelatives(src_mesh_trans, s=True)[0] if type(src_mesh_shape) != pm.nodetypes.Mesh: raise Exception("copyWeightsToFurCards: source object must be a skinned mesh.") # fur_trans = sel[1] fur_shape = pm.listRelatives(fur_trans, s=True)[0] if type(fur_shape) != pm.nodetypes.Mesh: raise Exception("copyWeightsToFurCards: target object must be a mesh.") # src_skincluster = getRelatedSkinCluster(src_mesh_trans) if type(src_skincluster) != pm.nodetypes.SkinCluster: raise Exception("copyWeightsToFurCards: source mesh must have a skinCluster deformer.") # fur_skincluster = getRelatedSkinCluster(fur_trans) if fur_skincluster != None: raise Exception("copyWeightsToFurCards: target mesh must not be skinned.") # bind the fur cards to the same influences as the source mesh src_influences = src_skincluster.getInfluence() pm.select(src_influences, r=True) pm.select(fur_trans, add=True) fur_skincluster = pm.skinCluster(tsb=True) # copy skin weights from source to fur cards pm.copySkinWeights( ss=str(src_skincluster), ds=str(fur_skincluster), noMirror=True, surfaceAssociation = "closestPoint", influenceAssociation = "oneToOne") # split mesh into list of vertex lists (1 per shell) vertex_shells = [] num_faces = pm.polyEvaluate(fur_trans,f=True) faces_checked = set(range(num_faces)) # gMainProgressBar = mel.eval('$tmp = $gMainProgressBar'); pm.progressBar( gMainProgressBar, edit=True, beginProgress=True, isInterruptable=True, status='Gathering vertex shells...', maxValue=num_faces ) # while len(faces_checked)>0: #progress if pm.progressBar(gMainProgressBar, query=True, isCancelled=True ) : return pm.progressBar(gMainProgressBar, edit=True, step=num_faces-len(faces_checked)) face = faces_checked.pop() shell_faces = pm.polySelect( fur_trans, extendToShell=face ) faces_checked = faces_checked.difference(shell_faces) face_vert_info = pm.polyInfo(faceToVertex=True) verts_in_shell = [] #pm.polyInfo returns horrible unicode format that must be parsed for face_verts_str in face_vert_info: verts_str = face_verts_str.split(":")[1] vert_strings = verts_str.split(" ") for v in vert_strings: try: v_id = int(v) verts_in_shell.append(v_id) except: pass vertex_shells.append(verts_in_shell) # now search for closest vertex in each shell... sel_list = OpenMaya.MSelectionList() sel_list.add(str(fur_shape)) nodeDagPath = sel_list.getDagPath(0) mfnMesh = OpenMaya.MFnMesh(nodeDagPath) space = OpenMaya.MSpace.kWorld pm.progressBar(gMainProgressBar, edit=True, step=0, status="Getting vertex positions...") verts = OpenMaya.MPointArray() verts = mfnMesh.getPoints(OpenMaya.MSpace.kWorld) pm.progressBar(gMainProgressBar, edit=True, status="Finding closest vertex per card...") pm.progressBar(gMainProgressBar, edit=True, step=0, maxValue=len(vertex_shells)) closest_vert_per_shell = [] for i,shell in enumerate(vertex_shells): #progress if pm.progressBar(gMainProgressBar, query=True, isCancelled=True ) : return pm.progressBar(gMainProgressBar, edit=True, step=i) closest_dist = None closest_vert = None for vert_id in shell: point = verts[vert_id] closestPoint, faceIdx = mfnMesh.getClosestPoint(point, space) dist = closestPoint.distanceTo(point) if closest_dist==None: closest_dist = dist closest_vert = vert_id elif dist < closest_dist: closest_dist = dist closest_vert = vert_id closest_vert_per_shell.append(closest_vert) pm.progressBar(gMainProgressBar, edit=True, status="Apply weights for each card...") pm.progressBar(gMainProgressBar, edit=True, step=0, maxValue=len(vertex_shells)) # vtx_base = str(fur_trans)+".vtx[" for i,shell in enumerate(vertex_shells): #progress if pm.progressBar(gMainProgressBar, query=True, isCancelled=True ) : return pm.progressBar(gMainProgressBar, edit=True, step=i) #get weight value of closest vertex c = closest_vert_per_shell[i] vtx = vtx_base+str(c)+"]" values = pm.skinPercent(fur_skincluster,vtx,q=1,v=1,ib=0.0001) transforms = pm.skinPercent(fur_skincluster,vtx,q=1,t=None,ib=0.0001) influences = [] for i in range(len(transforms)): influences.append((transforms[i],values[i])) #paste weight values on all other vertices in shell for v in shell: vtx = vtx_base+str(v)+"]" pm.skinPercent(fur_skincluster,vtx,tv=influences) pm.progressBar(gMainProgressBar, edit=True, endProgress=True)
def bNumNumInc(poly_mesh) : all_vertexs = pm.polyInfo(poly_mesh, ve=1) num = len(all_vertexs) b_num = len(boundaryVertexs(all_vertexs))/2 inc = int(num)/int(b_num) return inc