From 39a7a2483875d75db29e5fb05aa123e009094957 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Sun, 22 Jun 2008 17:06:50 +0000 Subject: [PATCH] Display graph in 3d view --- source/blender/include/reeb.h | 8 +- source/blender/src/buttons_editing.c | 20 +- source/blender/src/drawview.c | 4 + source/blender/src/reeb.c | 456 ++++++++++++++++++--------- source/blender/src/usiblender.c | 4 + 5 files changed, 338 insertions(+), 154 deletions(-) diff --git a/source/blender/include/reeb.h b/source/blender/include/reeb.h index c6be9ba2fbe..58dfb207764 100644 --- a/source/blender/include/reeb.h +++ b/source/blender/include/reeb.h @@ -119,7 +119,7 @@ int weightFromDistance(struct EditMesh *em); int weightFromLoc(struct EditMesh *me, int axis); void weightToVCol(struct EditMesh *em, int index); void arcToVCol(struct ReebGraph *rg, struct EditMesh *em, int index); -void angleToVCol(EditMesh *em, int index); +void angleToVCol(struct EditMesh *em, int index); void renormalizeWeight(struct EditMesh *em, float newmax); ReebGraph * generateReebGraph(struct EditMesh *me, int subdivisions); @@ -155,7 +155,13 @@ void verifyFaces(ReebGraph *rg); /*********************** PUBLIC *********************************/ ReebGraph *BIF_ReebGraphFromEditMesh(void); + +void BIF_GlobalReebGraphFromEditMesh(void); +void BIF_GlobalReebFree(void); + void REEB_freeGraph(ReebGraph *rg); void REEB_exportGraph(ReebGraph *rg, int count); +void REEB_draw(); + #endif /*REEB_H_*/ diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 77245049a1f..df67ffccdeb 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -180,6 +180,8 @@ #include "butspace.h" // own module #include "multires.h" +#include "reeb.h" + static float editbutweight= 1.0; float editbutvweight= 1; static int actmcol= 0, acttface= 0, acttface_rnd = 0, actmcol_rnd = 0; @@ -4992,6 +4994,16 @@ static void skgen_reorder(void *option, void *arg2) } } +static void skgen_graphgen(void *arg1, void *arg2) +{ + BIF_GlobalReebGraphFromEditMesh(); +} + +static void skgen_graphfree(void *arg1, void *arg2) +{ + BIF_GlobalReebFree(); +} + static void editing_panel_mesh_skgen_retarget(Object *ob, Mesh *me) { uiBlock *block; @@ -5035,10 +5047,14 @@ static void editing_panel_mesh_skgen(Object *ob, Mesh *me) uiNewPanelTabbed("Mesh Tools More", "Editing"); if(uiNewPanel(curarea, block, "Skeleton Generator", "Editing", 960, 0, 318, 204)==0) return; - uiDefBut(block, BUT, B_GEN_SKELETON, "Generate Skeleton", 1025,170,250,19, 0, 0, 0, 0, 0, "Generate Skeleton from Mesh"); + uiDefBut(block, BUT, B_GEN_SKELETON, "Generate Skeleton", 1025,170,125,19, 0, 0, 0, 0, 0, "Generate Skeleton from Mesh"); + but = uiDefBut(block, BUT, B_DIFF, "Generate", 1150,170,65,19, 0, 0, 0, 0, 0, "Generate Graph from Mesh"); + uiButSetFunc(but, skgen_graphgen, NULL, NULL); + but = uiDefBut(block, BUT, B_DIFF, "Free", 1215,170,60,19, 0, 0, 0, 0, 0, "Free Graph from Mesh"); + uiButSetFunc(but, skgen_graphfree, NULL, NULL); uiBlockBeginAlign(block); - 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"); + uiDefButS(block, NUM, B_DIFF, "Resolution:", 1025,150,225,19, &G.scene->toolsettings->skgen_resolution,2.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, "T:", 1111,130,164,19, &G.scene->toolsettings->skgen_threshold_internal,0.0, 1.0, 10, 0, "Specify the threshold ratio for filtering internal arcs"); diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 52e0d3d6f05..b3bc8f36388 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -159,6 +159,8 @@ #include "RE_pipeline.h" // make_stars +#include "reeb.h" + #include "multires.h" /* For MULTISAMPLE_ARB #define. @@ -3145,6 +3147,8 @@ void drawview3dspace(ScrArea *sa, void *spacedata) BIF_drawPropCircle(); // only editmode and particles have proportional edit BIF_drawSnap(); } + + REEB_draw(); if(G.scene->radio) RAD_drawall(v3d->drawtype>=OB_SOLID); diff --git a/source/blender/src/reeb.c b/source/blender/src/reeb.c index 4153d4f87ff..59afd0f1327 100644 --- a/source/blender/src/reeb.c +++ b/source/blender/src/reeb.c @@ -51,6 +51,7 @@ #include "BIF_interface.h" #include "BIF_toolbox.h" #include "BIF_graphics.h" +#include "BIF_gl.h" #include "BKE_global.h" #include "BKE_utildefines.h" @@ -65,6 +66,9 @@ /* REPLACE WITH NEW ONE IN UTILDEFINES ONCE PATCH IS APPLIED */ #define FTOCHAR(val) (val<=0.0f)? 0 : ((val>(1.0f-0.5f/255.0f))? 255 : (char)((255.0f*val)+0.5f)) +ReebGraph *GLOBAL_RG = NULL; +ReebGraph *FILTERED_RG = NULL; + /* * Skeleton generation algorithm based on: * "Harmonic Skeleton for Realistic Character Animation" @@ -86,10 +90,10 @@ typedef enum { MERGE_APPEND } MergeDirection; -int mergeArcs(ReebGraph *rg, ReebArc *a0, ReebArc *a1); -int mergeConnectedArcs(ReebGraph *rg, ReebArc *a0, ReebArc *a1); +int mergeArcs(ReebGraph *GLOBAL_RG, ReebArc *a0, ReebArc *a1); +int mergeConnectedArcs(ReebGraph *GLOBAL_RG, ReebArc *a0, ReebArc *a1); EditEdge * NextEdgeForVert(EditMesh *em, EditVert *v); -void mergeArcFaces(ReebGraph *rg, ReebArc *aDst, ReebArc *aSrc); +void mergeArcFaces(ReebGraph *GLOBAL_RG, ReebArc *aDst, ReebArc *aSrc); void addFacetoArc(ReebArc *arc, EditFace *efa); void REEB_RadialSymmetry(BNode* root_node, RadialArc* ring, int count); @@ -243,11 +247,11 @@ void calculateArcLength(ReebArc *arc) arc->length += VecLenf(arc->tail->p, vec1); } -void calculateGraphLength(ReebGraph *rg) +void calculateGraphLength(ReebGraph *GLOBAL_RG) { ReebArc *arc; - for (arc = rg->arcs.first; arc; arc = arc->next) + for (arc = GLOBAL_RG->arcs.first; arc; arc = arc->next) { calculateArcLength(arc); } @@ -294,13 +298,13 @@ void REEB_freeArc(BArc *barc) MEM_freeN(arc); } -void REEB_freeGraph(ReebGraph *rg) +void REEB_freeGraph(ReebGraph *GLOBAL_RG) { ReebArc *arc; ReebNode *node; // free nodes - for( node = rg->nodes.first; node; node = node->next ) + for( node = GLOBAL_RG->nodes.first; node; node = node->next ) { // Free adjacency lists if (node->arcs != NULL) @@ -308,10 +312,10 @@ void REEB_freeGraph(ReebGraph *rg) MEM_freeN(node->arcs); } } - BLI_freelistN(&rg->nodes); + BLI_freelistN(&GLOBAL_RG->nodes); // free arcs - arc = rg->arcs.first; + arc = GLOBAL_RG->arcs.first; while( arc ) { ReebArc *next = arc->next; @@ -320,23 +324,23 @@ void REEB_freeGraph(ReebGraph *rg) } // free edge map - BLI_edgehash_free(rg->emap, NULL); + BLI_edgehash_free(GLOBAL_RG->emap, NULL); - MEM_freeN(rg); + MEM_freeN(GLOBAL_RG); } -void repositionNodes(ReebGraph *rg) +void repositionNodes(ReebGraph *GLOBAL_RG) { BArc *arc = NULL; BNode *node = NULL; // Reset node positions - for(node = rg->nodes.first; node; node = node->next) + for(node = GLOBAL_RG->nodes.first; node; node = node->next) { node->p[0] = node->p[1] = node->p[2] = 0; } - for(arc = rg->arcs.first; arc; arc = arc->next) + for(arc = GLOBAL_RG->arcs.first; arc; arc = arc->next) { if (((ReebArc*)arc)->bcount > 0) { @@ -353,16 +357,16 @@ void repositionNodes(ReebGraph *rg) } } -void verifyNodeDegree(ReebGraph *rg) +void verifyNodeDegree(ReebGraph *GLOBAL_RG) { #ifdef DEBUG_REEB ReebNode *node = NULL; ReebArc *arc = NULL; - for(node = rg->nodes.first; node; node = node->next) + for(node = GLOBAL_RG->nodes.first; node; node = node->next) { int count = 0; - for(arc = rg->arcs.first; arc; arc = arc->next) + for(arc = GLOBAL_RG->arcs.first; arc; arc = arc->next) { if (arc->head == node || arc->tail == node) { @@ -377,11 +381,11 @@ void verifyNodeDegree(ReebGraph *rg) #endif } -void verifyBuckets(ReebGraph *rg) +void verifyBuckets(ReebGraph *GLOBAL_RG) { #ifdef DEBUG_REEB ReebArc *arc = NULL; - for(arc = rg->arcs.first; arc; arc = arc->next) + for(arc = GLOBAL_RG->arcs.first; arc; arc = arc->next) { ReebNode *head = (ReebNode*)arc->head; ReebNode *tail = (ReebNode*)arc->tail; @@ -413,12 +417,12 @@ void verifyBuckets(ReebGraph *rg) #endif } -void verifyFaces(ReebGraph *rg) +void verifyFaces(ReebGraph *GLOBAL_RG) { #ifdef DEBUG_REEB int total = 0; ReebArc *arc = NULL; - for(arc = rg->arcs.first; arc; arc = arc->next) + for(arc = GLOBAL_RG->arcs.first; arc; arc = arc->next) { total += BLI_ghash_size(arc->faces); } @@ -625,7 +629,7 @@ void REEB_AxialSymmetry(BNode* root_node, BNode* node1, BNode* node2, struct BAr /****************************************** SMOOTHING **************************************************/ -void postprocessGraph(ReebGraph *rg, char mode) +void postprocessGraph(ReebGraph *GLOBAL_RG, char mode) { ReebArc *arc; float fac1 = 0, fac2 = 1, fac3 = 0; @@ -648,7 +652,7 @@ void postprocessGraph(ReebGraph *rg, char mode) return; } - for(arc = rg->arcs.first; arc; arc = arc->next) + for(arc = GLOBAL_RG->arcs.first; arc; arc = arc->next) { EmbedBucket *buckets = arc->buckets; int bcount = arc->bcount; @@ -683,9 +687,9 @@ int compareNodesWeight(void *vnode1, void *vnode2) } } -void sortNodes(ReebGraph *rg) +void sortNodes(ReebGraph *GLOBAL_RG) { - BLI_sortlist(&rg->nodes, compareNodesWeight); + BLI_sortlist(&GLOBAL_RG->nodes, compareNodesWeight); } int compareArcsWeight(void *varc1, void *varc2) @@ -709,9 +713,9 @@ int compareArcsWeight(void *varc1, void *varc2) } } -void sortArcs(ReebGraph *rg) +void sortArcs(ReebGraph *GLOBAL_RG) { - BLI_sortlist(&rg->arcs, compareArcsWeight); + BLI_sortlist(&GLOBAL_RG->arcs, compareArcsWeight); } /****************************************** FILTERING **************************************************/ @@ -745,12 +749,12 @@ int compareArcs(void *varc1, void *varc2) } } -void filterArc(ReebGraph *rg, ReebNode *newNode, ReebNode *removedNode, ReebArc * srcArc, int merging) +void filterArc(ReebGraph *GLOBAL_RG, ReebNode *newNode, ReebNode *removedNode, ReebArc * srcArc, int merging) { ReebArc *arc = NULL, *nextArc = NULL; /* first pass, merge buckets for arcs that spawned the two nodes into the source arc*/ - for(arc = rg->arcs.first; arc; arc = arc->next) + for(arc = GLOBAL_RG->arcs.first; arc; arc = arc->next) { if (arc->head == srcArc->head && arc->tail == srcArc->tail && arc != srcArc) { @@ -761,7 +765,7 @@ void filterArc(ReebGraph *rg, ReebNode *newNode, ReebNode *removedNode, ReebArc } /* second pass, replace removedNode by newNode, remove arcs that are collapsed in a loop */ - arc = rg->arcs.first; + arc = GLOBAL_RG->arcs.first; while(arc) { nextArc = arc->next; @@ -786,7 +790,7 @@ void filterArc(ReebGraph *rg, ReebNode *newNode, ReebNode *removedNode, ReebArc // If it's safeArc, it'll be removed later, so keep it for now if (arc != srcArc) { - BLI_remlink(&rg->arcs, arc); + BLI_remlink(&GLOBAL_RG->arcs, arc); REEB_freeArc((BArc*)arc); } } @@ -796,13 +800,13 @@ void filterArc(ReebGraph *rg, ReebNode *newNode, ReebNode *removedNode, ReebArc // Decrement degree from the other node BLI_otherNode((BArc*)arc, (BNode*)newNode)->degree--; - BLI_remlink(&rg->arcs, arc); + BLI_remlink(&GLOBAL_RG->arcs, arc); REEB_freeArc((BArc*)arc); } else { newNode->degree++; // incrementing degree since we're adding an arc - mergeArcFaces(rg, arc, srcArc); + mergeArcFaces(GLOBAL_RG, arc, srcArc); if (merging) { @@ -820,11 +824,11 @@ void filterArc(ReebGraph *rg, ReebNode *newNode, ReebNode *removedNode, ReebArc } } -void filterNullReebGraph(ReebGraph *rg) +void filterNullReebGraph(ReebGraph *GLOBAL_RG) { ReebArc *arc = NULL, *nextArc = NULL; - arc = rg->arcs.first; + arc = GLOBAL_RG->arcs.first; while(arc) { nextArc = arc->next; @@ -840,29 +844,29 @@ void filterNullReebGraph(ReebGraph *rg) //newNode->weight = FloatLerpf(newNode->weight, removedNode->weight, blend); VecLerpf(newNode->p, newNode->p, removedNode->p, blend); - filterArc(rg, newNode, removedNode, arc, 0); + filterArc(GLOBAL_RG, newNode, removedNode, arc, 0); // Reset nextArc, it might have changed nextArc = arc->next; - BLI_remlink(&rg->arcs, arc); + BLI_remlink(&GLOBAL_RG->arcs, arc); REEB_freeArc((BArc*)arc); - BLI_freelinkN(&rg->nodes, removedNode); + BLI_freelinkN(&GLOBAL_RG->nodes, removedNode); } arc = nextArc; } } -int filterInternalReebGraph(ReebGraph *rg, float threshold) +int filterInternalReebGraph(ReebGraph *GLOBAL_RG, float threshold) { ReebArc *arc = NULL, *nextArc = NULL; int value = 0; - BLI_sortlist(&rg->arcs, compareArcs); + BLI_sortlist(&GLOBAL_RG->arcs, compareArcs); - arc = rg->arcs.first; + arc = GLOBAL_RG->arcs.first; while(arc) { nextArc = arc->next; @@ -885,15 +889,15 @@ int filterInternalReebGraph(ReebGraph *rg, float threshold) removedNode = arc->head; } - filterArc(rg, newNode, removedNode, arc, 1); + filterArc(GLOBAL_RG, newNode, removedNode, arc, 1); // Reset nextArc, it might have changed nextArc = arc->next; - BLI_remlink(&rg->arcs, arc); + BLI_remlink(&GLOBAL_RG->arcs, arc); REEB_freeArc((BArc*)arc); - BLI_freelinkN(&rg->nodes, removedNode); + BLI_freelinkN(&GLOBAL_RG->nodes, removedNode); value = 1; } @@ -903,14 +907,14 @@ int filterInternalReebGraph(ReebGraph *rg, float threshold) return value; } -int filterExternalReebGraph(ReebGraph *rg, float threshold) +int filterExternalReebGraph(ReebGraph *GLOBAL_RG, float threshold) { ReebArc *arc = NULL, *nextArc = NULL; int value = 0; - BLI_sortlist(&rg->arcs, compareArcs); + BLI_sortlist(&GLOBAL_RG->arcs, compareArcs); - arc = rg->arcs.first; + arc = GLOBAL_RG->arcs.first; while(arc) { nextArc = arc->next; @@ -954,7 +958,7 @@ int filterExternalReebGraph(ReebGraph *rg, float threshold) // Merging arc if (merging) { - filterArc(rg, newNode, removedNode, arc, 1); + filterArc(GLOBAL_RG, newNode, removedNode, arc, 1); } else { @@ -965,10 +969,10 @@ int filterExternalReebGraph(ReebGraph *rg, float threshold) // Reset nextArc, it might have changed nextArc = arc->next; - BLI_remlink(&rg->arcs, arc); + BLI_remlink(&GLOBAL_RG->arcs, arc); REEB_freeArc((BArc*)arc); - BLI_freelinkN(&rg->nodes, removedNode); + BLI_freelinkN(&GLOBAL_RG->nodes, removedNode); value = 1; } @@ -978,12 +982,12 @@ int filterExternalReebGraph(ReebGraph *rg, float threshold) return value; } -int filterSmartReebGraph(ReebGraph *rg, float threshold) +int filterSmartReebGraph(ReebGraph *GLOBAL_RG, float threshold) { ReebArc *arc = NULL, *nextArc = NULL; int value = 0; - BLI_sortlist(&rg->arcs, compareArcs); + BLI_sortlist(&GLOBAL_RG->arcs, compareArcs); #ifdef DEBUG_REEB { @@ -994,7 +998,7 @@ int filterSmartReebGraph(ReebGraph *rg, float threshold) } #endif - arc = rg->arcs.first; + arc = GLOBAL_RG->arcs.first; while(arc) { nextArc = arc->next; @@ -1124,7 +1128,7 @@ int filterSmartReebGraph(ReebGraph *rg, float threshold) // Merging arc if (merging) { - filterArc(rg, newNode, removedNode, arc, 1); + filterArc(GLOBAL_RG, newNode, removedNode, arc, 1); } else { @@ -1135,10 +1139,10 @@ int filterSmartReebGraph(ReebGraph *rg, float threshold) // Reset nextArc, it might have changed nextArc = arc->next; - BLI_remlink(&rg->arcs, arc); + BLI_remlink(&GLOBAL_RG->arcs, arc); REEB_freeArc((BArc*)arc); - BLI_freelinkN(&rg->nodes, removedNode); + BLI_freelinkN(&GLOBAL_RG->nodes, removedNode); value = 1; } } @@ -1216,7 +1220,7 @@ void exportNode(FILE *f, char *text, ReebNode *node) fprintf(f, "%s i:%i w:%f d:%i %f %f %f\n", text, node->index, node->weight, node->degree, node->p[0], node->p[1], node->p[2]); } -void REEB_exportGraph(ReebGraph *rg, int count) +void REEB_exportGraph(ReebGraph *GLOBAL_RG, int count) { ReebArc *arc; char filename[128]; @@ -1232,7 +1236,7 @@ void REEB_exportGraph(ReebGraph *rg, int count) } f = fopen(filename, "w"); - for(arc = rg->arcs.first; arc; arc = arc->next) + for(arc = GLOBAL_RG->arcs.first; arc; arc = arc->next) { int i; float p[3]; @@ -1256,11 +1260,11 @@ void REEB_exportGraph(ReebGraph *rg, int count) /***************************************** MAIN ALGORITHM **********************************************/ -ReebArc * findConnectedArc(ReebGraph *rg, ReebArc *arc, ReebNode *v) +ReebArc * findConnectedArc(ReebGraph *GLOBAL_RG, ReebArc *arc, ReebNode *v) { ReebArc *nextArc = arc->next; - for(nextArc = rg->arcs.first; nextArc; nextArc = nextArc->next) + for(nextArc = GLOBAL_RG->arcs.first; nextArc; nextArc = nextArc->next) { if (arc != nextArc && (nextArc->head == v || nextArc->tail == v)) { @@ -1272,24 +1276,24 @@ ReebArc * findConnectedArc(ReebGraph *rg, ReebArc *arc, ReebNode *v) } -void removeNormalNodes(ReebGraph *rg) +void removeNormalNodes(ReebGraph *GLOBAL_RG) { ReebArc *arc; // Merge degree 2 nodes - for(arc = rg->arcs.first; arc; arc = arc->next) + for(arc = GLOBAL_RG->arcs.first; arc; arc = 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 *nextArc = (ReebArc*)BLI_findConnectedArc((BGraph*)GLOBAL_RG, (BArc*)arc, (BNode*)arc->head); // Merge arc only if needed if (arc->head == nextArc->tail) { - mergeConnectedArcs(rg, arc, nextArc); + mergeConnectedArcs(GLOBAL_RG, arc, nextArc); } // Otherwise, mark down vert else @@ -1301,12 +1305,12 @@ 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 *nextArc = (ReebArc*)BLI_findConnectedArc((BGraph*)GLOBAL_RG, (BArc*)arc, (BNode*)arc->tail); // Merge arc only if needed if (arc->tail == nextArc->head) { - mergeConnectedArcs(rg, arc, nextArc); + mergeConnectedArcs(GLOBAL_RG, arc, nextArc); } // Otherwise, mark down vert else @@ -1349,7 +1353,7 @@ void addFacetoArc(ReebArc *arc, EditFace *efa) BLI_ghash_insert(arc->faces, efa, efa); } -void mergeArcFaces(ReebGraph *rg, ReebArc *aDst, ReebArc *aSrc) +void mergeArcFaces(ReebGraph *GLOBAL_RG, ReebArc *aDst, ReebArc *aSrc) { GHashIterator ghi; @@ -1362,7 +1366,7 @@ void mergeArcFaces(ReebGraph *rg, ReebArc *aDst, ReebArc *aSrc) } } -void mergeArcEdges(ReebGraph *rg, ReebArc *aDst, ReebArc *aSrc, MergeDirection direction) +void mergeArcEdges(ReebGraph *GLOBAL_RG, ReebArc *aDst, ReebArc *aSrc, MergeDirection direction) { ReebEdge *e = NULL; @@ -1387,7 +1391,7 @@ void mergeArcEdges(ReebGraph *rg, ReebArc *aDst, ReebArc *aSrc, MergeDirection d if (direction == MERGE_LOWER) { - void **p = BLI_edgehash_lookup_p(rg->emap, e->v1->index, e->v2->index); + void **p = BLI_edgehash_lookup_p(GLOBAL_RG->emap, e->v1->index, e->v2->index); newEdge->nextEdge = e; @@ -1419,13 +1423,13 @@ void mergeArcEdges(ReebGraph *rg, ReebArc *aDst, ReebArc *aSrc, MergeDirection d } // return 1 on full merge -int mergeConnectedArcs(ReebGraph *rg, ReebArc *a0, ReebArc *a1) +int mergeConnectedArcs(ReebGraph *GLOBAL_RG, ReebArc *a0, ReebArc *a1) { int result = 0; ReebNode *removedNode = NULL; - mergeArcEdges(rg, a0, a1, MERGE_APPEND); - mergeArcFaces(rg, a0, a1); + mergeArcEdges(GLOBAL_RG, a0, a1, MERGE_APPEND); + mergeArcFaces(GLOBAL_RG, a0, a1); // Bring a0 to the combine length of both arcs if (a0->tail == a1->head) @@ -1444,16 +1448,16 @@ int mergeConnectedArcs(ReebGraph *rg, ReebArc *a0, ReebArc *a1) mergeArcBuckets(a0, a1, a0->head->weight, a0->tail->weight); // remove a1 from graph - BLI_remlink(&rg->arcs, a1); + BLI_remlink(&GLOBAL_RG->arcs, a1); REEB_freeArc((BArc*)a1); - BLI_freelinkN(&rg->nodes, removedNode); + BLI_freelinkN(&GLOBAL_RG->nodes, removedNode); result = 1; return result; } // return 1 on full merge -int mergeArcs(ReebGraph *rg, ReebArc *a0, ReebArc *a1) +int mergeArcs(ReebGraph *GLOBAL_RG, ReebArc *a0, ReebArc *a1) { int result = 0; // TRIANGLE POINTS DOWN @@ -1461,8 +1465,8 @@ int mergeArcs(ReebGraph *rg, ReebArc *a0, ReebArc *a1) { if (a0->tail->weight == a1->tail->weight) // tails also the same, arcs can be totally merge together { - mergeArcEdges(rg, a0, a1, MERGE_APPEND); - mergeArcFaces(rg, a0, a1); + mergeArcEdges(GLOBAL_RG, a0, a1, MERGE_APPEND); + mergeArcFaces(GLOBAL_RG, a0, a1); mergeArcBuckets(a0, a1, a0->head->weight, a0->tail->weight); @@ -1471,15 +1475,15 @@ int mergeArcs(ReebGraph *rg, ReebArc *a0, ReebArc *a1) a1->tail->degree--; // remove a1 from graph - BLI_remlink(&rg->arcs, a1); + BLI_remlink(&GLOBAL_RG->arcs, a1); REEB_freeArc((BArc*)a1); result = 1; } else if (a0->tail->weight > a1->tail->weight) // a1->tail->weight is in the middle { - mergeArcEdges(rg, a1, a0, MERGE_LOWER); - mergeArcFaces(rg, a1, a0); + mergeArcEdges(GLOBAL_RG, a1, a0, MERGE_LOWER); + mergeArcFaces(GLOBAL_RG, a1, a0); // Adjust node degree a0->head->degree--; @@ -1491,8 +1495,8 @@ int mergeArcs(ReebGraph *rg, ReebArc *a0, ReebArc *a1) } else // a0>n2 is in the middle { - mergeArcEdges(rg, a0, a1, MERGE_LOWER); - mergeArcFaces(rg, a0, a1); + mergeArcEdges(GLOBAL_RG, a0, a1, MERGE_LOWER); + mergeArcFaces(GLOBAL_RG, a0, a1); // Adjust node degree a1->head->degree--; @@ -1508,8 +1512,8 @@ int mergeArcs(ReebGraph *rg, ReebArc *a0, ReebArc *a1) { if (a0->head->weight > a1->head->weight) // a0->head->weight is in the middle { - mergeArcEdges(rg, a0, a1, MERGE_HIGHER); - mergeArcFaces(rg, a0, a1); + mergeArcEdges(GLOBAL_RG, a0, a1, MERGE_HIGHER); + mergeArcFaces(GLOBAL_RG, a0, a1); // Adjust node degree a1->tail->degree--; @@ -1521,8 +1525,8 @@ int mergeArcs(ReebGraph *rg, ReebArc *a0, ReebArc *a1) } else // a1->head->weight is in the middle { - mergeArcEdges(rg, a1, a0, MERGE_HIGHER); - mergeArcFaces(rg, a1, a0); + mergeArcEdges(GLOBAL_RG, a1, a0, MERGE_HIGHER); + mergeArcFaces(GLOBAL_RG, a1, a0); // Adjust node degree a0->tail->degree--; @@ -1541,12 +1545,12 @@ int mergeArcs(ReebGraph *rg, ReebArc *a0, ReebArc *a1) return result; } -void glueByMergeSort(ReebGraph *rg, ReebArc *a0, ReebArc *a1, ReebEdge *e0, ReebEdge *e1) +void glueByMergeSort(ReebGraph *GLOBAL_RG, ReebArc *a0, ReebArc *a1, ReebEdge *e0, ReebEdge *e1) { int total = 0; while (total == 0 && a0 != a1 && a0 != NULL && a1 != NULL) { - total = mergeArcs(rg, a0, a1); + total = mergeArcs(GLOBAL_RG, a0, a1); if (total == 0) // if it wasn't a total merge, go forward { @@ -1562,18 +1566,18 @@ void glueByMergeSort(ReebGraph *rg, ReebArc *a0, ReebArc *a1, ReebEdge *e0, Reeb } } -void mergePaths(ReebGraph *rg, ReebEdge *e0, ReebEdge *e1, ReebEdge *e2) +void mergePaths(ReebGraph *GLOBAL_RG, ReebEdge *e0, ReebEdge *e1, ReebEdge *e2) { ReebArc *a0, *a1, *a2; a0 = e0->arc; a1 = e1->arc; a2 = e2->arc; - glueByMergeSort(rg, a0, a1, e0, e1); - glueByMergeSort(rg, a0, a2, e0, e2); + glueByMergeSort(GLOBAL_RG, a0, a1, e0, e1); + glueByMergeSort(GLOBAL_RG, a0, a2, e0, e2); } -ReebNode * addNode(ReebGraph *rg, EditVert *eve, float weight) +ReebNode * addNode(ReebGraph *GLOBAL_RG, EditVert *eve, float weight) { ReebNode *node = NULL; @@ -1584,20 +1588,20 @@ ReebNode * addNode(ReebGraph *rg, EditVert *eve, float weight) node->arcs = NULL; node->degree = 0; node->weight = weight; - node->index = rg->totnodes; + node->index = GLOBAL_RG->totnodes; VECCOPY(node->p, eve->co); - BLI_addtail(&rg->nodes, node); - rg->totnodes++; + BLI_addtail(&GLOBAL_RG->nodes, node); + GLOBAL_RG->totnodes++; return node; } -ReebEdge * createArc(ReebGraph *rg, ReebNode *node1, ReebNode *node2) +ReebEdge * createArc(ReebGraph *GLOBAL_RG, ReebNode *node1, ReebNode *node2) { ReebEdge *edge; - edge = BLI_edgehash_lookup(rg->emap, node1->index, node2->index); + edge = BLI_edgehash_lookup(GLOBAL_RG->emap, node1->index, node2->index); // Only add existing edges that haven't been added yet if (edge == NULL) @@ -1632,14 +1636,14 @@ ReebEdge * createArc(ReebGraph *rg, ReebNode *node1, ReebNode *node2) v1->degree++; v2->degree++; - BLI_edgehash_insert(rg->emap, node1->index, node2->index, edge); + BLI_edgehash_insert(GLOBAL_RG->emap, node1->index, node2->index, edge); edge->arc = arc; edge->nextEdge = NULL; edge->v1 = v1; edge->v2 = v2; - BLI_addtail(&rg->arcs, arc); + BLI_addtail(&GLOBAL_RG->arcs, arc); BLI_addtail(&arc->edges, edge); /* adding buckets for embedding */ @@ -1673,15 +1677,15 @@ ReebEdge * createArc(ReebGraph *rg, ReebNode *node1, ReebNode *node2) return edge; } -void addTriangleToGraph(ReebGraph *rg, ReebNode * n1, ReebNode * n2, ReebNode * n3, EditFace *efa) +void addTriangleToGraph(ReebGraph *GLOBAL_RG, ReebNode * n1, ReebNode * n2, ReebNode * n3, EditFace *efa) { ReebEdge *re1, *re2, *re3; ReebEdge *e1, *e2, *e3; float len1, len2, len3; - re1 = createArc(rg, n1, n2); - re2 = createArc(rg, n2, n3); - re3 = createArc(rg, n3, n1); + re1 = createArc(GLOBAL_RG, n1, n2); + re2 = createArc(GLOBAL_RG, n2, n3); + re3 = createArc(GLOBAL_RG, n3, n1); addFacetoArc(re1->arc, efa); addFacetoArc(re2->arc, efa); @@ -1723,29 +1727,29 @@ void addTriangleToGraph(ReebGraph *rg, ReebNode * n1, ReebNode * n2, ReebNode * } - mergePaths(rg, e1, e2, e3); + mergePaths(GLOBAL_RG, e1, e2, e3); } ReebGraph * newReebGraph() { - ReebGraph *rg; - rg = MEM_callocN(sizeof(ReebGraph), "reeb graph"); + ReebGraph *GLOBAL_RG; + GLOBAL_RG = MEM_callocN(sizeof(ReebGraph), "reeb graph"); - rg->totnodes = 0; - rg->emap = BLI_edgehash_new(); + GLOBAL_RG->totnodes = 0; + GLOBAL_RG->emap = BLI_edgehash_new(); - rg->free_arc = REEB_freeArc; - rg->free_node = NULL; - rg->radial_symmetry = REEB_RadialSymmetry; - rg->axial_symmetry = REEB_AxialSymmetry; + GLOBAL_RG->free_arc = REEB_freeArc; + GLOBAL_RG->free_node = NULL; + GLOBAL_RG->radial_symmetry = REEB_RadialSymmetry; + GLOBAL_RG->axial_symmetry = REEB_AxialSymmetry; - return rg; + return GLOBAL_RG; } ReebGraph * generateReebGraph(EditMesh *em, int subdivisions) { - ReebGraph *rg; + ReebGraph *GLOBAL_RG; struct DynamicList * dlist; EditVert *eve; EditFace *efa; @@ -1757,7 +1761,7 @@ ReebGraph * generateReebGraph(EditMesh *em, int subdivisions) int countfaces = 0; #endif - rg = newReebGraph(); + GLOBAL_RG = newReebGraph(); totvert = BLI_countlist(&em->verts); totfaces = BLI_countlist(&em->faces); @@ -1774,11 +1778,11 @@ ReebGraph * generateReebGraph(EditMesh *em, int subdivisions) { eve->hash = index; eve->f2 = 0; - eve->tmp.p = addNode(rg, eve, eve->tmp.fp); + eve->tmp.p = addNode(GLOBAL_RG, eve, eve->tmp.fp); } /* Temporarely convert node list to dynamic list, for indexed access */ - dlist = BLI_dlist_from_listbase(&rg->nodes); + dlist = BLI_dlist_from_listbase(&GLOBAL_RG->nodes); /* Adding face, edge per edge */ for(efa = em->faces.first; efa; efa = efa->next) @@ -1791,29 +1795,29 @@ ReebGraph * generateReebGraph(EditMesh *em, int subdivisions) n2 = (ReebNode*)BLI_dlist_find_link(dlist, efa->v2->hash); n3 = (ReebNode*)BLI_dlist_find_link(dlist, efa->v3->hash); - addTriangleToGraph(rg, n1, n2, n3, efa); + addTriangleToGraph(GLOBAL_RG, n1, n2, n3, efa); if (efa->v4) { ReebNode *n4 = (ReebNode*)efa->v4->tmp.p; - addTriangleToGraph(rg, n1, n3, n4, efa); + addTriangleToGraph(GLOBAL_RG, n1, n3, n4, efa); } #ifdef DEBUG_REEB countfaces++; if (countfaces % 100 == 0) { printf("face %i of %i\n", countfaces, totfaces); - verifyFaces(rg); + verifyFaces(GLOBAL_RG); } #endif } } - BLI_listbase_from_dlist(dlist, &rg->nodes); + BLI_listbase_from_dlist(dlist, &GLOBAL_RG->nodes); - removeNormalNodes(rg); + removeNormalNodes(GLOBAL_RG); - return rg; + return GLOBAL_RG; } /***************************************** WEIGHT UTILS **********************************************/ @@ -2073,8 +2077,9 @@ int weightFromDistance(EditMesh *em) } /* Initialize vertice flag and find at least one selected vertex */ - for(eve = em->verts.first; eve && vCount == 0; eve = eve->next) + for(eve = em->verts.first; eve; eve = eve->next) { + eve->tmp.fp = 0; eve->f1 = 0; if (eve->f & SELECT) { @@ -2094,6 +2099,7 @@ int weightFromDistance(EditMesh *em) { if (eve->f & SELECT) { + printf("one\n"); current_eve = eve; eve->f1 = 1; @@ -2170,14 +2176,27 @@ int weightFromDistance(EditMesh *em) } current_eve->tmp.fp = currentWeight; } + + } while (select_eed != NULL); MEM_freeN(edges); + + printf("%i / %i\n", eIndex, totedge); } } } } + for(eve = em->verts.first; eve && vCount == 0; eve = eve->next) + { + if (eve->f1 == 0) + { + printf("vertex not reached\n"); + break; + } + } + return 1; } @@ -2269,14 +2288,14 @@ void blendColor(MCol *dst, MCol *src) #endif } -void arcToVCol(ReebGraph *rg, EditMesh *em, int index) +void arcToVCol(ReebGraph *GLOBAL_RG, EditMesh *em, int index) { GHashIterator ghi; EditFace *efa; ReebArc *arc; MCol *mcol; MCol col; - int total = BLI_countlist(&rg->arcs); + int total = BLI_countlist(&GLOBAL_RG->arcs); int i = 0; if (!EM_vertColorCheck()) { @@ -2304,7 +2323,7 @@ void arcToVCol(ReebGraph *rg, EditMesh *em, int index) } } - for (arc = rg->arcs.first; arc; arc = arc->next, i++) + for (arc = GLOBAL_RG->arcs.first; arc; arc = arc->next, i++) { float r,g,b; col.a = 1; @@ -2509,7 +2528,7 @@ struct EmbedBucket * currentBucket(struct ReebArcIterator *iter) ReebGraph *BIF_ReebGraphFromEditMesh(void) { EditMesh *em = G.editMesh; - ReebGraph *rg = NULL; + ReebGraph *GLOBAL_RG = NULL; int i; if (em == NULL) @@ -2532,18 +2551,18 @@ ReebGraph *BIF_ReebGraphFromEditMesh(void) weightToVCol(em, 1); #endif - rg = generateReebGraph(em, G.scene->toolsettings->skgen_resolution); + GLOBAL_RG = generateReebGraph(em, G.scene->toolsettings->skgen_resolution); - REEB_exportGraph(rg, -1); + REEB_exportGraph(GLOBAL_RG, -1); - verifyBuckets(rg); + verifyBuckets(GLOBAL_RG); - verifyFaces(rg); + verifyFaces(GLOBAL_RG); /* Remove arcs without embedding */ - filterNullReebGraph(rg); + filterNullReebGraph(GLOBAL_RG); - verifyBuckets(rg); + verifyBuckets(GLOBAL_RG); i = 1; /* filter until there's nothing more to do */ @@ -2553,49 +2572,184 @@ ReebGraph *BIF_ReebGraphFromEditMesh(void) if (G.scene->toolsettings->skgen_options & SKGEN_FILTER_EXTERNAL) { - i |= filterExternalReebGraph(rg, G.scene->toolsettings->skgen_threshold_external * G.scene->toolsettings->skgen_resolution); + i |= filterExternalReebGraph(GLOBAL_RG, G.scene->toolsettings->skgen_threshold_external * G.scene->toolsettings->skgen_resolution); } - verifyBuckets(rg); + verifyBuckets(GLOBAL_RG); if (G.scene->toolsettings->skgen_options & SKGEN_FILTER_INTERNAL) { - i |= filterInternalReebGraph(rg, G.scene->toolsettings->skgen_threshold_internal * G.scene->toolsettings->skgen_resolution); + i |= filterInternalReebGraph(GLOBAL_RG, G.scene->toolsettings->skgen_threshold_internal * G.scene->toolsettings->skgen_resolution); } } - filterSmartReebGraph(rg, 0.5); + //filterSmartReebGraph(GLOBAL_RG, 0.5); #ifdef DEBUG_REEB - arcToVCol(rg, em, 0); + arcToVCol(GLOBAL_RG, em, 0); //angleToVCol(em, 1); #endif - verifyBuckets(rg); + verifyBuckets(GLOBAL_RG); - repositionNodes(rg); + repositionNodes(GLOBAL_RG); - verifyBuckets(rg); + verifyBuckets(GLOBAL_RG); /* Filtering might have created degree 2 nodes, so remove them */ - removeNormalNodes(rg); + removeNormalNodes(GLOBAL_RG); - verifyBuckets(rg); + verifyBuckets(GLOBAL_RG); for(i = 0; i < G.scene->toolsettings->skgen_postpro_passes; i++) { - postprocessGraph(rg, G.scene->toolsettings->skgen_postpro); + postprocessGraph(GLOBAL_RG, G.scene->toolsettings->skgen_postpro); } - BLI_buildAdjacencyList((BGraph*)rg); + BLI_buildAdjacencyList((BGraph*)GLOBAL_RG); - sortNodes(rg); + sortNodes(GLOBAL_RG); - sortArcs(rg); + sortArcs(GLOBAL_RG); - REEB_exportGraph(rg, -1); + REEB_exportGraph(GLOBAL_RG, -1); - calculateGraphLength(rg); + calculateGraphLength(GLOBAL_RG); - return rg; + return GLOBAL_RG; +} + +void BIF_GlobalReebFree() +{ + if (GLOBAL_RG != NULL) + { + REEB_freeGraph(GLOBAL_RG); + GLOBAL_RG = NULL; + } +} + +void BIF_GlobalReebGraphFromEditMesh(void) +{ + EditMesh *em = G.editMesh; + int i; + + if (em == NULL) + return; + + BIF_GlobalReebFree(); + + if (weightFromDistance(em) == 0) + { + error("No selected vertex\n"); + return; + } + + renormalizeWeight(em, 1.0f); + + if (G.scene->toolsettings->skgen_options & SKGEN_HARMONIC) + { + weightToHarmonic(em); + } + +#ifdef DEBUG_REEB + weightToVCol(em, 0); +#endif + + GLOBAL_RG = generateReebGraph(em, G.scene->toolsettings->skgen_resolution); + + REEB_exportGraph(GLOBAL_RG, -1); + + verifyBuckets(GLOBAL_RG); + + verifyFaces(GLOBAL_RG); + + /* Remove arcs without embedding */ + filterNullReebGraph(GLOBAL_RG); + + verifyBuckets(GLOBAL_RG); + + i = 1; + /* filter until there's nothing more to do */ + while (i == 1) + { + i = 0; /* no work done yet */ + + if (G.scene->toolsettings->skgen_options & SKGEN_FILTER_EXTERNAL) + { + i |= filterExternalReebGraph(GLOBAL_RG, G.scene->toolsettings->skgen_threshold_external * G.scene->toolsettings->skgen_resolution); + } + + verifyBuckets(GLOBAL_RG); + + if (G.scene->toolsettings->skgen_options & SKGEN_FILTER_INTERNAL) + { + i |= filterInternalReebGraph(GLOBAL_RG, G.scene->toolsettings->skgen_threshold_internal * G.scene->toolsettings->skgen_resolution); + } + } + + filterSmartReebGraph(GLOBAL_RG, 0.5); + + verifyBuckets(GLOBAL_RG); + + repositionNodes(GLOBAL_RG); + + verifyBuckets(GLOBAL_RG); + + /* Filtering might have created degree 2 nodes, so remove them */ + removeNormalNodes(GLOBAL_RG); + + verifyBuckets(GLOBAL_RG); + +#ifdef DEBUG_REEB + arcToVCol(GLOBAL_RG, em, 1); + //angleToVCol(em, 1); +#endif + + for(i = 0; i < G.scene->toolsettings->skgen_postpro_passes; i++) + { + postprocessGraph(GLOBAL_RG, G.scene->toolsettings->skgen_postpro); + } + + BLI_buildAdjacencyList((BGraph*)GLOBAL_RG); + + sortNodes(GLOBAL_RG); + + sortArcs(GLOBAL_RG); + + REEB_exportGraph(GLOBAL_RG, -1); + + calculateGraphLength(GLOBAL_RG); +} + +void REEB_draw() +{ + ReebArc *arc; + + if (GLOBAL_RG == NULL) + { + return; + } + + glDisable(GL_DEPTH_TEST); + glColor3f(1, 0, 0); + + for (arc = GLOBAL_RG->arcs.first; arc; arc = arc->next) + { + ReebArcIterator iter; + EmbedBucket *bucket; + + initArcIterator(&iter, arc, arc->head); + + glBegin(GL_LINE_STRIP); + glVertex3fv(arc->head->p); + + for (bucket = nextBucket(&iter); bucket; bucket = nextBucket(&iter)) + { + glVertex3fv(bucket->p); + } + + glVertex3fv(arc->tail->p); + glEnd(); + } + glEnable(GL_DEPTH_TEST); } diff --git a/source/blender/src/usiblender.c b/source/blender/src/usiblender.c index 6c0838288b8..4b3eef88255 100644 --- a/source/blender/src/usiblender.c +++ b/source/blender/src/usiblender.c @@ -145,6 +145,8 @@ #include "PIL_time.h" +#include "reeb.h" + /***/ /* define for setting colors in theme below */ @@ -1048,6 +1050,8 @@ void exit_usiblender(void) BIF_clear_tempfiles(); + BIF_GlobalReebFree(); + tf= G.ttfdata.first; while(tf) {