def _split_shells_(lssl=None): lssl = cm.ls(lssl) if not lssl: lssl = [x for x in cm.ls(tr=1) if cm.listRelatives(x, s=1, type="mesh")] for sel in lssl: bord_uvs = uv_borders(sel) cm.polySplitEdge(bord_uvs, ch=0)
def _decapitate(targets, edges, orig_mesh, index_target=1): """ Takes a lsit of target meshes and deparates them from their bodies so we have isolated head meshes Args: targets [str]: list of target meshes to separate edges [str]: list of edges orig_mesh (str): the original mesh we are replacing from the blends file name index_target (int): used just in case the separate is targetting the wrong index of shell Returns [str]: list of face template meshes created from the targets """ blend_table = {} for edge in [edge for edge in edges if '.' in edge]: transform = edge.split('.')[0] try: blend_table[transform].append(edge) except KeyError: blend_table[transform] = [edge] heads = [] for target in targets: for transform, edges in blend_table.iteritems(): target_shape = mc.listRelatives(target, s=True)[0] edges = [edge.replace(transform, target) for edge in edges] if mc.ls(edges) and len(list(set(mc.ls(edges))))==len(edges): mc.selectMode(co=True) mc.selectType(alc=0, pe=1) mc.select(mc.ls(edges), r=True) mc.polySplitEdge(operation=1, ch=1) shells = mc.polySeparate(target_shape, ch=False) for index, shell in enumerate(shells): if index != index_target: mc.delete(shell) else: shell=shell mc.ungroup(target, w=True) heads.append(shell) mc.selectMode(o=True) return heads
def proxy_duplicates(influence_map, method=1, constrain=True): """ Args: influence_map (dict): dictionary of transforms with subdicts of their influences and their affected faces as a list method (int): 1 - uses split edge on a single duplicate then queries nearest vert+influence of that vert, more efficient 0 - duplicates the mesh and deletes unaffected faces per duplicate/proxy Returns [str]: list of proxy meshes generated """ proxies = dict((k, []) for k in [transform for transform in influence_map.keys()]) for transform, influence_faces in influence_map.iteritems(): transform_shape = cmds.listRelatives(transform, s=True, c=True)[0] dup = cmds.duplicate(transform)[0] edges = [] for influence, faces in influence_faces.iteritems(): edges += [edge.replace(transform, dup) for edge in cmds.polyListComponentConversion(faces, toEdge=True, border=True)] cmds.polySplitEdge(edges, ch=False) shells = cmds.polySeparate(dup) cmds.delete(shells, ch=True) position_dict = mesh_vert_pos_dict(transform_shape) for shell in shells: vertices = cmds.ls(shell+'.vtx[:]', fl=True) if vertices: influences = [] for vertex in vertices: match_vert, influence = position_dict[','.join([str(pos) for pos in cmds.xform(vertex, t=True, ws=True, q=True)])] influences.append(influence) common_influence = Counter(influences).most_common(1)[0][0] if constrain: pm.parentConstraint(common_influence, shell, mo=True) shell_name = '%s_%s_PROXY' % (transform, common_influence) cmds.rename(shell, shell_name) proxies[transform].append(shell) cmds.rename(dup, '%s_cutupProxy_GRP' % transform) return proxies
def cleanupNonManifoldGeometry(self, normals=True): ## Get all the mesh that has mentalraySubdivApprox connected and has non-manifold problem # subdiv_mesh = [cmds.listRelatives(mesh, parent = True, fullPath = True)[0] for mesh in cmds.ls(type = 'mesh') if cmds.listConnections(mesh, type = 'mentalraySubdivApprox') if cmds.polyInfo(mesh, nme = True) or cmds.polyInfo(nmv = True)] subdiv_mesh = [ cmds.listRelatives(mesh, parent=True, fullPath=True)[0] for mesh in cmds.ls(type='mesh') if cmds.polyInfo(mesh, nme=True) or cmds.polyInfo(nmv=True) ] subdiv_mesh = list(set(subdiv_mesh)) if subdiv_mesh: for each in subdiv_mesh: ## Make sure we do indeed have nonmanifold geometry ## nonManifold = cmds.polyInfo(each, nmv=True, nme=True) if nonManifold: proceed = cmds.confirmDialog( title='Non-Manifold Geometry!', message='Geo Name:\n%s' % each, button=['Cleanup!', 'Skip...'], defaultButton='Skip...', cancelButton='Skip...', dismissString='Skip...') if proceed == 'Cleanup!': ## Conform the geo and see if that gets rid of all the nonmanifold bits ## if normals: cmds.polyNormal('%s.f[*]' % each, normalMode=2, constructionHistory=True) edges = cmds.polyInfo(each, nme=True) if cmds.polyInfo( each, nme=True) else [] vertices = [] if edges else cmds.polyInfo(each, nmv=True) lastEdges = [] lastVertices = [] while (not self.arraysMatch(lastEdges, edges) or not self.arraysMatch(lastVertices, vertices) ) and (edges or vertices): ## Remember what was nonmanifold last time ## lastEdges = edges lastVertices = vertices ## Split any nonmanifold edges ## if edges: cmds.polySplitEdge(edges, constructionHistory=True) vertices = cmds.polyInfo(each, nmv=True) edges = [] ## Split any remaining nonmanifold vertices ## if vertices: cmds.polySplitVertex(vertices, constructionHistory=True) vertices = [] ## Now check to see if the object is still nonmanifold ## nonManifold = cmds.polyInfo(each, nmv=True, nme=True) if nonManifold: ## Chip off the faces ## nonManifoldFaces = cmds.polyListComponentConversion( nonManifold, toFace=True) cmds.polyChipOff(nonManifoldFaces, kft=0, dup=0, constructionHistory=True) ## And then check for nonmanifold bits again ## edges = cmds.polyInfo(each, nme=True) if not edges: vertices = cmds.polyInfo(each, nmv=True) ## Check to see if we failed to cleanup if edges or vertices: cmds.warning( 'Failed to cleanup non-manifold geometry of %s...' % each)
def polySplitEdge(*args, **kwargs): res = cmds.polySplitEdge(*args, **kwargs) if not kwargs.get('query', kwargs.get('q', False)): res = _factories.maybeConvert(res, _general.PyNode) return res
def cleanupNonManifoldGeometry(self, normals = True): ## Get all the mesh that has mentalraySubdivApprox connected and has non-manifold problem # subdiv_mesh = [cmds.listRelatives(mesh, parent = True, fullPath = True)[0] for mesh in cmds.ls(type = 'mesh') if cmds.listConnections(mesh, type = 'mentalraySubdivApprox') if cmds.polyInfo(mesh, nme = True) or cmds.polyInfo(nmv = True)] subdiv_mesh = [cmds.listRelatives(mesh, parent = True, fullPath = True)[0] for mesh in cmds.ls(type = 'mesh') if cmds.polyInfo(mesh, nme = True) or cmds.polyInfo(nmv = True)] subdiv_mesh = list( set( subdiv_mesh ) ) if subdiv_mesh: for each in subdiv_mesh: ## Make sure we do indeed have nonmanifold geometry ## nonManifold = cmds.polyInfo(each, nmv = True, nme = True) if nonManifold: proceed = cmds.confirmDialog(title = 'Non-Manifold Geometry!', message = 'Geo Name:\n%s' % each, button = ['Cleanup!', 'Skip...'], defaultButton = 'Skip...', cancelButton = 'Skip...', dismissString = 'Skip...') if proceed == 'Cleanup!': ## Conform the geo and see if that gets rid of all the nonmanifold bits ## if normals: cmds.polyNormal('%s.f[*]' % each, normalMode = 2, constructionHistory = True) edges = cmds.polyInfo(each, nme = True) if cmds.polyInfo(each, nme = True) else [] vertices = [] if edges else cmds.polyInfo(each, nmv = True) lastEdges = [] lastVertices = [] while ( not self.arraysMatch(lastEdges, edges) or not self.arraysMatch(lastVertices, vertices) ) and ( edges or vertices ): ## Remember what was nonmanifold last time ## lastEdges = edges lastVertices = vertices ## Split any nonmanifold edges ## if edges: cmds.polySplitEdge(edges, constructionHistory = True) vertices = cmds.polyInfo(each, nmv = True) edges = [] ## Split any remaining nonmanifold vertices ## if vertices: cmds.polySplitVertex(vertices, constructionHistory = True) vertices = [] ## Now check to see if the object is still nonmanifold ## nonManifold = cmds.polyInfo(each, nmv = True, nme = True) if nonManifold: ## Chip off the faces ## nonManifoldFaces = cmds.polyListComponentConversion(nonManifold, toFace = True) cmds.polyChipOff(nonManifoldFaces, kft = 0, dup = 0, constructionHistory = True) ## And then check for nonmanifold bits again ## edges = cmds.polyInfo(each, nme = True) if not edges: vertices = cmds.polyInfo(each, nmv = True) ## Check to see if we failed to cleanup if edges or vertices: cmds.warning('Failed to cleanup non-manifold geometry of %s...' % each)
def split_shells(sel=None, uvset=None, hist=None): """Splitting edges by uv shell borders # Partially based on rebb's code: https://polycount.com/discussion/52722/maya-mel-script-help-needed-uv-border-edges/p1 # TODO: - optimipztion: get_uv_shells() is revoking each time edges are modified(splitting) # Using: - get_uv_shells() # Usage: select objects: >> split_shells(hist=True) # Args: - sel, str, if None current selections will be used - uvset, str, if None current uvSet will be used for each selection - hist, bool, construction history preservation, default is True # Returns: >> 0 # on success """ # solve selection lssl = cm.ls(sel, l=1) if not sel: lssl = cm.ls(sl=1, l=1) if not lssl: return # uv component name attr = "map" # resolve kwargs for all selection hist = True if hist is None else hist for sel_l in lssl: # resolve kwargs for each selection if not uvset: # if not given use current uvset = cm.getAttr(sel_l + ".cuvs") else: # if given, check if exists alluvs = cm.polyUVSet(sel_l, q=1, auv=1) if sel not in alluvs: msg = " ! Not found in: '{}':'{}'" print msg.format(uvset, sel_l), continue shells = get_uv_shells(sel_l, uvSet=uvset) # shell = shells[0] print ">", sel_l for i in range(len(shells)): comps = [] for j in shells[i]: comp = "{}.{}[{}]".format(sel_l, attr, j) comps.append(comp) #cm.select(comps) # chippoff shells except first(0) if i: # convert to containing face and flatten list # (faster than `ls -fl ..`) shell2face = cm.filterExpand( cm.polyListComponentConversion(comps, tf=1, internal=1), sm=34) #cm.select(shell2face) chipoff = cm.polyChipOff(shell2face, dup=0, ch=hist) comps = cm.polyListComponentConversion(shell2face, tuv=1) # select only borders of one shell cm.select(comps) # do not comment this line # (!) selection based operation # On selection mask type to "uv borders" bord_uvs = cm.polySelectConstraint( t=0x0010, uv=0, bo=1, m=2, returnSelection=1) # Off "uv borders" mask cm.polySelectConstraint(bo=0) #cm.select(bord_uvs) # convert to edge and flatten list edgs = cm.filterExpand( cm.polyListComponentConversion(bord_uvs, te=1, internal=1), sm=32) #cm.select(edgs) # filter edges by uv uv2edg = [] for ed in edgs: # cm.select(ed) uvs = cm.filterExpand( cm.polyListComponentConversion(ed, tuv=1), sm=35) if len(uvs) > 2: uv2edg.append(ed) #cm.select(uv2edg) if uv2edg: cm.polySplitEdge(uv2edg, ch=hist) # update shells # update uv shells' uv points shells = get_uv_shells(sel_l, uvSet=uvset) return 0