Still nothing to see here <shifty eyes>

This fixes up angle based subdivisions, adds embedding post processing methods (before, only average was there, added smooth and sharpen).

More parameters are controllable through the UI.
This commit is contained in:
Martin Poirier 2007-11-08 22:03:04 +00:00
parent e7c4bad8e9
commit eeb9e1486d
6 changed files with 64 additions and 110 deletions

View File

@ -27,7 +27,7 @@ def importGraph(count):
first = False
SIZE = 0.3
WITH_NODE = False
WITH_NODE = True
def addNode(v, s, verts, faces):
if WITH_NODE:
@ -85,84 +85,5 @@ def importGraph(count):
#for i in range(16):
# importGraph(i)
importGraph(-1)
import Blender
def name(count):
if count == -1:
return ""
else:
return "%05" % count
def importGraph(count):
me = Blender.Mesh.New("graph%s" % name(count))
f = open("test%s.txt" % name(count), "r")
verts = []
edges = []
faces = []
i = 0
first = False
SIZE = 0.3
WITH_NODE = False
def addNode(v, s, verts, faces):
if WITH_NODE:
v1 = [v[0], v[1], v[2] + s]
i1 = len(verts)
verts.append(v1)
v2 = [v[0], v[1] + 0.959 * s, v[2] - 0.283 * s]
i2 = len(verts)
verts.append(v2)
v3 = [v[0] - 0.830 * s, v[1] - 0.479 * s, v[2] - 0.283 * s]
i3 = len(verts)
verts.append(v3)
v4 = [v[0] + 0.830 * s, v[1] - 0.479 * s, v[2] - 0.283 * s]
i4 = len(verts)
verts.append(v4)
faces.append([i1,i2,i3])
faces.append([i1,i3,i4])
faces.append([i2,i3,i4])
faces.append([i1,i2,i4])
return 4
else:
return 0
for line in f:
data = line.strip().split(" ")
if data[0] == "v1":
v = [float(x) for x in data[-3:]]
i += addNode(v, SIZE, verts, faces)
verts.append(v)
i += 1
elif data[0] == "v2":
pass
v = [float(x) for x in data[-3:]]
verts.append(v)
edges.append((i-1, i))
i += 1
i += addNode(v, SIZE, verts, faces)
elif data[0] == "b":
verts.append([float(x) for x in data[-3:]])
edges.append((i-1, i))
i += 1
me.verts.extend(verts)
me.edges.extend(edges)
me.faces.extend(faces)
scn = Blender.Scene.GetCurrent()
ob = scn.objects.new(me, "graph%s" % name(count))
#for i in range(16):
# importGraph(i)
importGraph(-1)
if __name__=='__main__':
importGraph(-1)

View File

@ -6776,9 +6776,12 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
sce->toolsettings->skgen_resolution = 50;
sce->toolsettings->skgen_threshold_internal = 0.01f;
sce->toolsettings->skgen_threshold_external = 0.01f;
sce->toolsettings->skgen_threshold_angle = 45.0f;
sce->toolsettings->skgen_threshold_length = 1.3f;
sce->toolsettings->skgen_options = SKGEN_FILTER_INTERNAL|SKGEN_FILTER_EXTERNAL|SKGEN_REPOSITION|SKGEN_SMOOTH|SKGEN_CUT_LENGTH|SKGEN_CUT_ANGLE;
sce->toolsettings->skgen_angle_limit = 45.0f;
sce->toolsettings->skgen_length_ratio = 1.3f;
sce->toolsettings->skgen_length_limit = 1.5f;
sce->toolsettings->skgen_postpro = SKGEN_SMOOTH;
sce->toolsettings->skgen_options = SKGEN_FILTER_INTERNAL|SKGEN_FILTER_EXTERNAL|SKGEN_REPOSITION|SKGEN_CUT_LENGTH|SKGEN_CUT_ANGLE;
}
}
}

View File

@ -367,11 +367,13 @@ typedef struct ToolSettings {
short skgen_resolution;
float skgen_threshold_internal;
float skgen_threshold_external;
float skgen_threshold_length;
float skgen_threshold_angle;
float skgen_length_ratio;
float skgen_length_limit;
float skgen_angle_limit;
short skgen_options;
char skgen_postpro;
char pad4[6];
char pad4[1];
} ToolSettings;
/* Used by all brushes to store their properties, which can be directly set
@ -680,7 +682,12 @@ typedef struct Scene {
#define SKGEN_SYMMETRY 8
#define SKGEN_CUT_LENGTH 16
#define SKGEN_CUT_ANGLE 32
#define SKGEN_SMOOTH 64
/* toolsettings->skgen_postpro */
#define SKGEN_NONE 0
#define SKGEN_SMOOTH 1
#define SKGEN_AVERAGE 2
#define SKGEN_SHARPEN 3
#ifdef __cplusplus
}

View File

@ -4425,20 +4425,24 @@ static void editing_panel_mesh_skgen(Object *ob, Mesh *me)
block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_skgen", UI_EMBOSS, UI_HELV, curarea->win);
if(uiNewPanel(curarea, block, "Skeleton Generation", "Editing", 960, 0, 318, 204)==0) return;
uiDefBut(block, BUT, B_GEN_SKELETON, "Generate Skeleton", 1075,160,200,39, 0, 0, 0, 0, 0, "Generate Skeleton from Mesh");
uiDefBut(block, BUT, B_GEN_SKELETON, "Generate Skeleton", 1025,160,250,39, 0, 0, 0, 0, 0, "Generate Skeleton from Mesh");
uiBlockBeginAlign(block);
uiDefButS(block, NUM, B_DIFF, "Resolution:", 1075,110,200,19, &G.scene->toolsettings->skgen_resolution,10.0,1000.0, 0, 0, "Specifies the resolution of the graph's embedding");
uiDefButBitS(block, TOG, SKGEN_FILTER_INTERNAL, B_DIFF, "Filter In", 1075, 90, 83,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Filter internal small arcs from graph");
uiDefButF(block, NUM, B_DIFF, "Thresh:", 1161, 90,114,19, &G.scene->toolsettings->skgen_threshold_internal,0.0, 1.0, 10, 0, "Specify the threshold ratio for filtering internal arcs");
uiDefButBitS(block, TOG, SKGEN_FILTER_EXTERNAL, B_DIFF, "Filter Ex", 1075, 70, 83,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Filter external small arcs from graph");
uiDefButF(block, NUM, B_DIFF, "Thresh:", 1161, 70,114,19, &G.scene->toolsettings->skgen_threshold_external,0.0, 1.0, 10, 0, "Specify the threshold ratio for filtering external arcs");
uiDefButBitS(block, TOG, SKGEN_CUT_LENGTH, B_DIFF, "Cut Length", 1075, 50, 83,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Subdivide arcs based on length");
uiDefButF(block, NUM, B_DIFF, "Thresh:", 1161, 50,114,19, &G.scene->toolsettings->skgen_threshold_length,1.0, 2.0, 10, 0, "Specify the threshold ratio for subdivision");
uiDefButBitS(block, TOG, SKGEN_CUT_ANGLE, B_DIFF, "Cut Angle", 1075, 30, 83,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Subdivide arcs based on angle");
uiDefButF(block, NUM, B_DIFF, "Thresh:", 1161, 30,114,19, &G.scene->toolsettings->skgen_threshold_angle,0.0, 90.0, 10, 0, "Specify the threshold angle in degrees for subdivision");
uiDefButBitS(block, TOG, SKGEN_REPOSITION, B_DIFF, "Reposition", 1075, 10,100,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Reposition nodes based on embedding instead of original vertice positions");
uiDefButBitS(block, TOG, SKGEN_SMOOTH, B_DIFF, "Smooth", 1175, 10,100,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Smooth embeddings");
uiDefButS(block, NUM, B_DIFF, "Resolution:", 1025,130,250,19, &G.scene->toolsettings->skgen_resolution,10.0,1000.0, 0, 0, "Specifies the resolution of the graph's embedding");
uiDefButBitS(block, TOG, SKGEN_FILTER_INTERNAL, B_DIFF, "Filter In", 1025,110, 83,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Filter internal small arcs from graph");
uiDefButF(block, NUM, B_DIFF, "Thresh:", 1111,110,164,19, &G.scene->toolsettings->skgen_threshold_internal,0.0, 1.0, 10, 0, "Specify the threshold ratio for filtering internal arcs");
uiDefButBitS(block, TOG, SKGEN_FILTER_EXTERNAL, B_DIFF, "Filter Ex", 1025, 90, 83,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Filter external small arcs from graph");
uiDefButF(block, NUM, B_DIFF, "Thresh:", 1111, 90,164,19, &G.scene->toolsettings->skgen_threshold_external,0.0, 1.0, 10, 0, "Specify the threshold ratio for filtering external arcs");
uiDefButBitS(block, TOG, SKGEN_CUT_LENGTH, B_DIFF, "Cut Length", 1025, 70, 83,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Subdivide arcs based on embedding");
uiDefButF(block, NUM, B_DIFF, "Thresh:", 1111, 70, 82,19, &G.scene->toolsettings->skgen_length_ratio,1.0, 4.0, 10, 0, "Specify the ratio limit between straight arc and embeddings to trigger equal subdivisions");
uiDefButF(block, NUM, B_DIFF, "Len:", 1193, 70, 82,19, &G.scene->toolsettings->skgen_length_limit,0.1,50.0, 10, 0, "Maximum length of the bones when subdividing");
uiDefButBitS(block, TOG, SKGEN_CUT_ANGLE, B_DIFF, "Cut Angle", 1025, 50, 83,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Subdivide arcs based on angle");
uiDefButF(block, NUM, B_DIFF, "Thresh:", 1111, 50,164,19, &G.scene->toolsettings->skgen_angle_limit,0.0, 90.0, 10, 0, "Specify the threshold angle in degrees for subdivision");
uiDefButBitS(block, TOG, SKGEN_REPOSITION, B_DIFF, "Reposition", 1025, 30,250,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Reposition nodes based on embedding instead of original vertice positions");
uiDefButC(block, ROW, B_DIFF, "None", 1025, 10, 62,19, &G.scene->toolsettings->skgen_postpro, 5.0, (float)SKGEN_NONE, 0, 0, "No postprocessing on embeddings");
uiDefButC(block, ROW, B_DIFF, "Smooth", 1087, 10, 63,19, &G.scene->toolsettings->skgen_postpro, 5.0, (float)SKGEN_SMOOTH, 0, 0, "Smooth embeddings");
uiDefButC(block, ROW, B_DIFF, "Average", 1150, 10, 62,19, &G.scene->toolsettings->skgen_postpro, 5.0, (float)SKGEN_AVERAGE, 0, 0, "Average embeddings");
uiDefButC(block, ROW, B_DIFF, "Sharpen", 1212, 10, 63,19, &G.scene->toolsettings->skgen_postpro, 5.0, (float)SKGEN_SHARPEN, 0, 0, "Sharpen embeddings");
uiBlockEndAlign(block);
}

View File

@ -3230,14 +3230,14 @@ void generateSkeletonFromReebGraph(ReebGraph *rg)
/************************* CUT LENGTH *****************************/
if ((G.scene->toolsettings->skgen_options & SKGEN_CUT_LENGTH) &&
arcLengthRatio(arc) >= G.scene->toolsettings->skgen_threshold_length)
arcLengthRatio(arc) >= G.scene->toolsettings->skgen_length_ratio)
{
EditBone *child = NULL;
EditBone *parent = NULL;
int same = 0;
int index = 0;
int stride = 1;
float lengthLimit = 1.5f; // use value from UI
float lengthLimit = G.scene->toolsettings->skgen_length_limit;
// If head is the highest node, invert stride and start index
if (head == arc->v2)
@ -3330,14 +3330,14 @@ void generateSkeletonFromReebGraph(ReebGraph *rg)
lastBone = parent; /* set last bone in the chain */
added = 1;
added = 1;
}
/************************* CUT ANGLE *****************************/
else if (G.scene->toolsettings->skgen_options & SKGEN_CUT_ANGLE)
{
EditBone *child = NULL;
EditBone *parent = NULL;
float angleLimit = 0.80f;//cosf(M_PI / 4);//cosf(G.scene->toolsettings->skgen_threshold_angle * M_PI / 180.0f);
float angleLimit = (float)cos(G.scene->toolsettings->skgen_angle_limit * M_PI / 180.0f);
int same = 0;
int index = 0;
int stride = 1;

View File

@ -382,9 +382,28 @@ void buildAdjacencyList(ReebGraph *rg)
}
/****************************************** SMOOTHING **************************************************/
void smoothGraph(ReebGraph *rg)
void postprocessGraph(ReebGraph *rg, char mode)
{
ReebArc *arc;
float fac1, fac2, fac3;
switch(mode)
{
case SKGEN_AVERAGE:
fac1 = fac2 = fac3 = 1.0f / 3.0f;
break;
case SKGEN_SMOOTH:
fac1 = fac3 = 0.25f;
fac2 = 0.5f;
break;
case SKGEN_SHARPEN:
fac1 = fac2 = -0.5f;
fac2 = 2.0f;
break;
default:
error("Unknown post processing mode");
return;
}
for(arc = rg->arcs.first; arc; arc = arc->next)
{
@ -394,8 +413,8 @@ void smoothGraph(ReebGraph *rg)
for(index = 1; index < bcount - 1; index++)
{
VecLerpf(buckets[index].p, buckets[index].p, buckets[index - 1].p, 0.5f);
VecLerpf(buckets[index].p, buckets[index].p, buckets[index + 1].p, 1.0f/3.0f);
VecLerpf(buckets[index].p, buckets[index].p, buckets[index - 1].p, fac1 / (fac1 + fac2));
VecLerpf(buckets[index].p, buckets[index].p, buckets[index + 1].p, fac3 / (fac1 + fac2 + fac3));
}
}
}
@ -1806,9 +1825,9 @@ void generateSkeleton(void)
verifyBuckets(rg);
if (G.scene->toolsettings->skgen_options & SKGEN_SMOOTH)
if (G.scene->toolsettings->skgen_postpro != SKGEN_NONE)
{
smoothGraph(rg);
postprocessGraph(rg, G.scene->toolsettings->skgen_postpro);
}
buildAdjacencyList(rg);