Advertisement
Guest User

Untitled

a guest
Sep 2nd, 2012
1,187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. """
  2.  
  3.        z
  4.        ^
  5.        |
  6.  
  7.          4
  8.        4-----5
  9.       /|    /  5
  10.      7-----6 |
  11.      | |8  | |9
  12.      | | 0 |10
  13.      | 0---|-1   ->y
  14.      |/  11|/ 1
  15.      3-----2
  16.     /   2
  17.    <
  18.   x    
  19.  
  20. This Code is based on the example from
  21. http://paulbourke.net/geometry/polygonise/
  22. by Paul Bourke,
  23.  
  24. and modified by Tom Sapien to work with python within blender
  25.  
  26. V0.1
  27.  
  28. This code is under the terms of GPL
  29.  
  30. """
  31. __author__ = "Tom Sapiens"
  32. __copyright__ = "Copyright 2011, Tom Sapiens"
  33. __credits__ = ["Tom Sapiens", "Paul Bourke"]
  34. __license__ = "GPL"
  35. __version__ = "0.1"
  36. __maintainer__ = "Tom Sapiens"
  37. __email__ = "Tom.Sapiens@spot.colorado.edu"
  38. __status__ = "alpha"
  39.  
  40.  
  41. import time
  42. import math
  43. from math import sqrt,sin,cos,tan
  44. import mathutils
  45. import bpy
  46. from itertools import chain
  47. vec=mathutils.Vector
  48. ABS=abs
  49.  
  50. def main():
  51.     print("start calculation of isosurface")
  52.  
  53. #change this part to create your own surfaces
  54. #####################################################    
  55.     # define a 3D scalarfield (the function which defines the shape of the isosurface)
  56.     def scalarfield(pos):
  57.         x,y,z=pos[0],pos[1],pos[2]
  58.         m=2 #distance between spheres
  59.         a= 1.0/(1+(x-m)*(x-m)+y*y+z*z)
  60.         b= 1.0/(1+(x+m)*(x+m)+y*y+z*z)
  61.         c= 0.5*(sin(6*x)+sin(6*z))
  62.         csq=c**10
  63.         return (a+b)-csq
  64.  
  65.     p0=-5,-5,-5             #first point defining the gridbox of the MC-algorithm
  66.     p1=5,5,5                #second point defining the gridbox of the MC-algorithm
  67.     res=100
  68.     resolution=(res,res,res)   #resolution in x,y,z direction of the grid (10x10x10 means 1000 cubes)
  69.     isolevel=0.3         #threshold value used for the surface within the scalarfield
  70.  
  71. #end of isosurface definition
  72. ###############################################
  73.  
  74.  
  75.     isosurface(p0,p1,resolution,isolevel,scalarfield)
  76.  
  77.     print("end test"#   Determine the index into the edge table which
  78.     #   tells us which vertices are inside of the surface
  79.     cubeindex = 0
  80.     if cornervalues[0] < isolevel: cubeindex = cubeindex | 1
  81.     if cornervalues[1] < isolevel: cubeindex = cubeindex | 2
  82.     if cornervalues[2] < isolevel: cubeindex = cubeindex | 4
  83.     if cornervalues[3] < isolevel: cubeindex = cubeindex | 8
  84.     if cornervalues[4] < isolevel: cubeindex = cubeindex | 16
  85.     if cornervalues[5] < isolevel: cubeindex = cubeindex | 32
  86.     if cornervalues[6] < isolevel: cubeindex = cubeindex | 64
  87.     if cornervalues[7] < isolevel: cubeindex = cubeindex | 128
  88.    
  89.     # Cube is entirely in/out of the surface
  90.     if edgetable[cubeindex] == 0: return []
  91.    
  92.     vertlist=[[]]*12
  93.     # Find the vertices where the surface intersects the cube
  94.     if (edgetable[cubeindex] & 1):    vertlist[0]  = vertexinterp(isolevel,cornerpos[0],cornerpos[1],cornervalues[0],cornervalues[1])
  95.     if (edgetable[cubeindex] & 2):    vertlist[1]  = vertexinterp(isolevel,cornerpos[1],cornerpos[2],cornervalues[1],cornervalues[2])
  96.     if (edgetable[cubeindex] & 4):    vertlist[2]  = vertexinterp(isolevel,cornerpos[2],cornerpos[3],cornervalues[2],cornervalues[3])
  97.     if (edgetable[cubeindex] & 8):    vertlist[3]  = vertexinterp(isolevel,cornerpos[3],cornerpos[0],cornervalues[3],cornervalues[0])
  98.     if (edgetable[cubeindex] & 16):   vertlist[4]  = vertexinterp(isolevel,cornerpos[4],cornerpos[5],cornervalues[4],cornervalues[5])
  99.     if (edgetable[cubeindex] & 32):   vertlist[5]  = vertexinterp(isolevel,cornerpos[5],cornerpos[6],cornervalues[5],cornervalues[6])
  100.     if (edgetable[cubeindex] & 64):   vertlist[6]  = vertexinterp(isolevel,cornerpos[6],cornerpos[7],cornervalues[6],cornervalues[7])
  101.     if (edgetable[cubeindex] & 128):  vertlist[7]  = vertexinterp(isolevel,cornerpos[7],cornerpos[4],cornervalues[7],cornervalues[4])
  102.     if (edgetable[cubeindex] & 256):  vertlist[8]  = vertexinterp(isolevel,cornerpos[0],cornerpos[4],cornervalues[0],cornervalues[4])
  103.     if (edgetable[cubeindex] & 512):  vertlist[9]  = vertexinterp(isolevel,cornerpos[1],cornerpos[5],cornervalues[1],cornervalues[5])
  104.     if (edgetable[cubeindex] & 1024): vertlist[10] = vertexinterp(isolevel,cornerpos[2],cornerpos[6],cornervalues[2],cornervalues[6])
  105.     if (edgetable[cubeindex] & 2048): vertlist[11] = vertexinterp(isolevel,cornerpos[3],cornerpos[7],cornervalues[3],cornervalues[7])
  106.  
  107.     #Create the triangle
  108.     triangles = []
  109.     #for (i=0;triTable[cubeindex][i]!=-1;i+=3) {
  110.     i=0
  111.     while tritable[cubeindex][i] != -1:
  112.         triangles.append([vertlist[tritable[cubeindex][i  ]],
  113.                                    vertlist[tritable[cubeindex][i+1]],
  114.                                    vertlist[tritable[cubeindex][i+2]]])
  115.         i+=3
  116.        
  117.     return triangles
  118.  
  119. def vertexinterp(isolevel,p1,p2,valp1,valp2):
  120.    if (ABS(isolevel-valp1) < 0.00001):
  121.       return p1
  122.    if (ABS(isolevel-valp2) < 0.00001):
  123.       return p2
  124.    if (ABS(valp1-valp2) < 0.00001):
  125.       return p1
  126.    mu = (isolevel - valp1) / (valp2 - valp1);
  127.    p=vec([0,0,0])
  128.    p.x = p1.x + mu * (p2.x - p1.x);
  129.    p.y = p1.y + mu * (p2.y - p1.y);
  130.    p.z = p1.z + mu * (p2.z - p1.z);
  131.  
  132.    return p
  133.  
  134. def genobject(objname,verts=[],faces=[],edges=[]):
  135.     me = bpy.data.meshes.new(objname)  # create a new mesh
  136.     me.from_pydata(verts,edges,faces)
  137.     me.update()      # update the mesh with the new data
  138.     ob = bpy.data.objects.new(objname,me) # create a new object
  139.     ob.data = me          # link the mesh data to the object
  140.     scene = bpy.context.scene           # get the current scene
  141.     scene.objects.link(ob)                      # link the object into the scene
  142.     return ob
  143.  
  144. def creategeometry(verts):
  145.     faces=[]
  146.     faceoffset=0
  147.     for ver in verts:
  148.         if len(ver)==4:
  149.             faces.append((faceoffset+0,faceoffset+1,faceoffset+2,faceoffset+3))
  150.             faceoffset+=4
  151.         elif len(ver)==3:
  152.             faces.append((faceoffset+0,faceoffset+1,faceoffset+2))
  153.             faceoffset+=3
  154.     return list(chain.from_iterable(verts)),faces
  155.  
  156. def genobjandremovedoubles(verts):
  157.     verts,faces=creategeometry(verts)
  158.     block=genobject("block",verts,faces)
  159.     selectobj(block)
  160.     bpy.ops.object.editmode_toggle()
  161.     bpy.ops.mesh.select_all(action='SELECT')
  162.     bpy.ops.mesh.remove_doubles(mergedist=0.01)
  163.     bpy.ops.object.editmode_toggle()
  164.     return block
  165.  
  166. def selectobj(obj):
  167.     bpy.ops.object.select_all(action="DESELECT")
  168.     obj.select=True
  169.     bpy.context.scene.objects.active=obj
  170.  
  171. #a threshold function:
  172. borders=[5,5,5]
  173.  
  174. def arange(start, stop, step):
  175.      r = start
  176.      while r < stop:
  177.         yield r
  178.         r += step
  179.  
  180. def cellloop(p0,p1,r):
  181.     for z in arange(p0[2],p1[2],r[2]):
  182.      for y in arange(p0[1],p1[1],r[1]):
  183.       for x in arange(p0[0],p1[0],r[0]):
  184.         yield x,y,z        
  185.    
  186. def cornerloop(x,y,z):
  187.     for cz in (0,z):
  188.      for cy,cx in zip((0,y,y,0),(0,0,x,x)):
  189.        yield cx,cy,cz
  190.  
  191. def isosurface(p0,p1,resolution,isolevel,isofunc):
  192.     r=[(x1-x0)/sw for x0,x1,sw in zip(p0,p1,resolution)]
  193.    
  194.     triangles=[]  
  195.     for x,y,z in cellloop(p0,p1,r):
  196.        cornervalues=[]
  197.        cornerpos=[]
  198.        for cx,cy,cz in cornerloop(r[0],r[1],r[2]):
  199.           pos=vec((x+cx,y+cy,z+cz))
  200.           cornerpos.append(pos)
  201.           cornervalues.append(isofunc(pos))
  202.        triangles.extend(polygonise(cornervalues,cornerpos,isolevel))
  203.              
  204.     genobjandremovedoubles(triangles)
  205.  
  206. if __name__=="__main__":
  207.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement