Path: blob/devel/ElmerGUI/netgen/libsrc/interface/nglib.cpp
3206 views
/**************************************************************************/1/* File: nglib.cc */2/* Author: Joachim Schoeberl */3/* Date: 7. May. 2000 */4/**************************************************************************/56/*78Interface to the netgen meshing kernel910*/111213#include <mystdlib.h>14#include <myadt.hpp>1516#include <linalg.hpp>17#include <csg.hpp>18#include <stlgeom.hpp>19#include <geometry2d.hpp>20#include <meshing.hpp>21222324// #include <FlexLexer.h>2526namespace netgen {27extern void MeshFromSpline2D (SplineGeometry2d & geometry,28Mesh *& mesh,29MeshingParameters & mp);30}3132333435363738namespace nglib {39#include "nglib.h"40}4142using namespace netgen;4344// constants and types:4546namespace nglib47{48// initialize, deconstruct Netgen library:49void Ng_Init ()50{51mycout = &cout;52myerr = &cerr;53testout = new ofstream ("test.out");54}5556void Ng_Exit ()57{58;59}606162Ng_Mesh * Ng_NewMesh ()63{64Mesh * mesh = new Mesh;65mesh->AddFaceDescriptor (FaceDescriptor (1, 1, 0, 1));66return (Ng_Mesh*)(void*)mesh;67}6869void Ng_DeleteMesh (Ng_Mesh * mesh)70{71delete (Mesh*)mesh;72}7374// return bc property for surface element i75int76EG_GetSurfaceElementBCProperty(Ng_Mesh * mesh, int i)77{78int j = ((Mesh*)mesh)->SurfaceElement(i).GetIndex();79int k = ((Mesh*)mesh)->GetFaceDescriptor(j).BCProperty();80return k;81}8283// return surface and volume element in pi84Ng_Surface_Element_Type85EG_GetSurfaceElement (Ng_Mesh * mesh, int num, int * pi, int * ptrignum)86{87const Element2d & el = ((Mesh*)mesh)->SurfaceElement(num);88for (int i = 1; i <= el.GetNP(); i++) {89pi[i-1] = el.PNum(i);90ptrignum[i-1] = el.GeomInfoPi(i).trignum;91}92Ng_Surface_Element_Type et;93switch (el.GetNP())94{95case 3: et = NG_TRIG; break;96case 4: et = NG_QUAD; break;97case 6: et = NG_TRIG6; break;98}99return et;100}101102// return segment bcnum103void104EG_GetSegmentBCProperty (Ng_Mesh *mesh, Ng_Geometry_2D * geom, int num, int * bcnum)105{106const Segment & seg = ((Mesh*)mesh)->LineSegment(num);107108int edgenum = seg.edgenr;109110SplineGeometry2d *geom2d = (SplineGeometry2d*)geom;111112SplineSegment &spline = geom2d->GetSpline(num);113114if(bcnum)115*bcnum = spline.bc;116}117118// feeds points, surface elements and volume elements to the mesh119void Ng_AddPoint (Ng_Mesh * mesh, double * x)120{121Mesh * m = (Mesh*)mesh;122m->AddPoint (Point3d (x[0], x[1], x[2]));123}124125void Ng_AddSurfaceElement (Ng_Mesh * mesh, Ng_Surface_Element_Type et,126int * pi)127{128Mesh * m = (Mesh*)mesh;129Element2d el (3);130el.SetIndex (1);131el.PNum(1) = pi[0];132el.PNum(2) = pi[1];133el.PNum(3) = pi[2];134m->AddSurfaceElement (el);135}136137void Ng_AddVolumeElement (Ng_Mesh * mesh, Ng_Volume_Element_Type et,138int * pi)139{140Mesh * m = (Mesh*)mesh;141Element el (4);142el.SetIndex (1);143el.PNum(1) = pi[0];144el.PNum(2) = pi[1];145el.PNum(3) = pi[2];146el.PNum(4) = pi[3];147m->AddVolumeElement (el);148}149150// ask for number of points, surface and volume elements151int Ng_GetNP (Ng_Mesh * mesh)152{153return ((Mesh*)mesh) -> GetNP();154}155156int Ng_GetNSE (Ng_Mesh * mesh)157{158return ((Mesh*)mesh) -> GetNSE();159}160161int Ng_GetNE (Ng_Mesh * mesh)162{163return ((Mesh*)mesh) -> GetNE();164}165166167// return point coordinates168void Ng_GetPoint (Ng_Mesh * mesh, int num, double * x)169{170const Point3d & p = ((Mesh*)mesh)->Point(num);171x[0] = p.X();172x[1] = p.Y();173x[2] = p.Z();174}175176// return surface and volume element in pi177Ng_Surface_Element_Type178Ng_GetSurfaceElement (Ng_Mesh * mesh, int num, int * pi)179{180const Element2d & el = ((Mesh*)mesh)->SurfaceElement(num);181for (int i = 1; i <= el.GetNP(); i++)182pi[i-1] = el.PNum(i);183Ng_Surface_Element_Type et;184switch (el.GetNP())185{186case 3: et = NG_TRIG; break;187case 4: et = NG_QUAD; break;188case 6: et = NG_TRIG6; break;189}190return et;191}192193Ng_Volume_Element_Type194Ng_GetVolumeElement (Ng_Mesh * mesh, int num, int * pi)195{196const Element & el = ((Mesh*)mesh)->VolumeElement(num);197for (int i = 1; i <= el.GetNP(); i++)198pi[i-1] = el.PNum(i);199Ng_Volume_Element_Type et;200switch (el.GetNP())201{202case 4: et = NG_TET; break;203case 5: et = NG_PYRAMID; break;204case 6: et = NG_PRISM; break;205case 10: et = NG_TET10; break;206}207return et;208}209210void Ng_RestrictMeshSizeGlobal (Ng_Mesh * mesh, double h)211{212((Mesh*)mesh) -> SetGlobalH (h);213}214215void Ng_RestrictMeshSizePoint (Ng_Mesh * mesh, double * p, double h)216{217((Mesh*)mesh) -> RestrictLocalH (Point3d (p[0], p[1], p[2]), h);218}219220void Ng_RestrictMeshSizeBox (Ng_Mesh * mesh, double * pmin, double * pmax, double h)221{222for (double x = pmin[0]; x < pmax[0]; x += h)223for (double y = pmin[1]; y < pmax[1]; y += h)224for (double z = pmin[2]; z < pmax[2]; z += h)225((Mesh*)mesh) -> RestrictLocalH (Point3d (x, y, z), h);226}227228229// generates volume mesh from surface mesh230Ng_Result Ng_GenerateVolumeMesh (Ng_Mesh * mesh, Ng_Meshing_Parameters * mp)231{232Mesh * m = (Mesh*)mesh;233234235MeshingParameters mparam;236mparam.maxh = mp->maxh;237mparam.meshsizefilename = mp->meshsize_filename;238239m->CalcLocalH();240241MeshVolume (mparam, *m);242RemoveIllegalElements (*m);243OptimizeVolume (mparam, *m);244245return NG_OK;246}247248249250// 2D Meshing Functions:251252253254void Ng_AddPoint_2D (Ng_Mesh * mesh, double * x)255{256Mesh * m = (Mesh*)mesh;257258m->AddPoint (Point3d (x[0], x[1], 0));259}260261void Ng_AddBoundarySeg_2D (Ng_Mesh * mesh, int pi1, int pi2)262{263Mesh * m = (Mesh*)mesh;264265Segment seg;266seg.p1 = pi1;267seg.p2 = pi2;268m->AddSegment (seg);269}270271272int Ng_GetNP_2D (Ng_Mesh * mesh)273{274Mesh * m = (Mesh*)mesh;275return m->GetNP();276}277278int Ng_GetNE_2D (Ng_Mesh * mesh)279{280Mesh * m = (Mesh*)mesh;281return m->GetNSE();282}283284int Ng_GetNSeg_2D (Ng_Mesh * mesh)285{286Mesh * m = (Mesh*)mesh;287return m->GetNSeg();288}289290void Ng_GetPoint_2D (Ng_Mesh * mesh, int num, double * x)291{292Mesh * m = (Mesh*)mesh;293294Point<3> & p = m->Point(num);295x[0] = p(0);296x[1] = p(1);297}298299void Ng_GetElement_2D (Ng_Mesh * mesh, int num, int * pi, int * matnum)300{301const Element2d & el = ((Mesh*)mesh)->SurfaceElement(num);302for (int i = 1; i <= 3; i++)303pi[i-1] = el.PNum(i);304if (matnum)305*matnum = el.GetIndex();306}307308309void Ng_GetSegment_2D (Ng_Mesh * mesh, int num, int * pi, int * matnum)310{311const Segment & seg = ((Mesh*)mesh)->LineSegment(num);312pi[0] = seg.p1;313pi[1] = seg.p2;314315if (matnum)316*matnum = seg.edgenr;317}318319320321322Ng_Geometry_2D * Ng_LoadGeometry_2D (const char * filename)323{324SplineGeometry2d * geom = new SplineGeometry2d();325geom -> Load (filename);326return (Ng_Geometry_2D *)geom;327}328329Ng_Result Ng_GenerateMesh_2D (Ng_Geometry_2D * geom,330Ng_Mesh ** mesh,331Ng_Meshing_Parameters * mp)332{333// use global variable mparam334// MeshingParameters mparam;335mparam.maxh = mp->maxh;336mparam.meshsizefilename = mp->meshsize_filename;337mparam.quad = mp->quad_dominated;338339Mesh * m;340MeshFromSpline2D (*(SplineGeometry2d*)geom, m, mparam);341342cout << m->GetNSE() << " elements, " << m->GetNP() << " points" << endl;343344*mesh = (Ng_Mesh*)m;345return NG_OK;346}347348void Ng_HP_Refinement (Ng_Geometry_2D * geom,349Ng_Mesh * mesh,350int levels)351{352Refinement2d ref(*(SplineGeometry2d*)geom);353HPRefinement (*(Mesh*)mesh, &ref, levels);354}355356void Ng_HP_Refinement (Ng_Geometry_2D * geom,357Ng_Mesh * mesh,358int levels, double parameter)359{360Refinement2d ref(*(SplineGeometry2d*)geom);361HPRefinement (*(Mesh*)mesh, &ref, levels, parameter);362}363364365366367368369370371372373374375376377378ARRAY<STLReadTriangle> readtrias; //only before initstlgeometry379ARRAY<Point<3> > readedges; //only before init stlgeometry380381void Ng_SaveMesh(Ng_Mesh * mesh, const char* filename)382{383((Mesh*)mesh)->Save(filename);384}385386Ng_Mesh * Ng_LoadMesh(const char* filename)387{388Mesh * mesh = new Mesh;389mesh->Load(filename);390return ( (Ng_Mesh*)mesh );391}392393// loads geometry from STL file394Ng_STL_Geometry * Ng_STL_LoadGeometry (const char * filename, int binary)395{396int i;397STLGeometry geom;398STLGeometry* geo;399400if (binary)401{402ifstream ist(filename, ios::binary);403geo = geom.LoadBinary(ist);404}405else406{407ifstream ist(filename);408geo = geom.Load(ist);409}410411readtrias.SetSize(0);412readedges.SetSize(0);413414Point3d p;415Vec3d normal;416double p1[3];417double p2[3];418double p3[3];419double n[3];420421Ng_STL_Geometry * geo2 = Ng_STL_NewGeometry();422423for (i = 1; i <= geo->GetNT(); i++)424{425const STLTriangle& t = geo->GetTriangle(i);426p = geo->GetPoint(t.PNum(1));427p1[0] = p.X(); p1[1] = p.Y(); p1[2] = p.Z();428p = geo->GetPoint(t.PNum(2));429p2[0] = p.X(); p2[1] = p.Y(); p2[2] = p.Z();430p = geo->GetPoint(t.PNum(3));431p3[0] = p.X(); p3[1] = p.Y(); p3[2] = p.Z();432normal = t.Normal();433n[0] = normal.X(); n[1] = normal.Y(); n[2] = normal.Z();434435Ng_STL_AddTriangle(geo2, p1, p2, p3, n);436}437438return geo2;439}440441// generate new STL Geometry442Ng_STL_Geometry * Ng_STL_NewGeometry ()443{444return (Ng_STL_Geometry*)(void*)new STLGeometry;445}446447// after adding triangles (and edges) initialize448Ng_Result Ng_STL_InitSTLGeometry (Ng_STL_Geometry * geom)449{450STLGeometry* geo = (STLGeometry*)geom;451geo->InitSTLGeometry(readtrias);452readtrias.SetSize(0);453454if (readedges.Size() != 0)455{456int i;457/*458for (i = 1; i <= readedges.Size(); i+=2)459{460cout << "e(" << readedges.Get(i) << "," << readedges.Get(i+1) << ")" << endl;461}462*/463geo->AddEdges(readedges);464}465466if (geo->GetStatus() == STLTopology::STL_GOOD || geo->GetStatus() == STLTopology::STL_WARNING) return NG_OK;467return NG_SURFACE_INPUT_ERROR;468}469470// automatically generates edges:471Ng_Result Ng_STL_MakeEdges (Ng_STL_Geometry * geom,472Ng_Mesh* mesh,473Ng_Meshing_Parameters * mp)474{475STLGeometry* stlgeometry = (STLGeometry*)geom;476Mesh* me = (Mesh*)mesh;477478MeshingParameters mparam;479480mparam.maxh = mp->maxh;481mparam.meshsizefilename = mp->meshsize_filename;482483me -> SetGlobalH (mparam.maxh);484me -> SetLocalH (stlgeometry->GetBoundingBox().PMin() - Vec3d(10, 10, 10),485stlgeometry->GetBoundingBox().PMax() + Vec3d(10, 10, 10),4860.3);487488me -> LoadLocalMeshSize (mp->meshsize_filename);489/*490if (mp->meshsize_filename)491{492ifstream infile (mp->meshsize_filename);493if (!infile.good()) return NG_FILE_NOT_FOUND;494me -> LoadLocalMeshSize (infile);495}496*/497498STLMeshing (*stlgeometry, *me);499500stlgeometry->edgesfound = 1;501stlgeometry->surfacemeshed = 0;502stlgeometry->surfaceoptimized = 0;503stlgeometry->volumemeshed = 0;504505return NG_OK;506}507508509// generates mesh, empty mesh be already created.510Ng_Result Ng_STL_GenerateSurfaceMesh (Ng_STL_Geometry * geom,511Ng_Mesh* mesh,512Ng_Meshing_Parameters * mp)513{514STLGeometry* stlgeometry = (STLGeometry*)geom;515Mesh* me = (Mesh*)mesh;516517MeshingParameters mparam;518519mparam.maxh = mp->maxh;520mparam.meshsizefilename = mp->meshsize_filename;521522/*523me -> SetGlobalH (mparam.maxh);524me -> SetLocalH (stlgeometry->GetBoundingBox().PMin() - Vec3d(10, 10, 10),525stlgeometry->GetBoundingBox().PMax() + Vec3d(10, 10, 10),5260.3);527*/528/*529STLMeshing (*stlgeometry, *me);530531stlgeometry->edgesfound = 1;532stlgeometry->surfacemeshed = 0;533stlgeometry->surfaceoptimized = 0;534stlgeometry->volumemeshed = 0;535*/536int retval = STLSurfaceMeshing (*stlgeometry, *me);537if (retval == MESHING3_OK)538{539(*mycout) << "Success !!!!" << endl;540stlgeometry->surfacemeshed = 1;541stlgeometry->surfaceoptimized = 0;542stlgeometry->volumemeshed = 0;543}544else if (retval == MESHING3_OUTERSTEPSEXCEEDED)545{546(*mycout) << "ERROR: Give up because of too many trials. Meshing aborted!" << endl;547}548else if (retval == MESHING3_TERMINATE)549{550(*mycout) << "Meshing Stopped!" << endl;551}552else553{554(*mycout) << "ERROR: Surface meshing not successful. Meshing aborted!" << endl;555}556557558STLSurfaceOptimization (*stlgeometry, *me, mparam);559560return NG_OK;561}562563564// fills STL Geometry565// positive orientation566// normal vector may be null-pointer567void Ng_STL_AddTriangle (Ng_STL_Geometry * geom,568double * p1, double * p2, double * p3, double * nv)569{570Point<3> apts[3];571apts[0] = Point<3>(p1[0],p1[1],p1[2]);572apts[1] = Point<3>(p2[0],p2[1],p2[2]);573apts[2] = Point<3>(p3[0],p3[1],p3[2]);574575Vec<3> n;576if (!nv)577n = Cross (apts[0]-apts[1], apts[0]-apts[2]);578else579n = Vec<3>(nv[0],nv[1],nv[2]);580581readtrias.Append(STLReadTriangle(apts,n));582}583584// add (optional) edges:585void Ng_STL_AddEdge (Ng_STL_Geometry * geom,586double * p1, double * p2)587{588readedges.Append(Point3d(p1[0],p1[1],p1[2]));589readedges.Append(Point3d(p2[0],p2[1],p2[2]));590}591592593594Ng_Meshing_Parameters :: Ng_Meshing_Parameters()595{596maxh = 1000;597fineness = 0.5;598secondorder = 0;599meshsize_filename = 0;600quad_dominated = 0;601}602603604}605606607// compatibility functions:608609namespace netgen610{611612char geomfilename[255];613614void MyError (const char * ch)615{616cerr << ch;617}618619//Destination for messages, errors, ...620void Ng_PrintDest(const char * s)621{622(*mycout) << s << flush;623}624625double GetTime ()626{627return 0;628}629630void ResetTime ()631{632;633}634635void MyBeep (int i)636{637;638}639640}641642643