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 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 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 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 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 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 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 foldCorner( degree=30, lightPos=(1, 10, -1), fileName='D:/OneDrive - HKUST Connect/20Spring_UROP/3D-Modeling/Texture/foldCorner.obj' ): mc.select(all=True) if mc.ls(sl=True) != []: mc.delete() # clear all items from workspace myPlane = mc.polyPlane(sx=10, sy=15, w=15, h=20, name='myPlane') piv1 = mc.pointPosition('myPlane.vtx[24]') mc.move(0, 0, 0, myPlane) mc.rotate(0, -45, 0, myPlane, a=True, p=(piv1[0], piv1[1], piv1[2]), ws=True, fo=True) mc.select('myPlane.f[0:1]', 'myPlane.f[10:11]') mc.polyCut(cd='X', ch=1) piv2 = mc.pointPosition('myPlane.vtx[12]') mc.select('myPlane.f[0:1]', 'myPlane.f[10]') mc.rotate(0, 0, -degree, a=True, p=(piv2[0], piv2[1], piv2[2]), ws=True, fo=True) mc.rotate(0, 0, 0, myPlane, a=True, p=(piv1[0], piv1[1], piv1[2]), ws=True, fo=True) addPointLight(lightPos) exportObj(fileName)
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 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 main(): rgb = pickColor() uvList = getUV() faceList = getFaces() # null starting values should be left at 1 coordCount = 1 # selct the geometry & get the number of coords to check cmds.select(geometryName[0]) coords = cmds.polyEvaluate(uv=True) selectedUVs = [] compareUVs = [] picked = [] # for each UV coordinate found for uv in uvList: # define inital values for selected color from color picker r = 0.0 b = 0.0 g = 0.0 # define rgb values from each uv coord rPick = rgb[0] gPick = rgb[1] bPick = rgb[2] # if the coord count is NOT equal to the total number of coords to check...keep checking if coordCount != coords: # get the float rgb values for each color coord rSample = cmds.colorAtPoint(str(textureName[0]), o='RGB',u=uv[0], v=uv[1])[0] gSample = cmds.colorAtPoint(str(textureName[0]), o='RGB',u=uv[0], v=uv[1])[1] bSample = cmds.colorAtPoint(str(textureName[0]), o='RGB',u=uv[0], v=uv[1])[2] # round values and convert to 0 to 255 rPoint = round(rSample * 255) gPoint = round(gSample * 255) bPoint = round(bSample * 255) # print the coord that is currently being checked # subtract the coord from the total coords to get the remaining coordRemain = int(coords) - 1 # compare coord color to picked color if rPoint == rPick and gPoint == gPick and bPoint == bPick: # if the color matches, add the uv coord to the list of selected # if the coord color value matches the picked value, add the coorffd to the selected uv list selectedUVs.append(uv) # if the coord count is not yet equal to the total number of coords, continue processing coords if coordCount != coords: # add 1 to the total completed coordCount += 1 # print the percentage remaining complete = float(coordCount) / float(coords) * float(100) remaining = float(100)-complete rounded = round(remaining) if rounded < 1: print ('finishing') else: print (str(rounded) +'% remaining') # if the coordCount becomes equal to the number of coords, compare each list if coordCount == coords: # get the bounding box for the list of all the faces in geometry for bounds in faceList[0]: xFace = bounds[0] yFace = bounds[1] xFaceMin = xFace[0] xFaceMax = xFace[1] yFaceMin = yFace[0] yFaceMax = yFace[1] # we have a list of uvs with the color selected for youvee in selectedUVs: # now we need to compare each colored uv location with the face bounding boxes. if xFaceMin <= youvee[0] <= xFaceMax and yFaceMin <= youvee[1] <= yFaceMax: compareUVs.append(youvee) # we lost the name of the face when comparing the matched uv with the bounds of the face. # we get the matched uv list and recheck it against the face bounds and then select the face. for i in compareUVs: xUV = i[0] yUV = i[1] for face in faceList[1]: cmds.select(face) boundsCheck = cmds.polyEvaluate(bc2=True) xFace = boundsCheck[0] yFace = boundsCheck[1] xFaceMin = xFace[0] xFaceMax = xFace[1] yFaceMin = yFace[0] yFaceMax = yFace[1] if xFaceMin <= xUV <= xFaceMax and yFaceMin <= yUV <= yFaceMax: # if the UV bounds falls inside of the Facebounds, append the face to the picked list picked.append(face) # print the picked list, and select each face inside of it. print 'picked = ' + str(picked) for p in picked: cmds.polyCut(p)
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 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 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 CreateBranch(self, radius, height, subdivisionHeight1, subdivisionHeight2, subdivisionDelta1, subdivisionDelta2, branchScale1, branchScale2, branch): cmds.softSelect(sse=0) trunkTransform, trunkConstructor = cmds.polyCylinder(r=radius, h=height, sx=8, sy=1, sz=1, ax=(0, 1, 0), ch=True) cmds.sets(trunkTransform, e=True, forceElement=self.trunkMaterial) #MOVE TO CENTER cmds.move(0, height * 0.5, 0, trunkTransform, a=True) #SCALE DOWN TOP VERTICES cmds.select(clear=True) for vertex in range(8, 16): cmds.select('%s.vtx[%s]' % (trunkTransform, vertex), add=True) cmds.scale(0.25, 0.25, 0.25, p=(0, height, 0)) #MAKE TRUNK SUB-DIVISIONS cmds.select(trunkTransform) cmds.polyCut(pc=[0, subdivisionHeight1, 0], ro=[90, 0, 0], ef=True, eo=[0, 0, 0]) cmds.select(trunkTransform) cmds.polyCut(pc=[0, subdivisionHeight2, 0], ro=[90, 0, 0], ef=True, eo=[0, 0, 0]) #TRANSFORM SUBDIVIONS branchScale = branchScale1 cmds.select(clear=True) for vertex in range(18, 34): cmds.select('%s.vtx[%s]' % (trunkTransform, vertex), add=True) cmds.move(subdivisionDelta1[0], subdivisionDelta1[1], subdivisionDelta1[2], r=True) cmds.scale(branchScale, branchScale, branchScale, r=True) if branch == 1: subdivisionDelta2 = [ x + y for x, y in zip( subdivisionDelta1, self.GetDelta(math.pi / 2.0, 2 * math.pi, 1.0, 2.0)) ] branchScale = branchScale2 cmds.select(clear=True) for vertex in range(34, 50): cmds.select('%s.vtx[%s]' % (trunkTransform, vertex), add=True) cmds.move(subdivisionDelta2[0], subdivisionDelta2[1], subdivisionDelta2[2], r=True) cmds.scale(branchScale, branchScale, branchScale, r=True) #cmds.rotate(-subdivisionDelta2[2] * 30, subdivisionDelta2[1], subdivisionDelta2[0] * 30, r = True, os = True) #MOVE TOP topDelta = [] if branch == 1: topDelta = self.GetDelta(0.0, 2 * math.pi, 0.0, 1.0) topDelta[1] = round(random.uniform(-0.1, 1.5), 3) else: topDelta = self.GetDelta(0.0, 2 * math.pi, 1.0, 2.5) topDelta[1] = round(random.uniform(0.5, 2.0), 3) topDelta = [x + y for x, y in zip(subdivisionDelta2, topDelta)] cmds.select(clear=True) for vertex in range(8, 16) + range(17, 18): cmds.select('%s.vtx[%s]' % (trunkTransform, vertex), add=True) cmds.move(topDelta[0], topDelta[1], topDelta[2], r=True) cmds.scale(0.6, 0.6, 0.6, r=True) #Remove bottom part cmds.select(clear=True) for face in range(0, 16): cmds.select('%s.f[%s]' % (trunkTransform, face), add=True) if branch == 3: for face in range(24, 32): cmds.select('%s.f[%s]' % (trunkTransform, face), add=True) cmds.delete() return trunkTransform
def polyCut(*args, **kwargs): res = cmds.polyCut(*args, **kwargs) if not kwargs.get('query', kwargs.get('q', False)): res = _factories.maybeConvert(res, _general.PyNode) return res
def main(): rgb = pickColor() uvList = getUV() faceList = getFaces() # null starting values should be left at 1 coordCount = 1 # selct the geometry & get the number of coords to check cmds.select(geometryName[0]) coords = cmds.polyEvaluate(uv=True) selectedUVs = [] compareUVs = [] picked = [] # for each UV coordinate found for uv in uvList: # define inital values for selected color from color picker r = 0.0 b = 0.0 g = 0.0 # define rgb values from each uv coord rPick = rgb[0] gPick = rgb[1] bPick = rgb[2] # if the coord count is NOT equal to the total number of coords to check...keep checking if coordCount != coords: # get the float rgb values for each color coord rSample = cmds.colorAtPoint(str(textureName[0]), o='RGB', u=uv[0], v=uv[1])[0] gSample = cmds.colorAtPoint(str(textureName[0]), o='RGB', u=uv[0], v=uv[1])[1] bSample = cmds.colorAtPoint(str(textureName[0]), o='RGB', u=uv[0], v=uv[1])[2] # round values and convert to 0 to 255 rPoint = round(rSample * 255) gPoint = round(gSample * 255) bPoint = round(bSample * 255) # print the coord that is currently being checked # subtract the coord from the total coords to get the remaining coordRemain = int(coords) - 1 # compare coord color to picked color if rPoint == rPick and gPoint == gPick and bPoint == bPick: # if the color matches, add the uv coord to the list of selected # if the coord color value matches the picked value, add the coorffd to the selected uv list selectedUVs.append(uv) # if the coord count is not yet equal to the total number of coords, continue processing coords if coordCount != coords: # add 1 to the total completed coordCount += 1 # print the percentage remaining complete = float(coordCount) / float(coords) * float(100) remaining = float(100) - complete rounded = round(remaining) if rounded < 1: print('finishing') else: print(str(rounded) + '% remaining') # if the coordCount becomes equal to the number of coords, compare each list if coordCount == coords: # get the bounding box for the list of all the faces in geometry for bounds in faceList[0]: xFace = bounds[0] yFace = bounds[1] xFaceMin = xFace[0] xFaceMax = xFace[1] yFaceMin = yFace[0] yFaceMax = yFace[1] # we have a list of uvs with the color selected for youvee in selectedUVs: # now we need to compare each colored uv location with the face bounding boxes. if xFaceMin <= youvee[ 0] <= xFaceMax and yFaceMin <= youvee[ 1] <= yFaceMax: compareUVs.append(youvee) # we lost the name of the face when comparing the matched uv with the bounds of the face. # we get the matched uv list and recheck it against the face bounds and then select the face. for i in compareUVs: xUV = i[0] yUV = i[1] for face in faceList[1]: cmds.select(face) boundsCheck = cmds.polyEvaluate(bc2=True) xFace = boundsCheck[0] yFace = boundsCheck[1] xFaceMin = xFace[0] xFaceMax = xFace[1] yFaceMin = yFace[0] yFaceMax = yFace[1] if xFaceMin <= xUV <= xFaceMax and yFaceMin <= yUV <= yFaceMax: # if the UV bounds falls inside of the Facebounds, append the face to the picked list picked.append(face) # print the picked list, and select each face inside of it. print 'picked = ' + str(picked) for p in picked: cmds.polyCut(p)
def cut_at_y(obj_name, y_val): cmds.polyCut(obj_name, pc=[-999, y_val, 999], ro=[90, -90, 0]) edge_num = cmds.polyEvaluate(obj_name, e=True) return "{}.e[{}]".format(obj_name, edge_num)
height = 1.5 width = 2.0 depth = width #Make turret shape: turret = cmds.polyCube(name="turret", h=height, w=width, d=depth) cmds.move(0, height / 2, 0) cmds.select(turret[0] + '.f[1]') cmds.scale(0.1, 0.1, 0, xz=True) cmds.select(turret[0] + '.f[3]', r=True) cmds.delete() cmds.select(turret[0]) #Add rows to turret: for rowNumber in range(1, numberOfRows): cmds.polyCut(rx=90, pcy=rowNumber * height / numberOfRows) #Add tiles to turret: for i in range(2): for rowNumber in range(numberOfRows): for tileNumber in range(1, numberOfRows - rowNumber): #Create lists of all faces in turret: list1 = [] list2 = [] numberOfFaces = cmds.polyEvaluate('turret', f=True) for faceNumber in range(numberOfFaces): list1.append(turret[0] + '.f[' + str(faceNumber) + ']') list2.append(turret[0] + '.f[' + str(faceNumber) + ']') #Remove all faces not in the current row from list2:
def Voronoi(uvs, selection): try: originalName = selection mcSelection = getSelectionSurface(selection)[0] surface = getSelectionSurface(selection)[1] except (IndexError): return centers = [ WS_from_UV(uv, surface) for uv in uvs if WS_from_UV(uv, surface)[0] ] newFaces = [] #create progress bar progressBarWindow = utils.pyside.SimpleProgressBar( "Voronoi Cells", "Dividing 0/{0}".format(len(centers))) progressBarWindow.show() #setting cursor to wait cursor utils.pyside.qw.QApplication.setOverrideCursor( utils.pyside.qc.Qt.WaitCursor) for i, from_point in enumerate(centers): working_geom = mc.duplicate(mcSelection) for to_point in centers: if from_point != to_point: print "**** Cut " locator = mc.spaceLocator() mc.move(from_point[0], from_point[1], from_point[2]) mc.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 = mc.angleBetween(euler=True, v1=[0, 0, 1], v2=n) mc.polyCut(working_geom, deleteFaces=True, cutPlaneCenter=center_point, cutPlaneRotate=es) # RandomColors mc.setAttr(working_geom[0] + '.displayColors', 1) mc.polyOptions(working_geom[0], cm='diffuse') mc.polyColorPerVertex(working_geom[0], rgb=utils.geo.random_color(i)) newFaces.append(working_geom[0]) #update progressbar progressBarWindow.updateLabel("Dividing {0}/{1}".format( i, len(centers))) progressBarWindow.updateProgress( len(centers) / (i + 1.0) * 100.0) #removing progressbar utils.pyside.qw.QApplication.restoreOverrideCursor() progressBarWindow.hide() progressBarWindow.deleteLater() mc.delete(mcSelection) scalp = mc.polyUnite(newFaces, n=originalName) mc.polyMergeVertex(scalp, d=0.25)
workingGeom = cmds.duplicate(obj) cmds.select(workingGeom[0]) #cmds.rigidBody(active=True, mass=5, bounciness=0.08, collisions=False) #RigidBody.CreateRigidBody(True).executeCommandCB() 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)
def cutToBoundingBox(mesh,boundingObject,offset=0.0): ''' Cut a specified mesh by another geometries bounding box. @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 offset to apply before creating each cut. @type offset: float ''' # ========== # - Checks - # ========== 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!') if not mc.objExists(boundingObject): raise Exception('Bounding object "'+boundingObject+'" does not exist!') # ========================= # - Get Bounding Box Info - # ========================= bBox = glTools.utils.base.getMBoundingBox(boundingObject) center = bBox.center() minPt = bBox.min() min = [minPt[0]-offset,minPt[1]-offset,minPt[2]-offset] maxPt = bBox.max() max = [maxPt[0]+offset,maxPt[1]+offset,maxPt[2]+offset] # ============ # - Cut Mesh - # ============ # -Z mc.polyCut(mesh,ch=False,df=True,pc=[center[0],center[1],min[2]],ro=[0,0,0]) # +Z mc.polyCut(mesh,ch=False,df=True,pc=[center[0],center[1],max[2]],ro=[180,0,0]) # -X mc.polyCut(mesh,ch=False,df=True,pc=[min[0],center[1],center[2]],ro=[0,90,0]) # +X mc.polyCut(mesh,ch=False,df=True,pc=[max[0],center[1],center[2]],ro=[0,-90,0]) # -Y mc.polyCut(mesh,ch=False,df=True,pc=[center[0],min[1],center[2]],ro=[-90,0,0]) # +Y mc.polyCut(mesh,ch=False,df=True,pc=[center[0],max[1],center[2]],ro=[90,0,0])
def CreateTrunk(self, radius, height, subdivisionHeight1, subdivisionHeight2, subdivisionDelta1, subdivisionDelta2, sd1Scale, sd2Scale): cmds.softSelect(sse=0) trunkTransform, trunkConstructor = cmds.polyCylinder(r=radius, h=height, sx=8, sy=1, sz=1, ax=(0, 1, 0), ch=True) cmds.sets(trunkTransform, e=True, forceElement=self.trunkMaterial) #MOVE TO CENTER cmds.move(0, height * 0.5, 0, trunkTransform, a=True) #SCALE DOWN TOP VERTICES cmds.select(clear=True) for vertex in range(8, 16): cmds.select('%s.vtx[%s]' % (trunkTransform, vertex), add=True) cmds.scale(0.2, 0.2, 0.2, p=(0, height, 0)) #MAKE TRUNK SUB-DIVISIONS cmds.select(trunkTransform) cmds.polyCut(pc=[0, subdivisionHeight1, 0], ro=[90, 0, 0], ef=True, eo=[0, 0, 0]) cmds.select(trunkTransform) cmds.polyCut(pc=[0, subdivisionHeight2, 0], ro=[90, 0, 0], ef=True, eo=[0, 0, 0]) #TRANSFORM SUBDIVIONS cmds.select(clear=True) for vertex in range(18, 34): cmds.select('%s.vtx[%s]' % (trunkTransform, vertex), add=True) cmds.move(subdivisionDelta1[0], subdivisionDelta1[1], subdivisionDelta1[2], r=True) cmds.scale(sd1Scale, sd1Scale, sd1Scale, r=True) #cmds.rotate(subdivisionDelta1[2] * 30, subdivisionDelta1[1], -subdivisionDelta1[0] * 30, r = True, os = True) cmds.select(clear=True) for vertex in range(34, 50): cmds.select('%s.vtx[%s]' % (trunkTransform, vertex), add=True) cmds.move(subdivisionDelta2[0], subdivisionDelta2[1], subdivisionDelta2[2], r=True) cmds.scale(sd2Scale, sd2Scale, sd2Scale, r=True) #cmds.rotate(-subdivisionDelta2[2] * 30, subdivisionDelta2[1], subdivisionDelta2[0] * 30, r = True, os = True) #SCALE UP BOTTOM VERTICES cmds.select(clear=True) for vertex in range(0, 8): cmds.select('%s.vtx[%s]' % (trunkTransform, vertex), add=True) cmds.scale(1.4, 1.4, 1.4, p=(0, 0, 0)) return trunkTransform