diff --git a/Mesh/3D_Mesh.cpp b/Mesh/3D_Mesh.cpp index f9a6285b14ba3bd27d6f0c6383558a635a6472f3..d6a9c7f39006b38d4c8f7ab333245d455d9d0a4c 100644 --- a/Mesh/3D_Mesh.cpp +++ b/Mesh/3D_Mesh.cpp @@ -1,4 +1,4 @@ -// $Id: 3D_Mesh.cpp,v 1.61 2004-06-26 17:58:14 geuzaine Exp $ +// $Id: 3D_Mesh.cpp,v 1.62 2004-06-26 21:34:50 geuzaine Exp $ // // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle // @@ -897,11 +897,9 @@ void Maillage_Volume(void *data, void *dum) } else if(MeshTransfiniteVolume(v)) { } - else if(v->Typ != 99999){ - if (Mesh_Netgen(v)) { - } + else if((v->Typ != 99999) && Mesh_Netgen(v)) { } - else if((v->Typ == 99999) && (CTX.mesh.algo3d !=FRONTAL_NETGEN)) { + else if((v->Typ == 99999) && (CTX.mesh.algo3d != FRONTAL_NETGEN)) { Simplexes_New = List_Create(10, 10, sizeof(Simplex *)); Simplexes_Destroyed = List_Create(10, 10, sizeof(Simplex *)); diff --git a/Mesh/3D_Mesh_Netgen.cpp b/Mesh/3D_Mesh_Netgen.cpp index 1f8e8517519740b4275adba89b49683803e41da6..27f2900f138c3c25cca4d30498c13cd29d44acf9 100644 --- a/Mesh/3D_Mesh_Netgen.cpp +++ b/Mesh/3D_Mesh_Netgen.cpp @@ -1,4 +1,4 @@ -// $Id: 3D_Mesh_Netgen.cpp,v 1.1 2004-06-26 17:58:14 geuzaine Exp $ +// $Id: 3D_Mesh_Netgen.cpp,v 1.2 2004-06-26 21:34:50 geuzaine Exp $ // // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle // @@ -30,12 +30,18 @@ #if !defined(HAVE_NETGEN) -int Mesh_Netgen(Surface * s) +int Mesh_Netgen(Volume * v) { - Msg(GERROR, "Netgen is not compiled in this version of Gmsh"); + if(CTX.mesh.algo3d == FRONTAL_NETGEN) + Msg(GERROR, "Netgen is not compiled in this version of Gmsh"); return 0; } +void Optimize_Netgen(Volume * v) +{ + Msg(GERROR, "Netgen is not compiled in this version of Gmsh"); +} + #else extern "C" @@ -46,58 +52,65 @@ extern "C" extern Context_T CTX; extern Mesh *THEM; -int Mesh_Netgen(Volume * v) +class Netgen{ + private: + List_T *_vertices; + Volume *_vol; + Ng_Mesh *_ngmesh; + public: + Netgen(Volume *vol, int importVolumeMesh = 0); + Netgen(Surface *s, int importSurfaceMesh = 0); + ~Netgen(); + void MeshVolume(); + void OptimizeVolume(); +}; + +Netgen::Netgen(Volume *vol, int importVolumeMesh) + : _vol(vol) { - if(CTX.mesh.algo3d != FRONTAL_NETGEN) - return 0; - - if(THEM->BGM.Typ == ONFILE){ - Msg(GERROR, "Netgen is not ready to be used with a background mesh"); - return 0; - } - - List_T *lSurfaceVertexList = List_Create(100, 100, sizeof(Vertex*)); - - // =================================== - // GMSH => NETGEN - // =================================== - // creates Netgen mesh structure Ng_Init(); - Ng_Mesh *lNetgenMesh = Ng_NewMesh(); + _ngmesh = Ng_NewMesh(); - // Transfert all surface vertices to Netgen - for(int i = 0; i < List_Nbr(v->Surfaces); i++) { - Surface *s; - List_Read(v->Surfaces, i, &s); - List_T *lVertexList = Tree2List(s->Vertices); - for(int j = 0; j < List_Nbr(lVertexList); j++) { - Vertex *lVertex; - List_Read(lVertexList, j, &lVertex); - // We must *not* add 2 times the same vertex (the same vertex - // can belong to several surfaces) - if(List_ISearchSeq(lSurfaceVertexList, &lVertex, compareVertex) < 0) { - List_Add(lSurfaceVertexList, &lVertex); - double tmp[3]; - tmp[0] = lVertex->Pos.X; - tmp[1] = lVertex->Pos.Y; - tmp[2] = lVertex->Pos.Z; - Ng_AddPoint(lNetgenMesh, tmp); - } + if(importVolumeMesh){ + _vertices = Tree2List(_vol->Vertices); + } + else{ + // Transfert all surface vertices we must *not* add 2 times the + // same vertex (the same vertex can belong to several surfaces) + _vertices = List_Create(100, 100, sizeof(Vertex*)); + for(int i = 0; i < List_Nbr(_vol->Surfaces); i++) { + Surface *s; + List_Read(_vol->Surfaces, i, &s); + List_T *vlist = Tree2List(s->Vertices); + for(int j = 0; j < List_Nbr(vlist); j++) + List_Insert(_vertices, List_Pointer(vlist, j), compareVertex); + List_Delete(vlist); } - List_Delete(lVertexList) ; } - - // Transfert all surface simplices to Netgen - for(int i = 0; i < List_Nbr(v->Surfaces); i++) { + List_Sort(_vertices, compareVertex); + + // Transfer the vertices + for(int i = 0; i < List_Nbr(_vertices); i++){ + Vertex *v; + List_Read(_vertices, i, &v); + double tmp[3]; + tmp[0] = v->Pos.X; + tmp[1] = v->Pos.Y; + tmp[2] = v->Pos.Z; + Ng_AddPoint(_ngmesh, tmp); + } + + // Transfert all surface simplices + for(int i = 0; i < List_Nbr(_vol->Surfaces); i++) { Surface *s; + List_Read(_vol->Surfaces, i, &s); int sign; - List_Read(v->Surfaces, i, &s); - List_Read(v->SurfacesOrientations, i, &sign); - List_T *lSimplexeList = Tree2List(s->Simplexes); - for(int j = 0; j < List_Nbr(lSimplexeList); j++) { - Simplex *lSimplex; - List_Read(lSimplexeList, j, &lSimplex); + List_Read(_vol->SurfacesOrientations, i, &sign); + List_T *simplist = Tree2List(s->Simplexes); + for(int j = 0; j < List_Nbr(simplist); j++) { + Simplex *simp; + List_Read(simplist, j, &simp); int tmp[3], index[3]; if(sign > 0){ index[0] = 0; @@ -109,71 +122,116 @@ int Mesh_Netgen(Volume * v) index[1] = 2; index[2] = 1; } - tmp[0] = 1 + List_ISearchSeq(lSurfaceVertexList, &lSimplex->V[index[0]], - compareVertex); - tmp[1] = 1 + List_ISearchSeq(lSurfaceVertexList, &lSimplex->V[index[1]], - compareVertex); - tmp[2] = 1 + List_ISearchSeq(lSurfaceVertexList, &lSimplex->V[index[2]], - compareVertex); - Ng_AddSurfaceElement(lNetgenMesh, NG_TRIG, tmp); + tmp[0] = 1 + List_ISearch(_vertices, &simp->V[index[0]], compareVertex); + tmp[1] = 1 + List_ISearch(_vertices, &simp->V[index[1]], compareVertex); + tmp[2] = 1 + List_ISearch(_vertices, &simp->V[index[2]], compareVertex); + Ng_AddSurfaceElement(_ngmesh, NG_TRIG, tmp); } - List_Delete(lSimplexeList); + List_Delete(simplist); } - - // =================================== - // MESHING - // =================================== - // define Netgen meshing option + // Transfer the volume elements + if(importVolumeMesh){ + List_T *simplist = Tree2List(_vol->Simplexes); + for(int i = 0; i < List_Nbr(simplist); i++) { + Simplex *simp; + List_Read(simplist, i, &simp); + int tmp[4]; + tmp[0] = 1 + List_ISearch(_vertices, &simp->V[0], compareVertex); + tmp[1] = 1 + List_ISearch(_vertices, &simp->V[1], compareVertex); + tmp[2] = 1 + List_ISearch(_vertices, &simp->V[2], compareVertex); + tmp[3] = 1 + List_ISearch(_vertices, &simp->V[3], compareVertex); + Ng_AddVolumeElement(_ngmesh, NG_TET, tmp); + } + List_Delete(simplist); + } +} + +Netgen::Netgen(Surface *sur, int importSurfaceMesh) +{ + // todo +} + +Netgen::~Netgen() +{ + List_Delete(_vertices); + Ng_DeleteMesh(_ngmesh); + Ng_Exit(); +} + +void Netgen::MeshVolume() +{ Ng_Meshing_Parameters mp; mp.maxh = 1; mp.fineness = 1; mp.secondorder = 0; + Ng_GenerateVolumeMesh(_ngmesh, &mp); - // generate Netgen volume mesh - Msg(STATUS3, "Meshing volume %d", v->Num); - Ng_GenerateVolumeMesh(lNetgenMesh, &mp); - - // =================================== - // NETGEN => GMSH - // =================================== - // Gets total number of vertices of Netgen's mesh - int lNbOfNGPoints = Ng_GetNP(lNetgenMesh); - Vertex **vtable = (Vertex **)Malloc(lNbOfNGPoints * sizeof(Vertex*)); + int nbv = Ng_GetNP(_ngmesh); + Vertex **vtable = (Vertex **)Malloc(nbv * sizeof(Vertex*)); - // Writes existing surface vertices - for(int i = 0; i < List_Nbr(lSurfaceVertexList); i++) - List_Read(lSurfaceVertexList, i, &vtable[i]); + // Get existing vertices + for(int i = 0; i < List_Nbr(_vertices); i++) + List_Read(_vertices, i, &vtable[i]); - // Writes and transfers new volume vertices - for(int i = List_Nbr(lSurfaceVertexList); i < lNbOfNGPoints; i++) { + // Create new volume vertices + for(int i = List_Nbr(_vertices); i < nbv; i++) { double tmp[3]; - Ng_GetPoint(lNetgenMesh, i+1, tmp); + Ng_GetPoint(_ngmesh, i+1, tmp); vtable[i] = Create_Vertex(++(THEM->MaxPointNum), tmp[0], tmp[1], tmp[2], 1., 0); - Tree_Add(v->Vertices, &vtable[i]); + Tree_Add(_vol->Vertices, &vtable[i]); Tree_Add(THEM->Vertices, &vtable[i]); } // Get total number of simplices of Netgen's mesh - int lNbOfNGElements = Ng_GetNE(lNetgenMesh); - // Transfers new volume simplices - for(int i = 1; i <= lNbOfNGElements; i++) { + int nbe = Ng_GetNE(_ngmesh); + + // Create new volume simplices + for(int i = 0; i < nbe; i++) { int tmp[4]; - Ng_GetVolumeElement(lNetgenMesh, i, tmp); - Simplex *lSimplex = Create_Simplex(vtable[tmp[0]-1], vtable[tmp[1]-1], - vtable[tmp[2]-1], vtable[tmp[3]-1]); - lSimplex->iEnt = v->Num; - Tree_Add(v->Simplexes, &lSimplex); + Ng_GetVolumeElement(_ngmesh, i+1, tmp); + Simplex *simp = Create_Simplex(vtable[tmp[0]-1], vtable[tmp[1]-1], + vtable[tmp[2]-1], vtable[tmp[3]-1]); + simp->iEnt = _vol->Num; + Tree_Add(_vol->Simplexes, &simp); } - - List_Delete(lSurfaceVertexList); + Free(vtable); +} - Ng_DeleteMesh(lNetgenMesh); - Ng_Exit(); +void Netgen::OptimizeVolume() +{ + // remove the pure volume vertices from THEM->Vertices and v->Vertices + // remove the tets from THEM->Simplexes + // reset v->Simplexes + //RemoveIllegalElements(*_ngmesh); + //OptimizeVolume(mparam, *_ngmesh, NULL); + // transfer vertices and tets back into v and THEM +} +int Mesh_Netgen(Volume * v) +{ + if(CTX.mesh.algo3d != FRONTAL_NETGEN) + return 0; + + if(THEM->BGM.Typ == ONFILE){ + Msg(GERROR, "Netgen is not ready to be used with a background mesh"); + return 0; + } + + Msg(STATUS3, "Meshing volume %d", v->Num); + Netgen ng(v); + ng.MeshVolume(); + return 1; } +void Optimize_Netgen(Volume * v) +{ + Msg(STATUS3, "Optimizing volume %d", v->Num); + Netgen ng(v, 1); + ng.OptimizeVolume(); +} + #endif // !HAVE_NETGEN diff --git a/Mesh/Mesh.h b/Mesh/Mesh.h index c373ec234c8e000986f225698c3a4d100c55deeb..da8a0fbd1d224fd334e99774c5bea5f237d987a5 100644 --- a/Mesh/Mesh.h +++ b/Mesh/Mesh.h @@ -469,6 +469,7 @@ int AlgorithmeMaillage2DAnisotropeModeJF(Surface * s); void Maillage_Automatique_VieuxCode(Surface * pS, Mesh * m, int ori); int Mesh_Shewchuk(Surface *s); int Mesh_Netgen(Volume * v); +void Optimize_Netgen(Volume * v); int Calcule_Contours(Surface * s); void Link_Simplexes(List_T * Sim, Tree_T * Tim); diff --git a/tutorial/t5.geo b/tutorial/t5.geo index fb7db01277fed0a7157780d5e9386390594d9bc0..e84827ee51ececf4b61c931e21fa8893ba9b058c 100644 --- a/tutorial/t5.geo +++ b/tutorial/t5.geo @@ -116,8 +116,7 @@ Function CheeseHole theloops[t] = newreg ; - Surface Loop(theloops[t]) = {l8+1, l5+1, l1+1, l2+1, -(l3+1), -(l7+1), - l6+1, l4+1}; + Surface Loop(theloops[t]) = {l8+1, l5+1, l1+1, l2+1, l3+1, l7+1, l6+1, l4+1}; thehole = newreg ; Volume(thehole) = theloops[t] ;