Fix navmesh creation w/ multiple objects
[blender-staging.git] / source / blender / editors / mesh / editmesh_bisect.c
index b8d53116d669b8a004c19bc3b91196987f877c4a..3a9e278f0395538d93f0eb7526247403d32555a3 100644 (file)
 
 #include "BLI_math.h"
 
+#include "BLT_translation.h"
+
 #include "BKE_global.h"
 #include "BKE_context.h"
 #include "BKE_editmesh.h"
+#include "BKE_report.h"
 
 #include "RNA_define.h"
 #include "RNA_access.h"
@@ -50,7 +53,7 @@
 
 #include "mesh_intern.h"  /* own include */
 
-
+static int mesh_bisect_exec(bContext *C, wmOperator *op);
 
 /* -------------------------------------------------------------------- */
 /* Model Helpers */
@@ -70,6 +73,7 @@ static bool mesh_bisect_interactive_calc(
        wmGesture *gesture = op->customdata;
        BisectData *opdata;
 
+       View3D *v3d = CTX_wm_view3d(C);
        ARegion *ar = CTX_wm_region(C);
        RegionView3D *rv3d = ar->regiondata;
 
@@ -78,10 +82,11 @@ static bool mesh_bisect_interactive_calc(
        int x_end = RNA_int_get(op->ptr, "xend");
        int y_end = RNA_int_get(op->ptr, "yend");
 
+       /* reference location (some point in front of the view) for finding a point on a plane */
        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);
+       const float zfac = ED_view3d_calc_zfac(rv3d, co_ref, NULL);
 
        opdata = gesture->userdata;
 
@@ -94,9 +99,10 @@ static bool mesh_bisect_interactive_calc(
 
        /* cross both to get a normal */
        cross_v3_v3v3(plane_no, co_a, co_b);
+       normalize_v3(plane_no);  /* not needed but nicer for user */
 
        /* point on plane, can use either start or endpoint */
-       ED_view3d_win_to_3d(ar, co_ref, co_a_ss, plane_co);
+       ED_view3d_win_to_3d(v3d, ar, co_ref, co_a_ss, plane_co);
 
        if (opdata->is_first == false)
                EDBM_redo_state_restore(opdata->mesh_backup, em, false);
@@ -108,8 +114,25 @@ static bool mesh_bisect_interactive_calc(
 
 static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
 {
+       Object *obedit = CTX_data_edit_object(C);
+       BMEditMesh *em = BKE_editmesh_from_object(obedit);
        int ret;
 
+       if (em->bm->totedgesel == 0) {
+               BKE_report(op->reports, RPT_ERROR, "Selected edges/faces required");
+               return OPERATOR_CANCELLED;
+       }
+
+       /* if the properties are set or there is no rv3d,
+        * skip model and exec immediately */
+
+       if ((CTX_wm_region_view3d(C) == NULL) ||
+           (RNA_struct_property_is_set(op->ptr, "plane_co") &&
+            RNA_struct_property_is_set(op->ptr, "plane_no")))
+       {
+               return mesh_bisect_exec(C, op);
+       }
+
        ret = WM_gesture_straightline_invoke(C, op, event);
        if (ret & OPERATOR_RUNNING_MODAL) {
                View3D *v3d = CTX_wm_view3d(C);
@@ -117,8 +140,6 @@ static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
                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);
@@ -129,6 +150,9 @@ static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
                G.moving = G_TRANSFORM_EDIT;
                opdata->twtype = v3d->twtype;
                v3d->twtype = 0;
+
+               /* initialize modal callout */
+               ED_area_headerprint(CTX_wm_area(C), IFACE_("LMB: Click and drag to draw cut line"));
        }
        return ret;
 }
@@ -150,9 +174,18 @@ static int mesh_bisect_modal(bContext *C, wmOperator *op, const wmEvent *event)
 
        ret = WM_gesture_straightline_modal(C, op, event);
 
+       /* update or clear modal callout */
+       if (event->type == EVT_MODAL_MAP) {
+               if (event->val == GESTURE_MODAL_BEGIN) {
+                       ED_area_headerprint(CTX_wm_area(C), IFACE_("LMB: Release to confirm cut line"));
+               }
+               else {
+                       ED_area_headerprint(CTX_wm_area(C), NULL);
+               }
+       }
+
        if (ret & (OPERATOR_FINISHED | OPERATOR_CANCELLED)) {
-               if (opdata)
-                       edbm_bisect_exit(C, &opdata_back);
+               edbm_bisect_exit(C, &opdata_back);
        }
 
        return ret;
@@ -192,7 +225,7 @@ static int mesh_bisect_exec(bContext *C, wmOperator *op)
                RNA_property_float_get_array(op->ptr, prop_plane_co, plane_co);
        }
        else {
-               copy_v3_v3(plane_co, give_cursor(scene, v3d));
+               copy_v3_v3(plane_co, ED_view3d_cursor3d_get(scene, v3d));
                RNA_property_float_set_array(op->ptr, prop_plane_co, plane_co);
        }
 
@@ -232,7 +265,7 @@ static int mesh_bisect_exec(bContext *C, wmOperator *op)
 
        invert_m4_m4(imat, obedit->obmat);
        mul_m4_v3(imat, plane_co);
-       mul_mat3_m4_v3(imat, plane_no);
+       mul_transposed_mat3_m4_v3(obedit->obmat, 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",
@@ -253,13 +286,13 @@ static int mesh_bisect_exec(bContext *C, wmOperator *op)
 
                /* Fill */
                BMO_op_initf(
-                       bm, &bmop_fill, op->flag,
+                       bm, &bmop_fill, 0,
                        "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,
+               BMO_op_initf(bm, &bmop_attr, 0,
                             "face_attribute_fill faces=%S use_normals=%b use_data=%b",
                             &bmop_fill, "geom.out", false, true);
                BMO_op_exec(bm, &bmop_attr);
@@ -289,7 +322,7 @@ void MESH_OT_bisect(struct wmOperatorType *ot)
 
        /* identifiers */
        ot->name = "Bisect";
-       ot->description = "Enforce symmetry (both form and topological) across an axis";
+       ot->description = "Cut geometry along a plane (click-drag to define plane)";
        ot->idname = "MESH_OT_bisect";
 
        /* api callbacks */
@@ -303,16 +336,16 @@ void MESH_OT_bisect(struct wmOperatorType *ot)
        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);
+       prop = RNA_def_float_vector(ot->srna, "plane_co", 3, NULL, -1e12f, 1e12f,
+                                   "Plane Point", "A point on the plane", -1e4f, 1e4f);
        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);
+       prop = RNA_def_float_vector(ot->srna, "plane_no", 3, NULL, -1.0f, 1.0f,
+                                   "Plane Normal", "The direction the plane points", -1.0f, 1.0f);
        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_boolean(ot->srna, "clear_outer", false, "Clear Outer", "Remove geometry in front of the plane");
 
        RNA_def_float(ot->srna, "threshold", 0.0001, 0.0, 10.0, "Axis Threshold", "", 0.00001, 0.1);