[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