[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12658] branches/harmonic-skeleton/blender /source/blender: Code cleanup and recursive symmetry detection.

Martin Poirier theeth at yahoo.com
Fri Nov 23 00:34:03 CET 2007


Revision: 12658
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12658
Author:   theeth
Date:     2007-11-23 00:34:02 +0100 (Fri, 23 Nov 2007)

Log Message:
-----------
Code cleanup and recursive symmetry detection.

Modified Paths:
--------------
    branches/harmonic-skeleton/blender/source/blender/include/BIF_editarmature.h
    branches/harmonic-skeleton/blender/source/blender/include/BSE_edit.h
    branches/harmonic-skeleton/blender/source/blender/include/reeb.h
    branches/harmonic-skeleton/blender/source/blender/src/editarmature.c
    branches/harmonic-skeleton/blender/source/blender/src/reeb.c

Modified: branches/harmonic-skeleton/blender/source/blender/include/BIF_editarmature.h
===================================================================
--- branches/harmonic-skeleton/blender/source/blender/include/BIF_editarmature.h	2007-11-22 22:07:41 UTC (rev 12657)
+++ branches/harmonic-skeleton/blender/source/blender/include/BIF_editarmature.h	2007-11-22 23:34:02 UTC (rev 12658)
@@ -79,8 +79,6 @@
 void	apply_rot_armature (struct Object *ob, float mat[3][3]);
 void 	docenter_armature (struct Object *ob, int centermode);
 
-void generateSkeletonFromReebGraph(struct ReebGraph *rg);
-
 void	clear_armature(struct Object *ob, char mode);
 
 void	delete_armature(void);
@@ -104,6 +102,8 @@
 
 int		do_pose_selectbuffer(struct Base *base, unsigned int *buffer, short hits);
 
+void generateSkeleton(void);
+
 void	mouse_armature(void);
 void	remake_editArmature(void);
 void	selectconnected_armature(void);

Modified: branches/harmonic-skeleton/blender/source/blender/include/BSE_edit.h
===================================================================
--- branches/harmonic-skeleton/blender/source/blender/include/BSE_edit.h	2007-11-22 22:07:41 UTC (rev 12657)
+++ branches/harmonic-skeleton/blender/source/blender/include/BSE_edit.h	2007-11-22 23:34:02 UTC (rev 12658)
@@ -51,8 +51,6 @@
 void snap_curs_to_sel(void);
 void snap_to_center(void);
 
-void generateSkeleton(void);
-
 #endif /*  BSE_EDIT_H */
 
 

Modified: branches/harmonic-skeleton/blender/source/blender/include/reeb.h
===================================================================
--- branches/harmonic-skeleton/blender/source/blender/include/reeb.h	2007-11-22 22:07:41 UTC (rev 12657)
+++ branches/harmonic-skeleton/blender/source/blender/include/reeb.h	2007-11-22 23:34:02 UTC (rev 12658)
@@ -90,6 +90,8 @@
 void renormalizeWeight(struct EditMesh *em, float newmax);
 
 ReebGraph * generateReebGraph(struct EditMesh *me, int subdivisions);
+void freeGraph(ReebGraph *rg);
+void exportGraph(ReebGraph *rg, int count);
 
 #define OTHER_NODE(arc, node) ((arc->v1 == node) ? arc->v2 : arc->v1)
 
@@ -97,9 +99,28 @@
 void initArcIterator2(struct ReebArcIterator *iter, struct ReebArc *arc, int start, int end);
 struct EmbedBucket * nextBucket(struct ReebArcIterator *iter);
 
+/* Filtering */
+void filterNullReebGraph(ReebGraph *rg);
+void filterExternalReebGraph(ReebGraph *rg, float threshold);
+void filterInternalReebGraph(ReebGraph *rg, float threshold);
+
+/* Post-Build processing */
+void repositionNodes(ReebGraph *rg);
+void postprocessGraph(ReebGraph *rg, char mode);
+void removeNormalNodes(ReebGraph *rg);
+
+/* Graph processing */
+void buildAdjacencyList(ReebGraph *rg);
+
+void sortNodes(ReebGraph *rg);
+void sortArcs(ReebGraph *rg);
+
 int subtreeDepth(ReebNode *node);
 int countConnectedArcs(ReebGraph *rg, ReebNode *node);
 int hasAdjacencyList(ReebGraph *rg); 
 int	isGraphAcyclic(ReebGraph *rg);
 
+/* Sanity check */
+void verifyBuckets(ReebGraph *rg);
+
 #endif /*REEB_H_*/

