diff --git a/CREDITS.txt b/CREDITS.txt index 29ae579657e3785b3179e5a935b13df053efb63f..134c835f7fbf22e5baea415547119b20c88e57fc 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -32,9 +32,9 @@ Pierre-Alexandre Beaufort (HXT/reparam), Zhidong Han (LSDYNA export), Ismail Badia (hierarchical basis functions), Jeremy Theler (X3D export), Thomas Toulorge (high order mesh optimizer, new CGNS IO), Max Orok (binary PLY), Marek Wojciechowski (PyPi packaging), Maxence Reberol (automatic transfinite, quad -meshing tools), Michael Ermakov (Gambit export, Fortran API), Alex Krasner (X3D -export). See comments in the sources for more information. If we forgot to list -your contributions please send us an email! +meshing tools), Michael Ermakov (Gambit export, Fortran API, transfinite3), Alex +Krasner (X3D export). See comments in the sources for more information. If we +forgot to list your contributions please send us an email! Thanks to the following folks who have contributed by providing fresh ideas on theoretical or programming topics, who have sent patches, requests for changes diff --git a/src/geo/GFace.cpp b/src/geo/GFace.cpp index a1205cdbf3e99897487180ec3dbad1ba20ef9271..2f28db174ec09c77460aa54086fbae9a0f99b948 100644 --- a/src/geo/GFace.cpp +++ b/src/geo/GFace.cpp @@ -237,6 +237,7 @@ void GFace::resetMeshAttributes() meshAttributes.meshSizeFactor = 1.; meshAttributes.algorithm = 0; meshAttributes.meshSizeFromBoundary = -1; + meshAttributes.transfinite3 = false; } SBoundingBox3d GFace::bounds(bool fast) diff --git a/src/geo/GFace.h b/src/geo/GFace.h index 784e9b8bb31870ee48c96b61288daf1f9bd8e2b2..16fe0a5829aa5d3b616fddd66427cb0c48374d15 100644 --- a/src/geo/GFace.h +++ b/src/geo/GFace.h @@ -319,8 +319,8 @@ public: int algorithm; // do we force calculation of mesh size from boundary (if >= 0) int meshSizeFromBoundary; - // do we use transfinite standard algo - bool transfinite_standard; + // do we use a specific transfinite algorithm for 3-sided surfaces + bool transfinite3; } meshAttributes; int getMeshingAlgo() const; diff --git a/src/geo/GModelIO_OCC.cpp b/src/geo/GModelIO_OCC.cpp index 67a339fcaa4900dae464ab16fe1ec20e804f8323..fab492d6dc88db0bbf7c8de3b440a35d39241efe 100644 --- a/src/geo/GModelIO_OCC.cpp +++ b/src/geo/GModelIO_OCC.cpp @@ -2054,6 +2054,11 @@ static bool makeTrimmedSurface(const Handle(Geom_Surface) &surf, if(makeEdgeOnSurface(edge, surf, wire3D, edgeOnSurf)) w.Add(edgeOnSurf); } + w.Build(); + if(!w.IsDone()) { + Msg::Error("Could not create wire"); + return false; + } TopoDS_Wire wire = w.Wire(); wiresProj.push_back(wire); } diff --git a/src/geo/discreteFace.cpp b/src/geo/discreteFace.cpp index 9b0f389ffabce4980dad6a5763001c344c758e24..c067ee676c2759568279e355ab56deb139a3bf0f 100644 --- a/src/geo/discreteFace.cpp +++ b/src/geo/discreteFace.cpp @@ -931,4 +931,5 @@ void discreteFace::resetMeshAttributes() meshAttributes.reverseMesh = _s->ReverseMesh; meshAttributes.algorithm = _s->MeshAlgorithm; meshAttributes.meshSizeFromBoundary = _s->MeshSizeFromBoundary; + meshAttributes.transfinite3 = false; } diff --git a/src/geo/gmshFace.cpp b/src/geo/gmshFace.cpp index 9024d0059abdb6a5658f5de00600f29864db25ec..5134df2c62587f19aff1910d74695c608ce46549 100644 --- a/src/geo/gmshFace.cpp +++ b/src/geo/gmshFace.cpp @@ -127,6 +127,7 @@ void gmshFace::resetMeshAttributes() meshAttributes.reverseMesh = _s->ReverseMesh; meshAttributes.algorithm = _s->MeshAlgorithm; meshAttributes.meshSizeFromBoundary = _s->MeshSizeFromBoundary; + meshAttributes.transfinite3 = false; } Range<double> gmshFace::parBounds(int i) const { return Range<double>(0, 1); } diff --git a/src/mesh/meshGFaceTransfinite.cpp b/src/mesh/meshGFaceTransfinite.cpp index 6e1edcbc6e33fd50354f4fc2ad9a5775516bb2c3..947aed8cf2b555452143e5c599a94ff9b390cf5e 100644 --- a/src/mesh/meshGFaceTransfinite.cpp +++ b/src/mesh/meshGFaceTransfinite.cpp @@ -263,7 +263,7 @@ int MeshTransfiniteSurface(GFace *gf) V = V2; } - bool transfinite_standard = true; + bool transfinite3 = false; int N1 = N[0], N2 = N[1], N3 = N[2], N4 = N[3]; int L = N2 - N1, H = N3 - N2; @@ -280,8 +280,8 @@ int MeshTransfiniteSurface(GFace *gf) int Lb = m_vertices.size() - N3; #ifdef TFTria if(Lb == L && H == L) { - transfinite_standard = false; - Msg::Info("Meshing surface %d (Transfinite 3)", gf->tag()); + transfinite3 = true; + Msg::Info("Using specific algorithm for 3-sided surface %d", gf->tag()); } else { #endif @@ -296,7 +296,7 @@ int MeshTransfiniteSurface(GFace *gf) #endif } - gf->meshAttributes.transfinite_standard = transfinite_standard; + gf->meshAttributes.transfinite3 = transfinite3; /* 2L+H +------------+ L+H @@ -416,7 +416,7 @@ int MeshTransfiniteSurface(GFace *gf) } else { std::vector<double> u2, v2; - if(!transfinite_standard) { + if(transfinite3) { u2.reserve(H + 1); for(int j = 0; j <= H; j++) u2.push_back(U[N2 + j]); v2.reserve(H + 1); @@ -432,7 +432,7 @@ int MeshTransfiniteSurface(GFace *gf) int iP3 = ((N3 + N2) - i) % m_vertices.size(); double Up, Vp; if(gf->geomType() != GEntity::RuledSurface) { - if(transfinite_standard) { + if(!transfinite3) { Up = TRAN_TRI(U[iP1], U[iP2], U[iP3], UC1, UC2, UC3, u, v); Vp = TRAN_TRI(V[iP1], V[iP2], V[iP3], VC1, VC2, VC3, u, v); } @@ -489,7 +489,7 @@ int MeshTransfiniteSurface(GFace *gf) else if(gf->meshAttributes.transfiniteSmoothing > 0) numSmooth = gf->meshAttributes.transfiniteSmoothing; - if(corners.size() == 4 && numSmooth && transfinite_standard) { + if(corners.size() == 4 && numSmooth && !transfinite3) { std::vector<std::vector<double> > u(L + 1), v(L + 1); for(int i = 0; i <= L; i++) { u[i].resize(H + 1); @@ -590,7 +590,7 @@ int MeshTransfiniteSurface(GFace *gf) } } else { - if(transfinite_standard) { + if(!transfinite3) { for(int j = 0; j < H; j++) { MVertex *v1 = tab[0][0]; MVertex *v2 = tab[1][j]; diff --git a/src/mesh/meshGRegionTransfinite.cpp b/src/mesh/meshGRegionTransfinite.cpp index f3e7e387924583473401586442166caf52bd14b8..dc6fe11f7285609ac1c6eb949029a56d572e4644 100644 --- a/src/mesh/meshGRegionTransfinite.cpp +++ b/src/mesh/meshGRegionTransfinite.cpp @@ -179,23 +179,19 @@ private: int _ll, _hh; int _permutation, _index; std::vector<MVertex *> _list; - bool _transfinite_standard; public: GOrientedTransfiniteFace() - : _gf(nullptr), _ll(0), _hh(0), _permutation(-1), _index(-1), - _transfinite_standard(true) + : _gf(nullptr), _ll(0), _hh(0), _permutation(-1), _index(-1) { } GOrientedTransfiniteFace(GFace *gf, std::vector<MVertex *> &corners) - : _gf(gf), _ll(0), _hh(0), _permutation(-1), _index(-1), - _transfinite_standard(true) + : _gf(gf), _ll(0), _hh(0), _permutation(-1), _index(-1) { _ll = gf->transfinite_vertices.size() - 1; if(_ll <= 0) return; _hh = gf->transfinite_vertices[0].size() - 1; if(_hh <= 0) return; - _transfinite_standard = gf->meshAttributes.transfinite_standard; Msg::Debug("Face %d: L = %d H = %d", gf->tag(), _ll, _hh); // get the corners of the transfinite volume interpolation @@ -294,8 +290,6 @@ public: } return v; } - // returns the transfinite_standard - bool transfinite_standard() const { return _transfinite_standard; } }; void findTransfiniteCorners(GRegion *gr, std::vector<MVertex *> &corners) @@ -626,20 +620,19 @@ int MeshTransfiniteVolume(GRegion *gr) } } else if(faces.size() == 5) { - bool transfinite_standard_3d = true; + bool standard_algo = true; for(int i = 0; i < 5; i++) { - if(!orientedFaces[i].transfinite_standard()) { - transfinite_standard_3d = false; + if(orientedFaces[i].getSurface() && + orientedFaces[i].getSurface()->meshAttributes.transfinite3) { + standard_algo = false; break; } } - - if(transfinite_standard_3d) { + if(standard_algo) { for(int j = 0; j < N_j - 1; j++) { for(int k = 0; k < N_k - 1; k++) { #if defined(HAVE_QUADTRI) if(gr->meshAttributes.QuadTri) { - // create vertex array std::vector<MVertex *> verts; verts.resize(6); verts[0] = tab[0][j][k]; @@ -759,7 +752,7 @@ int MeshTransfiniteVolume(GRegion *gr) } } } - else { + else { // if surfaces meshed with specific algo for 3-sided surfaces for(int i = 0; i < N_i - 1; i++) { int j = i; for(int k = 0; k < N_k - 1; k++) { @@ -783,49 +776,14 @@ int MeshTransfiniteVolume(GRegion *gr) } } } - for(int i = 1; i < N_i - 1; i++) { for(int j = 0; j < i; j++) { for(int k = 0; k < N_k - 1; k++) { - /* - #if defined(HAVE_QUADTRI) - if(gr->meshAttributes.QuadTri) { - // create vertex array - std::vector<MVertex *> verts; - verts.resize(8); - verts[0] = tab[i][j][k]; - verts[1] = tab[i + 1][j][k]; - verts[2] = tab[i + 1][j + 1][k]; - verts[3] = tab[i][j + 1][k]; - verts[4] = tab[i][j][k + 1]; - verts[5] = tab[i + 1][j][k + 1]; - verts[6] = tab[i + 1][j + 1][k + 1]; - verts[7] = tab[i][j + 1][k + 1]; - if((!orientedFaces[1].recombined() && i == N_i - 2) || - (!orientedFaces[0].recombined() && j == 0) || - (!orientedFaces[2].recombined() && j == N_j - 2) || - (!orientedFaces[4].recombined() && k == 0) || - (!orientedFaces[5].recombined() && k == N_k - 2)) { - // make subdivided element - meshTransfElemWithInternalVertex(gr, verts, - &boundary_diags); - } - else - gr->hexahedra.push_back( - new MHexahedron(verts[0], verts[1], verts[2], - verts[3], verts[4], verts[5], verts[6], verts[7])); - // continue, skipping the rest which is for - non-divided elements continue; - } - #endif - */ - if(orientedFaces[0].recombined() && orientedFaces[1].recombined() && orientedFaces[2].recombined()) { gr->prisms.push_back(CREATE_PRISM_3); gr->prisms.push_back(CREATE_PRISM_4); } - else if(!orientedFaces[0].recombined() && !orientedFaces[1].recombined() && !orientedFaces[2].recombined() &&