diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_opdefines.c | 2 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_bisect_plane.c | 3 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_symmetrize.c | 5 | ||||
-rw-r--r-- | source/blender/bmesh/tools/bmesh_bisect_plane.c | 46 | ||||
-rw-r--r-- | source/blender/bmesh/tools/bmesh_bisect_plane.h | 3 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_tools.c | 8 |
6 files changed, 38 insertions, 29 deletions
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 14a7bee5d15..3f486482466 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -1129,6 +1129,7 @@ static BMOpDefine bmo_bisect_plane_def = { {"dist", BMO_OP_SLOT_FLT}, /* minimum distance when testing if a vert is exactly on the plane */ {"plane_co", BMO_OP_SLOT_VEC}, /* point on the plane */ {"plane_no", BMO_OP_SLOT_VEC}, /* direction of the plane */ + {"use_snap_center",BMO_OP_SLOT_BOOL}, /* snap axis aligned verts to the center */ {"clear_outer", BMO_OP_SLOT_BOOL}, /* when enabled. remove all geometry on the positive side of the plane */ {"clear_inner", BMO_OP_SLOT_BOOL}, /* when enabled. remove all geometry on the negative side of the plane */ {{'\0'}}, @@ -1775,6 +1776,7 @@ static BMOpDefine bmo_symmetrize_def = { /* slots_in */ {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, {"direction", BMO_OP_SLOT_INT}, + {"dist", BMO_OP_SLOT_FLT}, /* minimum distance */ {{'\0'}}, }, /* slots_out */ diff --git a/source/blender/bmesh/operators/bmo_bisect_plane.c b/source/blender/bmesh/operators/bmo_bisect_plane.c index d651f3974e0..575e6888df0 100644 --- a/source/blender/bmesh/operators/bmo_bisect_plane.c +++ b/source/blender/bmesh/operators/bmo_bisect_plane.c @@ -40,6 +40,7 @@ void bmo_bisect_plane_exec(BMesh *bm, BMOperator *op) { const float dist = BMO_slot_float_get(op->slots_in, "dist"); + const bool use_snap_center = BMO_slot_bool_get(op->slots_in, "use_snap_center"); const bool clear_outer = BMO_slot_bool_get(op->slots_in, "clear_outer"); const bool clear_inner = BMO_slot_bool_get(op->slots_in, "clear_inner"); @@ -64,7 +65,7 @@ void bmo_bisect_plane_exec(BMesh *bm, BMOperator *op) BMO_slot_buffer_flag_enable(bm, op->slots_in, "geom", BM_ALL_NOLOOP, ELE_INPUT); - BM_mesh_bisect_plane(bm, plane, true, + BM_mesh_bisect_plane(bm, plane, use_snap_center, true, ELE_NEW, dist); diff --git a/source/blender/bmesh/operators/bmo_symmetrize.c b/source/blender/bmesh/operators/bmo_symmetrize.c index b1a9950610d..4b538dccb4e 100644 --- a/source/blender/bmesh/operators/bmo_symmetrize.c +++ b/source/blender/bmesh/operators/bmo_symmetrize.c @@ -39,6 +39,7 @@ void bmo_symmetrize_exec(BMesh *bm, BMOperator *op) { + const float dist = BMO_slot_float_get(op->slots_in, "dist"); const int direction = BMO_slot_int_get(op->slots_in, "direction"); const int axis = direction % 3; @@ -63,8 +64,8 @@ void bmo_symmetrize_exec(BMesh *bm, BMOperator *op) /* Cut in half */ BMO_op_initf(bm, &op_bisect, op->flag, - "bisect_plane geom=%s plane_no=%v dist=%f clear_outer=%b", - op, "input", plane_no, 0.00001f, true); + "bisect_plane geom=%s plane_no=%v dist=%f clear_outer=%b use_snap_center=%b", + op, "input", plane_no, dist, true, true); BMO_op_exec(bm, &op_bisect); diff --git a/source/blender/bmesh/tools/bmesh_bisect_plane.c b/source/blender/bmesh/tools/bmesh_bisect_plane.c index 4852b2c9b59..d4d5ddd0f39 100644 --- a/source/blender/bmesh/tools/bmesh_bisect_plane.c +++ b/source/blender/bmesh/tools/bmesh_bisect_plane.c @@ -24,6 +24,13 @@ * \ingroup bmesh * * Cut the geometry in half using a plane. + * + * \par Implementation + * This simply works by splitting tagged edges whos verts span either side of + * the plane, then splitting faces along their dividing verts. + * The only complex case is when a ngon spans the axis multiple times, + * in this case we need to do some extra checks to correctly bisect the ngon. + * see: #bm_face_bisect_verts */ #include <limits.h> @@ -54,7 +61,7 @@ static int plane_point_test_v3(const float plane[4], const float co[3], const float eps, float *r_depth) { - const float f = plane_point_side_v3(co, plane); + const float f = plane_point_side_v3(plane, co); *r_depth = f; if (f <= -eps) return -1; @@ -68,24 +75,11 @@ static int plane_point_test_v3(const float plane[4], const float co[3], const fl * later we may want to move this into some hash lookup * to a separate struct, but for now we can store in BMesh data */ -/** - * Direction -1/0/1 - */ -#define BM_VERT_DIR(v) ((v)->head.index) -/** - * Distance from the plane. - */ -#define BM_VERT_DIST(v) ((v)->no[0]) - -/** - * Temp value for sorting. - */ -#define BM_VERT_SORTVAL(v) ((v)->no[1]) - -/** - * Temp value for sorting. - */ -#define BM_VERT_LOOPINDEX(v) (*((unsigned int *)(&(v)->no[2]))) +#define BM_VERT_DIR(v) ((v)->head.index) /* Direction -1/0/1 */ +#define BM_VERT_DIST(v) ((v)->no[0]) /* Distance from the plane. */ +#define BM_VERT_SORTVAL(v) ((v)->no[1]) /* Temp value for sorting. */ +#define BM_VERT_LOOPINDEX(v) /* The verts index within a face (temp var) */ \ + (*((unsigned int *)(&(v)->no[2]))) /** * Hide flag access @@ -97,6 +91,7 @@ BLI_INLINE void vert_is_center_enable(BMVert *v) { BM_elem_flag_enable(v, BM_ELE BLI_INLINE void vert_is_center_disable(BMVert *v) { BM_elem_flag_disable(v, BM_ELEM_TAG); } BLI_INLINE bool vert_is_center_test(BMVert *v) { return (BM_elem_flag_test(v, BM_ELEM_TAG) != 0); } +/* enable when the edge can be cut */ BLI_INLINE void edge_is_cut_enable(BMEdge *e) { BM_elem_flag_enable(e, BM_ELEM_TAG); } BLI_INLINE void edge_is_cut_disable(BMEdge *e) { BM_elem_flag_disable(e, BM_ELEM_TAG); } BLI_INLINE bool edge_is_cut_test(BMEdge *e) { return (BM_elem_flag_test(e, BM_ELEM_TAG) != 0); } @@ -244,7 +239,7 @@ static void bm_face_bisect_verts(BMesh *bm, BMFace *f, const float plane[4], con float co_mid[2]; /* geometric test before doing face lookups, - * find if the split */ + * find if the split spans a filled region of the polygon. */ mid_v2_v2v2(co_mid, face_verts_proj_2d[BM_VERT_LOOPINDEX(v_a)], face_verts_proj_2d[BM_VERT_LOOPINDEX(v_b)]); @@ -292,14 +287,15 @@ finally: } - /* -------------------------------------------------------------------- */ /* Main logic */ /** * \param use_tag Only bisect tagged edges and faces. + * \param use_snap Snap verts onto the plane. */ -void BM_mesh_bisect_plane(BMesh *bm, float plane[4], const bool use_tag, +void BM_mesh_bisect_plane(BMesh *bm, float plane[4], + const bool use_snap_center, const bool use_tag, const short oflag_new, const float eps) { unsigned int einput_len; @@ -314,8 +310,12 @@ void BM_mesh_bisect_plane(BMesh *bm, float plane[4], const bool use_tag, BMIter iter; BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - BM_VERT_DIR(v) = plane_point_test_v3(v->co, plane, eps, &(BM_VERT_DIST(v))); vert_is_center_disable(v); + + BM_VERT_DIR(v) = plane_point_test_v3(plane, v->co, eps, &(BM_VERT_DIST(v))); + if (use_snap_center && (BM_VERT_DIR(v) == 0)) { + closest_to_plane_v3(v->co, plane, v->co); + } } if (use_tag) { diff --git a/source/blender/bmesh/tools/bmesh_bisect_plane.h b/source/blender/bmesh/tools/bmesh_bisect_plane.h index 8cd04098cd2..bb7c8b357a4 100644 --- a/source/blender/bmesh/tools/bmesh_bisect_plane.h +++ b/source/blender/bmesh/tools/bmesh_bisect_plane.h @@ -27,7 +27,8 @@ * \ingroup bmesh */ -void BM_mesh_bisect_plane(BMesh *bm, float plane[4], const bool use_tag, +void BM_mesh_bisect_plane(BMesh *bm, float plane[4], + const bool use_snap_center, const bool use_tag, const short oflag_new, const float eps); #endif /* __BMESH_BISECT_PLANE_H__ */ diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index a0bb9839ca5..877e62a01f4 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -4441,8 +4441,11 @@ static int mesh_symmetrize_exec(bContext *C, wmOperator *op) BMEditMesh *em = BKE_editmesh_from_object(obedit); BMOperator bmop; - EDBM_op_init(em, &bmop, op, "symmetrize input=%hvef direction=%i", - BM_ELEM_SELECT, RNA_enum_get(op->ptr, "direction")); + const float thresh = RNA_float_get(op->ptr, "threshold"); + + EDBM_op_init(em, &bmop, op, + "symmetrize input=%hvef direction=%i dist=%f", + BM_ELEM_SELECT, RNA_enum_get(op->ptr, "direction"), thresh); BMO_op_exec(em->bm, &bmop); EDBM_flag_disable_all(em, BM_ELEM_SELECT); @@ -4476,6 +4479,7 @@ void MESH_OT_symmetrize(struct wmOperatorType *ot) ot->prop = RNA_def_enum(ot->srna, "direction", symmetrize_direction_items, BMO_SYMMETRIZE_NEGATIVE_X, "Direction", "Which sides to copy from and to"); + RNA_def_float(ot->srna, "threshold", 0.0001, 0.0, 10.0, "Threshold", "", 0.00001, 0.1); } static int mesh_symmetry_snap_exec(bContext *C, wmOperator *op) |