Created
May 22, 2015 18:24
-
-
Save kitsu/1508c120ac6f1174642b to your computer and use it in GitHub Desktop.
Old Blender 3d slice experiment (circa 2010)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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