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
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2017-10-25 07:42:08 +0300
committerCampbell Barton <ideasman42@gmail.com>2017-10-26 10:40:27 +0300
commitcd3c31b2c02ed024be2d772e37da73d9aa4dc220 (patch)
tree77d3fbc190127b055e6163c2732a3e1dd97aacea /source/blender/editors/mesh
parent4063c7062a325b611a4a74d42198d06dc22cc26a (diff)
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.
Diffstat (limited to 'source/blender/editors/mesh')
-rw-r--r--source/blender/editors/mesh/CMakeLists.txt1
-rw-r--r--source/blender/editors/mesh/editmesh_polybuild.c539
-rw-r--r--source/blender/editors/mesh/mesh_intern.h5
-rw-r--r--source/blender/editors/mesh/mesh_ops.c25
4 files changed, 569 insertions, 1 deletions
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_FINISHED;
+ }
+
+ 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_split_at_cursor(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Poly Build Split At Cursor";
+ ot->idname = "MESH_OT_polybuild_split_at_cursor";
+ ot->description = "";
+
+ /* api callbacks */
+ ot->invoke = edbm_polybuild_split_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 Dissolve At Cursor
+ *
+ * \{ */
+
+static int edbm_polybuild_dissolve_at_cursor_invoke(
+ bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ ViewContext vc;
+ em_setup_viewcontext(C, &vc);
+ bool changed = false;
+
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+ BMVert *v_act = BM_mesh_active_vert_get(bm);
+ BMEdge *e_act = BM_mesh_active_edge_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 (e_act) {
+ BMLoop *l_a, *l_b;
+ if (BM_edge_loop_pair(e_act, &l_a, &l_b)) {
+ BMFace *f_new = BM_faces_join_pair(bm, l_a, l_b, true);
+ if (f_new) {
+ changed = true;
+ }
+ }
+ }
+ else if (v_act) {
+ if (BM_vert_is_edge_pair(v_act)) {
+ BM_edge_collapse(
+ bm, v_act->e, v_act,
+ true, true);
+ }
+ else {
+ /* too involved to do inline */
+ if (!EDBM_op_callf(em, op,
+ "dissolve_verts verts=%hv use_face_split=%b use_boundary_tear=%b",
+ BM_ELEM_SELECT, false, true))
+ {
+ return OPERATOR_CANCELLED;
+ }
+ }
+ changed = true;
+ }
+
+ if (changed) {
+ EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+
+ 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_dissolve_at_cursor(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Poly Build Dissolve At Cursor";
+ ot->idname = "MESH_OT_polybuild_dissolve_at_cursor";
+ ot->description = "";
+
+ /* api callbacks */
+ ot->invoke = edbm_polybuild_dissolve_at_cursor_invoke;
+ ot->poll = EDBM_view3d_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Cursor Manipulator
+ *
+ * \note This may need its own file, for now not.
+ * \{ */
+
+static BMElem *edbm_hover_preselect(
+ bContext *C,
+ const int mval[2],
+ bool use_boundary)
+{
+ ViewContext vc;
+
+ 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);
+
+ const float mval_fl[2] = {UNPACK2(mval)};
+ float ray_origin[3], ray_direction[3];
+
+ BMElem *ele_best = NULL;
+
+ if (ED_view3d_win_to_ray(
+ vc.ar, vc.v3d, mval_fl,
+ ray_origin, ray_direction, true))
+ {
+ BMEdge *e;
+
+ BMIter eiter;
+ float dist_sq_best = FLT_MAX;
+
+ BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+ if ((BM_elem_flag_test(e, BM_ELEM_HIDDEN) == false) &&
+ (!use_boundary || BM_edge_is_boundary(e)))
+ {
+ float dist_sq_test;
+ float point[3];
+ float depth;
+#if 0
+ dist_sq_test = dist_squared_ray_to_seg_v3(
+ ray_origin, ray_direction,
+ e->v1->co, e->v2->co,
+ point, &depth);
+#else
+ mid_v3_v3v3(point, e->v1->co, e->v2->co);
+ dist_sq_test = dist_squared_to_ray_v3(
+ ray_origin, ray_direction,
+ point, &depth);
+#endif
+
+ if (dist_sq_test < dist_sq_best) {
+ dist_sq_best = dist_sq_test;
+ ele_best = (BMElem *)e;
+ }
+
+ dist_sq_test = dist_squared_to_ray_v3(
+ ray_origin, ray_direction,
+ e->v1->co, &depth);
+ if (dist_sq_test < dist_sq_best) {
+ dist_sq_best = dist_sq_test;
+ ele_best = (BMElem *)e->v1;
+ }
+ dist_sq_test = dist_squared_to_ray_v3(
+ ray_origin, ray_direction,
+ e->v2->co, &depth);
+ if (dist_sq_test < dist_sq_best) {
+ dist_sq_best = dist_sq_test;
+ ele_best = (BMElem *)e->v2;
+ }
+ }
+ }
+ }
+ return ele_best;
+}
+
+/*
+ * Developer note: this is not advocating pre-selection highlighting.
+ * This is just a quick way to test how a tool for interactively editing polygons may work. */
+static int edbm_polybuild_hover_invoke(
+ bContext *C, wmOperator *op, const wmEvent *event)
+{
+ const bool use_boundary = RNA_boolean_get(op->ptr, "use_boundary");
+ ViewContext vc;
+
+ em_setup_viewcontext(C, &vc);
+
+ /* Vertex selection is needed */
+ if ((vc.scene->toolsettings->selectmode & SCE_SELECT_VERTEX) == 0) {
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ /* Don't overwrite click-drag events. */
+ if (use_boundary == false) {
+ /* pass */
+ }
+ else if (vc.win->tweak ||
+ (vc.win->eventstate->check_click &&
+ vc.win->eventstate->prevval == KM_PRESS &&
+ ISMOUSE(vc.win->eventstate->prevtype)))
+ {
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+ BMElem *ele_active = BM_mesh_active_elem_get(bm);
+ BMElem *ele_hover = edbm_hover_preselect(C, event->mval, use_boundary);
+
+ if (ele_hover && (ele_hover != ele_active)) {
+ if (event->shift == 0) {
+ EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+ BM_select_history_clear(bm);
+ }
+ BM_elem_select_set(bm, ele_hover, true);
+ BM_select_history_store(em->bm, ele_hover);
+ BKE_mesh_batch_cache_dirty(obedit->data, BKE_MESH_BATCH_DIRTY_SELECT);
+
+ ED_region_tag_redraw(vc.ar);
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+}
+
+void MESH_OT_polybuild_hover(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Poly Build Hover";
+ ot->idname = "MESH_OT_polybuild_hover";
+ ot->description = "";
+
+ /* api callbacks */
+ ot->invoke = edbm_polybuild_hover_invoke;
+ ot->poll = EDBM_view3d_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_INTERNAL;
+
+ /* properties */
+ RNA_def_boolean(ot->srna, "use_boundary", false, "Boundary", "Select only boundary geometry");
+}
+
+/** \} */
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index 300b21a052d..99342222d52 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -109,6 +109,11 @@ void MESH_OT_dupli_extrude_cursor(struct wmOperatorType *ot);
void MESH_OT_spin(struct wmOperatorType *ot);
void MESH_OT_screw(struct wmOperatorType *ot);
+/* *** editmesh_polybuild.c *** */
+void MESH_OT_polybuild_face_at_cursor(struct wmOperatorType *ot);
+void MESH_OT_polybuild_split_at_cursor(struct wmOperatorType *ot);
+void MESH_OT_polybuild_dissolve_at_cursor(struct wmOperatorType *ot);
+void MESH_OT_polybuild_hover(struct wmOperatorType *ot);
/* *** editmesh_inset.c *** */
void MESH_OT_inset(struct wmOperatorType *ot);
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index 697a92f36d1..b9920f9deca 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -147,7 +147,13 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_rip_edge);
WM_operatortype_append(MESH_OT_blend_from_shape);
WM_operatortype_append(MESH_OT_shape_propagate_to_all);
-
+
+ /* editmesh_polybuild */
+ WM_operatortype_append(MESH_OT_polybuild_face_at_cursor);
+ WM_operatortype_append(MESH_OT_polybuild_split_at_cursor);
+ WM_operatortype_append(MESH_OT_polybuild_dissolve_at_cursor);
+ WM_operatortype_append(MESH_OT_polybuild_hover);
+
WM_operatortype_append(MESH_OT_uv_texture_add);
WM_operatortype_append(MESH_OT_uv_texture_remove);
WM_operatortype_append(MESH_OT_vertex_color_add);
@@ -298,6 +304,23 @@ void ED_operatormacros_mesh(void)
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
RNA_enum_set(otmacro->ptr, "proportional", 0);
RNA_boolean_set(otmacro->ptr, "mirror", false);
+
+
+ ot = WM_operatortype_append_macro(
+ "MESH_OT_polybuild_face_at_cursor_move", "Face At Cursor Move", "",
+ OPTYPE_UNDO | OPTYPE_REGISTER);
+ WM_operatortype_macro_define(ot, "MESH_OT_polybuild_face_at_cursor");
+ otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
+ RNA_enum_set(otmacro->ptr, "proportional", 0);
+ RNA_boolean_set(otmacro->ptr, "mirror", false);
+
+ ot = WM_operatortype_append_macro(
+ "MESH_OT_polybuild_split_at_cursor_move", "Split At Cursor Move", "",
+ OPTYPE_UNDO | OPTYPE_REGISTER);
+ WM_operatortype_macro_define(ot, "MESH_OT_polybuild_split_at_cursor");
+ otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
+ RNA_enum_set(otmacro->ptr, "proportional", 0);
+ RNA_boolean_set(otmacro->ptr, "mirror", false);
}
/* note mesh keymap also for other space? */