diff --git a/source/blender/include/reeb.h b/source/blender/include/reeb.h index d4a5187df0f..0be9dd29b86 100644 --- a/source/blender/include/reeb.h +++ b/source/blender/include/reeb.h @@ -51,7 +51,7 @@ typedef struct ReebGraph { int resolution; int totnodes; struct EdgeHash *emap; - struct ReebGraph *link; /* for multi resolution filtering, points to higher levels */ + struct ReebGraph *link_up; /* for multi resolution filtering, points to higher levels */ } ReebGraph; typedef struct EmbedBucket { @@ -75,6 +75,7 @@ typedef struct ReebNode { int index; float weight; + struct ReebNode *link_down; /* for multi resolution filtering, points to lower levels, if present */ } ReebNode; typedef struct ReebEdge { @@ -103,7 +104,7 @@ typedef struct ReebArc { struct GHash *faces; float angle; - struct ReebArc *link; /* for multi resolution filtering, points to higher levels */ + struct ReebArc *link_up; /* for multi resolution filtering, points to higher levels */ } ReebArc; typedef struct ReebArcIterator { @@ -159,12 +160,14 @@ void verifyFaces(ReebGraph *rg); /*********************** PUBLIC *********************************/ ReebGraph *BIF_ReebGraphFromEditMesh(void); ReebGraph *BIF_ReebGraphMultiFromEditMesh(void); +void BIF_flagMultiArcs(ReebGraph *rg, int flag); void BIF_GlobalReebGraphFromEditMesh(void); void BIF_GlobalReebFree(void); ReebNode *BIF_otherNodeFromIndex(ReebArc *arc, ReebNode *node); + void REEB_freeGraph(ReebGraph *rg); void REEB_exportGraph(ReebGraph *rg, int count); void REEB_draw(); diff --git a/source/blender/src/autoarmature.c b/source/blender/src/autoarmature.c index aa0f6a44b68..d24aef04bf6 100644 --- a/source/blender/src/autoarmature.c +++ b/source/blender/src/autoarmature.c @@ -81,7 +81,7 @@ typedef struct RigGraph { /*********************************/ struct RigNode *head; - ReebGraph *link; + ReebGraph *link_mesh; } RigGraph; typedef struct RigNode { @@ -97,7 +97,7 @@ typedef struct RigNode { float symmetry_axis[3]; /*********************************/ - ReebNode *link; + ReebNode *link_mesh; } RigNode; typedef struct RigArc { @@ -114,7 +114,7 @@ typedef struct RigArc { ListBase edges; int count; - ReebArc *link; + ReebArc *link_mesh; } RigArc; typedef struct RigEdge { @@ -387,7 +387,7 @@ static void RIG_findHead(RigGraph *rg) { RigEdge *edge = arc->edges.last; - if (edge->bone->flag & BONESEL_ANY) + if (edge->bone->flag & (BONE_TIPSEL|BONE_SELECTED)) { rg->head = arc->tail; break; @@ -514,7 +514,7 @@ static void retargetArctoArcLength(RigArc *iarc); static RetargetMode detectArcRetargetMode(RigArc *iarc) { RetargetMode mode = RETARGET_AGGRESSIVE; - ReebArc *earc = iarc->link; + ReebArc *earc = iarc->link_mesh; RigEdge *edge; int large_angle = 0; float avg_angle = 0; @@ -738,7 +738,7 @@ static void retargetArctoArcAggresive(RigArc *iarc) RigEdge *edge; EmbedBucket *bucket = NULL; ReebNode *node_start, *node_end; - ReebArc *earc = iarc->link; + ReebArc *earc = iarc->link_mesh; float min_cost = FLT_MAX; float *vec0, *vec1, *vec2; float **vec_cache; @@ -1074,7 +1074,7 @@ static void retargetArctoArcAggresive(RigArc *iarc) static void retargetArctoArcLength(RigArc *iarc) { ReebArcIterator iter; - ReebArc *earc = iarc->link; + ReebArc *earc = iarc->link_mesh; ReebNode *node_start, *node_end; RigEdge *edge; EmbedBucket *bucket = NULL; @@ -1203,7 +1203,7 @@ static void retargetArctoArcLength(RigArc *iarc) static void retargetArctoArc(RigArc *iarc) { - ReebArc *earc = iarc->link; + ReebArc *earc = iarc->link_mesh; if (BLI_countlist(&iarc->edges) == 1) { @@ -1247,27 +1247,27 @@ static void matchMultiResolutionArc(RigNode *start_node, RigArc *next_iarc, Reeb ishape = BLI_subtreeShape((BNode*)start_node, (BArc*)next_iarc, 1) % MAGIC_NUMBER; eshape = BLI_subtreeShape((BNode*)enode, (BArc*)next_earc, 1) % MAGIC_NUMBER; - while (ishape > eshape && next_earc->link) + while (ishape > eshape && next_earc->link_up) { - next_earc = next_earc->link; + next_earc = next_earc->link_up; enode = next_earc->head; eshape = BLI_subtreeShape((BNode*)enode, (BArc*)next_earc, 1) % MAGIC_NUMBER; } next_earc->flag = 1; // mark as taken - next_iarc->link = next_earc; + next_iarc->link_mesh = next_earc; } static void findCorrespondingArc(RigArc *start_arc, RigNode *start_node, RigArc *next_iarc) { - ReebNode *enode = start_node->link; + ReebNode *enode = start_node->link_mesh; ReebArc *next_earc; int symmetry_level = next_iarc->symmetry_level; int symmetry_group = next_iarc->symmetry_group; int symmetry_flag = next_iarc->symmetry_flag; int i; - next_iarc->link = NULL; + next_iarc->link_mesh = NULL; for(i = 0; i < enode->degree; i++) { @@ -1288,7 +1288,7 @@ static void findCorrespondingArc(RigArc *start_arc, RigNode *start_node, RigArc } - if (next_iarc->link == NULL) + if (next_iarc->link_mesh == NULL) { printf("--------------------------\n"); printf("NO CORRESPONDING ARC FOUND\n"); @@ -1310,9 +1310,9 @@ static void findCorrespondingArc(RigArc *start_arc, RigNode *start_node, RigArc static void retargetSubgraph(RigGraph *rigg, RigArc *start_arc, RigNode *start_node) { RigArc *iarc = start_arc; - ReebArc *earc = start_arc->link; + ReebArc *earc = start_arc->link_mesh; RigNode *inode = start_node; - ReebNode *enode = start_node->link; + ReebNode *enode = start_node->link_mesh; int i; retargetArctoArc(iarc); @@ -1320,7 +1320,7 @@ static void retargetSubgraph(RigGraph *rigg, RigArc *start_arc, RigNode *start_n enode = BIF_otherNodeFromIndex(earc, enode); inode = (RigNode*)BLI_otherNode((BArc*)iarc, (BNode*)inode); - inode->link = enode; + inode->link_mesh = enode; for(i = 0; i < inode->degree; i++) { @@ -1330,7 +1330,7 @@ static void retargetSubgraph(RigGraph *rigg, RigArc *start_arc, RigNode *start_n if (next_iarc != iarc) { findCorrespondingArc(iarc, inode, next_iarc); - if (next_iarc->link) + if (next_iarc->link_mesh) { retargetSubgraph(rigg, next_iarc, inode); } @@ -1340,17 +1340,17 @@ static void retargetSubgraph(RigGraph *rigg, RigArc *start_arc, RigNode *start_n static void retargetGraphs(RigGraph *rigg) { - ReebGraph *reebg = rigg->link; + ReebGraph *reebg = rigg->link_mesh; ReebArc *earc; RigArc *iarc; ReebNode *enode; RigNode *inode; /* flag all ReebArcs as not taken */ - for (earc = reebg->arcs.first; earc; earc = earc->next) - { - earc->flag = 0; - } + BIF_flagMultiArcs(reebg, 0); + + /* return to first level */ + reebg = rigg->link_mesh; earc = reebg->arcs.first; iarc = (RigArc*)rigg->head->arcs[0]; @@ -1358,10 +1358,10 @@ static void retargetGraphs(RigGraph *rigg) matchMultiResolutionArc(inode, iarc, earc); - earc = iarc->link; /* find might have changed it */ + earc = iarc->link_mesh; /* find might have changed it */ enode = earc->head; - inode->link = enode; + inode->link_mesh = enode; retargetSubgraph(rigg, iarc, inode); } @@ -1372,9 +1372,6 @@ void BIF_retargetArmature() Base *base; ReebGraph *reebg; - //reebg = BIF_ReebGraphFromEditMesh(); - //BLI_markdownSymmetry((BGraph*)reebg, reebg->nodes.first, G.scene->toolsettings->skgen_symmetry_limit); - reebg = BIF_ReebGraphMultiFromEditMesh(); @@ -1406,7 +1403,7 @@ void BIF_retargetArmature() RIG_printGraph(rigg); - rigg->link = reebg; + rigg->link_mesh = reebg; printf("retargetting %s\n", ob->id.name); diff --git a/source/blender/src/reeb.c b/source/blender/src/reeb.c index b65a23bee99..4b74e0e2e8e 100644 --- a/source/blender/src/reeb.c +++ b/source/blender/src/reeb.c @@ -145,9 +145,9 @@ void REEB_freeGraph(ReebGraph *rg) BLI_edgehash_free(rg->emap, NULL); /* free linked graph */ - if (rg->link) + if (rg->link_up) { - REEB_freeGraph(rg->link); + REEB_freeGraph(rg->link_up); } MEM_freeN(rg); @@ -170,6 +170,14 @@ ReebGraph * newReebGraph() return rg; } +void BIF_flagMultiArcs(ReebGraph *rg, int flag) +{ + for ( ; rg; rg = rg->link_up) + { + BLI_flagArcs((BGraph*)rg, flag); + } +} + ReebNode * addNode(ReebGraph *rg, EditVert *eve, float weight) { ReebNode *node = NULL; @@ -208,6 +216,28 @@ ReebNode * copyNode(ReebGraph *rg, ReebNode *node) return cp_node; } +void relinkNodes(ReebGraph *low_rg, ReebGraph *high_rg) +{ + ReebNode *low_node, *high_node; + + if (low_rg == NULL || high_rg == NULL) + { + return; + } + + for (low_node = low_rg->nodes.first; low_node; low_node = low_node->next) + { + for (high_node = high_rg->nodes.first; high_node; high_node = high_node->next) + { + if (low_node->index == high_node->index) + { + high_node->link_down = low_node; + break; + } + } + } +} + ReebNode *BIF_otherNodeFromIndex(ReebArc *arc, ReebNode *node) { return (arc->head->index == node->index) ? arc->tail : arc->head; @@ -222,7 +252,7 @@ ReebArc * copyArc(ReebGraph *rg, ReebArc *arc) memcpy(cp_arc, arc, sizeof(ReebArc)); - cp_arc->link = arc; + cp_arc->link_up = arc; cp_arc->head = NULL; cp_arc->tail = NULL; @@ -266,7 +296,7 @@ ReebGraph * copyReebGraph(ReebGraph *rg) ReebGraph *cp_rg = newReebGraph(); cp_rg->resolution = rg->resolution; - cp_rg->link = rg; + cp_rg->link_up = rg; /* Copy nodes */ for (node = rg->nodes.first; node; node = node->next) @@ -438,7 +468,7 @@ void verifyFaces(ReebGraph *rg) void verifyMultiResolutionLinks(ReebGraph *rg) { #ifdef DEBUG_REEB - ReebGraph *lower_rg = rg->link; + ReebGraph *lower_rg = rg->link_up; if (lower_rg) { @@ -446,9 +476,9 @@ void verifyMultiResolutionLinks(ReebGraph *rg) for (arc = rg->arcs.first; arc; arc = arc->next) { - if (BLI_findindex(&lower_rg->arcs, arc->link) == -1) + if (BLI_findindex(&lower_rg->arcs, arc->link_up) == -1) { - printf("missing arc %p\n", arc->link); + printf("missing arc %p\n", arc->link_up); } } @@ -2874,7 +2904,7 @@ ReebGraph *BIF_ReebGraphMultiFromEditMesh(void) { EditMesh *em = G.editMesh; ReebGraph *rg = NULL; - ReebGraph *rgi; + ReebGraph *rgi, *previous; int i, nb_levels = 5; if (em == NULL) @@ -2912,10 +2942,10 @@ ReebGraph *BIF_ReebGraphMultiFromEditMesh(void) rg = copyReebGraph(rg); } - for (rgi = rg, i = nb_levels; rgi; rgi = rgi->link, i--) + for (rgi = rg, i = nb_levels, previous = NULL; rgi; previous = rgi, rgi = rgi->link_up, i--) { /* don't fully filter last level */ - if (rgi->link) + 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); @@ -2930,6 +2960,8 @@ ReebGraph *BIF_ReebGraphMultiFromEditMesh(void) finalizeGraph(rgi, G.scene->toolsettings->skgen_postpro_passes, G.scene->toolsettings->skgen_postpro); BLI_markdownSymmetry((BGraph*)rgi, rgi->nodes.first, G.scene->toolsettings->skgen_symmetry_limit); + + relinkNodes(previous, rgi); } verifyMultiResolutionLinks(rg); @@ -3033,15 +3065,15 @@ void REEB_draw() return; } - if (GLOBAL_RG->link && G.scene->toolsettings->skgen_options & SKGEN_DISP_ORIG) + if (GLOBAL_RG->link_up && G.scene->toolsettings->skgen_options & SKGEN_DISP_ORIG) { - for (rg = GLOBAL_RG; rg->link; rg = rg->link) ; + for (rg = GLOBAL_RG; rg->link_up; rg = rg->link_up) ; } else { i = G.scene->toolsettings->skgen_multi_level; - for (rg = GLOBAL_RG; i && rg->link; i--, rg = rg->link) ; + for (rg = GLOBAL_RG; i && rg->link_up; i--, rg = rg->link_up) ; } glPointSize(BIF_GetThemeValuef(TH_VERTEX_SIZE));