From a9b20fb36c40b55ce6972413b26833086b500d4a Mon Sep 17 00:00:00 2001 From: Christophe Geuzaine <cgeuzaine@ulg.ac.be> Date: Thu, 15 Feb 2007 08:26:46 +0000 Subject: [PATCH] rewrote the interactive edge/face link finding routines in terms of GModel (hence we can now create volumes from OCC faces in the GUI) --- Fltk/Callbacks.cpp | 4 +- Fltk/Makefile | 4 +- Geo/Geo.cpp | 8 +- Geo/Makefile | 18 +- Geo/{GeoExtractContour.cpp => findLinks.cpp} | 256 +++++++------------ Geo/{GeoExtractContour.h => findLinks.h} | 8 +- doc/TODO | 13 +- doc/VERSIONS | 4 +- 8 files changed, 119 insertions(+), 196 deletions(-) rename Geo/{GeoExtractContour.cpp => findLinks.cpp} (50%) rename Geo/{GeoExtractContour.h => findLinks.h} (85%) diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp index 257ac30f70..97cdf592c0 100644 --- a/Fltk/Callbacks.cpp +++ b/Fltk/Callbacks.cpp @@ -1,4 +1,4 @@ -// $Id: Callbacks.cpp,v 1.513 2007-02-05 08:59:31 geuzaine Exp $ +// $Id: Callbacks.cpp,v 1.514 2007-02-15 08:26:45 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -27,7 +27,7 @@ #include "GmshUI.h" #include "Geo.h" #include "GeoStringInterface.h" -#include "GeoExtractContour.h" +#include "findLinks.h" #include "Generator.h" #include "SecondOrder.h" #include "Draw.h" diff --git a/Fltk/Makefile b/Fltk/Makefile index 74e6fdd060..c9f6b0604a 100644 --- a/Fltk/Makefile +++ b/Fltk/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.121 2007-02-01 15:09:43 geuzaine Exp $ +# $Id: Makefile,v 1.122 2007-02-15 08:26:45 geuzaine Exp $ # # Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle # @@ -146,7 +146,7 @@ Callbacks.o: Callbacks.cpp ../Common/Gmsh.h ../Common/Message.h \ ../Geo/SPoint3.h ../Geo/SVector3.h ../Geo/SPoint3.h \ ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Geo/SPoint2.h \ ../Geo/ExtrudeParams.h ../Geo/GeoStringInterface.h ../Geo/Geo.h \ - ../Geo/GeoExtractContour.h ../Mesh/Generator.h ../Mesh/SecondOrder.h \ + ../Geo/findLinks.h ../Mesh/Generator.h ../Mesh/SecondOrder.h \ ../Graphics/Draw.h ../Common/Views.h ../Common/ColorTable.h \ ../Common/VertexArray.h ../Common/SmoothNormals.h ../Numeric/Numeric.h \ ../Common/AdaptiveViews.h ../Common/GmshMatrix.h \ diff --git a/Geo/Geo.cpp b/Geo/Geo.cpp index 0f20e08852..519d089cb6 100644 --- a/Geo/Geo.cpp +++ b/Geo/Geo.cpp @@ -1,4 +1,4 @@ -// $Id: Geo.cpp,v 1.80 2007-02-12 08:36:10 geuzaine Exp $ +// $Id: Geo.cpp,v 1.81 2007-02-15 08:26:45 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -955,12 +955,10 @@ void CopySurface(Surface * s, Surface * ss) for(i = 0; i < 3; i++) for(j = 0; j < 3; j++) ss->invplan[i][j] = s->invplan[i][j]; - ss->Generatrices = - List_Create(List_Nbr(s->Generatrices), 1, sizeof(Curve *)); + ss->Generatrices = List_Create(List_Nbr(s->Generatrices), 1, sizeof(Curve *)); List_Copy(s->Generatrices, ss->Generatrices); if(s->Control_Points) { - ss->Control_Points = - List_Create(List_Nbr(s->Control_Points), 1, sizeof(Vertex *)); + ss->Control_Points = List_Create(List_Nbr(s->Control_Points), 1, sizeof(Vertex *)); List_Copy(s->Control_Points, ss->Control_Points); } End_Surface(ss); diff --git a/Geo/Makefile b/Geo/Makefile index a84a40823f..eda6a6bcb3 100644 --- a/Geo/Makefile +++ b/Geo/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.134 2007-02-12 08:36:10 geuzaine Exp $ +# $Id: Makefile,v 1.135 2007-02-15 08:26:45 geuzaine Exp $ # # Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle # @@ -41,7 +41,7 @@ SRC = GEntity.cpp\ ExtrudeParams.cpp \ Geo.cpp \ GeoStringInterface.cpp GeoInterpolation.cpp\ - GeoExtractContour.cpp\ + findLinks.cpp\ MVertex.cpp \ MElement.cpp \ SVector3.cpp\ @@ -251,12 +251,14 @@ GeoInterpolation.o: GeoInterpolation.cpp ../Common/Gmsh.h \ ../DataStr/Tree.h Geo.h ../Common/GmshDefines.h gmshSurface.h Pair.h \ Range.h SPoint2.h SPoint3.h SVector3.h SBoundingBox3d.h ExtrudeParams.h \ GeoInterpolation.h GeoStringInterface.h ../Numeric/Numeric.h -GeoExtractContour.o: GeoExtractContour.cpp ../Common/Gmsh.h \ - ../Common/Message.h ../DataStr/Malloc.h ../DataStr/List.h \ - ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h \ - ../DataStr/Tree.h Geo.h ../Common/GmshDefines.h gmshSurface.h Pair.h \ - Range.h SPoint2.h SPoint3.h SVector3.h SBoundingBox3d.h ExtrudeParams.h \ - ../Numeric/Numeric.h +findLinks.o: findLinks.cpp ../Common/Gmsh.h ../Common/Message.h \ + ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \ + ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \ + GModel.h GVertex.h GEntity.h Range.h SPoint3.h SBoundingBox3d.h \ + ../Common/GmshDefines.h MVertex.h GPoint.h SPoint2.h GEdge.h SVector3.h \ + MElement.h MEdge.h ../Common/Hash.h MFace.h ../Numeric/Numeric.h \ + ../Common/Context.h ExtrudeParams.h GFace.h GEdgeLoop.h Pair.h \ + GRegion.h ../Common/SmoothNormals.h MVertex.o: MVertex.cpp MVertex.h SPoint3.h MElement.o: MElement.cpp MElement.h ../Common/GmshDefines.h MVertex.h \ SPoint3.h MEdge.h SVector3.h ../Common/Hash.h MFace.h \ diff --git a/Geo/GeoExtractContour.cpp b/Geo/findLinks.cpp similarity index 50% rename from Geo/GeoExtractContour.cpp rename to Geo/findLinks.cpp index 379699751b..3698a48412 100644 --- a/Geo/GeoExtractContour.cpp +++ b/Geo/findLinks.cpp @@ -1,4 +1,4 @@ -// $Id: GeoExtractContour.cpp,v 1.3 2007-02-12 08:36:10 geuzaine Exp $ +// $Id: findLinks.cpp,v 1.1 2007-02-15 08:26:46 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -20,14 +20,9 @@ // Please report all bugs and problems to <gmsh@geuz.org>. #include "Gmsh.h" -#include "Geo.h" -#include "Numeric.h" +#include "GModel.h" -// 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... - -extern Mesh *THEM; +extern GModel *GMODEL; typedef struct{ int n, a; @@ -38,31 +33,32 @@ typedef struct{ List_T *l; }lnk; -int complink(const void *a, const void *b) +static int complink(const void *a, const void *b) { - lnk *q, *w; - q = (lnk *) a; - w = (lnk *) b; - return (q->n - w->n); + lnk *q = (lnk*)a; + lnk *w = (lnk*)b; + return q->n - w->n; } -// Find all linked edges +// Find all linked edges (note that 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 undos in the GUI) -void recurFindLinkedEdges(int ed, List_T * edges, Tree_T * points, Tree_T * links) +static void recurFindLinkedEdges(int ed, List_T *edges, Tree_T *points, + Tree_T *links) { - lnk lk; - nxa na; - int ip[2]; - Curve *c = FindCurve(ed); - if(!c){ + GEdge *ge = GMODEL->edgeByTag(ed); + if(!ge){ Msg(GERROR, "Unknown curve %d", ed); return; } - - ip[0] = c->beg->Num; - ip[1] = c->end->Num; + + int ip[2]; + ip[0] = ge->getBeginVertex()->tag(); + ip[1] = ge->getEndVertex()->tag(); for(int l = 0; l < 2; l++) { + lnk lk; lk.n = ip[l]; if(!Tree_Search(points, &lk.n)) Tree_Add(points, &lk.n); @@ -71,6 +67,7 @@ void recurFindLinkedEdges(int ed, List_T * edges, Tree_T * points, Tree_T * link Tree_Query(links, &lk); if(List_Nbr(lk.l) == 2) { for(int i = 0; i < 2; i++) { + nxa na; List_Read(lk.l, i, &na); if(na.a != ed) { if(List_ISearchSeq(edges, &na.a, fcmp_absint) < 0){ @@ -83,29 +80,24 @@ void recurFindLinkedEdges(int ed, List_T * edges, Tree_T * points, Tree_T * link } } -int createEdgeLinks(Tree_T *links) +static int createEdgeLinks(Tree_T *links) { - lnk li, *pli; - nxa na; - Curve *c; - - List_T *temp = Tree2List(THEM->Curves); - - for(int i = 0; i < List_Nbr(temp); i++) { - List_Read(temp, i, &c); - if(!c->beg || !c->end){ - List_Delete(temp); + for(GModel::eiter it = GMODEL->firstEdge(); it != GMODEL->lastEdge(); it++) { + GEdge *ge = *it;; + if(!ge->getBeginVertex() || !ge->getEndVertex()){ Msg(GERROR, "Cannot link curves with no begin or end points"); return 0; } - if(c->Num > 0) { - na.a = c->Num; + if(ge->tag() > 0) { + nxa na; + na.a = ge->tag(); int ip[2]; - ip[0] = c->beg->Num; - ip[1] = c->end->Num; + ip[0] = ge->getBeginVertex()->tag(); + ip[1] = ge->getEndVertex()->tag(); for(int k = 0; k < 2; k++){ + lnk li, *pli; li.n = ip[k]; - if((pli = (lnk *) Tree_PQuery(links, &li))) { + if((pli = (lnk*)Tree_PQuery(links, &li))) { List_Add(pli->l, &na); } else { @@ -116,47 +108,43 @@ int createEdgeLinks(Tree_T *links) } } } - List_Delete(temp); return 1; } -void orientAndSortEdges(List_T *edges, Tree_T *links) +static void orientAndSortEdges(List_T *edges, Tree_T *links) { - // this orients all the edges in a line loop in a consistent manner - // (left- or right-oriented, depending on the orientation of the - // first edge) *and* sorts them so that they form a path - int num; - lnk lk; - nxa na; - List_T *temp = List_Create(List_Nbr(edges), 1, sizeof(int)); List_Copy(edges, temp); List_Reset(edges); + int num; List_Read(temp, 0, &num); List_Add(edges, &num); - Curve *c0 = FindCurve(abs(num)); - if(!c0){ + + GEdge *ge0 = GMODEL->edgeByTag(abs(num)); + if(!ge0){ Msg(GERROR, "Unknown curve %d", abs(num)); return; } int sign = 1; while(List_Nbr(edges) < List_Nbr(temp)){ + lnk lk; if(sign > 0) - lk.n = c0->end->Num; + lk.n = ge0->getEndVertex()->tag(); else - lk.n = c0->beg->Num; + lk.n = ge0->getBeginVertex()->tag(); Tree_Query(links, &lk); for(int j = 0; j < List_Nbr(lk.l); j++){ + nxa na; List_Read(lk.l, j, &na); - if(c0->Num != na.a && List_Search(temp, &na.a, fcmp_absint)){ - Curve *c1 = FindCurve(abs(na.a)); - if(!c1){ + if(ge0->tag() != na.a && List_Search(temp, &na.a, fcmp_absint)){ + GEdge *ge1 = GMODEL->edgeByTag(abs(na.a)); + if(!ge1){ Msg(GERROR, "Unknown curve %d", abs(na.a)); return; } - if(lk.n == c1->beg->Num){ + if(lk.n == ge1->getBeginVertex()->tag()){ sign = 1; num = na.a; } @@ -165,7 +153,7 @@ void orientAndSortEdges(List_T *edges, Tree_T *links) num = -na.a; } List_Add(edges, &num); - c0 = c1; + ge0 = ge1; break; } } @@ -174,7 +162,7 @@ void orientAndSortEdges(List_T *edges, Tree_T *links) List_Delete(temp); } -int allEdgesLinked(int ed, List_T * edges) +int allEdgesLinked(int ed, List_T *edges) { Tree_T *links = Tree_Create(sizeof(lnk), complink); Tree_T *points = Tree_Create(sizeof(int), fcmp_int); @@ -186,14 +174,14 @@ int allEdgesLinked(int ed, List_T * edges) for(int i = 0; i < List_Nbr(edges); i++){ int num; List_Read(edges, i, &num); - Curve *c = FindCurve(abs(num)); - if(!c){ + GEdge *ge = GMODEL->edgeByTag(abs(num)); + if(!ge){ Msg(GERROR, "Unknown curve %d", abs(num)); return 0; } int ip[2]; - ip[0] = c->beg->Num; - ip[1] = c->end->Num; + ip[0] = ge->getBeginVertex()->tag(); + ip[1] = ge->getEndVertex()->tag(); for(int k = 0; k < 2; k++){ if(!Tree_Search(points, &ip[k])) Tree_Add(points, &ip[k]); @@ -211,8 +199,11 @@ int allEdgesLinked(int ed, List_T * edges) if(!Tree_Nbr(points)){ found = 1; - // we can only orient things now since we allow to select - // disconnected parts of the loop interactively + // at this point we can orient all the edges in a line loop in a + // consistent manner (left- or right-oriented, depending on the + // orientation of the first edge), and we can sort them so that + // they form a path (we can only do this now since we allow to + // select disconnected parts of the loop in the GUI) orientAndSortEdges(edges, links); } @@ -224,20 +215,20 @@ int allEdgesLinked(int ed, List_T * edges) // Find all linked faces -void recurFindLinkedFaces(int fac, List_T * faces, Tree_T * edges, Tree_T * links) +static void recurFindLinkedFaces(int fac, List_T *faces, Tree_T *edges, + Tree_T *links) { - lnk lk; - nxa na; - Curve *c; - Surface *s = FindSurface(abs(fac)); - if(!s){ + GFace *gf = GMODEL->faceByTag(abs(fac)); + if(!gf){ Msg(GERROR, "Unknown surface %d", abs(fac)); return; } - for(int l = 0; l < List_Nbr(s->Generatrices); l++) { - List_Read(s->Generatrices, l, &c); - lk.n = abs(c->Num); + std::list<GEdge*> l = gf->edges(); + for(std::list<GEdge*>::iterator it = l.begin(); it != l.end(); it++) { + GEdge *ge = *it; + lnk lk; + lk.n = abs(ge->tag()); if(!Tree_Search(edges, &lk.n)) Tree_Add(edges, &lk.n); else @@ -245,6 +236,7 @@ void recurFindLinkedFaces(int fac, List_T * faces, Tree_T * edges, Tree_T * link Tree_Query(links, &lk); if(List_Nbr(lk.l) == 2) { for(int i = 0; i < 2; i++) { + nxa na; List_Read(lk.l, i, &na); if(na.a != fac) { if(List_ISearchSeq(faces, &na.a, fcmp_absint) < 0){ @@ -257,23 +249,19 @@ void recurFindLinkedFaces(int fac, List_T * faces, Tree_T * edges, Tree_T * link } } -void createFaceLinks(Tree_T * links) +static void createFaceLinks(Tree_T *links) { - lnk li, *pli; - nxa na; - Surface *s; - Curve *c; - - List_T *temp = Tree2List(THEM->Surfaces); - - for(int i = 0; i < List_Nbr(temp); i++) { - List_Read(temp, i, &s); - if(s->Num > 0){ - na.a = s->Num; - 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))) { + for(GModel::fiter it = GMODEL->firstFace(); it != GMODEL->lastFace(); it++) { + GFace *gf = *it; + if(gf->tag() > 0){ + nxa na; + na.a = gf->tag(); + std::list<GEdge*> l = gf->edges(); + for(std::list<GEdge*>::iterator ite = l.begin(); ite != l.end(); ite++) { + GEdge *ge = *ite; + lnk li, *pli; + li.n = abs(ge->tag()); + if((pli = (lnk*)Tree_PQuery(links, &li))) { List_Add(pli->l, &na); } else { @@ -284,72 +272,9 @@ void createFaceLinks(Tree_T * links) } } } - List_Delete(temp); -} - -void recurOrientFace(int face, List_T *faces, List_T *available, Tree_T *links) -{ - Surface *s = FindSurface(abs(face)); - if(!s){ - Msg(GERROR, "Unknown surface %d", abs(face)); - return; - } - int ori = sign(face); - - for(int i = 0; i < List_Nbr(s->Generatrices); i++){ - Curve *c; - List_Read(s->Generatrices, i, &c); - lnk lk; - lk.n = abs(c->Num); - Tree_Query(links, &lk); - for(int j = 0; j < List_Nbr(lk.l); j++){ - nxa na; - List_Read(lk.l, j, &na); - int num = abs(na.a); - if(num != abs(s->Num) && List_Search(available, &num, fcmp_absint) && - List_ISearchSeq(faces, &num, fcmp_absint) < 0){ - Surface *s2 = FindSurface(num); - if(!s2){ - Msg(GERROR, "Unknown surface %d", num); - return; - } - for(int k = 0; k < List_Nbr(s2->Generatrices); k++){ - Curve *c2; - List_Read(s2->Generatrices, k, &c2); - if(abs(c->Num) == abs(c2->Num)){ - if(c->Num * c2->Num > 0) - num *= -ori; - else - num *= ori; - List_Add(faces, &num); - recurOrientFace(num, faces, available, links); - break; - } - } - } - } - } -} - -void orientFaces(List_T *faces, Tree_T *links) -{ - // this orients all the faces in a surface loop in a consistent - // manner (all normals pointing inside or outside--depending on the - // orientation of the first face) - - List_T *temp = List_Create(List_Nbr(faces), 1, sizeof(int)); - List_Copy(faces, temp); - List_Reset(faces); - - int num; - List_Read(temp, 0, &num); - List_Add(faces, &num); - recurOrientFace(num, faces, temp, links); - - List_Delete(temp); } -int allFacesLinked(int fac, List_T * faces) +int allFacesLinked(int fac, List_T *faces) { Tree_T *links = Tree_Create(sizeof(lnk), complink); Tree_T *edges = Tree_Create(sizeof(int), fcmp_int); @@ -360,15 +285,15 @@ int allFacesLinked(int fac, List_T * faces) for(int i = 0; i < List_Nbr(faces); i++){ int num; List_Read(faces, i, &num); - Surface *s = FindSurface(abs(num)); - if(!s){ + GFace *gf = GMODEL->faceByTag(abs(num)); + if(!gf){ Msg(GERROR, "Unknown surface %d", abs(num)); return 0; } - for(int k = 0; k < List_Nbr(s->Generatrices); k++) { - Curve *c; - List_Read(s->Generatrices, k, &c); - int ic = abs(c->Num); + std::list<GEdge*> l = gf->edges(); + for(std::list<GEdge*>::iterator it = l.begin(); it != l.end(); it++) { + GEdge *ge = *it; + int ic = abs(ge->tag()); if(!Tree_Search(edges, &ic)) Tree_Add(edges, &ic); else @@ -378,10 +303,10 @@ int allFacesLinked(int fac, List_T * faces) if(List_ISearchSeq(faces, &fac, fcmp_absint) < 0){ List_Add(faces, &fac); - // Warning: this is correct ONLY if the surfaces are defined - // correctly, i.e., if the surface hole boundaries are oriented - // consistently with the surface exterior boundaries. There is - // currently *nothing* in the code that checks this. + // Warning: this is correct only if the surfaces are defined with + // correct orientations, i.e., if the hole boundaries are oriented + // consistently with the exterior boundaries. There is currently + // nothing in the code that checks this! recurFindLinkedFaces(fac, faces, edges, links); } @@ -389,9 +314,8 @@ int allFacesLinked(int fac, List_T * faces) if(!Tree_Nbr(edges)){ found = 1; - // we can only orient things now since we allow to select - // disconnected parts of the loop interactively - orientFaces(faces, links); + // we could orient the faces here, but it's not really + // necessary... } Tree_Delete(links); diff --git a/Geo/GeoExtractContour.h b/Geo/findLinks.h similarity index 85% rename from Geo/GeoExtractContour.h rename to Geo/findLinks.h index 74cf6a29b5..7c9be0a0df 100644 --- a/Geo/GeoExtractContour.h +++ b/Geo/findLinks.h @@ -1,5 +1,5 @@ -#ifndef _GEO_EXTRACT_CONTOUR_H_ -#define _GEO_EXTRACT_CONTOUR_H_ +#ifndef _FIND_LINKS_H_ +#define _FIND_LINKS_H_ // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -22,7 +22,7 @@ #include "List.h" -int allEdgesLinked(int ed, List_T * Liste); -int allFacesLinked(int iz, List_T * Liste); +int allEdgesLinked(int ed, List_T *edges); +int allFacesLinked(int fac, List_T *faces); #endif diff --git a/doc/TODO b/doc/TODO index daabc5a505..a1b17a24cf 100644 --- a/doc/TODO +++ b/doc/TODO @@ -1,9 +1,4 @@ -$Id: TODO,v 1.48 2007-02-12 08:36:14 geuzaine Exp $ - -******************************************************************** - -interface GModel in surface/volume creation in the parser (so we can -define a volume from iges surfaces, etc.) +$Id: TODO,v 1.49 2007-02-15 08:26:46 geuzaine Exp $ ******************************************************************** @@ -20,7 +15,7 @@ reinterface Triangle for plane surfaces ******************************************************************** -interface GModel in surface/volume creation in the parser +interface GModel in surface creation in the parser ******************************************************************** @@ -59,6 +54,10 @@ recode BDS::extract edges ******************************************************************** +recode BDS::remesh (for STL remeshing) + +******************************************************************** + physical groups->add->line/surface: pressing '-' after/while selecting a surface should add it with reverse orientation? diff --git a/doc/VERSIONS b/doc/VERSIONS index 8a2a3075b8..654bb32c5f 100644 --- a/doc/VERSIONS +++ b/doc/VERSIONS @@ -1,8 +1,8 @@ -$Id: VERSIONS,v 1.377 2007-02-14 12:31:15 geuzaine Exp $ +$Id: VERSIONS,v 1.378 2007-02-15 08:26:46 geuzaine Exp $ since 2.0: volumes can now be defined from external CAD surfaces; use Delaunay/Tetgen algorithm by default when available; fixed various -small bugs. +bugs. 2.0 (February 5, 2007): new geometry and mesh databases, with support for STEP and IGES import via OpenCascade; complete rewrite of geometry -- GitLab