Add snapping parameters to transform operators (only Translation, Resize and Rotation...
authorMartin Poirier <theeth@yahoo.com>
Sun, 29 Mar 2009 19:52:53 +0000 (19:52 +0000)
committerMartin Poirier <theeth@yahoo.com>
Sun, 29 Mar 2009 19:52:53 +0000 (19:52 +0000)
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform.h
source/blender/editors/transform/transform_constraints.c
source/blender/editors/transform/transform_ops.c
source/blender/editors/transform/transform_snap.c

index 7faeef0bd6ad4f96aa5e3b477562a6f0914e21c8..091b35c7361f77de3a5304ea6869201f6f274f4c 100644 (file)
@@ -1064,7 +1064,7 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int
                return 0;
        }
 
-       initSnapping(t); // Initialize snapping data AFTER mode flags
+       initSnapping(t, op); // Initialize snapping data AFTER mode flags
 
        /* 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 */
index 655bff341814b8022bb7b04a3c73a591c93be7c0..dfbc22b1e14e3eaded55da62c4037e6c0942ccd9 100644 (file)
@@ -80,8 +80,9 @@ typedef struct NumInput {
 typedef struct TransSnap {
        short   modePoint;
        short   modeTarget;
-       int             mode;
-       int     status;
+       short   mode;
+       short   align;
+       short   status;
        float   snapPoint[3];
        float   snapTarget[3];
        float   snapNormal[3];
@@ -351,8 +352,9 @@ typedef struct TransInfo {
 
 /* transsnap->status */
 #define SNAP_ON                        1
-#define TARGET_INIT            2
-#define POINT_INIT             4
+#define SNAP_FORCED            2
+#define TARGET_INIT            4
+#define POINT_INIT             8
 
 /* transsnap->modePoint */
 #define SNAP_GRID                      0
@@ -522,7 +524,7 @@ typedef enum {
 void snapGrid(TransInfo *t, float *val);
 void snapGridAction(TransInfo *t, float *val, GearsType action);
 
-void initSnapping(struct TransInfo *t);
+void initSnapping(struct TransInfo *t, struct wmOperator *op);
 void applySnapping(TransInfo *t, float *vec);
 void resetSnapping(TransInfo *t);
 int  handleSnapping(TransInfo *t, struct wmEvent *event);
index 510351446cd9c504dd899718d50b47ecef24f499..0064317b57a1b591b06d5418ad2f5b231c11edd2 100644 (file)
@@ -179,7 +179,8 @@ static void postConstraintChecks(TransInfo *t, float vec[3], float pvec[3]) {
                constraintNumInput(t, vec);
        }
 
-       if (t->flag & T_AUTOVALUES)
+       /* autovalues is operator param, use that directly but not if snapping is forced */
+       if (t->flag & T_AUTOVALUES && (t->tsnap.status & SNAP_FORCED) == 0)
        {
                VECCOPY(vec, t->auto_values);
                constraintAutoValues(t, vec);
index 9c68c20329149d0c6be1ae266926a7d36143c677..a45af971d0144e06249f727c5d1136d095f1b88a 100644 (file)
@@ -62,6 +62,14 @@ EnumPropertyItem proportional_mode_types[] = {
                {0, NULL, NULL, NULL}
 };
 
+EnumPropertyItem snap_mode_types[] = {
+               {SCE_SNAP_TARGET_CLOSEST, "CLOSEST", "Closest", ""},
+               {SCE_SNAP_TARGET_CENTER,  "CENTER", "Center", ""},
+               {SCE_SNAP_TARGET_MEDIAN,  "MEDIAN", "Median", ""},
+               {SCE_SNAP_TARGET_ACTIVE,  "ACTIVE", "Active", ""},
+               {0, NULL, NULL, NULL}
+};
+
 EnumPropertyItem proportional_falloff_types[] = {
                {PROP_SMOOTH, "SMOOTH", "Smooth", ""},
                {PROP_SPHERE, "SPHERE", "Sphere", ""},
@@ -262,7 +270,19 @@ void Properties_Proportional(struct wmOperatorType *ot)
        RNA_def_enum(ot->srna, "proportional", proportional_mode_types, 0, "Proportional Edition", "");
        RNA_def_enum(ot->srna, "proportional_editing_falloff", prop_mode_items, 0, "Proportional Editing Falloff", "Falloff type for proportional editing mode.");
        RNA_def_float(ot->srna, "proportional_size", 1, 0, FLT_MAX, "Proportional Size", "", 0, 100);
+}
 
+void Properties_Snapping(struct wmOperatorType *ot, short align)
+{
+       RNA_def_boolean(ot->srna, "snap", 0, "Snap to Point", "");
+       RNA_def_enum(ot->srna, "snap_mode", snap_mode_types, 0, "Mode", "");
+       RNA_def_float_vector(ot->srna, "snap_point", 3, NULL, -FLT_MAX, FLT_MAX, "Point", "", -FLT_MAX, FLT_MAX);
+       
+       if (align)
+       {
+               RNA_def_boolean(ot->srna, "snap_align", 0, "Align with Point Normal", "");
+               RNA_def_float_vector(ot->srna, "snap_normal", 3, NULL, -FLT_MAX, FLT_MAX, "Normal", "", -FLT_MAX, FLT_MAX);
+       }
 }
 
 void Properties_Constraints(struct wmOperatorType *ot)
@@ -292,6 +312,8 @@ void TFM_OT_translation(struct wmOperatorType *ot)
        RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Edition", "");
 
        Properties_Constraints(ot);
+       
+       Properties_Snapping(ot, 1);
 }
 
 void TFM_OT_resize(struct wmOperatorType *ot)
@@ -315,6 +337,8 @@ void TFM_OT_resize(struct wmOperatorType *ot)
        RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Edition", "");
 
        Properties_Constraints(ot);
+       
+       Properties_Snapping(ot, 0);
 }
 
 void TFM_OT_rotation(struct wmOperatorType *ot)
@@ -338,6 +362,8 @@ void TFM_OT_rotation(struct wmOperatorType *ot)
        RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Edition", "");
 
        Properties_Constraints(ot);
+       
+       Properties_Snapping(ot, 0);
 }
 
 void TFM_OT_tilt(struct wmOperatorType *ot)
index bf1169072e1983d4443c9e95cb64614b56c3a108..dc32a46a301ef851526c9c095e753db8514f619c 100644 (file)
@@ -43,6 +43,9 @@
 #include "DNA_screen_types.h"
 #include "DNA_userdef_types.h"
 #include "DNA_view3d_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "RNA_access.h"
 
 #include "BLI_arithb.h"
 #include "BLI_editVert.h"
@@ -88,7 +91,7 @@
 
 /********************* PROTOTYPES ***********************/
 
-void setSnappingCallback(TransInfo *t);
+void setSnappingCallback(TransInfo *t, short snap_target);
 
 void ApplySnapTranslation(TransInfo *t, float vec[3]);
 void ApplySnapRotation(TransInfo *t, float *vec);
@@ -208,7 +211,7 @@ int  handleSnapping(TransInfo *t, wmEvent *event)
        {
                /* toggle snap and reinit */
                t->scene->snap_flag ^= SCE_SNAP;
-               initSnapping(t);
+               initSnapping(t, NULL);
                status = 1;
        }
        
@@ -217,7 +220,13 @@ int  handleSnapping(TransInfo *t, wmEvent *event)
 
 void applySnapping(TransInfo *t, float *vec)
 {
-       if ((t->tsnap.status & SNAP_ON) && 
+       if (t->tsnap.status & SNAP_FORCED)
+       {
+               t->tsnap.targetSnap(t);
+       
+               t->tsnap.applySnap(t, vec);
+       }
+       else if ((t->tsnap.status & SNAP_ON) && 
                (t->modifiers & MOD_SNAP_GEARS))
        {
                double current = PIL_check_seconds_timer();
@@ -241,6 +250,8 @@ void applySnapping(TransInfo *t, float *vec)
 void resetSnapping(TransInfo *t)
 {
        t->tsnap.status = 0;
+       t->tsnap.mode = 0;
+       t->tsnap.align = 0;
        t->tsnap.modePoint = 0;
        t->tsnap.modeTarget = 0;
        t->tsnap.last = 0;
@@ -253,14 +264,7 @@ void resetSnapping(TransInfo *t)
 
 int usingSnappingNormal(TransInfo *t)
 {
-       if (t->scene->snap_flag & SCE_SNAP_ROTATE)
-       {
-               return 1;
-       }
-       else
-       {
-               return 0;
-       }
+       return t->tsnap.align;
 }
 
 int validSnappingNormal(TransInfo *t)
@@ -276,19 +280,47 @@ int validSnappingNormal(TransInfo *t)
        return 0;
 }
 
-void initSnapping(TransInfo *t)
+void initSnapping(TransInfo *t, wmOperator *op)
 {
        Scene *scene = t->scene;
        Object *obedit = t->obedit;
+       int snapping = 0;
+       short snap_mode = t->scene->snap_target;
+       
        resetSnapping(t);
        
+       if (op && RNA_struct_find_property(op->ptr, "snap") && RNA_property_is_set(op->ptr, "snap"))
+       {
+               if (RNA_boolean_get(op->ptr, "snap"))
+               {
+                       snapping = 1;
+                       snap_mode = RNA_enum_get(op->ptr, "snap_mode");
+                       
+                       t->tsnap.status |= SNAP_FORCED|POINT_INIT;
+                       RNA_float_get_array(op->ptr, "snap_point", t->tsnap.snapPoint);
+                       
+                       /* snap align only defined in specific cases */
+                       if (RNA_struct_find_property(op->ptr, "snap_align"))
+                       {
+                               t->tsnap.align = RNA_boolean_get(op->ptr, "snap_align");
+                               RNA_float_get_array(op->ptr, "snap_normal", t->tsnap.snapNormal);
+                               Normalize(t->tsnap.snapNormal);
+                       }
+               }
+       }
+       else
+       {
+               snapping = ((scene->snap_flag & SCE_SNAP) == SCE_SNAP);
+               t->tsnap.align = ((t->scene->snap_flag & SCE_SNAP_ROTATE) == SCE_SNAP_ROTATE);
+       }
+       
        if ((t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) && // Only 3D view or UV
                        (t->flag & T_CAMERA) == 0) { // Not with camera selected
-               setSnappingCallback(t);
+               setSnappingCallback(t, snap_mode);
 
                /* Edit mode */
                if (t->tsnap.applySnap != NULL && // A snapping function actually exist
-                       (scene->snap_flag & SCE_SNAP) && // Only if the snap flag is on
+                       (snapping) && // Only if the snap flag is on
                        (obedit != NULL && ELEM(obedit->type, OB_MESH, OB_ARMATURE)) ) // Temporary limited to edit mode meshes or armature
                {
                        t->tsnap.status |= SNAP_ON;
@@ -305,7 +337,7 @@ void initSnapping(TransInfo *t)
                }
                /* Object mode */
                else if (t->tsnap.applySnap != NULL && // A snapping function actually exist
-                       (scene->snap_flag & SCE_SNAP) && // Only if the snap flag is on
+                       (snapping) && // Only if the snap flag is on
                        (obedit == NULL) ) // Object Mode
                {
                        t->tsnap.status |= SNAP_ON;
@@ -325,12 +357,11 @@ void initSnapping(TransInfo *t)
        }
 }
 
-void setSnappingCallback(TransInfo *t)
+void setSnappingCallback(TransInfo *t, short snap_target)
 {
-       Scene *scene = t->scene;
        t->tsnap.calcSnap = CalcSnapGeometry;
 
-       switch(scene->snap_target)
+       switch(snap_target)
        {
                case SCE_SNAP_TARGET_CLOSEST:
                        t->tsnap.modeTarget = SNAP_CLOSEST;
@@ -362,7 +393,7 @@ void setSnappingCallback(TransInfo *t)
                t->tsnap.distance = RotationBetween;
                
                // Can't do TARGET_CENTER with rotation, use TARGET_MEDIAN instead
-               if (scene->snap_target == SCE_SNAP_TARGET_CENTER) {
+               if (snap_target == SCE_SNAP_TARGET_CENTER) {
                        t->tsnap.modeTarget = SNAP_MEDIAN;
                        t->tsnap.targetSnap = TargetSnapMedian;
                }
@@ -372,7 +403,7 @@ void setSnappingCallback(TransInfo *t)
                t->tsnap.distance = ResizeBetween;
                
                // Can't do TARGET_CENTER with resize, use TARGET_MEDIAN instead
-               if (scene->snap_target == SCE_SNAP_TARGET_CENTER) {
+               if (snap_target == SCE_SNAP_TARGET_CENTER) {
                        t->tsnap.modeTarget = SNAP_MEDIAN;
                        t->tsnap.targetSnap = TargetSnapMedian;
                }