[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17098] branches/etch-a-ton/source/blender : Skeleton Sketching

Martin Poirier theeth at yahoo.com
Fri Oct 17 23:52:50 CEST 2008


Revision: 17098
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17098
Author:   theeth
Date:     2008-10-17 23:52:50 +0200 (Fri, 17 Oct 2008)

Log Message:
-----------
Skeleton Sketching

Cut gesture: drawing a line with RMB adds exact points (joints in the final skeleton) on strokes. Can cut multiple strokes at once as long as it cuts each one only once (this could be changed).

Shape of the gesture doesn't matter, but eventually it would be straight lines shapes for cuts.

Modified Paths:
--------------
    branches/etch-a-ton/source/blender/blenlib/BLI_arithb.h
    branches/etch-a-ton/source/blender/blenlib/intern/arithb.c
    branches/etch-a-ton/source/blender/src/editarmature_sketch.c

Modified: branches/etch-a-ton/source/blender/blenlib/BLI_arithb.h
===================================================================
--- branches/etch-a-ton/source/blender/blenlib/BLI_arithb.h	2008-10-17 19:17:45 UTC (rev 17097)
+++ branches/etch-a-ton/source/blender/blenlib/BLI_arithb.h	2008-10-17 21:52:50 UTC (rev 17098)
@@ -388,6 +388,7 @@
 void spheremap(float x, float y, float z, float *u, float *v);
 
 int LineIntersectLine(float v1[3], float v2[3], float v3[3], float v4[3], float i1[3], float i2[3]);
+int LineIntersectLineStrict(float v1[3], float v2[3], float v3[3], float v4[3], float vi[3], float *lambda);
 int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv);
 int RayIntersectsTriangle(float p1[3], float d[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv);
 int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, float v0[3], float v1[3], float v2[3], float *lambda, float *ipoint);

Modified: branches/etch-a-ton/source/blender/blenlib/intern/arithb.c
===================================================================
--- branches/etch-a-ton/source/blender/blenlib/intern/arithb.c	2008-10-17 19:17:45 UTC (rev 17097)
+++ branches/etch-a-ton/source/blender/blenlib/intern/arithb.c	2008-10-17 21:52:50 UTC (rev 17098)
@@ -4221,6 +4221,67 @@
 	}
 } 
 
+/* Intersection point strictly between the two lines
+ * 0 when no intersection is found 
+ * */
+int LineIntersectLineStrict(float v1[3], float v2[3], float v3[3], float v4[3], float vi[3], float *lambda)
+{
+	float a[3], b[3], c[3], ab[3], cb[3], ca[3], dir1[3], dir2[3];
+	float d;
+	float d1;
+	
+	VecSubf(c, v3, v1);
+	VecSubf(a, v2, v1);
+	VecSubf(b, v4, v3);
+
+	VecCopyf(dir1, a);
+	Normalize(dir1);
+	VecCopyf(dir2, b);
+	Normalize(dir2);
+	d = Inpf(dir1, dir2);
+	if (d == 1.0f || d == -1.0f || d == 0) {
+		/* colinear or one vector is zero-length*/
+		return 0;
+	}
+	
+	d1 = d;
+
+	Crossf(ab, a, b);
+	d = Inpf(c, ab);
+
+	/* test if the two lines are coplanar */
+	if (d > -0.000001f && d < 0.000001f) {
+		float f1, f2;
+		Crossf(cb, c, b);
+		Crossf(ca, c, a);
+
+		f1 = Inpf(cb, ab) / Inpf(ab, ab);
+		f2 = Inpf(ca, ab) / Inpf(ab, ab);
+		
+		if (f1 >= 0 && f1 <= 1 &&
+			f2 >= 0 && f2 <= 1)
+		{
+			VecMulf(a, f1);
+			VecAddf(vi, v1, a);
+			
+			if (lambda != NULL)
+			{
+				*lambda = f1;
+			}
+			
+			return 1; /* intersection found */
+		}
+		else
+		{
+			return 0;
+		}
+	}
+	else
+	{
+		return 0;
+	}
+} 
+
 int AabbIntersectAabb(float min1[3], float max1[3], float min2[3], float max2[3])
 {
 	return (min1[0]<max2[0] && min1[1]<max2[1] && min1[2]<max2[2] &&

Modified: branches/etch-a-ton/source/blender/src/editarmature_sketch.c
===================================================================
--- branches/etch-a-ton/source/blender/src/editarmature_sketch.c	2008-10-17 19:17:45 UTC (rev 17097)
+++ branches/etch-a-ton/source/blender/src/editarmature_sketch.c	2008-10-17 21:52:50 UTC (rev 17098)
@@ -93,6 +93,15 @@
 	SK_PType type;
 } SK_DrawData;
 
+typedef struct SK_Intersection
+{
+	struct SK_Intersection *next, *prev;
+	SK_Stroke *stroke;
+	int			start;
+	int			end;
+	float		p[3];
+} SK_Intersection;
+
 typedef struct SK_Sketch
 {
 	ListBase	strokes;
@@ -419,6 +428,19 @@
 	}
 }
 
+void sk_insertStrokePoint(SK_Stroke *stk, SK_Point *pt, int n)
+{
+	int size = stk->nb_points - n;
+	
+	sk_growStrokeBuffer(stk);
+	
+	memmove(stk->points + n + 1, stk->points + n, size * sizeof(SK_Point));
+	
+	memcpy(stk->points + n, pt, sizeof(SK_Point));
+	
+	stk->nb_points++;
+}
+
 void sk_appendStrokePoint(SK_Stroke *stk, SK_Point *pt)
 {
 	sk_growStrokeBuffer(stk);
@@ -1329,6 +1351,98 @@
 		}
 	}
 }
+/******************* GESTURE *************************/
+
+/* returns the maximum number of intersections per stroke */
+int sk_getIntersections(ListBase *list, SK_Sketch *sketch, SK_Stroke *gesture)
+{
+	SK_Stroke *stk;
+	int added = 0;
+
+	for (stk = sketch->strokes.first; stk; stk = stk->next)
+	{
+		int s_added = 0;
+		int s_i;
+		
+		for (s_i = 0; s_i < stk->nb_points - 1; s_i++)
+		{
+			float s_p1[3] = {0, 0, 0};
+			float s_p2[3] = {0, 0, 0};
+			int g_i;
+			
+			project_float(stk->points[s_i].p, s_p1);
+			project_float(stk->points[s_i + 1].p, s_p2);
+
+			for (g_i = 0; g_i < gesture->nb_points - 1; g_i++)
+			{
+				float g_p1[3] = {0, 0, 0};
+				float g_p2[3] = {0, 0, 0};
+				float vi[3];
+				float lambda;
+				
+				project_float(gesture->points[g_i].p, g_p1);
+				project_float(gesture->points[g_i + 1].p, g_p2);
+				
+				if (LineIntersectLineStrict(s_p1, s_p2, g_p1, g_p2, vi, &lambda))
+				{
+					SK_Intersection *isect = MEM_callocN(sizeof(SK_Intersection), "Intersection");
+					
+					isect->start = s_i;
+					isect->end = s_i + 1;
+					isect->stroke = stk;
+
+					VecSubf(isect->p, stk->points[s_i + 1].p, stk->points[s_i].p);
+					VecMulf(isect->p, lambda);
+					VecAddf(isect->p, isect->p, stk->points[s_i].p);
+					
+					BLI_addtail(list, isect);
+
+					s_added++;
+				}
+			}
+		}
+		
+		added = MAX2(s_added, added);
+	}
+	
+	
+	return added;
+}
+
+void sk_applyCutGesture(SK_Sketch *sketch, SK_Stroke *gesture, ListBase *list)
+{
+	SK_Intersection *isect;
+	
+	for (isect = list->first; isect; isect = isect->next)
+	{
+		SK_Point pt;
+		
+		pt.type = PT_EXACT;
+		pt.mode = PT_PROJECT; /* take mode from neighbouring points */
+		VECCOPY(pt.p, isect->p);
+		
+		sk_insertStrokePoint(isect->stroke, &pt, isect->end);
+	}
+}
+
+void sk_applyGesture(SK_Sketch *sketch)
+{
+	ListBase list;
+	int added;
+	
+	list.first = list.last = NULL;
+	
+	added = sk_getIntersections(&list, sketch, sketch->gesture);
+	
+	/* detect and apply */
+	if (added == 1)
+	{
+		sk_applyCutGesture(sketch, sketch->gesture, &list);
+	}
+	
+	BLI_freelistN(&list);
+}
+
 /********************************************/
 
 void sk_deleteStrokes(SK_Sketch *sketch)
@@ -1354,7 +1468,7 @@
 	if (mode == -1)
 	{
 		for (stk = sketch->strokes.first; stk; stk = stk->next)
-		{
+		{sk_applyGesture(sketch);
 			stk->selected = 0;
 		}
 	}
@@ -1468,7 +1582,8 @@
 		}
 	}
 	
-	if (sketch->gesture != NULL)
+	/* only draw gesture in active area */
+	if (sketch->gesture != NULL && area_is_active_area(G.vd->area))
 	{
 		float gesture_rgb[3] = {0, 0.5, 1};
 		sk_drawStroke(sketch->gesture, -1, gesture_rgb);
@@ -1480,6 +1595,7 @@
 		
 		if (last != NULL)
 		{
+			/* update point if in active area */
 			if (area_is_active_area(G.vd->area))
 			{
 				SK_DrawData dd;
@@ -1619,6 +1735,8 @@
 			
 			sk_endContinuousStroke(sketch->gesture);
 			sk_filterLastContinuousStroke(sketch->gesture);
+			sk_filterLastContinuousStroke(sketch->gesture);
+			sk_filterLastContinuousStroke(sketch->gesture);
 	
 			if (sketch->gesture->nb_points == 1)		
 			{
@@ -1627,6 +1745,7 @@
 			else
 			{
 				/* apply gesture here */
+				sk_applyGesture(sketch);
 				printf("FOO!\n");
 			}
 	





More information about the Bf-blender-cvs mailing list