Extrude Widget: Add orientation to topbar
authorCampbell Barton <ideasman42@gmail.com>
Mon, 7 May 2018 19:30:55 +0000 (21:30 +0200)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 7 May 2018 19:40:51 +0000 (21:40 +0200)
Add extrude operator that's intended to work on the current selection
and be activated as a tool.

release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
source/blender/editors/include/ED_transform.h
source/blender/editors/mesh/editmesh_extrude.c
source/blender/editors/mesh/mesh_intern.h
source/blender/editors/mesh/mesh_ops.c
source/blender/editors/transform/transform_manipulator_3d.c

index 4a2a7b5830f935b9a69950092d71870b89c2403a..b7aa7cf1ccf1da82b6e646a63ecada167549f0cf 100644 (file)
@@ -367,14 +367,21 @@ class _defs_edit_mesh:
 
     @ToolDef.from_fn
     def extrude():
+        def draw_settings(context, layout):
+            wm = context.window_manager
+            props = wm.operator_properties_last("mesh.extrude_context_move")
+            props_xform = props.TRANSFORM_OT_translate
+            layout.prop(props_xform, "constraint_orientation")
+
         return dict(
             text="Extrude Region",
             icon="ops.mesh.extrude_region_move",
             widget="MESH_WGT_extrude",
             keymap=(
-                ("mesh.extrude_region_move", dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
+                ("mesh.extrude_context_move", dict(TRANSFORM_OT_translate=dict(release_confirm=True)),
                  dict(type='ACTIONMOUSE', value='PRESS')),
             ),
+            draw_settings=draw_settings,
         )
 
     @ToolDef.from_fn
index 23cc55a239ac56fb472c4eb9a94c49be9175d1a9..e17d02abcd7d16a186138e3692b30e41b2728ac7 100644 (file)
@@ -206,6 +206,8 @@ struct TransformBounds {
 struct TransformCalcParams {
        uint use_only_center : 1;
        uint use_local_axis : 1;
+       /* Use 'Scene.orientation_type' when zero, otherwise subtract one and use. */
+       ushort orientation_type;
 };
 int ED_transform_calc_manipulator_stats(
         const struct bContext *C,
index 04dfeb6b037da890e6444b787ab479549d12f71e..0e1f2f882bdd560cf27c699e9f1856e2ed7b130f 100644 (file)
@@ -40,6 +40,7 @@
 #include "BKE_report.h"
 #include "BKE_editmesh.h"
 #include "BKE_global.h"
+#include "BKE_idprop.h"
 
 #include "RNA_define.h"
 #include "RNA_access.h"
@@ -360,6 +361,8 @@ typedef struct ManipulatorExtrudeGroup {
        struct wmManipulator *axis_arrow;
        /* Redo Z-axis translation. */
        struct wmManipulator *axis_redo;
+
+       wmOperatorType *ot_extrude;
 } ManipulatorExtrudeGroup;
 
 static bool manipulator_mesh_extrude_poll(const bContext *C, wmManipulatorGroupType *wgt)
@@ -387,6 +390,8 @@ static void manipulator_mesh_extrude_setup(const bContext *UNUSED(C), wmManipula
        man->axis_arrow = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL);
        man->axis_redo = WM_manipulator_new_ptr(wt_grab, mgroup, NULL);
 
+       man->ot_extrude = WM_operatortype_find("MESH_OT_extrude_context_move", true);
+
        UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, man->axis_arrow->color);
        UI_GetThemeColor3fv(TH_MANIPULATOR_SECONDARY, man->axis_redo->color);
 
@@ -400,8 +405,7 @@ static void manipulator_mesh_extrude_setup(const bContext *UNUSED(C), wmManipula
 
        /* New extrude. */
        {
-               wmOperatorType *ot = WM_operatortype_find("MESH_OT_extrude_region_move", true);
-               PointerRNA *ptr = WM_manipulator_operator_set(man->axis_arrow, 0, ot, NULL);
+               PointerRNA *ptr = WM_manipulator_operator_set(man->axis_arrow, 0, man->ot_extrude, NULL);
                {
                        PointerRNA macroptr = RNA_pointer_get(ptr, "TRANSFORM_OT_translate");
                        RNA_boolean_set(&macroptr, "release_confirm", true);
@@ -410,8 +414,7 @@ static void manipulator_mesh_extrude_setup(const bContext *UNUSED(C), wmManipula
        }
        /* Adjust extrude. */
        {
-               wmOperatorType *ot = WM_operatortype_find("MESH_OT_extrude_region_move", true);
-               PointerRNA *ptr = WM_manipulator_operator_set(man->axis_redo, 0, ot, NULL);
+               PointerRNA *ptr = WM_manipulator_operator_set(man->axis_redo, 0, man->ot_extrude, NULL);
                {
                        PointerRNA macroptr = RNA_pointer_get(ptr, "TRANSFORM_OT_translate");
                        RNA_boolean_set(&macroptr, "release_confirm", true);
@@ -432,8 +435,20 @@ static void manipulator_mesh_extrude_refresh(const bContext *C, wmManipulatorGro
        if (G.moving) {
                return;
        }
+
+       int orientation_type;
+       {
+               PointerRNA ot_ptr;
+               WM_operator_last_properties_ensure(man->ot_extrude, &ot_ptr);
+               PointerRNA macroptr = RNA_pointer_get(&ot_ptr, "TRANSFORM_OT_translate");
+               orientation_type = RNA_enum_get(&macroptr, "constraint_orientation");
+       }
+
        struct TransformBounds tbounds;
-       if (!ED_transform_calc_manipulator_stats(C, &(struct TransformCalcParams){0}, &tbounds)) {
+       if (!ED_transform_calc_manipulator_stats(
+                   C, &(struct TransformCalcParams){
+                       .orientation_type = orientation_type + 1,
+                   }, &tbounds)) {
                return;
        }
 
@@ -445,11 +460,17 @@ static void manipulator_mesh_extrude_refresh(const bContext *C, wmManipulatorGro
        WM_manipulator_set_matrix_location(man->axis_redo, tbounds.center);
 
        wmOperator *op = WM_operator_last_redo(C);
-       bool has_redo = (op && STREQ(op->type->idname, "MESH_OT_extrude_region_move"));
+       bool has_redo = (op && op->type == man->ot_extrude);
 
        WM_manipulator_set_flag(man->axis_arrow, WM_MANIPULATOR_HIDDEN, false);
        WM_manipulator_set_flag(man->axis_redo, WM_MANIPULATOR_HIDDEN, !has_redo);
 
+       {
+               wmManipulatorOpElem *mpop = WM_manipulator_operator_get(man->axis_arrow, 0);
+               PointerRNA macroptr = RNA_pointer_get(&mpop->ptr, "TRANSFORM_OT_translate");
+               RNA_enum_set(&macroptr, "constraint_orientation", orientation_type);
+       }
+
        /* Redo with current settings. */
        if (has_redo) {
                /* We could also access this from 'ot->last_properties' */
@@ -555,7 +576,9 @@ static int edbm_extrude_region_exec(bContext *C, wmOperator *op)
                        continue;
                }
 
-               edbm_extrude_mesh(obedit, em, op);
+               if (!edbm_extrude_mesh(obedit, em, op)) {
+                       continue;
+               }
                /* This normally happens when pushing undo but modal operators
                 * like this one don't push undo data until after modal mode is
                 * done.*/
@@ -582,6 +605,58 @@ void MESH_OT_extrude_region(wmOperatorType *ot)
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 
+       Transform_Properties(ot, P_NO_DEFAULTS | P_MIRROR_DUMMY);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Extrude Context Operator
+ *
+ * Guess what to do based on selection.
+ * \{ */
+
+/* extrude without transform */
+static int edbm_extrude_context_exec(bContext *C, wmOperator *op)
+{
+       ViewLayer *view_layer = CTX_data_view_layer(C);
+       uint objects_len = 0;
+       Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
+
+       for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+               Object *obedit = objects[ob_index];
+               BMEditMesh *em = BKE_editmesh_from_object(obedit);
+               if (em->bm->totvertsel == 0) {
+                       continue;
+               }
+
+               edbm_extrude_mesh(obedit, em, op);
+               /* This normally happens when pushing undo but modal operators
+                * like this one don't push undo data until after modal mode is
+                * done.*/
+
+               EDBM_mesh_normals_update(em);
+
+               EDBM_update_generic(em, true, true);
+       }
+       MEM_freeN(objects);
+       return OPERATOR_FINISHED;
+}
+
+void MESH_OT_extrude_context(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Extrude Context";
+       ot->idname = "MESH_OT_extrude_context";
+       ot->description = "Extrude selection";
+
+       /* api callbacks */
+       ot->exec = edbm_extrude_context_exec;
+       ot->poll = ED_operator_editmesh;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
        Transform_Properties(ot, P_NO_DEFAULTS | P_MIRROR_DUMMY);
 
 #ifdef USE_MANIPULATOR
index aefc8d72b72ea2678c9b9ea2cc6e3e14f238d3c6..43677bc6912cb9852749b107cf0077efb39e3c08 100644 (file)
@@ -102,6 +102,7 @@ void MESH_OT_bisect(struct wmOperatorType *ot);
 /* *** editmesh_extrude.c *** */
 void MESH_OT_extrude_repeat(struct wmOperatorType *ot);
 void MESH_OT_extrude_region(struct wmOperatorType *ot);
+void MESH_OT_extrude_context(struct wmOperatorType *ot);
 void MESH_OT_extrude_verts_indiv(struct wmOperatorType *ot);
 void MESH_OT_extrude_edges_indiv(struct wmOperatorType *ot);
 void MESH_OT_extrude_faces_indiv(struct wmOperatorType *ot);
index 6f663ddbf144cc03556ff494881cedca328c1f4a..6552062a0d9992037a4f416a5d6dd57c9c1b440d 100644 (file)
@@ -83,6 +83,7 @@ void ED_operatortypes_mesh(void)
        WM_operatortype_append(MESH_OT_screw);
 
        WM_operatortype_append(MESH_OT_extrude_region);
+       WM_operatortype_append(MESH_OT_extrude_context);
        WM_operatortype_append(MESH_OT_extrude_faces_indiv);
        WM_operatortype_append(MESH_OT_extrude_edges_indiv);
        WM_operatortype_append(MESH_OT_extrude_verts_indiv);
@@ -268,6 +269,13 @@ void ED_operatormacros_mesh(void)
        RNA_enum_set(otmacro->ptr, "proportional", 0);
        RNA_boolean_set(otmacro->ptr, "mirror", false);
 
+       ot = WM_operatortype_append_macro("MESH_OT_extrude_context_move", "Extrude Region and Move",
+                                         "Extrude context and move result", OPTYPE_UNDO | OPTYPE_REGISTER);
+       otmacro = WM_operatortype_macro_define(ot, "MESH_OT_extrude_context");
+       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_extrude_region_shrink_fatten", "Extrude Region and Shrink/Fatten",
                                          "Extrude region and move result", OPTYPE_UNDO | OPTYPE_REGISTER);
        otmacro = WM_operatortype_macro_define(ot, "MESH_OT_extrude_region");
index 5350bf783aa8c9175c6633a888bed8dfa6a4f14a..c3c4abbda372382a40689b466f3f40d0f25befb1 100644 (file)
@@ -616,8 +616,9 @@ int ED_transform_calc_manipulator_stats(
        /* global, local or normal orientation?
         * if we could check 'totsel' now, this should be skipped with no selection. */
        if (ob && !is_gp_edit) {
+               const short orientation_type = params->orientation_type ? (params->orientation_type - 1) : scene->orientation_type;
 
-               switch (scene->orientation_type) {
+               switch (orientation_type) {
 
                        case V3D_MANIP_GLOBAL:
                        {