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:
parent
e7c4bad8e9
commit
eeb9e1486d
|
@ -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)
|
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue