def a_ring(): ring_diameter = 22 # outer diameter ring_thickness = 1.5 divit_diameter = 1.5 divit_depth = .75 ring_height = 4 #divit_spacing = .5 divits = [] cmds.polyPipe(radius=ring_diameter/2, height=ring_height*2, thickness=ring_thickness, name='ring0') cmds.setAttr( 'polyPipe1.subdivisionsAxis', 20 ) for x in range(0,6): for y in range(0,3): letter = initials[x] symbol = letter[y] myName = "_c" + str(x) + str(y) if symbol == 0 : cmds.polyCylinder(axis=[0,0,1], radius=(divit_diameter/2), height=divit_depth, name=myName) elif symbol == 2: cmds.polyCylinder(axis=[0,0,1], radius=(divit_diameter/2), height=ring_thickness * 2.1, name=myName) if symbol != 1: divits.append(myName) y_off = 0 cmds.move(0,y_off,(ring_diameter/2 - divit_depth/2 + .3),myName) cmds.rotate(0,(x*3+y)*20,0,myName, pivot=[0,0,0]) rn = 0; for d in divits[:]: print 'ring' + str(rn) + " " + d cmds.polyBoolOp('ring' + str(rn), d, op=2, n='ring' + str(rn+1), ) rn += 1
def cut_one_with_one(cutter, target): print 'Cutting 1:1 %s with %s' % (target, cutter) # Duplicate targets targetA = cmds.duplicate(target, returnRootsOnly=True)[0] targetB = cmds.duplicate(target, returnRootsOnly=True)[0] prep(targetA) prep(targetB) cmds.delete(target) # Set up cutters cutterA = cmds.duplicate(cutter, returnRootsOnly=True)[0] cutterB = cmds.duplicate(cutter, returnRootsOnly=True)[0] prep(cutterA) prep(cutterB) # Flip second cutter's normals cmds.polyNormal(cutterB, normalMode=0, userNormalMode=0, constructionHistory=0) # Perform intersections newTargetA = cmds.polyBoolOp(cutterA, targetA, op=3, constructionHistory=False)[0] newTargetB = cmds.polyBoolOp(cutterB, targetB, op=3, constructionHistory=False)[0] return [newTargetA, newTargetB]
def createCrossAxel(): length = createMainAxel("CrossAvelWidth") cmds.select(cu[0]) cmds.scale(1, 1, 1.5) sideCylin1 = cmds.polyCylinder(r=0.4, h=length, sz=12, sx=12, sy=12) cmds.rotate(90, 0, 0) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(sideCylin1[0], cu[0], op=2, n="block", ch=False) Tor = cmds.polyTorus(sx=2, sy=2, r=0.377, sr=0.037) cmds.rotate(90, 0, 0) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(Tor[0], cu[0], op=1, n="block", ch=False) Tor2 = cmds.polyTorus(sx=2, sy=2, r=0.377, sr=0.037) cmds.rotate(90, 0, 0) cmds.move(length / 3.2, moveZ=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(Tor2[0], cu[0], op=1, n="block", ch=False) Tor3 = cmds.polyTorus(sx=2, sy=2, r=0.377, sr=0.037) cmds.rotate(90, 0, 0) cmds.move(-1 * (length / 3.2), moveZ=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(Tor3[0], cu[0], op=1, n="block", ch=False) cmds.select(cu[0]) cmds.rotate(0, 0, 45) distance1 = 0.33 distance2 = 0.35 createSideEdgesAxel(length, distance1, distance2)
def createSideEdgesAxel(length, distance1, distance2): cyl1 = cmds.polyCylinder(r=0.15, h=length + 0.1, sz=4, sy=24) cmds.rotate(90, 0, 0) cmds.move((distance1), moveY=True, a=True) cmds.move((distance2), moveX=True, a=True) cmds.move((-1 * (0.003)), moveZ=True, a=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(cu[0], cyl1[0], op=2, n="block", ch=False) cyl2 = cmds.polyCylinder(r=0.15, h=length + 0.1, sz=4, sy=12) cmds.rotate(90, 0, 0) cmds.move((distance1), moveY=True, a=True) cmds.move((-1 * (distance2)), moveX=True, a=True) cmds.move((-1 * (0.003)), moveZ=True, a=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(cu[0], cyl2[0], op=2, n="block", ch=False) cyl3 = cmds.polyCylinder(r=0.15, h=length + 0.1, sz=4, sy=12) cmds.rotate(90, 0, 0) cmds.move((-1 * (distance1)), moveY=True, a=True) cmds.move((distance2), moveX=True, a=True) cmds.move((-1 * (0.003)), moveZ=True, a=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(cu[0], cyl3[0], op=2, n="block", ch=False) cyl4 = cmds.polyCylinder(r=0.15, h=length + 0.1, sz=4, sy=12) cmds.rotate(90, 0, 0) cmds.move((-1 * (distance1)), moveY=True, a=True) cmds.move((-1 * (distance2)), moveX=True, a=True) cmds.move((-1 * (0.003)), moveZ=True, a=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(cu[0], cyl4[0], op=2, n="block", ch=False)
def cleanUp(self): ''' This is impossible without an external script. Maya's booleans are to finnicky to work with and make the mesh just disappear. :( ''' #union all together, and smooth!! #works range 0-6 for sectNum in range(0, self.val - 1): #for sectNum in range(0, 2): #Unions pairs of two branches into "sections" if sectNum == 0: firstB = "Tree_trunk_" + str(sectNum) #Tree_trunk_0 secondB = "Tree_trunk_" + str(sectNum + 1) #Tree_trunk_1 cmds.polyBoolOp(firstB, secondB, op=1, n="sect_" + str(sectNum)) #sect_0 else: lastSect = "sect_" + str(sectNum - 1) nextB = "Tree_trunk_" + str(sectNum + 1) cmds.polyBoolOp(lastSect, nextB, op=1, n="sect_" + str(sectNum))
def booleanLoop(): #1. Make an array of all selections target = mc.ls(sl=1) #2. Boolean union each item in the array to the next for i in range(0,len(target)-1,2): mc.polyBoolOp(target[i],target[i+1]) #3. Delete construction history mc.delete(ch=True) #4. Recenter the pivot mc.xform(cp=True)
def Fond(Stre, Freq, Ampl, colors={222, 202, 163}): cmds.file(f=True, new=True) # Stre=cmds.floatSliderGrp(field_strenth,q=True,v=True) # Freq=cmds.floatSliderGrp(field_frequency,q=True,v=True) # Ampl=cmds.floatSliderGrp(field_amplitude,q=True,v=True) #---------Creation Objet--------# cmds.polyCube(w=20, d=20, h=8, sx=80, sz=80, name="roche") #20 20 / 50 cmds.polySphere(r=10, sa=60, sy=60, name="contenant") #8 / 12 cmds.move(0, 6.5, 0, "contenant") cmds.polyBoolOp('contenant', 'roche', op=3, n='fond') cmds.delete(ch=True) cmds.move(0, -4, 0, "fond") #---------Selection Face--------# for i in range(0, 1707): cmds.select("fond.f[" + str(i) + "]", add=True) sl = cmds.ls(sl=True) #---------Texture Deformer--------# td = cmds.textureDeformer(s=Stre, ps="World", name="Textu".format(sl)) n = cmds.shadingNode("noise".format(sl), asTexture=True) #--------Attributre Noise-------# cmds.setAttr("noise1.threshold", 0.014) cmds.setAttr("noise1.amplitude", Ampl) cmds.setAttr("noise1.ratio", 0.15) cmds.setAttr("noise1.frequency", Freq) cmds.setAttr("noise1.falloff", 1) cmds.connectAttr(n + ".outColor", td[0] + ".texture", force=True) Color = cmds.shadingNode('aiStandardSurface', name="colo", asShader=True) cmds.setAttr("colo.specular", 0) cmds.setAttr(Color + ".baseColor", colors[0], colors[1], colors[2]) cmds.select("fond", hi=True, add=True) cmds.hyperShade(assign=Color) #cmds.window() #cmds.columnLayout() #sliderStrenght=cmds.floatSliderGrp(field=True,label="Strenth",minValue=0,maxValue=3,value=1.5,w=400) #sliderFreq=cmds.floatSliderGrp(field=True,label="Frequency",minValue=0,maxValue=1,value=0.3,w=400) #sliderAmplitude=cmds.floatSliderGrp(field=True,label="Amplitude",minValue=0,maxValue=1,value=0.4,w=400) #cmds.button(label="Fond", c="Fond()") #cmds.showWindow()
def generate(cls, *args): components = [] boolean = [] width = cmds.intSliderGrp(cls.get_prefix() + Labels["width_label"], query=True, value=True) rgb = cmds.colorSliderGrp(cls.get_prefix() + Labels["color_label"], query=True, rgbValue=True) block_width = width * Constants["block_width_unit"] block_height = Constants["block_height_unit"] block_depth = Constants["block_depth_unit"] for x in range(0, width): stub = cmds.polyCylinder(name=get_unique_name(cls.get_prefix(), "Stub"), radius=Constants["stub_radius"], height = Constants["stub_height"]) components.append(stub[0]) cmds.move(Constants["block_width_unit"] * x + half(Constants["block_width_unit"]), half(Constants["block_height_unit"]) + half(Constants["stub_height"]), half(Constants["block_depth_unit"]), stub[0]) for x in range(0, width-1): hole = cmds.polyCylinder(name=get_unique_name(cls.get_prefix(), "Hole"), radius=Constants["perforation_radius"], height=Constants["block_depth_unit"] + 0.2) boolean.append(hole[0]) cmds.rotate('90deg', 0, 0, hole[0]) cmds.move(Constants["block_width_unit"] * x + Constants["block_width_unit"], 0, half(Constants["block_depth_unit"]), hole[0]) cube = cmds.polyCube(sx=5,sy=2,sz=2,name=get_unique_name(cls.get_prefix(), "block"), width=block_width, height=block_height, depth=block_depth) components.append(cube[0]) cmds.move(half(width * Constants["block_width_unit"]), 0, half(Constants["block_depth_unit"]), cube) solid = cmds.polyUnite(components, name=get_unique_name(cls.get_prefix(), "")) boolean_group = cmds.polyUnite(boolean, name=get_unique_name(cls.get_prefix(),"boolean")) final = cmds.polyBoolOp( solid[0], boolean_group[0], op=2, n=get_unique_name(cls.get_prefix(), "") ) shader = cmds.shadingNode('blinn', asShader=True, name=get_unique_name(cls.get_prefix(),"mat")) cmds.setAttr(shader + ".color", rgb[0],rgb[1],rgb[2], type='double3') cmds.select(final[0], r=True) cmds.hyperShade(assign=shader)
def insertDots(self): # copy dot object # copy cutout object # run mesh difference # delete the layers # delete the groups # rename the cutout. for dot in self.dots: # Copy sphere object from the template object. newDot = cmds.duplicate(self.getTemplateObjectName(dot.templateName()))[0] for cutout in dot.cutouts: # Copy cutout object from the template object, and rotate it. newCutout = cmds.duplicate(self.getTemplateObjectName(cutout.shape))[0] cutoutDagPath = self.getDagPathFromPath(newCutout) mfnTransform = OpenMaya.MFnTransform(cutoutDagPath) mfnTransform.rotateBy(cutout.rotation, OpenMaya.MSpace.kTransform) # Mesh boolean combine, with 'difference' operator. boolOp = cmds.polyBoolOp(newDot, newCutout, op=2) # Update the dot copy name and remove history. newDot = boolOp[0] cmds.delete(newDot, constructionHistory=True) dotPath = "dot_{0}".format(dot.name()) cmds.rename(newDot, dotPath) # Move the new dot onto the final grid for printing. self.positionDot(dotPath, dot.vertexId)
def generate_kink_peice(cls, block_width): components = [] boolean = [] for x in range(0, block_width + 1): hole = cmds.polyCylinder(name=get_unique_name(cls.get_prefix(), "Hole"), radius=Constants["perforation_radius"], height=Constants["block_depth_unit"] + 0.2) boolean.append(hole[0]) cmds.rotate('90deg', 0, 0, hole[0]) cmds.move(Constants["block_width_unit"] * x , 0, half(Constants["block_depth_unit"]), hole[0]) cube = cmds.polyCube(sx=5,sy=2,sz=2,name=get_unique_name(cls.get_prefix(), "block"), width=block_width, height=Constants["block_height_unit"], depth=Constants["block_depth_unit"]) components.append(cube[0]) cmds.delete(cube[0] + ".f[40:47]") cmds.move(half(block_width * Constants["block_width_unit"]), 0, half(Constants["block_depth_unit"]), cube) #caps cap_one = cmds.polyCylinder(sc=1, sy=2, radius=half(Constants["block_height_unit"]), height=Constants["block_depth_unit"],name=get_unique_name(cls.get_prefix(), "cap")) cmds.rotate('90deg',0,0,cap_one[0]) cmds.move(0,0,half(Constants["block_depth_unit"]),cap_one[0]) cmds.delete(cap_one[0] + ".f[0:3]", cap_one[0] + ".f[14:23]", cap_one[0] + ".f[34:43]", cap_one[0] + ".f[54:63]", cap_one[0] + ".f[74:79]") components.append(cap_one[0]) #caps cap_two = cmds.polyCylinder(sc=1, sy=2, radius=half(Constants["block_height_unit"]), height=Constants["block_depth_unit"]) cmds.rotate('90deg','180deg',0,cap_two[0]) cmds.delete(cap_two[0] + ".f[0:3]", cap_two[0] + ".f[14:23]", cap_two[0] + ".f[34:43]", cap_two[0] + ".f[54:63]", cap_two[0] + ".f[74:79]") cmds.move(block_width,0,half(Constants["block_depth_unit"]),cap_two[0]) components.append(cap_two[0]) solid = cmds.polyUnite(components, name=get_unique_name(cls.get_prefix(), "")) boolean_group = cmds.polyUnite(boolean, name=get_unique_name(cls.get_prefix(),"boolean")) cmds.polyMergeVertex( solid[0], d=0.15 ) cmds.delete(solid[0],ch=1) return cmds.polyBoolOp( solid[0], boolean_group[0], op=2, n=get_unique_name(cls.get_prefix(), "") )
def createGroovedAxel(length): for i in range(2): cylTop = cmds.polyCylinder(r=0.15, h=1, sz=4, sy=12) cmds.rotate(0, 0, 90) if i == 0: cmds.move(((length / 3.5)), moveZ=True, a=True) else: cmds.move((-1 * ((length / 3.5))), moveZ=True, a=True) cmds.move((0.34), moveY=True, a=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(cu[0], cylTop[0], op=2, n="block", ch=False) cylTop = cmds.polyCylinder(r=0.15, h=1, sz=4, sy=12) cmds.rotate(0, 0, 90) if i == 0: cmds.move(((length / 3.5)), moveZ=True, a=True) else: cmds.move((-1 * ((length / 3.5))), moveZ=True, a=True) cmds.move((-0.34), moveY=True, a=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(cu[0], cylTop[0], op=2, n="block", ch=False) cylTop2 = cmds.polyCylinder(r=0.15, h=1, sz=4, sy=12) cmds.rotate(0, 0, 180) if i == 0: cmds.move(((length / 3.5)), moveZ=True, a=True) else: cmds.move((-1 * ((length / 3.5))), moveZ=True, a=True) cmds.move((0.29), moveY=True, a=True) cmds.move((0.34), moveX=True, a=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(cu[0], cylTop[0], op=2, n="block", ch=False) cylTop2 = cmds.polyCylinder(r=0.15, h=1, sz=4, sy=12) cmds.rotate(0, 0, 180) if i == 0: cmds.move(((length / 3.5)), moveZ=True, a=True) else: cmds.move((-1 * ((length / 3.5))), moveZ=True, a=True) cmds.move((0.29), moveY=True, a=True) cmds.move((-0.34), moveX=True, a=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(cu[0], cylTop[0], op=2, n="block", ch=False)
def make_base(): """ crane base """ base = cmds.polyCube(w=4, h=2, d=4, name="base") cmds.move(0, 1, 0, base) swivel = cmds.polyCylinder(axis=(0,1,0), h=.5,radius=1.5, name="swivel") cmds.move(0, 2.25, 0, swivel) sarm1 = cmds.polyCube(w=2, h=1, d=.2, name="sarm1") cmds.move(0, 3, .5, sarm1) sarm2 = cmds.polyCube(w=2, h=1, d=.2, name="sarm2") cmds.move(0, 3, -.5, sarm2) b1 = cmds.polyBoolOp(swivel[0], sarm1[0], op=1, name="b1") b2 = cmds.polyBoolOp(b1[0], sarm2[0], op=1, name="b2")
def createTire(): global cu cu = cmds.polyTorus(sx=2, sy=2, r=0.5, sr=0.25) cmds.scale(1, 1.712, 1) cmds.delete(ch=True) middle = cmds.polyCylinder(r=0.45, h=2, sz=4, sy=12) cu[0] = cmds.polyBoolOp(cu[0], middle[0], op=2, n="block", ch=False) extrudeForTire() cmds.delete(ch=True) pip1 = cmds.polyPipe(r=0.4906, h=1.5094, t=0.0755) cu[0] = cmds.polyUnite(cu[0], pip1[0], n="block", ch=False) pip2 = cmds.polyPipe(r=0.4150, h=1.1321, t=0.0) cu[0] = cmds.polyUnite(cu[0], pip2[0], n="block", ch=False)
def makeWindows(self, name_, windowShaders, booleans): ''' Creates windows for a cylinder or pipe house. self: Object of the class House. name_: A string with the name the polygonal house object will have. windowShader: A list with shaders for the windows. booleans: A boolean variable which determines whether the windows should be combined with the house using boolean difference or not. On exit: Columns of windows are created using makeWindowColumn(...) and these are then duplicated around the house. The windows are assigned shaders using assignWindowShaders(...), and are then combined with the house. The House object's name attribute is updated. ''' windowHeight = random.uniform(0.5,1.9) # Make sure the window height is not too close to 1.6 since the window edge # in that case will be too close to a edge loop on the house and the boolean # operation will fail. if booleans and (windowHeight > 1.59 and windowHeight < 1.61): windowHeight = random.choice([1.59, 1.61]) floorHeight = int(math.ceil(windowHeight)) heightNum = int((self.height - (1 + floorHeight/2.0))/floorHeight) if heightNum == 0: return angleR = 2.0 * math.pi / self.sides angleD = math.degrees(angleR) distance = math.cos(angleR / 2.0) * self.radius sideWidth = 2.0 * self.radius * math.sin(angleR / 2.0) windowWidth = random.uniform((sideWidth -0.2)/ 2.0, sideWidth - 0.2) if windowWidth <= 0.1: return windowColumn = makeWindowColumn(windowWidth, windowHeight, heightNum, floorHeight) cmds.rotate(90 - angleD / 2.0, windowColumn[0], y = True) for j in range(self.sides): # Copy the column faces around the house. cmds.polyChipOff(windowColumn[0] + ".f[0:" + str((heightNum * 6) - 1) + "]", dup = True, kft = True, translate = (math.sin(math.pi/2.0 - angleR/2.0 + angleR * j) * distance,0,math.cos(math.pi/2.0 - angleR/2.0 + angleR * j) * distance)) cmds.select(windowColumn[0] + ".f[0:" + str((heightNum * 6) - 1) + "]") cmds.rotate(angleD, y = True) cmds.delete(all = True, ch = True) cmds.refresh() cmds.delete(windowColumn[0] + ".f[0:" + str((heightNum * 6) - 1) + "]") windowNum = self.sides * heightNum assignWindowShaders(windowColumn, windowNum, windowShaders) cmds.select(windowColumn[0] + ".f[0:" + str(windowNum * 6 - 1) +"]") cmds.polySubdivideFacet() if booleans == True: result = cmds.polyBoolOp(self.name,windowColumn[0], op = 2, n = name_) else: result = cmds.polyUnite(self.name,windowColumn[0], n = name_) self.name = result[0] cmds.delete(all = True, ch = True)
def makeStreetLight(): ''' Creates a street light. On exit: A street light polygonal object has been created and appropriate shaders have been assigned. The street light object is returned. ''' streetLight = cmds.polyCube(name = "streetLight", w = 0.1, d = 0.1, h = 2.4) cmds.xform(streetLight, translation = (0, 1.2, 0)) cmds.select(streetLight[0] + ".f[1]") cmds.polyExtrudeFacet(scale = (1.7,1.7,1.7)) cmds.polyExtrudeFacet(scale = (2.2,2.2,2.2), translate = (0,0.2,0)) cmds.polyExtrudeFacet(scale = (0.8,0.8,0.8), translate = (0,0.1,0)) cmds.polyExtrudeFacet(scale = (0.6,0.6,0.6)) cmds.polyExtrudeFacet(scale = (0.8,0.8,0.8), translate = (0,0.08,0)) cmds.polyExtrudeFacet(scale = (0.6,0.6,0.6)) cmds.polyExtrudeFacet(scale = (0.7,0.7,0.7), translate = (0,0.08,0)) cmds.polyExtrudeFacet(scale = (0.5,0.5,0.5)) cmds.polyExtrudeFacet(scale = (0.2,0.2,0.2), translate = (0,0.7,0)) hole = cmds.polyCube(name = "hole", w = 0.16, d = 0.3, h = 0.22) cmds.select(hole[0] + ".f[1]") cmds.scale(1.9,1.9,1.9) cmds.xform(hole, translation = (0,2.59,0)) hole2 = cmds.duplicate(hole[0]) cmds.rotate(0,90,0, hole2[0]) streetLight = cmds.polyBoolOp((streetLight[0],hole[0]),op = 2) streetLight = cmds.polyBoolOp((streetLight[0],hole2[0]),op = 2) cmds.sets(streetLight[0], edit=True, forceElement="blackMetalGroup") light = cmds.polyCube(name = "hole", w = 0.16, d = 0.16, h = 0.22) cmds.select(light[0] + ".f[1]") cmds.scale(1.9,1.9,1.9) cmds.xform(light, translation = (0,2.59,0)) cmds.select(light) cmds.sets(light[0], edit=True, forceElement="whiteLightGroup") streetLight = cmds.polyUnite(light,streetLight) cmds.delete(streetLight, ch = True) cmds.group(streetLight[0], n = "streetLights") return streetLight
def createBevels(cubeSizeX, cubeSizeY, cubeSizeZ, blockWidth, blockDepth): for i in range(blockWidth - 1): cyl = cmds.polyCylinder(r=0.28, h=0.15) cmds.move((cubeSizeY - 0.30), moveY=True, a=True) cmds.move(((i * 0.8) - (cubeSizeX / 2.0) + 0.8), moveX=True, a=True) cmds.move(((0 * 0.05) - (cubeSizeZ / 2.0) + 0.8), moveZ=True, a=True) cmds.rotate(90, 0, 0) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(cu[0], cyl[0], op=2, n="block" + str(i), ch=False)
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 generate(cls, *args): components = [] boolean = [] width = cmds.intSliderGrp(cls.get_prefix() + Labels["width_label"], query=True, value=True) rgb = cmds.colorSliderGrp(cls.get_prefix() + Labels["color_label"], query=True, rgbValue=True) block_width = width * Constants["block_width_unit"] block_height = Constants["block_height_unit"] block_depth = Constants["block_depth_unit"] for x in range(0, width + 1): hole = cmds.polyCylinder(name=get_unique_name(cls.get_prefix(), "Hole"), radius=Constants["perforation_radius"], height=Constants["block_depth_unit"] + 0.2) boolean.append(hole[0]) cmds.rotate('90deg', 0, 0, hole[0]) cmds.move(Constants["block_width_unit"] * x , 0, half(Constants["block_depth_unit"]), hole[0]) cube = cmds.polyCube(sx=5,sy=2,sz=2,name=get_unique_name(cls.get_prefix(), "block"), width=block_width, height=block_height, depth=block_depth) components.append(cube[0]) cmds.delete(cube[0] + ".f[40:47]") cmds.move(half(width * Constants["block_width_unit"]), 0, half(Constants["block_depth_unit"]), cube) #caps cap_one = cmds.polyCylinder(sc=1, sy=2, radius=half(Constants["block_height_unit"]), height=Constants["block_depth_unit"],name=get_unique_name(cls.get_prefix(), "cap")) cmds.rotate('90deg',0,0,cap_one[0]) cmds.move(0,0,half(Constants["block_depth_unit"]),cap_one[0]) cmds.delete(cap_one[0] + ".f[0:3]", cap_one[0] + ".f[14:23]", cap_one[0] + ".f[34:43]", cap_one[0] + ".f[54:63]", cap_one[0] + ".f[74:79]") components.append(cap_one[0]) #caps cap_two = cmds.polyCylinder(sc=1, sy=2, radius=half(Constants["block_height_unit"]), height=Constants["block_depth_unit"]) cmds.rotate('90deg','180deg',0,cap_two[0]) cmds.delete(cap_two[0] + ".f[0:3]", cap_two[0] + ".f[14:23]", cap_two[0] + ".f[34:43]", cap_two[0] + ".f[54:63]", cap_two[0] + ".f[74:79]") cmds.move(block_width,0,half(Constants["block_depth_unit"]),cap_two[0]) components.append(cap_two[0]) solid = cmds.polyUnite(components, name=get_unique_name(cls.get_prefix(), "")) boolean_group = cmds.polyUnite(boolean, name=get_unique_name(cls.get_prefix(),"boolean")) cmds.polyMergeVertex( solid[0], d=0.15 ) cmds.delete(solid[0],ch=1) final = cmds.polyBoolOp( solid[0], boolean_group[0], op=2, n=get_unique_name(cls.get_prefix(), "") ) shader = cmds.shadingNode('blinn', asShader=True, name=get_unique_name(cls.get_prefix(),"mat")) cmds.setAttr(shader + ".color", rgb[0],rgb[1],rgb[2], type='double3') cmds.select(final[0], r=True) cmds.hyperShade(assign=shader)
def createWheelHub(): global cu cu = cmds.polyCylinder(r=0.4, h=0.8, sz=2, sx=2, sy=2) temp = str(cu[0]).rsplit("'", 1)[0] cmds.select(temp + ".e[40:59]") cmds.scale(0.768657, 0.768657, 0.768657) cyl = cmds.polyCylinder(r=0.3, h=1, sz=2, sx=2, sy=2) cu[0] = cmds.polyBoolOp(cu[0], cyl[0], op=2, n="block", ch=False) cyl2 = cmds.polyCylinder(r=0.35, h=.3, sz=2, sx=2, sy=2) cu[0] = cmds.polyBoolOp(cyl2[0], cu[0], op=1, n="block", ch=False) Tor1 = cmds.polyPipe(r=0.07, t=0.04, h=0.9434) cmds.move(0.128, moveX=True) cmds.move(-0.039, moveZ=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(Tor1[0], cu[0], op=1, n="block", ch=False) Tor2 = cmds.polyPipe(r=0.07, t=0.04, h=0.9434) cmds.move(0.013, moveX=True) cmds.move(-0.134, moveZ=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(Tor2[0], cu[0], op=1, n="block", ch=False) Tor3 = cmds.polyPipe(r=0.07, t=0.04, h=0.9434) cmds.move(-0.123, moveX=True) cmds.move(-0.082, moveZ=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(Tor3[0], cu[0], op=1, n="block", ch=False) Tor4 = cmds.polyPipe(r=0.07, t=0.04, h=0.9434) cmds.move(-0.123, moveX=True) cmds.move(0.065, moveZ=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(Tor4[0], cu[0], op=1, n="block", ch=False) Tor5 = cmds.polyPipe(r=0.07, t=0.04, h=0.9434) cmds.move(-0.017, moveX=True) cmds.move(0.155, moveZ=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(Tor5[0], cu[0], op=1, n="block", ch=False) Tor6 = cmds.polyPipe(r=0.07, t=0.04, h=0.9434) cmds.move(0.115, moveX=True) cmds.move(0.109, moveZ=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(Tor6[0], cu[0], op=1, n="block", ch=False)
def createPipeExtrusion(cubeSizeX, cubeSizeY, cubeSizeZ, blockWidth, blockDepth): blockWidth = str(blockWidth).rsplit(".", 1)[0] blockWidth = int(blockWidth) for i in range(blockWidth): for j in range(blockDepth): cyl = cmds.polyPipe(r=0.24, h=0.34, t=0.05) cmds.move((cubeSizeY + 0.05), moveY=True, a=True) cmds.move(((i * 0.8) - (cubeSizeX / 2.0) + 0.4), moveX=True, a=True) cmds.move(((j * 0.8) - (cubeSizeZ / 2.0) + 0.4), moveZ=True, a=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(cu[0], cyl[0], op=1, n="block", ch=False)
def createHoles(cubeSizeX, cubeSizeY, cubeSizeZ, blockWidth, blockDepth): blockWidth = str(blockWidth).rsplit(".", 1)[0] blockWidth = int(blockWidth) for i in range(blockWidth - 1): cylinderDepth = blockDepth + (blockDepth * 0.3) cyl = cmds.polyCylinder(r=0.24, h=cylinderDepth) cmds.move((cubeSizeY - 0.30), moveY=True, a=True) cmds.move(((i * 0.8) - (cubeSizeX / 2.0) + 0.8), moveX=True, a=True) cmds.move(((0 * 0.8) - (cubeSizeZ / 2.0) + 0.25), moveZ=True, a=True) cmds.rotate(90, 0, 0) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(cu[0], cyl[0], op=2, n="block" + str(i), ch=False) createBevels(cubeSizeX, cubeSizeY, cubeSizeZ, blockWidth, blockDepth)
def voxelize(self, source, voxelSize, gapSize, knifeCount, offset): """ Voxelize the first object in source. """ if len(source) < 1: return "" objName = source[0] boundingBox = cmds.exactWorldBoundingBox(source[0]) #translation = [(boundingBox[i] + boundingBox[i + 3]) / 2.0 for i in range(3)] knifeSize = max( [boundingBox[i + 3] * 2 - boundingBox[i] * 2 for i in range(3)]) knifeSize = max(knifeSize, voxelSize * (1 + max(knifeCount))) # Build knife frame and cut the source object base = [-voxelSize * (knifeCount[i] - 1) / 2.0 for i in range(3)] knifeX = cmds.polyCube(n='knife1', w=gapSize, h=knifeSize, d=knifeSize) cmds.move(base[0], 0, 0, knifeX[0]) cmds.move(offset[0], offset[1], offset[2], knifeX[0], relative=True) knifeY = cmds.polyCube(n='knife2', w=knifeSize, h=gapSize, d=knifeSize) cmds.move(0, base[1], 0, knifeY[0]) cmds.move(offset[0], offset[1], offset[2], knifeY[0], relative=True) knifeZ = cmds.polyCube(n='knife3', w=knifeSize, h=knifeSize, d=gapSize) cmds.move(0, 0, base[2], knifeZ[0]) cmds.move(offset[0], offset[1], offset[2], knifeZ[0], relative=True) for i in range(1, knifeCount[0]): knife = cmds.duplicate(knifeX[0]) cmds.move(voxelSize * i, 0, 0, knife[0], relative=True) source = cmds.polyBoolOp(source[0], knife[0], op=2) for i in range(1, knifeCount[1]): knife = cmds.duplicate(knifeY[0]) cmds.move(0, voxelSize * i, 0, knife[0], relative=True) source = cmds.polyBoolOp(source[0], knife[0], op=2) for i in range(1, knifeCount[2]): knife = cmds.duplicate(knifeZ[0]) cmds.move(0, 0, voxelSize * i, knife[0], relative=True) source = cmds.polyBoolOp(source[0], knife[0], op=2) source = cmds.polyBoolOp(source[0], knifeX[0], op=2) source = cmds.polyBoolOp(source[0], knifeY[0], op=2) source = cmds.polyBoolOp(source[0], knifeZ[0], op=2) cmds.delete(source[0], ch=True) objName = cmds.rename(source[0], objName) cmds.xform(objName, cpc=True) return objName
def makeTrafficLight(glow): ''' Creates a traffic light. glow: String that determines what colour should be glowing on the traffic light. Valid values are "R", "G", "Y" and "RY". On exit: A traffic light has been created and the right shaders have been assigned to it. The traffic light polygonal object is returned as a tuple containing the object name and node name. ''' pole = cmds.polyCube(n = "pole", w = 0.1,d = 0.1, h = 2) cmds.xform(pole, translation = (0, 1, 0)) cmds.sets(pole[0], edit=True, forceElement="blackMetalGroup") box = cmds.polyCube(n = "box", w = 0.3, d = 0.3, h = 0.7) cmds.xform(box, translation = (0, 2.35, 0)) cmds.sets(box[0], edit=True, forceElement="blackMetalGroup") lights = cmds.polyCylinder(n = "light", r = 0.1, h = 0.2, sx = 12) cmds.xform(lights, rotation = (90, 0, 0)) cmds.xform(lights, translation = (0, 2.575, 0.15), ws = True) cmds.polyChipOff(lights[0] + ".f[0:13]" , dup = True, kft = True, translate = (0, -0.225,0)) cmds.polyChipOff(lights[0] + ".f[0:13]" , dup = True, kft = True, translate = (0, -0.45,0)) if glow == "R" or glow == "RY": cmds.sets(lights[0] + ".f[0:13]", edit=True, forceElement="redLightGroup") else: cmds.sets(lights[0] + ".f[0:13]", edit=True, forceElement="redGroup") if glow == "Y" or glow == "RY": cmds.sets(lights[0] + ".f[14:27]", edit=True, forceElement="yellowLightGroup") else: cmds.sets(lights[0] + ".f[14:27]", edit=True, forceElement="yellowGroup") if glow == "G": cmds.sets(lights[0] + ".f[28:43]", edit=True, forceElement="greenLightGroup") else: cmds.sets(lights[0] + ".f[28:43]", edit=True, forceElement="greenGroup") trafficLight = cmds.polyBoolOp(box[0], lights[0], op = 2) trafficLight = cmds.polyUnite(trafficLight[0], pole[0], n = "trafficLight") cmds.delete(trafficLight[0], ch = True) return trafficLight
def createSideAngles(blockWidth): sideCylin1 = cmds.polyCylinder(r=0.31, h=0.8, sz=1) cmds.rotate(90, 0, 0) cmds.move((-1 * (((blockWidth * 0.8) / 2.0))), moveX=True) cmds.move(0.31, moveY=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(sideCylin1[0], cu[0], op=1, n="block", ch=False) sideCylin = cmds.polyCylinder(r=0.31, h=0.8, sz=1) cmds.rotate(90, 0, 0) cmds.move((((blockWidth * 0.8) / 2.0)), moveX=True) cmds.move(0.31, moveY=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(sideCylin1[0], cu[0], op=1, n="block", ch=False) sideCylin2 = cmds.polyCylinder(r=0.28, h=0.15, sz=1) cmds.rotate(90, 0, 0) cmds.move((-1 * (((blockWidth * 0.8) / 2.0))), moveX=True) cmds.move(((0 * 0.05) - (1 / 2.0) + 0.829), moveZ=True) cmds.move(0.31, moveY=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(cu[0], sideCylin2[0], op=2, n="block", ch=False) sideCylin3 = cmds.polyCylinder(r=0.28, h=0.15, sz=1) cmds.rotate(90, 0, 0) cmds.move((((blockWidth * 0.8) / 2.0)), moveX=True) cmds.move(((0 * 0.05) - (1 / 2.0) + 0.829), moveZ=True) cmds.move(0.31, moveY=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(cu[0], sideCylin3[0], op=2, n="block", ch=False) difference1 = cmds.polyCylinder(r=0.24, h=2) cmds.rotate(90, 0, 0) cmds.move((-1 * ((blockWidth * 0.8) / 2.0)), moveX=True) cmds.move(0.31, moveY=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(cu[0], difference1[0], op=2, n="block", ch=False) difference2 = cmds.polyCylinder(r=0.24, h=2) cmds.rotate(90, 0, 0) cmds.move((((blockWidth * 0.8) / 2.0)), moveX=True) cmds.move(0.31, moveY=True) cmds.delete(ch=True) cu[0] = cmds.polyBoolOp(cu[0], difference2[0], op=2, n="block", ch=False)
cmds.polyCube(n='Rempart',w=0.5,h=0.5,d=1) cmds.xform(ws=True,piv=(0,-.25,0)) cmds.move(0,.25,0) cmds.move(0,.2,3.2, relative=True) cmds.xform(ws=True, rotatePivot=(0,0,0)) cmds.rotate(0,30*i,0) for i in range(12): cmds.polyCube(n='Fente',w=1,h=.5,d=.1) cmds.move(3.2,0,0, relative=True) cmds.xform(ws=True, rotatePivot=(0,0,0)) cmds.rotate(0,30*i,0) cmds.group('Fente*', n='GroupFentes') cmds.group('Remp*',n='GroupRempart') cmds.rotate(0,15,0,) cmds.polyUnite('Fente*','Rempart*',n='TrouResult') cmds.polyBoolOp('Remp','TrouResult', op=2, n='RempartResult') cmds.move(0,0.2,0) cmds.group('GroupTour','GroupFentes','GroupRempart','RempartResult','TrouResult', n='Tour') cmds.duplicate('Tour',n='TourHaut') cmds.move(0,3,0) cmds.scale(.8,.8,.8)
def makeWindows(self, name_, windowShaders, booleans): ''' Creates windows for a box house. self: Object of the class BoxHouse. name_: A string with the name the house will have. windowShader: A list with shaders for the windows. booleans: A boolean variable which determines whether the windows should be combined with the house using boolean difference or not. On exit: Columns of windows are created using makeWindowColumn(...) and these are then duplicated around the house. The windows are assigned shaders using assignWindowShaders(...), and are then combined with the house. The House object's name attribute is updated. ''' windowHeight = random.uniform(0.5,1.9) # Make sure the window height is not too close to 1.6 since the window edge # in that case will be too close to a edge loop on the house and the boolean # operation will fail. if booleans and (windowHeight > 1.59 and windowHeight < 1.61): windowHeight = random.choice([1.59, 1.61]) windowWidth = random.uniform(1, 3) floorHeight = int(math.ceil(windowHeight)) heightNum = max(0,int((self.height - (1 + floorHeight/2.0))/floorHeight)) if heightNum == 0: return widthNum = max(0,int((self.width - 0.3) / (windowWidth))) if (widthNum != 0): # Makes it possible for houses to have less windows or no windows on a side. widthNum = widthNum - random.randint(0, min(2, widthNum)) # Space between window columns along the width of the house. widthSpace = (self.width - (widthNum * windowWidth)) /(widthNum + 1) depthNum = max(0,int((self.depth - 0.3)/ windowWidth)) if (depthNum != 0): # Makes it possible for houses to have less windows or no windows on a side. depthNum = depthNum - random.randint(0, min(2, depthNum)) if (depthNum == 0) and (widthNum == 0): return # Space between window columns along the width of the house. depthSpace = (self.depth - (depthNum * windowWidth)) / (depthNum + 1) windowColumn = makeWindowColumn(windowWidth,windowHeight, heightNum, floorHeight) for j in range(widthNum): # Duplicates all the faces of the first window column and translates the duplicates along the width. cmds.polyChipOff(windowColumn[0] + ".f[0:" + str((heightNum * 6) - 1) + "]", dup = True, kft = True, translate = (-self.width/2.0 + windowWidth/2.0 + widthSpace + (windowWidth + widthSpace) * j, 0, self.depth/2.0)) cmds.polyChipOff(windowColumn[0] + ".f[0:" + str((heightNum * 6) - 1) + "]", dup = True, kft = True, translate = (-self.width/2.0 + windowWidth/2.0 + widthSpace + (windowWidth + widthSpace) * j, 0, -self.depth/2.0)) cmds.delete(all = True, ch = True) cmds.refresh() cmds.select(windowColumn[0] + ".f[0:" + str((heightNum * 6) - 1) + "]") cmds.rotate(90, y = True) for j in range(depthNum): # Duplicates all the faces of the first window column and translates the duplicates along the depth. cmds.polyChipOff(windowColumn[0] + ".f[0:" + str((heightNum * 6) - 1) + "]", dup = True, kft = True, translate = (self.width/2.0, 0, -self.depth/2.0 + windowWidth/2.0 + depthSpace + (windowWidth + depthSpace) * j), ws = True) cmds.polyChipOff(windowColumn[0] + ".f[0:" + str((heightNum * 6) - 1) + "]", dup = True, kft = True, translate = (-self.width/2.0, 0, -self.depth/2.0 + windowWidth/2.0 + depthSpace + (windowWidth + depthSpace) * j), ws = True) cmds.delete(all = True, ch = True) cmds.refresh() cmds.select(windowColumn[0] + ".f[0:" + str((heightNum * 6) - 1) + "]") cmds.delete() windowNum = widthNum * heightNum * 2 + depthNum * heightNum * 2 # Total number of windows. assignWindowShaders(windowColumn, windowNum, windowShaders) cmds.select(windowColumn[0] + ".f[0:" + str(windowNum * 6 - 1) +"]") cmds.polySubdivideFacet() if booleans: result = cmds.polyBoolOp(self.name,windowColumn[0], op = 2, n = name_) else: result = cmds.polyUnite(self.name,windowColumn[0], n = name_) self.name = result[0] cmds.delete(self.name, ch = True)
def cut_by_part(obj, part): dup_obj = cmds.duplicate(obj)[0] new_cut = cmds.polyBoolOp(dup_obj, part, op=3)[0] return new_cut
def rec(remaining, part, move): print 'enter step', (move-5)/3 # last part if len(part) == 1: print 'done' return True # print 'last part!' # vol_rem = volume(remaining) # vol_part = volume(part) # ratio = vol_rem / vol_part # if ratio < 15 and ratio > 0.6: # print 'last part going to return true' # return True # else: # print 'last part going to return false' # cmds.delete(remaining) # return False backup_rem = cmds.duplicate(remaining) bbox_rem = cmds.exactWorldBoundingBox(remaining) for j in range(30): # get the cutpart at right position cutpart = create_part(part[0]) cutcenter = rand_center(remaining) move_obj_center(cutpart, cutcenter) vol_part = volume(cutpart) bbox_cut = cmds.exactWorldBoundingBox(cutpart) # percentage outside check pi = vertices_outside(bbox_rem, bbox_cut) if pi <= 6: cmds.delete(cutpart) continue # volumn check dum_rem = cmds.duplicate(remaining) dum_cut = cmds.duplicate(cutpart) new_cut = cmds.polyBoolOp(dum_rem, dum_cut, op=3)[0] new_rem = cmds.polyBoolOp(remaining, cutpart, op=2)[0] vol_cut = volume(new_cut) if vol_cut / vol_part > 0.5: # this part might work result = rec(new_rem, part[1:], move + 3) if result == True: print 'sol found, return to upper lv' cmds.move(move, 0, 0, new_cut, r=1) cmds.delete(backup_rem) return True else: cmds.delete(new_cut) remaining = cmds.duplicate(backup_rem) print 'try again in step', move else: cmds.delete(new_cut) cmds.delete(new_rem) remaining = cmds.duplicate(backup_rem) print 'fail in step', (move-5)/3 cmds.delete(backup_rem) cmds.delete(remaining) return False
def polyBoolOp(*args, **kwargs): res = cmds.polyBoolOp(*args, **kwargs) if not kwargs.get('query', kwargs.get('q', False)): res = _factories.maybeConvert(res, _general.PyNode) return res
def cut_by_part(obj, part): dup_obj = cmds.duplicate(obj)[0] new_cut = cmds.polyBoolOp(dup_obj, part, op=3, useThresholds=1, preserveColor=1)[0] return new_cut
#all rest are the cubes stencils = cmds.ls(sl=True)[1:] #print cubes newObjs = [] count = 0 for stencil in stencil: #dupe obj as objDupe newObj = cmds.duplicate(obj) #put obj dupe in list newObjs.append(newObj) #bool with the object selections (stencil then obj) #polyBoolOp -op 3 -ch 1 -useThresholds 1 -preserveColor 0 pstencil2 pSphere1; cmds.polyBoolOp(stencil, newObj, op=3, n="BooledObj_%s"%count) #hide stencil cmds.setAttr("%s.v"%stencil, 0) count += 1 #delete history on the newObjs # Deal with transferring the pivot point of cubes to new pieces of geo #create an empty group, name it "newObj_Grp" #parent the newObjs into the group #hide the orig object # Deal with UV mapping from original to new
def rec(remaining, part, move): print 'enter step', (move-5)/3 if len(part) == 0: print 'done', remaining return True backup_rem = cmds.duplicate(remaining) bbox_rem = cmds.exactWorldBoundingBox(remaining) # for all possible centers # center must be inside the bounding box # here we consider centers lies on one subdivision of axis nn = 20 xsub = nn ysub = nn zsub = nn sum = 0 for x in xrange(xsub): for y in xrange(ysub): for z in xrange(zsub): # for all possible orientations # create part cutpart = part_by_aspect(part[0]) # move part to this center cutcenter = center_with_sub_index(bbox_rem, x/float(xsub), y/float(ysub), z/float(zsub)) move_obj_center(cutpart, cutcenter) # store volume bbox_cut = cmds.exactWorldBoundingBox(cutpart) vol_part = volume_with_bbox(bbox_cut) # percentage of vertex outside check pi = vertices_outside(bbox_rem, bbox_cut) if pi < 6: cmds.delete(cutpart) continue # cut the part out from remaining dum_rem = cmds.duplicate(remaining) dum_cut = cmds.duplicate(cutpart) new_cut = cmds.polyBoolOp(dum_rem, dum_cut, op=3)[0] new_rem = cmds.polyBoolOp(remaining, cutpart, op=2)[0] # shell check # make sure that new_cut contains one single object if cmds.polyEvaluate(new_cut, shell = True) != 1: cmds.delete(new_rem) cmds.delete(new_cut) remaining = cmds.duplicate(backup_rem) continue # volume check vol_cut = volume(new_cut) if vol_cut / vol_part > 0.4: # this part might work result = rec(new_rem, part[1:], move + 3) if result == True: sum = sum + 1 print 'sol found, return to upper lv', vol_cut, vol_part cmds.move(move, 0, 0, new_cut, r=1) cmds.delete(backup_rem) return True else: print vol_cut / vol_part cmds.delete(new_rem) cmds.delete(new_cut) remaining = cmds.duplicate(backup_rem) # no solusion after tried all print 'fail in step', (move-5)/3, 'try', sum cmds.delete(backup_rem) cmds.delete(remaining) return False
def uniformVoroPoints(self): ''' Performs voronoi uniform fragmentation ''' # duplicate original shape mVoroInputMeshFn = OpenMaya.MFnMesh(self._mVoroInputMeshDAG) mPoints = OpenMaya.MPointArray() mVerticesCount = OpenMaya.MIntArray() mVerticesList = OpenMaya.MIntArray() mVoroInputMeshFn.getPoints(mPoints, OpenMaya.MSpace.kWorld) mVoroInputMeshFn.getVertices(mVerticesCount, mVerticesList) mNumPoly = mVoroInputMeshFn.numPolygons() mCopyMeshFn = OpenMaya.MFnMesh() mCopyTrs = mCopyMeshFn.create(mPoints.length(), mNumPoly, mPoints, mVerticesCount, mVerticesList) mDagPath = OpenMaya.MDagPath() OpenMaya.MDagPath.getAPathTo(mCopyTrs, mDagPath) mMeshName = mDagPath.fullPathName() # create boolean op between sphere and duplicated shape mRadius = cmds.getAttr(self._mVoroImpactShape + '.radius') mRadius = max(.15, mRadius) mImpact = cmds.polySphere(r = mRadius, sx = 8, sy = 8) cmds.xform(mImpact[0], translation = [self._mOriginPt.x, self._mOriginPt.y, self._mOriginPt.z]) cmds.select(clear = True) mVolume = None if int(cmds.about(version = True).split()[0]) > 2014: try: mVolume = cmds.polyCBoolOp(mMeshName, mImpact[0], op = 3, ch = False, classification = 1, n = 'IS_Volume') except: pass else: try: mVolume = cmds.polyBoolOp(mMeshName, mImpact[0], op = 3, ch = False, n = 'IS_Volume') except: pass cmds.flushUndo() # Check if mVolume is valid if mVolume: if cmds.polyEvaluate(mVolume, face = True) == 0: cmds.delete(mVolume) mVolume = cmds.polySphere(r = mRadius, sx = 8, sy = 8) else: mVolume = cmds.polySphere(r = mRadius, sx = 8, sy = 8) # Fill volume of the boolean object with points mSelection = OpenMaya.MSelectionList() mSelection.add(mVolume[0]) mSelection.getDagPath(0, mDagPath) mDagPath.extendToShape() mVerts = OpenMaya.MPointArray() triangleCounts, triangleVertices = OpenMaya.MIntArray(), OpenMaya.MIntArray() mVolMeshFn = OpenMaya.MFnMesh(mDagPath) mVolMeshFn.getPoints(mVerts, OpenMaya.MSpace.kWorld) mVolMeshFn.getTriangles(triangleCounts, triangleVertices) numTriangles = triangleVertices.length() / 3 mHitPoint = OpenMaya.MFloatPoint() mFloatRaySource = OpenMaya.MFloatPoint() mFloatRayNormal = OpenMaya.MFloatVector() # Randomly select a face, find a point on face surface (with bary coords) and launch a ray from the reversed normal mAccelerationStructure = mVolMeshFn.autoUniformGridParams() for n in xrange(self._mVoroCount): triId = rand.randint(0, numTriangles-1) v0 = triangleVertices[3 * triId + 0] v1 = triangleVertices[3 * triId + 1] v2 = triangleVertices[3 * triId + 2] mVectorAB = mVerts[v1] - mVerts[v0] mVectorAC = mVerts[v2] - mVerts[v0] mNormal = (mVectorAB ^ mVectorAC) * -1.0 mNormal.normalize() u = rand.uniform(0.0,1.0) v = rand.uniform(0.0, (1.0 - u)) mSample = (mVerts[v0] + mVectorAB * u + mVectorAC * v) + (mNormal * 0.001) mFloatRaySource.x, mFloatRaySource.y, mFloatRaySource.z = mSample.x, mSample.y, mSample.z mFloatRayNormal.x, mFloatRayNormal.y, mFloatRayNormal.z = mNormal.x, mNormal.y, mNormal.z hit = mVolMeshFn.closestIntersection( mFloatRaySource, mFloatRayNormal, None, None, None, OpenMaya.MSpace.kWorld, 99999, None, mAccelerationStructure, mHitPoint, None, None, None, None, None ) if hit: mDistance = mFloatRaySource.distanceTo(mHitPoint) self._mVoroPoints.append(mSample + (mNormal * rand.uniform(0.0, mDistance))) mVolMeshFn.freeCachedIntersectionAccelerator() cmds.delete(mVolume) # hide IShatter sphere helper cmds.setAttr(self._mVoroImpactTrs + '.visibility', False) cmds.setAttr(self._mVoroImpactShape + '.radius', 0.0001) cmds.xform(self._mVoroImpactTrs, translation = [0.0, 0.0, 0.0]) self._mView.refresh(False, True) # update fractureFX mel.eval("fxEraseParticles " + self._mVoroParticleObject) mVoroParticleSysFn = OpenMayaFX.MFnParticleSystem(self._mVoroParticleSysDAG) mVoroParticleSysFn.emit(self._mVoroPoints) mVoroParticleSysFn.saveInitialState()
def BOOLEAN(NSTMP, obj1, obj2, OP, RENAME): cmds.polyBoolOp(NSTMP + obj1, NSTMP + obj2, op=OP, n="merge") cmds.delete(ch=True) cmds.rename(RENAME)
def cubeVoro(obj, points, offset, rgb): mc.undoInfo( state = False) #variables usedPoints =[] validPoints =[] objBB = bbMinMaxMVector(obj) # open a progress window amount = 0 mc.progressWindow( title = "Voronoi Shatter", progress = 0, status = "Initializing . . .", isInterruptable = True, maxValue = len(points) )#end of progress window shardsGRP = mc.group(empty = True, name = (obj + '_shardsGRP')) color = rgb aim = (0,0,1) # Z_direction mat = makeMat(obj, color) check = 2*(om.MVector.length(objBB[1] - objBB[0])) for aPos in points: # Check if the dialog has been cancelled if mc.progressWindow( query=True, isCancelled=True ) : break # Check if end condition has been reached if mc.progressWindow( query=True, progress=True ) >= len(points) : break amount += 1 #initialise the setup mult = 0.1 BB1 = makeMVectorBB(aPos, objBB[0], objBB[1], mult) radius = om.MVector.length(objBB[1] - objBB[0])*2 #initialise the lists usedPoints = [] # no used points here usedPoints.append(aPos) #dupe the cell shards = cubeCell(obj,shardsGRP,mat,aPos) activeShard = shards[0] #mc.delete(activeShard, ch = True) cutShard = shards[1] #mc.delete(cutShard, ch = True) while om.MVector.length(BB1[1] - BB1[0])< check: validPoints = [] check1 = arePointsInRad(radius, aPos, points) check2 = arePointsinBBMVector(BB1[0], BB1[1], points) for point in check2: if point not in usedPoints and point in check1: validPoints.append(point) for bPos in validPoints: cutPos = calcMidPointMVector(aPos, bPos, aim, offset) cutCell(activeShard, mat, cutPos[0], cutPos[1], shardsGRP) usedPoints.append(bPos) #fit radius to activeShard, which will reduce with cuts #activeBB = bbMinMaxMVector(activeShard) intersect = BBintersection(activeShard, obj) radius = findMaxDistance(intersect[0], intersect[1], aPos)*2 #increaseBB1 to get out of while loop mult *= 1.1 BB1 = makeMVectorBB(aPos, objBB[0], objBB[1], mult) bool = mc.polyBoolOp( activeShard, cutShard, op=3, ch = False, n = (obj + '_shard_1')) #mc.delete(bool, ch = True) mc.parent(bool, shardsGRP) mc.progressWindow( edit=True, progress=amount, status=("Voronoi Shatter step %d of %d completed . . ." % (amount, len(points))) ) mc.refresh() mc.progressWindow(endProgress=1) mc.undoInfo( state = True)
def cubeVoro(obj, points, offset, rgb): mc.undoInfo(state=False) #variables usedPoints = [] validPoints = [] objBB = bbMinMaxMVector(obj) # open a progress window amount = 0 mc.progressWindow(title="Voronoi Shatter", progress=0, status="Initializing . . .", isInterruptable=True, maxValue=len(points)) #end of progress window shardsGRP = mc.group(empty=True, name=(obj + '_shardsGRP')) color = rgb aim = (0, 0, 1) # Z_direction mat = makeMat(obj, color) check = 2 * (om.MVector.length(objBB[1] - objBB[0])) for aPos in points: # Check if the dialog has been cancelled if mc.progressWindow(query=True, isCancelled=True): break # Check if end condition has been reached if mc.progressWindow(query=True, progress=True) >= len(points): break amount += 1 #initialise the setup mult = 0.1 BB1 = makeMVectorBB(aPos, objBB[0], objBB[1], mult) radius = om.MVector.length(objBB[1] - objBB[0]) * 2 #initialise the lists usedPoints = [] # no used points here usedPoints.append(aPos) #dupe the cell shards = cubeCell(obj, shardsGRP, mat, aPos) activeShard = shards[0] #mc.delete(activeShard, ch = True) cutShard = shards[1] #mc.delete(cutShard, ch = True) while om.MVector.length(BB1[1] - BB1[0]) < check: validPoints = [] check1 = arePointsInRad(radius, aPos, points) check2 = arePointsinBBMVector(BB1[0], BB1[1], points) for point in check2: if point not in usedPoints and point in check1: validPoints.append(point) for bPos in validPoints: cutPos = calcMidPointMVector(aPos, bPos, aim, offset) cutCell(activeShard, mat, cutPos[0], cutPos[1], shardsGRP) usedPoints.append(bPos) #fit radius to activeShard, which will reduce with cuts #activeBB = bbMinMaxMVector(activeShard) intersect = BBintersection(activeShard, obj) radius = findMaxDistance(intersect[0], intersect[1], aPos) * 2 #increaseBB1 to get out of while loop mult *= 1.1 BB1 = makeMVectorBB(aPos, objBB[0], objBB[1], mult) bool = mc.polyBoolOp(activeShard, cutShard, op=3, ch=False, n=(obj + '_shard_1')) #mc.delete(bool, ch = True) mc.parent(bool, shardsGRP) mc.progressWindow( edit=True, progress=amount, status=("Voronoi Shatter step %d of %d completed . . ." % (amount, len(points)))) mc.refresh() mc.progressWindow(endProgress=1) mc.undoInfo(state=True)