Cutting a mesh in half
I have a mesh which I have imported from an OBJ file. I would like to apply Material A to the section of the mesh which is on one side of a given plane, and apply Material B to the section of the mesh which is on the other side of that plane. A potential plane is indicated here as a blue line. Note that it does not necessarily intersect the centre.
To do this, I need to split the any faces which intersect this plane, and select all faces on one side of the plane so that I can apply a material to them. How can I do this in the current versions of Blender?
I've tried using the K knife tool in Z cut-through mode, but the cuts haven't been reliable. Even when they were, after the cut was finished I couldn't figure out how to select only the faces on one side of the cut. (The details were too fine to be reliably selected with any tools I know, such as the C circle select tool.) I tried using the B selection tool, but it only selected the faces on the near-side of the mesh.
We used to have a procedure to cut a mesh using a plane in Blender 2.4, but it involved using mesh boolean tools which appear to have been replaced, and I can't figure out how to adapt it.
Another use for this is for deleting one side before creating a mirrored object.
If i may point to https://blender.stackexchange.com/questions/143100/cut-object-into-two-objects-with-a-plane/158682#158682, i answered there with my (free) add-on, that does exactly what was asked there and if i read it right, here too, using a plane to cut (non-destructive).
I would recommend using the bisect tool (new in Blender 2.69):
- Enter edit mode (Tab), then press Space and type in Bisect, or select Bisect from the toolshelf (under Add).
- Click and drag, to bisect the object.
- Press F6 to bring up the options for the tool, and select clear inner, or clear outer depending on which half you don't want.
If you don't want to delete half, but just want to select it:
- Instead of step 3, press H to hide the loop:
- Hover over the half you want and press L to select linked vertices under the cursor:
- Unhide everything (AltH), leaving you with one half of the object selected:
Thank you, that's incredibly helpful! Do you know if there's a way to just select the other half, instead of deleting it?
Thank you very much. That almost works, but unfortunately the selections created with L sometimes cross over the bisection, even with the middle parts hidden. I'll keep trying to figure it out. Even if I can't get it perfect, you've helped me get a much better result than I had so far.
@JeremyBanks I think you are looking for **Select > Select Loop Inner Region**.
Note that this feature was added in Blender 2.69, which is at present newer than the version in the Ubuntu repositories. You can get a newer version from a PPA: http://askubuntu.com/questions/4586/is-there-a-ppa-for-the-latest-blender-version
@tecywiz121 You could create an n-gon with `F`, then triangulate the mesh with `Ctrl-T`.
A recommended workflow here would be:
- KZC, then drag a perfect vertical line. (Optional for C)
- Menu: Select > Select Loop Inner Region, to select one side of the cut result.(F6 > Select Bigger to select the other side)
- Assign a second material for the selection. Done.
As shown below:
I'd prefer this version over CharlesL's, because I had to cut in the perfect middle and with K + Ctrl you can snap to the exact center of an edge and thus keep full precision.
If you want to create two identical halves from a symmetrical mesh, all you need to do is to tab into Edit Mode and press Numpad 5 then Numpad 1. Now you can press B for Box Select and drag over the vertices to one side of the center line, then delete those vertices.
This method can be used to make Vertex Groups for easy selection, so you can assign materials. Notice that your selection will be limited to the vertex locations, and no new geometry will be created to ensure a straight line.
Just to add a more procedural way to do this cutting thing. This is one solution if using Sverchok Add-On. The cutting is done using Bisect Node, very similar to Blender's Modeling own Bisect operation.
You will end up with 2 new objects in this case, but you can join them if you like.
If you just want to do a temporary bisect you can also use the Bool Modifier.
Create an object with the shape of the cut you want to make, call your object cutout just for easy reference, then select the object you want to cut, add Modifier > Generate > Boolean and on the object select cutout, then select the type of operation you want to make, Intersect, Union or Diference...
Since this is a Modifier, the changes are not applied until you do so, and if you make a copy of the object, you can apply the same Modifier with opposite operation to create the effect you are looking for.
bmeshversion. Using cursor for plane coords
This one popped up today so what the hey. a blatant attempt to improve my people reached
Extended the bmesh bisect plane operator to return the left and right faces, and the cut's edges.
import bpy import bmesh from mathutils.geometry import distance_point_to_plane as dp2p def bisect(bm, plane_co=(0, 0, 0), plane_no=(1, 0, 0)): ret = bmesh.ops.bisect_plane(bm, geom=bm.faces[:] + bm.edges[:] + bm.verts[:], plane_co=plane_co, plane_no=plane_no ) cut = [e for e in ret["geom_cut"] if isinstance(e, bmesh.types.BMEdge)] left =  right =  for f in ret["geom"]: if not isinstance(f, bmesh.types.BMFace): continue left.append(f) if dp2p(f.calc_center_median(), plane_co, plane_no) > 0 else right.append(f) continue return left, cut, right
For the case in question to create new edges at cut and set materials left and right.
Example script append to above and run in object mode
context = bpy.context scene = context.scene cu = scene.cursor ob = context.object # convert cursor coordinates to object space mwi = ob.matrix_world.inverted() plane_co = mwi @ cu.location plane_no = mwi.to_3x3() @ cu.matrix.to_3x3().transposed() # create a bmesh from context object me = ob.data bm = bmesh.new() bm.from_mesh(me) left, cut, right = bisect(bm, plane_co, plane_no) # do something for f in left: f.material_index = 1 for f in right: f.material_index = 2 bm.to_mesh(me) me.update()
Split the cut edges
List of all vert indices in left faces, assigned to a new vertex group
# all left verts left_verts = [v.index for v in set(v for f in left for v in f.verts)] # create and assign to vertex group vg = ob.vertex_groups.new(name="Left") vg.add(left_verts, 1.0, 'REPLACE')