###################################################################### ## CUBISM! ## ## (C) 2001 by Schlops (Schlops@web.de) ## import math, time, whrandom, Blender from Blender import Object, NMesh, Draw from Blender.Draw import * from Blender.BGL import * ###################################################################### # Globals thresh = Create(0) tv = Create(0.0000) typus = Create(0) orgfaces = Create(0) nam = Create("Plane") weight = Create(0.5) rand = Create(0) ranCap = ['Weight: ','Max: '] ranTT =['Degree of the height of the cube/pyramid', 'Maximum allowed weight'] valid = 1 elapsed = 0 ###################################################################### # Calculate the plane Ax + By + Cz + D = 0 containing the vertices # of the given vertexlist # This is trivial for a vertlist consisting of 3 vertices # But 4 vertices need not fit to a plane exactly def getPlane(vertlist): plane = [0.0,0.0,0.0,0.0] for i in range(len(vertlist)): j = (i+1)%len(vertlist) xi = vertlist[i].co[0] xj = vertlist[j].co[0] yi = vertlist[i].co[1] yj = vertlist[j].co[1] zi = vertlist[i].co[2] zj = vertlist[j].co[2] plane[0] = plane[0] + (zi + zj) * (yj - yi) plane[1] = plane[1] + (xi + xj) * (zj - zi) plane[2] = plane[2] + (yi + yj) * (xj - xi) plane[0] = plane[0] / 2.0 plane[1] = plane[1] / 2.0 plane[2] = plane[2] / 2.0 plane[3] = -(plane[0]*vertlist[0].co[0] + plane[1]*vertlist[0].co[1] + plane[2]*vertlist[0].co[2]) return plane ###################################################################### # Get the maximum distance from the points of the vertexlist to its # calculated plane def getMaxDist(vertlist, plane): m = d = 0.0 for i in vertlist: z = plane[0]*i.co[0] + plane[1]*i.co[1] + plane[2]*i.co[2] + plane[3] n = math.sqrt(plane[0]*plane[0] + plane[1]*plane[1] + plane[2]*plane[2]) d = z/n m = max(abs(m),abs(d)) return m ###################################################################### # Get the center point of the given face def getCenter(face): x=y=z=0 vl = len(face.v) for c in face.v: x = x + c.co[0] y = y + c.co[1] z = z + c.co[2] x = x / vl y = y / vl z = z / vl return [x,y,z] ###################################################################### # Remove the faces 0 to uptoindex-1 from the mesh 'mesh' def removeFaces(uptoindex, mesh): for x in range(uptoindex): mesh.faces.remove(mesh.faces[0]) NMesh.PutRaw(mesh, mesh.name, 1) ###################################################################### # Construct a cube sitting on the given face: Extrude the face # along its normal. def addCube(face, dx, dy, dz, mesh): vl = [] for i in range(len(face.v)): # Add the vertecies v = NMesh.Vert(face.v[i].co[0] - dx, face.v[i].co[1] - dy, face.v[i].co[2] - dz) mesh.verts.append(v) vl.append(v) for i in range(len(face.v)): # Add the faces j = (i+1)%len(face.v) f = NMesh.Face() f.v.append(face.v[i]) f.v.append(face.v[j]) f.v.append(vl[j]) f.v.append(vl[i]) mesh.faces.append(f) f = NMesh.Face() for i in vl: f.v.append(i) mesh.faces.append(f) NMesh.PutRaw(mesh, mesh.name, 1) ###################################################################### # Construct a pyramid sitting on the given face def addPyramid(face, dx, dy, dz, mesh): cp = getCenter(face) # Add the vertex v = NMesh.Vert(cp[0] - dx, cp[1] - dy, cp[2] - dz) mesh.verts.append(v) for i in range(len(face.v)): # Add the faces j = (i+1)%len(face.v) f = NMesh.Face() f.v.append(face.v[i]) f.v.append(face.v[j]) f.v.append(v) mesh.faces.append(f) f = NMesh.Face() NMesh.PutRaw(mesh, mesh.name, 1) ###################################################################### # The main part: A cube for every face of the given mesh def cubism(): global nam, thresh, tv, typus, orgfaces, weight, valid, gen, elapsed, rand meOrig = NMesh.GetRaw(nam.val) if meOrig != None: print "Mesh: ",nam.val starttime=time.time() valid = 1 x = len(meOrig.faces) for i in range(x): print "Face No.: ",i+1,"/",x plane = getPlane(meOrig.faces[i].v) if ((thresh.val > 0) and (getMaxDist(meOrig.faces[i].v, plane) < tv.val)) or ( thresh.val == 0): # plane[:3] -> normal vector if rand.val == 0: fact = weight.val else: fact = whrandom.uniform(0.0, weight.val) dx = plane[0]*fact dy = plane[1]*fact dz = plane[2]*fact if typus.val == 0: addCube(meOrig.faces[i], dx, dy, dz, meOrig) else: addPyramid(meOrig.faces[i], dx, dy, dz, meOrig) if orgfaces.val == 1: removeFaces(x, meOrig) stoptime=time.time() elapsed = stoptime - starttime else: valid = 0 Register(gui,event,bevent) Blender.Redraw() ###################################################################### # The GUI, cool function-name, eeh? def gui(): global nam, tv, thresh, typus, orgfaces, weight, valid, elapsed glClearColor(0.674509803921569, 0.725490196078431, 0.83921568627451, 0.5) glClear(GL_COLOR_BUFFER_BIT) Button("GO!",1,10,10,100,40) Button("Exit",2,250,10,100,40) glRasterPos2d(130,35) Text("Elapsed:") glRasterPos2d(130,15) Text("%.6f sec." % (elapsed)) nam = String("Mesh:",3, 10,240,100,20, nam.val,20, "Name of the Mesh which should be CUBISMed!") glRasterPos2d(130, 245) if valid == 1: Text(" ") else: Text(nam.val+" is not a mesh!") Button("Type->",4, 10, 200, 100, 20, "Create Cubes or Pyramids") glRasterPos2d(130,205) if typus.val == 0: Text("CUBE ") else: Text("PYRAMID") Button("Orig Faces->",5, 10, 160, 100, 20, "What to do with the faces of the original mesh?") glRasterPos2d(130,165) if orgfaces.val == 0: Text("KEEP ") else: Text("REMOVE") Toggle("Random",9, 10, 120, 100, 20, rand.val, "Random weight for every face?") weight = Slider(ranCap[rand.val],6, 130,120,220,20, weight.val, 0.00000001, 20.0, 0, ranTT[rand.val]) Toggle("Threshold",7, 10, 80, 100, 20, thresh.val, "Should a threshold for the generated CUBEs be used?") tv = Slider("ThreshValue:",8, 130,80,220,20, tv.val, 0.0, 20.0, 0, "Threshold-Value: oblique faces allowed up to this value") glRasterPos2d(10,280) Text("CUBISM! by Schlops (Schlops@web.de)") ###################################################################### # Eventhandling def event(evt, val): if (evt == ESCKEY and not val): Exit() ###################################################################### # Buttonhandling def bevent(evt): global thresh,typus, orgfaces # print "bevent: ",evt if (evt == 1): cubism() if (evt == 2): Exit() if (evt == 4): # Type if typus.val == 0: typus.val = 1 else: typus.val = 0 Register(gui,event,bevent) if (evt == 5): # OrigFaces if orgfaces.val == 0: orgfaces.val = 1 else: orgfaces.val = 0 Register(gui,event,bevent) if (evt == 7): # Threshold if thresh.val == 0: thresh.val = 1 else: thresh.val = 0 if (evt == 9): # Random if rand.val == 0: rand.val = 1 else: rand.val = 0 Register(gui,event,bevent) ############ ## Start ############ Register(gui,event,bevent)