Moved both filtering operations (external and internal) into a loop, since both can create new cases that the other would filter out.

Finish radial symmetry restoration.
This commit is contained in:
Martin Poirier
2007-11-29 19:57:40 +00:00
parent 1cb7325c2b
commit 653f064e71
3 changed files with 165 additions and 44 deletions

View File

@@ -101,8 +101,8 @@ struct EmbedBucket * nextBucket(struct ReebArcIterator *iter);
/* Filtering */ /* Filtering */
void filterNullReebGraph(ReebGraph *rg); void filterNullReebGraph(ReebGraph *rg);
void filterExternalReebGraph(ReebGraph *rg, float threshold); int filterExternalReebGraph(ReebGraph *rg, float threshold);
void filterInternalReebGraph(ReebGraph *rg, float threshold); int filterInternalReebGraph(ReebGraph *rg, float threshold);
/* Post-Build processing */ /* Post-Build processing */
void repositionNodes(ReebGraph *rg); void repositionNodes(ReebGraph *rg);

View File

@@ -335,7 +335,7 @@ void editbones_to_armature (ListBase *list, Object *ob)
fix_bonelist_roll (&arm->bonebase, list); fix_bonelist_roll (&arm->bonebase, list);
/* so all users of this armature should get rebuilt */ /* so all users of this armature should get rebuilt */
for(obt= G.main->object.first; obt; obt= obt->id.next) { for (obt= G.main->object.first; obt; obt= obt->id.next) {
if(obt->data==arm) if(obt->data==arm)
armature_rebuild_pose(obt, arm); armature_rebuild_pose(obt, arm);
} }
@@ -3173,7 +3173,6 @@ typedef struct RadialArc
void reestablishRadialSymmetry(ReebNode *node, int depth, float axis[3]) void reestablishRadialSymmetry(ReebNode *node, int depth, float axis[3])
{ {
#if 0
RadialArc *ring = NULL; RadialArc *ring = NULL;
RadialArc *unit; RadialArc *unit;
float limit = G.scene->toolsettings->skgen_symmetry_limit; float limit = G.scene->toolsettings->skgen_symmetry_limit;
@@ -3182,7 +3181,7 @@ void reestablishRadialSymmetry(ReebNode *node, int depth, float axis[3])
int i; int i;
/* count the number of arcs in the symmetry ring */ /* count the number of arcs in the symmetry ring */
for(i = 0; node->arcs[i] != NULL; i++) for (i = 0; node->arcs[i] != NULL; i++)
{ {
ReebArc *connectedArc = node->arcs[i]; ReebArc *connectedArc = node->arcs[i];
@@ -3197,7 +3196,7 @@ void reestablishRadialSymmetry(ReebNode *node, int depth, float axis[3])
unit = ring; unit = ring;
/* fill in the ring */ /* fill in the ring */
for(unit = ring, i = 0; node->arcs[i] != NULL; i++) for (unit = ring, i = 0; node->arcs[i] != NULL; i++)
{ {
ReebArc *connectedArc = node->arcs[i]; ReebArc *connectedArc = node->arcs[i];
@@ -3221,13 +3220,13 @@ void reestablishRadialSymmetry(ReebNode *node, int depth, float axis[3])
} }
/* sort ring */ /* sort ring */
for(i = 0; i < count - 1; i++) for (i = 0; i < count - 1; i++)
{ {
float minAngle = 2; float minAngle = 2;
int minIndex = -1; int minIndex = -1;
int j; int j;
for(j = i + 1; j < count; j++) for (j = i + 1; j < count; j++)
{ {
float angle = Inpf(ring[i].n, ring[j].n); float angle = Inpf(ring[i].n, ring[j].n);
@@ -3254,7 +3253,7 @@ void reestablishRadialSymmetry(ReebNode *node, int depth, float axis[3])
} }
} }
for(i = 0; i < count && symmetric; i++) for (i = 0; i < count && symmetric; i++)
{ {
ReebNode *node1, *node2; ReebNode *node1, *node2;
float tangent[3]; float tangent[3];
@@ -3281,18 +3280,122 @@ void reestablishRadialSymmetry(ReebNode *node, int depth, float axis[3])
if (symmetric) if (symmetric)
{ {
printf("DO MORE STUFF\n"); /* first pass, merge incrementally */
for (i = 0; i < count - 1; i++)
{
ReebNode *node1, *node2;
float tangent[3];
float normal[3];
int j = i + 1;
VecAddf(tangent, ring[i].n, ring[j].n);
Crossf(normal, tangent, axis);
node1 = OTHER_NODE(ring[i].arc, node);
node2 = OTHER_NODE(ring[j].arc, node);
/* mirror first node and mix with the second */
mirrorAlongAxis(node1->p, node->p, normal);
VecLerpf(node2->p, node2->p, node1->p, 1.0f / (j + 1));
/* Merge buckets
* there shouldn't be any null arcs here, but just to be safe
* */
if (ring[i].arc->bcount > 0 && ring[j].arc->bcount > 0)
{
ReebArcIterator iter1, iter2;
EmbedBucket *bucket1 = NULL, *bucket2 = NULL;
initArcIterator(&iter1, ring[i].arc, node);
initArcIterator(&iter2, ring[j].arc, node);
bucket1 = nextBucket(&iter1);
bucket2 = nextBucket(&iter2);
/* Make sure they both start at the same value */
while(bucket1 && bucket1->val < bucket2->val)
{
bucket1 = nextBucket(&iter1);
}
while(bucket2 && bucket2->val < bucket1->val)
{
bucket2 = nextBucket(&iter2);
}
for ( ;bucket1 && bucket2; bucket1 = nextBucket(&iter1), bucket2 = nextBucket(&iter2))
{
bucket2->nv += bucket1->nv; /* add counts */
/* mirror on axis */
mirrorAlongAxis(bucket1->p, node->p, normal);
/* add bucket2 in bucket1 */
VecLerpf(bucket2->p, bucket2->p, bucket1->p, (float)bucket1->nv / (float)(bucket2->nv));
}
}
}
/* second pass, mirror back on previous arcs */
for (i = count - 1; i > 0; i--)
{
ReebNode *node1, *node2;
float tangent[3];
float normal[3];
int j = i - 1;
VecAddf(tangent, ring[i].n, ring[j].n);
Crossf(normal, tangent, axis);
node1 = OTHER_NODE(ring[i].arc, node);
node2 = OTHER_NODE(ring[j].arc, node);
/* copy first node than mirror */
VECCOPY(node2->p, node1->p);
mirrorAlongAxis(node2->p, node->p, normal);
/* Copy buckets
* there shouldn't be any null arcs here, but just to be safe
* */
if (ring[i].arc->bcount > 0 && ring[j].arc->bcount > 0)
{
ReebArcIterator iter1, iter2;
EmbedBucket *bucket1 = NULL, *bucket2 = NULL;
initArcIterator(&iter1, ring[i].arc, node);
initArcIterator(&iter2, ring[j].arc, node);
bucket1 = nextBucket(&iter1);
bucket2 = nextBucket(&iter2);
/* Make sure they both start at the same value */
while(bucket1 && bucket1->val < bucket2->val)
{
bucket1 = nextBucket(&iter1);
}
while(bucket2 && bucket2->val < bucket1->val)
{
bucket2 = nextBucket(&iter2);
}
for ( ;bucket1 && bucket2; bucket1 = nextBucket(&iter1), bucket2 = nextBucket(&iter2))
{
/* copy and mirror back to bucket2 */
bucket2->nv = bucket1->nv;
VECCOPY(bucket2->p, bucket1->p);
mirrorAlongAxis(bucket2->p, node->p, normal);
}
}
}
} }
MEM_freeN(ring); MEM_freeN(ring);
#endif
printf("radial symmetry not done yet\n");
} }
void reestablishAxialSymmetry(ReebNode *node, int depth, float axis[3]) void reestablishAxialSymmetry(ReebNode *node, int depth, float axis[3])
{ {
ReebArcIterator iter1, iter2;
EmbedBucket *bucket1 = NULL, *bucket2 = NULL;
ReebArc *arc1 = NULL; ReebArc *arc1 = NULL;
ReebArc *arc2 = NULL; ReebArc *arc2 = NULL;
ReebNode *node1, *node2; ReebNode *node1, *node2;
@@ -3300,7 +3403,7 @@ void reestablishAxialSymmetry(ReebNode *node, int depth, float axis[3])
float nor[3], vec[3], p[3]; float nor[3], vec[3], p[3];
int i; int i;
for(i = 0; node->arcs[i] != NULL; i++) for (i = 0; node->arcs[i] != NULL; i++)
{ {
ReebArc *connectedArc = node->arcs[i]; ReebArc *connectedArc = node->arcs[i];
@@ -3346,6 +3449,8 @@ void reestablishAxialSymmetry(ReebNode *node, int depth, float axis[3])
* */ * */
if (arc1->bcount > 0 && arc2->bcount > 0) if (arc1->bcount > 0 && arc2->bcount > 0)
{ {
ReebArcIterator iter1, iter2;
EmbedBucket *bucket1 = NULL, *bucket2 = NULL;
initArcIterator(&iter1, arc1, node); initArcIterator(&iter1, arc1, node);
initArcIterator(&iter2, arc2, node); initArcIterator(&iter2, arc2, node);
@@ -3365,7 +3470,7 @@ void reestablishAxialSymmetry(ReebNode *node, int depth, float axis[3])
} }
for( ;bucket1 && bucket2; bucket1 = nextBucket(&iter1), bucket2 = nextBucket(&iter2)) for ( ;bucket1 && bucket2; bucket1 = nextBucket(&iter1), bucket2 = nextBucket(&iter2))
{ {
bucket1->nv += bucket2->nv; /* add counts */ bucket1->nv += bucket2->nv; /* add counts */
@@ -3395,7 +3500,7 @@ void markdownSecondarySymmetry(ReebNode *node, int depth, int level)
/* count the number of branches in this symmetry group /* count the number of branches in this symmetry group
* and determinte the axis of symmetry * and determinte the axis of symmetry
* */ * */
for(i = 0; node->arcs[i] != NULL; i++) for (i = 0; node->arcs[i] != NULL; i++)
{ {
ReebArc *connectedArc = node->arcs[i]; ReebArc *connectedArc = node->arcs[i];
@@ -3426,7 +3531,7 @@ void markdownSecondarySymmetry(ReebNode *node, int depth, int level)
} }
/* markdown secondary symetries */ /* markdown secondary symetries */
for(i = 0; node->arcs[i] != NULL; i++) for (i = 0; node->arcs[i] != NULL; i++)
{ {
ReebArc *connectedArc = node->arcs[i]; ReebArc *connectedArc = node->arcs[i];
@@ -3445,7 +3550,7 @@ void markdownSymmetryArc(ReebArc *arc, ReebNode *node, int level)
node = OTHER_NODE(arc, node); node = OTHER_NODE(arc, node);
for(i = 0; node->arcs[i] != NULL; i++) for (i = 0; node->arcs[i] != NULL; i++)
{ {
ReebArc *connectedArc = node->arcs[i]; ReebArc *connectedArc = node->arcs[i];
@@ -3460,7 +3565,7 @@ void markdownSymmetryArc(ReebArc *arc, ReebNode *node, int level)
arc = NULL; arc = NULL;
for(i = 0; node->arcs[i] != NULL; i++) for (i = 0; node->arcs[i] != NULL; i++)
{ {
int issymmetryAxis = 0; int issymmetryAxis = 0;
ReebArc *connectedArc = node->arcs[i]; ReebArc *connectedArc = node->arcs[i];
@@ -3473,7 +3578,7 @@ void markdownSymmetryArc(ReebArc *arc, ReebNode *node, int level)
/* true by default */ /* true by default */
issymmetryAxis = 1; issymmetryAxis = 1;
for(j = 0; node->arcs[j] != NULL && issymmetryAxis == 1; j++) for (j = 0; node->arcs[j] != NULL && issymmetryAxis == 1; j++)
{ {
ReebArc *otherArc = node->arcs[j]; ReebArc *otherArc = node->arcs[j];
@@ -3511,7 +3616,7 @@ void markdownSymmetryArc(ReebArc *arc, ReebNode *node, int level)
/* secondary symmetry */ /* secondary symmetry */
for(i = 0; node->arcs[i] != NULL; i++) for (i = 0; node->arcs[i] != NULL; i++)
{ {
ReebArc *connectedArc = node->arcs[i]; ReebArc *connectedArc = node->arcs[i];
@@ -3532,13 +3637,13 @@ void markdownSymmetry(ReebGraph *rg)
int cyclic = isGraphCyclic(rg); int cyclic = isGraphCyclic(rg);
/* mark down all arcs as non-symetric */ /* mark down all arcs as non-symetric */
for(arc = rg->arcs.first; arc; arc = arc->next) for (arc = rg->arcs.first; arc; arc = arc->next)
{ {
arc->flags = 0; arc->flags = 0;
} }
/* mark down all nodes as not on the symmetry axis */ /* mark down all nodes as not on the symmetry axis */
for(node = rg->nodes.first; node; node = node->next) for (node = rg->nodes.first; node; node = node->next)
{ {
node->flags = 0; node->flags = 0;
} }
@@ -3554,7 +3659,7 @@ void markdownSymmetry(ReebGraph *rg)
markdownSymmetryArc(arc, node, 1); markdownSymmetryArc(arc, node, 1);
/* mark down non-symetric arcs */ /* mark down non-symetric arcs */
for(arc = rg->arcs.first; arc; arc = arc->next) for (arc = rg->arcs.first; arc; arc = arc->next)
{ {
if (arc->flags < 0) if (arc->flags < 0)
{ {
@@ -3596,7 +3701,7 @@ EditBone * subdivideByAngle(ReebArc *arc, ReebNode *head, ReebNode *tail)
root = parent; root = parent;
for(initArcIterator(&iter, arc, head), previous = nextBucket(&iter), current = nextBucket(&iter); for (initArcIterator(&iter, arc, head), previous = nextBucket(&iter), current = nextBucket(&iter);
current; current;
previous = current, current = nextBucket(&iter)) previous = current, current = nextBucket(&iter))
{ {
@@ -3651,7 +3756,7 @@ float calcCorrelation(ReebArc *arc, int start, int end, float v0[3], float n[3])
float s_xyz = 0.0f; float s_xyz = 0.0f;
/* First pass, calculate average */ /* First pass, calculate average */
for(initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter); for (initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter);
bucket; bucket;
bucket = nextBucket(&iter)) bucket = nextBucket(&iter))
{ {
@@ -3666,7 +3771,7 @@ float calcCorrelation(ReebArc *arc, int start, int end, float v0[3], float n[3])
avg_t /= len; avg_t /= len;
/* Second pass, calculate s_xyz and s_t */ /* Second pass, calculate s_xyz and s_t */
for(initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter); for (initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter);
bucket; bucket;
bucket = nextBucket(&iter)) bucket = nextBucket(&iter))
{ {
@@ -3719,7 +3824,7 @@ EditBone * subdivideByCorrelation(ReebArc *arc, ReebNode *head, ReebNode *tail)
parent = add_editbone("Bone"); parent = add_editbone("Bone");
VECCOPY(parent->head, head->p); VECCOPY(parent->head, head->p);
for(previous = nextBucket(&iter), bucket = nextBucket(&iter); for (previous = nextBucket(&iter), bucket = nextBucket(&iter);
bucket; bucket;
previous = bucket, bucket = nextBucket(&iter)) previous = bucket, bucket = nextBucket(&iter))
{ {
@@ -3759,7 +3864,7 @@ float arcLengthRatio(ReebArc *arc)
if (arc->bcount > 0) if (arc->bcount > 0)
{ {
/* Add the embedding */ /* Add the embedding */
for( i = 1; i < arc->bcount; i++) for ( i = 1; i < arc->bcount; i++)
{ {
embedLength += VecLenf(arc->buckets[i - 1].p, arc->buckets[i].p); embedLength += VecLenf(arc->buckets[i - 1].p, arc->buckets[i].p);
} }
@@ -3966,7 +4071,7 @@ void generateSkeletonFromReebGraph(ReebGraph *rg)
} }
/* Loop over subdivision methods */ /* Loop over subdivision methods */
for(i = 0; lastBone == NULL && i < SKGEN_SUB_TOTAL; i++) for (i = 0; lastBone == NULL && i < SKGEN_SUB_TOTAL; i++)
{ {
switch(G.scene->toolsettings->skgen_subdivisions[i]) switch(G.scene->toolsettings->skgen_subdivisions[i])
{ {
@@ -3998,12 +4103,12 @@ void generateSkeletonFromReebGraph(ReebGraph *rg)
} }
/* Second pass, setup parent relationship between arcs */ /* Second pass, setup parent relationship between arcs */
for(node = rg->nodes.first; node; node = node->next) for (node = rg->nodes.first; node; node = node->next)
{ {
ReebArc *incomingArc = NULL; ReebArc *incomingArc = NULL;
int i; int i;
for(i = 0; node->arcs[i] != NULL; i++) for (i = 0; node->arcs[i] != NULL; i++)
{ {
arc = node->arcs[i]; arc = node->arcs[i];
@@ -4029,7 +4134,7 @@ void generateSkeletonFromReebGraph(ReebGraph *rg)
EditBone *parentBone = BLI_ghash_lookup(arcBoneMap, incomingArc); EditBone *parentBone = BLI_ghash_lookup(arcBoneMap, incomingArc);
/* Look for outgoing arcs and parent their bones */ /* Look for outgoing arcs and parent their bones */
for(i = 0; node->arcs[i] != NULL; i++) for (i = 0; node->arcs[i] != NULL; i++)
{ {
arc = node->arcs[i]; arc = node->arcs[i];
@@ -4087,16 +4192,24 @@ void generateSkeleton(void)
verifyBuckets(rg); verifyBuckets(rg);
if (G.scene->toolsettings->skgen_options & SKGEN_FILTER_EXTERNAL)
{
filterExternalReebGraph(rg, G.scene->toolsettings->skgen_threshold_external * G.scene->toolsettings->skgen_resolution);
}
verifyBuckets(rg); i = 1;
/* filter until there's nothing more to do */
if (G.scene->toolsettings->skgen_options & SKGEN_FILTER_INTERNAL) while (i == 1)
{ {
filterInternalReebGraph(rg, G.scene->toolsettings->skgen_threshold_internal * G.scene->toolsettings->skgen_resolution); i = 0; /* no work done yet */
if (G.scene->toolsettings->skgen_options & SKGEN_FILTER_EXTERNAL)
{
i |= filterExternalReebGraph(rg, G.scene->toolsettings->skgen_threshold_external * G.scene->toolsettings->skgen_resolution);
}
verifyBuckets(rg);
if (G.scene->toolsettings->skgen_options & SKGEN_FILTER_INTERNAL)
{
i |= filterInternalReebGraph(rg, G.scene->toolsettings->skgen_threshold_internal * G.scene->toolsettings->skgen_resolution);
}
} }
verifyBuckets(rg); verifyBuckets(rg);

View File

@@ -639,9 +639,10 @@ void filterNullReebGraph(ReebGraph *rg)
} }
} }
void filterInternalReebGraph(ReebGraph *rg, float threshold) int filterInternalReebGraph(ReebGraph *rg, float threshold)
{ {
ReebArc *arc = NULL, *nextArc = NULL; ReebArc *arc = NULL, *nextArc = NULL;
int value = 0;
BLI_sortlist(&rg->arcs, compareArcs); BLI_sortlist(&rg->arcs, compareArcs);
@@ -677,15 +678,19 @@ void filterInternalReebGraph(ReebGraph *rg, float threshold)
freeArc(arc); freeArc(arc);
BLI_freelinkN(&rg->nodes, removedNode); BLI_freelinkN(&rg->nodes, removedNode);
value = 1;
} }
arc = nextArc; arc = nextArc;
} }
return value;
} }
void filterExternalReebGraph(ReebGraph *rg, float threshold) int filterExternalReebGraph(ReebGraph *rg, float threshold)
{ {
ReebArc *arc = NULL, *nextArc = NULL; ReebArc *arc = NULL, *nextArc = NULL;
int value = 0;
BLI_sortlist(&rg->arcs, compareArcs); BLI_sortlist(&rg->arcs, compareArcs);
@@ -748,10 +753,13 @@ void filterExternalReebGraph(ReebGraph *rg, float threshold)
freeArc(arc); freeArc(arc);
BLI_freelinkN(&rg->nodes, removedNode); BLI_freelinkN(&rg->nodes, removedNode);
value = 1;
} }
arc = nextArc; arc = nextArc;
} }
return value;
} }
/************************************** WEIGHT SPREADING ***********************************************/ /************************************** WEIGHT SPREADING ***********************************************/