[Bf-blender-cvs] [cd3c31b2c02] blender2.8: Tool System: experimental low-poly construction

Campbell Barton noreply at git.blender.org
Thu Oct 26 09:36:04 CEST 2017


Commit: cd3c31b2c02ed024be2d772e37da73d9aa4dc220
Author: Campbell Barton
Date:   Wed Oct 25 15:42:08 2017 +1100
Branches: blender2.8
https://developer.blender.org/rBcd3c31b2c02ed024be2d772e37da73d9aa4dc220

Tool System: experimental low-poly construction

Tool for creating polygons, exact usage may change based on feedback.

LMB to add faces at boundaries (tris from edges, quads from verts).
- Ctrl splits edges
- Alt to dissolve edges/verts.

Works well with vertex snap & auto-merge.

This uses selection hover but isn't intended to introduce more widely
pre-selection highlighting, at least it will be restricted to this tool.

===================================================================

M	release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
M	source/blender/editors/mesh/CMakeLists.txt
A	source/blender/editors/mesh/editmesh_polybuild.c
M	source/blender/editors/mesh/mesh_intern.h
M	source/blender/editors/mesh/mesh_ops.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
index b03efce87c4..71e41850a51 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
@@ -109,6 +109,19 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
                 ("mesh.rip_edge_move", dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
                  dict(type='ACTIONMOUSE', value='PRESS')),
             )),
