```
#Im not sure the best way to import these things. Ive heard "wildcard"
#imports are bad? But I'm not sure exactly how to import things correctly
#This seems to work fine
import bpy
import math
from math import *
from mathutils import *
from mathutils import Vector
from mathutils import Matrix
import time
def invRotation(mx):
"""
Finds the matrix that does the inverse rotation of the given matrix but takes
scale out of the way to keep things sane
mx: Matrix - the matrix whose rotation you want to invert
Returns: Matrix - a matrix of the inverse rotation
"""
r = mx.rotation_part()
s = mx.scale_part()
smx = Matrix()
for i in range(0,3):
smx[i][i] = s[i] #should this be 1/s[i] to undo any scaling too?
rmx = r.resize4x4().invert() * smx
return rmx
def section(cut_object, world_pp, world_pno, FILL=False):
"""
Finds the section between a mesh and a plane mesh
cut_me: Blender Mesh - the mesh to be cut
mx: world matrix of mesh
pp: Vector - a point on the plane
pno: Vector - The cutting plane normal
together, pp and pno define the cutting plane
FILL: Boolean - check if you want to fill mesh
Returns: Mesh - the resulting mesh of the cut
"""
#First get the mesh and it's transformation matrix
cut_me=cut_object.data
mx=cut_object.matrix_world
irot=invRotation(mx)
#Now, my plan is to take the plane from world coordinates
#to local (for each object) and then compute the cross section
#after that, just apply the world matrix of the object to the cross
#section and it will be all good....in most cases.
pno=world_pno*mx #this is weird. At first I thought I would need the INVERSE matrix. But this works...any guesses why?
pp=(world_pp-mx.translation_part())*irot #the reverse of scale, rotate, translate, is translate, rotate, scale...
verts = []
edges = []
faces = []
ed_xsect = {} #why is this a dictionary? I don't know
for ed in cut_me.edges:
#get a vector from each edge to a point on the plane
v1index = ed.vertices[0]
v1=cut_me.vertices[v1index].co
co1=v1-pp
v2index=ed.vertices[1]
v2=cut_me.vertices[v2index].co
co2=v2-pp
#project them onto normal
proj1 = co1.project(pno).length
proj2 = co2.project(pno).length
if (proj1 != 0):
angle1=co1.angle(pno)
else: angle1 = 0
if (proj2 != 0):
angle2=co2.angle(pno)
else: angle2 = 0
#Check to see if edge intersects. Also check if coplanar cutting plane
if ((proj1 == 0) or (proj2 == 0) or \
(angle1 > math.pi/2) != (angle2 > math.pi/2)) and \
(proj1+proj2 > 0):
#edge intersects...ill take your word for it :-)
proj1 /= proj1+proj2
co = ((v2-v1)*proj1)+v1
verts.append(co)
#store a mapping between the new vertices and the mesh's edges
ed_xsect[ed.key] = len(ed_xsect)
for f in cut_me.faces:
# get the edges that the intersection points form
ps = [ ed_xsect[key] for key in f.edge_keys if key in ed_xsect]
if len(ps) == 2:
edges.append(tuple(ps))
x_me=bpy.data.meshes.new("cross section")
x_me.from_pydata(verts,edges,faces)
#Create a new object and link it to scene
sce = bpy.context.scene
new_ob = bpy.data.objects.new("cross section", x_me)
sce.objects.link(new_ob)
new_ob.matrix_world=mx
return new_ob
```