# How to get part of a mesh with Python API, which requires breaking down some faces?

Suppose I have an object, for simplicity, created as a grid and two circles. How can I extract a mesh, which satisfies a condition: x>=0 and y>=0. This implies that the faces associated with the circles have to be bisected. I am wondering if there is a relatively easy solution to this. May be, bmesh.ops.bisect_plane can be of any help in this situation, but I do not know how to apply it.

import bpy

import bmesh

bpy.ops.object.select_all(action='SELECT')

bpy.ops.object.delete()

location=(0.5, 0.5, 0.0), fill_type='NGON')

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

bpy.ops.mesh.select_all(action="DESELECT")

location=(0.5, 0.5, 0.0), fill_type='NGON')

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

bpy.ops.mesh.select_all(action="DESELECT")

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

bpy.ops.mesh.select_all(action="DESELECT")

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

obj = bpy.context.selected_objects[0]


All with bmesh in object mode.

With appropriate bmesh operators

• translate them to desired location
• bisect with YZ plane at origin and clear the inner. Note the plane coordinate is at (0, 0, 0) by default.
• repeat with XZ plane.

Test script, run in object mode. Adds a plane and replaces its mesh.

import bpy
import bmesh
context = bpy.context

bm = bmesh.new()

bmesh.ops.create_circle(bm,
cap_ends=True,
segments=32)

bmesh.ops.create_circle(bm,
cap_ends=True,
segments=32)
bmesh.ops.translate(bm, verts=bm.verts, vec=(0.5, 0.5, 0))
bmesh.ops.create_grid(bm,
x_segments=3,
y_segments=3,
size=4)

# run two bisect planes
def geom(bm):
return bm.faces[:] + bm.edges[:] + bm.verts[:]

bmesh.ops.bisect_plane(bm,
plane_no=(1, 0, 0), # x > 0
geom=geom(bm),
clear_inner=True)
bmesh.ops.bisect_plane(bm,
plane_no=(0, 1, 0), # y > 0
geom=geom(bm),
clear_inner=True)

# quick hack to add object
ob = context.object
bm.to_mesh(ob.data)
ob.data.update()


To pick up from where your script above left off, with a minor change in that the object added in object mode will be the context object (don't rely on it being first in selected objects list), and no need to switch into edit mode from edit mode, can remove a couple of redundant operators.

# create the meshes as in question
ob = context.object
bm = bmesh.new()
bm.from_mesh(obj.data)

# and then pick up script above
# run two bisect planes
def geom(bm):
return bm.faces[:] + bm.edges[:] + bm.verts[:]

bmesh.ops.bisect_plane(bm,
plane_no=(1, 0, 0), # x > 0
geom=geom(bm),
clear_inner=True)
bmesh.ops.bisect_plane(bm,
plane_no=(0, 1, 0), # y > 0
geom=geom(bm),
clear_inner=True)

bm.to_mesh(ob.data)
ob.data.update()

• Thank you @batFINGER. That was really helpful. The only thing is that when I added your code to mine, the bisection planes were shifted - not going through (0,0,0). I think it has something to do with the local and global coordinates. So, I added : bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.transform_apply(location=True, rotation=True, scale=True) before applying bisect_plane, and it worked well. – olbersia Feb 6 at 21:28
• Similarly the local coordinate of global origin plane_co = matrix_world.inverted() * Vector() Please consider accepting and upvoting if answer worked for you. – batFINGER Feb 7 at 4:32