Continue snapping cleaning job.
authorMartin Poirier <theeth@yahoo.com>
Wed, 25 Feb 2009 20:07:45 +0000 (20:07 +0000)
committerMartin Poirier <theeth@yahoo.com>
Wed, 25 Feb 2009 20:07:45 +0000 (20:07 +0000)
Snap to armature correctly in edit mode and when posed.
Merge snap and embed in skeleton sketching. Ctrl key does both, depends on the snap mode (volume or other). Snaps to other strokes in all snapping mode except Volume.

source/blender/include/BIF_transform.h
source/blender/src/editarmature_sketch.c
source/blender/src/transform_snap.c

index 8a8d7dc3b4a0752bbc24776c03e72dc0278b405d..096201f86d03d317ca81a3041818e9e56f0128ff 100644 (file)
@@ -148,6 +148,8 @@ typedef enum SnapMode
        NOT_ACTIVE = 1
 } SnapMode;
 
+#define SNAP_MIN_DISTANCE 30
+
 int snapObjects(int *dist, float *loc, float *no, SnapMode mode);
 int peelObjects(struct ListBase *depth_peels, short mval[2]);
 
index 7314add5e7b24e62cfef8d8a684a4a59fcb4a01e..1452a3d04417ea2b58cbc216eafc78d059100499 100644 (file)
@@ -71,7 +71,6 @@ typedef enum SK_PType
 
 typedef enum SK_PMode
 {
-       PT_EMBED,
        PT_SNAP,
        PT_PROJECT,
 } SK_PMode;
@@ -178,8 +177,6 @@ SK_Point boneSnap;
 int    LAST_SNAP_POINT_VALID = 0;
 float  LAST_SNAP_POINT[3];
 
-#define SNAP_MIN_DISTANCE 12
-
 /******************** PROTOTYPES ******************************/
 
 void initStrokeIterator(BArcIterator *iter, SK_Stroke *stk, int start, int end);
@@ -1474,100 +1471,7 @@ int sk_addStrokeDrawPoint(SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
        return 1;
 }
 
