Revision: 16984
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16984
Author:   theeth
Date:     2008-10-08 22:54:19 +0200 (Wed, 08 Oct 2008)

Log Message:
-----------
Sketching snapping.

Hold Ctrl to snap to an exact point (black dots). Continuous strokes are 
extrapolated between the depth difference of both end points when snapping.

Modified Paths:
--------------
    branches/etch-a-ton/source/blender/src/editarmature_sketch.c

Modified: branches/etch-a-ton/source/blender/src/editarmature_sketch.c
===================================================================
--- branches/etch-a-ton/source/blender/src/editarmature_sketch.c        
2008-10-08 19:58:57 UTC (rev 16983)
+++ branches/etch-a-ton/source/blender/src/editarmature_sketch.c        
2008-10-08 20:54:19 UTC (rev 16984)
@@ -26,11 +26,13 @@
 
 #include "DNA_listBase.h"
 #include "DNA_scene_types.h"
+#include "DNA_view3d_types.h"
 
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
 
 #include "BKE_utildefines.h"
+#include "BKE_global.h"
 
 #include "BSE_view.h"
 
@@ -80,8 +82,27 @@
 
 SK_Sketch *GLOBAL_sketch = NULL;
 
+/******************** PROTOTYPES ******************************/
+
+void sk_freeStroke(SK_Stroke *stk);
+void sk_freeSketch(SK_Sketch *sketch);
+
 /**************************************************************/
 
+void sk_freeSketch(SK_Sketch *sketch)
+{
+       SK_Stroke *stk, *next;
+       
+       for (stk = sketch->strokes.first; stk; stk = next)
+       {
+               next = stk->next;
+               
+               sk_freeStroke(stk);
+       }
+       
+       MEM_freeN(sketch);
+}
+
 SK_Sketch* sk_createSketch()
 {
        SK_Sketch *sketch;
@@ -101,6 +122,12 @@
        stk->points = MEM_callocN(sizeof(SK_Point) * stk->buf_size, "SK_Point 
buffer");
 }
 
+void sk_freeStroke(SK_Stroke *stk)
+{
+       MEM_freeN(stk->points);
+       MEM_freeN(stk);
+}
+
 SK_Stroke* sk_createStroke()
 {
        SK_Stroke *stk;
@@ -251,18 +278,65 @@
 
        glEnd();
 
-       glColor3f(1, 1, 1);
-       glBegin(GL_POINTS);
+//     glColor3f(1, 1, 1);
+//     glBegin(GL_POINTS);
+//
+//     for (i = 0; i < stk->nb_points; i++)
+//     {
+//             if (stk->points[i].type == PT_CONTINUOUS)
+//             {
+//                     glVertex3fv(stk->points[i].p);
+//             }
+//     }
+//
+//     glEnd();
+}
 
+SK_Point *sk_snapPointStroke(SK_Stroke *stk, short mval[2], int *dist)
+{
+       SK_Point *pt = NULL;
+       int i;
+       
        for (i = 0; i < stk->nb_points; i++)
        {
-               if (stk->points[i].type == PT_CONTINUOUS)
+               if (stk->points[i].type == PT_EXACT)
                {
-                       glVertex3fv(stk->points[i].p);
+                       short pval[2];
+                       int pdist;
+                       
+                       project_short_noclip(stk->points[i].p, pval);
+                       
+                       pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]);
+                       
+                       if (pdist < *dist)
+                       {
+                               *dist = pdist;
+                               pt = stk->points + i;
+                       }
                }
        }
+       
+       return pt;
+}
 
-       glEnd();
+
+SK_Point *sk_snapPoint(SK_Sketch *sketch, short mval[2], int min_dist)
+{
+       SK_Point *pt = NULL;
+       SK_Stroke *stk;
+       int dist = min_dist;
+       
+       for (stk = sketch->strokes.first; stk; stk = stk->next)
+       {
+               SK_Point *spt = sk_snapPointStroke(stk, mval, &dist);
+               
+               if (spt != NULL)
+               {
+                       pt = spt;
+               }
+       }
+       
+       return pt;
 }
 
 void sk_startStroke(SK_Sketch *sketch)
@@ -293,28 +367,103 @@
                VECCOPY(fp, last->p);
        }
        
+       initgrabz(fp[0], fp[1], fp[2]);
+       
        /* method taken from editview.c - mouse_cursor() */
        project_short_noclip(fp, cval);
        window_to_3d(dvec, cval[0] - dd->mval[0], cval[1] - dd->mval[1]);
        VecSubf(vec, fp, dvec);
 }
 
