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 bridge(): selected = mampy.complist() if not selected: raise NothingSelected() # Quit early if face selections. if selected[0].type == api.MFn.kMeshPolygonComponent: bridge_face() # Only work on border components for component in get_borders_from_complist(selected): component = component.to_edge(internal=True) connected = list(component.get_connected_components()) # If border is closed or edges are next to each others if len(connected) == 1: border_edge = get_border_loop_indices_from_edge_index(component.index) if border_edge == set(component.indices): cmds.polyCloseBorder(component.cmdslist()) else: cmds.polyAppend( str(component.dagpath), s=1, a=(component.index, component.indices[-1]) ) else: cmds.polyBridgeEdge(divisions=0)
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 priv_doCut( _way, _loc1, _loc2, _object, _crack): # make sure it`s a positive value, a negative value will make pieces grow and overlap if _crack < 0: _crack = 0 _start = [] _end = [] if _way == 0: _start = mc.xform( _loc1, q=True, ws=True, t=True) _end = mc.xform( _loc2, q=True, ws=True, t=True ) else: _start = mc.xform( _loc2, q=True, ws=True, t=True ) _end = mc.xform( _loc1, q=True, ws=True, t=True ) _distFactor = 0.5 + _crack _dir = om.MFloatVector( (_end[0] - _start[0]), (_end[1] - _start[1]), (_end[2] - _start[2]) ) _planePos = om.MFloatVector( _start[0] + (_dir[0] * _distFactor), _start[1] + (_dir[1] * _distFactor), _start[2] + (_dir[2] * _distFactor) ) _dir = _dir.normal() _xrot = - mt.degrees(mt.asin( _dir.y )) _yrot = mt.degrees(mt.atan2( _dir.x, _dir.z )) mc.select( _object, r=True ) #mc.polyCut( constructionHistory=False, deleteFaces=True, cutPlaneCenter=( _planePos.x, _planePos.y, _planePos.z), cutPlaneRotate=( _xrot, _yrot, 0), cch=True ) mc.polyCut( constructionHistory=False, deleteFaces=True, cutPlaneCenter=( _planePos.x, _planePos.y, _planePos.z), cutPlaneRotate=( _xrot, _yrot, 0) ) mc.polyCloseBorder( constructionHistory=False )
def cutObject(object, voronoiPoints): #Create group so we can easily access shards later shards = cmds.group(em=True, name='shards') # Cut according to Voronoi cells for from_point in voronoiPoints: # https://openmaya.quora.com/How-to-implement-Voronoi-with-Python-for-Maya # print(from_point) working_geom = cmds.duplicate(object[0]) cmds.select(working_geom[0]) cmds.parent(working_geom, shards) for to_point in voronoiPoints: if from_point != to_point: locator = cmds.spaceLocator() cmds.move(from_point[0], from_point[1], from_point[2]) cmds.parent(locator, working_geom) center_point = [(e1 + e2) / 2 for (e1, e2) in zip(to_point, from_point)] n = [(e1 - e2) for (e1, e2) in zip(from_point, to_point)] es = cmds.angleBetween(euler=True, v1=[0, 0, 1], v2=n) cmds.polyCut(working_geom, deleteFaces=True, cutPlaneCenter=center_point, cutPlaneRotate=es) cmds.polyCloseBorder(working_geom) cmds.delete(object) return shards
def voronoiFracture( i, j, seeds, shapeCopy ): p1 = cmds.xform( seeds[j], q = True, ws = True, t = True ) p2 = cmds.xform( seeds[i], q = True, ws = True, t = True ) #cutting position planePos = getVecPoint( p1, p2, 0.5 ) #calculate unit vector vec = getVector( p1, p2 ) vecMag = magnitude( vec ) vecNorm = [ 0, 0, 0 ] vecNorm[0] = vec[0] / vecMag vecNorm[1] = vec[1] / vecMag vecNorm[2] = vec[2] / vecMag #calculate cutting angles rX = -math.degrees( math.asin( vecNorm[1])) rY = math.degrees( math.atan2( vecNorm[0], vecNorm[2] )) #cut the shape cmds.select( shapeCopy ) cmds.polyCut( constructionHistory = False, deleteFaces = True, pc = planePos, ro = ( rX, rY, 0 ) ) cmds.polyCloseBorder( constructionHistory = False )
def F(self): # Sets a Keyframe on the focal length of a camera if selected - Just like Shift + w sets a keyframe on the move attr if self.getType(0)[1] == 'CAMERA': currentCamera = self.getSelection() cmds.setKeyframe(str(currentCamera[0]) + '.fl') if self.getType(0) == 'edge': cmds.polyCloseBorder() if self.getType(0) == 'vertex': self.flattenVertex()
def F (self): # Sets a Keyframe on the focal length of a camera if selected - Just like Shift + w sets a keyframe on the move attr if self.getType(0)[1] == 'CAMERA': currentCamera = self.getSelection() cmds.setKeyframe(str(currentCamera[0]) + '.fl') if self.getType(0) == 'edge': cmds.polyCloseBorder() if self.getType(0) == 'vertex': self.flattenVertex()
def ncsc_get_borders_fix(): """A fix solution for the open borders """ sel = mc.ls(sl=True) if sel: for obj in sel: mc.polyCloseBorder(obj, ch=1) mc.select(clear=True)
def voronoiShatter(obj, n, pShowProgress,id): # random point placement for polycut operation vPoints = getVoronoiPoints(obj,n) # create new group for shards cmds.setAttr(obj+'.visibility',0) shardGroup = cmds.group( em=True, name = obj + '_chunks_'+str(id) ) cmds.undoInfo(state = False) cmds.setAttr(str(obj) + '.visibility',0) step = 0 if pShowProgress: cmds.progressWindow(title = "Voronoi Calculating", progress = 0, isInterruptable = True, maxValue = n) cmds.undoInfo(state = False) for vFrom in vPoints: if pShowProgress: if cmds.progressWindow(q = True, isCancelled=True): break if cmds.progressWindow(q = True, progress = True) >= n: break step = step + 1 cmds.progressWindow(edit=True, progress = step, status=("Shattering step %d of %d completed..." % (step, n))) cmds.refresh() tempObj = cmds.duplicate(obj) if tempObj: cmds.setAttr(str(tempObj[0]) + '.visibility',1) cmds.parent(tempObj,shardGroup) for vTo in vPoints: if vFrom != vTo: aim = [(v1-v2) for (v1,v2) in zip(vFrom,vTo)] vCenter = [(v1 + v2)/2 for (v1,v2) in zip(vTo,vFrom)] planeAngle = cmds.angleBetween( euler = True, v1=[0,0,1], v2=aim ) cmds.polyCut(tempObj[0], df = True, cutPlaneCenter = vCenter, cutPlaneRotate = planeAngle) cmds.polyCloseBorder(tempObj[0], ch = False) cmds.xform(tempObj, cp = True) cmds.xform(shardGroup) cmds.undoInfo(state = True) cmds.progressWindow(endProgress=1) ConnectDynamic.addNewRigidBodies(id)
def cutCell(obj, mat, pos, rot, shardsGRP): #do the cut procedure tocut = mc.polyEvaluate(obj, face = True) mc.polyCut( ('%s.f[0:%d]'% (obj,tocut)), pc = (pos[0], pos[1], pos[2]), ro = (rot[0], rot[1], rot[2]), ch = False, df = True) cutFaces = mc.polyEvaluate(obj, face = True) mc.polyCloseBorder(obj, ch = False) newFaces = mc.polyEvaluate(obj, face = True) newFaces = newFaces - cutFaces #assign material to faces for face in range(newFaces): mc.sets( ( '%s.f[ %d ]' % (obj, (cutFaces + newFaces - 1))), forceElement = ('%sSG' % (mat)), e = True)
def cutMeshBool(mesh,boundingObject): ''' Cut a specified mesh by applying a boolean intersect operation. @param mesh: The mesh to cut based on a bounding geometry @type mesh: str @param boundingObject: The object to intersect @type boundingObject: str ''' # ========== # - Checks - # ========== # Check Mesh if not mc.objExists(mesh): raise Exception('Mesh "'+mesh+'" does not exist!') if not glTools.utils.mesh.isMesh(mesh): raise Exception('Object "'+mesh+'" is not a valid mesh!') # Check Bounding Mesh if not mc.objExists(boundingObject): raise Exception('Bounding object "'+boundingObject+'" does not exist!') if not glTools.utils.mesh.isMesh(boundingObject): raise Exception('Bounding object "'+boundingObject+'" is not a valid mesh!') # ============ # - Cut Mesh - # ============ # Get Prefix prefix = glTools.utils.stringUtils.stripSuffix(boundingObject) # Triangulate Bounding Mesh mc.polyTriangulate(boundingObject,ch=False) # Cut Mesh cutMesh = mc.polyBoolOp(mesh,boundingObject,op=3,n=prefix+'Cut') if not cutMesh: raise Exception('Boolean intersection failed!') cutMesh = mc.rename(cutMesh[0],prefix+'Geo') # Cleanup mc.polyCloseBorder(cutMesh,ch=False) # ================= # - Return Result - # ================= return cutMesh
def cutCell(obj, mat, pos, rot, shardsGRP): #do the cut procedure tocut = mc.polyEvaluate(obj, face=True) mc.polyCut(('%s.f[0:%d]' % (obj, tocut)), pc=(pos[0], pos[1], pos[2]), ro=(rot[0], rot[1], rot[2]), ch=False, df=True) cutFaces = mc.polyEvaluate(obj, face=True) mc.polyCloseBorder(obj, ch=False) newFaces = mc.polyEvaluate(obj, face=True) newFaces = newFaces - cutFaces #assign material to faces for face in range(newFaces): mc.sets(('%s.f[ %d ]' % (obj, (cutFaces + newFaces - 1))), forceElement=('%sSG' % (mat)), e=True)
def pinocchioObjExport(mesh, objFilePath): loadObjPlugin() savedSel = cmds.ls(sl=1) try: if not isATypeOf(mesh, 'geometryShape'): subShape = getShape(mesh) if subShape: mesh = subShape if not isATypeOf(mesh, 'geometryShape'): raise TypeError('cannot find a geometry shape for %s' % mesh) meshDup = addShape(mesh) cmds.polyCloseBorder(meshDup, ch=0) cmds.polyTriangulate(meshDup, ch=0) cmds.select(meshDup, r=1) cmds.file(objFilePath, op="groups=0;ptgroups=0;materials=0;smoothing=0;normals=0", typ="OBJexport", es=True, f=1) cmds.delete(meshDup) finally: cmds.select(savedSel) return objFilePath
def polyCloseBorder(*args, **kwargs): res = cmds.polyCloseBorder(*args, **kwargs) if not kwargs.get('query', kwargs.get('q', False)): res = _factories.maybeConvert(res, _general.PyNode) return res
import maya.cmds as mc import maya.mel as mel oEdges = mc.ls(sl=True) oObj = oEdges[0].split('.')[0] oFace = '' for i in oEdges: if '.f[' in i: oFace = i mc.DetachComponent() mc.select(cl=True) mc.select(oFace) mc.ConvertSelectionToShell() oFacesFinal = mc.ls(sl=True) mc.select(oObj) mc.polyMergeVertex(d=0.0001) mc.select(oFacesFinal) mc.selectType(smp=0, sme=0, smf=1, smu=0, pv=0, pe=0, pf=1, puv=0) mc.hilite(oObj, r=True) mel.eval('doDelete;') mc.select(oObj, r=True) mc.polyCloseBorder()
cmds.setAttr(str(workingGeom[0])+'.visibility', 1) cmds.parent(workingGeom, allShards) for endPoint in voroPoints: if startPoint != endPoint: # Construct line segments and calculate the mid point and its normal dirVec = [(pt2-pt1) for (pt1, pt2) in zip(startPoint, endPoint)] centerPoint = [(pt1 + pt2)/2 for (pt1, pt2) in zip(startPoint, endPoint)] planeAngle = cmds.angleBetween( euler=True, v1=[0,0,1], v2=dirVec ) # Cut Geometry (Bullet shatter) cmds.polyCut(workingGeom[0], deleteFaces=True, cutPlaneCenter = centerPoint, cutPlaneRotate = planeAngle) # Applying the material to the cut faces originalFaces = cmds.polyEvaluate(workingGeom[0], face=True) cmds.polyCloseBorder(workingGeom[0], ch=False) resultingFaces = cmds.polyEvaluate(workingGeom[0], face=True) newFaces = resultingFaces - originalFaces cutFaces = ( '%s.f[ %d ]' % (workingGeom[0], (resultingFaces + originalFaces - 1))) cmds.sets(cutFaces, forceElement = (surfaceMat + 'SG'), e=True) cmds.xform(workingGeom, cp=True) print str(workingGeom) cmds.xform(allShards, cp=True) cmds.progressWindow(endProgress=1) cmds.undoInfo(state = True) # Create set of rigid bodies
def slicer(pObj, pNumCuts): bb = mc.exactWorldBoundingBox() ymin = bb[1] ymax = bb[4] ocx = mc.objectCenter(x=True) ocy = mc.objectCenter(y=True) ocz = mc.objectCenter(z=True) sliceht = [ymin] #Cut into parts, still same object for i in range(1, pNumCuts): sht = round(ymin + i * ((ymax - ymin) / pNumCuts), 2) mc.polyCut(pObj, cutPlaneCenter=[ocx, sht, ocz], cutPlaneRotate=[90, 0, 0], extractFaces=True, extractOffset=[0, 0, 0]) sliceht.append(sht) #separate each part into different objects objList = mc.polySeparate(pObj) sliceht.append(ymax) #to store the parts in each place - dictionary #index represents slice number places = {} #initialize each slice with an empty list for i in range(pNumCuts): places[i] = [] partList = [] i = 0 #close border and rename each part, and keep track of parts for part in objList: try: mc.polyCloseBorder(part) #get part's bounding box pbb = mc.polyEvaluate(part, b=True) #to see if bbox is returned or a message saying "Nothing is..." is returned if (pbb[0] != 'N'): mc.rename(part, 'part' + str(i)) #just need max/min y of part, so pbb[1] required #part's min y pm = round(pbb[1][0], 2) #part's max y pM = round(pbb[1][1], 2) #find which slice the part belongs to pl = place(pm, pM, sliceht) #add the new part to the places dictionary to the right slice places[pl].append('part' + str(i)) i += 1 except RuntimeError: break #combine parts at same slice level for key in places: #if a slice has more than one part if (len(places[key]) > 1): #combine parts in slice numbered "key", name it something unique mc.polyUnite(*places[key], n='unite' + str(key)) #initialize newpart to this newly created object newpart = 'unite' + str(key) #else there's no need for combining anything else: newpart = places[key] #rename each new part to coll<key> where key is the slice number mc.rename(newpart, 'coll' + str(key)) #add this new collection to the partList partList.append('coll' + str(key)) return partList
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 splitMesh(mesh, assetName): """ Take the given mesh and break it into chunks based on the influence weights of each bone. For example, if the mesh was a leg that was skinned to a thigh bone, a calf bone, and a foot bone, this function will split the leg mesh into three new meshes, one for each major influence. This is sometimes known as an "anim mesh" :param mesh: name of mesh to split up :param assetName: name of character or rig (the name given on publish) :return: a list of the newly created meshes """ # get mesh's skinCluster skinCluster = riggingUtils.findRelatedSkinCluster(mesh) # get the influences in that skinCluster influences = cmds.skinCluster(skinCluster, q=True, inf=True) # create a group if it doesn't exist if not cmds.objExists(assetName + "_animMeshGrp"): cmds.group(empty=True, name=assetName + "_animMeshGrp") newMeshes = [] # loop through each influence, creating a mesh for that influnece is applicable for influence in influences: # create a new mesh if cmds.objExists(mesh + "_" + influence): cmds.warning("Mesh with name: " + mesh + "_" + influence + " already exists. Skipping.") else: newMesh = cmds.duplicate(mesh, name=mesh + "_" + influence)[0] # unlock attrs so we can add a constraint later for attr in [".tx", ".ty", ".tz", ".rx", ".ry", ".rz"]: cmds.setAttr(newMesh + attr, lock=False) # if there is only 1 influence, constrain the entire mesh as is if len(influences) <= 1: cmds.parentConstraint(influence, newMesh, mo=True) # otherwise, loop through each influence getting the components affected by that influence else: verts = [] notWeighted = [] for i in range(cmds.polyEvaluate(mesh, v=True)): value = cmds.skinPercent(skinCluster, mesh + ".vtx[" + str(i) + "]", transform=influence, q=True) if value > 0.5: verts.append(newMesh + ".vtx[" + str(i) + "]") else: notWeighted.append(newMesh + ".vtx[" + str(i) + "]") # if the amount of non-weighted verts is the same as the number of verts in the mesh, delete the mesh. if len(notWeighted) == cmds.polyEvaluate(mesh, v=True): cmds.delete(newMesh) if verts: # select all verts cmds.select(newMesh + ".vtx[*]") # Convert the selection to contained faces if len(verts) != cmds.polyEvaluate(mesh, v=True): # unselect the verts we want to keep, convert remaining to faces and delete cmds.select(verts, tgl=True) cmds.select( cmds.polyListComponentConversion(fv=True, tf=True, internal=False)) cmds.delete() # constrain mesh to influence, parent mesh to group cmds.parentConstraint(influence, newMesh, mo=True) cmds.parent(newMesh, assetName + "_animMeshGrp") # fill holes, triangulate, and smooth normals cmds.polyCloseBorder(newMesh, ch=False) cmds.polyTriangulate(newMesh, ch=False) cmds.polySoftEdge(newMesh, a=90, ch=False) newMeshes.append(newMesh) return (newMeshes)
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 makeBarrel(*args): #Molding and Shaping first Plank cmds.polyCube( sx=8, sy=8, sz=4, h=20 ) cmds.scale( 1, 1, 0.3 ) cmds.select('pCube1.e[32:39]', 'pCube1.e[128:135]', 'pCube1.e[420:423]', 'pCube1.e[472:475]') cmds.softSelect(ssd=19, sud=0.5) cmds.move( 0, 0, -2, relative = True) cmds.softSelect(ssd=12.5, sud=0.5) cmds.scale(1.4,1,1) cmds.softSelect(ssd=5, sud=0.2) cmds.select('pCube1.e[56:63]', 'pCube1.e[104:111]', 'pCube1.e[432:435]', 'pCube1.e[484:487]') cmds.scale(1.05,1,1) cmds.select('pCube1.e[8:15]', 'pCube1.e[152:159]', 'pCube1.e[408:411]', 'pCube1.e[460:463]') cmds.scale(1.05,1,1) cmds.sets('pCube1', addElement = toBeGrouped) #Moving WholePlank & Duplication Process cmds.select('pCube1.vtx[4]') cmds.softSelect(ssd=500, sud=1) cmds.move(-cmds.pointPosition('pCube1.vtx[4]')[0], -cmds.pointPosition('pCube1.vtx[4]')[1], -cmds.pointPosition('pCube1.vtx[4]')[2], relative = True) cmds.move(0,0,-4, rotatePivotRelative = True, relative = True) cmds.select('pCube1') cmds.rename('pCube1', 'BarrelPlank1') i=0 while (i < 23): cmds.duplicate(returnRootsOnly = True) cmds.rotate(0,15,0, relative = True) i = i+1 #Creates Metal Rings With Variation #Chance of Top Four Top Rings i = 0 numbOfTopRings = rand.randint(1,4) openLoc = [0,0,0,0] while (i < numbOfTopRings): location = rand.randint(0,3) while (openLoc[location] == 1): location = rand.randint(0,3) if(location == 0): #0 cmds.softSelect(ssd=5, sud=0.2) cmds.polyTorus(sx=20, sy=8, r=1, sr=0.01) cmds.move(0,19.5,0,relative = True) cmds.scale(4.55,45.1,4.55, relative = True) cmds.select('pTorus1.e[40:59]') cmds.softSelect(ssd=1.05, sud = 0.2) cmds.scale(0.97, 0.97, 0.97, relative = True) cmds.sets('pTorus1', addElement = toBeGrouped) cmds.rename('pTorus1', 'MetalRing1') openLoc[location] = 1 elif(location == 1): #1 cmds.softSelect(ssd=5, sud=0.2) cmds.polyTorus(sx=20, sy=8, r=1, sr=0.01) cmds.move(0,18,0,relative = True) cmds.scale(4.83,45.1,4.83, relative = True) cmds.select('pTorus1.e[40:59]') cmds.softSelect(ssd=1.05, sud = 0.2) cmds.scale(0.97, 0.97, 0.97, relative = True) cmds.sets('pTorus1', addElement = toBeGrouped) cmds.rename('pTorus1', 'MetalRing1') openLoc[location] = 1 elif(location == 2): #2 cmds.softSelect(ssd=5, sud=0.2) cmds.polyTorus(sx=20, sy=8, r=1, sr=0.01) cmds.move(0,16.5,0,relative = True) cmds.scale(5.05,60,5.05, relative = True) cmds.select('pTorus1.e[40:59]') cmds.softSelect(ssd=1.05, sud = 0.2) cmds.scale(0.97, 0.97, 0.97, relative = True) cmds.sets('pTorus1', addElement = toBeGrouped) cmds.rename('pTorus1', 'MetalRing1') openLoc[location] = 1 else: #3 cmds.softSelect(ssd=5, sud=0.2) cmds.polyTorus(sx=20, sy=8, r=1, sr=0.01) cmds.move(0,12.5,0,relative = True) cmds.scale(5.45,70,5.45, relative = True) cmds.select('pTorus1.e[40:59]') cmds.softSelect(ssd=1.05, sud = 0.2) cmds.scale(0.98, 0.98, 0.98, relative = True) cmds.sets('pTorus1', addElement = toBeGrouped) cmds.rename('pTorus1', 'MetalRing1') i += 1 #Guarented bottom ring then a change of two others #Guarented cmds.softSelect(ssd=5, sud=0.2) cmds.polyTorus(sx=20, sy=8, r=1, sr=0.01) cmds.move(0,0.45,0,relative = True) cmds.scale(4.55,45.1,4.55, relative = True) cmds.select('pTorus1.e[120:139]') cmds.softSelect(ssd=1.05, sud = 0.2) cmds.scale(0.97, 0.97, 0.97, relative = True) cmds.sets('pTorus1', addElement = toBeGrouped) cmds.rename('pTorus1', 'MetalRing1') i = 0 numbOfTopRings = rand.randint(0,2) openLoc = [0,0] while (i < numbOfTopRings): location = rand.randint(0,1) while (openLoc[location] == 1): location = rand.randint(0,1) if(location == 0): #0 cmds.softSelect(ssd=5, sud=0.2) cmds.polyTorus(sx=20, sy=8, r=1, sr=0.01) cmds.move(0,3.8,0,relative = True) cmds.scale(5.12,60,5.12, relative = True) cmds.select('pTorus1.e[120:139]') cmds.softSelect(ssd=1.05, sud = 0.2) cmds.scale(0.97, 0.97, 0.97, relative = True) cmds.sets('pTorus1', addElement = toBeGrouped) cmds.rename('pTorus1', 'MetalRing1') openLoc[location] = 1 else: #1 cmds.softSelect(ssd=5, sud=0.2) cmds.polyTorus(sx=20, sy=8, r=1, sr=0.01) cmds.move(0,5.5,0,relative = True) cmds.scale(5.38,60,5.38, relative = True) cmds.select('pTorus1.e[120:139]') cmds.softSelect(ssd=1.05, sud = 0.2) cmds.scale(0.97, 0.97, 0.97, relative = True) cmds.sets('pTorus1', addElement = toBeGrouped) cmds.rename('pTorus1', 'MetalRing1') openLoc[location] = 1 i += 1 #Make the lid and bottom #Bottom cmds.polyCube(sx=2, sy = 1, sz = 1, h = 0.143, d = 8.07) cmds.sets('pCube1', addElement = toBeGrouped) cmds.move(0,0.143,0) #Create planks off of first i = 0 while (i < 4): if(i<4): cmds.duplicate(returnRootsOnly = True) cmds.move(1.01,0,0, relative = True) i = i+1 #Shape Planks into rounded bottom cmds.softSelect(sse=0) def shapeLidPlank(plank,scale1,scale2,scale3): #ScalesPlankEdges i = 0 while (i < 2): selectCube = cmds.format('pCube^1s.e', stringArg=(plank)) cmds.select("{0}[{1}]".format(selectCube,8), "{0}[{1}]".format(selectCube,11), "{0}[{1}]".format(selectCube,14), "{0}[{1}]".format(selectCube,17)) cmds.scale(1, 1, scale1, relative = True) cmds.select("{0}[{1}]".format(selectCube,9), "{0}[{1}]".format(selectCube,12), "{0}[{1}]".format(selectCube,15), "{0}[{1}]".format(selectCube,18)) cmds.scale(1, 1, scale2, relative = True) cmds.select("{0}[{1}]".format(selectCube,10), "{0}[{1}]".format(selectCube,13), "{0}[{1}]".format(selectCube,16), "{0}[{1}]".format(selectCube,19)) cmds.scale(1, 1, scale3, relative = True) i = i+1 shapeLidPlank(2,0.997351,0.98069,0.962469) shapeLidPlank(3,0.963,0.925,0.885) shapeLidPlank(4,0.8835,0.8,0.7) shapeLidPlank(5,0.698,0.4,0.2) cmds.select('pCube5.f[1]','pCube5.f[3]','pCube5.f[5]','pCube5.f[7:8]') cmds.delete() cmds.polyCloseBorder('pCube5.e[5]', 'pCube5.e[7]', 'pCube5.e[9]', 'pCube5.e[11]') #mirror half of the lid cmds.polyUnite('pCube1','pCube2','pCube3','pCube4','pCube5') cmds.delete(ch = True) cmds.polyMirrorFace( 'polySurface1', direction=0, mergeMode=1 ) cmds.sets('polySurface1', addElement = toBeGrouped) cmds.rename('polySurface1', 'LidBottom') #Decide To create top & Where to Place Top lidOn = 0 if(cmds.radioButtonGrp(queryDic['lidControl'], q=True, select=True)==3): lidOn = rand.randint(0,4) if(cmds.radioButtonGrp(queryDic['lidControl'], q=True, select=True)==1 or lidOn > 0): #createTop cmds.duplicate(returnRootsOnly = True) cmds.polyCube(w = 7.433, h = 0.13) cmds.move(0,0,0.973) cmds.select('pCube1.e[8:9]') cmds.scale(1.07,1,1, relative = True) cmds.polyMirrorFace( 'pCube1', direction = 0, mergeMode=1, axis = 2 ) cmds.polyUnite( 'pCube1', 'LidBottom1', n='Lid' ) cmds.sets('Lid', addElement = toBeGrouped) cmds.rename('Lid', 'LidTop') cmds.delete(ch = True) cmds.delete('LidBottom1') lidLocRan = 0 if(cmds.radioButtonGrp(queryDic['lidLoc'], q=True, select=True)==4): lidLocRan = rand.randint(1,3) if(cmds.radioButtonGrp(queryDic['lidLoc'], q=True, select=True)==1 or lidLocRan==1): cmds.move(0,19.5,0) elif(cmds.radioButtonGrp(queryDic['lidLoc'], q=True, select=True)==2 or lidLocRan==2): cmds.move(0,19.5,0) cmds.rotate(0,rand.random()*359,rand.random()*16, r=True, ws = True) cmds.rotate(0,rand.random()*359,0, r=True, ws = True) elif(cmds.radioButtonGrp(queryDic['lidLoc'], q=True, select=True)==3 or lidLocRan==3): cmds.rotate(0,rand.random()*359, 98.852097) cmds.move(6.2,4.3,0) #Finaly Group everything in the toBeGrouped set and cleanup cmds.select( toBeGrouped ) cmds.group( n='Barrel1' ) cleanUp()
def cutToMesh(mesh,boundingObject,offset=0.0): ''' Cut a specified mesh by using the faces of another mesh object. Mesh cut planes are defined by each face center and normal of the bounding object. @param mesh: The mesh to cut based on a bounding box @type mesh: str @param boundingObject: The object to use as the cut bounding box @type boundingObject: str @param offset: The amount of normal offset to apply before creating each cut. @type offset: float ''' # ========== # - Checks - # ========== # Check Mesh if not mc.objExists(mesh): raise Exception('Mesh "'+mesh+'" does not exist!') if not glTools.utils.mesh.isMesh(mesh): raise Exception('Object "'+mesh+'" is not a valid mesh!') # Check Bounding Mesh if not mc.objExists(boundingObject): raise Exception('Bounding object "'+boundingObject+'" does not exist!') if not glTools.utils.mesh.isMesh(boundingObject): raise Exception('Bounding object "'+boundingObject+'" is not a valid mesh!') # ============ # - Cut Mesh - # ============ # Undo OFF mc.undoInfo(state=False) # Get face iterator faceIt = glTools.utils.mesh.getMeshFaceIter(boundingObject) # Cut Mesh at each Face faceIt.reset() while not faceIt.isDone(): # Get Face position and normal pt = faceIt.center(OpenMaya.MSpace.kWorld) n = OpenMaya.MVector() faceIt.getNormal(n,OpenMaya.MSpace.kWorld) faceIt.next() # Offset Cut Point n.normalize() pt += (n*offset) cutPt = [pt[0],pt[1],pt[2]] # ============================== # - Convert Normal to Rotation - # ============================== up = OpenMaya.MVector(0,1,0) # Check upVector if abs(n*up) > 0.9: up = OpenMaya.MVector(0,0,1) # Build Rotation rotateMatrix = glTools.utils.matrix.buildRotation( aimVector = (n[0],n[1],n[2]), upVector = (up[0],up[1],up[2]), aimAxis = '-z', upAxis = 'y' ) rotate = glTools.utils.matrix.getRotation(rotateMatrix) # Cut Mesh mc.polyCut(mesh,ch=False,df=True,pc=cutPt,ro=rotate) mc.polyCloseBorder(mesh,ch=False) # Set Selection mc.select(mesh) # Undo ON mc.undoInfo(state=True) # ================= # - Return Result - # ================= return mesh
def drawBranch(iteration, cX, cY, cZ, nrX, nrY, nrZ, radius, length,old_circle,ShereBool): if(iteration < branches): iteration = iteration + 1 print("iteration= "+str(iteration)) #Draw circle and extrude based on parameters R=radius*math.fabs(math.sin(iteration)) R=radius+iteration-math.fabs(iteration) R=10-iteration circle( nr=(nrX, nrY, nrZ), c=(cX, cY, cZ), r=radius) shape = cmds.ls(sl=True)[0] circleReffArr.append(shape) cmds.select( clear=True ) cmds.select( old_circle, add=True ) cmds.select( shape, add=True ) cmds.loft( c=0, ch=1, d=3, ss=1, rsn=True, ar=1, u=1, rn=0, po=0) extrudedSurface = cmds.ls(sl=True)[0] print("nrX= "+str(nrX)+" nrY= "+str(nrY)+" nrZ= "+str(nrZ)) if(0==True): cmds.polySphere(createUVs=2, sy=20, ch=1, sx=20, r=radius*10) SpherePoly = cmds.ls(sl=True)[0] cmds.move( cX, cY, cZ, SpherePoly, absolute=True ) #extrudedSurface=extrude (shape, et=0, d= (nrX, nrY, nrZ), l= length) #extrudedSurface=extrude (shape, extrudeType=0, d= (nrX, nrY, nrZ), l= length,polygon=1) #extrudedSurface=extrude (shape, extrudeType=0, d= (nrX, nrY, nrZ), l= length) cmds.nurbsToPoly(extrudedSurface, uss=1, ch=1, ft=0.01, d=0.1, pt=0, f=0, mrt=0, mel=0.001, ntr=0, vn=3, pc=1000, chr=0.9, un=3, vt=1, ut=1, ucr=0, cht=0.01, mnd=1, es=0, uch=0) delete(extrudedSurface) #print("extrudedSurface= "+str(extrudedSurface)) extrudedPoly = cmds.ls(sl=True)[0] print("extrudedPoly= "+str(extrudedPoly)) cmds.polyCloseBorder(extrudedPoly, ch=1)# Close Holl hollface = cmds.ls(sl=True)[0] print("hollface= "+str(hollface)) cmds.polyTriangulate(hollface, ch=1) cmds.select(extrudedPoly) #cmds.polyClean(extrudedPoly) #cmds.eval('polyCleanupArgList 4 { "0","1","1","1","1","1","1","1","0","1e-05","0","1e-05","0","1e-05","0","1","1","0" };') #Delete the base circle, keep the cylinder #delete(shape) #Define direction vector and normalize vector = MVector(nrX, nrY, nrZ) vector.normalize() cX = cX + (length*vector.x) cY = cY + (length*vector.y) cZ = cZ + (length*vector.z) randX = random.randint(0, 1)*2 -1 randY = random.randint(0, 1)*2 -1 randZ = random.randint(0, 1)*2 -1 #Random direction vector #For X, Y, Z, ( -1 or 1 )*angle + (randint from -angleVariance to +angleVariance) nrX = nrX + ((angle*randX) + random.randint(0, angleVariance*2) - angleVariance)/100.0 nrY = nrY + ((angle*randY) + random.randint(0, angleVariance*2) - angleVariance)/100.0 nrZ = nrZ + ((angle*randZ) + random.randint(0, angleVariance*2) - angleVariance)/100.0 #Length and Radius based on factor + (randint from -variance to +variance) length = length * (lengthFactor + (random.randint(0, lengthVariance*2*100)/100.0) - lengthVariance) radius = radius * (radiusFactor + (random.randint(0, radiusVariance*2*100)/100.0) - radiusVariance) #Draw first branch drawBranch(iteration, cX, cY, cZ, nrX, nrY, nrZ, radius, length,shape,False) #drawBranch(iteration, cX, cY, cZ, 0, 1, 0, radius, length,shape,False) #-------------------- #Use opposite base angle from previous branch nrX = nrX + ((angle*randX*-1) + random.randint(0, angleVariance*2) - angleVariance)/100.0 nrY = nrY + ((angle*randY*-1) + random.randint(0, angleVariance*2) - angleVariance)/100.0 nrZ = nrZ + ((angle*randZ*-1) + random.randint(0, angleVariance*2) - angleVariance)/100.0 length = length * (lengthFactor + (random.randint(0, lengthVariance*2*100)/100.0) - lengthVariance) radius = radius * (radiusFactor + (random.randint(0, radiusVariance*2*100)/100.0) - radiusVariance) #Draw second branch drawBranch(iteration, cX, cY, cZ, nrX, nrY, nrZ, radius, length,shape,True)
verticesForRelax = cmds.ls(selection=True, flatten=True) cmds.polyAverageVertex(verticesForRelax, iterations=100) mel.eval( "selectType -smp 0 -sme 0 -smf 0 -smu 0 -pv 0 -pe 1 -pf 0 -puv 0;") cmds.select(clear=True) #################################################### #### MAYA WINDOW #### #################################################### #Check if there are 4 edges or more in the loop selection if (len(originalSelection)) == 4: cmds.select(originalSelection) cmds.polyCloseBorder() if (len(originalSelection)) == 6: cmds.select(originalSelection) cmds.select(originalSelection[0], originalSelection[1], originalSelection[3], originalSelection[4]) cmds.polyBridgeEdge(divisions=0) if (len(originalSelection)) == 8: cmds.select(originalSelection) cmds.select(originalSelection[0], originalSelection[1], originalSelection[2], originalSelection[4], originalSelection[5], originalSelection[6]) cmds.polyBridgeEdge(divisions=0) if lessTenCheck == "True":