-
-int sk_getStrokeSnapPoint(SK_Point *pt, SK_Sketch *sketch, SK_Stroke *source_stk, SK_DrawData *dd)
-{
-       SK_Stroke *stk;
-       int dist = SNAP_MIN_DISTANCE;
-       int point_added = 0;
-       
-       for (stk = sketch->strokes.first; stk; stk = stk->next)
-       {
-               SK_Point *spt = NULL;
-               if (stk == source_stk)
-               {
-                       spt = sk_snapPointStroke(stk, dd->mval, &dist, NULL, 0);
-               }
-               else
-               {
-                       spt = sk_snapPointStroke(stk, dd->mval, &dist, NULL, 1);
-               }
-                       
-               if (spt != NULL)
-               {
-                       VECCOPY(pt->p, spt->p);
-                       point_added = 1;
-               }
-       }
-       
-       /* check on bones */
-       {
-               SK_Point *spt = sk_snapPointArmature(G.obedit, &G.edbo, dd->mval, &dist);
-               
-               if (spt != NULL)
-               {
-                       VECCOPY(pt->p, spt->p);
-                       point_added = 1;
-               }
-       }
-       
-       if (point_added)
-       {
-               pt->type = PT_EXACT;
-               pt->mode = PT_SNAP;
-       }
-       
-       return point_added;
-}
-
-int sk_addStrokeSnapPoint(SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
-{
-       int point_added = 0;
-       SK_Point pt;
-       
-       sk_initPoint(&pt);
-       
-       point_added = sk_getStrokeSnapPoint(&pt, sketch, stk, dd);
-
-       if (point_added)
-       {
-               float final_p[3];
-               float distance;
-               float length;
-               int i, total;
-               
-               VECCOPY(final_p, pt.p);
-
-               sk_projectDrawPoint(pt.p, stk, dd);
-               sk_appendStrokePoint(stk, &pt);
-               
-               /* update all previous point to give smooth Z progresion */
-               total = 0;
-               length = 0;
-               for (i = stk->nb_points - 2; i > 0; i--)
-               {
-                       length += VecLenf(stk->points[i].p, stk->points[i + 1].p);
-                       total++;
-                       if (stk->points[i].type == PT_EXACT)
-                       {
-                               break;
-                       }
-               }
-               
-               if (total > 1)
-               {
-                       distance = sk_distanceDepth(final_p, stk->points[i].p);
-                       
-                       sk_interpolateDepth(stk, i + 1, stk->nb_points - 2, length, distance);
-               }
-       
-               VECCOPY(stk->points[stk->nb_points - 1].p, final_p);
-       }
-       
-       return point_added;
-}
-
-int sk_getStrokeEmbedPoint(SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
+int sk_getStrokeSnapPoint(SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
 {
        int point_added = 0;
 
@@ -1657,7 +1561,7 @@ int sk_getStrokeEmbedPoint(SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_D
                if (dist != FLT_MAX)
                {
                        pt->type = dd->type;
-                       pt->mode = PT_EMBED;
+                       pt->mode = PT_SNAP;
                        VECCOPY(pt->p, p);
                        
                        point_added = 1;
@@ -1667,16 +1571,39 @@ int sk_getStrokeEmbedPoint(SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_D
        }
        else
        {
+               SK_Stroke *snap_stk;
                float vec[3];
                float no[3];
                int found = 0;
-               int dist = 40; // Use a user defined value here
+               int dist = SNAP_MIN_DISTANCE; // Use a user defined value here
+
+               /* snap to strokes */
+               // if (G.scene->snap_mode == SCE_SNAP_MODE_VERTEX) /* snap all the time to strokes */
+               for (snap_stk = sketch->strokes.first; snap_stk; snap_stk = snap_stk->next)
+               {
+                       SK_Point *spt = NULL;
+                       if (snap_stk == stk)
+                       {
+                               spt = sk_snapPointStroke(snap_stk, dd->mval, &dist, NULL, 0);
+                       }
+                       else
+                       {
+                               spt = sk_snapPointStroke(snap_stk, dd->mval, &dist, NULL, 1);
+                       }
+                               
+                       if (spt != NULL)
+                       {
+                               VECCOPY(pt->p, spt->p);
+                               point_added = 1;
+                       }
+               }
 
+               /* try to snap to closer object */
                found = snapObjects(&dist, vec, no, NOT_SELECTED);
                if (found == 1)
                {
                        pt->type = dd->type;
-                       pt->mode = PT_EMBED;
+                       pt->mode = PT_SNAP;
                        VECCOPY(pt->p, vec);
                        
                        point_added = 1;
@@ -1686,14 +1613,14 @@ int sk_getStrokeEmbedPoint(SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_D
        return point_added;
 }
 
-int sk_addStrokeEmbedPoint(SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
+int sk_addStrokeSnapPoint(SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
 {
        int point_added;
        SK_Point pt;
        
        sk_initPoint(&pt);
 
-       point_added = sk_getStrokeEmbedPoint(&pt, sketch, stk, dd);
+       point_added = sk_getStrokeSnapPoint(&pt, sketch, stk, dd);
        
        if (point_added)
        {
@@ -1714,7 +1641,7 @@ int sk_addStrokeEmbedPoint(SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
                {
                        length += VecLenf(stk->points[i].p, stk->points[i + 1].p);
                        total++;
-                       if (stk->points[i].mode == PT_EMBED || stk->points[i].type == PT_EXACT)
+                       if (stk->points[i].mode == PT_SNAP || stk->points[i].type == PT_EXACT)
                        {
                                break;
                        }
@@ -1744,11 +1671,6 @@ void sk_addStrokePoint(SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, short
                point_added = sk_addStrokeSnapPoint(sketch, stk, dd);
        }
        
-       if (point_added == 0 && qual & LR_SHIFTKEY)
-       {
-               point_added = sk_addStrokeEmbedPoint(sketch, stk, dd);
-       }
-       
        if (point_added == 0)
        {
                point_added = sk_addStrokeDrawPoint(sketch, stk, dd);
@@ -1767,11 +1689,6 @@ void sk_getStrokePoint(SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawD
        if (qual & LR_CTRLKEY)
        {
                point_added = sk_getStrokeSnapPoint(pt, sketch, stk, dd);
-       }
-       
-       if (point_added == 0 && qual & LR_SHIFTKEY)
-       {
-               point_added = sk_getStrokeEmbedPoint(pt, sketch, stk, dd);
                LAST_SNAP_POINT_VALID = 1;
                VECCOPY(LAST_SNAP_POINT, pt->p);
        }
@@ -2840,9 +2757,6 @@ void sk_drawSketch(SK_Sketch *sketch, int with_names)
                                switch (sketch->next_point.mode)
                                {
                                        case PT_SNAP:
-                                               glColor3f(0, 0.5, 1);
-                                               break;
-                                       case PT_EMBED:
                                                glColor3f(0, 1, 0);
                                                break;
                                        case PT_PROJECT:
index 3353c209d67d11f280eddea4f428334d33a89a68..6be8b0e881a7397fe74a57ea1fd5eca8b6446d31 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "PIL_time.h"
 
+#include "DNA_action_types.h"
 #include "DNA_armature_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
@@ -50,6 +51,7 @@
 
 #include "editmesh.h"
 #include "BIF_editsima.h"
+#include "BIF_editarmature.h"
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
 #include "BIF_mywindow.h"
@@ -485,7 +487,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
                float loc[3];
                float no[3];
                int found = 0;
-               int dist = 40; // Use a user defined value here
+               int dist = SNAP_MIN_DISTANCE; // Use a user defined value here
                SnapMode mode;
                
                if (G.scene->snap_mode == SCE_SNAP_MODE_VOLUME)
@@ -593,7 +595,7 @@ void CalcSnapGeometry(TransInfo *t, float *vec)
                                mode = NOT_ACTIVE;
                        }
                                
-                       found = snapObjects(&dist, loc, no, NOT_SELECTED);
+                       found = snapObjects(&dist, loc, no, mode);
                }
                
                if (found == 1)
@@ -921,7 +923,7 @@ int snapEdge(float v1co[3], short v1no[3], float v2co[3], short v2no[3], short m
                         * this takes care of series of connected edges a bit slanted w.r.t the viewport
                         * otherwise, it would stick to the verts of the closest edge and not slide along merrily 
                         * */
-                       if (new_dist <= *dist && new_depth < *depth * 1.01)
+                       if (new_dist <= *dist && new_depth < *depth * 1.001)
                        {
                                float n1[3], n2[3];
                                
@@ -996,9 +998,8 @@ int snapVertex(float vco[3], short vno[3], short mval[2], float ray_start[3], fl
        return retval;
 }
 
-int snapArmature(Object *ob, bArmature *ar, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth)
+int snapArmature(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 editarmature)
 {
-       Bone *b = ar->bonebase.first;
        float imat[4][4];
        float ray_start_local[3], ray_normal_local[3];
        int retval = 0;
@@ -1010,42 +1011,50 @@ int snapArmature(Object *ob, bArmature *ar, float obmat[][4], float ray_start[3]
        
        Mat4MulVecfl(imat, ray_start_local);
        Mat4Mul3Vecfl(imat, ray_normal_local);
-                       
-       while(b)
+
+       if(editarmature)
        {
-               switch (G.scene->snap_mode)
-               {
-                       case SCE_SNAP_MODE_VERTEX:
-                               retval |= snapVertex(b->arm_head, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth);
-                               retval |= snapVertex(b->arm_tail, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth);
-                               break;
-                       case SCE_SNAP_MODE_EDGE:
-                               retval |= snapEdge(b->arm_head, NULL, b->arm_tail, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth);
-                               break;
+               EditBone *eBone;
+
+               for (eBone=G.edbo.first; eBone; eBone=eBone->next) {
+                       if (eBone->layer & arm->layer) {
+                               /* skip hidden or moving (selected) bones */
+                               if ((eBone->flag & (BONE_HIDDEN_A|BONE_ROOTSEL|BONE_TIPSEL))==0) {
+                                       switch (G.scene->snap_mode)
+                                       {
+                                               case SCE_SNAP_MODE_VERTEX:
+                                                       retval |= snapVertex(eBone->head, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth);
+                                                       retval |= snapVertex(eBone->tail, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth);
+                                                       break;
+                                               case SCE_SNAP_MODE_EDGE:
+                                                       retval |= snapEdge(eBone->head, NULL, eBone->tail, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth);
+                                                       break;
+                                       }
+                               }
+                       }
                }
+       }
+       else if (ob->pose && ob->pose->chanbase.first)
+       {
+               bPoseChannel *pchan;
+               Bone *bone;
                
-               
-               if (b->childbase.first != NULL)
-               {
-                       b = b->childbase.first;
-               }
-               else
-               {
-                       while(1)
-                       {
-                               if (b->next != NULL)
-                               {
-                                       b = b->next;
-                                       break;
-                               }
-                               else if (b->parent != NULL)
-                               {
-                                       b = b->parent;
-                               }
-                               else /* nothing to go to */
+               for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+                       bone= pchan->bone;
+                       /* skip hidden bones */
+                       if (bone && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) {
+                               float *head_vec = pchan->pose_head;
+                               float *tail_vec = pchan->pose_tail;
+                               
+                               switch (G.scene->snap_mode)
                                {
-                                       b = NULL;
-                                       break;
+                                       case SCE_SNAP_MODE_VERTEX:
+                                               retval |= snapVertex(head_vec, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth);
+                                               retval |= snapVertex(tail_vec, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth);
+                                               break;
+                                       case SCE_SNAP_MODE_EDGE:
+                                               retval |= snapEdge(head_vec, NULL, tail_vec, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth);
+                                               break;
                                }
                        }
                }
@@ -1288,6 +1297,40 @@ int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_sta
        return retval;
 } 
 
+int snapObject(Object *ob, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth)
+{
+       int editobject = 0;
+       int retval = 0;
+       
+       if (ob == G.obedit)
+       {
+               editobject = 1;
+       }
+
+       if (ob->type == OB_MESH) {
+               DerivedMesh *dm;
+               
+               if (editobject)
+               {
+                       dm = editmesh_get_derived_cage(CD_MASK_BAREMESH);
+               }
+               else
+               {
+                       dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH);
+               }
+               
+               retval = snapDerivedMesh(ob, dm, obmat, ray_start, ray_normal, mval, loc, no, dist, depth, editobject);
+
+               dm->release(dm);
+       }
+       else if (ob->type == OB_ARMATURE)
+       {
+               retval = snapArmature(ob, ob->data, obmat, ray_start, ray_normal, mval, loc, no, dist, depth, editobject);
+       }
+       
+       return retval;
+}
+
 int snapObjects(int *dist, float *loc, float *no, SnapMode mode) {
        Base *base;
        float depth = FLT_MAX;
@@ -1300,17 +1343,9 @@ int snapObjects(int *dist, float *loc, float *no, SnapMode mode) {
 
        if (mode == NOT_ACTIVE)
        {
-               DerivedMesh *dm;
                Object *ob = G.obedit;
                
-               if (ob->type == OB_MESH)
-               {
-                       dm = editmesh_get_derived_cage(CD_MASK_BAREMESH);
-                       
-                       retval = snapDerivedMesh(ob, dm, ob->obmat, ray_start, ray_normal, mval, loc, no, dist, &depth, 1);
-                       
-                       dm->release(dm);
-               }
+               retval |= snapObject(ob, ob->obmat, ray_start, ray_normal, mval, loc, no, dist, &depth);
        }
        
        base= FIRSTBASE;
@@ -1327,50 +1362,13 @@ int snapObjects(int *dist, float *loc, float *no, SnapMode mode) {
                                {
                                        Object *ob = dupli_ob->ob;
                                        
-                                       if (ob->type == OB_MESH) {
-                                               DerivedMesh *dm;
-                                               int editmesh = 0;
-                                               int val;
-                                               
-                                               if (ob == G.obedit)
-                                               {
-                                                       dm = editmesh_get_derived_cage(CD_MASK_BAREMESH);
-                                                       editmesh = 1;
-                                               }
-                                               else
-                                               {
-                                                       dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH);
-                                               }
-                                               
-                                               val = snapDerivedMesh(ob, dm, dupli_ob->mat, ray_start, ray_normal, mval, loc, no, dist, &depth, editmesh);
-       
-                                               retval = retval || val;
-       
-                                               dm->release(dm);
-                                       }
+                                       retval |= snapObject(ob, dupli_ob->mat, ray_start, ray_normal, mval, loc, no, dist, &depth);
                                }
                                
                                free_object_duplilist(lb);
                        }
                        
-                       if (ob->type == OB_MESH) {
-                               DerivedMesh *dm = mesh_get_derived_final(ob, CD_MASK_BAREMESH);
-                               int val;
-                               
-                               val = snapDerivedMesh(ob, dm, ob->obmat, ray_start, ray_normal, mval, loc, no, dist, &depth, 0);
-                               
-                               retval = retval || val;
-                               
-                               dm->release(dm);
-                       }
-                       else if (ob->type == OB_ARMATURE)
-                       {
-                               int val;
-                               
-                               val = snapArmature(ob, ob->data, ob->obmat, ray_start, ray_normal, mval, loc, no, dist, &depth);
-                               
-                               retval = retval || val;
-                       }
+                       retval |= snapObject(ob, ob->obmat, ray_start, ray_normal, mval, loc, no, dist, &depth);
                }
        }