Project option for snap to faces.
authorMartin Poirier <theeth@yahoo.com>
Mon, 12 Oct 2009 22:33:32 +0000 (22:33 +0000)
committerMartin Poirier <theeth@yahoo.com>
Mon, 12 Oct 2009 22:33:32 +0000 (22:33 +0000)
This is similar to the old retopo all option but uses the snapping code and not the openGL depth buffer (it's thus more precise).

Not sure if making it available as a snap option is sensible, this is up for discussion.

NOTE: it will get slow fast on large meshes, we need to plug in an acceleration structure into snapping.

This will need an icon too.

14 files changed:
source/blender/editors/armature/editarmature_sketch.c
source/blender/editors/include/ED_transform.h
source/blender/editors/include/ED_view3d.h
source/blender/editors/space_view3d/view3d_header.c
source/blender/editors/space_view3d/view3d_view.c
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform.h
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_generics.c
source/blender/editors/transform/transform_ops.c
source/blender/editors/transform/transform_snap.c
source/blender/makesdna/DNA_scene_types.h
source/blender/makesrna/RNA_enum_types.h
source/blender/makesrna/intern/rna_scene.c

index 74876691daca89e376d05fdb3faf3ef290b96a4b..989070c114781a20abfcc245fecb833326150110 100644 (file)
@@ -1174,6 +1174,7 @@ int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Strok
                SK_Stroke *snap_stk;
                float vec[3];
                float no[3];
+               float mval[2];
                int found = 0;
                int dist = SNAP_MIN_DISTANCE; // Use a user defined value here
 
@@ -1197,9 +1198,12 @@ int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Strok
                                point_added = 1;
                        }
                }
+               
+               mval[0] = dd->mval[0];
+               mval[1] = dd->mval[1];
 
                /* try to snap to closer object */
