[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [59641] trunk/blender: mesh bisect can now be defined with mouse input

Campbell Barton ideasman42 at gmail.com
Thu Aug 29 20:45:04 CEST 2013


Revision: 59641
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=59641
Author:   campbellbarton
Date:     2013-08-29 18:45:04 +0000 (Thu, 29 Aug 2013)
Log Message:
-----------
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

Modified Paths:
--------------
    trunk/blender/release/scripts/startup/bl_ui/space_view3d_toolbar.py
    trunk/blender/source/blender/editors/mesh/CMakeLists.txt
    trunk/blender/source/blender/editors/mesh/editmesh_tools.c
    trunk/blender/source/blender/editors/mesh/mesh_intern.h
    trunk/blender/source/blender/windowmanager/intern/wm_operators.c

Added Paths:
-----------
    trunk/blender/source/blender/editors/mesh/editmesh_bisect.c

Modified: trunk/blender/release/scripts/startup/bl_ui/space_view3d_toolbar.py
===================================================================
--- trunk/blender/release/scripts/startup/bl_ui/space_view3d_toolbar.py	2013-08-29 18:37:27 UTC (rev 59640)
+++ trunk/blender/release/scripts/startup/bl_ui/space_view3d_toolbar.py	2013-08-29 18:45:04 UTC (rev 59641)
@@ -174,8 +174,9 @@
         col.operator("mesh.subdivide")
         col.operator("mesh.loopcut_slide")
         col.operator("mesh.duplicate_move", text="Duplicate")
-        col.operator("mesh.spin")
-        col.operator("mesh.screw")
+        row = col.row(align=True)
+        row.operator("mesh.spin")
+        row.operator("mesh.screw")
 
         row = col.row(align=True)
         props = row.operator("mesh.knife_tool", text="Knife")
@@ -185,6 +186,7 @@
         props.use_occlude_geometry = False
         props.only_selected = True
         col.operator("mesh.knife_project")
+        col.operator("mesh.bisect")
 
         col = layout.column(align=True)
         col.label(text="Remove:")

Modified: trunk/blender/source/blender/editors/mesh/CMakeLists.txt
===================================================================
--- trunk/blender/source/blender/editors/mesh/CMakeLists.txt	2013-08-29 18:37:27 UTC (rev 59640)
+++ trunk/blender/source/blender/editors/mesh/CMakeLists.txt	2013-08-29 18:45:04 UTC (rev 59641)
@@ -42,6 +42,7 @@
 	editface.c
 	editmesh_add.c
 	editmesh_bevel.c
+	editmesh_bisect.c
 	editmesh_extrude.c
 	editmesh_inset.c
 	editmesh_knife.c

Added: trunk/blender/source/blender/editors/mesh/editmesh_bisect.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/editmesh_bisect.c	                        (rev 0)
+++ trunk/blender/source/blender/editors/mesh/editmesh_bisect.c	2013-08-29 18:45:04 UTC (rev 59641)
@@ -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);

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list