code cleanup: use const events for modal and invoke operators.
[blender.git] / source / blender / editors / mesh / editmesh_knife.c
index 590bcd5939e154da41d674eadcc47fb1fc971c44..af793c1e0a2fbf1225ea8b73615cf58995915efc 100644 (file)
@@ -41,6 +41,8 @@
 #include "BLI_smallhash.h"
 #include "BLI_memarena.h"
 
+#include "BLF_translation.h"
+
 #include "BKE_DerivedMesh.h"
 #include "BKE_context.h"
 
@@ -102,7 +104,7 @@ typedef struct KnifeEdge {
        ListBase faces;
        int draw;
 
-       BMEdge *e, *oe; /* non-NULL if this is an original edge */
+       BMEdge *e /* , *e_old */; /* non-NULL if this is an original edge */
 } KnifeEdge;
 
 typedef struct BMEdgeHit {
@@ -128,7 +130,7 @@ typedef struct KnifePosData {
        BMFace *bmface;
        int is_space;
 
-       int mval[2]; /* mouse screen position */
+       float mval[2]; /* mouse screen position (may be non-integral if snapped to something) */
 } KnifePosData;
 
 /* struct for properties used while drawing */
@@ -204,27 +206,32 @@ typedef struct KnifeTool_OpData {
 static ListBase *knife_get_face_kedges(KnifeTool_OpData *kcd, BMFace *f);
 
 #if 0
-static void knife_input_ray_cast(KnifeTool_OpData *kcd, const int mval_i[2],
+static void knife_input_ray_cast(KnifeTool_OpData *kcd, const float mval[2],
                                  float r_origin[3], float r_ray[3]);
 #endif
-static void knife_input_ray_segment(KnifeTool_OpData *kcd, const int mval_i[2], const float ofs,
+static void knife_input_ray_segment(KnifeTool_OpData *kcd, const float mval[2], const float ofs,
                                     float r_origin[3], float r_dest[3]);
 
 static void knife_update_header(bContext *C, KnifeTool_OpData *kcd)
 {
-       #define HEADER_LENGTH 190
+       #define HEADER_LENGTH 256
        char header[HEADER_LENGTH];
 
-       BLI_snprintf(header, HEADER_LENGTH, "LMB: define cut lines, Return/Spacebar: confirm, Esc or RMB: cancel, E: new cut, Ctrl: midpoint snap (%s), "
-                    "Shift: ignore snap (%s), C: angle constrain (%s), Z: cut through (%s)",
-                    kcd->snap_midpoints ? "On" : "Off",
-                    kcd->ignore_edge_snapping ?  "On" : "Off",
-                    kcd->angle_snapping ? "On" : "Off",
-                    kcd->cut_through ? "On" : "Off");
+       BLI_snprintf(header, HEADER_LENGTH, IFACE_("LMB: define cut lines, Return/Spacebar: confirm, Esc or RMB: cancel, "
+                                                  "E: new cut, Ctrl: midpoint snap (%s), Shift: ignore snap (%s), "
+                                                  "C: angle constrain (%s), Z: cut through (%s)"),
+                    kcd->snap_midpoints ? IFACE_("On") : IFACE_("Off"),
+                    kcd->ignore_edge_snapping ?  IFACE_("On") : IFACE_("Off"),
+                    kcd->angle_snapping ? IFACE_("On") : IFACE_("Off"),
+                    kcd->cut_through ? IFACE_("On") : IFACE_("Off"));
 
        ED_area_headerprint(CTX_wm_area(C), header);
 }
 
+BLI_INLINE int round_ftoi(float x)
+{
+       return x > 0.0f ?  (int)(x + 0.5f) : (int)(x - 0.5f);
+}
 
 static void knife_project_v3(KnifeTool_OpData *kcd, const float co[3], float sco[3])
 {
@@ -238,8 +245,8 @@ static void knife_pos_data_clear(KnifePosData *kpd)
        kpd->vert = NULL;
        kpd->edge = NULL;
        kpd->bmface = NULL;
-       kpd->mval[0] = 0;
-       kpd->mval[1] = 0;
+       kpd->mval[0] = 0.0f;
+       kpd->mval[1] = 0.0f;
 }
 
 static ListBase *knife_empty_list(KnifeTool_OpData *kcd)
@@ -641,6 +648,7 @@ static void knife_get_vert_faces(KnifeTool_OpData *kcd, KnifeVert *kfv, BMFace *
 {
        BMIter bmiter;
        BMFace *f;
+       Ref *r;
 
        if (kfv->isface && facef) {
                knife_append_list(kcd, lst, facef);
@@ -650,6 +658,11 @@ static void knife_get_vert_faces(KnifeTool_OpData *kcd, KnifeVert *kfv, BMFace *
                        knife_append_list(kcd, lst, f);
                }
        }
+       else {
+               for (r = kfv->faces.first; r; r = r->next) {
+                       knife_append_list(kcd, lst, r->ref);
+               }
+       }
 }
 
 static void knife_get_edge_faces(KnifeTool_OpData *kcd, KnifeEdge *kfe, ListBase *lst)
@@ -776,6 +789,7 @@ static void knife_cut_through(KnifeTool_OpData *kcd)
        kcd->totlinehit = 0;
 
        /* set up for next cut */
+       kcd->curr.vert = lastv;
        kcd->prev = kcd->curr;
 }
 
@@ -1320,7 +1334,7 @@ static void calc_ortho_extent(KnifeTool_OpData *kcd)
 {
        BMIter iter;
        BMVert *v;
-       BMeshbm = kcd->em->bm;
+       BMesh *bm = kcd->em->bm;
        float max_xyz = 0.0f;
        int i;
 
@@ -1420,17 +1434,14 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
 
 /* this works but gives numeric problems [#33400] */
 #if 0
-static void knife_input_ray_cast(KnifeTool_OpData *kcd, const int mval_i[2],
+static void knife_input_ray_cast(KnifeTool_OpData *kcd, const float mval[2],
                                  float r_origin[3], float r_ray[3])
 {
        bglMats mats;
-       float mval[2], imat[3][3];
+       float imat[3][3];
 
        knife_bgl_get_mats(kcd, &mats);
 
-       mval[0] = (float)mval_i[0];
-       mval[1] = (float)mval_i[1];
-
        /* unproject to find view ray */
        ED_view3d_unproject(&mats, r_origin, mval[0], mval[1], 0.0f);
 
@@ -1452,23 +1463,19 @@ static void knife_input_ray_cast(KnifeTool_OpData *kcd, const int mval_i[2],
 }
 #endif
 
-static void knife_input_ray_segment(KnifeTool_OpData *kcd, const int mval_i[2], const float ofs,
+static void knife_input_ray_segment(KnifeTool_OpData *kcd, const float mval[2], const float ofs,
                                     float r_origin[3], float r_origin_ofs[3])
 {
        bglMats mats;
-       float mval[2];
 
        knife_bgl_get_mats(kcd, &mats);
 
-       mval[0] = (float)mval_i[0];
-       mval[1] = (float)mval_i[1];
-
        /* unproject to find view ray */
        ED_view3d_unproject(&mats, r_origin,     mval[0], mval[1], 0.0f);
        ED_view3d_unproject(&mats, r_origin_ofs, mval[0], mval[1], ofs);
 
        /* transform into object space */
-       invert_m4_m4(kcd->ob->imat, kcd->ob->obmat);
+       invert_m4_m4(kcd->ob->imat, kcd->ob->obmat); 
 
        mul_m4_v3(kcd->ob->imat, r_origin);
        mul_m4_v3(kcd->ob->imat, r_origin_ofs);
@@ -1483,7 +1490,7 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float
        float ray[3];
 
        /* unproject to find view ray */
-       knife_input_ray_segment(kcd, kcd->vc.mval, 1.0f, origin, origin_ofs);
+       knife_input_ray_segment(kcd, kcd->curr.mval, 1.0f, origin, origin_ofs);
        sub_v3_v3v3(ray, origin_ofs, origin);
 
        f = BMBVH_RayCast(kcd->bmbvh, origin, ray, co, cageco);
@@ -1641,8 +1648,8 @@ static KnifeEdge *knife_find_closest_edge(KnifeTool_OpData *kcd, float p[3], flo
                                /* update mouse coordinates to the snapped-to edge's screen coordinates
                                 * this is important for angle snap, which uses the previous mouse position */
                                edgesnap = new_knife_vert(kcd, p, cagep);
-                               kcd->curr.mval[0] = (int)edgesnap->sco[0];
-                               kcd->curr.mval[1] = (int)edgesnap->sco[1];
+                               kcd->curr.mval[0] = edgesnap->sco[0];
+                               kcd->curr.mval[1] = edgesnap->sco[1];
 
                        }
                        else {
@@ -1720,8 +1727,8 @@ static KnifeVert *knife_find_closest_vert(KnifeTool_OpData *kcd, float p[3], flo
 
                                /* update mouse coordinates to the snapped-to vertex's screen coordinates
                                 * this is important for angle snap, which uses the previous mouse position */
-                               kcd->curr.mval[0] = (int)curv->sco[0];
-                               kcd->curr.mval[1] = (int)curv->sco[1];
+                               kcd->curr.mval[0] = curv->sco[0];
+                               kcd->curr.mval[1] = curv->sco[1];
                        }
 
                        return curv;
@@ -1740,48 +1747,56 @@ static KnifeVert *knife_find_closest_vert(KnifeTool_OpData *kcd, float p[3], flo
        return NULL;
 }
 
+/* update both kcd->curr.mval and kcd->vc.mval to snap to required angle */
 static void knife_snap_angle(KnifeTool_OpData *kcd)
 {
-       int dx, dy;
+       float dx, dy;
        float w, abs_tan;
 
-       dx = kcd->vc.mval[0] - kcd->prev.mval[0];
-       dy = kcd->vc.mval[1] - kcd->prev.mval[1];
-       if (dx == 0 || dy == 0)
+       dx = kcd->curr.mval[0] - kcd->prev.mval[0];
+       dy = kcd->curr.mval[1] - kcd->prev.mval[1];
+       if (dx == 0.0f && dy == 0.0f)
                return;
 
-       w = (float)dy / (float)dx;
+       if (dx == 0.0f) {
+               kcd->angle_snapping = ANGLE_90;
+               kcd->curr.mval[0] = kcd->prev.mval[0];
+       }
+
+       w = dy / dx;
        abs_tan = fabsf(w);
        if (abs_tan <= 0.4142f) { /* tan(22.5 degrees) = 0.4142 */
                kcd->angle_snapping = ANGLE_0;
-               kcd->vc.mval[1] = kcd->prev.mval[1];
+               kcd->curr.mval[1] = kcd->prev.mval[1];
        }
        else if (abs_tan < 2.4142f) { /* tan(67.5 degrees) = 2.4142 */
                if (w > 0) {
                        kcd->angle_snapping = ANGLE_45;
-                       kcd->vc.mval[1] = kcd->prev.mval[1] + dx;
+                       kcd->curr.mval[1] = kcd->prev.mval[1] + dx;
                }
                else {
                        kcd->angle_snapping = ANGLE_135;
-                       kcd->vc.mval[1] = kcd->prev.mval[1] - dx;
+                       kcd->curr.mval[1] = kcd->prev.mval[1] - dx;
                }
        }
        else {
                kcd->angle_snapping = ANGLE_90;
-               kcd->vc.mval[0] = kcd->prev.mval[0];
+               kcd->curr.mval[0] = kcd->prev.mval[0];
        }
+
+       kcd->vc.mval[0] = round_ftoi(kcd->curr.mval[0]);
+       kcd->vc.mval[1] = round_ftoi(kcd->curr.mval[1]);
 }
 
 /* update active knife edge/vert pointers */
 static int knife_update_active(KnifeTool_OpData *kcd)
 {
+       knife_pos_data_clear(&kcd->curr);
+       kcd->curr.mval[0] = (float)kcd->vc.mval[0];
+       kcd->curr.mval[1] = (float)kcd->vc.mval[1];
        if (kcd->angle_snapping != ANGLE_FREE && kcd->mode == MODE_DRAGGING)
                knife_snap_angle(kcd);
 
-       knife_pos_data_clear(&kcd->curr);
-       kcd->curr.mval[0] = kcd->vc.mval[0];
-       kcd->curr.mval[1] = kcd->vc.mval[1];
-
        /* XXX knife_snap_angle updates the view coordinate mouse values to constrained angles,
         * which current mouse values are set to current mouse values are then used
         * for vertex and edge snap detection, without regard to the exact angle constraint */
@@ -1799,7 +1814,7 @@ static int knife_update_active(KnifeTool_OpData *kcd)
                float origin[3];
                float origin_ofs[3];
 
-               knife_input_ray_segment(kcd, kcd->vc.mval, 1.0f, origin, origin_ofs);
+               knife_input_ray_segment(kcd, kcd->curr.mval, 1.0f, origin, origin_ofs);
 
                closest_to_line_v3(kcd->curr.cage, kcd->prev.cage, origin_ofs, origin);
        }
@@ -1848,7 +1863,7 @@ static void remerge_faces(KnifeTool_OpData *kcd)
        BMOperator bmop;
        int idx;
 
-       BMO_op_initf(bm, &bmop, "beautify_fill faces=%ff constrain_edges=%fe", FACE_NEW, BOUNDARY);
+       BMO_op_initf(bm, &bmop, "beautify_fill faces=%ff edges=%Fe", FACE_NEW, BOUNDARY);
 
        BMO_op_exec(bm, &bmop);
        BMO_slot_buffer_flag_enable(bm, &bmop, "geom.out", BM_FACE, FACE_NEW);
@@ -1979,14 +1994,14 @@ static void knifenet_fill_faces(KnifeTool_OpData *kcd)
                i++;
 
                if (kfe->e && kfe->v1->v == kfe->e->v1 && kfe->v2->v == kfe->e->v2) {
-                       kfe->oe = kfe->e;
+                       kfe->e_old = kfe->e;
                        continue;
                }
 
                j++;
 
                if (kfe->e) {
-                       kfe->oe = kfe->e;
+                       kfe->e_old = kfe->e;
 
                        BMO_elem_flag_enable(bm, kfe->e, DEL);
                        BMO_elem_flag_disable(bm, kfe->e, BOUNDARY);
@@ -2012,13 +2027,13 @@ static void knifenet_fill_faces(KnifeTool_OpData *kcd)
 
                if (!kfe->v1 || !kfe->v2 || kfe->v1->inspace || kfe->v2->inspace)
                        continue;
-               if (!(kfe->oe && kfe->v1->v == kfe->oe->v1 && kfe->v2->v == kfe->oe->v2))
+               if (!(kfe->e_old && kfe->v1->v == kfe->e_old->v1 && kfe->v2->v == kfe->e_old->v2))
                        continue;
 
                k++;
 
                BMO_elem_flag_enable(bm, kfe->e, BOUNDARY);
-               kfe->oe = kfe->e;
+               kfe->e_old = kfe->e;
 
                for (ref = kfe->faces.first; ref; ref = ref->next) {
                        f = ref->ref;
@@ -2081,7 +2096,7 @@ static void knifenet_fill_faces(KnifeTool_OpData *kcd)
                        if (sf_vert->poly_nr > 1 && sf_vert_last->poly_nr > 1) {
                                ScanFillEdge *sf_edge;
                                sf_edge = BLI_scanfill_edge_add(&sf_ctx, sf_vert_last, sf_vert);
-                               if (entry->kfe->oe)
+                               if (entry->kfe->e_old)
                                        sf_edge->f = SF_EDGE_BOUNDARY;  /* mark as original boundary edge */
 
                                BMO_elem_flag_disable(bm, entry->kfe->e->v1, DEL);
@@ -2929,11 +2944,11 @@ static void cage_mapped_verts_callback(void *userData, int index, const float co
        }
 }
 
-static void knifetool_update_mval(KnifeTool_OpData *kcd, int mval[2])
+static void knifetool_update_mval(KnifeTool_OpData *kcd, const int mval_i[2])
 {
        knife_recalc_projmat(kcd);
-       kcd->vc.mval[0] = mval[0];
-       kcd->vc.mval[1] = mval[1];
+       kcd->vc.mval[0] = mval_i[0];
+       kcd->vc.mval[1] = mval_i[1];
 
        if (knife_update_active(kcd)) {
                ED_region_tag_redraw(kcd->ar);
@@ -3019,7 +3034,7 @@ static int knifetool_cancel(bContext *C, wmOperator *op)
        return OPERATOR_CANCELLED;
 }
 
-static int knifetool_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int knifetool_invoke(bContext *C, wmOperator *op, const wmEvent *event)
 {
        KnifeTool_OpData *kcd;
 
@@ -3033,7 +3048,7 @@ static int knifetool_invoke(bContext *C, wmOperator *op, wmEvent *evt)
        WM_event_add_modal_handler(C, op);
 
        kcd = op->customdata;
-       knifetool_update_mval(kcd, evt->mval);
+       knifetool_update_mval(kcd, event->mval);
 
        knife_update_header(C, kcd);
 
@@ -3104,7 +3119,7 @@ wmKeyMap *knifetool_modal_keymap(wmKeyConfig *keyconf)
        return keymap;
 }
 
-static int knifetool_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
 {
        Object *obedit = CTX_data_edit_object(C);
        KnifeTool_OpData *kcd = op->customdata;