diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp index aa7c673ffe224e334f8665d51db678e62ff01aed..47161edb86894c8d6532a8908749e4f39b79846c 100644 --- a/Fltk/Callbacks.cpp +++ b/Fltk/Callbacks.cpp @@ -1,4 +1,4 @@ -// $Id: Callbacks.cpp,v 1.237 2004-05-18 20:51:50 geuzaine Exp $ +// $Id: Callbacks.cpp,v 1.238 2004-05-19 03:56:08 geuzaine Exp $ // // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle // @@ -222,46 +222,25 @@ int SetGlobalShortcut(int event) return WID->global_shortcuts(event); } -int SelectContour(int type, int num, List_T * List1) +int SelectContour(int type, int num, List_T * List) { - int k = 0, ip, i; + int k = 0, ip; - if(!List_Nbr(List1)) { - switch (type) { - case ENT_LINE: - k = alledgeslinked(num, List1, (List_T *) NULL); - break; - case ENT_SURFACE: - k = allfaceslinked(num, List1, (List_T *) NULL); - break; - } - } - else { - List_T *List2 = List_Create(1, 1, sizeof(int)); - for(i = 0; i < List_Nbr(List1); i++) - List_Add(List2, List_Pointer(List1, i)); - List_Reset(List1); - switch (type) { - case ENT_LINE: - k = alledgeslinked(num, List1, List2); - break; - case ENT_SURFACE: - k = allfaceslinked(num, List1, List2); - break; - } - List_Delete(List2); - } - - for(i = 0; i < List_Nbr(List1); i++) { - List_Read(List1, i, &ip); - switch (type) { - case ENT_LINE: + switch (type) { + case ENT_LINE: + k = allEdgesLinked(num, List); + for(int i = 0; i < List_Nbr(List); i++) { + List_Read(List, i, &ip); HighlightEntityNum(0, abs(ip), 0, 1); - break; - case ENT_SURFACE: + } + break; + case ENT_SURFACE: + k = allFacesLinked(num, List); + for(int i = 0; i < List_Nbr(List); i++) { + List_Read(List, i, &ip); HighlightEntityNum(0, 0, abs(ip), 1); - break; } + break; } return k; @@ -2003,7 +1982,6 @@ static void _new_surface_volume(int mode) List_T *List1 = List_Create(10, 10, sizeof(int)); List_T *List2 = List_Create(10, 10, sizeof(int)); - List_T *ListUnsorted = List_Create(10, 10, sizeof(int)); if(mode == 2) { type = ENT_SURFACE; @@ -2023,7 +2001,6 @@ static void _new_surface_volume(int mode) while(1) { List_Reset(List1); List_Reset(List2); - List_Reset(ListUnsorted); while(1) { if(type == ENT_LINE){ @@ -2044,35 +2021,23 @@ static void _new_surface_volume(int mode) goto stopall; } if(ib == 'u') { - if(List_Nbr(ListUnsorted) > 0){ - for(int i = 0; i < List_Nbr(List1); i++){ - List_Read(List1, i, &num); - ZeroHighlightEntityNum(0, - (type == ENT_LINE) ? abs(num) : 0, - (type != ENT_LINE) ? abs(num) : 0); - } - List_Reset(List1); - List_Pop(ListUnsorted); - for(int i = 0; i < List_Nbr(ListUnsorted); i++){ - List_Read(ListUnsorted, i, &num); - List_Add(List1, &num); - HighlightEntityNum(0, - (type == ENT_LINE) ? abs(num) : 0, - (type != ENT_LINE) ? abs(num) : 0, 1); - } + if(List_Nbr(List1) > 0){ + List_Read(List1, List_Nbr(List1)-1, &num); + ZeroHighlightEntityNum(0, + (type == ENT_LINE) ? abs(num) : 0, + (type != ENT_LINE) ? abs(num) : 0); + List_Pop(List1); Draw(); } } if(ib == 'l') { int num = (type == ENT_LINE) ? c->Num : s->Num; - List_Add(ListUnsorted, &num); if(SelectContour(type, num, List1)) { if(type == ENT_LINE) add_loop(List1, CTX.filename, &num); else add_vol(List1, CTX.filename, &num); List_Reset(List1); - List_Reset(ListUnsorted); List_Add(List2, &num); while(1) { Msg(ONSCREEN, "Select hole boundaries (if none, press 'e')\n" @@ -2087,39 +2052,26 @@ static void _new_surface_volume(int mode) ZeroHighlight(THEM); Draw(); List_Reset(List1); - List_Reset(ListUnsorted); break; } if(ib == 'u') { - if(List_Nbr(ListUnsorted) > 0){ - for(int i = 0; i < List_Nbr(List1); i++){ - List_Read(List1, i, &num); - ZeroHighlightEntityNum(0, - (type == ENT_LINE) ? abs(num) : 0, - (type != ENT_LINE) ? abs(num) : 0); - } - List_Reset(List1); - List_Pop(ListUnsorted); - for(int i = 0; i < List_Nbr(ListUnsorted); i++){ - List_Read(ListUnsorted, i, &num); - List_Add(List1, &num); - HighlightEntityNum(0, - (type == ENT_LINE) ? abs(num) : 0, - (type != ENT_LINE) ? abs(num) : 0, 1); - } + if(List_Nbr(List1) > 0){ + List_Read(List1, List_Nbr(List1)-1, &num); + ZeroHighlightEntityNum(0, + (type == ENT_LINE) ? abs(num) : 0, + (type != ENT_LINE) ? abs(num) : 0); + List_Pop(List1); Draw(); } } if(ib == 'l') { num = (type == ENT_LINE) ? c->Num : s->Num; - List_Add(ListUnsorted, &num); if(SelectContour(type, num, List1)) { if(type == ENT_LINE) add_loop(List1, CTX.filename, &num); else add_vol(List1, CTX.filename, &num); List_Reset(List1); - List_Reset(ListUnsorted); List_Add(List2, &num); } } @@ -2142,7 +2094,6 @@ static void _new_surface_volume(int mode) stopall:; List_Delete(List1); List_Delete(List2); - List_Delete(ListUnsorted); Msg(STATUS3N, "Ready"); Msg(ONSCREEN, ""); } diff --git a/Geo/ExtractContour.cpp b/Geo/ExtractContour.cpp index 2465ffa7b512925ec5dacd33c9805604e4fb7c41..774d937fdeeb078d29c0252c7465e10711541e71 100644 --- a/Geo/ExtractContour.cpp +++ b/Geo/ExtractContour.cpp @@ -1,4 +1,4 @@ -// $Id: ExtractContour.cpp,v 1.1 2004-02-28 00:48:49 geuzaine Exp $ +// $Id: ExtractContour.cpp,v 1.2 2004-05-19 03:56:08 geuzaine Exp $ // // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle // @@ -21,23 +21,22 @@ #include "Gmsh.h" #include "Geo.h" +#include "GeoUtils.h" #include "CAD.h" #include "Mesh.h" -extern Mesh *THEM; - -// Contour extraction by a tree method +// Note: we use List_ISearchSeq so that the input lists don't get +// sorted: it's less efficient, but it allows us to do multi-level +// user-friendly "undo"s... -static Tree_T *treelink; -static Tree_T *treeedges; -static Tree_T *treefaces; +extern Mesh *THEM; typedef struct{ - int n, a, arbre; + int n, a; }nxa; typedef struct{ - int n, visited; + int n; List_T *l; }lnk; @@ -49,237 +48,254 @@ int complink(const void *a, const void *b) return (q->n - w->n); } -static int POINT_FINAL; -static int CONTOUR_TROUVE; -static List_T *VisitedNodes; +// Find all linked edges -void recur_trouvecont(int ip, int ed, List_T * Liste, int gauche, - List_T * old) +void recurFindLinkedEdges(int ed, List_T * edges, Tree_T * points, Tree_T * links) { lnk lk; - nxa a; - int i, rev; - - lk.n = ip; - Tree_Query(treelink, &lk); - if(List_Nbr(lk.l) != 2 && !old) - return; - for(i = 0; i < List_Nbr(lk.l); i++) { - List_Read(lk.l, i, &a); - if(abs(a.a) != abs(ed)) { - if(!old || List_Search(old, &a.a, fcmp_absint) || List_Nbr(lk.l) == 2) { - if(!gauche) { - List_Add(Liste, &a.a); - if(List_Search(VisitedNodes, &a.n, fcmp_absint)) { - CONTOUR_TROUVE = 1; - return; - } - } - if(a.n == POINT_FINAL) { - CONTOUR_TROUVE = 1; - } - else { - recur_trouvecont(a.n, abs(a.a), Liste, gauche, old); - } - if(gauche) { - rev = -a.a; - List_Add(Liste, &rev); - List_Add(VisitedNodes, &a.n); - } + nxa na; + int ip[2]; + Curve *c = FindCurve(ed, THEM); + + ip[0] = c->beg->Num; + ip[1] = c->end->Num; + + for(int l = 0; l < 2; l++) { + lk.n = ip[l]; + if(!Tree_Search(points, &lk.n)) + Tree_Add(points, &lk.n); + else + Tree_Suppress(points, &lk.n); + Tree_Query(links, &lk); + if(List_Nbr(lk.l) == 2) { + for(int i = 0; i < 2; i++) { + List_Read(lk.l, i, &na); + if(na.a != ed) { + if(List_ISearchSeq(edges, &na.a, fcmp_absint) < 0){ + List_Add(edges, &na.a); + recurFindLinkedEdges(na.a, edges, points, links); + } + } } } } } - -void recur_trouvevol(int ifac, int iedge, List_T * Liste, List_T * old, - Tree_T * treeedges, Tree_T * treefaces) +void createEdgeLinks(Tree_T *links) { - lnk lk; - nxa a; - int i, is, rev, l; + lnk li, *pli; + nxa na; Curve *c; - Surface *s = FindSurface(abs(ifac), THEM); - for(l = 0; l < List_Nbr(s->Generatrices); l++) { - List_Read(s->Generatrices, l, &c); - lk.n = abs(c->Num); - is = lk.n; - if(!Tree_Search(treeedges, &is)) { - Tree_Add(treeedges, &is); - } - else { - Tree_Suppress(treeedges, &is); - } - Tree_Query(treelink, &lk); - if(List_Nbr(lk.l) == 2 || old) { - for(i = 0; i < List_Nbr(lk.l); i++) { - List_Read(lk.l, i, &a); - if(abs(a.a) != abs(ifac)) { - if(!Tree_Search(treefaces, &a.a)) { - Tree_Add(treefaces, &a.a); - if(!old || List_Search(old, &a.a, fcmp_absint) - || List_Nbr(lk.l) == 2) { - rev = abs(a.a); - List_Add(Liste, &rev); - recur_trouvevol(rev, is, Liste, old, treeedges, treefaces); - } - } - } + List_T *temp = Tree2List(THEM->Curves); + + for(int i = 0; i < List_Nbr(temp); i++) { + List_Read(temp, i, &c); + if(c->Num > 0) { + na.a = c->Num; + int ip[2]; + ip[0] = c->beg->Num; + ip[1] = c->end->Num; + for(int k = 0; k < 2; k++){ + li.n = ip[k]; + if((pli = (lnk *) Tree_PQuery(links, &li))) { + List_Add(pli->l, &na); + } + else { + li.l = List_Create(20, 1, sizeof(nxa)); + List_Add(li.l, &na); + Tree_Add(links, &li); + } } } } + List_Delete(temp); } - -void BegEndCurve(Curve * c, int *ip1, int *ip2) +void orientAndSortEdges(List_T *edges, Tree_T *links) { - *ip1 = c->beg->Num; - *ip2 = c->end->Num; + int num; + lnk lk; + nxa na; + + List_T *temp = List_Create(List_Nbr(edges), 1, sizeof(int)); + List_Copy(edges, temp); + List_Reset(edges); + + List_Read(temp, 0, &num); + List_Add(edges, &num); + Curve *c0 = FindCurve(abs(num), THEM); + + int sign = 1; + while(List_Nbr(edges) < List_Nbr(temp)){ + if(sign > 0) + lk.n = c0->end->Num; + else + lk.n = c0->beg->Num; + Tree_Query(links, &lk); + for(int j = 0; j < List_Nbr(lk.l); j++){ + List_Read(lk.l, j, &na); + if(c0->Num != na.a && List_Search(temp, &na.a, fcmp_absint)){ + Curve *c1 = FindCurve(abs(na.a), THEM); + if(lk.n == c1->beg->Num){ + sign = 1; + num = na.a; + } + else{ + sign = -1; + num = -na.a; + } + List_Add(edges, &num); + c0 = c1; + break; + } + } + } + + List_Delete(temp); } -void CreeLiens(void) +int allEdgesLinked(int ed, List_T * edges) { - int i, is, ip1, ip2; - lnk li, *pli; - nxa na1, na2; - Curve *ic; + Tree_T *links = Tree_Create(sizeof(lnk), complink); + Tree_T *points = Tree_Create(sizeof(int), fcmp_int); + + createEdgeLinks(links); + + // initialize point tree with all hanging points + for(int i = 0; i < List_Nbr(edges); i++){ + int num; + List_Read(edges, i, &num); + Curve *c = FindCurve(abs(num), THEM); + int ip[2]; + ip[0] = c->beg->Num; + ip[1] = c->end->Num; + for(int k = 0; k < 2; k++){ + if(!Tree_Search(points, &ip[k])) + Tree_Add(points, &ip[k]); + else + Tree_Suppress(points, &ip[k]); + } + } - treelink = Tree_Create(sizeof(lnk), complink); + if(List_ISearchSeq(edges, &ed, fcmp_absint) < 0){ + List_Add(edges, &ed); + recurFindLinkedEdges(ed, edges, points, links); + } - List_T *temp = Tree2List(THEM->Curves); - for(i = 0; i < List_Nbr(temp); i++) { - List_Read(temp, i, &ic); - if(ic->Num > 0) { - is = ic->Num; - BegEndCurve(ic, &ip1, &ip2); - - na1.a = -is; - na2.a = is; - na2.arbre = na1.arbre = li.visited = 0; - na1.n = li.n = ip1; - na2.n = ip2; - if((pli = (lnk *) Tree_PQuery(treelink, &li))) { - List_Add(pli->l, &na2); - } - else { - li.l = List_Create(20, 1, sizeof(nxa)); - List_Add(li.l, &na2); - Tree_Add(treelink, &li); - } - li.n = ip2; - if((pli = (lnk *) Tree_PQuery(treelink, &li))) { - List_Add(pli->l, &na1); - } - else { - li.l = List_Create(20, 1, sizeof(nxa)); - List_Add(li.l, &na1); - Tree_Add(treelink, &li); + int found = 0; + + if(!Tree_Nbr(points)) + found = 1; + + if(found) + orientAndSortEdges(edges, links); + + Tree_Delete(links); + Tree_Delete(points); + + return found; +} + +// Find all linked faces + +void recurFindLinkedFaces(int fac, List_T * faces, Tree_T * edges, Tree_T * links) +{ + lnk lk; + nxa na; + Curve *c; + Surface *s = FindSurface(abs(fac), THEM); + + for(int l = 0; l < List_Nbr(s->Generatrices); l++) { + List_Read(s->Generatrices, l, &c); + lk.n = abs(c->Num); + if(!Tree_Search(edges, &lk.n)) + Tree_Add(edges, &lk.n); + else + Tree_Suppress(edges, &lk.n); + Tree_Query(links, &lk); + if(List_Nbr(lk.l) == 2) { + for(int i = 0; i < 2; i++) { + List_Read(lk.l, i, &na); + if(na.a != fac) { + if(List_ISearchSeq(faces, &na.a, fcmp_absint) < 0){ + List_Add(faces, &na.a); + recurFindLinkedFaces(na.a, faces, edges, links); + } + } } } } } - -void CreeLiens2(void) +void createFaceLinks(Tree_T * links) { - int i, k; lnk li, *pli; nxa na; Surface *s; Curve *c; - treelink = Tree_Create(sizeof(lnk), complink); List_T *temp = Tree2List(THEM->Surfaces); - for(i = 0; i < List_Nbr(temp); i++) { + for(int i = 0; i < List_Nbr(temp); i++) { List_Read(temp, i, &s); - if(s->Num > 0) + if(s->Num > 0){ na.a = s->Num; - for(k = 0; k < List_Nbr(s->Generatrices); k++) { - List_Read(s->Generatrices, k, &c); - li.n = abs(c->Num); - if((pli = (lnk *) Tree_PQuery(treelink, &li))) { - List_Add(pli->l, &na); - } - else { - li.l = List_Create(20, 1, sizeof(nxa)); - List_Add(li.l, &na); - Tree_Add(treelink, &li); + for(int k = 0; k < List_Nbr(s->Generatrices); k++) { + List_Read(s->Generatrices, k, &c); + li.n = abs(c->Num); + if((pli = (lnk *) Tree_PQuery(links, &li))) { + List_Add(pli->l, &na); + } + else { + li.l = List_Create(20, 1, sizeof(nxa)); + List_Add(li.l, &na); + Tree_Add(links, &li); + } } } } List_Delete(temp); } - -int alledgeslinked(int ed, List_T * Liste, List_T * old) +int allFacesLinked(int fac, List_T * faces) { - int ip1, ip2, i, rev; - lnk lk; - nxa a; - - VisitedNodes = List_Create(20, 20, sizeof(int)); - - CreeLiens(); - - Curve *c, C; - c = &C; - c->Num = ed; - Tree_Query(THEM->Curves, &c); - - BegEndCurve(c, &ip1, &ip2); - - CONTOUR_TROUVE = 0; - - POINT_FINAL = ip2; - recur_trouvecont(ip1, ed, Liste, 1, old); - - if(old) { - List_Sort(old, fcmp_absint); - } - - lk.n = ip2; - Tree_Query(treelink, &lk); - for(i = 0; i < List_Nbr(lk.l); i++) { - List_Read(lk.l, i, &a); - if(abs(a.a) == abs(ed)) { - rev = -a.a; - List_Add(Liste, &rev); + Tree_T *links = Tree_Create(sizeof(lnk), complink); + Tree_T *edges = Tree_Create(sizeof(int), fcmp_int); + + createFaceLinks(links); + + // initialize edge tree with all boundary edges + for(int i = 0; i < List_Nbr(faces); i++){ + int num; + List_Read(faces, i, &num); + Surface *s = FindSurface(abs(num), THEM); + + for(int k = 0; k < List_Nbr(s->Generatrices); k++) { + Curve *c; + List_Read(s->Generatrices, k, &c); + int ic = abs(c->Num); + if(!Tree_Search(edges, &ic)) { + Tree_Add(edges, &ic); + } + else { + Tree_Suppress(edges, &ic); + } } } - - if(!CONTOUR_TROUVE) { - POINT_FINAL = ip1; - recur_trouvecont(ip2, ed, Liste, 0, old); + if(List_ISearchSeq(faces, &fac, fcmp_absint) < 0){ + List_Add(faces, &fac); + recurFindLinkedFaces(fac, faces, edges, links); } - List_Delete(VisitedNodes); - - return (CONTOUR_TROUVE); -} + int found = 0; + if(!Tree_Nbr(edges)) + found = 1; -int allfaceslinked(int iz, List_T * Liste, List_T * old) -{ - CreeLiens2(); - treeedges = Tree_Create(sizeof(int), fcmp_absint); - treefaces = Tree_Create(sizeof(int), fcmp_absint); - - Tree_Add(treefaces, &iz); - List_Add(Liste, &iz); - recur_trouvevol(iz, 0, Liste, old, treeedges, treefaces); - - if(!Tree_Nbr(treeedges)) { - CONTOUR_TROUVE = 1; - } - else { - CONTOUR_TROUVE = 0; - } - - Tree_Delete(treeedges); - Tree_Delete(treefaces); + Tree_Delete(links); + Tree_Delete(edges); - return (CONTOUR_TROUVE); + return found; } diff --git a/Geo/ExtractContour.h b/Geo/ExtractContour.h index c226ee74aa679eac29c35558231fd7fe416b199f..2eb3c80e6243073bb8bc727392e2ab766d457ad6 100644 --- a/Geo/ExtractContour.h +++ b/Geo/ExtractContour.h @@ -22,7 +22,7 @@ #include "List.h" -int alledgeslinked(int ed, List_T * Liste, List_T * old); -int allfaceslinked(int iz, List_T * Liste, List_T * old); +int allEdgesLinked(int ed, List_T * Liste); +int allFacesLinked(int iz, List_T * Liste); #endif diff --git a/doc/VERSIONS b/doc/VERSIONS index bc7780b739949000b5b1d5540b0f9263145e842b..4cb37deb91ec17cafc7a50576590443cd50b3423 100644 --- a/doc/VERSIONS +++ b/doc/VERSIONS @@ -1,4 +1,4 @@ -$Id: VERSIONS,v 1.207 2004-05-18 04:54:51 geuzaine Exp $ +$Id: VERSIONS,v 1.208 2004-05-19 03:56:08 geuzaine Exp $ New since 1.52: various background mesh fixes and enhancements; new Plugin(Evaluate) to evaluate arbitrary expressions on post-processing @@ -6,7 +6,8 @@ views; generalized Plugin(Extract) to handle any combination of components; generalized "Coherence" to handle transfinite surface/volume attributes; plugin options can now be set in the option file (like all other options); added "undo" capability during geometry -creation; many small cleanups; +creation; rewrote the contour guessing routines so that entities can +be selected in an arbitrary order; many small cleanups; New in 1.52: new raster ("bitmap") PostScript/EPS/PDF output formats; new Plugin(Extract) to extract a given component from a