-void sk_addStrokePoint(SK_Stroke *stk, SK_DrawData *dd)
+void sk_updateDrawData(SK_DrawData *dd)
 {
+       dd->type = PT_CONTINUOUS;
+       
+       dd->previous_mval[0] = dd->mval[0];
+       dd->previous_mval[1] = dd->mval[1];
+}
+
+float sk_distanceDepth(float p1[3], float p2[3])
+{
+       float vec[3];
+       float distance;
+       
+       VecSubf(vec, p1, p2);
+       
+       Projf(vec, vec, G.vd->viewinv[2]);
+       
+       distance = VecLength(vec);
+       
+       if (Inpf(G.vd->viewinv[2], vec) > 0)
+       {
+               distance *= -1;
+       }
+       
+       return distance; 
+}
+
+void sk_addStrokeSnapPoint(SK_Stroke *stk, SK_DrawData *dd, SK_Point *snap_pt)
+{
        SK_Point pt;
+       float distance;
+       float length;
+       int i, j, total;
        
-       pt.type = dd->type;
-
+       pt.type = PT_EXACT;
+       
        sk_projectPaintData(stk, dd, pt.p);
 
        sk_appendStrokePoint(stk, &pt);
        
-       dd->type = PT_CONTINUOUS;
+       /* 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;
+               }
+       }
        
-       dd->previous_mval[0] = dd->mval[0];
-       dd->previous_mval[1] = dd->mval[1];
+       if (total > 1)
+       {
+               float progress = length - VecLenf(stk->points[stk->nb_points - 
2].p, stk->points[stk->nb_points - 1].p);
+               
+               distance = sk_distanceDepth(snap_pt->p, stk->points[i].p);
+               
+               for (j = 1, i = stk->nb_points - 2; j < total; j++, i--)
+               {
+                       float ray_start[3], ray_normal[3];
+                       float delta = VecLenf(stk->points[i].p, stk->points[i - 
1].p);
+                       short pval[2];
+                       
+                       project_short_noclip(stk->points[i].p, pval);
+                       viewray(pval, ray_start, ray_normal);
+                       
+                       VecMulf(ray_normal, distance * progress / length);
+                       VecAddf(stk->points[i].p, stk->points[i].p, ray_normal);
+
+                       progress -= delta ;
+               }
+       }
+
+       VECCOPY(stk->points[stk->nb_points - 1].p, snap_pt->p);
 }
 
+void sk_addStrokeDrawPoint(SK_Stroke *stk, SK_DrawData *dd)
+{
+       SK_Point pt;
+       
+       pt.type = dd->type;
+
+       sk_projectPaintData(stk, dd, pt.p);
+
+       sk_appendStrokePoint(stk, &pt);
+}
+
 void sk_endContinuousStroke(SK_Stroke *stk)
 {
        stk->points[stk->nb_points - 1].type = PT_EXACT;
@@ -391,6 +540,20 @@
                        
                        glDisable(GL_LINE_STIPPLE);
                        
+                       if (G.qual & LR_CTRLKEY)
+                       {
+                               SK_Point *snap_pt = sk_snapPoint(sketch, 
dd.mval, 30);
+                               
+                               if (snap_pt != NULL)
+                               {
+                                       glColor3f(0, 0.5, 1);
+                                       glBegin(GL_POINTS);
+                                       
+                                               glVertex3fv(snap_pt->p);
+                                       
+                                       glEnd();
+                               }
+                       }
                }
        }
        
@@ -421,13 +584,37 @@
                        
                        /* only add current point to buffer if mouse moved 
(otherwise wait until it does) */
                        if (sk_stroke_filtermval(&dd)) {
-                               sk_addStrokePoint(sketch->active_stroke, &dd);
+                               if (G.qual & LR_CTRLKEY)
+                               {
+                                       SK_Point *snap_pt = 
sk_snapPoint(sketch, dd.mval, 30);
+                                       
+                                       if (snap_pt != NULL)
+                                       {
+                                               
sk_addStrokeSnapPoint(sketch->active_stroke, &dd, snap_pt);
+                                       }
+                                       else
+                                       {
+                                               
sk_addStrokeDrawPoint(sketch->active_stroke, &dd);
+                                       }
+                               }
+                               else
+                               {
+                                       
sk_addStrokeDrawPoint(sketch->active_stroke, &dd);
+                               }
                                
+                               sk_updateDrawData(&dd);
                                force_draw(0);
                        }
                        else
+                       {
                                BIF_wait_for_statechange();
+                       }
                        
+                       while( qtest() ) {
+                               short event, val;
+                               event = extern_qread(&val);
+                       }
+                       
                        /* do mouse checking at the end, so don't check twice, 
and potentially
                         * miss a short tap 
                         */
@@ -441,6 +628,7 @@
                {
                        sk_filterStroke(sketch->active_stroke);
                        sk_endStroke(sketch);
+                       allqueue(REDRAWVIEW3D, 0);
                }
        }
        


_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to