Fix T61536: can't snap vertex to another vertex in edit mode using curves
[blender.git] / source / blender / editors / transform / transform.c
index c42e350fd5fba8265d0dfb4802ffff24a61292a2..727706f8ffec6e79fe3ac597a1d115ffc746be55 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * ***** 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
  *
  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
  * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
  */
 
-/** \file blender/editors/transform/transform.c
- *  \ingroup edtransform
+/** \file \ingroup edtransform
  */
 
 #include <stdlib.h>
@@ -72,8 +63,6 @@
 
 #include "DEG_depsgraph.h"
 
-#include "BIF_glutil.h"
-
 #include "GPU_immediate.h"
 #include "GPU_immediate_util.h"
 #include "GPU_matrix.h"
@@ -382,7 +371,8 @@ void projectIntViewEx(TransInfo *t, const float vec[3], int adr[2], const eV3DPr
        if (t->spacetype == SPACE_VIEW3D) {
                if (t->ar->regiontype == RGN_TYPE_WINDOW) {
                        if (ED_view3d_project_int_global(t->ar, vec, adr, flag) != V3D_PROJ_RET_OK) {
-                               adr[0] = (int)2140000000.0f;  /* this is what was done in 2.64, perhaps we can be smarter? */
+                               /* this is what was done in 2.64, perhaps we can be smarter? */
+                               adr[0] = (int)2140000000.0f;
                                adr[1] = (int)2140000000.0f;
                        }
                }
@@ -942,7 +932,7 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
                {TFM_MODAL_TRANSLATE, "TRANSLATE", 0, "Move", ""},
                {TFM_MODAL_ROTATE, "ROTATE", 0, "Rotate", ""},
                {TFM_MODAL_RESIZE, "RESIZE", 0, "Resize", ""},
-               {0, NULL, 0, NULL, NULL}
+               {0, NULL, 0, NULL, NULL},
        };
 
        wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "Transform Modal Map");
@@ -995,7 +985,7 @@ static void transform_event_xyz_constraint(TransInfo *t, short key_type, char cm
                                stopConstraint(t);
                        }
                        else {
-                               setUserConstraint(t, V3D_MANIP_GLOBAL, constraint_axis, msg1);
+                               setUserConstraint(t, V3D_ORIENT_GLOBAL, constraint_axis, msg1);
                        }
                }
                else if (!edit_2d) {
@@ -1003,7 +993,7 @@ static void transform_event_xyz_constraint(TransInfo *t, short key_type, char cm
                                /* First press, constraint to an axis. */
                                t->orientation.index = 0;
                                const short *orientation_ptr = t->orientation.types[t->orientation.index];
-                               const short  orientation = orientation_ptr ? *orientation_ptr : V3D_MANIP_GLOBAL;
+                               const short  orientation = orientation_ptr ? *orientation_ptr : V3D_ORIENT_GLOBAL;
                                if (is_plane == false) {
                                        setUserConstraint(t, orientation, constraint_axis, msg2);
                                }
@@ -1020,7 +1010,7 @@ static void transform_event_xyz_constraint(TransInfo *t, short key_type, char cm
                                }
                                else {
                                        const short *orientation_ptr = t->orientation.types[t->orientation.index];
-                                       const short  orientation = orientation_ptr ? *orientation_ptr : V3D_MANIP_GLOBAL;
+                                       const short  orientation = orientation_ptr ? *orientation_ptr : V3D_ORIENT_GLOBAL;
                                        if (is_plane == false) {
                                                setUserConstraint(t, orientation, constraint_axis, msg2);
                                        }
@@ -1055,7 +1045,8 @@ int transformEvent(TransInfo *t, const wmEvent *event)
 
                copy_v2_v2_int(t->mval, event->mval);
 
-               // t->redraw |= TREDRAW_SOFT; /* Use this for soft redraw. Might cause flicker in object mode */
+               /* Use this for soft redraw. Might cause flicker in object mode */
+               // t->redraw |= TREDRAW_SOFT;
                t->redraw |= TREDRAW_HARD;
 
                if (t->state == TRANS_STARTING) {
@@ -1162,7 +1153,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
                                if (ELEM(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL, TFM_EDGE_SLIDE, TFM_VERT_SLIDE)) {
 
                                        /* Scale isn't normally very useful after extrude along normals, see T39756 */
-                                       if ((t->con.mode & CON_APPLY) && (t->con.orientation == V3D_MANIP_NORMAL)) {
+                                       if ((t->con.mode & CON_APPLY) && (t->con.orientation == V3D_ORIENT_NORMAL)) {
                                                stopConstraint(t);
                                        }
 
@@ -1381,7 +1372,8 @@ int transformEvent(TransInfo *t, const wmEvent *event)
                                                }
                                                else {
                                                        if (event->shift) {
-                                                               /* bit hackish... but it prevents mmb select to print the orientation from menu */
+                                                               /* bit hackish... but it prevents mmb select to print the
+                                                                * orientation from menu */
                                                                float mati[3][3];
                                                                strcpy(t->spacename, "global");
                                                                unit_m3(mati);
@@ -1985,7 +1977,8 @@ static void drawTransformView(const struct bContext *C, ARegion *ar, void *arg)
        }
 }
 
-/* just draw a little warning message in the top-right corner of the viewport to warn that autokeying is enabled */
+/* just draw a little warning message in the top-right corner of the viewport
+ * to warn that autokeying is enabled */
 static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *ar)
 {
        rcti rect;
@@ -2145,7 +2138,7 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
                if (t->spacetype == SPACE_VIEW3D) {
                        if ((prop = RNA_struct_find_property(op->ptr, "constraint_orientation")) &&
                            !RNA_property_is_set(op->ptr, prop) &&
-                           (t->orientation.user != V3D_MANIP_CUSTOM_MATRIX))
+                           (t->orientation.user != V3D_ORIENT_CUSTOM_MATRIX))
                        {
                                TransformOrientationSlot *orient_slot = &t->scene->orientation_slots[SCE_ORIENT_DEFAULT];
                                orient_slot->type = t->orientation.user;
@@ -2179,19 +2172,20 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
                 * so use the orientation in the constraint if set */
                short orientation = (t->con.mode & CON_APPLY) ? t->con.orientation : t->orientation.user;
 
-               if (orientation == V3D_MANIP_CUSTOM) {
+               if (orientation == V3D_ORIENT_CUSTOM) {
                        const int orientation_index_custom = BKE_scene_transform_orientation_get_index(
                                t->scene, t->orientation.custom);
 
-                       /* Maybe we need a t->con.custom_orientation? Seems like it would always match t->orientation.custom. */
-                       orientation = V3D_MANIP_CUSTOM + orientation_index_custom;
-                       BLI_assert(orientation >= V3D_MANIP_CUSTOM);
+                       /* Maybe we need a t->con.custom_orientation?
+                        * Seems like it would always match t->orientation.custom. */
+                       orientation = V3D_ORIENT_CUSTOM + orientation_index_custom;
+                       BLI_assert(orientation >= V3D_ORIENT_CUSTOM);
                }
 
                RNA_float_set_array(op->ptr, "constraint_matrix", &t->spacemtx[0][0]);
 
                /* Use 'constraint_matrix' instead. */
-               if (orientation != V3D_MANIP_CUSTOM_MATRIX) {
+               if (orientation != V3D_ORIENT_CUSTOM_MATRIX) {
                        RNA_enum_set(op->ptr, "constraint_orientation", orientation);
                }
 
@@ -2378,9 +2372,13 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
 
        initSnapSpatial(t, t->snap_spatial);
 
-       /* EVIL! posemode code can switch translation to rotate when 1 bone is selected. will be removed (ton) */
+       /* EVIL! posemode code can switch translation to rotate when 1 bone is selected.
+        * will be removed (ton) */
+
        /* EVIL2: we gave as argument also texture space context bit... was cleared */
-       /* EVIL3: extend mode for animation editors also switches modes... but is best way to avoid duplicate code */
+
+       /* EVIL3: extend mode for animation editors also switches modes...
+        * but is best way to avoid duplicate code */
        mode = t->mode;
 
        calculatePropRatio(t);
@@ -2600,18 +2598,11 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
                        setUserConstraint(t, t->orientation.user, t->con.mode, "%s");
                }
        }
-       /* Apply values_modal_offset (after we have constraints). */
+
+       /* Don't write into the values when non-modal because they are already set from operator redo values. */
        if (t->flag & T_MODAL) {
-               if (!is_zero_v3(t->values_modal_offset)) {
-                       float values_ofs[3];
-                       if (t->con.mode & CON_APPLY) {
-                               mul_v3_m3v3(values_ofs, t->spacemtx, t->values_modal_offset);
-                       }
-                       else {
-                               copy_v3_v3(values_ofs, t->values_modal_offset);
-                       }
-                       add_v3_v3(t->values, values_ofs);
-               }
+               /* Setup the mouse input with initial values. */
+               applyMouseInput(t, &t->mouse, t->mouse.imval, t->values);
        }
 
        if ((prop = RNA_struct_find_property(op->ptr, "preserve_clnor"))) {
@@ -2622,8 +2613,10 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
                                        BMEditMesh *em = NULL;// BKE_editmesh_from_object(t->obedit);
                                        bool do_skip = false;
 
-                                       /* Currently only used for two of three most frequent transform ops, can include more ops.
-                                        * Note that scaling cannot be included here, non-uniform scaling will affect normals. */
+                                       /* Currently only used for two of three most frequent transform ops,
+                                        * can include more ops.
+                                        * Note that scaling cannot be included here,
+                                        * non-uniform scaling will affect normals. */
                                        if (ELEM(t->mode, TFM_TRANSLATION, TFM_ROTATION)) {
                                                if (em->bm->totvertsel == em->bm->totvert) {
                                                        /* No need to invalidate if whole mesh is selected. */
@@ -3318,7 +3311,20 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2]))
                                CLAMP(fac, 0.0f, 1.0f);
                        }
 
-                       fac_scaled = fac * td->factor;
+                       if (t->options & CTX_GPENCIL_STROKES) {
+                               /* grease pencil multiframe falloff */
+                               bGPDstroke *gps = (bGPDstroke *)td->extra;
+                               if (gps != NULL) {
+                                       fac_scaled = fac * td->factor * gps->runtime.multi_frame_falloff;
+                               }
+                               else {
+                                       fac_scaled = fac * td->factor;
+                               }
+                       }
+                       else {
+                               fac_scaled = fac * td->factor;
+                       }
+
                        axis_angle_normalized_to_mat3(mat, data->warp_nor, values.angle * fac_scaled);
                        interp_v3_v3v3(delta, warp_sta_local, warp_end_radius_local, fac_scaled);
                        sub_v3_v3(delta, warp_sta_local);
@@ -3517,7 +3523,19 @@ static void applyShear(TransInfo *t, const int UNUSED(mval[2]))
                        add_v3_v3(vec, center);
                        sub_v3_v3(vec, co);
 
-                       mul_v3_fl(vec, td->factor);
+                       if (t->options & CTX_GPENCIL_STROKES) {
+                               /* grease pencil multiframe falloff */
+                               bGPDstroke *gps = (bGPDstroke *)td->extra;
+                               if (gps != NULL) {
+                                       mul_v3_fl(vec, td->factor * gps->runtime.multi_frame_falloff);
+                               }
+                               else {
+                                       mul_v3_fl(vec, td->factor);
+                               }
+                       }
+                       else {
+                               mul_v3_fl(vec, td->factor);
+                       }
 
                        add_v3_v3v3(td->loc, td->iloc, vec);
                }
@@ -4308,7 +4326,7 @@ static void ElementRotation_ex(TransInfo *t, TransDataContainer *tc, TransData *
                                mul_m3_m3m3(smat, td->smtx, totmat);
 
                                /* calculate the total rotatation in eulers */
-                               add_v3_v3v3(eul, td->ext->irot, td->ext->drot); /* we have to correct for delta rot */
+                               add_v3_v3v3(eul, td->ext->irot, td->ext->drot); /* correct for delta rot */
                                eulO_to_mat3(obmat, eul, td->ext->rotOrder);
                                /* mat = transform, obmat = object rotation */
                                mul_m3_m3m3(fmat, smat, obmat);
@@ -4530,7 +4548,7 @@ static void applyTrackball(TransInfo *t, const int UNUSED(mval[2]))
 /* Transform (Normal Rotation) */
 
 /** \name Transform Normal Rotation
-* \{ */
+ * \{ */
 
 static void storeCustomLNorValue(TransDataContainer *tc, BMesh *bm)
 {
@@ -4550,7 +4568,8 @@ void freeCustomNormalArray(TransInfo *t, TransDataContainer *tc, TransCustomData
                BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
                BMesh *bm = em->bm;
 
-               for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) {  /* Restore custom loop normal on cancel */
+               /* Restore custom loop normal on cancel */
+               for (int i = 0; i < lnors_ed_arr->totloop; i++, lnor_ed++) {
                        BKE_lnor_space_custom_normal_to_data(
                                bm->lnor_spacearr->lspacearr[lnor_ed->loop_index], lnor_ed->niloc, lnor_ed->clnors_data);
                }
@@ -6114,9 +6133,12 @@ static void slide_origdata_interp_data_vert(
                        bool co_next_ok;
 
 
-                       /* In the unlikely case that we're next to a zero length edge - walk around the to the next.
+                       /* In the unlikely case that we're next to a zero length edge -
+                        * walk around the to the next.
+                        *
                         * Since we only need to check if the vertex is in this corner,
-                        * its not important _which_ loop - as long as its not overlapping 'sv->co_orig_3d', see: T45096. */
+                        * its not important _which_ loop - as long as its not overlapping
+                        * 'sv->co_orig_3d', see: T45096. */
                        project_plane_normalized_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
                        while (UNLIKELY(((co_prev_ok = (len_squared_v3v3(v_proj[1], v_proj[0]) > eps)) == false) &&
                                        ((l_prev = l_prev->prev) != l->next)))
@@ -6954,7 +6976,9 @@ static bool createEdgeSlideVerts_double_side(TransInfo *t, TransDataContainer *t
                                        else if (l_b == NULL && l_a && (l_a->radial_next != l_a)) l_b = l_a->radial_next;
                                }
                                else if (e->l != NULL) {
-                                       /* if there are non-contiguous faces, we can still recover the loops of the new edges faces */
+                                       /* if there are non-contiguous faces, we can still recover
+                                        * the loops of the new edges faces */
+
                                        /* note!, the behavior in this case means edges may move in opposite directions,
                                         * this could be made to work more usefully. */
 
@@ -8554,7 +8578,8 @@ static void initSeqSlide(TransInfo *t)
 
        copy_v3_fl(t->num.val_inc, t->snap[1]);
        t->num.unit_sys = t->scene->unit.system;
-       /* Would be nice to have a time handling in units as well (supporting frames in addition to "natural" time...). */
+       /* Would be nice to have a time handling in units as well
+        * (supporting frames in addition to "natural" time...). */
        t->num.unit_type[0] = B_UNIT_NONE;
        t->num.unit_type[1] = B_UNIT_NONE;
 }