# Rewriting the Cross Section Script

This is my first attempt at a real script so be nice

My weekend project was to rewrite the Cross Section script/addon for Blender 2.5. If this has already been done, please let me know (or maybe don’t since I have already worked on it ha ha).

As far as I know the first script was written by Yorik and has not been updated yet.

This may become useless if the exact mode in knife cut ever gets back to like 2.49

``````

#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 &gt; math.pi/2) != (angle2 &gt; math.pi/2)) and \
(proj1+proj2 &gt; 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)
new_ob.matrix_world=mx

return new_ob

``````

sorry about the terrible posting…I thought the tabs would have shown up. Here is a video showing it working/not working in different scenarios.

I manually define a plane (3d point and a normal) in world coords and then try and tranform them into each objects local space, then make the section, then tranform it back into world space. It seems that the point is the problem as the normals appear to always work.

also, can I post the .blend or the .py or even a link to a screen cast? It say’s I’m not allowed to post attachments or link in my posts?

Just a tip, your post count has to be above a certain number before you can post links, it’s an anti-spam measure. To post code, scroll down the page and check out the ‘BB code’ link at the bottom of this page…

Randy

Awesome thanks Randy. I edited it appropriately. Some day I’ll be able to post links

is this the one that makes only across on any given object with a plane ?

would like to see the plane cut knife

can you make this one too?

Thanks and happy 2.5

That’s not all the code is it?

Hi Ricky,

This is my first real stab at doing any programming or writing a script (python, blender or otherwise) outside of matlab so I want to get this one figured out and polished before undertaking the plane cut knife since that involves mouse clicks and the angle of the 3d view. The math should be more or less the same so once I get this one behaving properly maybe some of us can get together and make that happen.

-Patrick

@ Dune2k

No that’s definitely not all of it, just the relevant bit for actually computing the cross section. I’ve left out the buttons/panel, the license etc. I have also left out some of the looking for duplication and testing for edges that are coplanar with the cutting plane. But since this isn’t acting “quite right” at the moment, I figured I could start with the core part.

bit as i said is it the script that makes a copy of the cross section with a plane at angle through an object ?

i’m not very good yet with vertices list ect…

definitively would be interested in seeing this plane cut knife in 2.5

it’s very usefull and faster to use the knife tool just place the plane at whaterver angle and cut the objecct in 2 !

thanks

@Ricky

I think we can make that happen. To find out if an edge intersects the plane, we test to see if each of the vertices (belonging to that edge) lies on opposite sides of the plane. So by default, we have already determined on what side of the cutting plane all the vertices are on. This makes it easy to divide the object into two pieces.

Ok, so I “made that happen.” It only does the edges right now. Here it is in action. Give me a few days to clean it up, see what kind of idiotic repetition and unnecessary calculations I have in there. Then I will post it so we can get it polished.

did you think about the plane cut thing!

Thanks

http://www.4shared.com/file/_5_MOTSs/filltesting.html
This is a script I wrote to fill holes in complicated shapes, it works most of the time, but it is in 2.49, if you could convert it, it might solve your filling problem.

does it do the plane cut like in the french knife plane cut we had in 2.49 ?

thanks

Heeey! the forum is back! I haven’t had much time to work on it since I was studying for boards, but, it is in an “almost there” state. The problems it has are as follows.

1. Some of the new faces aren’t connected correctly. Eg a quad which is supposed to have edge keys (0,1)(1,2)(2,3)(3,0) is (0,1)(1,3)(3,2)(2,4)

2. Something is wrong with the matrix transformations. For now, I just have the script make duplicates, apply the matrices, and then calculate the cross section.

3. It leaves all the old vertices on the other half…

number 3 I can fix
number 2 is fine for now, but kind of a pain
number 1, I haven’t brainstormed on.

video to come shortly to show you what I mean.

ok, actually there are more problems than that. It wont cut suzanne and it wont cut a UV sphere…but it will cut an icosphere? And blender crashes after I use it? Life is tough today.

well can you upload the script so we can look at it and may be help!

did you look at the knife plane script to give you some ideas may be!

happy 2.5

Ok, here is just the cross section script. This seems to work in most situations. use at own risk!

http://dl.dropbox.com/u/2586482/cross_section_matrix_apply.py

Usage…

2. In “User Preferences,” activate this addon by checking it
3. Select the object (mesh only!) which you want to “slice”
4. Select the plane which is your cutting tool
5. In the “Object Properties” panel, “Make Cross Section” will appear, indicating which mesh is to be cut, and what the name of your cutting plane is.
6. Click the button

A new object labeled “cross section” should appear. The cutting plane will also have it’s origin shifted to the origin.

Try it with:

an icosphere
a uv sphere
a monkey

Report back initial bugs here.

Bug 1…

Using Blender 2.56a