Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Old Blender 3d slice experiment (circa 2010)
import bpy
target = bpy.context.object
mesh = target.data
#tmat = target.matrix_world
#bpy.ops.object.visual_transform_apply()
#bpy.ops.ed.undo()
# Get a list of the objects bounding box z-coords
zs = [point[2] for point in target.bound_box]
bottom = min(zs)
top = max(zs)
slice = bottom
slice_step = 0.1 # TBD by units and hardware setup
while slice < top:
"""Ideally we would like to have a list of all edges cut by the slice plane.
Since that isn't provided and is too much work to setup I instead divide the
mesh into top and bottom halfs."""
# Create a set containing all verts below z
below = set([vert for vert in mesh.vertices if vert.co.z < slice])
# And a set of all above
above = set([vert for vert in mesh.vertices if vert.co.z >= slice])
assert above.isdisjoint(below) # couldn't hurt to check
# Attempt to slice each face in the mesh
points = list() # Intersect point between edges and the cutting plane
edges = list() # list of [index, index] pairs indexing the points list
for face in mesh.faces:
"""One nice thing about slicing by face is that (excluding pathological cases)
any face that is cut by a plane will be cut across exactly two edges. And since
a face represents the boundary between inside/outside the model we can connect
those two points to create an edge. Indexing the edges to the points ensures
there are no double points""" # What about tris with an edge on the cutting plane?
# This will contain the vert indicies of the resulting edge if the face is cut
ends = list()
for edge in face.edge_keys:
# Edge_keys are pairs of vert indices
v1, v2 = edge
v1 = mesh.vertices[v1]
v2 = mesh.vertices[v2]
s = {v1, v2} # Set of these verts
if s.issubset(above) or s.issubset(below):
# Edge is completely above or below
continue # This edge isn't cut
ev = v2.co - v1.co # Vector from v1 to v2 (the edge)
ev.normalize()
# multiply ev by the scale factor from ev.z to slice and add to v1
point = v1.co + (ev * ((slice - v1.co.z)/ev.z))
if point in points:
index = points.index(point)
else:
points.append(point)
index = len(points)-1
ends.append(index)
if ends:
# Could ends ever contain just one point?
edges.append(ends)
# This is visual output of the slice data, this could be written to some output format...
me = bpy.data.meshes.new('slice') # A number is automatically appended to slices after the first
me.from_pydata(points, edges, [])
me.update()
scn = bpy.context.scene
ob = bpy.data.objects.new('slice', me)
ob.show_x_ray = True
scn.objects.link(ob)
# On to the next slice!
slice += slice_step
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.