-               found = snapObjectsContext(C, dd->mval, &dist, vec, no, SNAP_NOT_SELECTED);
+               found = snapObjectsContext(C, mval, &dist, vec, no, SNAP_NOT_SELECTED);
                if (found == 1)
                {
                        pt->type = dd->type;
index a7ffefba8df5ebdcc7eb1c2352db538964dbda1d..e07cbff429ac07b4689a6c30402375ad5c94b72a 100644 (file)
@@ -166,10 +166,10 @@ typedef enum SnapMode
 
 #define SNAP_MIN_DISTANCE 30
 
-int peelObjectsTransForm(struct TransInfo *t, struct ListBase *depth_peels, short mval[2]);
-int peelObjectsContext(struct bContext *C, struct ListBase *depth_peels, short mval[2]);
-int snapObjectsTransform(struct TransInfo *t, short mval[2], int *dist, float *loc, float *no, SnapMode mode);
-int snapObjectsContext(struct bContext *C, short mval[2], int *dist, float *loc, float *no, SnapMode mode);
+int peelObjectsTransForm(struct TransInfo *t, struct ListBase *depth_peels, float mval[2]);
+int peelObjectsContext(struct bContext *C, struct ListBase *depth_peels, float mval[2]);
+int snapObjectsTransform(struct TransInfo *t, float mval[2], int *dist, float *loc, float *no, SnapMode mode);
+int snapObjectsContext(struct bContext *C, float mval[2], int *dist, float *loc, float *no, SnapMode mode);
 
 #endif
 
index 7b1022d1a3f82b8b8c35fbcae9e02b1d4802a262..2752402fb6655ae5d39167b769a2c872dfe8b3ba 100644 (file)
@@ -88,8 +88,8 @@ void project_int_noclip(struct ARegion *ar, float *vec, int *adr);
 void project_float(struct ARegion *ar, float *vec, float *adr);
 void project_float_noclip(struct ARegion *ar, float *vec, float *adr);
 
-void viewline(struct ARegion *ar, struct View3D *v3d, short mval[2], float ray_start[3], float ray_end[3]);
-void viewray(struct ARegion *ar, struct View3D *v3d, short mval[2], float ray_start[3], float ray_normal[3]);
+void viewline(struct ARegion *ar, struct View3D *v3d, float mval[2], float ray_start[3], float ray_end[3]);
+void viewray(struct ARegion *ar, struct View3D *v3d, float mval[2], float ray_start[3], float ray_normal[3]);
 
 int get_view3d_viewplane(struct View3D *v3d, struct RegionView3D *rv3d, int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend, float *pixsize);
 int get_view3d_ortho(struct View3D *v3d, struct RegionView3D *rv3d);
index a44e3743bb428aaf27bfd121bd0942529c1e1eaf..8dcc8791d88cd1c07996f6cb0ab87e1197f74434 100644 (file)
@@ -2144,6 +2144,10 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
                                        uiDefIconButBitS(block, TOG, SCE_SNAP_PEEL_OBJECT, B_REDR, ICON_SNAP_PEEL_OBJECT,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Consider objects as whole when finding volume center");  
                                        xco+= XIC;
                                }
+                               if (ts->snap_mode == SCE_SNAP_MODE_FACE) {
+                                       uiDefIconButBitS(block, TOG, SCE_SNAP_PROJECT, B_REDR, ICON_ROTATECOLLECTION,xco,yco,XIC,YIC, &ts->snap_flag, 0, 0, 0, 0, "Project elements instead of snapping them");
+                                       xco+= XIC;
+                               }
                                uiDefIconTextButS(block, ICONTEXTROW,B_REDR, ICON_SNAP_VERTEX, snapmode_pup(), xco,yco,XIC+10,YIC, &(ts->snap_mode), 0.0, 0.0, 0, 0, "Snapping mode");
                                xco+= XIC + 10;
                                uiDefButS(block, MENU, B_NOP, "Snap Mode%t|Closest%x0|Center%x1|Median%x2|Active%x3",xco,yco,70,YIC, &ts->snap_target, 0, 0, 0, 0, "Snap Target Mode");
index fd850e90ff521243c9321e606309c0892fb22ec9..8b378f05eb256c2609398f2084facec4ecd5b259 100644 (file)
@@ -482,7 +482,7 @@ void VIEW3D_OT_setobjectascamera(wmOperatorType *ot)
 /* ********************************** */
 
 /* create intersection coordinates in view Z direction at mouse coordinates */
-void viewline(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float ray_end[3])
+void viewline(ARegion *ar, View3D *v3d, float mval[2], float ray_start[3], float ray_end[3])
 {
        RegionView3D *rv3d= ar->regiondata;
        float vec[4];
@@ -517,7 +517,7 @@ void viewline(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float
 }
 
 /* create intersection ray in view Z direction at mouse coordinates */
-void viewray(ARegion *ar, View3D *v3d, short mval[2], float ray_start[3], float ray_normal[3])
+void viewray(ARegion *ar, View3D *v3d, float mval[2], float ray_start[3], float ray_normal[3])
 {
        float ray_end[3];
        
index 0b7a672a0b6110741c30b8e38240e40ee05a4d1c..4c24d36616229452db218666952d73b2b0296e28 100644 (file)
@@ -2605,7 +2605,6 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
                        center = td->center;
                }
                else {
-                       /* !TODO! Make this if not rely on G */
                        if(around==V3D_LOCAL && (t->settings->selectmode & SCE_SELECT_FACE)) {
                                center = td->center;
                        }
index 60786127e3a53943cf7a5409237273966b5df316..5cee1f51b0a3d60ed4e273f9fe6df3f7489f16c1 100644 (file)
@@ -87,6 +87,7 @@ typedef struct TransSnap {
        short   modeTarget;
        short   mode;
        short   align;
+       short   project;
        short   status;
        float   snapPoint[3]; /* snapping from this point */
        float   snapTarget[3]; /* to this point */
@@ -578,6 +579,7 @@ void snapGrid(TransInfo *t, float *val);
 void snapGridAction(TransInfo *t, float *val, GearsType action);
 
 void initSnapping(struct TransInfo *t, struct wmOperator *op);
+void applyProject(TransInfo *t);
 void applySnapping(TransInfo *t, float *vec);
 void resetSnapping(TransInfo *t);
 int  handleSnapping(TransInfo *t, struct wmEvent *event);
index 51ce87803fdce4aa8a3097e929f1a2646bc7d81d..826fcb0c2ddf998c2fd6be9373cc20137ad6f582 100644 (file)
 #include "ED_object.h"
 #include "ED_markers.h"
 #include "ED_mesh.h"
-#include "ED_retopo.h"
 #include "ED_types.h"
 #include "ED_uvedit.h"
 #include "ED_view3d.h"
@@ -4478,12 +4477,6 @@ void special_aftertrans_update(TransInfo *t)
                if (t->obedit) {
                        if (cancelled==0) {
                                EM_automerge(t->scene, t->obedit, 1);
-#if 0 // TRANSFORM_FIX_ME
-                               /* when snapping, delay retopo until after automerge */
-                               if (G.qual & LR_CTRLKEY) {
-                                       retopo_do_all();
-                               }
-#endif
                        }
                }
        }
index c3ceea1a0c8311dc7a0676a70bae17576b79ef40..20d136e479033f02b83cca897dd6102e0a01778e 100644 (file)
@@ -91,7 +91,6 @@
 #include "ED_keyframing.h"
 #include "ED_markers.h"
 #include "ED_mesh.h"
-#include "ED_retopo.h"
 #include "ED_particle.h"
 #include "ED_screen_types.h"
 #include "ED_space_api.h"
@@ -617,201 +616,201 @@ void recalcData(TransInfo *t)
                        }
                }
        }
