def generate( self, radius = 10, iterations = 1 ): self.radius = radius self.iterations = iterations print( "%s radius %f iterations %i" % ( self.__class__.__name__, self.radius, self.iterations ) ) octahedronRadius = float(self.radius) / util.pow( float(2), float(self.iterations ) ) octahedron = self.mesh( radius = octahedronRadius ) octahedra = [ octahedron ] pm.polySoftEdge( angle = 0 ) octahedronHeight = octahedron[ 1 ].getSideLength() / util.sqrt( 2 ) for i in range( iterations ): mesh = self.__generateMesh( octahedra[ 0 ], octahedronHeight, octahedronRadius, ( i + 1 ) ) octahedronHeight *= 2 octahedronRadius *= 2 octahedra = [ mesh ] pm.xform( mesh[ 0 ], centerPivots = True ) print( "Construction complete" ) return mesh
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 poly_soft_edge(self, target, prefix=True, suffix=False): if suffix: prefix = False if prefix: prefix = 'unlockNorm_' suffix = '' elif suffix: prefix = '' suffix = '_unlockNorm' target_list = target if not isinstance(target_list, list): target_list = [target_list] for target in target_list: target = pm.PyNode(target) target_shape = self.get_visible_shape(target) old_polySoftEdge_list = pm.listHistory(target_shape, type = 'polySoftEdge') pm.polySoftEdge(target, angle = 180, constructionHistory = True) new_polySoftEdge_list = pm.listHistory(target_shape, type = 'polySoftEdge') for polySoftEdge in new_polySoftEdge_list: if polySoftEdge not in old_polySoftEdge_list: polySoftEdge.rename(prefix + target.stripNamespace() + suffix)
def generate(self, radius=10, iterations=1): self.radius = radius self.iterations = iterations print("%s radius %f iterations %i" % (self.__class__.__name__, self.radius, self.iterations)) octahedronRadius = float(self.radius) / util.pow( float(2), float(self.iterations)) octahedron = self.mesh(radius=octahedronRadius) octahedra = [octahedron] pm.polySoftEdge(angle=0) octahedronHeight = octahedron[1].getSideLength() / util.sqrt(2) for i in range(iterations): mesh = self.__generateMesh(octahedra[0], octahedronHeight, octahedronRadius, (i + 1)) octahedronHeight *= 2 octahedronRadius *= 2 octahedra = [mesh] pm.xform(mesh[0], centerPivots=True) print("Construction complete") return mesh
def sphere_generator(source_sphrs, source_verts, gen_bones, settings): spheres = [] for i in range(len(source_sphrs)): sphere = source_sphrs[i] core_vert = source_verts[sphere.vertex] coords = [core_vert.x, core_vert.y, core_vert.z] poly_transform, poly_sphere = pm.polySphere( name="Sphere" + str(i), r=sphere.size * WORLD_SCALE, sx=settings.sphere_resolution, sy=settings.sphere_resolution) poly_transform.translate.set(coords) poly_transform.rotate.set([90, 0, 0]) poly_shape = poly_transform.getShape() if settings.use_palette: sg = "paletteSG" + str(sphere.colour) pm.sets(sg, edit=True, forceElement=poly_transform) pm.polySoftEdge(a=180) if settings.use_rigging: pm.skinCluster(gen_bones[core_vert.bone], poly_shape, tsb=True) spheres.append(poly_shape) return spheres
def prepareWireframe(selected): # List relatives relatives = pc.listRelatives(selected) # We scan if any relative is a group, if so we dig deeper for relative in relatives: if relative.type() == 'transform': prepareWireframe(relative) # We assign values if everything is ok elif relative.type() == 'mesh': # Get all the edges edgesList = [relative.edges[v] for v in range(len(relative.edges))] # Select edges and store them in a set pc.select(edgesList) wireSet = pc.sets(name='wireSet') # Smooth object subdiv = relative.smoothLevel.get() pc.polySmooth( edgesList, dv=subdiv) # # # Smooth normals # edgesList2 = [relative.edges[v] for v in range(len(relative.edges))] # pc.polySoftEdge(edgesList2, a=180) # # Select base edges and harden them pc.select(wireSet) pc.polySoftEdge(a=0)
def fixNormals(target=None): if not target: target = s() for i in range(0, len(target)): s(target[i]) py.polySetToFaceNormal() py.polySoftEdge()
def fixNormals(target=None): if not target: target = s() for i in range(0,len(target)): s(target[i]) py.polySetToFaceNormal() py.polySoftEdge()
def fix_normals(cls): selection = pm.ls(sl=1) pm.polySetToFaceNormal() for item in selection: pm.polyNormal(item, normalMode=2, userNormalMode=0, ch=1) pm.polySoftEdge(item, a=30, ch=1) pm.delete(ch=1) pm.select(selection)
def unlockNormal(): curr = time.time() mesh = pm.ls(sl=1,dag=1,ni=1,type="mesh") if not mesh: return mesh = mesh[0] smooth_list = [] # NOTE OpenMaya 加速遍历过程 # NOTE Benchmark 选择400个面的基础球体 # NOTE OpenMaya elapsed time : 0.010999917984 s # NOTE PyMel elapsed time : 2.47600007057 s # NOTE OpenMaya 方案 sel_list = om.MSelectionList() sel_list.add(mesh.fullPathName()) dagPath = sel_list.getDagPath(0) edge_itr = om.MItMeshEdge(dagPath) vert_itr = om.MItMeshVertex(dagPath) while not edge_itr.isDone(): flag = 0 for i in range(2): vert_idx = edge_itr.vertexId(i) vert_itr.setIndex(vert_idx) for nor_1,nor_2 in combinations(vert_itr.getNormals(),2): if (nor_1 - nor_2).length() < 0.001: flag += 1 break else: continue if flag == 2: edge = "%s.e[%s]" % (dagPath.fullPathName(),edge_itr.index()) smooth_list.append(edge) edge_itr.next() # NOTE PyMel 方案 # for edge in mesh.edges: # flag = 0 # for vtx in edge.connectedVertices(): # for nor_1,nor_2 in combinations(vtx.getNormals(),2): # if (nor_1 - nor_2).length() < 0.001: # flag += 1 # break # else: # continue # if flag == 2: # smooth_list.append(edge) pm.polyNormalPerVertex(mesh,ufn=1) pm.polySoftEdge(smooth_list,a=180,ch=0) # pm.select(smooth_list) print "elapsed time : %s s" % (time.time() - curr)
def fixHardEdges(*args): meshList = pm.ls(type='surfaceShape') if not meshList: return [] # Find Triangles for obj in meshList: pm.polySoftEdge(obj, a=180, ch=0) return 'ok'
def cleanMe(self): cmds.viewFit() object = pm.ls(tr=True)[0:6] for x in object: pm.select(x) pm.polyNormalPerVertex(x, ufn=True) pm.polySoftEdge(x, a=180, ch=1) pm.bakePartialHistory(x, ppt=True) pm.select(cl=True)
def rig_makeBlockGeo(geometry, mpcStyle=False): '''Uses the MPC block geo script to create automaded block geo out of one selected object which is properly constrained. Args: geometry (pm.PyNode): poly mesh to be broken apart mpcStyle (boolean): replaces the suffix based on JNT and GEO Returns (list[pm.PyNode]): List of proxies that were generated Example Usage: rig_makeBlockGeo() ''' #convert the list to a mel list as a string to pass command = 'rig_makeBlockGeo ({{"{MESHES}"}},"");'.format(MESHES=geometry) print command proxies = mel.eval(command) if len(proxies): #Time to sort them and order them + constrain them if not pm.objExists('proxy_GRP'): prx_grp = pm.group(em=True, n='proxy_GRP') else: prx_grp = pm.PyNode('proxy_GRP') if pm.objExists('model_GRP'): prx_grp.setParent('model_GRP') if pm.objExists('globalCon_GRP'): pm.scaleConstraint('globalCon_GRP', prx_grp, mo=True) final={} proxy_grp = geometry.replace('GEO','PROXY_GRP') if not pm.objExists(proxy_grp): proxy_grp=pm.group(em=True,n=proxy_grp) else: proxy_grp=pm.PyNode(proxy_grp) proxy_grp.setParent(prx_grp) for proxy in proxies: if mpcStyle: proxy=pm.PyNode(proxy) pm.polySoftEdge(proxy, a=0, ch=0) jnt = proxy.name().replace('_GEO','') print proxy.name().replace('_GEO','') print proxy.name().replace('GEO','JNT') if pm.objExists(proxy.replace('GEO','JNT')): jnt = proxy.replace('GEO','JNT') pm.parentConstraint(jnt, proxy, mo=True) proxy.setParent(proxy_grp) proxy.rename(geometry+'_'+proxy.replace('GEO','PROXY')) print 'adding joint' final[proxy]=jnt else: proxy=pm.PyNode(proxy) pm.polySoftEdge(proxy, a=0, ch=0) proxy.rename(proxy.replace('GEO','PROXY')) final[proxy]=proxy.replace('_PROXY', '') return final
def uvmp_merge_special(*args, **kwargs): ''' merge with a very close distance ''' sel = pm.ls(sl=True) if sel: pm.polyMergeVertex(sel, distance=0.001) pm.delete(sel, constructionHistory=True) pm.polySoftEdge(sel, a=180) pm.select(sel, replace=True) else: lcUtility.Utility.lc_print('Please select one or more objects', mode='warning')
def findInconsistentFaceNormal(): inconsistentFaceNormals = [] for mesh in pm.ls(type='mesh', noIntermediate=True): duplicatedMesh = pm.duplicate(mesh.name(), rr=True)[0] pm.polySoftEdge(duplicatedMesh, a=180, ch=False) for vert in duplicatedMesh.getShape().vtx: normals = vert.getNormals() if len([n for n in normals[1:] if n != normals[0]]): inconsistentFaceNormals.append((mesh.name(), vert.connectedFaces().name())) break pm.delete(duplicatedMesh) return inconsistentFaceNormals
def line_generator(source_lines, source_verts, gen_bones, settings): lines = [] for i in range(len(source_lines)): line = source_lines[i] vert1 = source_verts[line.vertex1] vert2 = source_verts[line.vertex2] dx = vert2.x - vert1.x dy = vert2.y - vert1.y dz = vert2.z - vert1.z dist = math.sqrt(dx**2 + dy**2 + dz**2) poly_transform, poly_cylinder = pm.polyCylinder( n="Line" + str(i), h=dist, r=settings.line_radius, sa=settings.line_resolution) poly_transform.translate.set( (dx / 2 + vert1.x, dy / 2 + vert1.y, dz / 2 + vert1.z)) phi = math.degrees(math.atan2(dz, -dx)) theta = math.degrees(math.acos(dy / dist)) poly_transform.setRotationOrder('XZY', True) poly_transform.rotate.set([0, phi, theta]) poly_shape = poly_transform.getShape() if settings.use_palette: sg = "paletteSG" + str(line.colour) pm.sets(sg, edit=True, forceElement=poly_transform) pm.polySoftEdge(a=180) if settings.use_rigging: pm.select(d=True) cluster = pm.skinCluster(gen_bones[vert1.bone], gen_bones[vert2.bone], poly_shape, tsb=True) if vert1.bone != vert2.bone: pm.select(poly_shape.vtx[:3]) pm.skinPercent(cluster, transformValue=[(gen_bones[vert1.bone], 1), (gen_bones[vert2.bone], 0)]) pm.select(d=True) pm.select(poly_shape.vtx[3:]) pm.skinPercent(cluster, transformValue=[(gen_bones[vert1.bone], 0), (gen_bones[vert2.bone], 1)]) lines.append(poly_shape) pm.select(d=True) return lines
def generate( self, radius = 10, iterations = 1 ): self.radius = radius self.iterations = iterations print( "%s radius %f iterations %i" % ( self.__class__.__name__, self.radius, self.iterations ) ) tetrahedronRadius = float(self.radius) / util.pow( float(2), float(self.iterations ) ) tetrahedron = self.mesh( radius = tetrahedronRadius ) tetrahedra = [ tetrahedron ] pm.polySoftEdge( angle = 0 ) sideLength = tetrahedron[ 1 ].getSideLength() tetrahedronHeight = util.sqrt(6) / 3 * sideLength positions = [ ] for vertex in tetrahedron[ 0 ].vtx: position = vertex.getPosition() positions.append( dt.FloatVector( position ) ); for i in range( iterations ): mesh = self.__generateMesh( tetrahedra[ 0 ], tetrahedronHeight, tetrahedronRadius, sideLength, positions, ( i + 1 ) ) for j in range( len( positions ) ): positions[ j ] *= 2 tetrahedronHeight = tetrahedronHeight * 2 tetrahedronRadius = tetrahedronRadius * 2 sideLength = sideLength * 2 tetrahedra = [ mesh ] print( "Construction complete" ) return mesh
def generate(self, radius=10, iterations=1): self.radius = radius self.iterations = iterations print("%s radius %f iterations %i" % (self.__class__.__name__, self.radius, self.iterations)) icosahedronRadius = float(self.radius) / util.pow( float(self.scaleRatio), float(self.iterations)) icosahedron = self.mesh(radius=icosahedronRadius) icosahedra = [icosahedron] pm.polySoftEdge(angle=0) positions = [] vertices = icosahedron[0].vtx for vertex in vertices: position = vertex.getPosition() positions.append(dt.FloatVector(position)) for i in range(iterations): for j in range(len(positions)): positions[j] *= self.scaleRatio mesh = self.__generateMesh(icosahedra[0], positions, icosahedronRadius, (i + 1)) icosahedronRadius *= self.scaleRatio icosahedra = [mesh] pm.xform(mesh[0], centerPivots=True) print("Construction complete") return mesh
def generate( self, radius = 10, iterations = 1 ): self.radius = radius self.iterations = iterations print( "%s radius %f iterations %i" % ( self.__class__.__name__, self.radius, self.iterations ) ) icosahedronRadius = float(self.radius) / util.pow( float(self.scaleRatio), float(self.iterations) ) icosahedron = self.mesh( radius = icosahedronRadius ) icosahedra = [ icosahedron ] pm.polySoftEdge( angle = 0 ) positions = [ ] vertices = icosahedron[ 0 ].vtx for vertex in vertices: position = vertex.getPosition() positions.append( dt.FloatVector( position ) ) for i in range( iterations ): for j in range( len( positions ) ): positions[ j ] *= self.scaleRatio mesh = self.__generateMesh( icosahedra[ 0 ], positions, icosahedronRadius, ( i + 1 ) ) icosahedronRadius *= self.scaleRatio icosahedra = [ mesh ] pm.xform( mesh[ 0 ], centerPivots = True ) print( "Construction complete" ) return mesh
def unlockNormal(): curr = time.time() mesh = pm.ls(sl=1, dag=1, ni=1, type="mesh") if not mesh: return mesh = mesh[0] smooth_list = [] # pm.progressWindow() # NOTE OpenMaya 加速遍历过程 sel_list = om.MSelectionList() sel_list.add(mesh.fullPathName()) dagPath = sel_list.getDagPath(0) edge_itr = om.MItMeshEdge(dagPath) vert_itr = om.MItMeshVertex(dagPath) normal_data = {} while not edge_itr.isDone(): for i in range(2): vert_idx = edge_itr.vertexId(i) vert_itr.setIndex(vert_idx) normals = vert_itr.getNormals() edges = vert_itr.getConnectedEdges() for nor, edge in zip(normals, edges): if edge == edge_itr.index(): if i == 0: normal_list = [nor] else: normal_list.append(nor) normal_data[edge_itr.index()] = normal_list break # if length > 0.0001: # edge = "%s.e[%s]" % (dagPath.fullPathName(),edge_itr.index()) # smooth_list.append(edge) edge_itr.next() # print normal_data # NOTE 解锁法线 pm.polyNormalPerVertex(mesh, ufn=1) # NOTE 整体添加硬边 pm.polySoftEdge(mesh, a=0, ch=0) edge_itr = om.MItMeshEdge(dagPath) while not edge_itr.isDone(): flag = 0 for i in range(2): vert_idx = edge_itr.vertexId(i) vert_itr.setIndex(vert_idx) normals = vert_itr.getNormals() edges = vert_itr.getConnectedEdges() for nor, edge in zip(normals, edges): if edge == edge_itr.index(): _nor = normal_data[edge_itr.index()][i] if (nor - _nor).length() < 0.01: flag += 1 break if flag == 2: edge = "%s.e[%s]" % (dagPath.fullPathName(), edge_itr.index()) smooth_list.append(edge) edge_itr.next() # pm.polySoftEdge(smooth_list,a=180,ch=0) pm.select(smooth_list) print "elapsed time : %s s" % (time.time() - curr)
def unlockNormal(): curr = time.time() sel = pm.ls(sl=1, dag=1, ni=1, type="mesh") if not sel: return sel = sel[0] smooth_list = [] # pm.progressWindow() # NOTE OpenMaya 加速遍历过程 sel_list = om.MSelectionList() sel_list.add(sel.fullPathName()) dagPath = sel_list.getDagPath(0) edge_itr = om.MItMeshEdge(dagPath) vert_itr = om.MItMeshVertex(dagPath) exclude_list = [] normal_data = {} while not edge_itr.isDone(): idx = edge_itr.index() normal_list = [] flag = 0 for i in range(2): vert_idx = edge_itr.vertexId(i) vert_itr.setIndex(vert_idx) normals = vert_itr.getNormals() value = sum([round(val, 2) for vec in normals for val in vec]) normal_list.append(value) # NOTE 检查列表元素是否全部相等来判断是否是完全平滑的点 # NOTE http://www.voidcn.com/article/p-oqthigpz-bsh.html if normals[1:] != normals[:-1]: flag += 1 if flag == 2: pass normal_data[idx] = normal_list edge_itr.next() # NOTE 解锁法线 pm.polyNormalPerVertex(sel, ufn=1) # NOTE 整体添加硬边 pm.polySoftEdge(sel, a=0) edge_itr = om.MItMeshEdge(dagPath) vert_itr = om.MItMeshVertex(dagPath) while not edge_itr.isDone(): flag = 0 idx = edge_itr.index() normal_list = normal_data[idx] for i in range(2): vert_idx = edge_itr.vertexId(i) vert_itr.setIndex(vert_idx) normals = vert_itr.getNormals() value = sum([round(val, 2) for vec in normals for val in vec]) if value not in normal_list: flag += 1 if flag == 2: edge = "%s.e[%s]" % (dagPath.fullPathName(), edge_itr.index()) smooth_list.append(edge) edge_itr.next() pm.polySoftEdge(smooth_list, a=180, ch=0) pm.select(smooth_list) print "elapsed time : %s s" % (time.time() - curr)
def exportSkin(meshes=None, path=None): """ Exports the given mesh nodes as a skyrim skin fbx. If no meshes are given the current selected meshes will be used. If no meshes are selected all meshes skinned to the root skeleton will be used. Args: meshes(list): A list of meshes to export. path(str): The destination fbx path. Returns: str: The exported file path. """ path = path or saveFbxDialog('Save Skin Dialog', dir=getSceneCharacterAssetDirectory()) # Get the root skeleton root = getRootJoint() if root is None: raise RootJointException('Export rig failed, could not find a root joint in the scene.') rootSkeleton = [root] + root.listRelatives(ad=True, type='joint') def getSkinnedMeshes(): clusters = set() for joint in rootSkeleton: for cluster in pmc.ls(pmc.listConnections(joint), type='skinCluster'): clusters.add(cluster) return [pmc.skinCluster(cluster, geometry=True, q=True)[0] for cluster in clusters] meshes = meshes or pmc.selected() or getSkinnedMeshes() meshes = getMeshes(meshes) if len(meshes) > 1: raise NotImplementedError('Multiple meshes selected for export. Currently we only support one mesh per skin.') # Check max influences for mesh in meshes: if not _checkMaxInfluences(mesh): raise MaxInfluenceException('Failed to export "%s". Skinning contains more than 4 influences.' % mesh) try: pmc.undoInfo(openChunk=True) # Set vertex colors to white for mesh in meshes: pmc.polyColorPerVertex(mesh, colorRGB=[1, 1, 1], a=1) # To fix certain issues with skinning we need to mess with the normals for mesh in meshes: pmc.bakePartialHistory(mesh, prePostDeformers=True) # Delete Non-deformer history pmc.polyNormalPerVertex(mesh, unFreezeNormal=True) # Unlock the normals pmc.polySoftEdge(mesh, a=180) # Soften the normals pmc.bakePartialHistory(mesh, prePostDeformers=True) # Delete Non-deformer history pmc.polyNormalPerVertex(mesh, freezeNormal=True) # Lock the normals pmc.polySoftEdge(mesh, a=0) # Harden the normals pmc.bakePartialHistory(mesh, prePostDeformers=True) # Delete Non-deformer history # Remove all joint constraints constraints = root.listRelatives(ad=True, type='constraint') if len(constraints) > 0: pmc.delete(constraints) # Disconnect message connections for joint in rootSkeleton: joint.message.disconnect() if not joint.hasAttr(MATCH_ATTR_NAME): continue for input in joint.attr(MATCH_ATTR_NAME).inputs(plugs=True): input.disconnect(joint.attr(MATCH_ATTR_NAME)) exportFbx(rootSkeleton + [mesh.getParent() for mesh in meshes], path=path) finally: pmc.undoInfo(closeChunk=True) pmc.undo() # Export nif ckcmd.importskin(path, os.path.dirname(path))
def unlockNormal(sel, thersold=0.05): smooth_list = set() edit_list = set() # # NOTE 执行一个 mesh 命令 - 更新模型数据 避免获取的法线数据不对 # pm.polyConnectComponents(sel,ch=0) # NOTE OpenMaya 加速遍历过程 sel_list = om.MSelectionList() sel_list.add(sel.fullPathName()) dagPath = sel_list.getDagPath(0) # NOTE 获取 mesh 所有的法线信息 mesh_normal = {} itr = om.MItMeshFaceVertex(dagPath) while not itr.isDone(): face_id = itr.faceId() vert_id = itr.vertexId() normal = itr.getNormal() if not mesh_normal.has_key(vert_id): mesh_normal[vert_id] = {} mesh_normal[vert_id][face_id] = normal itr.next() pm.progressWindow(title='Unlock normal', progress=0.0, status='%s - colleting data...' % dagPath.fullPathName(), isInterruptable=True) mesh = om.MFnMesh(dagPath) face_itr = om.MItMeshPolygon(dagPath) edge_itr = om.MItMeshEdge(dagPath) vert_itr = om.MItMeshVertex(dagPath) while not edge_itr.isDone(): if edge_itr.onBoundary(): edge_itr.next() continue edge_id = edge_itr.index() if pm.progressWindow(query=True, isCancelled=True): pm.progressWindow(endProgress=1) return amount = float(edge_id) / edge_itr.count() * 100 pm.progressWindow(e=1, progress=amount) smooth_flag = 0 for i in range(2): vert_id = edge_itr.vertexId(i) face_list = edge_itr.getConnectedFaces() if len(face_list) != 2: edge = "%s.e[%s]" % (dagPath.fullPathName(), edge_id) print edge msg = u"模型的边存在同时连接三个面\n边序号为 : %s" % edge QtWidgets.QMessageBox.warning( QtWidgets.QApplication.activeWindow(), u"警告", msg) raise EdgeError(msg) face_1, face_2 = face_list normal_1 = mesh_normal[vert_id][face_1] normal_2 = mesh_normal[vert_id][face_2] # NOTE 法线不分叉 说明是 软边边 if normal_1 == normal_2: vert_itr.setIndex(vert_id) vert_avg_normal = om.MVector(0.0, 0.0, 0.0) edge_avg_normal = om.MVector(0.0, 0.0, 0.0) vtx_face_list = vert_itr.getConnectedFaces() for face in vtx_face_list: face_itr.setIndex(face) normal = face_itr.getNormal() if face in face_list: edge_avg_normal += normal vert_avg_normal += normal vert_avg_normal = vert_avg_normal / len(vtx_face_list) edge_avg_normal = edge_avg_normal / 2 vert_avg_1 = (vert_avg_normal - normal_1).length() vert_avg_2 = (vert_avg_normal - normal_2).length() edge_avg_1 = (edge_avg_normal - normal_1).length() edge_avg_2 = (edge_avg_normal - normal_2).length() # NOTE 判断顶点是否近似 average if (vert_avg_1 < thersold and vert_avg_2 < thersold)\ or (edge_avg_1 < thersold and edge_avg_2 < thersold): smooth_flag += 1 # NOTE 特殊调整的且统一的法线 else: edit_list.add(vert_id) else: # NOTE 硬边或特殊调整的法线 edit_list.add(vert_id) break # NOTE smooth_flag 1 为 1个点 smooth # NOTE smooth_flag 2 为 2个点 smooth if smooth_flag >= 1: edge = "%s.e[%s]" % (dagPath.fullPathName(), edge_id) smooth_list.add(edge) edge_itr.next() # NOTE 获取特殊法线要修改的数据 pm.progressWindow(e=1, progress=0.0, status='%s - get edited normal...' % dagPath.fullPathName()) normal_list = [] face_list = [] vtx_list = [] print "edit_list", edit_list for i, vert_id in enumerate(edit_list): if pm.progressWindow(query=True, isCancelled=True): pm.progressWindow(endProgress=1) return amount = float(i) / len(edit_list) * 100 pm.progressWindow(e=1, progress=amount) for face_id, normal in mesh_normal[vert_id].items(): normal_list.append(normal) face_list.append(face_id) vtx_list.append(vert_id) pm.progressWindow(e=1, progress=0.0, status='%s - modify normal...' % dagPath.fullPathName()) # NOTE 解锁法线 pm.polyNormalPerVertex(sel, ufn=1) pm.progressWindow(e=1, progress=10) # NOTE 批量设置法线 mesh.setFaceVertexNormals(normal_list, face_list, vtx_list) pm.progressWindow(e=1, progress=70) if smooth_list: pm.polySoftEdge(smooth_list, a=180, ch=0) pm.progressWindow(endProgress=1)
def unlockNormal(thersold=0.05): curr = time.time() sel = pm.ls(sl=1, dag=1, ni=1, type="mesh") if not sel: return sel = sel[0] smooth_list = [] hard_list = [] smooth_vtx_list = set() edit_list = set() # NOTE OpenMaya 加速遍历过程 sel_list = om.MSelectionList() sel_list.add(sel.fullPathName()) dagPath = sel_list.getDagPath(0) # NOTE 获取 mesh 所有的法线信息 mesh_normal = {} itr = om.MItMeshFaceVertex(dagPath) while not itr.isDone(): face_id = itr.faceId() vert_id = itr.vertexId() normal = itr.getNormal() if not mesh_normal.has_key(vert_id): mesh_normal[vert_id] = {} # mesh_normal[vert_id][face_id] = [round(data,2) for data in normal] mesh_normal[vert_id][face_id] = normal itr.next() # output = r"F:\MayaTecent\MayaScript\model\unlockNormal\data.json" # with open(output,'w') as f: # json.dump(mesh_normal,f,indent=4) # return pm.progressWindow(title='Unlock model normal', progress=0.0, status='colleting data...', isInterruptable=True) face_itr = om.MItMeshPolygon(dagPath) edge_itr = om.MItMeshEdge(dagPath) vert_itr = om.MItMeshVertex(dagPath) while not edge_itr.isDone(): if edge_itr.onBoundary(): edge_itr.next() continue edge_id = edge_itr.index() edge = "%s.e[%s]" % (dagPath.fullPathName(), edge_id) if pm.progressWindow(query=True, isCancelled=True): pm.progressWindow(endProgress=1) break amount = float(edge_id) / edge_itr.count() * 100 pm.progressWindow(e=1, progress=amount) smooth_flag = 0 hard_flag = 0 for i in range(2): vert_id = edge_itr.vertexId(i) face_list = edge_itr.getConnectedFaces() if len(face_list) != 2: print dagPath, edge_itr.index() raise RuntimeError( u"model edge should not have 3 faces connected") face_1, face_2 = face_list normal_1 = mesh_normal[vert_id][face_1] normal_2 = mesh_normal[vert_id][face_2] # vertex = "%s.vtx[%s]" % (dagPath.fullPathName(),vert_id) # NOTE 法线分叉 说明不是 软边边 if normal_1 == normal_2: vert_itr.setIndex(vert_id) vert_avg_normal = om.MVector(0.0, 0.0, 0.0) edge_avg_normal = om.MVector(0.0, 0.0, 0.0) face_list = vert_itr.getConnectedFaces() for face in face_list: face_itr.setIndex(face) normal = face_itr.getNormal() if face in [face_1, face_2]: edge_avg_normal += normal vert_avg_normal += normal vert_avg_normal = vert_avg_normal / len(face_list) edge_avg_normal = edge_avg_normal / 2 vert_avg_1 = (vert_avg_normal - normal_1).length() vert_avg_2 = (vert_avg_normal - normal_2).length() edge_avg_1 = (edge_avg_normal - normal_1).length() edge_avg_2 = (edge_avg_normal - normal_2).length() # NOTE 判断顶点是否近似 average if (vert_avg_1 < thersold and vert_avg_2 < thersold)\ or (edge_avg_1 < thersold and edge_avg_2 < thersold): smooth_flag += 1 smooth_vtx_list.add(vert_id) # NOTE 特殊调整的且统一的法线 else: edit_list.add(vert_id) else: # NOTE 硬边或特殊调整的法线 edit_list.add(vert_id) break # NOTE 两个点 smooth (百分百smooth) if smooth_flag > 1: smooth_list.append(edge) edge_itr.next() # if not smooth_list: # return pm.progressWindow(e=1, status='Unlocking...', progress=0) # NOTE 解锁法线 pm.polyNormalPerVertex(sel, ufn=1) # NOTE 添加软边 pm.polySoftEdge(smooth_list, a=180, ch=0) mesh = om.MFnMesh(dagPath) total = len(edit_list) normal_list = [] face_list = [] vtx_list = [] for i, vert_id in enumerate(edit_list): if pm.progressWindow(query=True, isCancelled=True): pm.progressWindow(endProgress=1) break amount = float(i) / total * 100 pm.progressWindow(e=1, progress=amount) for face_id, normal in mesh_normal[vert_id].items(): normal_list.append(normal) face_list.append(face_id) vtx_list.append(vert_id) # NOTE 多个设置比起单个法线设置要快很多 mesh.setFaceVertexNormals(normal_list, face_list, vtx_list) pm.progressWindow(e=1, status='Fixing...', progress=0) vtx_list = [] vert_itr = om.MItMeshVertex(dagPath) for i, vert_id in enumerate(smooth_vtx_list): if vert_id in edit_list: continue if pm.progressWindow(query=True, isCancelled=True): pm.progressWindow(endProgress=1) break amount = float(i) / total * 100 pm.progressWindow(e=1, progress=amount) vert_itr.setIndex(vert_id) for nor_1, nor_2 in combinations(vert_itr.getNormals(), 2): if (nor_1 - nor_2).length() > thersold: break else: continue vertex = "%s.vtx[%s]" % (dagPath.fullPathName(), vert_id) vtx_list.append(vertex) # pm.select(["%s.vtx[%s]" % (dagPath.fullPathName(),vert_id) for vert_id in edit_list]) pm.polySoftEdge(vtx_list, a=180, ch=0) pm.flushUndo() pm.progressWindow(endProgress=1) print "elapsed time : %s s" % (time.time() - curr)
def unlockNormal(thersold=0.05): curr = time.time() sel = pm.ls(sl=1, dag=1, ni=1, type="mesh") if not sel: return sel = sel[0] smooth_list = [] hard_list = [] sp_list = {} # pm.progressWindow() # NOTE OpenMaya 加速遍历过程 sel_list = om.MSelectionList() sel_list.add(sel.fullPathName()) dagPath = sel_list.getDagPath(0) # NOTE 获取 mesh 所有的法线信息 mesh_normal = {} itr = om.MItMeshFaceVertex(dagPath) while not itr.isDone(): face_id = itr.faceId() vert_id = itr.vertexId() normal = itr.getNormal() if not mesh_normal.has_key(vert_id): mesh_normal[vert_id] = {} mesh_normal[vert_id][face_id] = normal itr.next() face_itr = om.MItMeshPolygon(dagPath) edge_itr = om.MItMeshEdge(dagPath) vert_itr = om.MItMeshVertex(dagPath) while not edge_itr.isDone(): if edge_itr.onBoundary(): edge_itr.next() continue smooth_flag = 0 hard_flag = 0 for i in range(2): vert_idx = edge_itr.vertexId(i) face_list = edge_itr.getConnectedFaces() if len(face_list) != 2: print dagPath, edge_itr.index() raise RuntimeError( u"model edge should not have 3 faces connected") face_1, face_2 = face_list normal_1 = mesh_normal[vert_idx][face_1] normal_2 = mesh_normal[vert_idx][face_2] # NOTE 法线分叉 说明是 硬边 if normal_1 != normal_2: hard_flag += 1 continue vert_itr.setIndex(vert_idx) vert_avg_normal = om.MVector(0.0, 0.0, 0.0) edge_avg_normal = om.MVector(0.0, 0.0, 0.0) face_list = vert_itr.getConnectedFaces() for face in face_list: face_itr.setIndex(face) normal = face_itr.getNormal() if face == face_1: face_1_normal = normal edge_avg_normal += normal elif face == face_2: face_2_normal = normal edge_avg_normal += normal vert_avg_normal += normal vert_avg_normal = vert_avg_normal / len(face_list) edge_avg_normal = edge_avg_normal / 2 vert_avg_1 = (vert_avg_normal - normal_1).length() vert_avg_2 = (vert_avg_normal - normal_2).length() edge_avg_1 = (edge_avg_normal - normal_1).length() edge_avg_2 = (edge_avg_normal - normal_2).length() # NOTE 判断顶点是否近似 average if (vert_avg_1 < thersold and vert_avg_2 < thersold)\ or (edge_avg_1 < thersold and edge_avg_2 < thersold): smooth_flag += 1 else: # NOTE 过滤 非 hard _normal_1 = (face_1_normal - normal_1).length() _normal_2 = (face_2_normal - normal_2).length() if _normal_1 < thersold * 5 and _normal_2 < thersold * 5: hard_flag += 1 else: vertex = "%s.vtx[%s]" % (dagPath.fullPathName(), vert_idx) if vertex not in sp_list: sp_list[vertex] = normal_1 edge = "%s.e[%s]" % (dagPath.fullPathName(), edge_itr.index()) # NOTE 两个点 smooth (百分百smooth) if smooth_flag > 1: smooth_list.append(edge) if hard_flag > 0: hard_list.append(edge) edge_itr.next() if not hard_list: return # # NOTE 解锁法线 # pm.polyNormalPerVertex(sel,ufn=1) # # NOTE 添加软边 # pm.polySoftEdge(sel,a=180,ch=0) # # NOTE 添加硬边 # pm.polySoftEdge(hard_list,a=0,ch=0) # # NOTE 添加硬边 # pm.polySoftEdge(sel,a=0,ch=0) # NOTE 解锁法线 pm.polyNormalPerVertex(sel, ufn=1) # NOTE 添加软边 pm.polySoftEdge(smooth_list, a=180, ch=0) for vtx, normal in sp_list.items(): pm.polyNormalPerVertex(vtx, xyz=list(normal)) print "elapsed time : %s s" % (time.time() - curr)
def unlockNormal(thersold=0.01): curr = time.time() sel = pm.ls(sl=1, dag=1, ni=1, type="mesh") if not sel: raise sel = sel[0] smooth_list = set() hard_list = set() edit_list = [] # pm.progressWindow() # NOTE OpenMaya 加速遍历过程 sel_list = om.MSelectionList() sel_list.add(sel.fullPathName()) dagPath = sel_list.getDagPath(0) # NOTE 获取 mesh 所有的法线信息 mesh_normal = {} itr = om.MItMeshFaceVertex(dagPath) while not itr.isDone(): face_id = itr.faceId() vert_id = itr.vertexId() normal = itr.getNormal(space=om.MSpace.kWorld) if not mesh_normal.has_key(vert_id): mesh_normal[vert_id] = {} mesh_normal[vert_id][face_id] = normal itr.next() # NOTE 解锁法线 | 添加软边 pm.polyNormalPerVertex(sel, ufn=1) pm.polySoftEdge(sel, a=180, ch=0) itr = om.MItMeshFaceVertex(dagPath) while not itr.isDone(): face_id = itr.faceId() vert_id = itr.vertexId() normal = itr.getNormal(space=om.MSpace.kWorld) _normal = mesh_normal[vert_id][face_id] if (_normal - normal).length() > thersold: edit_list.append([_normal, face_id, vert_id]) else: vertex = "%s.vtx[%s]" % (dagPath.fullPathName(), vert_id) smooth_list.add(vertex) itr.next() mesh = om.MFnMesh(dagPath) for data in edit_list: _normal, face_id, vert_id = data try: mesh.setFaceVertexNormal(_normal, face_id, vert_id) except: import traceback traceback.print_exc() print vert_id, face_id raise vtx_list = [] for vtx in smooth_list: vtx = pm.PyNode(vtx) for nor_1, nor_2 in combinations(vtx.getNormals(), 2): if (nor_1 - nor_2).length() > 0.001: break else: continue vtx_list.append(vtx) pm.polySoftEdge(vtx_list, a=180, ch=0) # print edit_list print "elapsed time : %s s" % (time.time() - curr)
def unlockNormal(): curr = time.time() sel = pm.ls(sl=1,dag=1,ni=1,type="mesh") if not sel: return sel = sel[0] smooth_list = [] # pm.progressWindow() # NOTE OpenMaya 加速遍历过程 sel_list = om.MSelectionList() sel_list.add(sel.fullPathName()) dagPath = sel_list.getDagPath(0) # NOTE 获取 mesh 所有的法线信息 itr = om.MItMeshFaceVertex(dagPath) mesh_normal = {} while not itr.isDone(): face_id = itr.faceId() vert_id = itr.vertexId() normal = itr.getNormal() if not mesh_normal.has_key(vert_id): mesh_normal[vert_id] = {} mesh_normal[vert_id][face_id] = normal itr.next() edge_itr = om.MItMeshEdge(dagPath) vert_itr = om.MItMeshVertex(dagPath) while not edge_itr.isDone(): # NOTE 测试 # if edge_itr.index() != 43: # edge_itr.next() # continue if edge_itr.onBoundary(): edge_itr.next() continue for i in range(2): vert_idx = edge_itr.vertexId(i) vert_itr.setIndex(vert_idx) try: face_1,face_2 = edge_itr.getConnectedFaces() except: print dagPath,edge_itr.index() import traceback traceback.print_exc() raise normal_1 = mesh_normal[vert_idx][face_1] normal_2 = mesh_normal[vert_idx][face_2] if normal_1 != normal_2: break else: edge = "%s.e[%s]" % (dagPath.fullPathName(),edge_itr.index()) smooth_list.append(edge) edge_itr.next() # NOTE 解锁法线 pm.polyNormalPerVertex(sel,ufn=1) # NOTE 添加软边边 pm.polySoftEdge(smooth_list,a=180,ch=0) # pm.select(smooth_list) print "elapsed time : %s s" % (time.time() - curr)
def main(): sels = pm.selected() for sel in sels: pm.polySoftEdge(sel, a=180) pm.delete(ch=True)
import pymel.core as pm sel=pm.ls(sl=True) for obj in sel: if obj.getShape().type()=='mesh': pm.polyQuad(obj,kgb=True,ws=True,khe=False,ktb=False) pm.polySoftEdge(obj,a=180) if pm.polyUVSet(obj,auv=True,q=True): if 'UVW' in pm.polyUVSet(obj,auv=True,q=True): pm.polyCopyUV(obj,uvSetNameInput="UVW", uvSetName="map1", ch=0) pm.polyUVSet(obj,uvs="UVW",delete=True) pm.delete(obj,ch=True) pm.select(sel,r=True) shaders=pm.ls(type='phong') for shader in shaders: if len(shader.split('_'))>1: name=shader.split('_')[1] else: name=shader shader.rename(name+'_MTL')
def unlockNormal(thersold=0.05): curr = time.time() sel = pm.ls(sl=1, dag=1, ni=1, type="mesh") if not sel: return sel = sel[0] smooth_list = [] hard_list = [] smooth_vtx_list = set() edit_list = set() # NOTE OpenMaya 加速遍历过程 sel_list = om.MSelectionList() sel_list.add(sel.fullPathName()) dagPath = sel_list.getDagPath(0) # NOTE 获取 mesh 所有的法线信息 mesh_normal = getMeshNormals(dagPath) # # NOTE 解锁法线 # pm.polyNormalPerVertex(sel,ufn=1) # hard_vert_list = set() # itr = om.MItMeshFaceVertex(dagPath) # while not itr.isDone(): # face_id = itr.faceId() # vert_id = itr.vertexId() # normal = itr.getNormal() # if (normal - mesh_normal[vert_id][face_id]).length() < thersold: # hard_vert_list.add("%s.vtx[%s]" % (dagPath.fullPathName(),vert_id)) # itr.next() # pm.polySoftEdge(sel,a=180,ch=0) # soft_vert_list = set() # itr = om.MItMeshFaceVertex(dagPath) # while not itr.isDone(): # face_id = itr.faceId() # vert_id = itr.vertexId() # normal = itr.getNormal() # if (normal - mesh_normal[vert_id][face_id]).length() < thersold: # soft_vert_list.add("%s.vtx[%s]" % (dagPath.fullPathName(),vert_id)) # itr.next() # print list(hard_vert_list) # print list(soft_vert_list) # return # NOTE ----------------- pm.progressWindow(title='Unlock model normal', progress=0.0, status='colleting data...', isInterruptable=True) face_itr = om.MItMeshPolygon(dagPath) edge_itr = om.MItMeshEdge(dagPath) vert_itr = om.MItMeshVertex(dagPath) mesh = om.MFnMesh(dagPath) avg_vert_list = set() avg_edge_list = set() nonAvg_vert_list = set() modify_vert_list = set() edge_list = [] while not vert_itr.isDone(): vert_id = vert_itr.index() if pm.progressWindow(query=True, isCancelled=True): pm.progressWindow(endProgress=1) break amount = float(vert_id) / vert_itr.count() * 100 pm.progressWindow(e=1, progress=amount) # normals = vert_itr.getNormals() normals = mesh_normal[vert_id].values() normals_set = set() [normals_set.add(nor.length()) for nor in normals] vtx = "%s.vtx[%s]" % (dagPath.fullPathName(), vert_id) if len(normals_set) != 1: for edge in vert_itr.getConnectedEdges(): if edge not in edge_list: edge_list.append("%s.e[%s]" % (dagPath.fullPathName(), edge)) # nonAvg_vert_list.add("%s.vtx[%s]" % (dagPath.fullPathName(),vert_id)) nonAvg_vert_list.add(vert_id) # else: # normal = normals[0] # face_list = vert_itr.getConnectedFaces() # if (normal - getAvgVertNormal(face_list,face_itr)).length() > thersold: # modify_vert_list.add(vtx) # else: # avg_vert_list.add(vtx) # for edge in vert_itr.getConnectedEdges(): # avg_edge_list.add("%s.e[%s]" % (dagPath.fullPathName(),edge)) vert_itr.next() # print nonAvg_vert_list # pm.select(nonAvg_vert_list) pm.polyNormalPerVertex(sel, ufn=1) pm.polySoftEdge(sel, a=180, ch=0) normal_list = [] face_list = [] vtx_list = [] for i, vert_id in enumerate(nonAvg_vert_list): # if i > 20: # break for face_id, normal in mesh_normal[vert_id].items(): normal_list.append(normal) face_list.append(face_id) vtx_list.append(vert_id) # NOTE 多个设置比起单个法线设置要快很多 mesh.setFaceVertexNormals(normal_list, face_list, vtx_list) # pm.select(avg_edge_list) # dul = pm.duplicate(sel,rr=1)[0] # # NOTE 解锁法线 # pm.polyNormalPerVertex(sel,ufn=1) # # NOTE 添加软边 # pm.polySoftEdge(sel,a=180,ch=0) # pm.select(dul,r=1) # pm.select(vert_list,r=1) # pm.transferAttributes(transferNormals=1 ,sampleSpace=4 ,searchMethod=3) # while not edge_itr.isDone(): # if edge_itr.onBoundary(): # edge_itr.next() # continue # edge_id = edge_itr.index() # edge = "%s.e[%s]" % (dagPath.fullPathName(),edge_id) # if pm.progressWindow( query=True, isCancelled=True ) : # pm.progressWindow(endProgress=1) # break # amount = float(edge_id)/edge_itr.count()*100 # pm.progressWindow( e=1, progress=amount) # smooth_flag = 0 # hard_flag = 0 # for i in range(2): # vert_id = edge_itr.vertexId(i) # face_list = edge_itr.getConnectedFaces() # if len(face_list) != 2: # print dagPath,edge_itr.index() # raise RuntimeError(u"model edge should not have 3 faces connected") # face_1,face_2 = face_list # normal_1 = mesh_normal[vert_id][face_1] # normal_2 = mesh_normal[vert_id][face_2] # # vertex = "%s.vtx[%s]" % (dagPath.fullPathName(),vert_id) # # NOTE 法线分叉 说明不是 软边边 # if normal_1 == normal_2: # vert_itr.setIndex(vert_id) # vert_avg_normal = om.MVector(0.0, 0.0, 0.0) # edge_avg_normal = om.MVector(0.0, 0.0, 0.0) # face_list = vert_itr.getConnectedFaces() # for face in face_list: # face_itr.setIndex(face) # normal = face_itr.getNormal() # if face in [face_1,face_2]: # edge_avg_normal += normal # vert_avg_normal += normal # vert_avg_normal = vert_avg_normal/len(face_list) # edge_avg_normal = edge_avg_normal/2 # vert_avg_1 = (vert_avg_normal - normal_1).length() # vert_avg_2 = (vert_avg_normal - normal_2).length() # edge_avg_1 = (edge_avg_normal - normal_1).length() # edge_avg_2 = (edge_avg_normal - normal_2).length() # # NOTE 判断顶点是否近似 average # if (vert_avg_1 < thersold and vert_avg_2 < thersold)\ # or (edge_avg_1 < thersold and edge_avg_2 < thersold): # smooth_flag += 1 # smooth_vtx_list.add(vert_id) # # NOTE 特殊调整的且统一的法线 # else: # edit_list.add(vert_id) # else: # # NOTE 硬边或特殊调整的法线 # edit_list.add(vert_id) # break # # NOTE 两个点 smooth (百分百smooth) # if smooth_flag > 1: # smooth_list.append(edge) # edge_itr.next() # # if not smooth_list: # # return # pm.progressWindow( e=1,status='Unlocking...',progress=0) # # NOTE 解锁法线 # pm.polyNormalPerVertex(sel,ufn=1) # # NOTE 添加软边 # pm.polySoftEdge(smooth_list,a=180,ch=0) # mesh = om.MFnMesh(dagPath) # total = len(edit_list) # normal_list = [] # face_list = [] # vtx_list = [] # for i,vert_id in enumerate(edit_list): # if pm.progressWindow( query=True, isCancelled=True ) : # pm.progressWindow(endProgress=1) # break # amount = float(i)/total * 100 # pm.progressWindow( e=1, progress=amount) # for face_id,normal in mesh_normal[vert_id].items(): # normal_list.append(normal) # face_list.append(face_id) # vtx_list.append(vert_id) # # NOTE 多个设置比起单个法线设置要快很多 # mesh.setFaceVertexNormals(normal_list,face_list,vtx_list) # pm.progressWindow( e=1,status='Fixing...',progress=0) # vtx_list = [] # vert_itr = om.MItMeshVertex(dagPath) # for i,vert_id in enumerate(smooth_vtx_list): # if vert_id in edit_list: # continue # if pm.progressWindow( query=True, isCancelled=True ) : # pm.progressWindow(endProgress=1) # break # amount = float(i)/total * 100 # pm.progressWindow( e=1, progress=amount) # vert_itr.setIndex(vert_id) # for nor_1,nor_2 in combinations(vert_itr.getNormals(),2): # if (nor_1 - nor_2).length() > thersold: # break # else: # continue # vertex = "%s.vtx[%s]" % (dagPath.fullPathName(),vert_id) # vtx_list.append(vertex) # # pm.select(["%s.vtx[%s]" % (dagPath.fullPathName(),vert_id) for vert_id in edit_list]) # pm.polySoftEdge(vtx_list,a=180,ch=0) # pm.flushUndo() pm.progressWindow(endProgress=1) print "elapsed time : %s s" % (time.time() - curr)