def spAll(): theNodes = cmds.ls(dag=True, s=True, type="shape") for n in theNodes: try: cmds.polySeparate(n) except: print(n + " separate fail.")
def fxSeparate(): selection = m.ls(sl=True, long=True, tr=True) for s in selection: try: m.polySeparate(s, ch=False) except RuntimeError: m.warning('Mesh ignored because has only one piece: {}'.format(s))
def CreateBushes(self, posX=0, posZ=0): brushesBase = cmds.polyPrimitive(r=0.4, pt=0)[0] cmds.polyChipOff(dup=False, kft=False) cmds.polyChipOff(dup=False, kft=True, ltz=0.1, ran=1.0) cmds.polyExtrudeFacet(ltz=0.2) cmds.polySmooth() cmds.polySeparate() cmds.xform(cp=True) for leaf in cmds.ls(sl=True): leafScale = round(random.uniform(2, 2.5), 3) cmds.select(leaf) cmds.polySoftEdge(a=0, name=leaf) cmds.scale(leafScale, leafScale, leafScale) leafPosition = cmds.xform(leaf, q=True, rp=True, ws=True) if leafPosition[1] < 0: cmds.delete(leaf) else: cmds.xform(leaf, t=leafPosition, ws=True) self.SetRandomLeafColor(leaf) cmds.setAttr(brushesBase + ".translateX", posX) cmds.setAttr(brushesBase + ".translateZ", posZ) return cmds.rename(brushesBase, 'Bushes#')
def polySeperateTool(self): cmds.polySeparate() cmds.delete(ch=1) A = self.getSelection() B = cmds.listRelatives(A[0], p=True) cmds.ungroup( B ) cmds.select(A) JR_rename_tool.UI('exit') # to rename the freshly branched poly
def polySeperateTool(self): cmds.polySeparate() cmds.delete(ch=1) A = self.getSelection() B = cmds.listRelatives(A[0], p=True) cmds.ungroup(B) cmds.select(A) JR_rename_tool.UI('exit') # to rename the freshly branched poly
def Chop(*args): curSel = cmds.ls(sl=True) if (len(curSel) > 0): cmds.polyChipOff(ch=1, kft=1, dup=0, off=0) gotoObjectmod() cmds.polySeparate() else: print "nothing selected, please select faces"
def readyToExtrude(subdX, twistT, divisionsD, number): cmds.setAttr('combined.rotate', 0, 0, 90) cmds.select('curve1') checkFaces2(subdX, number) cmds.setAttr('polyExtrudeFace1.divisions', divisionsD) cmds.setAttr('polyExtrudeFace1.twist', twistT) cmds.select('combined') cmds.polyNormal(normalMode=0, userNormalMode=0) cmds.polySeparate('combined')
def GEO_clean_separate(): ''' Separates selection and deletes history ''' sel = cmds.ls(sl=True) mesh = cmds.listRelatives(sel, pa=True, type="mesh") all_sel = cmds.listRelatives(mesh, parent=True, fullPath=False) if all_sel is None: return "Select Meshes first.", 0 try: cmds.polySeparate(sel, ch=False) # combines and deletehistory return "Shapes separated with no history: ({})".format(len(all_sel)), 1 except Exception as e: return str(e), 0
def chipFacesTool(self): # cuts faces off of the poly and then seperates the faces to it's own polygon object, also ungroups them selectedFaces = self.getSelection() selectionParent = cmds.listRelatives(selectedFaces[0], p=True) cmds.polyChipOff(selectedFaces, dup=True) seperated = cmds.polySeparate(selectionParent[0]) allSeperated = [i for i in seperated if 'Separate' not in i] if len(allSeperated) > 2: cmds.polyUnite(allSeperated[1:]) new = self.getSelection() else: new = allSeperated[1] old = [] old.append(allSeperated[0]) oldParent = cmds.listRelatives(old[0], p=True) oldParentChildren = cmds.listRelatives(oldParent[0], c=True) oldNodesToDelete = set(old) ^ set(oldParentChildren) print oldNodesToDelete, ' this is old nodes to delete' cmds.ungroup(oldParent) cmds.delete(new, ch=1) cmds.delete(old, ch=1) cmds.rename(old, oldParent) cmds.select(new) self.assignRandomMaterial( ) # assigns random lambert to newly created poly cmds.delete(selectedFaces) cmds.select(old) cmds.xform(centerPivots=True) cmds.select(new) # reselect it after material assign cmds.xform(centerPivots=True) # Center pivot of new article. JR_rename_tool.UI('exit') # to rename the freshly branched poly
def SeparateAndCombine(): # 先框选需要分离的所有模型 # 运行命令 # 结束后如果有错误的物体超过1个 selectObj = mc.ls(sl=True, l=True) SeparateErrorObj = [] if not selectObj: mc.error('please select model!') for obj in selectObj: objSplit = obj.split('|') objName = objSplit[-1] objParent = ('|').join(objSplit[:-1]) try: objSeparate = mc.polySeparate(obj, ch=1) newObj = mc.polyUnite(objSeparate, name=objName, ch=1, mergeUVSets=1) mm.eval('DeleteHistory;') if objParent: mc.parent(newObj[0], objParent) except: SeparateErrorObj.append(obj) mc.select(SeparateErrorObj)
def shell_UV_scaler(): global sele sele = cmds.ls(sl=True, fl=True) if len(sele) > 1: om.MGlobal.displayError("Select only one object") return mel.eval("select " + sele[0]) old_mesh_dupe = cmds.duplicate() cmds.progressBar(progressControl, edit=True, beginProgress=True) cmds.progressBar(progressControl, edit=True, visible=True) try: separated = cmds.polySeparate(ch=True) cmds.progressBar(progressControl, edit=True, pr=5) set_UV_ratio(0) combined_mesh = cmds.polyUnite(ch=True) mel.eval("polyTransfer -uv 1 -ch off -ao \"" + combined_mesh[0] + "\" \"" + sele[0] + "\"") cmds.delete(combined_mesh[0]) mel.eval("select " + sele[0]) cmds.progressBar(progressControl, edit=True, pr=0) except: cmds.delete(old_mesh_dupe) mel.eval("select " + sele[0]) om.MGlobal.displayError("The object has only one face shell") cmds.progressBar(progressControl, edit=True, endProgress=True) cmds.progressBar(progressControl, edit=True, visible=False) om.MGlobal.displayInfo("Done")
def chipFacesTool(self): # cuts faces off of the poly and then seperates the faces to it's own polygon object, also ungroups them selectedFaces = self.getSelection() selectionParent = cmds.listRelatives(selectedFaces[0], p=True) cmds.polyChipOff( selectedFaces, dup=True) seperated = cmds.polySeparate(selectionParent[0]) allSeperated = [i for i in seperated if 'Separate' not in i] if len(allSeperated) > 2: cmds.polyUnite(allSeperated[1:]) new = self.getSelection() else: new = allSeperated[1] old = []; old.append(allSeperated[0]) oldParent = cmds.listRelatives(old[0], p=True) oldParentChildren = cmds.listRelatives(oldParent[0], c=True) oldNodesToDelete = set(old) ^ set(oldParentChildren) print oldNodesToDelete, ' this is old nodes to delete' cmds.ungroup( oldParent ) cmds.delete(new, ch=1) cmds.delete(old, ch=1) cmds.rename(old, oldParent ) cmds.select(new) self.assignRandomMaterial() # assigns random lambert to newly created poly cmds.delete(selectedFaces) cmds.select(old) cmds.xform(centerPivots = True) cmds.select(new) # reselect it after material assign cmds.xform(centerPivots = True) # Center pivot of new article. JR_rename_tool.UI('exit') # to rename the freshly branched poly
def pieslice(self, pStAn, pEnAn, pR, pH=0.1): cyl = mc.polyCylinder(h=pH, r=pR, n='stairObject') cx = mc.objectCenter(x=True) cy = mc.objectCenter(y=True) cz = mc.objectCenter(z=True) h = pH #cut the cylinder, and separate different parts cut = mc.polyCut(cyl, cutPlaneCenter=[cx, h / 2, cz], cutPlaneRotate=[0, pStAn, 0], extractFaces=True, extractOffset=[0, 0, 0]) cut = mc.polyCut(cyl, cutPlaneCenter=[cx, h / 2, cz], cutPlaneRotate=[0, pEnAn, 0], extractFaces=True, extractOffset=[0, 0, 0]) obj = mc.polySeparate(cyl) names = [] for i in range(len(obj)): mc.rename(obj[i], 'part' + str(i)) names.append('part' + str(i)) #fill hole of the required pieslice mc.polyCloseBorder(names[2]) #delete useless parts from the now separated cylinder mc.delete(names[0:2] + names[3:4], s=True) return names[2]
def cleanProcedure(): cmds.undoInfo(ock=1) sel = cmds.ls(sl=1) selRelatives = cmds.listRelatives(sel) if selRelatives[0].startswith('instanceAlongCurveLocator'): selectedLocator = [] selectedLocator=cmds.ls(sl=1) tempGroupName = "" tempGroupName=str(cmds.group(em=1, n='InstanceMesh')) selectedMesh = [] selectedMeshDuplicatedShape = [] selectedThings = [] cmds.select(selectedLocator) selectedThings=cmds.listRelatives(c=1) selectedMesh=cmds.filterExpand(sm=12) cmds.select(selectedMesh) selectedMeshDuplicatedShape=cmds.listRelatives(c=1) eachOverride=selectedMeshDuplicatedShape[0] + ".overrideEnabled" cmds.setAttr(eachOverride, 1) selectedMeshDuplicated=cmds.duplicate() cmds.parent(selectedMeshDuplicated, tempGroupName) cmds.ungroup(tempGroupName) cmds.delete(selectedLocator) cmds.select(selectedMeshDuplicated) cmds.polyUnite(centerPivot=1, ch=1, mergeUVSets=1) separatedMesh = [] separatedMesh=cmds.polySeparate(ch=1) cmds.CenterPivot() separatedMeshGroup=cmds.listRelatives(separatedMesh, p=1) cmds.select(separatedMeshGroup) cmds.select(selectedMeshDuplicated, add=1) cmds.ungroup() cmds.DeleteHistory() resultAll = cmds.ls(sl=1,o=1) result = cmds.filterExpand(resultAll,sm=12) toDelete = list(set(resultAll).difference(set(result))) cmds.delete(toDelete) else: try: selectedForClean=cmds.ls(sl=1) cmds.polyCube(sz=1, sy=1, sx=1, d=1, cuv=4, h=1, ch=1, w=1, ax=(0, 1, 0)) temp_polyCube=cmds.ls(sl=1) cmds.select(selectedForClean) cmds.select(temp_polyCube, add=1) cmds.CombinePolygons() temp_BeforeSeparate=cmds.ls(sl=1) cmds.SeparatePolygon() temp_AfterSeparate=cmds.ls(sl=1) cmds.delete(temp_AfterSeparate[- 1]) cmds.DeleteHistory() temp_father=cmds.listRelatives(temp_AfterSeparate[0], p=1) cmds.select(temp_BeforeSeparate) cmds.ungroup() cmds.delete(selectedForClean) cmds.CombinePolygons() cmds.DeleteHistory() except: pass cmds.undoInfo(cck=1)
def fixFaceShaderObject(items): for shapename in items(): templist = om.MSelectionList() om.MGlobal.getSelectionListByName(shapename, templist) shapedagpath = om.MDagPath() templist.getDagPath(0, shapedagpath) fnmesh = om.MFnMesh(shapedagpath) sgs = om.MObjectArray() faceinsg = om.MObjectArray() fnmesh.getConnectedSetsAndMembers(0, sgs, faceinsg, True) fn_firstsg = om.MFnDependencyNode(sgs[0]) firstsgname = fn_firstsg.name() fn_compent = om.MFnSingleIndexedComponent(faceinsg[0]) m_faceid = om.MIntArray() fn_compent.getElements(m_faceid) tempTrans = om.MFloatVector() fnmesh.extractFaces(m_faceid, tempTrans) fnmesh.updateSurface() try: shapes = mc.polySeparate(fnmesh.fullPathName(), ch=False) except RuntimeError: shapes = [] if filter(pmcfs.checkShaderMulti, shapes): for objname in filter(pmcfs.checkShaderMulti, shapes): fixFaceShaderObject(objname)
def pieslice(pStAn, pEnAn, pR, pH=0.1): cyl = mc.polyCylinder(h=pH, r=pR) cx = mc.objectCenter(x=True) cy = mc.objectCenter(y=True) cz = mc.objectCenter(z=True) h = pH #cut the cylinder, and separate different parts cut = mc.polyCut(cyl, cutPlaneCenter=[cx, h / 2, cz], cutPlaneRotate=[0, pStAn, 0], extractFaces=True, extractOffset=[0, 0, 0]) cut = mc.polyCut(cyl, cutPlaneCenter=[cx, h / 2, cz], cutPlaneRotate=[0, pEnAn, 0], extractFaces=True, extractOffset=[0, 0, 0]) obj = mc.polySeparate(cyl) names = [] for i in range(len(obj)): mc.rename(obj[i], 'part' + str(i)) names.append('part' + str(i)) #delete useless parts from the now separated cylinder mc.delete(names[0:2] + names[3:], s=True) #fill hole of the leftover pieslice mc.polyCloseBorder(names[2]) #add and assign a material (which was deleted when delete was called) myBlinn = mc.shadingNode('blinn', asShader=True) mc.select(names[2]) mc.hyperShade(assign=myBlinn) return names[2]
def separate(self, obj): ''' Seperates the geometry that has been combined with the combine method. This proc restores the names to what they were in the state before the combine. @param obj: Mesh object to separate @type obj: str ''' # Check origNames attribute if not mc.objExists(obj+'.origNames'): raise UserInputError('Object '+obj+' does not have a "origNames" attribute!') origNamesIsMulti = True if not mc.addAttr(obj+'.origNames',q=True,multi=True): origNamesIsMulti = False # Need to phase out the old format origNames attribute #------------------------------------------------------- #raise UserInputError(obj+'.origNames attribute is not in the correct format! Please run MeshCombineUtilities.updateOrigNamesFormat().') # Deal with scene namespace scene_ns = mm.eval('getOfficialNS') mm.eval('pauseNS') ns='' if obj.count(':'): ns = obj.split(':')[0]+':' obj_parent = mc.listRelatives(obj, p=1,pa=True) obj_fPath = mc.ls(obj,l=1) objs = [] try: objs = mc.polySeparate(obj,ch=1) except: raise UserInputError('Separate failed on object "'+obj+'"!') # Get original names list nameList=[] if origNamesIsMulti: for i in range(mc.getAttr(obj+'.origNames',s=True)): nameList.append( mc.getAttr(obj+'.origNames['+str(i)+']') ) else: for attr in mc.listAttr(obj+'.origNames')[1:]: nameList.append( mc.getAttr(obj+'.origNames.'+attr) ) # Rename separated objects for i in range(len(nameList)): nameList[i] = mc.rename(objs[i],ns+nameList[i]) # Re-Parent separated objects if mc.objExists(obj_parent[0]): mc.parent(nameList[i],obj_parent[0]) elif mc.objExists(ns+'model'): mc.parent(nameList[i],ns+'model') else: mc.parent(nameList[i], w=1 ) # Cleanup: # Removed rename of original objects: Objects that are referenced can't be renamed # orig_child = mc.listRelatives(obj_fPath, c=1, ni=1, pa=True) for i in orig_child: if mc.listRelatives(i): mc.delete(i) # handle namespace mm.eval('setNS("'+scene_ns+'")') return nameList
def hfSplitBadShaded(self, engines): modifiedShapes = [] for sg in engines: print('checking shading group: '+sg) cmds.hyperShade(objects=sg) components = cmds.ls(sl=1) uniqueShapes = [] for entry in components: uniqueShapes.append(entry.split('.')[0]) # remove whole shapes (not components) from the list. if entry.rfind('.f') == -1: components.remove(entry) if len(components) > 0: components.sort() # remove duplicates from uniqueShapes. uniqueShapes = list(set(uniqueShapes)) modifiedShapes.extend(uniqueShapes) # print('\nunique shapes under shading group: ') # print(uniqueShapes) for shape in uniqueShapes: cmds.select(cl=1) # get the total num of faces for the shape for later use. totalFaces = cmds.polyEvaluate(shape, f=1) for comp in components: testStr = shape+'.f[' if testStr in comp: # the current component is a member of the current mesh we're splitting and it has the shader we want. cmds.select(comp, add=1) selFaces = cmds.ls(sl=1) # print 'selection:' # print selFaces # extract the selected faces if we aren't selecting every face of the current mesh. if len(selFaces) < int(totalFaces) and len(selFaces) > 0: cmds.polyChipOff(selFaces, kft=1, dup=0) cmds.delete(shape,ch=1) # now the mesh is broken into shells. separate it if possible. if cmds.polyEvaluate(shape, s=1) > 1: newObjects = cmds.polySeparate(shape, ch=0) modifiedShapes.extend(newObjects) # print('split new shapes: ') # print(newObjects) cmds.select(newObjects) # print(cmds.ls(sl=1)) cmds.delete(ch=1) cmds.select(cl=1) # now in order to return all the new meshes we made, we should sort through uniqueShapes and remove anything that no longer # exists. anything that's been split, etc. modifiedShapes = list(set(modifiedShapes)) returnShapes = [] for shape in modifiedShapes: if cmds.objExists(shape) == 0: modifiedShapes.remove(shape) else: meshNodes = cmds.listRelatives(shape, s=1) if meshNodes != None: # if we are not testing an xform, meshNodes will be a 'NoneType' object so we should include an exception. returnShapes.extend(meshNodes) return returnShapes
def separate(self, obj): ''' Seperates the geometry that has been combined with the combine method. This proc restores the names to what they were in the state before the combine. @param obj: Mesh object to separate @type obj: str ''' # Check origNames attribute if not mc.objExists(obj+'.origNames'): raise Exception('Object '+obj+' does not have a "origNames" attribute!') origNamesIsMulti = True if not mc.addAttr(obj+'.origNames',q=True,multi=True): origNamesIsMulti = False # Need to phase out the old format origNames attribute #------------------------------------------------------- #raise Exception(obj+'.origNames attribute is not in the correct format! Please run MeshCombineUtilities.updateOrigNamesFormat().') # Deal with scene namespace scene_ns = mm.eval('getOfficialNS') mm.eval('pauseNS') ns='' if obj.count(':'): ns = obj.split(':')[0]+':' obj_parent = mc.listRelatives(obj, p=1,pa=True) obj_fPath = mc.ls(obj,l=1) objs = [] try: objs = mc.polySeparate(obj,ch=1) except: raise Exception('Separate failed on object "'+obj+'"!') # Get original names list nameList=[] if origNamesIsMulti: for i in range(mc.getAttr(obj+'.origNames',s=True)): nameList.append( mc.getAttr(obj+'.origNames['+str(i)+']') ) else: for attr in mc.listAttr(obj+'.origNames')[1:]: nameList.append( mc.getAttr(obj+'.origNames.'+attr) ) # Rename separated objects for i in range(len(nameList)): nameList[i] = mc.rename(objs[i],ns+nameList[i]) # Re-Parent separated objects if mc.objExists(obj_parent[0]): mc.parent(nameList[i],obj_parent[0]) elif mc.objExists(ns+'model'): mc.parent(nameList[i],ns+'model') else: mc.parent(nameList[i], w=1 ) # Cleanup: # Removed rename of original objects: Objects that are referenced can't be renamed # orig_child = mc.listRelatives(obj_fPath, c=1, ni=1, pa=True) for i in orig_child: if mc.listRelatives(i): mc.delete(i) # handle namespace mm.eval('setNS("'+scene_ns+'")') return nameList
def separateIntoPlanarElements(name): # Use the automatic UV tool to do the heavy lifting in breaking up the 3d mesh for us cmds.polyAutoProjection('%s.f[0:%i]' % (name, cmds.polyEvaluate(name, f=True)), o=1, p=12) shells = getUVShells(name) for shell in shells: cmds.polyChipOff(shell) elements = cmds.polySeparate( name )[:-1] cmds.delete(elements[0]) # Delete the duplicate mesh return elements[1:]
def hfSplitBadShaded(engines): modifiedShapes = [] for sg in engines: print('checking shading group: ' + sg) cmds.hyperShade(objects=sg) components = cmds.ls(sl=1) uniqueShapes = [] for entry in components: uniqueShapes.append(entry.split('.')[0]) # remove whole shapes (not components) from the list. if entry.rfind('.f') == -1: components.remove(entry) if len(components) > 0: components.sort() # remove duplicates from uniqueShapes. uniqueShapes = list(set(uniqueShapes)) modifiedShapes.extend(uniqueShapes) # print('\nunique shapes under shading group: ') # print(uniqueShapes) for shape in uniqueShapes: cmds.select(cl=1) # get the total num of faces for the shape for later use. totalFaces = cmds.polyEvaluate(shape, f=1) for comp in components: if comp.rfind(shape) != -1: # the current component is a member of the current mesh we're splitting and it has the shader we want. cmds.select(comp, add=1) selFaces = cmds.ls(sl=1) # extract the selected faces if we aren't selecting every face of the current mesh. if len(selFaces) < int(totalFaces) and len(selFaces) > 0: cmds.polyChipOff(selFaces, kft=1, dup=0) cmds.delete(shape, ch=1) # now the mesh is broken into shells. separate it if possible. if cmds.polyEvaluate(shape, s=1) > 1: newObjects = cmds.polySeparate(shape, ch=0) modifiedShapes.extend(newObjects) # print('split new shapes: ') # print(newObjects) cmds.select(newObjects) # print(cmds.ls(sl=1)) cmds.delete(ch=1) cmds.select(cl=1) # now in order to return all the new meshes we made, we should sort through uniqueShapes and remove anything that no longer # exists. anything that's been split, etc. modifiedShapes = list(set(modifiedShapes)) returnShapes = [] for shape in modifiedShapes: if cmds.objExists(shape) == 0: modifiedShapes.remove(shape) meshNodes = cmds.listRelatives(shape, s=1) if meshNodes != None: # if we are not testing an xform, meshNodes will be a 'NoneType' object so we should include an exception. returnShapes.extend(meshNodes) # we're going to get a list of xforms here. we should build a list of shapes and return that for the cleanup op. # print('modified shapes: ') # print(returnShapes) return returnShapes
def combine_separate(): """ Depending on selection will combine or separate objects. Script will try to retain the transforms and outline position of the first object selected. """ def clean_up_object(new): """ Cleans up after `polyUnite` / `polySeparate` """ if not new.get_parent() == parent: new.set_parent(parent) cmds.reorder(str(new), f=True) cmds.reorder(str(new), r=outliner_index) new.transform.set_pivot(pivot) new.attr['rotate'] = list(transforms.rotate) new.attr['scale'] = list(transforms.scale) return cmds.rename(str(new), name.split('|')[-1]) selected = mampy.daglist(os=True, tr=True, l=True) if not selected: raise InvalidSelection() dag = selected.pop() name, parent = dag.short_name, dag.get_parent() transforms = dag.transform.get_transforms() pivot = dag.transform.get_rotate_pivot() if selected: logger.debug('Combining Objects.') for each in selected: if dag.is_child_of(each): raise InvalidSelection('Cannot parent an object to one of its ' 'children') elif dag.is_parent_of(each): continue each.set_parent(each) outliner_index = get_outliner_index(dag) dag.transform.attr['rotate'] = (0, 0, 0) dag.transform.attr['scale'] = (1, 1, 1) if selected: new_dag = Node(cmds.polyUnite(name, selected.cmdslist(), ch=False)[0]) cmds.select(clean_up_object(new_dag), r=True) else: logger.debug('Separate Objects.') new_dags = mampy.daglist(cmds.polySeparate(name, ch=False)) for new in new_dags: cmds.rename(clean_up_object(new), name.split('|')[-1]) cmds.delete(name) cmds.select(new_dags.cmdslist(), r=True)
def seperateGeo(*args): geo = cmds.ls(sl=True)[0] shape = cmds.listRelatives(geo, type="mesh")[0] SGs = list(set(cmds.listConnections(shape, type="shadingEngine"))) for SG in SGs: cmds.select(SG) cmds.polyChipOff(ch=True, kft=True, dup=False) cmds.polySeparate(shape, ch=False) partitionGeos = cmds.listRelatives(geo, c=True, type="transform") for pGeo in partitionGeos: pShape = cmds.listRelatives(pGeo, type="mesh")[0] pSG = cmds.listConnections(pShape, type="shadingEngine")[0] cmds.rename(pGeo, pSG.replace("_lambertSG", "_geo"))
def J_CFXWorkFlow_autoMatchAbc(_sampleSpace=4, separateMesh=False): selectAbcFile = cmds.fileDialog2(fileMode=1, caption="Import clothInfo")[0] if not selectAbcFile.endswith('.abc'): print(selectAbcFile) print 'abc error' return destinationMeshs = J_getAllMeshUnderSelections(cmds.ls(sl=True)[0]) if len(destinationMeshs) < 1: print 'select some mesh' return prFxName = os.path.basename(selectAbcFile).replace('.abc', '') abcNode = '' suffix = 0 trNodeName = prFxName + '_abcCache' + '_' + str(suffix) while cmds.objExists(trNodeName): suffix += 1 trNodeName = prFxName + '_abcCache' + '_' + str(suffix) groupNode = cmds.createNode('transform', name=trNodeName) cmds.setAttr((groupNode + '.visibility'), 0) if selectAbcFile is not None: abcNode = mel.eval('AbcImport -mode import -reparent ' + groupNode + ' \"' + selectAbcFile + '\";') startTime = int(cmds.getAttr(abcNode + '.startFrame')) cmds.currentTime(startTime) allAbcMeshs = cmds.listConnections(abcNode, type='mesh') allAbcAnimationMesh = [] cmds.currentTime(int(cmds.getAttr(abcNode + '.startFrame'))) for meshItem in allAbcMeshs: if cmds.polyEvaluate(meshItem, shell=True) > 1 and separateMesh: separateMeshs = cmds.polySeparate(meshItem) for separateMeshItem in separateMeshs: if cmds.objectType(separateMeshItem, isType='polySeparate'): continue allAbcAnimationMesh.append(separateMeshItem) else: allAbcAnimationMesh.append(meshItem) for meshItem in allAbcAnimationMesh: for destinationMeshItem in destinationMeshs: if J_compareMesh(meshItem, destinationMeshItem, 5): if _sampleSpace < 5: cmds.transferAttributes(meshItem, destinationMeshItem, transferPositions=1, transferNormals=0, transferUVs=0, transferColors=0, sampleSpace=_sampleSpace, sourceUvSpace="map1", targetUvSpace="map1", searchMethod=3, flipUVs=0, colorBorders=1)
def removeShadow(): try: cmds.polySeparate(cmds.ls(g=1)[0], ch=0) except: pass for shape in cmds.ls(g=True): bbox = cmds.exactWorldBoundingBox(shape) if abs(bbox[4] - bbox[1]) <= 1: cmds.delete(cmds.listRelatives(shape, p=1)[0]) else: for i in cmds.ls(assemblies=True): g = cmds.listRelatives(i, type='transform') if g: cmds.select(i) cmds.ungroup() try: cmds.sets(g, e=True, fe='initialShadingGroup') except: pass
def createChunksFromGeo(self, currHair, loopDict): import pprint as pp hairChunksGRP = cmds.createNode("transform", name="{0}_hairChunksGeo_GRP".format( currHair.name())) deleted = False newHair = None justIndexDict = {} for edge in sorted(loopDict.keys()): justIndex = [] for v in loopDict[edge]: justIndex.append(v.index()) justIndexDict[edge] = justIndex for edge in sorted(justIndexDict.keys()): if int(edge) + 1 >= len(justIndexDict): continue if deleted: currHair = pym.PyNode(newHair) hairShape = currHair.getShape().name() hairName = currHair.name() firstLoop = [] secondLoop = [] for vtx in justIndexDict[edge]: firstLoop.append(pym.MeshVertex(currHair, vtx)) for vtx in justIndexDict['{:04d}'.format(int(edge) + 1)]: secondLoop.append(pym.MeshVertex(currHair, vtx)) pym.select(firstLoop + secondLoop) cmds.ConvertSelectionToContainedFaces() cmds.polyChipOff(ch=1, kft=1, dup=1, off=0) hairPieces = cmds.polySeparate(hairShape, rs=1, ch=1) for i in hairPieces: cmds.DeleteHistory(i) cmds.parent(hairPieces[1], hairChunksGRP) cmds.rename(hairPieces[1], "{0}_piece_{1}".format(hairName, edge)) deletable, = cmds.listRelatives(hairPieces[0], p=1) cmds.parent(hairPieces[0], w=1) cmds.delete(deletable) newHair = cmds.rename(hairPieces[0], hairName) deleted = True return hairChunksGRP, newHair
def separate(self): for i in range(len(self.mDags)): shellCount = cm.polyEvaluate(self.mDags[i] , shell=True) if shellCount > 1: separatedObj = cm.polySeparate(self.mDags[i] , ch=False) tmpSel = Om2.MSelectionList() self.mDags[i] = [self.mDags[i]] for obj in separatedObj: tmpSel.clear() tmpSel.add(obj) self.mDags[i].append(tmpSel.getDagPath(0))
def CreateLeaves(self, height, minSize, maxSize): leafBase = cmds.polyPrimitive(r=1, l=1, pt=0)[0] cmds.move(height, y=True) cmds.polyChipOff(dup=False, kft=False) cmds.polyChipOff(dup=False, kft=True, ltz=0.08, ran=1.0) cmds.polyExtrudeFacet(ltz=0.6) cmds.polySmooth() cmds.polySeparate() cmds.xform(cp=True) for leaf in cmds.ls(sl=True): leafScale = round(random.uniform(minSize, maxSize), 3) cmds.select(leaf) cmds.polySoftEdge(a=0, name=leaf) cmds.scale(leafScale, leafScale, leafScale) leafPosition = cmds.xform(leaf, q=True, rp=True, ws=True) leafPosition[1] = height + 0.5 * (height - leafPosition[1]) cmds.xform(leaf, t=leafPosition, ws=True) self.SetRandomLeafColor(leaf) return leafBase
def cutGeo(*args): cutObjs = cmds.ls(sl=True)[:-1] geo = cmds.ls(sl=True)[-1] # for cutObj in cutObjs: for x in range(1, len(cutObjs)): cutObj = cutObjs[x] prevCutObj = cutObjs[x - 1] shape = cmds.listRelatives(geo, type="mesh")[0] cutPlane = cmds.polyPlane(w=3, h=3, sx=1, sy=1, ax=[0, 0, 1], name=cutObj + "_cut_plane")[0] cmds.parent(cutPlane, cutObj, relative=True) cmds.setAttr(cutPlane + ".rotateY", 90) t = cmds.xform(cutPlane, q=True, ws=True, t=True) r = cmds.xform(cutPlane, q=True, ws=True, ro=True) cmds.polyCut(geo, pc=[t[0], t[1], t[2]], ro=[r[0], r[1], r[2]], ef=True, eo=[0, 0, 0]) cutGeos = None try: cutGeos = cmds.polySeparate(shape, ch=False) except: cmds.parent(geo, cutObj) cmds.delete(cutPlane) if cutGeos: for cutGeo in cutGeos: cmds.xform(cutGeo, cp=True) loc = cmds.spaceLocator(name="testing")[0] cmds.parent(loc, cutObj, relative=True) cmds.delete(cmds.pointConstraint(cutGeo, loc, maintainOffset=False)) localX = cmds.getAttr(loc + ".translateX") if round(cmds.xform(loc, q=True, ws=True, translation=True)[0], 2) < 0: # mirrored localX = localX * -1 if localX < 0: parent = prevCutObj else: parent = cutObj geo = cutGeo cmds.parent(cutGeo, parent, absolute=True) cmds.addAttr(cutGeo, ln="cutGeoParent", dt="string") cmds.delete(loc)
def skinInsideFaces(insideFaceList): """ Copy skinCluster weights to inside faces from the outside faces of the same mesh. insideFaceList @param insideFaceList: List of inside faces to copy skinWeights to. @type insideFaceList: list """ # Get Component List By Object objFaceList = glTools.utils.selection.componentListByObject(insideFaceList) # For Each for objFaces in objFaceList: # Get Source Mesh mesh = cmds.ls(objFaces[0], o=True)[0] # Get Face ID List faceIds = glTools.utils.component.getSingleIndexComponentList(objFaces) faceIds = faceIds[faceIds.keys()[0]] # Duplicate Original Mesh mesh_dup = cmds.duplicate(mesh)[0] mesh_dup_children = cmds.ls(cmds.listRelatives(mesh_dup, c=True), transforms=True) if mesh_dup_children: cmds.delete(mesh_dup_children) # Extract Faces from Duplicate faces = [mesh_dup + '.f[' + str(i) + ']' for i in faceIds] extract = cmds.polyChipOff(faces, dup=False, ch=False) separate = cmds.polySeparate(mesh_dup, ch=False) # Transfer Weights to Extracted Mesh copyToMany(mesh, [separate[0]]) copyToMany(separate[0], [separate[1]]) # Transfer Weights from Extracted Mesh srcSkin = glTools.utils.skinCluster.findRelatedSkinCluster(separate[1]) skinData = glTools.data.skinClusterData.SkinClusterData(srcSkin) skinData.remapGeometry(mesh) skinData.rebuildWorldSpaceData(mesh) # Apply Transferred Weights vtxList = cmds.polyListComponentConversion(objFaces, fromFace=True, toVertex=True, internal=False) skinData.loadWeights(componentList=vtxList) # Clean Up cmds.delete(mesh_dup)
def chipOff(obj, ch=0): import re import os import maya.cmds as mc pc = mc.createNode('mesh') obj.append(pc) nobj = mc.polyUnite(obj, ch=ch) mc.rename(nobj[1], "polyChipOff#") sobj = mc.polySeparate(nobj[0]) for i in range(len(obj)): try: mc.rename(obj[i], 'transform#') except: pass mc.rename(sobj[i], obj[i])
def extract_part(self, mesh, polycount): # grow selection cmds.select(mesh+'.f[1]') while cmds.polyEvaluate(tc=True) < polycount: mel.eval('GrowPolygonSelectionRegion;') # extract cmds.polyChipOff(ch=False, kft=True, dup=False, off=False) parts = cmds.polySeparate(mesh, ch=False) # select the mesh with the higher polycount nodes = {} for part in parts: nodes[mesh+'|'+part] = cmds.polyEvaluate(part, f=True) sortList = nodes.values() sortList.sort() key = [key for key in nodes.keys() if nodes[key] == sortList[-1]] cmds.select(key) # return created parts return nodes.keys()
def subtract(self, other): if self.mayaBB is not None and other.mayaBB is not None: #separate cmd.polyChipOff(self.mayaBB + '.f[0:1]', ch=0, kft=1, dup=0, off=0) tempBBPieces = cmd.polySeparate(self.mayaBB, ch=0) #bool cutter = cmd.duplicate(other.mayaBB)[0] tempBBPieces[0] = mel.eval( 'polyCBoolOp -op 2 -ch 0 -classification 2 %s %s' % (tempBBPieces[0], cutter)) cutter = cmd.duplicate(other.mayaBB)[0] tempBBPieces[1] = mel.eval( 'polyCBoolOp -op 2 -ch 0 -classification 2 %s %s' % (tempBBPieces[1], cutter)) #combine self.mayaBB = cmd.polyUnite(tempBBPieces[0], tempBBPieces[1], ch=0, n=self.mayaBB)[0]
def energy(self, objName): """ Calculate the energy of this voxelization""" source = cmds.polySeparate(objName) # cmds.xform(source, cpc=True) selection = OpenMaya.MSelectionList() OpenMaya.MGlobal.getActiveSelectionList(selection) iterSel = OpenMaya.MItSelectionList(selection, OpenMaya.MFn.kMesh) while not iterSel.isDone(): dagPath = OpenMaya.MDagPath() iterSel.getDagPath(dagPath) currentInMeshMFnMesh = OpenMaya.MFnMesh(dagPath) # Create empty point array inMeshMPointArray = OpenMaya.MPointArray() currentInMeshMFnMesh.getPoints(inMeshMPointArray, OpenMaya.MSpace.kWorld) for i in range(inMeshMPointArray.length()): self.output(inMeshMPointArray[i]) mel.eval("print \"\\r\\n\";") iterSel.next()
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 removeStud() : # Remove studs from lego models # Get selected objects sels = mc.ls( sl=True ) for sel in sels : # Separate current mesh mc.select( sel , r=True ) meshes = mc.polySeparate( ch=False ) # Contains mesh's volume as a key and object's name as an element volDct = {} for mesh in meshes : # Computing the object's bounding box mc.select( mesh ) bbox = mc.exactWorldBoundingBox( mesh ) vol = ( ( bbox[3]-bbox[0] ) * ( bbox[4] - bbox[1] ) * ( bbox[5] - bbox[3] ) ) # Making value absolute if vol < 0 : vol = vol*-1 volDct[ vol ] = mesh # Get the biggest mesh last = volDct[ sorted( volDct.keys() )[-1] ] for key in sorted( volDct.keys() ) : curr = volDct[ key ] if not curr == last : mc.delete( curr ) mc.select( sels , r=True )
def createInfluenceObject(*args, **keywords): # Create a skin patch to locally deformed the skin as influence object # The patch can be deformed by blendShape or nCloth # usage: select faces on a skinned object # TBD: mirror (boolean), combine (boolean), layer # TBD: need to preserve one skin cluster having no influence object (joint binded only, rigid shape w/o collision) # for the creation of attract to matching mesh constraint if 'influenceType' not in keywords: raise Exception, "missing argument influenceType" influenceType = keywords['influenceType'] s = cmds.ls(sl=True, l=True) if not s: raise Exception, "no selection" faces = cmds.polyListComponentConversion(s, tf=True, internal=True) obj = cmds.listRelatives(cmds.ls(sl=True, o=True, l=True), p=True, f=True) sc = jc.helper.findTypeInHistory(obj, 'skinCluster') dup = cmds.duplicate(obj) def f(x): return dup[0] + re.search('\..*', x).group(0) faces = map(f, faces) cmds.polyChipOff(faces, ch=True, kft=True, dup=True, off=0) dup = cmds.listRelatives(list(set(cmds.ls(faces, o=True, l=True))), p=True, f=True) objs = cmds.polySeparate(dup, ch=False, rs=True) def f(x): return len(cmds.ls(cmds.polyListComponentConversion(x, tf=True), fl=True, l=True)) face_counts = map(f, objs) cmds.delete(objs[face_counts.index(max(face_counts))]) objs.pop(face_counts.index(max(face_counts))) jts = jc.helper.findTypeInHistory(sc, 'joint') for o in objs: if influenceType == "blendShape": dup = cmds.duplicate(o, rr=True) (x1,y1,z1, x2,y2,z2) = cmds.exactWorldBoundingBox(obj) cmds.move((x2-x1), 0, 0, dup, r=True) # bind objs to sc, then copy skin weights from obj to objs sc2 = cmds.skinCluster(jts, o)[0] cmds.copySkinWeights(ss=sc, ds=sc2, nm=True, sa="closestPoint", ia="closestJoint") if influenceType == "blendShape": bs = cmds.blendShape(dup, o, foc=True) cmds.setAttr(bs[0]+"."+dup[0], 1) elif influenceType == "nCloth": cmds.select(o, r=True) mel.eval("createNCloth 0;") ncloth = cmds.ls(sl=True) if ncloth: ncloth = ncloth[0] cmds.setAttr(ncloth+".inputMeshAttract", 2) cmds.select(o, r=True) jc.clothes.__updateNClothAttribute(cmds.ls(cmds.polyListComponentConversion(o, tv=True), fl=True), "inputMeshAttract", 0.03) cmds.select(cmds.polyListComponentConversion(o, te=True), r=True) cmds.polySelectConstraint(m=2, w=1) cmds.select(cmds.polyListComponentConversion(tv=True), r=True) cmds.polySelectConstraint(m=0, w=0) jc.clothes.__updateNClothAttribute(cmds.ls(sl=True, fl=True), "inputMeshAttract", 1) cmds.setAttr(sc+".useComponents", 1) def f((x,y)): return x-y for o in objs: cmds.skinCluster(sc, e=True, ug=True, dr=99, ps=0, ai=o) pts = [] (x1,y1,z1, x2,y2,z2) = cmds.exactWorldBoundingBox(o) for v in cmds.ls(cmds.polyListComponentConversion(obj, tv=True), fl=True, l=True): outside = True (x,y,z) = cmds.pointPosition(v) if x>x1 and x<x2 and y>y1 and y<y2 and z>z1 and z<z2: for u in cmds.ls(cmds.polyListComponentConversion(o, tv=True), fl=True, l=True): zp = zip([x,y,z], cmds.pointPosition(u)) (dx,dy,dz) = map(f, zp) if abs(dx) < 0.0001 and abs(dy) < 0.0001 and abs(dz) < 0.0001: outside = False break if outside: pts.append(v) if pts: cmds.skinPercent(sc, pts, tv=[o, 0]) return
def cutSkin_reduce(mesh, percent=50): """ Basic mesh cleanup and reduce. @param mesh: Mesh to cleanup and reduce @type mesh: str @param percent: Poly reduce percent amount @type percent: int or float """ # Get Influence Mesh Attributes infProxy = None infProxyAttr = 'influenceProxy' if cmds.objExists(mesh + '.' + infProxyAttr): infProxy = cmds.getAttr(mesh + '.' + infProxyAttr) meshProxy = None meshProxyAttr = 'meshProxy' if cmds.objExists(mesh + '.' + meshProxyAttr): meshProxy = cmds.getAttr(mesh + '.' + meshProxyAttr) # Separate to Shells meshItems = [mesh] try: meshItems = cmds.polySeparate(mesh, ch=False) except: pass # Clean Non-manifold Geometry glTools.utils.mesh.polyCleanup(meshList=meshItems, nonManifold=True, keepHistory=False, fix=True) # Poly Reduce for meshItem in meshItems: try: cmds.polyReduce(meshItem, version=1, # New termination=0, # Percentage termination percentage=percent, sharpness=1, keepBorder=1, keepMapBorder=1, keepColorBorder=0, keepFaceGroupBorder=0, keepHardEdge=0, keepCreaseEdge=0, keepBorderWeight=1, keepMapBorderWeight=1, preserveTopology=1, keepQuadsWeight=1, replaceOriginal=1, cachingReduce=0, constructionHistory=0) except: pass # Cleanup if len(meshItems) > 1: meshResult = cmds.polyUnite(meshItems, ch=False, mergeUVSets=True) if cmds.objExists(mesh): cmds.delete(mesh) mesh = cmds.rename(meshResult, mesh) # Rebuild Influence Mesh Attributes if infProxy and not cmds.objExists(mesh + '.' + infProxyAttr): cmds.addAttr(mesh, ln=infProxyAttr, dt='string') cmds.setAttr(mesh + '.' + infProxyAttr, infProxy, type='string', l=True) if meshProxy and not cmds.objExists(mesh + '.' + meshProxyAttr): cmds.addAttr(mesh, ln=meshProxyAttr, dt='string') cmds.setAttr(mesh + '.' + meshProxyAttr, meshProxy, type='string', l=True) # Return Result return mesh
def main(): facecluster=[] dupobject=[] #return null if no target object specified if maya.textScrollList(targetObjBox,q=True,si=True)==None: return selectface=processFaceSelection() #if not select face, return null if selectface==None: return if maya.radioButtonGrp(snapModeButton,q=True,sl=True)==2: duplicateMode=True grp_dupObj=maya.group(n='grp_dup_transform',em=True) else: duplicateMode=False targetObj=maya.textScrollList(targetObjBox,q=True,si=True)[0] objectname=selectface[0].split('.')[0] #print objectname for com in selectface: #print com if duplicateMode==True: dup_targetObj=maya.duplicate(targetObj,n='dup_'+targetObj) maya.parent(dup_targetObj,grp_dupObj) dup_object=maya.duplicate(objectname,n='dup_'+objectname) dupobject.append(dup_object[0]) #print dupobject raw_data=maya.polyInfo(com,fv=True)[0] #print raw_data #data processing raw_verindex=raw_data.split(':')[1] #print raw_verindex verindex=[] ver_all=raw_verindex.split(' ') #print ver_all for ver in ver_all: if ver != ''and ver != '\n': verindex.append(ver) #print verindex for ver in verindex: #print objectname cluster_temp=maya.cluster(objectname+'.vtx[{0}]'.format(ver),en=True,rel=True) if duplicateMode==True: maya.pointConstraint(cluster_temp,dup_targetObj,o=(0,0,0)) else: maya.pointConstraint(cluster_temp,targetObj,o=(0,0,0)) facecluster.append(cluster_temp) #print facecluster maya.polyChipOff(dup_object[0]+'.'+com.split('.')[1],kft=True,dup=True,off=0,ch=True) grp_obj=maya.polySeparate(dup_object,o=True,n='seperate_'+dup_object[0]) if duplicateMode==True: maya.normalConstraint(grp_obj[1],dup_targetObj,aim=(0,1,0),u=(1,0,0),wut='vector') else: maya.normalConstraint(grp_obj[1],targetObj,aim=(0,1,0),u=(1,0,0),wut='vector') #print T_channel_keyable #print R_channel_keyable if T_channel_keyable: maya.setKeyframe(targetObj,at='translataeX') maya.setKeyframe(targetObj,at='translateY') maya.setKeyframe(targetObj,at='translateZ') maya.delete(targetObj+'_pointConstraint*') if R_channel_keyable: maya.setKeyframe(targetObj,at='rotateX') maya.setKeyframe(targetObj,at='rotateY') maya.setKeyframe(targetObj,at='rotateZ') maya.delete(targetObj+'_normalConstraint*') #print facecluster for cluster in facecluster: #not sure here which to delete?? maya.delete(cluster) for dupObj in dupobject: maya.delete(dupObj)
def doIt(self, argList): # get objects from argument list try: selList = misc.getArgObj(self.syntax(), argList) except: cmds.warning("No object selected!") return # read and check arguments args = vhacd.readArgs(om.MArgParser(self.syntax(), argList)) if (args == None): cmds.error("V-HACD: one or more arguments are invalid!") return # list to hold names of convex decomposition result groups objCD = [] # save processes to parallelize calculations processes = [] # loop over all objects: select, export and convex decomposition for i,obj in enumerate(selList): cmds.select(obj) tmpFile = os.path.abspath('{0}/tmp{1}'.format(args['tmp'], i)) # export current object as *.obj file format cmds.file(tmpFile + '.obj', es = 1, type = "OBJexport", f = 1) # system call to vhacd library with all parameters (use non-blocking subprocess) exeDir, exeName = os.path.split(args['exe']) p = subprocess.Popen([exeName, '--input', tmpFile + '.obj', '--output', tmpFile + '_out.obj', '--log', tmpFile + '.log', '--resolution', str(args['res']), '--depth', str(args['d']), '--concavity', str(args['con']), '--planeDownsampling', str(args['pd']), '--convexhullDownsampling', str(args['chd']), '--alpha', str(args['a']), '--beta', str(args['b']), '--gamma', str(args['g']), '--pca', str(args['pca']), '--mode', str(int(args['mode'])), '--maxNumVerticesPerCH', str(args['vtx']), '--minVolumePerCH', str(args['vol']), ], executable=args['exe']) # save process, current object and index processes.append((p, obj, i)) # loop over all created processes, wait till each one is completed and import result into maya for p, obj, i in processes: p.wait() tmpFile = os.path.abspath('{0}/tmp{1}'.format(args['tmp'], i)) #import OBJ rnn = cmds.file(tmpFile+'_out.obj', type='OBJ', i=True, rnn=True, ns = obj+'_vhacd') cmds.polySeparate(rnn[0], ch=False) # use eval and mel-exclusive command 'catchQuiet' to avoid error messages popping up during file import # cause of error messages: (ma-parser of Maya since version 2012) # mel.eval(' catchQuiet (` file -ra 1 -type "mayaAscii" -rpr "{0}_vhacd" -pmt 0 -i "{1}_out.ma" `) '.format(obj, tmpFile)) # rename created group for convenience # objCD.append(cmds.rename(obj + '_vhacd_root', obj + '_vhacd')) objCD.append(rnn[0]) # delete all temporarily created files # cmds.sysFile(tmpFile + '.mtl', delete = 1) # cmds.sysFile(tmpFile + '.obj', delete = 1) # cmds.sysFile(tmpFile + '.wrl', delete = 1) # cmds.sysFile(tmpFile + '.log', delete = 1) # cmds.sysFile(tmpFile + '_out.ma', delete = 1) # set name of groups (which hold convex decomposition) as result of command for o in objCD: self.appendToResult(o)
def cut_object_with_planes_and_ratios(obj, volume_total, planes, ratios, threshold): # create a list of booleans indicating ratios found or not ratio_found = [] for r in ratios: ratio_found.append(0) ratios.sort() results = [] # a list of objects that volume cannot be match anymore bad_cut_objs = [] all_found = False # initially we have only one object to cut objs_to_cut = [obj] # loop all cut planes for plane in planes: # store all object result from this cut objs_for_next_plane_iteration = [] # for each object in world for i in range(len(objs_to_cut)): #print 'cut object: ' + objs_to_cut[i] mc.select(objs_to_cut[i], r = True) # cut mc.polyCut(pc = plane['pc'], ro = plane['ro'], ef = True, eo = [0, 0, 0]) # fill hole mc.select(objs_to_cut[i], r = True) mc.polyCloseBorder() # separate # if number of pieces < 2, means the plane and the object did not have intersection if mc.polyEvaluate(objs_to_cut[i], shell = True) < 2: # add back this object objs_for_next_plane_iteration.append(objs_to_cut[i]) # continue with other objs_to_cut continue parts = mc.polySeparate(objs_to_cut[i]) # add these parts to future objs to cut objs_for_next_plane_iteration.extend(parts[0:-1]) # for each parts for j in range(len(parts) - 1): this_volume_ratio = mm.eval('meshVolume(\"' + parts[j] + '\")') / volume_total # check volume first_unfound_volume = True for k in range(len(ratios)): if ratio_found[k] == 0: # this part's volume is less than the smallest volume unfound if first_unfound_volume and this_volume_ratio + threshold < ratios[k]: print 'bad volume found, save', this_volume_ratio objs_for_next_plane_iteration.remove(parts[j]) bad_cut_objs.append(parts[j]) break # got match elif abs(this_volume_ratio - ratios[k]) < threshold: print 'volume found: ', this_volume_ratio # dup the object temp = mc.duplicate(parts[j]) mc.select(temp[0], r = True) # move away the duplication mc.move(kMoveAwayXDistance, 0, 0, temp[0]) # add it to the result list results.append(temp[0]) # remove the current object mc.delete(parts[j]) objs_for_next_plane_iteration.remove(parts[j]) # mark volume as found ratio_found[k] = 1 # if all parts found if ratio_found.count(0) == 0: all_found = True break if first_unfound_volume: first_unfound_volume = False if all_found: break if all_found: break objs_to_cut = objs_for_next_plane_iteration if all_found: # todo move back all result obj print 'FFFFFFFFFFFFFFFFFFFFFFFFUUUUUUUUUUUUUUUUUUUUUUUUUU' return results elif len(objs_to_cut) == 0: # no more cuttings but not all_found break # objs_to_cut might be empty due to insufficient planes OR empty if len(objs_to_cut) != 0: bad_cut_objs.extend(objs_to_cut) ratios_remaining = [] for i in range(len(ratio_found)): if ratio_found[i] == 0: ratios_remaining.append(ratios[i]) return {'bad_cut_objs': bad_cut_objs, 'ratios_remaining': ratios_remaining, 'good_cut_objs': results}
def slicePieces(visualize_field, *args): if (len(cmds.ls(sl=True)) == 0): cmds.error("You must have an object selected.") else: object = cmds.ls(sl=True)[0] print "Object: " + object num_verts = cmds.polyEvaluate(object, vertex=True) object_pos = cmds.xform(object, query=True, worldSpace=True, translation=True) object_scale = cmds.xform(object, query=True, relative=True, scale=True) visualize_flag = cmds.checkBox(visualize_field, query=True, value=True) object_latest = cmds.ls(sl=True)[0] object_pos = cmds.xform(object_latest, query=True, worldSpace=True, translation=True) object_scale = cmds.xform(object_latest, query=True, relative=True, scale=True) bbox = cmds.exactWorldBoundingBox(object_latest) min_sc_rad = int( min(bbox[3] - bbox[0], bbox[4] - bbox[1], bbox[5] - bbox[2]) / 2) # minimum scale radius num_edges = cmds.polyEvaluate(object_latest, edge=True) # get random slice plane position and rotation slice_plane_pos = [ object_pos[0] + random.randint(0, min_sc_rad), object_pos[1] + random.randint(0, min_sc_rad), object_pos[2] + random.randint(0, min_sc_rad) ] plane_rotx = random.randint(0, 90) plane_roty = random.randint(0, 90) plane_rotz = random.randint(0, 90) print "Cut plane rotations: " + str(plane_rotx), str(plane_roty), str( plane_rotz) if visualize_flag: # ---- DEBUGGING: DRAW CUT PLANE ---- # cmds.polyPlane(n='plane_visual', w=20, h=20) cmds.xform('plane_visual', worldSpace=True, translation=slice_plane_pos, rotation=(90 + plane_rotx, plane_roty, plane_rotz)) # ----------------------------------- # # slice the mesh cmds.polyCut(object_latest, extractFaces=1, pc=slice_plane_pos, constructionHistory=1, rx=plane_rotx, ry=plane_roty, rz=plane_rotz) new_num_edges = cmds.polyEvaluate(object_latest, edge=True) # fill the openings of the resulting pieces and separate the mesh cmds.select(object_latest + '.e[' + str(num_edges) + ':' + str(new_num_edges) + ']') cmds.polyCloseBorder() cmds.polySeparate(object_latest) pieces = cmds.ls(selection=True) cmds.xform(pieces[0], centerPivots=1) for i in xrange(1, len(pieces)): # center pivot for each piece cmds.xform(pieces[i], centerPivots=1) piece_pos = cmds.xform(pieces[i], query=True, translation=True, worldSpace=True)
def sepGeo(*args): cmds.polySeparate()
selected = pm.ls(sl=True) geometries_poly = cmds.polyListComponentConversion(selected, tf=True) try: cmds.polyChipOff(geometries_poly, kft=False, dup=False) print("ChipOff") except: pass obj_name = [] for obj in geometry: obj_name.append(obj) for i in obj_name: try: cmds.polySeparate(str(i)) print("Separate: " + str(i)) except: pass for mat in materials: cmds.hyperShade(objects=str(mat)) selected = pm.ls(sl=True) for i in range(len(selected)): selected[i] = str(selected[i]).split(".") selected[i] = selected[i][0] try: cmds.polyUnite(selected, ch=0, n=str(mat) + "_model") print("Unite: " + selected[i]) except:
def cutSkin_reduce(mesh, percent=50): ''' Basic mesh cleanup and reduce. @param mesh: Mesh to cleanup and reduce @type mesh: str @param percent: Poly reduce percent amount @type percent: int or float ''' # Get Influence Mesh Attributes infProxy = None infProxyAttr = 'influenceProxy' if mc.objExists(mesh + '.' + infProxyAttr): infProxy = mc.getAttr(mesh + '.' + infProxyAttr) meshProxy = None meshProxyAttr = 'meshProxy' if mc.objExists(mesh + '.' + meshProxyAttr): meshProxy = mc.getAttr(mesh + '.' + meshProxyAttr) # Separate to Shells meshItems = [mesh] try: meshItems = mc.polySeparate(mesh, ch=False) except: pass # Clean Non-manifold Geometry glTools.utils.mesh.polyCleanup(meshList=meshItems, nonManifold=True, keepHistory=False, fix=True) # Poly Reduce for meshItem in meshItems: try: mc.polyReduce( meshItem, version=1, # New termination=0, # Percentage termination percentage=percent, sharpness=1, keepBorder=1, keepMapBorder=1, keepColorBorder=0, keepFaceGroupBorder=0, keepHardEdge=0, keepCreaseEdge=0, keepBorderWeight=1, keepMapBorderWeight=1, preserveTopology=1, keepQuadsWeight=1, replaceOriginal=1, cachingReduce=0, constructionHistory=0) except: pass # Cleanup if len(meshItems) > 1: meshResult = mc.polyUnite(meshItems, ch=False, mergeUVSets=True) if mc.objExists(mesh): mc.delete(mesh) mesh = mc.rename(meshResult, mesh) # Rebuild Influence Mesh Attributes if infProxy and not mc.objExists(mesh + '.' + infProxyAttr): mc.addAttr(mesh, ln=infProxyAttr, dt='string') mc.setAttr(mesh + '.' + infProxyAttr, infProxy, type='string', l=True) if meshProxy and not mc.objExists(mesh + '.' + meshProxyAttr): mc.addAttr(mesh, ln=meshProxyAttr, dt='string') mc.setAttr(mesh + '.' + meshProxyAttr, meshProxy, type='string', l=True) # Return Result return mesh
def setClone(self, *arg): ''' Creating the smear and its associated control ''' self.chainText = cmds.textField(self.chainName, query=True, text=True) # select the arm geo you want to act as the smear, then run this if cmds.objExists(self.chainText + "_smearGeo"): raise KeyError('Please change the name in the text field') else: print "Making geo clones." oldMan = cmds.textField("oldGeo", query=True, text=True) theSea = cmds.textField("theSea", query=True, text=True) Origin = cmds.ls(selection=True) cmds.select(Origin) cmds.polyChipOff(constructionHistory=1, keepFacesTogether=True, duplicate=True, off=0) if cmds.objExists('originalGeo'): cmds.select('originalGeo') cmds.rename('originalGeo_Grp') else: cmds.select(oldMan) cmds.polySeparate() SuperSmear = cmds.ls(selection=True) cmds.select(SuperSmear[0]) print SuperSmear[0] g1 = cmds.rename("originalGeo") cmds.select(SuperSmear[1]) print SuperSmear[1] g2 = cmds.rename(self.chainText + "_smearGeo") del SuperSmear[:] SuperSmear = [g1, g2] cmds.setAttr('originalGeoShape.doubleSided', 0) cmds.setAttr(self.chainText + '_smearGeoShape.doubleSided', 0) # meant to group the new arm geo twice Grp = cmds.group(empty=True, name=self.chainText + "_Clone_Arm_Grp") cmds.parent(Grp, oldMan) Offset = cmds.group(empty=True, name=self.chainText + "_Clone_Arm_Offset") cmds.parent(Offset, Grp) cmds.parent(SuperSmear[1], Offset) cmds.select(clear=True) # Organize the new Transformation Null cmds.select('transform1') theProphet = cmds.rename(self.chainText + '_transform') if cmds.objExists('Smear_DO_NOT_TOUCH'): print "No need for another 'DNT', as one already exists" else: cmds.group(empty=True, name='Smear_DO_NOT_TOUCH') cmds.parent('Smear_DO_NOT_TOUCH', oldMan) Agro = ('Smear_DO_NOT_TOUCH') cmds.parent(theProphet, Agro) cmds.select(clear=True) # Create the adjustment Locator if cmds.objExists(self.chainText + "_smearLoc"): print "Locator exists, proceeding" else: cmds.spaceLocator(name=self.chainText + "_smearLoc") Loc = (self.chainText + "_smearLoc") cmds.parent(Loc, Grp) cmds.parentConstraint(oldMan, Loc, name=self.chainText + "_warpPC") cmds.parentConstraint(theSea, Grp, name=self.chainText + "_warpGrpPC") cmds.select(clear=True) # Connects Locator's translate and rotate attributes to clone arm attributes cmds.connectAttr(self.chainText + '_smearLoc.translate', self.chainText + '_smearGeo.translate') cmds.connectAttr(self.chainText + '_smearLoc.rotate', self.chainText + '_smearGeo.rotate') # Create control for the new arm cmds.curve(degree=1, point=[(0, 0, 3), (2, 0, 2), (3, 0, 0), (2, 0, -2), (0, 0, -3), (-2, 0, -2), (-3, 0, 0), (-2, 0, 2), (0, 0, 3), (0, -2, 2), (0, -3, 0), (0, -2, -2), (0, 0, -3), (0, 2, -2), (0, 3, 0), (0, 2, 2), (0, 0, 3), (0, 0, 0), (-3, 0, 0), (3, 0, 0), (0, 0, 0), (0, -3, 0), (0, 3, 0), (0, 0, 0), (0, 0, -3), (0, 0, 0), (3, 0, 0), (2, 2, 0), (0, 3, 0), (-2, 2, 0), (-3, 0, 0), (-2, -2, 0), (0, -3, 0), (2, -2, 0), (3, 0, 0)], knot=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34]) warpControl = cmds.rename(self.chainText + '_Warp_Ctrl') WarpControlGroup = cmds.group(warpControl, name=self.chainText + '_Warp_Ctrl_Grp') cmds.parent(WarpControlGroup, theSea, relative=True) cmds.parent(WarpControlGroup, world=True) cmds.select(clear=True) if cmds.objExists('Warp_Controls_Group'): print "The host thrives" elif cmds.objExists('Warp_Ctrls_Group'): print "The host thrives" else: cmds.group(empty=True, name='Warp_Ctrls_Group') cmds.parent(WarpControlGroup, 'Warp_Ctrls_Group') cmds.parentConstraint(warpControl, Offset) cmds.scaleConstraint(warpControl, Offset) cmds.setAttr(Offset + '.t', lock=True) cmds.setAttr(Offset + '.r', lock=True) cmds.setAttr(Offset + '.s', lock=True) cmds.setAttr(Offset + '.v', lock=True) cmds.setAttr(Grp + '.t', lock=True) cmds.setAttr(Grp + '.r', lock=True) cmds.setAttr(Grp + '.s', lock=True) cmds.setAttr(Grp + '.v', lock=True) cmds.setAttr(Loc + '.t', lock=True) cmds.setAttr(Loc + '.r', lock=True) cmds.setAttr(Loc + '.s', lock=True) cmds.setAttr(Loc + '.v', 0, lock=True) cmds.setAttr(Agro + '.t', lock=True) cmds.setAttr(Agro + '.r', lock=True) cmds.setAttr(Agro + '.s', lock=True) cmds.setAttr(Agro + '.v', lock=True) cmds.setAttr(theProphet + '.t', lock=True) cmds.setAttr(theProphet + '.r', lock=True) cmds.setAttr(theProphet + '.s', lock=True) cmds.setAttr(theProphet + '.v', lock=True) cmds.select(clear=True) # Connect the smear control to the rig cmds.parentConstraint(theSea, WarpControlGroup, maintainOffset=True) cmds.setAttr(self.chainText + '_Warp_Ctrl.v', lock=True, keyable=False, channelBox=False) cmds.setAttr(self.chainText + '_Warp_Ctrl_Grp.t', lock=True) cmds.setAttr(self.chainText + '_Warp_Ctrl_Grp.r', lock=True) cmds.setAttr(self.chainText + '_Warp_Ctrl_Grp.s', lock=True) cmds.setAttr(self.chainText + '_Warp_Ctrl_Grp.v', lock=True) cmds.setAttr(self.chainText + '_Warp_CtrlShape.overrideDisplayType', 1) print "Please select the group you wish to place the smear pivot control to"