[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16984] branches/etch-a-ton/source/blender /src/editarmature_sketch.c: Sketching snapping.

Martin Poirier theeth at yahoo.com
Wed Oct 8 22:54:19 CEST 2008


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);
 		}
 	}
 	





More information about the Bf-blender-cvs mailing list