Modified: branches/harmonic-skeleton/blender/source/blender/src/editarmature.c
===================================================================
--- branches/harmonic-skeleton/blender/source/blender/src/editarmature.c	2007-11-22 22:07:41 UTC (rev 12657)
+++ branches/harmonic-skeleton/blender/source/blender/src/editarmature.c	2007-11-22 23:34:02 UTC (rev 12658)
@@ -3148,102 +3148,115 @@
 
 /*****************************************************************************************************/
 
-float arcLengthRatio(ReebArc *arc)
+void markdownSymetryArc(ReebArc *arc, ReebNode *node, int level);
+
+void reestablishSymetry(ReebNode *node, int depth, int level)
 {
-	float arcLength = 0.0f;
-	float embedLength = 0.0f;
 	int i;
 	
-	arcLength = VecLenf(arc->v1->p, arc->v2->p);
-	
-	if (arc->bcount > 0)
+	/* detect spatial symetry */
+
+
+	/* markdown secondary symetries */	
+	for(i = 0; node->arcs[i] != NULL; i++)
 	{
-		// Add the embedding
-		for( i = 1; i < arc->bcount; i++)
+		ReebArc *connectedArc = node->arcs[i];
+		
+		/* depth is store as a negative in flag. symetry level is positive */
+		if (connectedArc->flags == -depth)
 		{
-			embedLength += VecLenf(arc->buckets[i - 1].p, arc->buckets[i].p);
+			/* markdown symetry for branches corresponding to the depth */
+			markdownSymetryArc(connectedArc, node, level + 1);
 		}
-		// Add head and tail -> embedding vectors
-		embedLength += VecLenf(arc->v1->p, arc->buckets[0].p);
-		embedLength += VecLenf(arc->v2->p, arc->buckets[arc->bcount - 1].p);
 	}
-	else
+}
+
+void markdownSymetryArc(ReebArc *arc, ReebNode *node, int level)
+{
+	int i;
+	arc->flags = level;
+	
+	node = OTHER_NODE(arc, node);
+	
+	for(i = 0; node->arcs[i] != NULL; i++)
 	{
-		embedLength = arcLength;
+		ReebArc *connectedArc = node->arcs[i];
+		
+		if (connectedArc != arc)
+		{
+			ReebNode *connectedNode = OTHER_NODE(connectedArc, node);
+			
+			/* symetry level is positive value, negative values is subtree depth */
+			connectedArc->flags = -subtreeDepth(connectedNode);
+		}
 	}
 	
-	return embedLength / arcLength;	
-}
+	arc = NULL;
 
-void symetryMarkdownArc(ReebArc *arc, ReebNode *node, int level)
-{
-	while(arc)
+	for(i = 0; node->arcs[i] != NULL; i++)
 	{
-		int i;
-		arc->flags = level;
+		int isSymetryAxis = 0;
+		ReebArc *connectedArc = node->arcs[i];
 		
-		node = OTHER_NODE(arc, node);
-		
-		for(i = 0; node->arcs[i] != NULL; i++)
+		/* only arcs not already marked as symetric */
+		if (connectedArc->flags < 0)
 		{
-			ReebArc *connectedArc = node->arcs[i];
+			int j;
 			
-			if (connectedArc != arc)
+			/* true by default */
+			isSymetryAxis = 1;
+			
+			for(j = 0; node->arcs[j] != NULL && isSymetryAxis == 1; j++)
 			{
-				ReebNode *connectedNode = OTHER_NODE(connectedArc, node);
+				ReebArc *otherArc = node->arcs[j];
 				
-				connectedArc->flags = -subtreeDepth(connectedNode);
+				/* different arc, same depth */
+				if (otherArc != connectedArc && otherArc->flags == connectedArc->flags)
+				{
+					/* not on the symetry axis */
+					isSymetryAxis = 0;
+				} 
 			}
 		}
 		
-		arc = NULL;
-
-		for(i = 0; node->arcs[i] != NULL; i++)
+		/* arc could be on the symetry axis */
+		if (isSymetryAxis == 1)
 		{
-			int isSymetryAxis = 0;
-			ReebArc *connectedArc = node->arcs[i];
-			
-			/* only arcs not already marked as symetric */
-			if (connectedArc->flags < 0)
+			/* no arc as been marked previously, keep this one */
+			if (arc == NULL)
 			{
-				int j;
-				
-				/* true by default */
-				isSymetryAxis = 1;
-				
-				for(j = 0; node->arcs[j] != NULL && isSymetryAxis == 1; j++)
-				{
-					ReebArc *otherArc = node->arcs[j];
-					
-					/* different arc, same depth */
-					if (otherArc != connectedArc && otherArc->flags == connectedArc->flags)
-					{
-						/* not on the symetry axis */
-						isSymetryAxis = 0;
-					} 
-				}
+				arc = connectedArc;
 			}
-			
-			/* arc could be on the symetry axis */
-			if (isSymetryAxis == 1)
+			else
 			{
-				/* no arc as been marked previously, keep this one */
-				if (arc == NULL)
-				{
-					arc = connectedArc;
-				}
-				else
-				{
-					/* there can't be more than one symetry arc */
-					arc = NULL;
-					break;
-				}
+				/* there can't be more than one symetry arc */
+				arc = NULL;
+				break;
 			}
 		}
 	}
+	
+	/* go down the arc continuing the symetry axis */
+	if (arc)
+	{
+		markdownSymetryArc(arc, node, level);
+	}
+	
+	/* restore symetry */
+	for(i = 0; node->arcs[i] != NULL; i++)
+	{
+		ReebArc *connectedArc = node->arcs[i];
+		
+		/* only arcs not already marked as symetric and is not the next arc on the symetry axis */
+		if (connectedArc->flags < 0)
+		{
+			/* subtree depth is store as a negative value in the flag */
+			reestablishSymetry(node, -connectedArc->flags, level);
+		}
+	}
 }
 
