# Script for splitting a mesh into n components along z axis

I'm trying to divide a mesh into multiple parts along the z axis. I've followed another tutorial and managed this, which divides the mesh into 2 parts, but I can't seem to divide it into more than two. Quite new to blender scripting so I'm not sure how to fix this. Any help would be appreciated, but the solution does need to be a script. The code I'm using at the moment is below.

import bpy, bmesh
from bpy import context as C

bpy.ops.object.mode_set(mode='EDIT')

bm = bmesh.from_edit_mesh(C.object.data)

edges = []

for i in range(-10, 10, 2):
ret = bmesh.ops.bisect_plane(bm, geom=bm.verts[:]+bm.edges[:]+bm.faces[:], plane_co=(0,0,i), plane_no=(0,0,1))
bmesh.ops.split_edges(bm, edges=[e for e in ret['geom_cut'] if isinstance(e, bmesh.types.BMEdge)])

bmesh.update_edit_mesh(C.object.data)

bpy.ops.mesh.separate(type='LOOSE')
bpy.ops.object.mode_set(mode='OBJECT')


Thanks!

## 1 Answer

My guess is you have scaled the mesh and haven't allowed for local space for the bmesh operator(s). Eg if you add a prim cylinder and scale it by z 10 fold, it's local space will still range between -1 to 1 for z for each vert coord. Running the script will only give the 0 plane cut.

Multiplying the plane location by the inverse of the objects matrix world will put the cuts into local space.

import bpy, bmesh
from bpy import context as C
from  mathutils import Vector

# matrix world inverse
mwi = C.object.matrix_world.inverted()
bpy.ops.object.mode_set(mode='EDIT')

bm = bmesh.from_edit_mesh(C.object.data)
geom = bm.verts[:] + bm.edges[:] + bm.faces[:]

for i in range(-10, 10, 2):
j = mwi @ Vector((0, 0, i))        # Blender <3.90: mwi * Vector((0, 0, i))
ret = bmesh.ops.bisect_plane(bm, geom=geom, plane_co=j, plane_no=(0,0,1))
bmesh.ops.split_edges(bm, edges=[e for e in ret['geom_cut'] if isinstance(e, bmesh.types.BMEdge)])

bmesh.update_edit_mesh(C.object.data)

bpy.ops.mesh.separate(type='LOOSE')
bpy.ops.object.mode_set(mode='OBJECT')


Alternatively apply scale before running splits.

bpy.ops.object.transform_apply(scale=True)