diff --git a/Geo/GModelIO_Mesh.cpp b/Geo/GModelIO_Mesh.cpp index 0c599353e20186a97932da349bf295c676311ec4..f80268ca45fb35ff48eeea97070d7a0bf0462955 100644 --- a/Geo/GModelIO_Mesh.cpp +++ b/Geo/GModelIO_Mesh.cpp @@ -1,4 +1,4 @@ -// $Id: GModelIO_Mesh.cpp,v 1.38 2008-02-23 15:30:07 geuzaine Exp $ +// $Id: GModelIO_Mesh.cpp,v 1.39 2008-03-01 01:32:02 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -297,7 +297,6 @@ int GModel::readMSH(const std::string &name) if(!fgets(str, sizeof(str), fp)) return 0; int format, size; if(sscanf(str, "%lf %d %d", &version, &format, &size) != 3) return 0; - if(format){ binary = true; Msg(INFO, "Mesh is in binary format"); @@ -340,10 +339,8 @@ int GModel::readMSH(const std::string &name) int numVertices; if(sscanf(str, "%d", &numVertices) != 1) return 0; Msg(INFO, "%d vertices", numVertices); - vertexVector.clear(); vertexMap.clear(); - int progress = (numVertices > 100000) ? numVertices / 25 : 0; int minVertex = numVertices + 1, maxVertex = -1; for(int i = 0; i < numVertices; i++) { @@ -368,7 +365,6 @@ int GModel::readMSH(const std::string &name) Msg(PROGRESS, "Read %d vertices", i + 1); } if(progress) Msg(PROGRESS, ""); - // If the vertex numbering is dense, tranfer the map into a // vector to speed up element creation if((int)vertexMap.size() == numVertices && @@ -393,7 +389,6 @@ int GModel::readMSH(const std::string &name) int numElements; sscanf(str, "%d", &numElements); Msg(INFO, "%d elements", numElements); - int progress = (numElements > 100000) ? numElements / 25 : 0; if(!binary){ for(int i = 0; i < numElements; i++) { @@ -470,13 +465,21 @@ int GModel::readMSH(const std::string &name) } else if(!strncmp(&str[1], "NodeData", 8)) { - // there's some post-processing data to read later on, so cache - // the vertex indexing data + + // there's some nodal post-processing data to read later on, so + // cache the vertex indexing data if(vertexVector.size()) _vertexVectorCache = vertexVector; else _vertexMapCache = vertexMap; postpro = true; + + } + else if(!strncmp(&str[1], "ElementData", 11)) { + + // there's some element post-processing data to read later on + postpro = true; + } do { diff --git a/Graphics/Post.cpp b/Graphics/Post.cpp index d16e3b8144f2ffcd719d3b0e58b887110e953daa..0b69dc3cb2a9ebeffde99b75adfa2b262d45d22a 100644 --- a/Graphics/Post.cpp +++ b/Graphics/Post.cpp @@ -1,4 +1,4 @@ -// $Id: Post.cpp,v 1.153 2008-02-24 16:18:19 geuzaine Exp $ +// $Id: Post.cpp,v 1.154 2008-03-01 01:32:02 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -31,7 +31,6 @@ #include "Context.h" #include "gl2ps.h" - #if defined(HAVE_MATH_EVAL) #include "matheval.h" #endif diff --git a/Mesh/BDS.cpp b/Mesh/BDS.cpp index 1d92fdffdbc5d65ac557fe36b81afd93ebad7c9c..a2f6397488e1055fa1f787d40c71838986a2d074 100644 --- a/Mesh/BDS.cpp +++ b/Mesh/BDS.cpp @@ -1,4 +1,4 @@ -// $Id: BDS.cpp,v 1.102 2008-02-21 12:11:12 geuzaine Exp $ +// $Id: BDS.cpp,v 1.103 2008-03-01 01:32:03 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -240,7 +240,7 @@ BDS_Edge *BDS_Mesh::recover_edge(int num1, int num2, std::set<EdgeToRecover> *e2 if(!p1 || !p2) throw; - Msg(DEBUG, " edge %d %d has to be recovered", num1, num2); + Msg(DEBUG, "edge %d %d has to be recovered", num1, num2); int ix = 0; int ixMax = 300; @@ -260,7 +260,7 @@ BDS_Edge *BDS_Mesh::recover_edge(int num1, int num2, std::set<EdgeToRecover> *e2 e2r->find(EdgeToRecover(e->p1->iD, e->p2->iD, 0)); std::set<EdgeToRecover>::iterator itr2 = e2r->find(EdgeToRecover(num1, num2, 0)); - Msg(DEBUG2, " edge %d %d on model edge %d cannot be recovered because" + Msg(DEBUG2, "edge %d %d on model edge %d cannot be recovered because" " it intersects %d %d on model edge %d", num1, num2, itr2->ge->tag(), e->p1->iD, e->p2->iD, itr1->ge->tag()); // now throw a class that contains the diagnostic @@ -274,7 +274,7 @@ BDS_Edge *BDS_Mesh::recover_edge(int num1, int num2, std::set<EdgeToRecover> *e2 } // if(ix > 300){ -// Msg(WARNING," edge %d %d cannot be recovered after %d iterations, trying again", +// Msg(WARNING, "edge %d %d cannot be recovered after %d iterations, trying again", // num1, num2, ix); // ix = 0; // } @@ -285,7 +285,7 @@ BDS_Edge *BDS_Mesh::recover_edge(int num1, int num2, std::set<EdgeToRecover> *e2 if(!eee){ outputScalarField(triangles, "debugp.pos", 1); outputScalarField(triangles, "debugr.pos", 0); - Msg(GERROR," edge %d %d cannot be recovered at all, look at debugp.pos " + Msg(GERROR, "edge %d %d cannot be recovered at all, look at debugp.pos " "and debugr.pos", num1, num2); return 0; } @@ -1434,7 +1434,7 @@ recombine_T::recombine_T(const BDS_Edge *_e) void BDS_Mesh::recombineIntoQuads(const double angle_limit, GFace *gf) { - Msg(INFO,"Recombining triangles for surface %d", gf->tag()); + Msg(INFO, "Recombining triangles for surface %d", gf->tag()); for(int i = 0; i < 5; i++){ std::set<recombine_T> pairs; for(std::list<BDS_Edge*>::const_iterator it = edges.begin(); diff --git a/Mesh/DivideAndConquer.cpp b/Mesh/DivideAndConquer.cpp index 66da06851507ad6daee5bbded0f0badfda9b4236..8956f8749d078183f57ef183c4d1e6188102ef70 100644 --- a/Mesh/DivideAndConquer.cpp +++ b/Mesh/DivideAndConquer.cpp @@ -1,4 +1,4 @@ -// $Id: DivideAndConquer.cpp,v 1.15 2008-02-21 19:27:58 geuzaine Exp $ +// $Id: DivideAndConquer.cpp,v 1.16 2008-03-01 01:32:03 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -19,21 +19,17 @@ // // Please report all bugs and problems to <gmsh@geuz.org>. -/* - A L G O R I T H M E D I V I D E A N D C O N Q U E R - - le noeud de cette methode est de pouvoir fusionner deux - triangulations de Delaunay en une seule (routine merge) on procede - alors recursivement en separant les points en deux groupes puis en - separant les groupes en 2 ... jusqu'a n'obtenir que 1 2 ou 3 points - (la triangulation est alors triviale) - - Dans le mailleur, on utilise cet algorithme pour construire le - maillage initial - - !!! il faut PERTURBER les points d'une faible valeur aleatoire pour - eviter d'avoir 3 points alignes ou 4 points cocycliques !!! -*/ +// Triangulation using a divide and conquer algorithm +// +// The main idea is to be able to merge two Delaunay triangulations +// into a single one (see the 'merge' function). Points are then +// separated into two groups, then each group into two, ... until +// having 1, 2 or 3 points (the triangulation is then trivial). +// +// This is used to contruct the initial mesh. +// +// Warning: point positions must be PERTURBED by a small random +// value to avoid 3 aligned points or 4 cocyclical points! #include "Message.h" #include "Numeric.h" @@ -102,7 +98,7 @@ PointNumero First(PointNumero x) return (pPointArray[x].adjacent)->point_num; } -int Is_left_of(PointNumero x, PointNumero y, PointNumero check) +int IsLeftOf(PointNumero x, PointNumero y, PointNumero check) { double pa[2] = {(double)pPointArray[x].where.h, (double)pPointArray[x].where.v}; double pb[2] = {(double)pPointArray[y].where.h, (double)pPointArray[y].where.v}; @@ -114,9 +110,9 @@ int Is_left_of(PointNumero x, PointNumero y, PointNumero check) return result > 0; } -int Is_right_of(PointNumero x, PointNumero y, PointNumero check) +int IsRightOf(PointNumero x, PointNumero y, PointNumero check) { - return Is_left_of(y, x, check); + return IsLeftOf(y, x, check); } Segment LowerCommonTangent(DT vl, DT vr) @@ -130,12 +126,12 @@ Segment LowerCommonTangent(DT vl, DT vr) z1 = First(x); z2 = Predecessor(x, z1); for(;;) { - if(Is_right_of(x, y, z)) { + if(IsRightOf(x, y, z)) { temp = z; z = Successor(z, y); y = temp; } - else if(Is_right_of(x, y, z2)) { + else if(IsRightOf(x, y, z2)) { temp = z2; z2 = Predecessor(z2, x); x = temp; @@ -159,12 +155,12 @@ Segment UpperCommonTangent(DT vl, DT vr) z1 = First(x); z2 = Predecessor(y, z); for(;;) { - if(Is_left_of(x, y, z2)) { + if(IsLeftOf(x, y, z2)) { temp = z2; z2 = Predecessor(z2, y); y = temp; } - else if(Is_left_of(x, y, z1)) { + else if(IsLeftOf(x, y, z1)) { temp = z1; z1 = Successor(z1, x); x = temp; @@ -215,7 +211,7 @@ int merge(DT vl, DT vr) r1 = Predecessor(r, l); if(r1 == -1) return 0; - if(Is_right_of(l, r, r1)) + if(IsRightOf(l, r, r1)) a = 1; else { out = 0; @@ -231,7 +227,7 @@ int merge(DT vl, DT vr) if(!Delete(r, r1)) return 0; r1 = r2; - if(Is_right_of(l, r, r1)) + if(IsRightOf(l, r, r1)) out = a = 1; } } @@ -240,7 +236,7 @@ int merge(DT vl, DT vr) l1 = Successor(l, r); if(l1 == -1) return 0; - if(Is_left_of(r, l, l1)) + if(IsLeftOf(r, l, l1)) b = 1; else { out = 0; @@ -256,7 +252,7 @@ int merge(DT vl, DT vr) if(!Delete(l, l1)) return 0; l1 = l2; - if(Is_left_of(r, l, l1)) + if(IsLeftOf(r, l, l1)) out = b = 1; } } @@ -307,7 +303,7 @@ DT recur_trig(PointNumero left, PointNumero right) Insert(left, right); Insert(left, left + 1); Insert(left + 1, right); - if(Is_right_of(left, right, left + 1)) { + if(IsRightOf(left, right, left + 1)) { FixFirst(left, left + 1); FixFirst(left + 1, right); FixFirst(right, left); @@ -340,18 +336,12 @@ int comparePoints(const void *i, const void *j) return (x < 0.) ? -1 : 1; } -// this fonction builds the delaunay triangulation and the voronoi for -// a window. All error handling is done here -int DelaunayAndVoronoi(DocPeek doc) +// this fonction builds the delaunay triangulation for a window +int BuildDelaunay(DocRecord *doc) { pPointArray = doc->points; - - if(doc->numPoints < 2) - return 1; - qsort(doc->points, doc->numPoints, sizeof(PointRecord), comparePoints); recur_trig(0, doc->numPoints - 1); - return 1; } @@ -515,19 +505,8 @@ PointNumero *ConvertDlistToArray(DListPeek *dlist, int *n) return ptr; } -void filldel(Delaunay *deladd, int aa, int bb, int cc, - PointRecord *points) -{ - deladd->t.a = aa; - deladd->t.b = bb; - deladd->t.c = cc; - deladd->v.voisin1 = NULL; - deladd->v.voisin2 = NULL; - deladd->v.voisin3 = NULL; -} - // Convertir les listes d'adjacence en triangles -int Conversion(DocPeek doc) +int ConvertDListToTriangles(DocRecord *doc) { // on suppose que n >= 3. gPointArray est suppose OK. @@ -544,10 +523,7 @@ int Conversion(DocPeek doc) // nombre de triangles que l'on doit obtenir count2 = 2 * (n - 1) - count2; - if(doc->delaunay) - Free(doc->delaunay); - - doc->delaunay = (Delaunay *) Malloc(2 * count2 * sizeof(Delaunay)); + doc->triangles = (Triangle *) Malloc(2 * count2 * sizeof(Triangle)); for(i = 0; i < n; i++) { // on cree une liste de points connectes au point i (t) + nombre @@ -563,11 +539,13 @@ int Conversion(DocPeek doc) for(i = 0; i < n; i++) { for(j = 0; j < striangle[i].t_length; j++) { if((striangle[i].t[j] > i) && (striangle[i].t[j + 1] > i) && - (Is_right_of(i, striangle[i].t[j], striangle[i].t[j + 1]))) { + (IsRightOf(i, striangle[i].t[j], striangle[i].t[j + 1]))) { aa = i; bb = striangle[i].t[j]; cc = striangle[i].t[j + 1]; - filldel(&doc->delaunay[count], aa, bb, cc, gPointArray); + doc->triangles[count].a = aa; + doc->triangles[count].b = bb; + doc->triangles[count].c = cc; count++; } } @@ -581,7 +559,7 @@ int Conversion(DocPeek doc) } // Cette routine efface toutes les listes d'adjacence du pPointArray -void remove_all_dlist(int n, PointRecord *pPointArray) +void RemoveAllDList(int n, PointRecord *pPointArray) { int i; DListPeek p, temp; @@ -598,13 +576,23 @@ void remove_all_dlist(int n, PointRecord *pPointArray) } } -void Make_Mesh_With_Points(DocRecord *ptr, PointRecord *Liste, int Numpoints) +DocRecord::DocRecord(int n) + : numPoints(n), points(NULL), numTriangles(0), triangles(NULL) +{ + if(numPoints) + points = (PointRecord*)Malloc(numPoints * sizeof(PointRecord)); +} + +DocRecord::~DocRecord() +{ + Free(points); + Free(triangles); +} + +void DocRecord::MakeMeshWithPoints() { - ptr->numTriangles = 0; - ptr->points = Liste; - ptr->numPoints = Numpoints; - ptr->delaunay = 0; - DelaunayAndVoronoi(ptr); - Conversion(ptr); - remove_all_dlist(ptr->numPoints, ptr->points); + if(numPoints < 3) return; + BuildDelaunay(this); + ConvertDListToTriangles(this); + RemoveAllDList(numPoints, points); } diff --git a/Mesh/DivideAndConquer.h b/Mesh/DivideAndConquer.h index 44511c488b255204a465d6dd8003c2ba72642a48..28c2ad380049ec4c20c416c6bf4bbccd6013ba84 100644 --- a/Mesh/DivideAndConquer.h +++ b/Mesh/DivideAndConquer.h @@ -20,29 +20,19 @@ // // Please report all bugs and problems to <gmsh@geuz.org>. -typedef struct _POINT PointRecord, *PointPeek; -typedef struct _DOC DocRecord, *DocPeek; typedef struct _CDLIST DListRecord, *DListPeek; -typedef struct _DELAUNAY Delaunay, *delpeek; typedef int PointNumero; -struct _DOC{ - PointRecord *points; // points to triangulate - int numPoints; // number of points - int numTriangles; // number of triangles - Delaunay *delaunay; // 2D results -}; - typedef struct{ double v; double h; }MPoint; -struct _POINT{ +typedef struct{ MPoint where; DListPeek adjacent; void *data; -}; +}PointRecord; struct _CDLIST{ PointNumero point_num; @@ -74,15 +64,15 @@ typedef struct{ PointNumero a, b, c; }Triangle; -typedef struct { - Delaunay *voisin1, *voisin2, *voisin3; -}Voronoi; - -struct _DELAUNAY{ - Triangle t; - Voronoi v; +class DocRecord{ + public: + int numPoints; // number of points + PointRecord *points; // points to triangulate + int numTriangles; // number of triangles + Triangle *triangles; // 2D results + DocRecord(int n); + ~DocRecord(); + void MakeMeshWithPoints(); }; -void Make_Mesh_With_Points(DocRecord *ptr, PointRecord *Liste, int Numpoints); - #endif diff --git a/Mesh/HighOrder.cpp b/Mesh/HighOrder.cpp index 888a297aadf05102a23b17d45ebb97c98defc3d3..562e77dfbc89db2a2eb92ce6f75db821d7e7bace 100644 --- a/Mesh/HighOrder.cpp +++ b/Mesh/HighOrder.cpp @@ -1,4 +1,4 @@ -// $Id: HighOrder.cpp,v 1.23 2008-02-27 12:39:08 geuzaine Exp $ +// $Id: HighOrder.cpp,v 1.24 2008-03-01 01:32:03 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -98,7 +98,7 @@ bool computeEquidistantParameters(GEdge *ge, double u0, double uN, int N, double // N is the total number of points (3 for quadratic, 4 for cubic ...) // u[0] = u0; // u[N-1] = uN; - // dist ( ge(u[i]), ge(u[i+1]) ) = dist ( ge(u[i+1]), ge(u[i+2]) ) , i = 0,...,N-2 + // dist(ge(u[i]), ge(u[i+1])) = dist(ge(u[i+1]), ge(u[i+2])), i = 0,...,N-2 // initialize as equidistant in parameter space u[0] = u0; @@ -891,7 +891,7 @@ void deriv_smoothing_objective_function_HighOrderN(double *uv, double *dF, } } -void optimizeNodeLocations ( GFace *gf, smoothVertexDataHON &vdN , double eps = .2) +void optimizeNodeLocations(GFace *gf, smoothVertexDataHON &vdN, double eps = .2) { if(!vdN.v.size()) return; double uv[20]; @@ -958,8 +958,8 @@ bool optimizeHighOrderMesh(GFace *gf, edgeContainer &edgeVertices) GEntity *ge = ver->onWhat(); if (ge->dim() == 2){ double initu,initv; - ver->getParameter ( 0,initu); - ver->getParameter ( 1,initv); + ver->getParameter(0, initu); + ver->getParameter(1, initv); smoothVertexDataHON vdN; vdN.ts = it->second; @@ -973,7 +973,7 @@ bool optimizeHighOrderMesh(GFace *gf, edgeContainer &edgeVertices) double val; double F = -smooth_obj_HighOrder(initu,initv, &vd); if (F < .2){ - minimize_2 ( smooth_obj_HighOrder, + minimize_2(smooth_obj_HighOrder, deriv_smoothing_objective_function_HighOrder, &vd, 1, initu,initv,val); double Fafter = -smooth_obj_HighOrder(initu,initv, &vd); if (F < Fafter){ @@ -1098,28 +1098,28 @@ bool smoothInternalEdges(GFace *gf, edgeContainer &edgeVertices) MVertex *vert4 = (n4 < n1) ? e4[e4.size() - i - 1] : e4[i]; MVertex *vert2 = (n2 < n3) ? e2[i] : e2[e2.size() - i - 1]; double U1,V1,U2,V2,U3,V3,U4,V4,U,V,nU1,nV1,nU2,nV2,nU3,nV3,nU4,nV4; - parametricCoordinates(vert , gf,U,V); - parametricCoordinates(vert1, gf,U1,V1); - parametricCoordinates(vert2, gf,U2,V2); - parametricCoordinates(vert3, gf,U3,V3); - parametricCoordinates(vert4, gf,U4,V4); - parametricCoordinates(n1, gf,nU1,nV1); - parametricCoordinates(n2, gf,nU2,nV2); - parametricCoordinates(n3, gf,nU3,nV3); - parametricCoordinates(n4, gf,nU4,nV4); + parametricCoordinates(vert , gf, U, V); + parametricCoordinates(vert1, gf, U1, V1); + parametricCoordinates(vert2, gf, U2, V2); + parametricCoordinates(vert3, gf, U3, V3); + parametricCoordinates(vert4, gf, U4, V4); + parametricCoordinates(n1, gf, nU1, nV1); + parametricCoordinates(n2, gf, nU2, nV2); + parametricCoordinates(n3, gf, nU3, nV3); + parametricCoordinates(n4, gf, nU4, nV4); - Unew[k][i] = U + relax * ( (1.-u) * U4 + u * U2 + - (1.-v) * U1 + v * U3 - - ( (1.-u)*(1.-v) * nU1 - + u * (1.-v) * nU2 - + u*v*nU3 - + (1.-u) * v * nU4) - U); - Vnew[k][i] = V + relax * ( (1.-u) * V4 + u * V2 + - (1.-v) * V1 + v * V3 - - ( (1.-u)*(1.-v) * nV1 - + u * (1.-v) * nV2 - + u*v*nV3 - + (1.-u) * v * nV4) - V); + Unew[k][i] = U + relax * ((1.-u) * U4 + u * U2 + + (1.-v) * U1 + v * U3 - + ((1.-u)*(1.-v) * nU1 + + u * (1.-v) * nU2 + + u * v * nU3 + + (1.-u) * v * nU4) - U); + Vnew[k][i] = V + relax * ((1.-u) * V4 + u * V2 + + (1.-v) * V1 + v * V3 - + ((1.-u)*(1.-v) * nV1 + + u * (1.-v) * nV2 + + u * v * nV3 + + (1.-u) * v * nV4) - V); GPoint gp = gf->point(Unew[k][i],Vnew[k][i]); vert->x() = gp.x(); vert->y() = gp.y(); @@ -1127,8 +1127,8 @@ bool smoothInternalEdges(GFace *gf, edgeContainer &edgeVertices) } double minJloc = 1.e22; double maxJloc = -1.e22; - getMinMaxJac (t1, minJloc, maxJloc); - getMinMaxJac (t2, minJloc, maxJloc); + getMinMaxJac(t1, minJloc, maxJloc); + getMinMaxJac(t2, minJloc, maxJloc); if (minJloc > minJ){ kopt = k; diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp index 709cfb91d4e9a46dc7d5be71034336a2d997c32b..16438dfcfec42f4d63924f6822bbbf262e8bec30 100644 --- a/Mesh/meshGFace.cpp +++ b/Mesh/meshGFace.cpp @@ -1,4 +1,4 @@ -// $Id: meshGFace.cpp,v 1.122 2008-02-23 16:19:22 remacle Exp $ +// $Id: meshGFace.cpp,v 1.123 2008-03-01 01:32:03 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -259,7 +259,7 @@ bool recover_medge(BDS_Mesh *m, GEdge *ge, std::set<EdgeToRecover> *e2r, BDS_Edge * e = m->recover_edge(vstart->getNum(), vend->getNum(), e2r, not_recovered); if (e) e->g = g; else { - // Msg(GERROR,"The unrecoverable edge is on model edge %d",ge->tag()); + // Msg(GERROR, "The unrecoverable edge is on model edge %d",ge->tag()); return false; } return true; @@ -281,7 +281,7 @@ bool recover_medge(BDS_Mesh *m, GEdge *ge, std::set<EdgeToRecover> *e2r, e = m->recover_edge(vstart->getNum(), vend->getNum(), e2r, not_recovered); if (e) e->g = g; else { - // Msg(GERROR,"The unrecoverable edge is on model edge %d",ge->tag()); + // Msg(GERROR, "The unrecoverable edge is on model edge %d",ge->tag()); // return false; } } @@ -294,7 +294,7 @@ bool recover_medge(BDS_Mesh *m, GEdge *ge, std::set<EdgeToRecover> *e2r, e = m->recover_edge(vstart->getNum(), vend->getNum(), e2r, not_recovered); if (e) e->g = g; else { - // Msg(GERROR,"Unable to recover an edge %g %g && %g %g (%d/%d)", + // Msg(GERROR, "Unable to recover an edge %g %g && %g %g (%d/%d)", // vstart->x(), vstart->y(), vend->x(), vend->y(), i, // ge->mesh_vertices.size()); // return false; @@ -308,7 +308,7 @@ bool recover_medge(BDS_Mesh *m, GEdge *ge, std::set<EdgeToRecover> *e2r, e = m->recover_edge(vstart->getNum(), vend->getNum(), e2r, not_recovered); if (e)e->g = g; else { - // Msg(GERROR,"Unable to recover an edge %g %g && %g %g (%d/%d)", + // Msg(GERROR, "Unable to recover an edge %g %g && %g %g (%d/%d)", // vstart->x(), vstart->y(), vend->x(), vend->y(), // ge->mesh_vertices.size(), ge->mesh_vertices.size()); // return false; @@ -361,6 +361,11 @@ bool gmsh2DMeshGenerator(GFace *gf, int RECUR_ITER, bool debug = true) ++it; } + if (all_vertices.size() < 3){ + Msg(WARNING, "Cannot triangulate less than 3 vertices"); + return false; + } + double *U_ = new double[all_vertices.size()]; double *V_ = new double[all_vertices.size()]; @@ -407,112 +412,97 @@ bool gmsh2DMeshGenerator(GFace *gf, int RECUR_ITER, bool debug = true) SVector3 dd (bbox.max(), bbox.min()); double LC2D = norm(dd); - // Use a divide & conquer type algorithm to create a triangulation - // We add to the triangulation a box with 4 points that encoses - // the domain. - - /// Fill the DocRecord Data Structure with the points - DocRecord doc; - - doc.points = (PointRecord*)malloc((all_vertices.size() + 4) * sizeof(PointRecord)); - itv = all_vertices.begin(); - int j = 0; - while(itv != all_vertices.end()){ - MVertex *here = *itv; - double XX = CTX.mesh.rand_factor * LC2D * (double)rand() / (double)RAND_MAX; - double YY = CTX.mesh.rand_factor * LC2D * (double)rand() / (double)RAND_MAX; - doc.points[j].where.h = U_[j] + XX; - doc.points[j].where.v = V_[j] + YY; - doc.points[j].adjacent = NULL; - doc.points[j].data = here; - j++; - ++itv; - } - - // Increase the size of the bounding box - bbox *= 2.5; - // add 4 points than encloses the domain (use negative number to - // distinguish thos fake vertices) - MVertex *bb[4]; - bb[0] = new MVertex(bbox.min().x(), bbox.min().y(), 0, gf, -1); - bb[1] = new MVertex(bbox.min().x(), bbox.max().y(), 0, gf, -2); - bb[2] = new MVertex(bbox.max().x(), bbox.min().y(), 0, gf, -3); - bb[3] = new MVertex(bbox.max().x(), bbox.max().y(), 0, gf, -4); - - for(int ip = 0; ip < 4; ip++){ - doc.points[all_vertices.size() + ip].where.h = bb[ip]->x(); - doc.points[all_vertices.size() + ip].where.v = bb[ip]->y(); - doc.points[all_vertices.size() + ip].adjacent = 0; - doc.points[all_vertices.size() + ip].data = bb[ip]; - } - - // if the number of vertices is less or equal to 2, then no elements are generated - if (all_vertices.size() <= 2){ - free(doc.points); - free(doc.delaunay); - for(int ip = 0; ip < 4; ip++) delete bb[ip]; - } - - // Use "fast" inhouse recursive algo to generate the triangulation - // At this stage the triangulation is not what we need - // -) It does not necessary recover the boundaries - // -) It contains triangles outside the domain (the first edge - // loop is the outer one) - Msg(DEBUG1,"Meshing of the convex hull (%d points)", all_vertices.size()); - Make_Mesh_With_Points(&doc, doc.points, all_vertices.size() + 4); - - // Buid a BDS_Mesh structure that is convenient for doing the actual meshing procedure + // Buid a BDS_Mesh structure that is convenient for doing the actual + // meshing procedure BDS_Mesh *m = new BDS_Mesh; m->scalingU = 1; m->scalingV = 1; - for(int i = 0; i < doc.numPoints; i++){ - MVertex *here = (MVertex *)doc.points[i].data; - int num = here->getNum(); - double U, V; - // This test was missing in 2.0.0 and led to the seemingly random - // Windows/Mac slowdowns (we were passing random numbers to curve - // interpolation, and straight line interpol does "while(not in - // bounds) i--" which would take forever to get back into a - // reasonnable interval). - // JFR : the fix was WRONG, I fixed the fix ;-) - if(num< 0){ // fake bbox points - U = bb[-1-num]->x(); - V = bb[-1-num]->y(); - } - else{ - U = U_[num]; - V = V_[num]; + // Use a divide & conquer type algorithm to create a triangulation. + // We add to the triangulation a box with 4 points that encloses the + // domain. + { + DocRecord doc(all_vertices.size() + 4); + itv = all_vertices.begin(); + int j = 0; + while(itv != all_vertices.end()){ + MVertex *here = *itv; + double XX = CTX.mesh.rand_factor * LC2D * (double)rand() / (double)RAND_MAX; + double YY = CTX.mesh.rand_factor * LC2D * (double)rand() / (double)RAND_MAX; + doc.points[j].where.h = U_[j] + XX; + doc.points[j].where.v = V_[j] + YY; + doc.points[j].adjacent = NULL; + doc.points[j].data = here; + j++; + ++itv; } - BDS_Point *pp = m->add_point(num, U, V, gf); + // Increase the size of the bounding box + bbox *= 2.5; + // add 4 points than encloses the domain (use negative number to + // distinguish thos fake vertices) + MVertex *bb[4]; + bb[0] = new MVertex(bbox.min().x(), bbox.min().y(), 0, gf, -1); + bb[1] = new MVertex(bbox.min().x(), bbox.max().y(), 0, gf, -2); + bb[2] = new MVertex(bbox.max().x(), bbox.min().y(), 0, gf, -3); + bb[3] = new MVertex(bbox.max().x(), bbox.max().y(), 0, gf, -4); - GEntity *ge = here->onWhat(); - if(ge->dim() == 0){ - pp->lcBGM() = BGM_MeshSize(ge,0,0,here->x(),here->y(),here->z()); + for(int ip = 0; ip < 4; ip++){ + doc.points[all_vertices.size() + ip].where.h = bb[ip]->x(); + doc.points[all_vertices.size() + ip].where.v = bb[ip]->y(); + doc.points[all_vertices.size() + ip].adjacent = 0; + doc.points[all_vertices.size() + ip].data = bb[ip]; } - else if(ge->dim() == 1){ - double u; - here->getParameter(0,u); - pp->lcBGM() = BGM_MeshSize(ge,u,0,here->x(),here->y(),here->z()); + + // Use "fast" inhouse recursive algo to generate the triangulation + // At this stage the triangulation is not what we need + // -) It does not necessary recover the boundaries + // -) It contains triangles outside the domain (the first edge + // loop is the outer one) + Msg(DEBUG1, "Meshing of the convex hull (%d points)", all_vertices.size()); + doc.MakeMeshWithPoints(); + + for(int i = 0; i < doc.numPoints; i++){ + MVertex *here = (MVertex *)doc.points[i].data; + int num = here->getNum(); + double U, V; + if(num < 0){ // fake bbox points + U = bb[-1 - num]->x(); + V = bb[-1 - num]->y(); + } + else{ + U = U_[num]; + V = V_[num]; + } + + BDS_Point *pp = m->add_point(num, U, V, gf); + + GEntity *ge = here->onWhat(); + if(ge->dim() == 0){ + pp->lcBGM() = BGM_MeshSize(ge, 0, 0, here->x(), here->y(), here->z()); + } + else if(ge->dim() == 1){ + double u; + here->getParameter(0,u); + pp->lcBGM() = BGM_MeshSize(ge, u, 0, here->x(), here->y(), here->z()); + } + else + pp->lcBGM() = 1.e22; + + pp->lc() = pp->lcBGM(); } - else - pp->lcBGM() = 1.e22; - pp->lc() = pp->lcBGM(); - } - - Msg(DEBUG1, "Meshing of the convex hull (%d points) done", all_vertices.size()); + Msg(DEBUG1, "Meshing of the convex hull (%d points) done", all_vertices.size()); + + for(int i = 0; i < doc.numTriangles; i++) { + MVertex *V1 = (MVertex*)doc.points[doc.triangles[i].a].data; + MVertex *V2 = (MVertex*)doc.points[doc.triangles[i].b].data; + MVertex *V3 = (MVertex*)doc.points[doc.triangles[i].c].data; + m->add_triangle(V1->getNum(), V2->getNum(), V3->getNum()); + } - for(int i = 0; i < doc.numTriangles; i++) { - MVertex *V1 = (MVertex*)doc.points[doc.delaunay[i].t.a].data; - MVertex *V2 = (MVertex*)doc.points[doc.delaunay[i].t.b].data; - MVertex *V3 = (MVertex*)doc.points[doc.delaunay[i].t.c].data; - m->add_triangle(V1->getNum(), V2->getNum(), V3->getNum()); + for(int ip = 0; ip < 4; ip++) delete bb[ip]; } - free(doc.points); - free(doc.delaunay); - for(int ip = 0; ip < 4; ip++) delete bb[ip]; // Recover the boundary edges and compute characteristic lenghts // using mesh edge spacing @@ -544,7 +534,7 @@ bool gmsh2DMeshGenerator(GFace *gf, int RECUR_ITER, bool debug = true) ++it; } - Msg(DEBUG1,"Recovering %d mesh Edges", edgesToRecover.size()); + Msg(DEBUG1, "Recovering %d mesh Edges", edgesToRecover.size()); // effectively recover the medge it = edges.begin(); @@ -566,8 +556,9 @@ bool gmsh2DMeshGenerator(GFace *gf, int RECUR_ITER, bool debug = true) int p1 = itr->p1; int p2 = itr->p2; int tag = itr->ge->tag(); - Msg(WARNING,"MEdge %d %d in GEdge %d",p1,p2,tag); + Msg(WARNING, "MEdge %d %d in GEdge %d",p1,p2,tag); } + // delete the mesh delete m; delete [] U_; delete [] V_; @@ -576,10 +567,10 @@ bool gmsh2DMeshGenerator(GFace *gf, int RECUR_ITER, bool debug = true) return false; } if(RECUR_ITER > 0) - Msg(WARNING,":-) Gmsh was able to recover all edges after %d ITERATIONS", + Msg(WARNING, ":-) Gmsh was able to recover all edges after %d ITERATIONS", RECUR_ITER); - // Msg(INFO,"Boundary Edges recovered for surface %d",gf->tag()); + // Msg(INFO, "Boundary Edges recovered for surface %d",gf->tag()); // Look for an edge that is on the boundary for which one of the two // neighbors has a negative number node. The other triangle is // inside the domain and, because all edges were recovered, @@ -644,9 +635,9 @@ bool gmsh2DMeshGenerator(GFace *gf, int RECUR_ITER, bool debug = true) if (debug){ char name[245]; - sprintf(name,"surface%d-recovered-real.pos", gf->tag()); + sprintf(name, "surface%d-recovered-real.pos", gf->tag()); outputScalarField(m->triangles, name, 0); - sprintf(name,"surface%d-recovered-param.pos", gf->tag()); + sprintf(name, "surface%d-recovered-param.pos", gf->tag()); outputScalarField(m->triangles, name, 1); } @@ -716,15 +707,14 @@ bool gmsh2DMeshGenerator(GFace *gf, int RECUR_ITER, bool debug = true) } else if (debug){ char name[256]; - sprintf(name,"real%d.pos",gf->tag()); - outputScalarField(m->triangles, name,0,gf); - sprintf(name,"param%d.pos",gf->tag()); + sprintf(name, "real%d.pos", gf->tag()); + outputScalarField(m->triangles, name, 0, gf); + sprintf(name, "param%d.pos", gf->tag()); outputScalarField(m->triangles, name,1); } // delete the mesh delete m; - delete [] U_; delete [] V_; @@ -843,7 +833,7 @@ bool buildConsecutiveListOfVertices(GFace *gf, GEdgeLoop &gel, if (seam && seam_the_first){ coords = ((*it)._sign == 1) ? mesh1d_seam : mesh1d_seam_reversed; found = (*it); - Msg(INFO,"This test case would have failed in Previous Gmsh Version ;-)"); + Msg(INFO, "This test case would have failed in Previous Gmsh Version ;-)"); } else{ coords = ((*it)._sign == 1) ? mesh1d : mesh1d_reversed; @@ -1030,64 +1020,64 @@ bool gmsh2DMeshGeneratorPeriodic(GFace *gf, bool debug = true) } } - // build a point record structure to create the initial mesh - DocRecord doc; - doc.points = (PointRecord*)malloc((nbPointsTotal + 4) * sizeof(PointRecord)); - int count = 0; - for (unsigned int i = 0; i < edgeLoops_BDS.size(); i++){ - std::vector<BDS_Point*> &edgeLoop_BDS = edgeLoops_BDS[i]; - for (unsigned int j = 0; j < edgeLoop_BDS.size(); j++){ - BDS_Point *pp = edgeLoop_BDS[j]; - const double U = pp->u; - const double V = pp->v; - double XX = CTX.mesh.rand_factor * LC2D * (double)rand() / (double)RAND_MAX; - double YY = CTX.mesh.rand_factor * LC2D * (double)rand() / (double)RAND_MAX; - doc.points[count].where.h = U + XX; - doc.points[count].where.v = V + YY; - doc.points[count].adjacent = NULL; - doc.points[count].data = pp; - count++; + // Use a divide & conquer type algorithm to create a triangulation. + // We add to the triangulation a box with 4 points that encloses the + // domain. + { + DocRecord doc(nbPointsTotal + 4); + int count = 0; + for (unsigned int i = 0; i < edgeLoops_BDS.size(); i++){ + std::vector<BDS_Point*> &edgeLoop_BDS = edgeLoops_BDS[i]; + for (unsigned int j = 0; j < edgeLoop_BDS.size(); j++){ + BDS_Point *pp = edgeLoop_BDS[j]; + const double U = pp->u; + const double V = pp->v; + double XX = CTX.mesh.rand_factor * LC2D * (double)rand() / (double)RAND_MAX; + double YY = CTX.mesh.rand_factor * LC2D * (double)rand() / (double)RAND_MAX; + doc.points[count].where.h = U + XX; + doc.points[count].where.v = V + YY; + doc.points[count].adjacent = NULL; + doc.points[count].data = pp; + count++; + } } - } - // Increase the size of the bounding box, add 4 points that encloses - // the domain, use negative number to distinguish those fake - // vertices - bbox *= 3.5; - MVertex *bb[4]; - bb[0] = new MVertex(bbox.min().x(), bbox.min().y(), 0, 0, -1); - bb[1] = new MVertex(bbox.min().x(), bbox.max().y(), 0, 0, -2); - bb[2] = new MVertex(bbox.max().x(), bbox.min().y(), 0, 0, -3); - bb[3] = new MVertex(bbox.max().x(), bbox.max().y(), 0, 0, -4); - - for ( int ip = 0; ip < 4; ip++){ - BDS_Point *pp = m->add_point(-ip - 1, bb[ip]->x(), bb[ip]->y(), gf); - m->add_geom(gf->tag(), 2); - BDS_GeomEntity *g = m->get_geom(gf->tag(), 2); - pp->g = g; - doc.points[nbPointsTotal+ip].where.h = bb[ip]->x(); - doc.points[nbPointsTotal+ip].where.v = bb[ip]->y(); - doc.points[nbPointsTotal+ip].adjacent = 0; - doc.points[nbPointsTotal+ip].data = pp; - } - for (int ip = 0; ip < 4; ip++) delete bb[ip]; - - // Use "fast" inhouse recursive algo to generate the triangulation - // At this stage the triangulation is not what we need - // -) It does not necessary recover the boundaries - // -) It contains triangles outside the domain (the first edge - // loop is the outer one) - Msg(DEBUG1, "Meshing of the convex hull (%d points)", nbPointsTotal); - Make_Mesh_With_Points(&doc, doc.points,nbPointsTotal + 4); - for(int i = 0; i < doc.numTriangles; i++){ - BDS_Point *p1 = (BDS_Point*)doc.points[doc.delaunay[i].t.a].data; - BDS_Point *p2 = (BDS_Point*)doc.points[doc.delaunay[i].t.b].data; - BDS_Point *p3 = (BDS_Point*)doc.points[doc.delaunay[i].t.c].data; - m->add_triangle(p1->iD, p2->iD, p3->iD); + // Increase the size of the bounding box, add 4 points that enclose + // the domain, use negative number to distinguish those fake + // vertices + bbox *= 3.5; + MVertex *bb[4]; + bb[0] = new MVertex(bbox.min().x(), bbox.min().y(), 0, 0, -1); + bb[1] = new MVertex(bbox.min().x(), bbox.max().y(), 0, 0, -2); + bb[2] = new MVertex(bbox.max().x(), bbox.min().y(), 0, 0, -3); + bb[3] = new MVertex(bbox.max().x(), bbox.max().y(), 0, 0, -4); + for (int ip = 0; ip < 4; ip++){ + BDS_Point *pp = m->add_point(-ip - 1, bb[ip]->x(), bb[ip]->y(), gf); + m->add_geom(gf->tag(), 2); + BDS_GeomEntity *g = m->get_geom(gf->tag(), 2); + pp->g = g; + doc.points[nbPointsTotal+ip].where.h = bb[ip]->x(); + doc.points[nbPointsTotal+ip].where.v = bb[ip]->y(); + doc.points[nbPointsTotal+ip].adjacent = 0; + doc.points[nbPointsTotal+ip].data = pp; + } + for (int ip = 0; ip < 4; ip++) delete bb[ip]; + + // Use "fast" inhouse recursive algo to generate the triangulation + // At this stage the triangulation is not what we need + // -) It does not necessary recover the boundaries + // -) It contains triangles outside the domain (the first edge + // loop is the outer one) + Msg(DEBUG1, "Meshing of the convex hull (%d points)", nbPointsTotal); + doc.MakeMeshWithPoints(); + + for(int i = 0; i < doc.numTriangles; i++){ + BDS_Point *p1 = (BDS_Point*)doc.points[doc.triangles[i].a].data; + BDS_Point *p2 = (BDS_Point*)doc.points[doc.triangles[i].b].data; + BDS_Point *p3 = (BDS_Point*)doc.points[doc.triangles[i].c].data; + m->add_triangle(p1->iD, p2->iD, p3->iD); + } } - // Free stuff - free(doc.points); - free(doc.delaunay); // Recover the boundary edges and compute characteristic lenghts // using mesh edge spacing @@ -1117,7 +1107,7 @@ bool gmsh2DMeshGeneratorPeriodic(GFace *gf, bool debug = true) } } - // Msg(INFO,"Boundary Edges recovered for surface %d",gf->tag()); + // Msg(INFO, "Boundary Edges recovered for surface %d",gf->tag()); // Look for an edge that is on the boundary for which one of the two // neighbors has a negative number node. The other triangle is // inside the domain and, because all edges were recovered, @@ -1244,7 +1234,6 @@ bool gmsh2DMeshGeneratorPeriodic(GFace *gf, bool debug = true) } } - // delete the mesh if (debug){ char name[245]; sprintf(name, "surface%d-final-real.pos", gf->tag()); @@ -1257,8 +1246,10 @@ bool gmsh2DMeshGeneratorPeriodic(GFace *gf, bool debug = true) insertVerticesInFace(gf, m); laplaceSmoothing(gf); } - + + // delete the mesh delete m; + computeElementShapes(gf, gf->meshStatistics.worst_element_shape, gf->meshStatistics.average_element_shape, gf->meshStatistics.best_element_shape, diff --git a/Mesh/meshGFaceBDS.cpp b/Mesh/meshGFaceBDS.cpp index a96a3c866062523303a163b0bd9cdc722fb90830..6695c2e635d22b70960326f936240a0f64a8ab94 100644 --- a/Mesh/meshGFaceBDS.cpp +++ b/Mesh/meshGFaceBDS.cpp @@ -1,4 +1,4 @@ -// $Id: meshGFaceBDS.cpp,v 1.8 2008-02-21 13:34:40 geuzaine Exp $ +// $Id: meshGFaceBDS.cpp,v 1.9 2008-03-01 01:32:03 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -611,7 +611,7 @@ void gmshRefineMeshBDS(GFace *gf, BDS_Mesh &m, const int NIT, t_sm += t6 - t5; m.cleanup(); IT++; - Msg(DEBUG1," iter %3d minL %8.3f/%8.3f maxL %8.3f/%8.3f : " + Msg(DEBUG1, " iter %3d minL %8.3f/%8.3f maxL %8.3f/%8.3f : " "%6d splits, %6d swaps, %6d collapses, %6d moves", IT, minL, minE, maxL, maxE, nb_split, nb_swap, nb_collaps, nb_smooth); if (nb_split == 0 && nb_collaps == 0) break; @@ -619,16 +619,16 @@ void gmshRefineMeshBDS(GFace *gf, BDS_Mesh &m, const int NIT, double t_total = t_spl + t_sw + t_col + t_sm; if(!t_total) t_total = 1.e-6; - Msg(DEBUG1," ---------------------------------------"); - Msg(DEBUG1," CPU Report "); - Msg(DEBUG1," ---------------------------------------"); - Msg(DEBUG1," CPU SWAP %12.5E sec (%3.0f %%)", t_sw,100 * t_sw / t_total); - Msg(DEBUG1," CPU SPLIT %12.5E sec (%3.0f %%) ", t_spl,100 * t_spl / t_total); - Msg(DEBUG1," CPU COLLAPS %12.5E sec (%3.0f %%) ", t_col,100 * t_col / t_total); - Msg(DEBUG1," CPU SMOOTH %12.5E sec (%3.0f %%) ", t_sm,100 * t_sm / t_total); - Msg(DEBUG1," ---------------------------------------"); - Msg(DEBUG1," CPU TOTAL %12.5E sec ",t_total); - Msg(DEBUG1," ---------------------------------------"); + Msg(DEBUG1, " ---------------------------------------"); + Msg(DEBUG1, " CPU Report "); + Msg(DEBUG1, " ---------------------------------------"); + Msg(DEBUG1, " CPU SWAP %12.5E sec (%3.0f %%)", t_sw,100 * t_sw / t_total); + Msg(DEBUG1, " CPU SPLIT %12.5E sec (%3.0f %%) ", t_spl,100 * t_spl / t_total); + Msg(DEBUG1, " CPU COLLAPS %12.5E sec (%3.0f %%) ", t_col,100 * t_col / t_total); + Msg(DEBUG1, " CPU SMOOTH %12.5E sec (%3.0f %%) ", t_sm,100 * t_sm / t_total); + Msg(DEBUG1, " ---------------------------------------"); + Msg(DEBUG1, " CPU TOTAL %12.5E sec ",t_total); + Msg(DEBUG1, " ---------------------------------------"); } void allowAppearanceofEdge (BDS_Point *p1, BDS_Point *p2) diff --git a/Plugin/Triangulate.cpp b/Plugin/Triangulate.cpp index 7083b9c2d4cfe7822957092304a4affe0d940c29..9e79310cedde9df626b75860594ad49d13acaeac 100644 --- a/Plugin/Triangulate.cpp +++ b/Plugin/Triangulate.cpp @@ -1,4 +1,4 @@ -// $Id: Triangulate.cpp,v 1.45 2008-02-20 09:20:47 geuzaine Exp $ +// $Id: Triangulate.cpp,v 1.46 2008-03-01 01:32:03 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -117,8 +117,7 @@ static void Triangulate(int nbIn, List_T *inList, int *nbOut, List_T *outList, double lc = norm(SVector3(bbox.max(), bbox.min())); // build a point record structure for the divide and conquer algorithm - DocRecord doc; - doc.points = (PointRecord*)malloc(points.size() * sizeof(PointRecord)); + DocRecord doc(points.size()); for(unsigned int i = 0; i < points.size(); i++){ double XX = CTX.mesh.rand_factor * lc * (double)rand() / (double)RAND_MAX; double YY = CTX.mesh.rand_factor * lc * (double)rand() / (double)RAND_MAX; @@ -130,13 +129,13 @@ static void Triangulate(int nbIn, List_T *inList, int *nbOut, List_T *outList, } // triangulate - Make_Mesh_With_Points(&doc, doc.points, nbIn); + doc.MakeMeshWithPoints(); // create output (using unperturbed data) for(int i = 0; i < doc.numTriangles; i++){ - double *pa = (double*)doc.points[doc.delaunay[i].t.a].data; - double *pb = (double*)doc.points[doc.delaunay[i].t.b].data; - double *pc = (double*)doc.points[doc.delaunay[i].t.c].data; + double *pa = (double*)doc.points[doc.triangles[i].a].data; + double *pb = (double*)doc.points[doc.triangles[i].b].data; + double *pc = (double*)doc.points[doc.triangles[i].c].data; for(int j = 0; j < 3; j++) { List_Add(outList, pa + j); List_Add(outList, pb + j); @@ -149,9 +148,6 @@ static void Triangulate(int nbIn, List_T *inList, int *nbOut, List_T *outList, } (*nbOut)++; } - - free(doc.points); - free(doc.delaunay); } PView *GMSH_TriangulatePlugin::execute(PView *v) diff --git a/Post/PView.cpp b/Post/PView.cpp index a83789a938c7c6d3775dedf87f784fed533a2980..2392cc74b43614d0c797081f2155dbc18ba054b6 100644 --- a/Post/PView.cpp +++ b/Post/PView.cpp @@ -1,4 +1,4 @@ -// $Id: PView.cpp,v 1.17 2008-02-20 09:24:41 geuzaine Exp $ +// $Id: PView.cpp,v 1.18 2008-03-01 01:32:03 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -300,22 +300,56 @@ bool PView::readMSH(std::string filename, int fileIndex) return false; } - Msg(INFO, "Reading post-processing data from MSH file..."); - - // FIXME: to be implemented! - int index = 0; - PViewDataGModel *d = new PViewDataGModel(GModel::current()); - if(!d->readMSH(fp)){ - Msg(GERROR, "Could not read data in msh file"); - delete d; - return false; - } - else{ - d->setFileName(filename); - d->setFileIndex(index); - new PView(d); + char str[256]; + double version; + int format, size, index = -1; + + while(1) { + + do { + if(!fgets(str, 256, fp) || feof(fp)) + break; + } while(str[0] != '$'); + + if(feof(fp)) + break; + + if(!strncmp(&str[1], "NodeData", 8)) { + index++; + if(fileIndex < 0 || fileIndex == index){ + // either get existing viewData, or create new one + // check timestep storage limit, do magic if exceeded + PView *p = 0; + PViewDataGModel *d; + // read view name and timestep + // if append + // p = getView + // d = p->getData() + // else + d = new PViewDataGModel(GModel::current()); + if(!d->readMSH(fp)){ + Msg(GERROR, "Could not read data in msh file"); + delete d; + return false; + } + else{ + d->setFileName(filename); + d->setFileIndex(index); + if(!p) new PView(d); + } + } + } + + do { + if(!fgets(str, 256, fp) || feof(fp)){ + Msg(GERROR, "Prematured end of file"); + break; + } + } while(str[0] != '$'); + } - + + fclose(fp); return true; } diff --git a/Post/PViewDataGModelIO.cpp b/Post/PViewDataGModelIO.cpp index 1e8d5e6e7577e366b818e3ec17095db6bef4e3a0..48c71a2ada5228abedd0084dcc1b46accc375c9d 100644 --- a/Post/PViewDataGModelIO.cpp +++ b/Post/PViewDataGModelIO.cpp @@ -1,4 +1,4 @@ -// $Id: PViewDataGModelIO.cpp,v 1.1 2008-02-24 19:59:03 geuzaine Exp $ +// $Id: PViewDataGModelIO.cpp,v 1.2 2008-03-01 01:32:03 geuzaine Exp $ // // Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle // @@ -27,30 +27,14 @@ #include "PViewDataGModel.h" /* - if(!fgets(str, sizeof(str), fp)) return 0; - // name = str[1] + remove final " - int timeStep, numData, numComponents; - double time; - if(_vertexVector.empty() && _vertexMap.empty()){ - Msg(GERROR, "Mesh vertex information missing: impossible to load dataset"); - return false; - } - - if(fscanf(fp, "%d %lf %d %d", &timeStep, &time, &numData, &numComponents) != 4) - return 0; - Msg(INFO, "%d node data", numData); - - //std::map<int, int> nodeNumber, nodeIndex - PViewDataGModel *p = getPViewDataGModel(name) - if(p){ // add data to existing view - if(!p.count(timeStep)){ - // we don't have any data for this time step - p[timeStep] = new nodeData(numNodes); - } - data = p[timeStep]; - if(num - data.scalar.indices.append(); - data.scalar.values.append(); + if(!fgets(str, sizeof(str), fp)) return 0; + // name = str[1] + remove final " + int timeStep, numData, numComponents; + double time; + if(fscanf(fp, "%d %lf %d %d", &timeStep, &time, &numData, &numComponents) != 4) + return 0; + Msg(INFO, "%d node data", numData); + fill in data */ bool PViewDataGModel::readMSH(FILE *fp) diff --git a/doc/VERSIONS b/doc/VERSIONS index 9d5e0c608fc972652d03d31cf3635b7131345cff..89718988623f6204c4de0e50a6402df20a55c8a1 100644 --- a/doc/VERSIONS +++ b/doc/VERSIONS @@ -1,6 +1,7 @@ -$Id: VERSIONS,v 1.398 2008-02-27 12:39:28 geuzaine Exp $ +$Id: VERSIONS,v 1.399 2008-03-01 01:32:03 geuzaine Exp $ -2.1.1 (Feb , 2008): small bug fixes (higher order elements) +2.1.1 (Feb , 2008): small bug fixes (second order meshes, combine +views, divide and conquer crash). 2.1.0 (Feb 23, 2008): new post-processing database; complete rewrite of post-processing drawing code; improved surface mesh algorithms;