+
+            ("Poly Build", None, (
+                ("mesh.polybuild_face_at_cursor_move",
+                 dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
+                 dict(type='ACTIONMOUSE', value='PRESS')),
+                ("mesh.polybuild_split_at_cursor_move",
+                 dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
+                 dict(type='ACTIONMOUSE', value='PRESS', ctrl=True)),
+                ("mesh.polybuild_dissolve_at_cursor", dict(), dict(type='ACTIONMOUSE', value='CLICK', alt=True)),
+                ("mesh.polybuild_hover", dict(use_boundary=False), dict(type='MOUSEMOVE', value='ANY', alt=True)),
+                ("mesh.polybuild_hover", dict(use_boundary=True), dict(type='MOUSEMOVE', value='ANY', any=True)),
+            )),
+
             ("Knife", None, (("mesh.knife_tool", dict(wait_for_input=False), dict(type='ACTIONMOUSE', value='PRESS')),)),
             ("Bisect", None, (("mesh.bisect", dict(), dict(type='EVT_TWEAK_A', value='ANY')),)),
             ("Extrude Cursor", None,
diff --git a/source/blender/editors/mesh/CMakeLists.txt b/source/blender/editors/mesh/CMakeLists.txt
index 4607ed79c3b..80e1187609c 100644
--- a/source/blender/editors/mesh/CMakeLists.txt
+++ b/source/blender/editors/mesh/CMakeLists.txt
@@ -52,6 +52,7 @@ set(SRC
 	editmesh_knife_project.c
 	editmesh_loopcut.c
 	editmesh_path.c
+	editmesh_polybuild.c
 	editmesh_rip.c
 	editmesh_rip_edge.c
 	editmesh_select.c
diff --git a/source/blender/editors/mesh/editmesh_polybuild.c b/source/blender/editors/mesh/editmesh_polybuild.c
new file mode 100644
index 00000000000..6600874655b
--- /dev/null
+++ b/source/blender/editors/mesh/editmesh_polybuild.c
@@ -0,0 +1,539 @@
+/*
+ * ***** 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/mesh/editmesh_polybuild.c
+ *  \ingroup edmesh
+ *
+ * Tools to implement polygon building tool,
+ * an experimental tool for quickly constructing/manipulating faces.
+ */
+
+#include "DNA_object_types.h"
+
+#include "BLI_math.h"
+
+#include "BKE_context.h"
+#include "BKE_report.h"
+#include "BKE_editmesh.h"
+#include "BKE_mesh.h"
+
+#include "WM_types.h"
+
+#include "ED_mesh.h"
+#include "ED_screen.h"
+#include "ED_transform.h"
+#include "ED_view3d.h"
+
+#include "bmesh.h"
+
+#include "mesh_intern.h"  /* own include */
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "WM_api.h"
+
+/* -------------------------------------------------------------------- */
+/** \name Local Utilities
+ * \{ */
+
+static void edbm_selectmode_ensure(Scene *scene, BMEditMesh *em, short selectmode)
+{
+	if ((scene->toolsettings->selectmode & selectmode) == 0) {
+		scene->toolsettings->selectmode |= selectmode;
+		em->selectmode = scene->toolsettings->selectmode;
+		EDBM_selectmode_set(em);
+	}
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Face At Cursor
+ * \{ */
+
+static int edbm_polybuild_face_at_cursor_invoke(
+        bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+{
+	ViewContext vc;
+	float center[3];
+	bool changed = false;
+
+	em_setup_viewcontext(C, &vc);
+	Object *obedit = CTX_data_edit_object(C);
+	BMEditMesh *em = BKE_editmesh_from_object(obedit);
+	BMesh *bm = em->bm;
+	BMElem *ele_act = BM_mesh_active_elem_get(bm);
+
+	invert_m4_m4(vc.obedit->imat, vc.obedit->obmat);
+	ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
+
+	edbm_selectmode_ensure(vc.scene, vc.em, SCE_SELECT_VERTEX);
+
+	if (ele_act == NULL || ele_act->head.htype == BM_FACE) {
+		/* Just add vert */
+		copy_v3_v3(center, ED_view3d_cursor3d_get(vc.scene, vc.v3d));
+		mul_v3_m4v3(center, vc.obedit->obmat, center);
+		ED_view3d_win_to_3d_int(vc.v3d, vc.ar, center, event->mval, center);
+		mul_m4_v3(vc.obedit->imat, center);
+
+		BMVert *v_new = BM_vert_create(bm, center, NULL, BM_CREATE_NOP);
+		EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+		BM_vert_select_set(bm, v_new, true);
+		changed = true;
+	}
+	else if (ele_act->head.htype == BM_EDGE) {
+		BMEdge *e_act = (BMEdge *)ele_act;
+		BMFace *f_reference = e_act->l ? e_act->l->f : NULL;
+
+		mid_v3_v3v3(center, e_act->v1->co, e_act->v2->co);
+		mul_m4_v3(vc.obedit->obmat, center);
+		ED_view3d_win_to_3d_int(vc.v3d, vc.ar, center, event->mval, center);
+		mul_m4_v3(vc.obedit->imat, center);
+
+		BMVert *v_tri[3];
+		v_tri[0] = e_act->v1;
+		v_tri[1] = e_act->v2;
+		v_tri[2] = BM_vert_create(bm, center, NULL, BM_CREATE_NOP);
+		if (e_act->l && e_act->l->v == v_tri[0]) {
+			SWAP(BMVert *, v_tri[0], v_tri[1]);
+		}
+		// BMFace *f_new =
+		BM_face_create_verts(bm, v_tri, 3, f_reference, BM_CREATE_NOP, true);
+
+		EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+		BM_vert_select_set(bm, v_tri[2], true);
+		changed = true;
+	}
+	else if (ele_act->head.htype == BM_VERT) {
+		BMVert *v_act = (BMVert *)ele_act;
+		BMEdge *e_pair[2] = {NULL};
+
+		for (uint allow_wire = 0; allow_wire < 2 && (e_pair[1] == NULL); allow_wire++) {
+			int i = 0;
+			BMEdge *e_iter = v_act->e;
+			do {
+				if ((BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN) == false) &&
+				    (allow_wire ? BM_edge_is_wire(e_iter) : BM_edge_is_boundary(e_iter)))
+				{
+					if (i == 2) {
+						e_pair[0] = e_pair[1] = NULL;
+						break;
+					}
+					e_pair[i++] = e_iter;
+				}
+			} while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v_act)) != v_act->e);
+		}
+
+		if (e_pair[1] != NULL) {
+			/* Quad from edge pair. */
+			if (BM_edge_calc_length_squared(e_pair[0]) <
+			    BM_edge_calc_length_squared(e_pair[1]))
+			{
+				SWAP(BMEdge *, e_pair[0], e_pair[1]);
+			}
+
+			BMFace *f_reference = e_pair[0]->l ? e_pair[0]->l->f : NULL;
+
+			mul_v3_m4v3(center, vc.obedit->obmat, v_act->co);
+			ED_view3d_win_to_3d_int(vc.v3d, vc.ar, center, event->mval, center);
+			mul_m4_v3(vc.obedit->imat, center);
+
+			BMVert *v_quad[4];
+			v_quad[0] = v_act;
+			v_quad[1] = BM_edge_other_vert(e_pair[0], v_act);
+			v_quad[2] = BM_vert_create(bm, center, NULL, BM_CREATE_NOP);
+			v_quad[3] = BM_edge_other_vert(e_pair[1], v_act);
+			if (e_pair[0]->l && e_pair[0]->l->v == v_quad[0]) {
+				SWAP(BMVert *, v_quad[1], v_quad[3]);
+			}
+			// BMFace *f_new =
+			BM_face_create_verts(bm, v_quad, 4, f_reference, BM_CREATE_NOP, true);
+
+			EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+			BM_vert_select_set(bm, v_quad[2], true);
+			changed = true;
+		}
+		else {
+			/* Just add edge */
+			mul_m4_v3(vc.obedit->obmat, center);
+			ED_view3d_win_to_3d_int(vc.v3d, vc.ar, v_act->co, event->mval, center);
+			mul_m4_v3(vc.obedit->imat, center);
+
+			BMVert *v_new = BM_vert_create(bm, center, NULL, BM_CREATE_NOP);
+
+			BM_edge_create(bm, v_act, v_new, NULL, BM_CREATE_NOP);
+
+			BM_vert_select_set(bm, v_new, true);
+		}
+	}
+
+	if (changed) {
+		BM_select_history_clear(bm);
+
+		EDBM_mesh_normals_update(em);
+		EDBM_update_generic(em, true, true);
+
+		WM_event_add_mousemove(C);
+
+		return OPERATOR_FINISHED;
+	}
+	else {
+		return OPERATOR_CANCELLED;
+	}
+}
+
+void MESH_OT_polybuild_face_at_cursor(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name = "Poly Build Face At Cursor";
+	ot->idname = "MESH_OT_polybuild_face_at_cursor";
+	ot->description = "";
+
+	/* api callbacks */
+	ot->invoke = edbm_polybuild_face_at_cursor_invoke;
+	ot->poll = EDBM_view3d_poll;
+
+	/* flags */
+	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+	/* to give to transform */
+	Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR_DUMMY);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Split At Cursor
+ * \{ */
+
+static int edbm_polybuild_split_at_cursor_invoke(
+        bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+{
+	ViewContext vc;
+	float center[3];
+	bool changed = false;
+
+	em_setup_viewcontext(C, &vc);
+	Object *obedit = CTX_data_edit_object(C);
+	BMEditMesh *em = BKE_editmesh_from_object(obedit);
+	BMesh *bm = em->bm;
+
+	invert_m4_m4(vc.obedit->imat, vc.obedit->obmat);
+	ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
+
+	edbm_selectmode_ensure(vc.scene, vc.em, SCE_SELECT_VERTEX);
+
+	BMElem *ele_act = BM_mesh_active_elem_get(bm);
+
+	if (ele_act == NULL || ele_act->head.hflag == BM_FACE) {
+		return OPERATOR_PASS_THROUGH;
+	}
+	else if (ele_act->head.htype == BM_EDGE) {
+		BMEdge *e_act = (BMEdge *)ele_act;
+		mid_v3_v3v3(center, e_act->v1->co, e_act->v2->co);
+		mul_m4_v3(vc.obedit->obmat, center);
+		ED_view3d_win_to_3d_int(vc.v3d, vc.ar, center, event->mval, center);
+		mul_m4_v3(vc.obedit->imat, center);
+
+		const float fac = line_point_factor_v3(center, e_act->v1->co, e_act->v2->co);
+		BMVert *v_new = BM_edge_split(bm, e_act, e_act->v1, NULL, CLAMPIS(fac, 0.0f, 1.0f));
+		copy_v3_v3(v_new->co, center);
+
+		EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+		BM_vert_select_set(bm, v_new, true);
+		changed = true;
+	}
+	else if (ele_act->head.htype == BM_VERT) {
+		/* Just do nothing, allow dragging. */
+		return OPERATOR_FINIS

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list