Skeleton generation

Add option to select bone placement on embedding (following last commit).

Add option for distance to embedding adaptive subdivide (for comparison with correlation based method)
This commit is contained in:
Martin Poirier
2008-06-10 21:15:48 +00:00
parent d6d4382396
commit dce7e07001
3 changed files with 76 additions and 138 deletions

View File

@@ -834,6 +834,8 @@ typedef struct Scene {
#define SKGEN_CUT_ANGLE 16
#define SKGEN_CUT_CORRELATION 32
#define SKGEN_HARMONIC 64
#define SKGEN_STICK_TO_EMBEDDING 128
#define SKGEN_ADAPTIVE_DISTANCE 512
#define SKGEN_SUB_LENGTH 0
#define SKGEN_SUB_ANGLE 1

View File

@@ -5063,8 +5063,10 @@ static void editing_panel_mesh_skgen(Object *ob, Mesh *me)
uiDefButF(block, NUM, B_DIFF, "T:", 1111, y,164,19, &G.scene->toolsettings->skgen_angle_limit,0.0, 90.0, 10, 0, "Specify the threshold angle in degrees for subdivision");
break;
case SKGEN_SUB_CORRELATION:
uiDefButBitS(block, TOG, SKGEN_CUT_CORRELATION, B_DIFF, "Correlation", 1041, y, 67,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Subdivide arcs based on correlation");
uiDefButF(block, NUM, B_DIFF, "T:", 1111, y,164,19, &G.scene->toolsettings->skgen_correlation_limit,0.0, 1.0, 0.01, 0, "Specify the threshold correlation for subdivision");
uiDefButBitS(block, TOG, SKGEN_CUT_CORRELATION, B_DIFF, "Adaptative", 1041, y, 67,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Subdivide arcs adaptatively");
uiDefButF(block, NUM, B_DIFF, "T:", 1111, y,114,19, &G.scene->toolsettings->skgen_correlation_limit,0.0, 1.0, 0.01, 0, "Specify the adaptive threshold for subdivision");
uiDefButBitS(block, TOG, SKGEN_STICK_TO_EMBEDDING, B_DIFF, "E", 1225, y, 25,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Stick endpoint to embedding");
uiDefButBitS(block, TOG, SKGEN_ADAPTIVE_DISTANCE, B_DIFF, "D", 1250, y, 25,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Adaptive distance (on) or variance(off)");
break;
}
}

View File

@@ -4207,9 +4207,7 @@ EditBone * subdivideByAngle(ReebArc *arc, ReebNode *head, ReebNode *tail)
return lastBone;
}
#if 1
float calcCorrelation(ReebArc *arc, int start, int end, float v0[3], float n[3])
float calcVariance(ReebArc *arc, int start, int end, float v0[3], float n[3])
{
int len = 2 + abs(end - start);
@@ -4257,134 +4255,47 @@ float calcCorrelation(ReebArc *arc, int start, int end, float v0[3], float n[3])
/* adding start(0) and end(1) values to s_t */
s_t += (avg_t * avg_t) + (1 - avg_t) * (1 - avg_t);
return 1.0f - s_xyz / s_t;
return s_xyz / s_t;
}
else
{
return 1.0f;
return 0;
}
}
float calcDistance(ReebArc *arc, int start, int end, float head[3], float tail[3])
{
ReebArcIterator iter;
EmbedBucket *bucket = NULL;
float max_dist = 0;
/* calculate maximum distance */
for (initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter);
bucket;
bucket = nextBucket(&iter))
{
float v1[3], v2[3], c[3];
float dist;
VecSubf(v1, head, tail);
VecSubf(v2, bucket->p, tail);
Crossf(c, v1, v2);
dist = Inpf(c, c) / Inpf(v1, v1);
max_dist = dist > max_dist ? dist : max_dist;
}
return max_dist;
}
EditBone * subdivideByCorrelation(ReebArc *arc, ReebNode *head, ReebNode *tail)
{
ReebArcIterator iter;
float n[3];
float CORRELATION_THRESHOLD = G.scene->toolsettings->skgen_correlation_limit;
EditBone *lastBone = NULL;
/* init iterator to get start and end from head */
initArcIterator(&iter, arc, head);
/* Calculate overall */
VecSubf(n, arc->buckets[iter.end].p, head->p);
if (G.scene->toolsettings->skgen_options & SKGEN_CUT_CORRELATION &&
calcCorrelation(arc, iter.start, iter.end, head->p, n) < CORRELATION_THRESHOLD)
{
EmbedBucket *bucket = NULL;
EmbedBucket *previous = NULL;
EditBone *child = NULL;
EditBone *parent = NULL;
int boneStart = iter.start;
parent = add_editbone("Bone");
parent->flag = BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
VECCOPY(parent->head, head->p);
for (previous = nextBucket(&iter), bucket = nextBucket(&iter);
bucket;
previous = bucket, bucket = nextBucket(&iter))
{
/* Calculate normal */
VecSubf(n, bucket->p, parent->head);
if (calcCorrelation(arc, boneStart, iter.index, parent->head, n) < CORRELATION_THRESHOLD)
{
VECCOPY(parent->tail, previous->p);
child = add_editbone("Bone");
VECCOPY(child->head, parent->tail);
child->parent = parent;
child->flag |= BONE_CONNECTED|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
parent = child; // new child is next parent
boneStart = iter.index; // start from end
}
}
VECCOPY(parent->tail, tail->p);
lastBone = parent; /* set last bone in the chain */
}
return lastBone;
}
#else
float calcCorrelation(ReebArc *arc, int start, int end, float v0[3], float n[3])
{
int len = 2 + abs(end - start);
if (len > 2)
{
ReebArcIterator iter;
EmbedBucket *bucket = NULL;
float avg_t = 0.0f;
float s_t = 0.0f;
float s_xyz = 0.0f;
/* First pass, calculate average */
for (initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter);
bucket;
bucket = nextBucket(&iter))
{
float v[3];
VecSubf(v, bucket->p, v0);
Normalize(v);
avg_t += Inpf(v, n);
}
avg_t /= Inpf(n, n);
avg_t += 1.0f; /* adding start (0) and end (1) values */
avg_t /= len;
/* Second pass, calculate s_xyz and s_t */
for (initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter);
bucket;
bucket = nextBucket(&iter))
{
float v[3], d[3];
float dt;
VecSubf(v, bucket->p, v0);
Normalize(v);
Projf(d, v, n);
VecSubf(v, v, d);
dt = VecLength(d) - avg_t;
s_t += dt * dt;
s_xyz += Inpf(v, v);
}
/* adding start(0) and end(1) values to s_t */
s_t += (avg_t * avg_t) + (1 - avg_t) * (1 - avg_t);
return 1.0f - s_xyz / s_t;
}
else
{
return 1.0f;
}
}
EditBone * subdivideByCorrelation(ReebArc *arc, ReebNode *head, ReebNode *tail)
{
ReebArcIterator iter;
float n[3];
float CORRELATION_THRESHOLD = G.scene->toolsettings->skgen_correlation_limit;
float ADAPTIVE_THRESHOLD = G.scene->toolsettings->skgen_correlation_limit;
EditBone *lastBone = NULL;
/* init iterator to get start and end from head */
@@ -4412,22 +4323,46 @@ EditBone * subdivideByCorrelation(ReebArc *arc, ReebNode *head, ReebNode *tail)
bucket;
previous = bucket, bucket = nextBucket(&iter))
{
float length;
/* Calculate normal */
VecSubf(n, bucket->p, parent->head);
length = Normalize(n);
total += 1;
VecAddf(normal, normal, n);
VECCOPY(avg_normal, normal);
VecMulf(avg_normal, 1.0f / total);
float btail[3];
float value = 0;
if (calcCorrelation(arc, boneStart, iter.index, parent->head, avg_normal) < CORRELATION_THRESHOLD)
if (G.scene->toolsettings->skgen_options & SKGEN_STICK_TO_EMBEDDING)
{
VECCOPY(parent->tail, avg_normal);
VecMulf(parent->tail, length);
VecAddf(parent->tail, parent->tail, parent->head);
VECCOPY(btail, bucket->p);
}
else
{
float length;
/* Calculate normal */
VecSubf(n, bucket->p, parent->head);
length = Normalize(n);
total += 1;
VecAddf(normal, normal, n);
VECCOPY(avg_normal, normal);
VecMulf(avg_normal, 1.0f / total);
VECCOPY(btail, avg_normal);
VecMulf(btail, length);
VecAddf(btail, btail, parent->head);
}
if (G.scene->toolsettings->skgen_options & SKGEN_ADAPTIVE_DISTANCE)
{
value = calcDistance(arc, boneStart, iter.index, parent->head, btail);
}
else
{
float n[3];
VecSubf(n, btail, parent->head);
value = calcVariance(arc, boneStart, iter.index, parent->head, n);
}
if (value > ADAPTIVE_THRESHOLD)
{
VECCOPY(parent->tail, btail);
child = add_editbone("Bone");
VECCOPY(child->head, parent->tail);
@@ -4449,7 +4384,6 @@ EditBone * subdivideByCorrelation(ReebArc *arc, ReebNode *head, ReebNode *tail)
return lastBone;
}
#endif
float arcLengthRatio(ReebArc *arc)
{