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:
@@ -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]);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -42,6 +42,8 @@ typedef struct ReebGraph {
|
||||
ListBase arcs;
|
||||
ListBase nodes;
|
||||
|
||||
float length;
|
||||
|
||||
FreeArc free_arc;
|
||||
FreeNode free_node;
|
||||
RadialSymmetry radial_symmetry;
|
||||
|
||||
@@ -74,6 +74,8 @@ typedef struct RigGraph {
|
||||
ListBase arcs;
|
||||
ListBase nodes;
|
||||
|
||||
float length;
|
||||
|
||||
FreeArc free_arc;
|
||||
FreeNode free_node;
|
||||
RadialSymmetry radial_symmetry;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user