Use tree length as parameter for multi resolution filtering.

This is the begining of the simplification phase (meaning less parameters to mess up users)
This commit is contained in:
2008-07-10 18:48:27 +00:00
parent fbc105335f
commit ccc62d3385
5 changed files with 73 additions and 9 deletions

View File

@@ -24,6 +24,8 @@ typedef struct BGraph {
ListBase arcs;
ListBase nodes;
float length;
/* function pointer to deal with custom fonctionnality */
FreeArc free_arc;
FreeNode free_node;
@@ -79,6 +81,8 @@ void BLI_freeAdjacencyList(BGraph *rg);
int BLI_FlagSubgraphs(BGraph *graph);
int BLI_subtreeShape(BNode *node, BArc *rootArc, int include_root);
float BLI_subtreeLength(BNode *node, BArc *rootArc);
void BLI_calcGraphLength(BGraph *graph);
void BLI_replaceNode(BGraph *graph, BNode *node_src, BNode *node_replaced);
void BLI_removeDoubleNodes(BGraph *graph, float limit);
@@ -88,7 +92,6 @@ BArc * BLI_findConnectedArc(BGraph *graph, BArc *arc, BNode *v);
int BLI_isGraphCyclic(BGraph *graph);
/*------------ Symmetry handling ------------*/
// float limit = G.scene->toolsettings->skgen_symmetry_limit;
void BLI_markdownSymmetry(BGraph *graph, BNode *root_node, float limit);
void BLI_mirrorAlongAxis(float v[3], float center[3], float axis[3]);

View File

@@ -358,6 +358,59 @@ int BLI_subtreeShape(BNode *node, BArc *rootArc, int include_root)
}
}
float BLI_subtreeLength(BNode *node, BArc *rootArc)
{
float length = 0;
int i;
for(i = 0; i < node->degree; i++)
{
BArc *arc = node->arcs[i];
/* don't go back on the root arc */
if (arc != rootArc)
{
length = MAX2(length, BLI_subtreeLength(BLI_otherNode(arc, node), arc));
}
}
if (rootArc)
{
length += rootArc->length;
}
return length;
}
void BLI_calcGraphLength(BGraph *graph)
{
if (BLI_isGraphCyclic(graph) == 0)
{
float length = 0;
int nb_subgraphs;
int i;
nb_subgraphs = BLI_FlagSubgraphs(graph);
for (i = 1; i <= nb_subgraphs; i++)
{
BNode *node;
for (node = graph->nodes.first; node; node = node->next)
{
/* start on an external node of the subgraph */
if (node->flag == i && node->degree == 1)
{
length = MAX2(length, BLI_subtreeLength(node, NULL));
break;
}
}
}
graph->length = length;
}
}
/********************************* SYMMETRY DETECTION **************************************************/
void markdownSymmetryArc(BGraph *graph, BArc *arc, BNode *node, int level, float limit);

View File

@@ -42,6 +42,8 @@ typedef struct ReebGraph {
ListBase arcs;
ListBase nodes;
float length;
FreeArc free_arc;
FreeNode free_node;
RadialSymmetry radial_symmetry;

View File

@@ -74,6 +74,8 @@ typedef struct RigGraph {
ListBase arcs;
ListBase nodes;
float length;
FreeArc free_arc;
FreeNode free_node;
RadialSymmetry radial_symmetry;

View File

@@ -310,6 +310,7 @@ ReebGraph * copyReebGraph(ReebGraph *rg)
ReebGraph *cp_rg = newReebGraph();
cp_rg->resolution = rg->resolution;
cp_rg->length = rg->length;
cp_rg->link_up = rg;
/* Copy nodes */
@@ -2947,11 +2948,19 @@ ReebGraph *BIF_ReebGraphMultiFromEditMesh(void)
/* Remove arcs without embedding */
filterNullReebGraph(rg);
/* smart filter and loop filter on basic level */
filterGraph(rg, SKGEN_FILTER_SMART, 0, 0);
repositionNodes(rg);
/* Filtering might have created degree 2 nodes, so remove them */
removeNormalNodes(rg);
BLI_rebuildAdjacencyList((BGraph*)rg);
/* calc length before copy, so we have same length on all levels */
BLI_calcGraphLength((BGraph*)rg);
for (i = 0; i < nb_levels; i++)
{
rg = copyReebGraph(rg);
@@ -2959,18 +2968,13 @@ ReebGraph *BIF_ReebGraphMultiFromEditMesh(void)
for (rgi = rg, i = nb_levels, previous = NULL; rgi; previous = rgi, rgi = rgi->link_up, i--)
{
/* don't fully filter last level */
/* don't filter last level */
if (rgi->link_up)
{
float internal_threshold = G.scene->toolsettings->skgen_threshold_internal * (i / (float)nb_levels);
float external_threshold = G.scene->toolsettings->skgen_threshold_external * (i / (float)nb_levels);
float internal_threshold = rg->length * G.scene->toolsettings->skgen_threshold_internal * (i / (float)nb_levels);
float external_threshold = rg->length * G.scene->toolsettings->skgen_threshold_external * (i / (float)nb_levels);
filterGraph(rgi, G.scene->toolsettings->skgen_options, internal_threshold, external_threshold);
}
/* on last level, only smart filter and loop filter */
else
{
filterGraph(rgi, SKGEN_FILTER_SMART, 0, 0);
}
finalizeGraph(rgi, G.scene->toolsettings->skgen_postpro_passes, G.scene->toolsettings->skgen_postpro);