forked from bartvdbraak/blender
new mesh bisect tool, available in the mesh menu.
cuts the mesh in half based on the cursor location and the viewport, optionally supports filling the cut area (with uvs. vcols, etc), and removing geometry on either side of the cut.
This commit is contained in:
parent
e203c4c390
commit
c752346cfa
@ -1828,6 +1828,7 @@ class VIEW3D_MT_edit_mesh(Menu):
|
||||
|
||||
layout.operator("mesh.symmetrize")
|
||||
layout.operator("mesh.symmetry_snap")
|
||||
layout.operator("mesh.bisect")
|
||||
layout.operator_menu_enum("mesh.sort_elements", "type", text="Sort Elements...")
|
||||
|
||||
layout.separator()
|
||||
|
@ -4435,6 +4435,133 @@ void MESH_OT_convex_hull(wmOperatorType *ot)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int mesh_bisect_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
|
||||
/* both can be NULL, fallbacks values are used */
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
RegionView3D *rv3d = ED_view3d_context_rv3d(C);
|
||||
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
BMesh *bm = em->bm;
|
||||
BMOperator bmop;
|
||||
float plane_co[3];
|
||||
float plane_no[3];
|
||||
float imat[4][4];
|
||||
|
||||
const float thresh = RNA_float_get(op->ptr, "threshold");
|
||||
const bool use_fill = RNA_boolean_get(op->ptr, "use_fill");
|
||||
const bool clear_inner = RNA_boolean_get(op->ptr, "clear_inner");
|
||||
const bool clear_outer = RNA_boolean_get(op->ptr, "clear_outer");
|
||||
|
||||
PropertyRNA *prop;
|
||||
|
||||
prop = RNA_struct_find_property(op->ptr, "plane_co");
|
||||
if (RNA_property_is_set(op->ptr, prop)) {
|
||||
RNA_property_float_get_array(op->ptr, prop, plane_co);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(plane_co, give_cursor(scene, v3d));
|
||||
RNA_property_float_set_array(op->ptr, prop, plane_co);
|
||||
}
|
||||
|
||||
prop = RNA_struct_find_property(op->ptr, "plane_no");
|
||||
if (RNA_property_is_set(op->ptr, prop)) {
|
||||
RNA_property_float_get_array(op->ptr, prop, plane_no);
|
||||
}
|
||||
else {
|
||||
if (rv3d) {
|
||||
copy_v3_v3(plane_no, rv3d->viewinv[1]);
|
||||
}
|
||||
else {
|
||||
/* fallback... */
|
||||
plane_no[0] = plane_no[1] = 0.0f; plane_no[2] = 1.0f;
|
||||
}
|
||||
RNA_property_float_set_array(op->ptr, prop, plane_no);
|
||||
}
|
||||
|
||||
invert_m4_m4(imat, obedit->obmat);
|
||||
mul_m4_v3(imat, plane_co);
|
||||
mul_mat3_m4_v3(imat, plane_no);
|
||||
normalize_v3(plane_no);
|
||||
|
||||
EDBM_op_init(em, &bmop, op,
|
||||
"bisect_plane geom=%hvef plane_co=%v plane_no=%v dist=%f clear_inner=%b clear_outer=%b",
|
||||
BM_ELEM_SELECT, plane_co, plane_no, thresh, clear_inner, clear_outer);
|
||||
BMO_op_exec(bm, &bmop);
|
||||
|
||||
if (use_fill) {
|
||||
float normal_fill[3];
|
||||
BMOperator bmop_fill;
|
||||
BMOperator bmop_attr;
|
||||
|
||||
normalize_v3_v3(normal_fill, plane_no);
|
||||
if (clear_outer == true && clear_inner == false) {
|
||||
negate_v3(normal_fill);
|
||||
}
|
||||
|
||||
/* Fill */
|
||||
BMO_op_initf(
|
||||
bm, &bmop_fill, op->flag,
|
||||
"triangle_fill edges=%S normal=%v use_dissolve=%b",
|
||||
&bmop, "geom_cut.out", normal_fill, true);
|
||||
BMO_op_exec(bm, &bmop_fill);
|
||||
|
||||
/* Copy Attributes */
|
||||
BMO_op_initf(bm, &bmop_attr, op->flag,
|
||||
"face_attribute_fill faces=%S use_normals=%b use_data=%b",
|
||||
&bmop_fill, "geom.out", false, true);
|
||||
BMO_op_exec(bm, &bmop_attr);
|
||||
BMO_op_finish(bm, &bmop_attr);
|
||||
BMO_op_finish(bm, &bmop_fill);
|
||||
}
|
||||
|
||||
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
|
||||
BMO_slot_buffer_hflag_enable(bm, bmop.slots_out, "geom_cut.out", BM_VERT | BM_EDGE, BM_ELEM_SELECT, true);
|
||||
|
||||
if (!EDBM_op_finish(em, &bmop, op, true)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
else {
|
||||
EDBM_update_generic(em, true, true);
|
||||
EDBM_selectmode_flush(em);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
}
|
||||
|
||||
void MESH_OT_bisect(struct wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
/* identifiers */
|
||||
ot->name = "Bisect";
|
||||
ot->description = "Enforce symmetry (both form and topological) across an axis";
|
||||
ot->idname = "MESH_OT_bisect";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = mesh_bisect_exec;
|
||||
ot->poll = ED_operator_editmesh;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
|
||||
prop = RNA_def_float_vector(ot->srna, "plane_co", 3, NULL, -FLT_MAX, FLT_MAX, "Point", "", -FLT_MAX, FLT_MAX);
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
prop = RNA_def_float_vector(ot->srna, "plane_no", 3, NULL, -FLT_MAX, FLT_MAX, "Direction", "", -FLT_MAX, FLT_MAX);
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
|
||||
RNA_def_boolean(ot->srna, "use_fill", false, "Fill", "Fill in the cut");
|
||||
RNA_def_boolean(ot->srna, "clear_inner", false, "Clear Inner", "Remove geometry behind the plane");
|
||||
RNA_def_boolean(ot->srna, "clear_outer", false, "Clear Outer", "Remove geometry infront of the plane");
|
||||
|
||||
RNA_def_float(ot->srna, "threshold", 0.0001, 0.0, 10.0, "Axis Threshold", "", 0.00001, 0.1);
|
||||
|
||||
}
|
||||
|
||||
static int mesh_symmetrize_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
|
@ -171,6 +171,7 @@ void MESH_OT_edge_split(struct wmOperatorType *ot);
|
||||
void MESH_OT_bridge_edge_loops(struct wmOperatorType *ot);
|
||||
void MESH_OT_wireframe(struct wmOperatorType *ot);
|
||||
void MESH_OT_convex_hull(struct wmOperatorType *ot);
|
||||
void MESH_OT_bisect(struct wmOperatorType *ot);
|
||||
void MESH_OT_symmetrize(struct wmOperatorType *ot);
|
||||
void MESH_OT_symmetry_snap(struct wmOperatorType *ot);
|
||||
void MESH_OT_shape_propagate_to_all(struct wmOperatorType *ot);
|
||||
|
@ -175,6 +175,7 @@ void ED_operatortypes_mesh(void)
|
||||
WM_operatortype_append(MESH_OT_convex_hull);
|
||||
#endif
|
||||
|
||||
WM_operatortype_append(MESH_OT_bisect);
|
||||
WM_operatortype_append(MESH_OT_symmetrize);
|
||||
WM_operatortype_append(MESH_OT_symmetry_snap);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user