-void symetryMarkdown(ReebGraph *rg)
+void markdownSymetry(ReebGraph *rg)
 {
 	ReebNode *node;
 	ReebArc *arc;
@@ -3268,7 +3281,7 @@
 	{
 		arc = node->arcs[0];
 		
-		symetryMarkdownArc(arc, node, 1);
+		markdownSymetryArc(arc, node, 1);
 	}
 
 	/* mark down non-symetric arcs */
@@ -3280,9 +3293,15 @@
 		}
 		else
 		{
-			/* mark down nodes that are on the symetry axis */
-			arc->v1->flags = 1;
-			arc->v2->flags = 1;
+			/* mark down nodes with the lowest level symetry axis */
+			if (arc->v1->flags == 0 || arc->v1->flags > arc->flags)
+			{
+				arc->v1->flags = arc->flags;
+			}
+			if (arc->v2->flags == 0 || arc->v2->flags > arc->flags)
+			{
+				arc->v2->flags = arc->flags;
+			}
 		}
 		
 	}
@@ -3299,11 +3318,14 @@
 		EmbedBucket *previous = NULL;
 		EditBone *child = NULL;
 		EditBone *parent = NULL;
+		EditBone *root = NULL;
 		float angleLimit = (float)cos(G.scene->toolsettings->skgen_angle_limit * M_PI / 180.0f);
 		
 		parent = add_editbone("Bone");
 		VECCOPY(parent->head, head->p);
 		
+		root = parent;
+		
 		for(initArcIterator(&iter, arc, head), previous = nextBucket(&iter), current = nextBucket(&iter); current; previous = current, current = nextBucket(&iter))
 		{
 			float vec1[3], vec2[3];
@@ -3315,8 +3337,6 @@
 			len1 = Normalize(vec1);
 			len2 = Normalize(vec2);
 
-			//printf("%f < %f\n", Inpf(vec1, vec2), angleLimit);
-
 			if (len1 > 0.0f && len2 > 0.0f && Inpf(vec1, vec2) < angleLimit)
 			{
 				VECCOPY(parent->tail, previous->p);
@@ -3326,11 +3346,20 @@
 				child->parent = parent;
 				child->flag |= BONE_CONNECTED;
 				
-				parent = child; // new child is next parent
+				parent = child; /* new child is next parent */
 			}
 		}
 		VECCOPY(parent->tail, tail->p);
 		
+		/* If the bone wasn't subdivided, delete it and return NULL
+		 * to let subsequent subdivision methods do their thing. 
+		 * */
+		if (parent == root)
+		{
+			delete_bone(parent);
+			parent = NULL;
+		}
+		
 		lastBone = parent; /* set last bone in the chain */
 	}
 	
@@ -3441,6 +3470,33 @@
 	return lastBone;
 }
 
+float arcLengthRatio(ReebArc *arc)
+{
+	float arcLength = 0.0f;
+	float embedLength = 0.0f;
+	int i;
+	
+	arcLength = VecLenf(arc->v1->p, arc->v2->p);
+	
+	if (arc->bcount > 0)
+	{
+		/* Add the embedding */
+		for( i = 1; i < arc->bcount; i++)
+		{
+			embedLength += VecLenf(arc->buckets[i - 1].p, arc->buckets[i].p);
+		}
+		/* Add head and tail -> embedding vectors */
+		embedLength += VecLenf(arc->v1->p, arc->buckets[0].p);
+		embedLength += VecLenf(arc->v2->p, arc->buckets[arc->bcount - 1].p);
+	}
+	else
+	{
+		embedLength = arcLength;
+	}
+	
+	return embedLength / arcLength;	
+}
+
 EditBone * subdivideByLength(ReebArc *arc, ReebNode *head, ReebNode *tail)
 {
 	EditBone *lastBone = NULL;
@@ -3577,12 +3633,13 @@
 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list