Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2013-08-29 22:45:04 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-08-29 22:45:04 +0400
commit07994d6f505622ca9c572064f54c9a53525f8662 (patch)
tree27bc213f43d2da05b028f4381da816329dc1eb1a /source
parent973e317461c1c4541e04a742c18ca328dd48b35a (diff)
mesh bisect can now be defined with mouse input
(using cursor + numeric values was too clumsy for defining orientation). once the cut is done numeric input still works as before
Diffstat (limited to 'source')
-rw-r--r--source/blender/editors/mesh/CMakeLists.txt1
-rw-r--r--source/blender/editors/mesh/editmesh_bisect.c320
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c132
-rw-r--r--source/blender/editors/mesh/mesh_intern.h3
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c1
5 files changed, 324 insertions, 133 deletions
diff --git a/source/blender/editors/mesh/CMakeLists.txt b/source/blender/editors/mesh/CMakeLists.txt
index 69ef4715df6..8d91b300ff3 100644
--- a/source/blender/editors/mesh/CMakeLists.txt
+++ b/source/blender/editors/mesh/CMakeLists.txt
@@ -42,6 +42,7 @@ set(SRC
editface.c
editmesh_add.c
editmesh_bevel.c
+ editmesh_bisect.c
editmesh_extrude.c
editmesh_inset.c
editmesh_knife.c
diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c
new file mode 100644
index 00000000000..b8d53116d66
--- /dev/null
+++ b/source/blender/editors/mesh/editmesh_bisect.c
@@ -0,0 +1,320 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2013 by Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/mesh/editmesh_bisect.c
+ * \ingroup edmesh
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_object_types.h"
+
+#include "BLI_math.h"
+
+#include "BKE_global.h"
+#include "BKE_context.h"
+#include "BKE_editmesh.h"
+
+#include "RNA_define.h"
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_mesh.h"
+#include "ED_screen.h"
+#include "ED_view3d.h"
+
+
+#include "mesh_intern.h" /* own include */
+
+
+
+/* -------------------------------------------------------------------- */
+/* Model Helpers */
+
+typedef struct {
+ /* modal only */
+ BMBackup mesh_backup;
+ bool is_first;
+ short twtype;
+} BisectData;
+
+static bool mesh_bisect_interactive_calc(
+ bContext *C, wmOperator *op,
+ BMEditMesh *em,
+ float plane_co[3], float plane_no[3])
+{
+ wmGesture *gesture = op->customdata;
+ BisectData *opdata;
+
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
+
+ int x_start = RNA_int_get(op->ptr, "xstart");
+ int y_start = RNA_int_get(op->ptr, "ystart");
+ int x_end = RNA_int_get(op->ptr, "xend");
+ int y_end = RNA_int_get(op->ptr, "yend");
+
+ const float *co_ref = rv3d->ofs;
+ float co_a_ss[2] = {x_start, y_start}, co_b_ss[2] = {x_end, y_end}, co_delta_ss[2];
+ float co_a[3], co_b[3];
+ float zfac = ED_view3d_calc_zfac(rv3d, co_ref, NULL);
+
+ opdata = gesture->userdata;
+
+ /* view vector */
+ ED_view3d_win_to_vector(ar, co_a_ss, co_a);
+
+ /* view delta */
+ sub_v2_v2v2(co_delta_ss, co_a_ss, co_b_ss);
+ ED_view3d_win_to_delta(ar, co_delta_ss, co_b, zfac);
+
+ /* cross both to get a normal */
+ cross_v3_v3v3(plane_no, co_a, co_b);
+
+ /* point on plane, can use either start or endpoint */
+ ED_view3d_win_to_3d(ar, co_ref, co_a_ss, plane_co);
+
+ if (opdata->is_first == false)
+ EDBM_redo_state_restore(opdata->mesh_backup, em, false);
+
+ opdata->is_first = false;
+
+ return true;
+}
+
+static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ int ret;
+
+ ret = WM_gesture_straightline_invoke(C, op, event);
+ if (ret & OPERATOR_RUNNING_MODAL) {
+ View3D *v3d = CTX_wm_view3d(C);
+
+ wmGesture *gesture = op->customdata;
+ BisectData *opdata;
+
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+
+ opdata = MEM_mallocN(sizeof(BisectData), "inset_operator_data");
+ opdata->mesh_backup = EDBM_redo_state_store(em);
+ opdata->is_first = true;
+ gesture->userdata = opdata;
+
+ /* misc other vars */
+ G.moving = G_TRANSFORM_EDIT;
+ opdata->twtype = v3d->twtype;
+ v3d->twtype = 0;
+ }
+ return ret;
+}
+
+static void edbm_bisect_exit(bContext *C, BisectData *opdata)
+{
+ View3D *v3d = CTX_wm_view3d(C);
+ EDBM_redo_state_free(&opdata->mesh_backup, NULL, false);
+ v3d->twtype = opdata->twtype;
+ G.moving = 0;
+}
+
+static int mesh_bisect_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ wmGesture *gesture = op->customdata;
+ BisectData *opdata = gesture->userdata;
+ BisectData opdata_back = *opdata; /* annoyance, WM_gesture_straightline_modal, frees */
+ int ret;
+
+ ret = WM_gesture_straightline_modal(C, op, event);
+
+ if (ret & (OPERATOR_FINISHED | OPERATOR_CANCELLED)) {
+ if (opdata)
+ edbm_bisect_exit(C, &opdata_back);
+ }
+
+ return ret;
+}
+
+/* End Model Helpers */
+/* -------------------------------------------------------------------- */
+
+
+
+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;
+ 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_plane_co;
+ PropertyRNA *prop_plane_no;
+
+ prop_plane_co = RNA_struct_find_property(op->ptr, "plane_co");
+ if (RNA_property_is_set(op->ptr, prop_plane_co)) {
+ RNA_property_float_get_array(op->ptr, prop_plane_co, plane_co);
+ }
+ else {
+ copy_v3_v3(plane_co, give_cursor(scene, v3d));
+ RNA_property_float_set_array(op->ptr, prop_plane_co, plane_co);
+ }
+
+ prop_plane_no = RNA_struct_find_property(op->ptr, "plane_no");
+ if (RNA_property_is_set(op->ptr, prop_plane_no)) {
+ RNA_property_float_get_array(op->ptr, prop_plane_no, 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, plane_no);
+ }
+
+
+
+ /* -------------------------------------------------------------------- */
+ /* Modal support */
+ /* Note: keep this isolated, exec can work wihout this */
+ if ((op->customdata != NULL) &&
+ mesh_bisect_interactive_calc(C, op, em, plane_co, plane_no))
+ {
+ /* write back to the props */
+ RNA_property_float_set_array(op->ptr, prop_plane_no, plane_no);
+ RNA_property_float_set_array(op->ptr, prop_plane_co, plane_co);
+ }
+ /* End Modal */
+ /* -------------------------------------------------------------------- */
+
+
+
+ bm = em->bm;
+
+ invert_m4_m4(imat, obedit->obmat);
+ mul_m4_v3(imat, plane_co);
+ mul_mat3_m4_v3(imat, 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);
+
+ EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+
+ 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_slot_buffer_hflag_enable(bm, bmop_fill.slots_out, "geom.out", BM_FACE, BM_ELEM_SELECT, true);
+
+ BMO_op_finish(bm, &bmop_attr);
+ BMO_op_finish(bm, &bmop_fill);
+ }
+
+ 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->invoke = mesh_bisect_invoke;
+ ot->modal = mesh_bisect_modal;
+ ot->cancel = WM_gesture_straightline_cancel;
+ 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,
+ "Plane Point", "A point on the plane", -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,
+ "Plane Normal", "The direction the plane points", -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);
+
+ WM_operator_properties_gesture_straightline(ot, CURSOR_EDIT);
+}
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index d23cee407b6..f384ac9c448 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -4435,138 +4435,6 @@ 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);
-
- 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);
-
- EDBM_flag_disable_all(em, BM_ELEM_SELECT);
-
- 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_slot_buffer_hflag_enable(bm, bmop_fill.slots_out, "geom.out", BM_FACE, BM_ELEM_SELECT, true);
-
- BMO_op_finish(bm, &bmop_attr);
- BMO_op_finish(bm, &bmop_fill);
- }
-
- 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,
- "Plane Point", "A point on the plane", -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,
- "Plane Normal", "The direction the plane points", -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);
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index be9243dc7ef..ed026258e4b 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -95,6 +95,8 @@ void MESH_OT_primitive_ico_sphere_add(struct wmOperatorType *ot);
/* *** editmesh_bevel.c *** */
void MESH_OT_bevel(struct wmOperatorType *ot);
+/* *** editmesh_bisect.c *** */
+void MESH_OT_bisect(struct wmOperatorType *ot);
/* *** editmesh_extrude.c *** */
void MESH_OT_extrude_repeat(struct wmOperatorType *ot);
@@ -171,7 +173,6 @@ 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);
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index fbb51702844..b52357a8f46 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -4256,6 +4256,7 @@ static void gesture_straightline_modal_keymap(wmKeyConfig *keyconf)
/* assign map to operators */
WM_modalkeymap_assign(keymap, "IMAGE_OT_sample_line");
WM_modalkeymap_assign(keymap, "PAINT_OT_weight_gradient");
+ WM_modalkeymap_assign(keymap, "MESH_OT_bisect");
}