Revision: 15573 http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15573 Author: theeth Date: 2008-07-14 21:05:25 +0200 (Mon, 14 Jul 2008)
Log Message: ----------- First draft of subgraph joining Modified Paths: -------------- branches/harmonic-skeleton/source/blender/src/reeb.c Modified: branches/harmonic-skeleton/source/blender/src/reeb.c =================================================================== --- branches/harmonic-skeleton/source/blender/src/reeb.c 2008-07-14 18:42:53 UTC (rev 15572) +++ branches/harmonic-skeleton/source/blender/src/reeb.c 2008-07-14 19:05:25 UTC (rev 15573) @@ -103,7 +103,9 @@ void REEB_RadialSymmetry(BNode* root_node, RadialArc* ring, int count); void REEB_AxialSymmetry(BNode* root_node, BNode* node1, BNode* node2, struct BArc* barc1, BArc* barc2); +void flipArcBuckets(ReebArc *arc); + /***************************************** UTILS **********************************************/ void REEB_freeArc(BArc *barc) @@ -355,6 +357,16 @@ } } +void flipArc(ReebArc *arc) +{ + ReebNode *tmp; + tmp = arc->head; + arc->head = arc->tail; + arc->tail = tmp; + + flipArcBuckets(arc); +} + #ifdef DEBUG_REEB_NODE void NodeDegreeDecrement(ReebGraph *rg, ReebNode *node) { @@ -585,8 +597,8 @@ void allocArcBuckets(ReebArc *arc) { int i; - float start = ceil(((ReebNode*)arc->head)->weight); - arc->bcount = (int)(floor(((ReebNode*)arc->tail)->weight) - start) + 1; + float start = ceil(arc->head->weight); + arc->bcount = (int)(floor(arc->tail->weight) - start) + 1; if (arc->bcount > 0) { @@ -641,6 +653,86 @@ } } +void reweightBuckets(ReebArc *arc) +{ + int i; + float start = ceil((arc->head)->weight); + + if (arc->bcount > 0) + { + for(i = 0; i < arc->bcount; i++) + { + arc->buckets[i].val = start + i; + } + } +} + +static void interpolateBuckets(ReebArc *arc, float *start_p, float *end_p, int start_index, int end_index) +{ + int total; + int j; + + total = end_index - start_index + 2; + + for (j = start_index; j <= end_index; j++) + { + EmbedBucket *empty = arc->buckets + j; + empty->nv = 1; + VecLerpf(empty->p, start_p, end_p, (float)(j - start_index + 1) / total); + } +} + +void fillArcEmptyBuckets(ReebArc *arc) +{ + float *start_p, *end_p; + int start_index, end_index; + int missing = 0; + int i; + + start_p = arc->head->p; + + for(i = 0; i < arc->bcount; i++) + { + EmbedBucket *bucket = arc->buckets + i; + + if (missing) + { + if (bucket->nv > 0) + { + missing = 0; + + end_p = bucket->p; + end_index = i - 1; + + interpolateBuckets(arc, start_p, end_p, start_index, end_index); + } + } + else + { + if (bucket->nv == 0) + { + missing = 1; + + if (i > 0) + { + start_p = arc->buckets[i - 1].p; + } + start_index = i; + } + } + } + + if (missing) + { + end_p = arc->tail->p; + end_index = arc->bcount - 1; + + interpolateBuckets(arc, start_p, end_p, start_index, end_index); + } +} + +/**************************************** LENGTH CALCULATIONS ****************************************/ + void calculateArcLength(ReebArc *arc) { ReebArcIterator iter; @@ -966,7 +1058,121 @@ { BLI_sortlist(&rg->arcs, compareArcsWeight); } +/******************************************* JOINING ***************************************************/ +void reweightArc(ReebArc *arc, ReebNode *start_node, float start_weight) +{ + float delta_weight = arc->tail->weight - arc->head->weight; + + if (arc->tail == start_node) + { + flipArc(arc); + } + + arc->head->weight = start_weight; + arc->tail->weight = start_weight + delta_weight; + + reweightBuckets(arc); + + /* recurse here */ +} + +void reweightSubgraph(ReebGraph *rg, ReebNode *start_node, float start_weight) +{ + ReebArc *arc; + + arc = start_node->arcs[0]; + + reweightArc(arc, start_node, start_weight); +} + +int joinSubgraphsEnds(ReebGraph *rg, float threshold, int nb_subgraphs) +{ + int joined = 0; + int subgraph; + + for (subgraph = 1; subgraph <= nb_subgraphs; subgraph++) + { + ReebNode *start_node, *end_node; + + for (start_node = rg->nodes.first; start_node; start_node = start_node->next) + { + if (start_node->flag == subgraph && start_node->degree == 1) + { + for (end_node = rg->nodes.first; end_node; end_node = end_node->next) + { + if (end_node->flag != subgraph && end_node->degree == 1 && VecLenf(start_node->p, end_node->p) < threshold) + { + break; + } + } + + if (end_node) + { + ReebArc *start_arc, *end_arc; + int merging = 0; + + start_arc = start_node->arcs[0]; + end_arc = end_node->arcs[0]; + + if (start_arc->tail == start_node) + { + reweightSubgraph(rg, end_node, start_node->weight); + + end_arc->head = start_node; + + merging = 1; + } + else if (start_arc->head == start_node) + { + reweightSubgraph(rg, start_node, end_node->weight); + + end_arc->tail = start_node; + + merging = 1; + } + + + if (merging) + { + resizeArcBuckets(end_arc); + fillArcEmptyBuckets(end_arc); + + NodeDegreeIncrement(rg, start_node); + + BLI_removeNode((BGraph*)rg, (BNode*)end_node); + } + + joined = 1; + break; + } + } + } + } + + return joined; +} + +int joinSubgraphs(ReebGraph *rg, float threshold) +{ + int nb_subgraphs; + int joined = 0; + + BLI_rebuildAdjacencyList((BGraph*)rg); + + nb_subgraphs = BLI_FlagSubgraphs((BGraph*)rg); + + joined |= joinSubgraphsEnds(rg, threshold, nb_subgraphs); + + if (joined) + { + removeNormalNodes(rg); + BLI_rebuildAdjacencyList((BGraph*)rg); + } + + return joined; +} + /****************************************** FILTERING **************************************************/ float lengthArc(ReebArc *arc) @@ -1055,12 +1261,7 @@ /* flip arcs that flipped, can happen on diamond shapes, mostly on null arcs */ if (arc->head->weight > arc->tail->weight) { - ReebNode *tmp; - tmp = arc->head; - arc->head = arc->tail; - arc->tail = tmp; - - flipArcBuckets(arc); + flipArc(arc); } //newNode->degree++; // incrementing degree since we're adding an arc NodeDegreeIncrement(rg, newNode); @@ -2956,6 +3157,8 @@ /* Filtering might have created degree 2 nodes, so remove them */ removeNormalNodes(rg); + joinSubgraphs(rg, 1.5); + BLI_rebuildAdjacencyList((BGraph*)rg); /* calc length before copy, so we have same length on all levels */ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs