diff options
author | Martin Poirier <theeth@yahoo.com> | 2008-07-08 00:31:53 +0400 |
---|---|---|
committer | Martin Poirier <theeth@yahoo.com> | 2008-07-08 00:31:53 +0400 |
commit | 52219d52dd5e4902f38d9be4d07f39e67ba461b2 (patch) | |
tree | e71d1f0a2ba4dd15ed5eaf193af1d6a9b290c729 | |
parent | f139e1f1b4a496b193d988cdde02e290dc8cb478 (diff) |
First draft: Use multiresolution graph for retargetting (enables bypassing small appendages that don't correspond to anything on the armature).
-rw-r--r-- | source/blender/blenlib/BLI_graph.h | 2 | ||||
-rw-r--r-- | source/blender/blenlib/intern/graph.c | 38 | ||||
-rw-r--r-- | source/blender/include/reeb.h | 2 | ||||
-rw-r--r-- | source/blender/src/autoarmature.c | 13 | ||||
-rw-r--r-- | source/blender/src/buttons_editing.c | 12 | ||||
-rw-r--r-- | source/blender/src/reeb.c | 83 |
6 files changed, 118 insertions, 32 deletions
diff --git a/source/blender/blenlib/BLI_graph.h b/source/blender/blenlib/BLI_graph.h index a814b6f8c96..ae99ad5f5c7 100644 --- a/source/blender/blenlib/BLI_graph.h +++ b/source/blender/blenlib/BLI_graph.h @@ -78,6 +78,8 @@ void BLI_freeAdjacencyList(BGraph *rg); int BLI_FlagSubgraphs(BGraph *graph); +int BLI_subtreeShape(BNode *node, BArc *rootArc, int include_root); + void BLI_replaceNode(BGraph *graph, BNode *node_src, BNode *node_replaced); void BLI_removeDoubleNodes(BGraph *graph, float limit); diff --git a/source/blender/blenlib/intern/graph.c b/source/blender/blenlib/intern/graph.c index 1371e59a77a..2aea9bc0a4a 100644 --- a/source/blender/blenlib/intern/graph.c +++ b/source/blender/blenlib/intern/graph.c @@ -321,34 +321,40 @@ BArc * BLI_findConnectedArc(BGraph *graph, BArc *arc, BNode *v) /*********************************** GRAPH AS TREE FUNCTIONS *******************************************/ -int BLI_subtreeShape(BNode *node, BArc *rootArc) +int BLI_subtreeShape(BNode *node, BArc *rootArc, int include_root) { int depth = 0; - /* Base case, no arcs leading away */ - if (node->arcs == NULL || *(node->arcs) == NULL) + if (include_root) { - return 0; + BNode *newNode = BLI_otherNode(rootArc, node); + depth = BLI_subtreeShape(newNode, rootArc, 0); } else { - int i; - - for(i = 0; i < node->degree; i++) + /* Base case, no arcs leading away */ + if (node->arcs == NULL || *(node->arcs) == NULL) { - BArc *arc = node->arcs[i]; - - /* only arcs that go down the tree */ - if (arc != rootArc) + return 0; + } + else + { + int i; + + for(i = 0; i < node->degree; i++) { - BNode *newNode = BLI_otherNode(arc, node); - //depth = MAX2(depth, BLI_subtreeShape(newNode, arc)); - depth += BLI_subtreeShape(newNode, arc); + BArc *arc = node->arcs[i]; + + /* only arcs that go down the tree */ + if (arc != rootArc) + { + BNode *newNode = BLI_otherNode(arc, node); + depth += BLI_subtreeShape(newNode, arc, 0); + } } } } - //return depth + 1; return 10 * depth + 1; } @@ -776,7 +782,7 @@ void markdownSymmetryArc(BGraph *graph, BArc *arc, BNode *node, int level, float BNode *connectedNode = BLI_otherNode(connectedArc, node); /* symmetry level is positive value, negative values is subtree depth */ - connectedArc->symmetry_level = -BLI_subtreeShape(connectedNode, connectedArc); + connectedArc->symmetry_level = -BLI_subtreeShape(connectedNode, connectedArc, 0); } } diff --git a/source/blender/include/reeb.h b/source/blender/include/reeb.h index 384e8d82b48..d4a5187df0f 100644 --- a/source/blender/include/reeb.h +++ b/source/blender/include/reeb.h @@ -163,6 +163,8 @@ ReebGraph *BIF_ReebGraphMultiFromEditMesh(void); 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 4b0136092fd..826e81259d9 100644 --- a/source/blender/src/autoarmature.c +++ b/source/blender/src/autoarmature.c @@ -1257,11 +1257,22 @@ static void findCorrespondingArc(RigArc *start_arc, RigNode *start_node, RigArc next_earc->symmetry_group == symmetry_group && next_earc->symmetry_level == symmetry_level) { + int ishape, eshape; printf("-----------------------\n"); printf("CORRESPONDING ARC FOUND\n"); RIG_printArcBones(next_iarc); printf("flag %i -- symmetry level %i -- symmetry flag %i\n", next_earc->flag, next_earc->symmetry_level, next_earc->symmetry_flag); + + ishape = BLI_subtreeShape((BNode*)start_node, (BArc*)next_iarc, 1); + eshape = BLI_subtreeShape((BNode*)enode, (BArc*)next_earc, 1); + + while (ishape > eshape && next_earc->link) + { + next_earc = next_earc->link; + enode = next_earc->head; //enode->link; + eshape = BLI_subtreeShape((BNode*)enode, (BArc*)next_earc, 1); + } next_earc->flag = 1; // mark as taken next_iarc->link = next_earc; @@ -1299,7 +1310,7 @@ static void retargetSubgraph(RigGraph *rigg, RigArc *start_arc, RigNode *start_n retargetArctoArc(iarc); - enode = (ReebNode*)BLI_otherNode((BArc*)earc, (BNode*)enode); + enode = BIF_otherNodeFromIndex(earc, enode); inode = (RigNode*)BLI_otherNode((BArc*)iarc, (BNode*)inode); inode->link = enode; diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 7c8152b037d..fd772066122 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -5027,10 +5027,10 @@ static void editing_panel_mesh_skgen_display(Object *ob, Mesh *me) uiDefButS(block, NUM, B_DIFF, "Resolution:", 1025,150,225,19, &G.scene->toolsettings->skgen_resolution,10.0,1000.0, 0, 0, "Specifies the resolution of the graph's embedding"); uiDefButBitS(block, TOG, SKGEN_HARMONIC, B_DIFF, "H", 1250,150, 25,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Apply harmonic smoothing to the weighting"); uiDefButBitS(block, TOG, SKGEN_FILTER_INTERNAL, B_DIFF, "Filter In", 1025,130, 83,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Filter internal small arcs from graph"); - uiDefButF(block, NUM, B_DIFF, "", 1111,130,164,19, &G.scene->toolsettings->skgen_threshold_internal,0.0, 1.0, 10, 0, "Specify the threshold ratio for filtering internal arcs"); + uiDefButF(block, NUM, B_DIFF, "", 1111,130,164,19, &G.scene->toolsettings->skgen_threshold_internal,0.0, 5.0, 10, 0, "Specify the threshold ratio for filtering internal arcs"); uiDefButBitS(block, TOG, SKGEN_FILTER_EXTERNAL, B_DIFF, "Filter Ex", 1025,110, 53,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Filter external small arcs from graph"); uiDefButBitS(block, TOG, SKGEN_FILTER_SMART, B_DIFF, "Sm", 1078,110, 30,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Smart Filtering"); - uiDefButF(block, NUM, B_DIFF, "", 1111,110,164,19, &G.scene->toolsettings->skgen_threshold_external,0.0, 1.0, 10, 0, "Specify the threshold ratio for filtering external arcs"); + uiDefButF(block, NUM, B_DIFF, "", 1111,110,164,19, &G.scene->toolsettings->skgen_threshold_external,0.0, 5.0, 10, 0, "Specify the threshold ratio for filtering external arcs"); uiBlockEndAlign(block); uiDefButBitS(block, TOG, SKGEN_DISP_LENGTH, REDRAWVIEW3D, "Length", 1025, 60, 83,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Show Length"); @@ -5054,10 +5054,10 @@ static void editing_panel_mesh_skgen_retarget(Object *ob, Mesh *me) uiDefButS(block, NUM, B_DIFF, "Resolution:", 1025,150,225,19, &G.scene->toolsettings->skgen_resolution,10.0,1000.0, 0, 0, "Specifies the resolution of the graph's embedding"); uiDefButBitS(block, TOG, SKGEN_HARMONIC, B_DIFF, "H", 1250,150, 25,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Apply harmonic smoothing to the weighting"); uiDefButBitS(block, TOG, SKGEN_FILTER_INTERNAL, B_DIFF, "Filter In", 1025,130, 83,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Filter internal small arcs from graph"); - uiDefButF(block, NUM, B_DIFF, "", 1111,130,164,19, &G.scene->toolsettings->skgen_threshold_internal,0.0, 1.0, 10, 0, "Specify the threshold ratio for filtering internal arcs"); + uiDefButF(block, NUM, B_DIFF, "", 1111,130,164,19, &G.scene->toolsettings->skgen_threshold_internal,0.0, 5.0, 10, 0, "Specify the threshold ratio for filtering internal arcs"); uiDefButBitS(block, TOG, SKGEN_FILTER_EXTERNAL, B_DIFF, "Filter Ex", 1025,110, 53,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Filter external small arcs from graph"); uiDefButBitS(block, TOG, SKGEN_FILTER_SMART, B_DIFF, "Sm", 1078,110, 30,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Smart Filtering"); - uiDefButF(block, NUM, B_DIFF, "", 1111,110,164,19, &G.scene->toolsettings->skgen_threshold_external,0.0, 1.0, 10, 0, "Specify the threshold ratio for filtering external arcs"); + uiDefButF(block, NUM, B_DIFF, "", 1111,110,164,19, &G.scene->toolsettings->skgen_threshold_external,0.0, 5.0, 10, 0, "Specify the threshold ratio for filtering external arcs"); uiBlockEndAlign(block); uiDefButF(block, NUM, B_DIFF, "Ang:", 1025, 60, 83,19, &G.scene->toolsettings->skgen_retarget_angle_weight, 0, 10, 1, 0, "Angle Weight"); @@ -5090,10 +5090,10 @@ static void editing_panel_mesh_skgen(Object *ob, Mesh *me) uiDefButS(block, NUM, B_DIFF, "Resolution:", 1025,150,225,19, &G.scene->toolsettings->skgen_resolution,10.0,1000.0, 0, 0, "Specifies the resolution of the graph's embedding"); uiDefButBitS(block, TOG, SKGEN_HARMONIC, B_DIFF, "H", 1250,150, 25,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Apply harmonic smoothing to the weighting"); uiDefButBitS(block, TOG, SKGEN_FILTER_INTERNAL, B_DIFF, "Filter In", 1025,130, 83,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Filter internal small arcs from graph"); - uiDefButF(block, NUM, B_DIFF, "", 1111,130,164,19, &G.scene->toolsettings->skgen_threshold_internal,0.0, 1.0, 10, 0, "Specify the threshold ratio for filtering internal arcs"); + uiDefButF(block, NUM, B_DIFF, "", 1111,130,164,19, &G.scene->toolsettings->skgen_threshold_internal,0.0, 5.0, 10, 0, "Specify the threshold ratio for filtering internal arcs"); uiDefButBitS(block, TOG, SKGEN_FILTER_EXTERNAL, B_DIFF, "Filter Ex", 1025,110, 53,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Filter external small arcs from graph"); uiDefButBitS(block, TOG, SKGEN_FILTER_SMART, B_DIFF, "Sm", 1078,110, 30,19, &G.scene->toolsettings->skgen_options, 0, 0, 0, 0, "Smart Filtering"); - uiDefButF(block, NUM, B_DIFF, "", 1111,110,164,19, &G.scene->toolsettings->skgen_threshold_external,0.0, 1.0, 10, 0, "Specify the threshold ratio for filtering external arcs"); + uiDefButF(block, NUM, B_DIFF, "", 1111,110,164,19, &G.scene->toolsettings->skgen_threshold_external,0.0, 5.0, 10, 0, "Specify the threshold ratio for filtering external arcs"); uiBlockEndAlign(block); uiBlockBeginAlign(block); diff --git a/source/blender/src/reeb.c b/source/blender/src/reeb.c index 20c9da75bb2..a0d52944683 100644 --- a/source/blender/src/reeb.c +++ b/source/blender/src/reeb.c @@ -54,6 +54,7 @@ #include "BIF_toolbox.h" #include "BIF_graphics.h" #include "BIF_gl.h" +#include "BIF_resources.h" #include "BKE_global.h" #include "BKE_utildefines.h" @@ -207,6 +208,11 @@ ReebNode * copyNode(ReebGraph *rg, ReebNode *node) return cp_node; } +ReebNode *BIF_otherNodeFromIndex(ReebArc *arc, ReebNode *node) +{ + return (arc->head->index == node->index) ? arc->tail : arc->head; +} + ReebArc * copyArc(ReebGraph *rg, ReebArc *arc) { ReebArc *cp_arc; @@ -429,6 +435,28 @@ void verifyFaces(ReebGraph *rg) #endif } +void verifyMultiResolutionLinks(ReebGraph *rg) +{ +#ifdef DEBUG_REEB + ReebGraph *lower_rg = rg->link; + + if (lower_rg) + { + ReebArc *arc; + + for (arc = rg->arcs.first; arc; arc = arc->next) + { + if (BLI_findindex(&lower_rg->arcs, arc->link) == -1) + { + printf("missing arc %p\n", arc->link); + } + } + + + verifyMultiResolutionLinks(lower_rg); + } +#endif +} /***************************************** BUCKET UTILS **********************************************/ void addVertToBucket(EmbedBucket *b, float co[3]) @@ -1555,22 +1583,35 @@ ReebArc * findConnectedArc(ReebGraph *rg, ReebArc *arc, ReebNode *v) void removeNormalNodes(ReebGraph *rg) { - ReebArc *arc; + ReebArc *arc, *nextArc; // Merge degree 2 nodes - for(arc = rg->arcs.first; arc; arc = arc->next) + for(arc = rg->arcs.first; arc; arc = nextArc) { + nextArc = arc->next; + while (arc->head->degree == 2 || arc->tail->degree == 2) { // merge at v1 if (arc->head->degree == 2) { - ReebArc *nextArc = (ReebArc*)BLI_findConnectedArc((BGraph*)rg, (BArc*)arc, (BNode*)arc->head); + ReebArc *connectedArc = (ReebArc*)BLI_findConnectedArc((BGraph*)rg, (BArc*)arc, (BNode*)arc->head); // Merge arc only if needed - if (arc->head == nextArc->tail) - { - mergeConnectedArcs(rg, arc, nextArc); + if (arc->head == connectedArc->tail) + { + /* remove furthest arc */ + if (arc->tail->weight < connectedArc->head->weight) + { + mergeConnectedArcs(rg, arc, connectedArc); + nextArc = arc->next; + } + else + { + mergeConnectedArcs(rg, connectedArc, arc); + break; + arc = connectedArc; /* arc was removed, continue with connected */ + } } // Otherwise, mark down vert else @@ -1582,12 +1623,23 @@ void removeNormalNodes(ReebGraph *rg) // merge at v2 if (arc->tail->degree == 2) { - ReebArc *nextArc = (ReebArc*)BLI_findConnectedArc((BGraph*)rg, (BArc*)arc, (BNode*)arc->tail); + ReebArc *connectedArc = (ReebArc*)BLI_findConnectedArc((BGraph*)rg, (BArc*)arc, (BNode*)arc->tail); // Merge arc only if needed - if (arc->tail == nextArc->head) + if (arc->tail == connectedArc->head) { - mergeConnectedArcs(rg, arc, nextArc); + /* remove furthest arc */ + if (arc->head->weight < connectedArc->tail->weight) + { + mergeConnectedArcs(rg, arc, connectedArc); + nextArc = arc->next; + } + else + { + mergeConnectedArcs(rg, connectedArc, arc); + break; + arc = connectedArc; /* arc was removed, continue with connected */ + } } // Otherwise, mark down vert else @@ -2879,6 +2931,8 @@ ReebGraph *BIF_ReebGraphMultiFromEditMesh(void) BLI_markdownSymmetry((BGraph*)rgi, rgi->nodes.first, G.scene->toolsettings->skgen_symmetry_limit); } + + verifyMultiResolutionLinks(rg); return rg; } @@ -2990,6 +3044,8 @@ void REEB_draw() for (rg = GLOBAL_RG; i && rg->link; i--, rg = rg->link) ; } + glPointSize(BIF_GetThemeValuef(TH_VERTEX_SIZE)); + glDisable(GL_DEPTH_TEST); for (arc = rg->arcs.first; arc; arc = arc->next, i++) { @@ -3022,6 +3078,13 @@ void REEB_draw() glVertex3fv(arc->tail->p); glEnd(); + + + glColor3f(1, 1, 1); + glBegin(GL_POINTS); + glVertex3fv(arc->head->p); + glVertex3fv(arc->tail->p); + glEnd(); VecLerpf(vec, arc->head->p, arc->tail->p, 0.5f); @@ -3042,4 +3105,6 @@ void REEB_draw() BMF_DrawString( G.fonts, text); } glEnable(GL_DEPTH_TEST); + + glPointSize(1.0); } |