-       else if (t->obedit) {
-               if ELEM(t->obedit->type, OB_CURVE, OB_SURF) {
-                       Curve *cu= t->obedit->data;
-                       Nurb *nu= cu->editnurb->first;
-                       
-                       DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA);  /* sets recalc flags */
-                       
-                       if (t->state == TRANS_CANCEL) {
-                               while(nu) {
-                                       calchandlesNurb(nu); /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */
-                                       nu= nu->next;
-                               }
-                       } else {
-                               /* Normal updating */
-                               while(nu) {
-                                       test2DNurb(nu);
-                                       calchandlesNurb(nu);
-                                       nu= nu->next;
-                               }
-                               /* TRANSFORM_FIX_ME */
-                               // retopo_do_all();
-                       }
-               }
-               else if(t->obedit->type==OB_LATTICE) {
-                       Lattice *la= t->obedit->data;
-                       DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA);  /* sets recalc flags */
-
-                       if(la->editlatt->flag & LT_OUTSIDE) outside_lattice(la->editlatt);
+       else if (t->spacetype == SPACE_VIEW3D) {
+               
+               /* project */
+               if(t->state != TRANS_CANCEL) {
+                       applyProject(t);
                }
-               else if (t->obedit->type == OB_MESH) {
-                       if(t->spacetype==SPACE_IMAGE) {
-                               SpaceImage *sima= t->sa->spacedata.first;
+               
+               if (t->obedit) {
+                       if ELEM(t->obedit->type, OB_CURVE, OB_SURF) {
+                               Curve *cu= t->obedit->data;
+                               Nurb *nu= cu->editnurb->first;
                                
-                               flushTransUVs(t);
-                               if(sima->flag & SI_LIVE_UNWRAP)
-                                       ED_uvedit_live_unwrap_re_solve();
+                               DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA);  /* sets recalc flags */
                                
-                               DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA);
-                       } else {
-                               EditMesh *em = ((Mesh*)t->obedit->data)->edit_mesh;
-                               /* mirror modifier clipping? */
-                               if(t->state != TRANS_CANCEL) {
-                                       /* TRANSFORM_FIX_ME */
-//                                     if ((G.qual & LR_CTRLKEY)==0) {
-//                                             /* Only retopo if not snapping, Note, this is the only case of G.qual being used, but we have no T_SHIFT_MOD - Campbell */
-//                                             retopo_do_all();
-//                                     }
-                                       clipMirrorModifier(t, t->obedit);
+                               if (t->state == TRANS_CANCEL) {
+                                       while(nu) {
+                                               calchandlesNurb(nu); /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */
+                                               nu= nu->next;
+                                       }
+                               } else {
+                                       /* Normal updating */
+                                       while(nu) {
+                                               test2DNurb(nu);
+                                               calchandlesNurb(nu);
+                                               nu= nu->next;
+                                       }
                                }
-                               if((t->options & CTX_NO_MIRROR) == 0 && (t->flag & T_MIRROR))
-                                       editmesh_apply_to_mirror(t);
-                                       
+                       }
+                       else if(t->obedit->type==OB_LATTICE) {
+                               Lattice *la= t->obedit->data;
                                DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA);  /* sets recalc flags */
-                               
-                               recalc_editnormals(em);
+       
+                               if(la->editlatt->flag & LT_OUTSIDE) outside_lattice(la->editlatt);
                        }
-               }
-               else if(t->obedit->type==OB_ARMATURE) { /* no recalc flag, does pose */
-                       bArmature *arm= t->obedit->data;
-                       ListBase *edbo = arm->edbo;
-                       EditBone *ebo;
-                       TransData *td = t->data;
-                       int i;
-                       
-                       /* Ensure all bones are correctly adjusted */
-                       for (ebo = edbo->first; ebo; ebo = ebo->next){
-                               
-                               if ((ebo->flag & BONE_CONNECTED) && ebo->parent){
-                                       /* If this bone has a parent tip that has been moved */
-                                       if (ebo->parent->flag & BONE_TIPSEL){
-                                               VECCOPY (ebo->head, ebo->parent->tail);
-                                               if(t->mode==TFM_BONE_ENVELOPE) ebo->rad_head= ebo->parent->rad_tail;
-                                       }
-                                       /* If this bone has a parent tip that has NOT been moved */
-                                       else{
-                                               VECCOPY (ebo->parent->tail, ebo->head);
-                                               if(t->mode==TFM_BONE_ENVELOPE) ebo->parent->rad_tail= ebo->rad_head;
+                       else if (t->obedit->type == OB_MESH) {
+                               if(t->spacetype==SPACE_IMAGE) {
+                                       SpaceImage *sima= t->sa->spacedata.first;
+                                       
+                                       flushTransUVs(t);
+                                       if(sima->flag & SI_LIVE_UNWRAP)
+                                               ED_uvedit_live_unwrap_re_solve();
+                                       
+                                       DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA);
+                               } else {
+                                       EditMesh *em = ((Mesh*)t->obedit->data)->edit_mesh;
+                                       /* mirror modifier clipping? */
+                                       if(t->state != TRANS_CANCEL) {
+                                               clipMirrorModifier(t, t->obedit);
                                        }
+                                       if((t->options & CTX_NO_MIRROR) == 0 && (t->flag & T_MIRROR))
+                                               editmesh_apply_to_mirror(t);
+                                               
+                                       DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA);  /* sets recalc flags */
+                                       
+                                       recalc_editnormals(em);
                                }
+                       }
+                       else if(t->obedit->type==OB_ARMATURE) { /* no recalc flag, does pose */
+                               bArmature *arm= t->obedit->data;
+                               ListBase *edbo = arm->edbo;
+                               EditBone *ebo;
+                               TransData *td = t->data;
+                               int i;
                                
-                               /* on extrude bones, oldlength==0.0f, so we scale radius of points */
-                               ebo->length= VecLenf(ebo->head, ebo->tail);
-                               if(ebo->oldlength==0.0f) {
-                                       ebo->rad_head= 0.25f*ebo->length;
-                                       ebo->rad_tail= 0.10f*ebo->length;
-                                       ebo->dist= 0.25f*ebo->length;
-                                       if(ebo->parent) {
-                                               if(ebo->rad_head > ebo->parent->rad_tail)
-                                                       ebo->rad_head= ebo->parent->rad_tail;
+                               /* Ensure all bones are correctly adjusted */
+                               for (ebo = edbo->first; ebo; ebo = ebo->next){
+                                       
+                                       if ((ebo->flag & BONE_CONNECTED) && ebo->parent){
+                                               /* If this bone has a parent tip that has been moved */
+                                               if (ebo->parent->flag & BONE_TIPSEL){
+                                                       VECCOPY (ebo->head, ebo->parent->tail);
+                                                       if(t->mode==TFM_BONE_ENVELOPE) ebo->rad_head= ebo->parent->rad_tail;
+                                               }
+                                               /* If this bone has a parent tip that has NOT been moved */
+                                               else{
+                                                       VECCOPY (ebo->parent->tail, ebo->head);
+                                                       if(t->mode==TFM_BONE_ENVELOPE) ebo->parent->rad_tail= ebo->rad_head;
+                                               }
+                                       }
+                                       
+                                       /* on extrude bones, oldlength==0.0f, so we scale radius of points */
+                                       ebo->length= VecLenf(ebo->head, ebo->tail);
+                                       if(ebo->oldlength==0.0f) {
+                                               ebo->rad_head= 0.25f*ebo->length;
+                                               ebo->rad_tail= 0.10f*ebo->length;
+                                               ebo->dist= 0.25f*ebo->length;
+                                               if(ebo->parent) {
+                                                       if(ebo->rad_head > ebo->parent->rad_tail)
+                                                               ebo->rad_head= ebo->parent->rad_tail;
+                                               }
+                                       }
+                                       else if(t->mode!=TFM_BONE_ENVELOPE) {
+                                               /* if bones change length, lets do that for the deform distance as well */
+                                               ebo->dist*= ebo->length/ebo->oldlength;
+                                               ebo->rad_head*= ebo->length/ebo->oldlength;
+                                               ebo->rad_tail*= ebo->length/ebo->oldlength;
+                                               ebo->oldlength= ebo->length;
                                        }
                                }
-                               else if(t->mode!=TFM_BONE_ENVELOPE) {
-                                       /* if bones change length, lets do that for the deform distance as well */
-                                       ebo->dist*= ebo->length/ebo->oldlength;
-                                       ebo->rad_head*= ebo->length/ebo->oldlength;
-                                       ebo->rad_tail*= ebo->length/ebo->oldlength;
-                                       ebo->oldlength= ebo->length;
-                               }
-                       }
-                       
-                       
-                       if (t->mode != TFM_BONE_ROLL)
-                       {
-                               /* fix roll */
-                               for(i = 0; i < t->total; i++, td++)
+                               
+                               
+                               if (t->mode != TFM_BONE_ROLL)
                                {
-                                       if (td->extra)
+                                       /* fix roll */
+                                       for(i = 0; i < t->total; i++, td++)
                                        {
-                                               float vec[3], up_axis[3];
-                                               float qrot[4];
-                                               
-                                               ebo = td->extra;
-                                               VECCOPY(up_axis, td->axismtx[2]);
-                                               
-                                               if (t->mode != TFM_ROTATION)
+                                               if (td->extra)
                                                {
-                                                       VecSubf(vec, ebo->tail, ebo->head);
-                                                       Normalize(vec);
-                                                       RotationBetweenVectorsToQuat(qrot, td->axismtx[1], vec);
-                                                       QuatMulVecf(qrot, up_axis);
-                                               }
-                                               else
-                                               {
-                                                       Mat3MulVecfl(t->mat, up_axis);
+                                                       float vec[3], up_axis[3];
+                                                       float qrot[4];
+                                                       
+                                                       ebo = td->extra;
+                                                       VECCOPY(up_axis, td->axismtx[2]);
+                                                       
+                                                       if (t->mode != TFM_ROTATION)
+                                                       {
+                                                               VecSubf(vec, ebo->tail, ebo->head);
+                                                               Normalize(vec);
+                                                               RotationBetweenVectorsToQuat(qrot, td->axismtx[1], vec);
+                                                               QuatMulVecf(qrot, up_axis);
+                                                       }
+                                                       else
+                                                       {
+                                                               Mat3MulVecfl(t->mat, up_axis);
+                                                       }
+                                                       
+                                                       ebo->roll = ED_rollBoneToVector(ebo, up_axis);
                                                }
-                                               
-                                               ebo->roll = ED_rollBoneToVector(ebo, up_axis);
                                        }
                                }
+                               
+                               if(arm->flag & ARM_MIRROR_EDIT)
+                                       transform_armature_mirror_update(t->obedit);
+                               
                        }
-                       
-                       if(arm->flag & ARM_MIRROR_EDIT)
-                               transform_armature_mirror_update(t->obedit);
-                       
-               }
-               else
-                       DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA);  /* sets recalc flags */
-       }
-       else if( (t->flag & T_POSE) && t->poseobj) {
-               Object *ob= t->poseobj;
-               bArmature *arm= ob->data;
-               
-               /* if animtimer is running, and the object already has animation data,
-                * check if the auto-record feature means that we should record 'samples'
-                * (i.e. uneditable animation values)
-                */
-               // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes?
-               if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) {
-                       int targetless_ik= (t->flag & T_AUTOIK); // XXX this currently doesn't work, since flags aren't set yet!
-                       
-                       animrecord_check_state(t->scene, &ob->id, t->animtimer);
-                       autokeyframe_pose_cb_func(t->scene, (View3D *)t->view, ob, t->mode, targetless_ik);
-               }
-               
-               /* old optimize trick... this enforces to bypass the depgraph */
-               if (!(arm->flag & ARM_DELAYDEFORM)) {
-                       DAG_id_flush_update(&ob->id, OB_RECALC_DATA);  /* sets recalc flags */
+                       else
+                               DAG_id_flush_update(t->obedit->data, OB_RECALC_DATA);  /* sets recalc flags */
                }
-               else
-                       where_is_pose(scene, ob);
-       }
-       else {
-               for(base= FIRSTBASE; base; base= base->next) {
-                       Object *ob= base->object;
+               else if( (t->flag & T_POSE) && t->poseobj) {
+                       Object *ob= t->poseobj;
+                       bArmature *arm= ob->data;
                        
-                       /* this flag is from depgraph, was stored in initialize phase, handled in drawview.c */
-                       if(base->flag & BA_HAS_RECALC_OB)
-                               ob->recalc |= OB_RECALC_OB;
-                       if(base->flag & BA_HAS_RECALC_DATA)
-                               ob->recalc |= OB_RECALC_DATA;
+                       /* if animtimer is running, and the object already has animation data,
+                        * check if the auto-record feature means that we should record 'samples'
+                        * (i.e. uneditable animation values)
+                        */
+                       // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes?
+                       if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) {
+                               int targetless_ik= (t->flag & T_AUTOIK); // XXX this currently doesn't work, since flags aren't set yet!
+                               
+                               animrecord_check_state(t->scene, &ob->id, t->animtimer);
+                               autokeyframe_pose_cb_func(t->scene, (View3D *)t->view, ob, t->mode, targetless_ik);
+                       }
                        
-                       /* if object/base is selected */
-                       if ((base->flag & SELECT) || (ob->flag & SELECT)) {
-                               /* if animtimer is running, and the object already has animation data,
-                                * check if the auto-record feature means that we should record 'samples'
-                                * (i.e. uneditable animation values)
-                                */
-                               // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes?
-                               if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) {
-                                       animrecord_check_state(t->scene, &ob->id, t->animtimer);
-                                       autokeyframe_ob_cb_func(t->scene, (View3D *)t->view, ob, t->mode);
+                       /* old optimize trick... this enforces to bypass the depgraph */
+                       if (!(arm->flag & ARM_DELAYDEFORM)) {
+                               DAG_id_flush_update(&ob->id, OB_RECALC_DATA);  /* sets recalc flags */
+                       }
+                       else
+                               where_is_pose(scene, ob);
+               }
+               else {
+                       for(base= FIRSTBASE; base; base= base->next) {
+                               Object *ob= base->object;
+                               
+                               /* this flag is from depgraph, was stored in initialize phase, handled in drawview.c */
+                               if(base->flag & BA_HAS_RECALC_OB)
+                                       ob->recalc |= OB_RECALC_OB;
+                               if(base->flag & BA_HAS_RECALC_DATA)
+                                       ob->recalc |= OB_RECALC_DATA;
+                               
+                               /* if object/base is selected */
+                               if ((base->flag & SELECT) || (ob->flag & SELECT)) {
+                                       /* if animtimer is running, and the object already has animation data,
+                                        * check if the auto-record feature means that we should record 'samples'
+                                        * (i.e. uneditable animation values)
+                                        */
+                                       // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes?
+                                       if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) {
+                                               animrecord_check_state(t->scene, &ob->id, t->animtimer);
+                                               autokeyframe_ob_cb_func(t->scene, (View3D *)t->view, ob, t->mode);
+                                       }
                                }
+                               
+                               /* proxy exception */
+                               if(ob->proxy)
+                                       ob->proxy->recalc |= ob->recalc;
+                               if(ob->proxy_group)
+                                       group_tag_recalc(ob->proxy_group->dup_group);
                        }
-                       
-                       /* proxy exception */
-                       if(ob->proxy)
-                               ob->proxy->recalc |= ob->recalc;
-                       if(ob->proxy_group)
-                               group_tag_recalc(ob->proxy_group->dup_group);
                }
+               
+               if(t->spacetype==SPACE_VIEW3D && ((View3D*)t->view)->drawtype == OB_SHADED)
+                       reshadeall_displist(t->scene);
        }
-       
-       /* update shaded drawmode while transform */
-       if(t->spacetype==SPACE_VIEW3D && ((View3D*)t->view)->drawtype == OB_SHADED)
-               reshadeall_displist(t->scene);
 }
 
 void drawLine(TransInfo *t, float *center, float *dir, char axis, short options)
index b0e79b3b062cfff0290fd631cfac8541196eb8fa..3408f6cf3f7a463260c8026256f1aa972f2bac50 100644 (file)
@@ -63,32 +63,6 @@ EnumPropertyItem proportional_mode_types[] = {
                {0, NULL, 0, NULL, NULL}
 };
 
-EnumPropertyItem snap_mode_types[] = {
-               {SCE_SNAP_TARGET_CLOSEST, "CLOSEST", 0, "Closest", ""},
-               {SCE_SNAP_TARGET_CENTER,  "CENTER", 0, "Center", ""},
-               {SCE_SNAP_TARGET_MEDIAN,  "MEDIAN", 0, "Median", ""},
-               {SCE_SNAP_TARGET_ACTIVE,  "ACTIVE", 0, "Active", ""},
-               {0, NULL, 0, NULL, NULL}
-};
-
-EnumPropertyItem proportional_falloff_types[] = {
-               {PROP_SMOOTH, "SMOOTH", 0, "Smooth", ""},
-               {PROP_SPHERE, "SPHERE", 0, "Sphere", ""},
-               {PROP_ROOT, "ROOT", 0, "Root", ""},
-               {PROP_SHARP, "SHARP", 0, "Sharp", ""},
-               {PROP_LIN, "LINEAR", 0, "Linear", ""},
-               {PROP_CONST, "CONSTANT", 0, "Constant", ""},
-               {PROP_RANDOM, "RANDOM", 0, "Random", ""},
-               {0, NULL, 0, NULL, NULL}
-};
-
-EnumPropertyItem orientation_items[]= {
-       {V3D_MANIP_GLOBAL, "GLOBAL", 0, "Global", ""},
-       {V3D_MANIP_NORMAL, "NORMAL", 0, "Normal", ""},
-       {V3D_MANIP_LOCAL, "LOCAL", 0, "Local", ""},
-       {V3D_MANIP_VIEW, "VIEW", 0, "View", ""},
-       {0, NULL, 0, NULL, NULL}};
-
 char OP_TRANSLATION[] = "TFM_OT_translate";
 char OP_ROTATION[] = "TFM_OT_rotate";
 char OP_TOSPHERE[] = "TFM_OT_tosphere";
@@ -157,7 +131,8 @@ void TFM_OT_select_orientation(struct wmOperatorType *ot)
        ot->exec   = select_orientation_exec;
        ot->poll   = ED_operator_areaactive;
 
-       prop= RNA_def_enum(ot->srna, "orientation", orientation_items, V3D_MANIP_GLOBAL, "Orientation", "DOC_BROKEN");
+       prop= RNA_def_property(ot->srna, "orientation", PROP_ENUM, PROP_NONE);
+       RNA_def_property_ui_text(prop, "Orientation", "Transformation orientation.");
        RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf);
 }
 
@@ -374,7 +349,7 @@ void Properties_Proportional(struct wmOperatorType *ot)
 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_enum(ot->srna, "snap_mode", snap_mode_items, 0, "Mode", "");
        RNA_def_float_vector(ot->srna, "snap_point", 3, NULL, -FLT_MAX, FLT_MAX, "Point", "", -FLT_MAX, FLT_MAX);
 
        if (align)
@@ -389,7 +364,8 @@ void Properties_Constraints(struct wmOperatorType *ot)
        PropertyRNA *prop;
 
        RNA_def_boolean_vector(ot->srna, "constraint_axis", 3, NULL, "Constraint Axis", "");
-       prop= RNA_def_enum(ot->srna, "constraint_orientation", orientation_items, V3D_MANIP_GLOBAL, "Orientation", "DOC_BROKEN");
+       prop= RNA_def_property(ot->srna, "constraint_orientation", PROP_ENUM, PROP_NONE);
+       RNA_def_property_ui_text(prop, "Orientation", "Transformation orientation.");
        RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf);
 }
 
index 84dc9e69e7a2e0141e68320f1d8524078b35220f..0e3f999d47b0ff71e33276be2faf3f88262f6cad 100644 (file)
@@ -217,8 +217,69 @@ int  handleSnapping(TransInfo *t, wmEvent *event)
        return status;
 }
 
+void applyProject(TransInfo *t)
+{
+       /* XXX FLICKER IN OBJECT MODE */
+       if ((t->tsnap.project) && (t->tsnap.status & SNAP_ON) && (t->modifiers & MOD_SNAP_GEARS))
+       {
+               TransData *td = t->data;
+               float tvec[3];
+               float imat[4][4];
+               int i;
+       
+               if(t->flag & (T_EDIT|T_POSE)) {
+                       Object *ob = t->obedit?t->obedit:t->poseobj;
+                       Mat4Invert(imat, ob->obmat);
+               }
+
+               for(i = 0 ; i < t->total; i++, td++) {
+                       float iloc[3], loc[3], no[3];
+                       float mval[2];
+                       int dist = 1000;
+                       
+                       if (td->flag & TD_NOACTION)
+                               break;
+                       
+                       if (td->flag & TD_SKIP)
+                               continue;
+                       
+                       VECCOPY(iloc, td->loc);
+                       if (t->flag & (T_EDIT|T_POSE))
+                       {
+                               Object *ob = t->obedit?t->obedit:t->poseobj;
+                               Mat4MulVecfl(ob->obmat, iloc);
+                       }
+                       else if (t->flag & T_OBJECT)
+                       {
+                               VECCOPY(iloc, td->ob->obmat[3]);
+                       }
+                       
+                       project_float(t->ar, iloc, mval);
+                       
+                       if (snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.mode))
+                       {
+//                             if(t->flag & (T_EDIT|T_POSE)) {
+//                                     Mat4MulVecfl(imat, loc);
+//                             }
+//                             
+                               VecSubf(tvec, loc, iloc);
+                               
+                               Mat3MulVecfl(td->smtx, tvec);
+                               
+                               VecAddf(td->loc, td->loc, tvec);
+                       }
+                       
+                       //XXX constraintTransLim(t, td);
+               }
+       }
+}
+
 void applySnapping(TransInfo *t, float *vec)
 {
+       /* project is not applied this way */
+       if (t->tsnap.project)
+               return;
+       
        if (t->tsnap.status & SNAP_FORCED)
        {
                t->tsnap.targetSnap(t);
@@ -305,12 +366,24 @@ void initSnapping(TransInfo *t, wmOperator *op)
                                RNA_float_get_array(op->ptr, "snap_normal", t->tsnap.snapNormal);
                                Normalize(t->tsnap.snapNormal);
                        }
+
+                       if (RNA_struct_find_property(op->ptr, "snap_project"))
+                       {
+                               t->tsnap.project = RNA_boolean_get(op->ptr, "snap_project");
+                       }
                }
        }
        else
        {
                snapping = ((ts->snap_flag & SCE_SNAP) == SCE_SNAP);
                t->tsnap.align = ((t->settings->snap_flag & SCE_SNAP_ROTATE) == SCE_SNAP_ROTATE);
+               t->tsnap.project = ((t->settings->snap_flag & SCE_SNAP_PROJECT) == SCE_SNAP_PROJECT);
+       }
+       
+       /* force project off when not supported */
+       if (ts->snap_mode != SCE_SNAP_MODE_FACE)
+       {
+               t->tsnap.project = 0;
        }
        
        if ((t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) && // Only 3D view or UV
@@ -537,9 +610,13 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
        {
                float loc[3];
                float no[3];
+               float mval[2];
                int found = 0;
                int dist = SNAP_MIN_DISTANCE; // Use a user defined value here
                
+               mval[0] = t->mval[0];
+               mval[1] = t->mval[1];
+               
                if (t->settings->snap_mode == SCE_SNAP_MODE_VOLUME)
                {
                        ListBase depth_peels;
@@ -550,7 +627,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
                        
                        depth_peels.first = depth_peels.last = NULL;
                        
-                       peelObjectsTransForm(t, &depth_peels, t->mval);
+                       peelObjectsTransForm(t, &depth_peels, mval);
                        
 //                     if (LAST_SNAP_POINT_VALID)
 //                     {
@@ -633,7 +710,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
                }
                else
                {
-                       found = snapObjectsTransform(t, t->mval, &dist, loc, no, t->tsnap.mode);
+                       found = snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.mode);
                }
                
                if (found == 1)
@@ -854,7 +931,7 @@ void TargetSnapClosest(TransInfo *t)
 }
 /*================================================================*/
 
-int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4co, short mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth)
+int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4co, float mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth)
 {
        float lambda;
        int result;
@@ -885,7 +962,7 @@ int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4
                new_depth = VecLenf(location, ray_start);                                       
                
                project_int(ar, location, screen_loc);
-               new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]);
+               new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]);
                
                if (new_dist <= *dist && new_depth < *depth) 
                {
@@ -905,7 +982,7 @@ int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4
        return retval;
 }
 
-int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2no[3], short mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth)
+int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2no[3], float mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth)
 {
        float intersect[3] = {0, 0, 0}, ray_end[3], dvec[3];
        int result;
@@ -953,7 +1030,7 @@ int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2n
                        new_depth = VecLenf(location, ray_start);                                       
                        
                        project_int(ar, location, screen_loc);
-                       new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]);
+                       new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]);
                        
                        /* 10% threshold if edge is closer but a bit further
                         * this takes care of series of connected edges a bit slanted w.r.t the viewport
@@ -990,7 +1067,7 @@ int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2n
        return retval;
 }
 
-int snapVertex(ARegion *ar, float vco[3], short vno[3], short mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth)
+int snapVertex(ARegion *ar, float vco[3], short vno[3], float mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth)
 {
        int retval = 0;
        float dvec[3];
@@ -1011,7 +1088,7 @@ int snapVertex(ARegion *ar, float vco[3], short vno[3], short mval[2], float ray
                new_depth = VecLenf(location, ray_start);                                       
                
                project_int(ar, location, screen_loc);
-               new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]);
+               new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]);
                
                if (new_dist <= *dist && new_depth < *depth)
                {
@@ -1034,7 +1111,7 @@ int snapVertex(ARegion *ar, float vco[3], short vno[3], short mval[2], float ray
        return retval;
 }
 
-int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth)
+int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float obmat[][4], float ray_start[3], float ray_normal[3], float mval[2], float *loc, float *no, int *dist, float *depth)
 {
        float imat[4][4];
        float ray_start_local[3], ray_normal_local[3];
@@ -1099,7 +1176,7 @@ int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float
        return retval;
 }
 
-int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, EditMesh *em, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth)
+int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, EditMesh *em, float obmat[][4], float ray_start[3], float ray_normal[3], float mval[2], float *loc, float *no, int *dist, float *depth)
 {
        int retval = 0;
        int totvert = dm->getNumVerts(dm);
@@ -1333,7 +1410,7 @@ int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, E
        return retval;
 } 
 
-int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth)
+int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[][4], float ray_start[3], float ray_normal[3], float mval[2], float *loc, float *no, int *dist, float *depth)
 {
        ToolSettings *ts= scene->toolsettings;
        int retval = 0;
@@ -1365,7 +1442,7 @@ int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obma
        return retval;
 }
 
-int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, short mval[2], int *dist, float *loc, float *no, SnapMode mode) {
+int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, float mval[2], int *dist, float *loc, float *no, SnapMode mode) {
        Base *base;
        float depth = FLT_MAX;
        int retval = 0;
@@ -1382,7 +1459,7 @@ int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, short mv
        
        base= FIRSTBASE;
        for ( base = FIRSTBASE; base != NULL; base = base->next ) {
-               if ( BASE_SELECTABLE(v3d, base) && (base->flag & (BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA)) == 0 && ((mode == SNAP_NOT_SELECTED && (base->flag & (SELECT|BA_WAS_SEL)) == 0) || (mode == SNAP_NOT_OBEDIT && base != BASACT)) ) {
+               if ( BASE_SELECTABLE(v3d, base) && (base->flag & (BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA)) == 0 && ((mode == SNAP_NOT_SELECTED && (base->flag & (SELECT|BA_WAS_SEL)) == 0) || (ELEM(mode, SNAP_ALL, SNAP_NOT_OBEDIT) && base != BASACT)) ) {
                        Object *ob = base->object;
                        
                        if (ob->transflag & OB_DUPLI)
@@ -1407,12 +1484,12 @@ int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, short mv
        return retval;
 }
 
-int snapObjectsTransform(TransInfo *t, short mval[2], int *dist, float *loc, float *no, SnapMode mode)
+int snapObjectsTransform(TransInfo *t, float mval[2], int *dist, float *loc, float *no, SnapMode mode)
 {
        return snapObjects(t->scene, t->view, t->ar, t->obedit, mval, dist, loc, no, mode);
 }
 
-int snapObjectsContext(bContext *C, short mval[2], int *dist, float *loc, float *no, SnapMode mode)
+int snapObjectsContext(bContext *C, float mval[2], int *dist, float *loc, float *no, SnapMode mode)
 {
        ScrArea *sa = CTX_wm_area(C);
        View3D *v3d = sa->spacedata.first;
@@ -1477,7 +1554,7 @@ void addDepthPeel(ListBase *depth_peels, float depth, float p[3], float no[3], O
        peel->flag = 0;
 }
 
-int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], ListBase *depth_peels)
+int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_start[3], float ray_normal[3], float mval[2], ListBase *depth_peels)
 {
        int retval = 0;
        int totvert = dm->getNumVerts(dm);
@@ -1585,7 +1662,7 @@ int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta
        return retval;
 } 
 
-int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase *depth_peels, short mval[2])
+int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase *depth_peels, float mval[2])
 {
        Base *base;
        int retval = 0;
@@ -1666,12 +1743,12 @@ int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase
        return retval;
 }
 
-int peelObjectsTransForm(TransInfo *t, ListBase *depth_peels, short mval[2])
+int peelObjectsTransForm(TransInfo *t, ListBase *depth_peels, float mval[2])
 {
        return peelObjects(t->scene, t->view, t->ar, t->obedit, depth_peels, mval);
 }
 
-int peelObjectsContext(bContext *C, ListBase *depth_peels, short mval[2])
+int peelObjectsContext(bContext *C, ListBase *depth_peels, float mval[2])
 {
        ScrArea *sa = CTX_wm_area(C);
        View3D *v3d = sa->spacedata.first;
index 437b45cfda140e1bfb5ac1eef32a7e3b76051c50..e069136d46a81721fcaa708aafc89c32083f93bb 100644 (file)
@@ -982,6 +982,7 @@ typedef struct Scene {
 #define SCE_SNAP                               1
 #define SCE_SNAP_ROTATE                        2
 #define SCE_SNAP_PEEL_OBJECT   4
+#define SCE_SNAP_PROJECT               8
 /* toolsettings->snap_target */
 #define SCE_SNAP_TARGET_CLOSEST        0
 #define SCE_SNAP_TARGET_CENTER 1
index ff4eee8d074419175e6d048edcb2b8222936cdd2..4db76c7f312ad3a848f16eb0deb8aac9914bbef0 100644 (file)
@@ -32,6 +32,7 @@
 extern EnumPropertyItem object_mode_items[];
 
 extern EnumPropertyItem prop_mode_items[];
+extern EnumPropertyItem snap_mode_items[];
 extern EnumPropertyItem space_type_items[];
 extern EnumPropertyItem region_type_items[];
 extern EnumPropertyItem modifier_type_items[];
index 4a42a63bf6bde8944c5fb35e59300947ffcfc1c9..29fb9e4deb2cce15e25de495ee2812e0672236de 100644 (file)
 
 #include "WM_types.h"
 
-/* prop_mode needs to be accessible from transform operator */
+
+EnumPropertyItem snap_mode_items[] = {
+       {SCE_SNAP_TARGET_CLOSEST, "CLOSEST", 0, "Closest", "Snap closest point onto target."},
+       {SCE_SNAP_TARGET_CENTER, "CENTER", 0, "Center", "Snap center onto target."},
+       {SCE_SNAP_TARGET_MEDIAN, "MEDIAN", 0, "Median", "Snap median onto target."},
+       {SCE_SNAP_TARGET_ACTIVE, "ACTIVE", 0, "Active", "Snap active onto target."},
+       {0, NULL, 0, NULL, NULL}};
+       
 EnumPropertyItem prop_mode_items[] ={
        {PROP_SMOOTH, "SMOOTH", 0, "Smooth", ""},
        {PROP_SPHERE, "SPHERE", 0, "Sphere", ""},
@@ -54,6 +61,7 @@ EnumPropertyItem prop_mode_items[] ={
        {PROP_RANDOM, "RANDOM", 0, "Random", ""},
        {0, NULL, 0, NULL, NULL}};
 
+       
 #ifdef RNA_RUNTIME
 
 #include "DNA_anim_types.h"
@@ -489,13 +497,6 @@ static void rna_def_tool_settings(BlenderRNA  *brna)
                {SCE_SNAP_MODE_VOLUME, "VOLUME", ICON_SNAP_VOLUME, "Volume", "Snap to volume."},
                {0, NULL, 0, NULL, NULL}};
 
-       static EnumPropertyItem snap_mode_items[] = {
-               {SCE_SNAP_TARGET_CLOSEST, "CLOSEST", 0, "Closest", "Snap closest point onto target."},
-               {SCE_SNAP_TARGET_CENTER, "CENTER", 0, "Center", "Snap center onto target."},
-               {SCE_SNAP_TARGET_MEDIAN, "MEDIAN", 0, "Median", "Snap median onto target."},
-               {SCE_SNAP_TARGET_ACTIVE, "ACTIVE", 0, "Active", "Snap active onto target."},
-               {0, NULL, 0, NULL, NULL}};
-               
        static EnumPropertyItem auto_key_items[] = {
                {AUTOKEY_MODE_NORMAL, "ADD_REPLACE_KEYS", 0, "Add & Replace", ""},
                {AUTOKEY_MODE_EDITKEYS, "REPLACE_KEYS", 0, "Replace", ""},
@@ -570,6 +571,11 @@ static void rna_def_tool_settings(BlenderRNA  *brna)
        RNA_def_property_ui_text(prop, "Snap Peel Object", "Consider objects as whole when finding volume center.");
        RNA_def_property_ui_icon(prop, ICON_SNAP_PEEL_OBJECT, 0);
        
+       prop= RNA_def_property(srna, "snap_project", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "snap_flag", SCE_SNAP_PROJECT);
+       RNA_def_property_ui_text(prop, "Project Individual Elements", "DOC_BROKEN");
+       RNA_def_property_ui_icon(prop, ICON_ROTATECOLLECTION, 0);
+
        /* Auto Keying */
        prop= RNA_def_property(srna, "enable_auto_key", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "autokey_mode", AUTOKEY_ON);