Clean up user mesh format code

This commit is contained in:
Matthias Hochsteger 2023-10-09 20:41:02 +02:00
parent 1b080b3384
commit 987f0fcc07
25 changed files with 256 additions and 542 deletions

View File

@ -1,8 +1,8 @@
target_sources(nglib PRIVATE target_sources(nglib PRIVATE writeuser.cpp
nginterface.cpp nginterface_v2.cpp nginterface.cpp nginterface_v2.cpp
read_fnf_mesh.cpp readtetmesh.cpp readuser.cpp writeabaqus.cpp writediffpack.cpp read_fnf_mesh.cpp readtetmesh.cpp readuser.cpp writeabaqus.cpp writediffpack.cpp
writedolfin.cpp writeelmer.cpp writefeap.cpp writefluent.cpp writegmsh.cpp writejcm.cpp writedolfin.cpp writeelmer.cpp writefeap.cpp writefluent.cpp writegmsh.cpp writejcm.cpp
writepermas.cpp writetecplot.cpp writetet.cpp writetochnog.cpp writeuser.cpp writepermas.cpp writetecplot.cpp writetet.cpp writetochnog.cpp
wuchemnitz.cpp writegmsh2.cpp writeOpenFOAM15x.cpp rw_cgns.cpp wuchemnitz.cpp writegmsh2.cpp writeOpenFOAM15x.cpp rw_cgns.cpp
) )

View File

@ -11,10 +11,10 @@
#include <meshing.hpp> #include <meshing.hpp>
#include <sys/stat.h> #include <sys/stat.h>
#include "writeuser.hpp"
namespace netgen namespace netgen
{ {
#include "writeuser.hpp"
bool ReadLine (istream & in, string & buf) bool ReadLine (istream & in, string & buf)
{ {
@ -471,4 +471,5 @@ namespace netgen
} }
mesh.ComputeNVertices(); mesh.ComputeNVertices();
} }
static RegisterUserFormat reg_fnf ("Pro/ENGINEER Format", {".fnf"}, ReadFNFFormat, nullopt);
} }

View File

@ -15,6 +15,12 @@
namespace netgen namespace netgen
{ {
extern void ReadTETFormat (Mesh & mesh, const filesystem::path & filename);
extern void ReadFNFFormat (Mesh & mesh, const filesystem::path & filename);
#ifdef NG_CGNS
extern void ReadCGNSMesh (Mesh & mesh, const filesystem::path & filename);
#endif // NG_CGNS
void ReadFile (Mesh & mesh, void ReadFile (Mesh & mesh,
const filesystem::path & filename) const filesystem::path & filename)
{ {
@ -665,9 +671,11 @@ namespace netgen
if ( ext == ".fnf" ) if ( ext == ".fnf" )
ReadFNFFormat (mesh, filename); ReadFNFFormat (mesh, filename);
#ifdef NG_CGNS
// .cgns file - CFD General Notation System // .cgns file - CFD General Notation System
if ( ext == ".cgns" ) if ( ext == ".cgns" )
ReadCGNSMesh (mesh, filename); ReadCGNSMesh (mesh, filename);
#endif // NG_CGNS
if ( ext == ".stl" || ext == ".stlb" ) if ( ext == ".stl" || ext == ".stlb" )
{ {
@ -696,5 +704,23 @@ namespace netgen
} }
} }
void ReadUserFormat(Mesh & mesh, const filesystem::path & filename, const string & format)
{
if(format == "")
return ReadFile(mesh, filename);
if(!UserFormatRegister::HaveFormat(format))
throw Exception("Unknown format: " + format);
const auto & entry = UserFormatRegister::Get(format);
if(!entry.read)
throw Exception("Reading format " + format + " is not implemented");
(*entry.read)(mesh, filename);
}
static RegisterUserFormat reg_uni ("Universial Format", {".unv"}, ReadFile, nullopt);
static RegisterUserFormat reg_olaf ("Olaf Format", {".emt"}, ReadFile, nullopt);
} }

View File

@ -808,32 +808,9 @@ namespace netgen
cg_close(fn); cg_close(fn);
} }
} static RegisterUserFormat reg_cgns ("CGNS Format", {".cgns"},
static_cast<void(*)(Mesh &, const filesystem::path&)>(&ReadCGNSMesh),
#else // NG_CGNS static_cast<void(*)(const Mesh &, const filesystem::path&)>(&WriteCGNSMesh));
namespace netgen
{
void ReadCGNSMesh (Mesh & mesh, const filesystem::path & filename)
{
PrintMessage(1, "Could not import CGNS mesh: Netgen was built without CGNS support");
}
tuple<shared_ptr<Mesh>, vector<string>, vector<Array<double>>, vector<int>> ReadCGNSFile(const filesystem::path & filename, int base)
{
throw Exception("Netgen was built without CGNS support");
}
void WriteCGNSMesh (const Mesh & mesh, const filesystem::path & filename)
{
PrintMessage(1, "Could not write CGNS mesh: Netgen was built without CGNS support");
}
void WriteCGNSFile(shared_ptr<Mesh> mesh, const filesystem::path & filename, vector<string> fields, vector<Array<double>> values, vector<int> locations)
{
throw Exception("Netgen was built without CGNS support");
}
} }
#endif // NG_CGNS #endif // NG_CGNS

View File

@ -31,10 +31,10 @@
#include <sys/stat.h> #include <sys/stat.h>
#include "../general/gzstream.h" #include "../general/gzstream.h"
#include "writeuser.hpp"
namespace netgen namespace netgen
{ {
#include "writeuser.hpp"
extern MeshingParameters mparam; extern MeshingParameters mparam;
@ -757,5 +757,11 @@ namespace netgen
cout << "Error in OpenFOAM 1.5+ Export.... Aborted!\n"; cout << "Error in OpenFOAM 1.5+ Export.... Aborted!\n";
} }
} }
void WriteOpenFOAM15xFormatCompressed (const Mesh & mesh, const filesystem::path & dirname) { WriteOpenFOAM15xFormat(mesh, dirname, true); }
void WriteOpenFOAM15xFormatUncompressed (const Mesh & mesh, const filesystem::path & dirname) { WriteOpenFOAM15xFormat(mesh, dirname, false); }
static RegisterUserFormat reg_openfoam ("OpenFOAM 1.5+ Format", {"*"}, nullopt, WriteOpenFOAM15xFormatUncompressed);
static RegisterUserFormat reg_openfoam_compressed ("OpenFOAM 1.5+ Compressed", {"*"}, nullopt, WriteOpenFOAM15xFormatCompressed);
} }

View File

@ -10,9 +10,10 @@
#include <csg.hpp> #include <csg.hpp>
#include <meshing.hpp> #include <meshing.hpp>
#include "writeuser.hpp"
namespace netgen namespace netgen
{ {
#include "writeuser.hpp"
@ -229,4 +230,5 @@ void WriteAbaqusFormat (const Mesh & mesh,
cout << "done" << endl; cout << "done" << endl;
} }
static RegisterUserFormat reg_abaqus ("Abaqus Format", {".mesh"}, nullopt, WriteAbaqusFormat);
} }

View File

@ -13,14 +13,13 @@
#include <csg.hpp> #include <csg.hpp>
#include <meshing.hpp> #include <meshing.hpp>
#include "writeuser.hpp"
namespace netgen namespace netgen
{ {
#include "writeuser.hpp"
void WriteDiffPackFormat (const Mesh & mesh, void WriteDiffPackFormat (const Mesh & mesh,
const NetgenGeometry & geom,
const filesystem::path & filename) const filesystem::path & filename)
{ {
// double scale = globflags.GetNumFlag ("scale", 1); // double scale = globflags.GetNumFlag ("scale", 1);
@ -322,4 +321,5 @@ void WriteDiffPackFormat (const Mesh & mesh,
} }
} }
} }
static RegisterUserFormat reg_surface("DIFFPACK Format", {".mesh"}, nullopt, WriteDiffPackFormat);
} }

View File

@ -197,4 +197,6 @@ void WriteElmerFormat (const Mesh &mesh,
outfile_h << tmap[eltype] << " " << count << "\n"; outfile_h << tmap[eltype] << " " << count << "\n";
} }
static RegisterUserFormat reg_elmer ("Elmer Format", {"*"}, nullopt, WriteElmerFormat);
} }

View File

@ -13,12 +13,13 @@
#include <csg.hpp> #include <csg.hpp>
#include <meshing.hpp> #include <meshing.hpp>
#include "writeuser.hpp"
namespace netgen namespace netgen
{ {
extern MeshingParameters mparam; extern MeshingParameters mparam;
#include "writeuser.hpp"
void WriteFEAPFormat (const Mesh & mesh, void WriteFEAPFormat (const Mesh & mesh,
@ -219,4 +220,5 @@ void WriteFEAPFormat (const Mesh & mesh,
cout << "done" << endl; cout << "done" << endl;
} }
static RegisterUserFormat reg_feap ("FEAP Format", {".mesh"}, nullopt, WriteFEAPFormat);
} }

View File

@ -10,11 +10,10 @@
#include <csg.hpp> #include <csg.hpp>
#include <meshing.hpp> #include <meshing.hpp>
namespace netgen
{
#include "writeuser.hpp" #include "writeuser.hpp"
namespace netgen
{
void WriteFluentFormat (const Mesh & mesh, void WriteFluentFormat (const Mesh & mesh,
@ -190,4 +189,5 @@ void WriteFluentFormat (const Mesh & mesh,
cout << "done" << endl; cout << "done" << endl;
} }
static RegisterUserFormat reg_fluent ("Fluent Format", {".mesh"}, nullopt, WriteFluentFormat);
} }

View File

@ -17,10 +17,10 @@
#include <linalg.hpp> #include <linalg.hpp>
#include <csg.hpp> #include <csg.hpp>
#include <meshing.hpp> #include <meshing.hpp>
#include "writeuser.hpp"
namespace netgen namespace netgen
{ {
#include "writeuser.hpp"
extern MeshingParameters mparam; extern MeshingParameters mparam;
@ -31,7 +31,6 @@ namespace netgen
*/ */
void WriteGmshFormat (const Mesh & mesh, void WriteGmshFormat (const Mesh & mesh,
const NetgenGeometry & geom,
const filesystem::path & filename) const filesystem::path & filename)
{ {
ofstream outfile (filename); ofstream outfile (filename);
@ -196,6 +195,7 @@ void WriteGmshFormat (const Mesh & mesh,
} }
static RegisterUserFormat reg_gmsh ("Gmsh Format", {".gmsh"}, nullopt, WriteGmshFormat);
} }

View File

@ -20,10 +20,10 @@
#include <linalg.hpp> #include <linalg.hpp>
#include <csg.hpp> #include <csg.hpp>
#include <meshing.hpp> #include <meshing.hpp>
#include "writeuser.hpp"
namespace netgen namespace netgen
{ {
#include "writeuser.hpp"
extern MeshingParameters mparam; extern MeshingParameters mparam;
@ -48,7 +48,6 @@ namespace netgen
* *
*/ */
void WriteGmsh2Format (const Mesh & mesh, void WriteGmsh2Format (const Mesh & mesh,
const NetgenGeometry & geom,
const filesystem::path & filename) const filesystem::path & filename)
{ {
ofstream outfile (filename); ofstream outfile (filename);
@ -258,6 +257,7 @@ namespace netgen
cout << " Invalid element type for Gmsh v2.xx Export Format !\n"; cout << " Invalid element type for Gmsh v2.xx Export Format !\n";
} }
} // End: WriteGmsh2Format } // End: WriteGmsh2Format
static RegisterUserFormat reg_gmsh2 ("Gmsh2 Format", {".gmsh2"}, nullopt, WriteGmsh2Format);
} // End: namespace netgen } // End: namespace netgen

View File

@ -11,12 +11,12 @@
#include <meshing.hpp> #include <meshing.hpp>
#include <sys/stat.h> #include <sys/stat.h>
namespace netgen
{
#include "writeuser.hpp" #include "writeuser.hpp"
namespace netgen
{
void WriteJCMFormat (const Mesh & mesh, void WriteJCMFormat (const Mesh & mesh,
const NetgenGeometry & geom,
const filesystem::path & filename) const filesystem::path & filename)
{ {
if (mesh.GetDimension() != 3) if (mesh.GetDimension() != 3)
@ -426,5 +426,6 @@ void WriteJCMFormat (const Mesh & mesh,
cout << " JCMwave grid file written." << endl; cout << " JCMwave grid file written." << endl;
} }
static RegisterUserFormat reg_jcmwave ("JCMwave Format", {".jcm"}, nullopt, WriteJCMFormat);
} }

View File

@ -12,14 +12,15 @@
#include <string> #include <string>
using namespace std;
#include "writeuser.hpp" #include "writeuser.hpp"
using namespace std;
namespace netgen namespace netgen
{ {
// Forward declarations (don't know, where to define them, sorry) // Forward declarations (don't know, where to define them, sorry)
int addComponent(string &strComp, string &strSitu, ofstream &out); int addComponent(string &strComp, string &strSitu, ofstream &out);
void WritePermasFormat (const Mesh &mesh, const filesystem::path &filename);
// This should be the new function to export a PERMAS file // This should be the new function to export a PERMAS file
void WritePermasFormat (const Mesh &mesh, const filesystem::path &filename, void WritePermasFormat (const Mesh &mesh, const filesystem::path &filename,
@ -205,4 +206,5 @@ namespace netgen
return 0; return 0;
} }
static RegisterUserFormat reg_permas ("Permas Format", {".mesh"}, nullopt, static_cast<void(*)(const Mesh &, const filesystem::path&)>(&WritePermasFormat));
} }

View File

@ -9,16 +9,19 @@
#include <csg.hpp> #include <csg.hpp>
#include <meshing.hpp> #include <meshing.hpp>
#include "writeuser.hpp"
namespace netgen namespace netgen
{ {
#include "writeuser.hpp"
void WriteTecPlotFormat (const Mesh & mesh, void WriteTecPlotFormat (const Mesh & mesh,
const CSGeometry & geom, const filesystem::path & filename)
const string & filename)
{ {
auto geom = dynamic_pointer_cast<CSGeometry>(mesh.GetGeometry());
if(geom == nullptr)
throw Exception("TecPlot format requires a CSGeometry");
INDEX i; INDEX i;
int j, k, e, z; int j, k, e, z;
Vec<3> n; Vec<3> n;
@ -30,7 +33,7 @@ void WriteTecPlotFormat (const Mesh & mesh,
NgArray<int> sn(np); NgArray<int> sn(np);
ofstream outfile(filename); ofstream outfile(filename);
outfile << "TITLE=\" " << filename << "\"" << endl; outfile << "TITLE=\" " << filename.string() << "\"" << endl;
// fill hashtable // fill hashtable
@ -56,7 +59,7 @@ void WriteTecPlotFormat (const Mesh & mesh,
} }
for (j = 1; j <= geom.GetNSurf(); j++) /* Flaeche Nummer j */ for (j = 1; j <= geom->GetNSurf(); j++) /* Flaeche Nummer j */
{ {
for (i = 1; i <= np; i++) for (i = 1; i <= np; i++)
sn.Elem(i) = 0; sn.Elem(i) = 0;
@ -85,7 +88,7 @@ void WriteTecPlotFormat (const Mesh & mesh,
for (i = 1; i <= np; i++) for (i = 1; i <= np; i++)
if (sn.Elem(i) != 0) if (sn.Elem(i) != 0)
{ {
n = geom.GetSurface(j) -> GetNormalVector ( mesh.Point(i) ); n = geom->GetSurface(j) -> GetNormalVector ( mesh.Point(i) );
outfile << mesh.Point(i)(0) << " " /* Knoten Koordinaten */ outfile << mesh.Point(i)(0) << " " /* Knoten Koordinaten */
<< mesh.Point(i)(1) << " " << mesh.Point(i)(1) << " "
@ -123,5 +126,6 @@ void WriteTecPlotFormat (const Mesh & mesh,
} }
} }
static RegisterUserFormat reg_tecplot ("TecPlot Format", {".mesh"}, nullopt, WriteTecPlotFormat);
} }

View File

@ -6,21 +6,20 @@
#include <csg.hpp> #include <csg.hpp>
#include <acisgeom.hpp> #include <acisgeom.hpp>
#include <meshing.hpp> #include <meshing.hpp>
#include "writeuser.hpp"
namespace netgen namespace netgen
{ {
extern void ReadTETFormat (Mesh & mesh, const filesystem::path & filename);
#include "writeuser.hpp"
void WriteTETFormat (const Mesh & mesh, void WriteTETFormat (const Mesh & mesh,
const string & filename)//, const string& problemType ) const filesystem::path & filename)//, const string& problemType )
{ {
string problemType = ""; string problemType = "";
if(!mesh.PureTetMesh()) if(!mesh.PureTetMesh())
throw NgException("Can only export pure tet mesh in this format"); throw NgException("Can only export pure tet mesh in this format");
cout << "starting .tet export to file " << filename << endl; cout << "starting .tet export to file " << filename.string() << endl;
NgArray<int> point_ids,edge_ids,face_ids; NgArray<int> point_ids,edge_ids,face_ids;
@ -1095,4 +1094,5 @@ namespace netgen
cout << ".tet export done" << endl; cout << ".tet export done" << endl;
} }
static RegisterUserFormat reg_tet ("TET Format", {".tet"}, ReadTETFormat, WriteTETFormat);
} }

View File

@ -13,10 +13,10 @@
#include <csg.hpp> #include <csg.hpp>
#include <meshing.hpp> #include <meshing.hpp>
#include "writeuser.hpp"
namespace netgen namespace netgen
{ {
#include "writeuser.hpp"
void WriteTochnogFormat (const Mesh & mesh, void WriteTochnogFormat (const Mesh & mesh,
@ -105,4 +105,5 @@ void WriteTochnogFormat (const Mesh & mesh,
cout << "done" << endl; cout << "done" << endl;
} }
static RegisterUserFormat reg_tochnog ("Tochnog Format", {".mesh"}, nullopt, WriteTochnogFormat);
} }

View File

@ -18,155 +18,43 @@ namespace netgen
{ {
extern MeshingParameters mparam; extern MeshingParameters mparam;
Array<UserFormatRegister::UserFormatEntry> UserFormatRegister::entries;
std::map<string, int> UserFormatRegister::format_to_entry_index;
void RegisterUserFormats (NgArray<const char*> & names, void RegisterUserFormats (NgArray<const char*> & names,
NgArray<const char*> & extensions) NgArray<const char*> & extensions)
{ {
const char *types[] = for (const auto & entry : UserFormatRegister::entries)
{ {
"Neutral Format", ".mesh", names.Append (entry.format.c_str());
"Surface Mesh Format", ".mesh" , extensions.Append (entry.extensions[0].c_str());
"DIFFPACK Format", ".mesh",
"TecPlot Format", ".mesh",
"Tochnog Format", ".mesh",
"Abaqus Format", ".mesh",
"Fluent Format", ".mesh",
"Permas Format", ".mesh",
"FEAP Format", ".mesh",
"Elmer Format", "*",
"STL Format", ".stl",
"STL Extended Format", ".stl",
"VRML Format", ".*",
"Gmsh Format", ".gmsh",
"Gmsh2 Format", ".gmsh2",
"OpenFOAM 1.5+ Format", "*",
"OpenFOAM 1.5+ Compressed", "*",
"JCMwave Format", ".jcm",
"TET Format", ".tet",
"CGNS Format", ".cgns",
// { "Chemnitz Format" },
0
};
for (int i = 0; types[2*i]; i++)
{
names.Append (types[2*i]);
extensions.Append (types[2*i+1]);
} }
} }
bool WriteUserFormat (const string & format,
bool WriteUserFormat (const filesystem::path & format,
const Mesh & mesh, const Mesh & mesh,
const filesystem::path & filename) const filesystem::path & filename)
{ {
// cout << "write user &hgeom = " << &hgeom << endl; if(!UserFormatRegister::HaveFormat(format))
// const CSGeometry & geom = *dynamic_cast<const CSGeometry*> (&hgeom); return true;
const CSGeometry & geom = *dynamic_pointer_cast<CSGeometry> (mesh.GetGeometry());
PrintMessage (1, "Export mesh to file ", filename, const auto & entry = UserFormatRegister::Get(format);
", format is ", format); if(!entry.write)
return true;
if (format == "Neutral Format") (*entry.write)(mesh, filename);
WriteNeutralFormat (mesh, geom, filename); return false;
else if (format == "Surface Mesh Format")
WriteSurfaceFormat (mesh, filename);
else if (format == "DIFFPACK Format")
WriteDiffPackFormat (mesh, geom, filename);
else if (format == "Tochnog Format")
WriteTochnogFormat (mesh, filename);
else if (format == "TecPlot Format")
cerr << "ERROR: TecPlot format currently out of order" << endl;
// WriteTecPlotFormat (mesh, geom, filename);
else if (format == "Abaqus Format")
WriteAbaqusFormat (mesh, filename);
else if (format == "Fluent Format")
WriteFluentFormat (mesh, filename);
else if (format == "Permas Format")
WritePermasFormat (mesh, filename);
else if (format == "FEAP Format")
WriteFEAPFormat (mesh, filename);
else if (format == "Elmer Format")
WriteElmerFormat (mesh, filename);
else if (format == "STL Format")
WriteSTLFormat (mesh, filename);
// Philippose - 16 August 2010
// Added additional STL Export in which
// each face of the geometry is treated
// as a separate "solid" entity
else if (format == "STL Extended Format")
WriteSTLExtFormat (mesh, filename);
else if (format == "VRML Format")
WriteVRMLFormat (mesh, 1, filename);
else if (format == "Fepp Format")
WriteFEPPFormat (mesh, geom, filename);
else if (format == "EdgeElement Format")
WriteEdgeElementFormat (mesh, geom, filename);
else if (format == "Chemnitz Format")
WriteUserChemnitz (mesh, filename);
else if (format == "Gmsh Format")
WriteGmshFormat (mesh, geom, filename);
// Philippose - 29/01/2009
// Added Gmsh v2.xx Mesh export capability
else if (format == "Gmsh2 Format")
WriteGmsh2Format (mesh, geom, filename);
// Philippose - 25/10/2009
// Added OpenFOAM 1.5+ Mesh export capability
else if (format == "OpenFOAM 1.5+ Format")
WriteOpenFOAM15xFormat (mesh, filename, false);
else if (format == "OpenFOAM 1.5+ Compressed")
WriteOpenFOAM15xFormat (mesh, filename, true);
else if (format == "JCMwave Format")
WriteJCMFormat (mesh, geom, filename);
#ifdef OLIVER
else if (format == "TET Format")
WriteTETFormat( mesh, filename);//, "High Frequency" );
#endif
else if (format == "CGNS Format")
WriteCGNSMesh( mesh, filename);
else
{
return 1;
}
return 0;
} }
/* /*
* Neutral mesh format * Neutral mesh format
* points, elements, surface elements * points, elements, surface elements
*/ */
void WriteNeutralFormat (const Mesh & mesh, void WriteNeutralFormat (const Mesh & mesh,
const NetgenGeometry & geom,
const filesystem::path & filename) const filesystem::path & filename)
{ {
cout << "write neutral, new" << endl; cout << "write neutral, new" << endl;
@ -631,6 +519,16 @@ void WriteVRMLFormat (const Mesh & mesh,
} }
void WriteVRMLFormatLineset (const Mesh & mesh, const filesystem::path & filename)
{
WriteVRMLFormat(mesh, false, filename);
}
void WriteVRMLFormatFaceset (const Mesh & mesh, const filesystem::path & filename)
{
WriteVRMLFormat(mesh, true, filename);
}
@ -640,7 +538,6 @@ void WriteVRMLFormat (const Mesh & mesh,
* FEPP .. a finite element package developed at University Linz, Austria * FEPP .. a finite element package developed at University Linz, Austria
*/ */
void WriteFEPPFormat (const Mesh & mesh, void WriteFEPPFormat (const Mesh & mesh,
const NetgenGeometry & geom,
const filesystem::path & filename) const filesystem::path & filename)
{ {
@ -771,7 +668,6 @@ void WriteFEPPFormat (const Mesh & mesh,
*/ */
void WriteEdgeElementFormat (const Mesh & mesh, void WriteEdgeElementFormat (const Mesh & mesh,
const NetgenGeometry & geom,
const filesystem::path & filename) const filesystem::path & filename)
{ {
cout << "write edge element format" << endl; cout << "write edge element format" << endl;
@ -898,169 +794,14 @@ void WriteEdgeElementFormat (const Mesh & mesh,
} }
} }
static RegisterUserFormat reg_neutral("Neutral Format", {".mesh"}, ReadFile, WriteNeutralFormat);
static RegisterUserFormat reg_surface("Surface Mesh Format", {".mesh", ".surf"} ,ReadFile, WriteSurfaceFormat);
static RegisterUserFormat reg_stl ("STL Format", {".stl", ".stlb"}, ReadFile, WriteSTLFormat);
static RegisterUserFormat reg_stlx ("STL Extended Format", {".stl", ".stlb"}, nullopt, WriteSTLExtFormat);
static RegisterUserFormat reg_vrml ("VRML Format", {".*"}, nullopt, WriteVRMLFormatLineset);
static RegisterUserFormat reg_vrml_faces ("VRML Format Faces", {".*"}, nullopt, WriteVRMLFormatFaceset);
static RegisterUserFormat reg_fepp ("Fepp Format", {"*"}, nullopt, WriteFEPPFormat);
static RegisterUserFormat reg_edgeelement ("EdgeElement Format", {"*"}, nullopt, WriteEdgeElementFormat);
#ifdef OLDSTYLE_WRITE
void WriteFile (int typ,
const Mesh & mesh,
const CSGeometry & geom,
const filesystem::path & filename,
const filesystem::path & geomfile,
double h)
{
int inverttets = mparam.inverttets;
int invertsurf = mparam.inverttrigs;
if (typ == WRITE_EDGEELEMENT)
{
// write edge element file
// Peter Harscher, ETHZ
cout << "Write Edge-Element Format" << endl;
ofstream outfile (filename);
int i, j;
int ned;
// hash table representing edges;
INDEX_2_HASHTABLE<int> edgeht(mesh.GetNP());
// list of edges
NgArray<INDEX_2> edgelist;
// edge (point) on boundary ?
NgBitArray bedge, bpoint(mesh.GetNP());
static int eledges[6][2] = { { 1, 2 } , { 1, 3 } , { 1, 4 },
{ 2, 3 } , { 2, 4 } , { 3, 4 } };
// fill hashtable (point1, point2) ----> edgenr
for (i = 1; i <= mesh.GetNE(); i++)
{
const Element & el = mesh.VolumeElement (i);
INDEX_2 edge;
for (j = 1; j <= 6; j++)
{
edge.I1() = el.PNum (eledges[j-1][0]);
edge.I2() = el.PNum (eledges[j-1][1]);
edge.Sort();
if (!edgeht.Used (edge))
{
edgelist.Append (edge);
edgeht.Set (edge, edgelist.Size());
}
}
}
// set bedges, bpoints
bedge.SetSize (edgelist.Size());
bedge.Clear();
bpoint.Clear();
for (i = 1; i <= mesh.GetNSE(); i++)
{
const Element2d & sel = mesh.SurfaceElement(i);
for (j = 1; j <= 3; j++)
{
bpoint.Set (sel.PNum(j));
INDEX_2 edge;
edge.I1() = sel.PNum(j);
edge.I2() = sel.PNum(j%3+1);
edge.Sort();
bedge.Set (edgeht.Get (edge));
}
}
outfile << mesh.GetNE() << endl;
// write element ---> point
for (i = 1; i <= mesh.GetNE(); i++)
{
const Element & el = mesh.VolumeElement(i);
outfile.width(8);
outfile << i;
for (j = 1; j <= 4; j++)
{
outfile.width(8);
outfile << el.PNum(j);
}
outfile << endl;
}
// write element ---> edge
for (i = 1; i <= mesh.GetNE(); i++)
{
const Element & el = mesh.VolumeElement (i);
INDEX_2 edge;
for (j = 1; j <= 6; j++)
{
edge.I1() = el.PNum (eledges[j-1][0]);
edge.I2() = el.PNum (eledges[j-1][1]);
edge.Sort();
outfile.width(8);
outfile << edgeht.Get (edge);
}
outfile << endl;
}
// write points
outfile << mesh.GetNP() << endl;
outfile.precision (6);
for (i = 1; i <= mesh.GetNP(); i++)
{
const Point3d & p = mesh.Point(i);
for (j = 1; j <= 3; j++)
{
outfile.width(8);
outfile << p.X(j);
}
outfile << " "
<< (bpoint.Test(i) ? "1" : 0) << endl;
}
// write edges
outfile << edgelist.Size() << endl;
for (i = 1; i <= edgelist.Size(); i++)
{
outfile.width(8);
outfile << edgelist.Get(i).I1();
outfile.width(8);
outfile << edgelist.Get(i).I2();
outfile << " "
<< (bedge.Test(i) ? "1" : "0") << endl;
}
}
}
#endif
} }

View File

@ -7,176 +7,73 @@
/* Date: 10. Dec. 97 */ /* Date: 10. Dec. 97 */
/**************************************************************************/ /**************************************************************************/
#include <filesystem>
#include <functional>
#include <optional>
#include <meshing.hpp>
namespace netgen { namespace netgen {
DLL_HEADER extern using namespace std::filesystem;
void WriteFile (int typ,
const Mesh & mesh, typedef std::function<void (const Mesh & mesh, const filesystem::path & filename)> FWrite;
const NetgenGeometry & geom, typedef std::function<void (Mesh & mesh, const filesystem::path & filename)> FRead;
const filesystem::path & filename, typedef std::function<bool (const filesystem::path & filename)> FTest;
const filesystem::path & geomfile = "",
double h = 0); struct UserFormatRegister {
struct UserFormatEntry {
string format;
Array<string> extensions;
optional<FRead> read;
optional<FWrite> write;
};
DLL_HEADER static Array<UserFormatEntry> entries;
DLL_HEADER static std::map<string, int> format_to_entry_index;
static void Register(UserFormatEntry && entry) {
format_to_entry_index[entry.format] = entries.Size();
entries.Append( std::move(entry) );
}
static const bool HaveFormat(string format) {
return format_to_entry_index.count(format) > 0;
}
static const UserFormatEntry & Get(string format) {
return entries[format_to_entry_index[format]];
}
template<typename TFunc>
static void IterateFormats(TFunc func, bool need_read=false, bool need_write=false) {
Array<string> import_formats;
for(const auto & e: entries)
if((!need_read || e.read) && (!need_write || e.write))
import_formats.Append(e.format);
QuickSort(import_formats);
for(auto format : import_formats)
func(entries[format_to_entry_index[format]]);
}
};
struct RegisterUserFormat {
RegisterUserFormat(string format, Array<string> extensions, optional<FRead> read, optional<FWrite> write, FTest ftest = [](const filesystem::path & ){return true;})
{
UserFormatRegister::Register({format, std::move(extensions), std::move(read), std::move(write)});
}
};
DLL_HEADER void ReadFile(Mesh & mesh, const filesystem::path & filename);
DLL_HEADER void ReadUserFormat(Mesh & mesh, const filesystem::path & filename, const string & format = "");
extern bool DLL_HEADER WriteUserFormat (const string & format,
DLL_HEADER extern const Mesh & mesh,
void ReadFile (Mesh & mesh, const filesystem::path & filename);
const filesystem::path & filename);
extern
void WriteNeutralFormat (const Mesh & mesh,
const NetgenGeometry & geom,
const filesystem::path & filename);
extern
void WriteSurfaceFormat (const Mesh & mesh,
const filesystem::path & filename);
extern
void WriteSTLFormat (const Mesh & mesh,
const filesystem::path & filename);
// Philippose - 16 August 2010
// Added the STL Extended format in which
// each face of the geometry is treated as
// a separate "solid" entity in the STL file
extern
void WriteSTLExtFormat (const Mesh & mesh,
const filesystem::path & filename);
extern
void WriteVRMLFormat (const Mesh & mesh,
bool faces,
const filesystem::path & filename);
extern
void WriteFEPPFormat (const Mesh & mesh,
const NetgenGeometry & geom,
const filesystem::path & filename);
extern
void WriteGmshFormat (const Mesh & mesh,
const NetgenGeometry & geom,
const filesystem::path & filename);
// Philippose - 29/01/2009
// Added GMSH v2.xx Mesh Export support
void WriteGmsh2Format (const Mesh & mesh,
const NetgenGeometry & geom,
const filesystem::path & filename);
// Philippose - 25/10/2009
// Added OpenFOAM 1.5+ Mesh Export support
extern
void WriteOpenFOAM15xFormat (const Mesh & mesh,
const filesystem::path & casename,
const bool compressed);
extern
void WriteUserChemnitz (const Mesh & mesh,
const filesystem::path & filename);
extern
void WriteJCMFormat (const Mesh & mesh,
const NetgenGeometry & geom,
const filesystem::path & filename);
extern
void WriteDiffPackFormat (const Mesh & mesh,
const NetgenGeometry & geom,
const filesystem::path & filename);
extern
void WriteTochnogFormat (const Mesh & mesh,
const filesystem::path & filename);
extern
void WriteTecPlotFormat (const Mesh & mesh,
const NetgenGeometry & geom,
const filesystem::path & filename);
extern
void WriteAbaqusFormat (const Mesh & mesh,
const filesystem::path & filename);
extern
void WriteFluentFormat (const Mesh & mesh,
const filesystem::path & filename);
extern
void WritePermasFormat (const Mesh & mesh,
const filesystem::path & filename);
extern
void WriteFEAPFormat (const Mesh & mesh,
const filesystem::path & filename);
extern
void WriteElmerFormat (const Mesh & mesh,
const filesystem::path & filename);
extern
void WriteEdgeElementFormat (const Mesh & mesh,
const NetgenGeometry & geom,
const filesystem::path & filename);
#ifdef OLIVER
extern
void WriteTETFormat (const Mesh & mesh,
const filesystem::path & filename);
#endif
extern void ReadTETFormat (Mesh & mesh,
const filesystem::path & filename);
extern void ReadFNFFormat (Mesh & mesh,
const filesystem::path & filename);
extern void DLL_HEADER ReadCGNSMesh (Mesh & mesh,
const filesystem::path & filename);
extern void DLL_HEADER WriteCGNSMesh (const Mesh & mesh,
const filesystem::path & filename);
// read/write mesh and solutions from CGNS file
extern tuple<shared_ptr<Mesh>, vector<string>, vector<Array<double>>, vector<int>>
DLL_HEADER ReadCGNSFile(const filesystem::path & filename, int base);
extern void DLL_HEADER WriteCGNSFile(shared_ptr<Mesh> mesh, const filesystem::path & filename, vector<string> fields,
vector<Array<double>> values, vector<int> locations);
void WriteDolfinFormat (const Mesh & mesh,
const filesystem::path & filename);
extern void DLL_HEADER RegisterUserFormats (NgArray<const char*> & names, extern void DLL_HEADER RegisterUserFormats (NgArray<const char*> & names,
NgArray<const char*> & extensions); NgArray<const char*> & extensions);
extern bool DLL_HEADER WriteUserFormat (const filesystem::path & format,
const Mesh & mesh,
// const NetgenGeometry & geom,
const filesystem::path & filename);
} }
#endif #endif

View File

@ -9,6 +9,8 @@
#include <csg.hpp> #include <csg.hpp>
#include <meshing.hpp> #include <meshing.hpp>
#include "writeuser.hpp"
namespace netgen namespace netgen
{ {
@ -316,4 +318,5 @@ namespace netgen
WriteFile (outfile); WriteFile (outfile);
cout << "Wrote Chemnitz standard file" << endl; cout << "Wrote Chemnitz standard file" << endl;
} }
static RegisterUserFormat reg_chemnitz ("Chemnitz Format", {"*"}, nullopt, WriteUserChemnitz );
} }

View File

@ -79,6 +79,10 @@ namespace netgen
extern bool netgen_executable_started; extern bool netgen_executable_started;
extern shared_ptr<NetgenGeometry> ng_geometry; extern shared_ptr<NetgenGeometry> ng_geometry;
extern void Optimize2d (Mesh & mesh, MeshingParameters & mp, int faceindex=0); extern void Optimize2d (Mesh & mesh, MeshingParameters & mp, int faceindex=0);
#ifdef NG_CGNS
extern tuple<shared_ptr<Mesh>, vector<string>, vector<Array<double>>, vector<int>> ReadCGNSFile(const filesystem::path & filename, int base);
extern void WriteCGNSFile(shared_ptr<Mesh> mesh, const filesystem::path & filename, vector<string> fields, vector<Array<double>> values, vector<int> locations);
#endif // NG_CGNS
} }
@ -725,6 +729,20 @@ DLL_HEADER void ExportNetgenMeshing(py::module &m)
ExportArray<MeshPoint,PointIndex>(m); ExportArray<MeshPoint,PointIndex>(m);
ExportArray<FaceDescriptor>(m); ExportArray<FaceDescriptor>(m);
string export_docu = "Export mesh to other file format. Supported formats are:\n";
Array<string> export_formats;
for(auto & e : UserFormatRegister::entries)
if(e.write) {
string s = '\t'+e.format+"\t("+e.extensions[0];
for(auto & ext : e.extensions.Range(1, e.extensions.Size()))
s += ", "+ext;
s += ")\n";
export_formats.Append(s);
}
QuickSort(export_formats);
for(const auto & s : export_formats)
export_docu += s;
py::implicitly_convertible< int, PointIndex>(); py::implicitly_convertible< int, PointIndex>();
py::class_<NetgenGeometry, shared_ptr<NetgenGeometry>> (m, "NetgenGeometry", py::dynamic_attr()) py::class_<NetgenGeometry, shared_ptr<NetgenGeometry>> (m, "NetgenGeometry", py::dynamic_attr())
@ -932,18 +950,11 @@ DLL_HEADER void ExportNetgenMeshing(py::module &m)
.def("Export", .def("Export",
[] (Mesh & self, string filename, string format) [] (Mesh & self, string filename, string format)
{ {
if (WriteUserFormat (format, self, /* *self.GetGeometry(), */ filename)) if (WriteUserFormat (format, self, filename))
{ throw Exception ("Nothing known about format"+format);
string err = string ("nothing known about format")+format;
NgArray<const char*> names, extensions;
RegisterUserFormats (names, extensions);
err += "\navailable formats are:\n";
for (auto name : names)
err += string("'") + name + "'\n";
throw NgException (err);
}
}, },
py::arg("filename"), py::arg("format"),py::call_guard<py::gil_scoped_release>()) py::arg("filename"), py::arg("format"), export_docu.c_str(),
py::call_guard<py::gil_scoped_release>())
.def_property("dim", &Mesh::GetDimension, &Mesh::SetDimension) .def_property("dim", &Mesh::GetDimension, &Mesh::SetDimension)
@ -1672,20 +1683,21 @@ project_boundaries : Optional[str] = None
}) })
; ;
m.def("ImportMesh", [](const string& filename) string import_docu = "Import mesh from other file format. Leaving format parameter empty guesses based on file extension.\nSupported formats are:\n";
UserFormatRegister::IterateFormats([&](auto & e) {
string s = '\t'+e.format+"\t("+e.extensions[0];
for(auto & ext : e.extensions.Range(1, e.extensions.Size()))
s += ", "+ext;
s += ")\n";
import_docu += s;
}, true);
m.def("ImportMesh", [](const string& filename, const string & format)
{ {
auto mesh = make_shared<Mesh>(); auto mesh = make_shared<Mesh>();
ReadFile(*mesh, filename); ReadUserFormat(*mesh, filename, format);
return mesh; return mesh;
}, py::arg("filename"), }, py::arg("filename"), py::arg("format")="", import_docu.c_str());
R"delimiter(Import mesh from other file format, supported file formats are:
Neutral format (*.mesh, *.emt)
Surface file (*.surf)
Universal format (*.unv)
Olaf format (*.emt)
Tet format (*.tet)
Pro/ENGINEER format (*.fnf)
)delimiter");
py::enum_<MESHING_STEP>(m,"MeshingStep") py::enum_<MESHING_STEP>(m,"MeshingStep")
.value("ANALYSE", MESHCONST_ANALYSE) .value("ANALYSE", MESHCONST_ANALYSE)
.value("MESHEDGES", MESHCONST_MESHEDGES) .value("MESHEDGES", MESHCONST_MESHEDGES)
@ -1757,6 +1769,7 @@ project_boundaries : Optional[str] = None
m.attr("debugparam") = py::cast(&debugparam); m.attr("debugparam") = py::cast(&debugparam);
#ifdef NG_CGNS
m.def("ReadCGNSFile", &ReadCGNSFile, py::arg("filename"), py::arg("base")=1, "Read mesh and solution vectors from CGNS file"); m.def("ReadCGNSFile", &ReadCGNSFile, py::arg("filename"), py::arg("base")=1, "Read mesh and solution vectors from CGNS file");
m.def("WriteCGNSFile", &WriteCGNSFile, py::arg("mesh"), py::arg("filename"), py::arg("names"), py::arg("values"), py::arg("locations"), m.def("WriteCGNSFile", &WriteCGNSFile, py::arg("mesh"), py::arg("filename"), py::arg("names"), py::arg("values"), py::arg("locations"),
R"(Write mesh and solution vectors to CGNS file, possible values for locations: R"(Write mesh and solution vectors to CGNS file, possible values for locations:
@ -1765,6 +1778,7 @@ project_boundaries : Optional[str] = None
FaceCenter = 2 FaceCenter = 2
CellCenter = 3 CellCenter = 3
)"); )");
#endif // NG_CGNS
py::class_<SurfaceGeometry, NetgenGeometry, shared_ptr<SurfaceGeometry>> (m, "SurfaceGeometry") py::class_<SurfaceGeometry, NetgenGeometry, shared_ptr<SurfaceGeometry>> (m, "SurfaceGeometry")
.def(py::init<>()) .def(py::init<>())

View File

@ -222,9 +222,15 @@ loadmeshinifile;
set meshimportformats [Ng_GetImportFormats]
.ngmenu.file add command -label "Import Mesh..." \ .ngmenu.file add command -label "Import Mesh..." \
-command { -command {
foreach importformat $meshimportformats {
if { [lindex $importformat 0] == $importfiletype } {
set extension [lindex $importformat 1]
}
}
set types { set types {
{"Neutral format" {.mesh .emt} } {"Neutral format" {.mesh .emt} }
{"Surface mesh format" {.surf} } {"Surface mesh format" {.surf} }
@ -235,9 +241,9 @@ loadmeshinifile;
{"Pro/ENGINEER neutral format" {.fnf} } {"Pro/ENGINEER neutral format" {.fnf} }
{"CFD General Notation System" {.cgns} } {"CFD General Notation System" {.cgns} }
} }
set file [tk_getOpenFile -filetypes $types ] set file [tk_getOpenFile -filetypes $meshimportformats -typevariable importfiletype]
if {$file != ""} { if {$file != ""} {
Ng_ImportMesh $file Ng_ImportMesh $file $importfiletype
set selectvisual mesh set selectvisual mesh
Ng_SetVisParameters Ng_SetVisParameters
redraw redraw

View File

@ -282,17 +282,33 @@ namespace netgen
} }
int Ng_GetImportFormats (ClientData clientData,
Tcl_Interp * interp,
int argc, tcl_const char *argv[])
{
ostringstream fstr;
UserFormatRegister::IterateFormats([&](auto & entry) {
fstr << "{ {" << entry.format << "} {" << entry.extensions[0];
for(auto ext : entry.extensions.Range(1, entry.extensions.Size()))
fstr << ' ' << ext;
fstr << "} }\n";
}, true, false);
Tcl_SetResult (interp, const_cast<char*>(fstr.str().c_str()), TCL_VOLATILE);
return TCL_OK;
}
int Ng_GetExportFormats (ClientData clientData, int Ng_GetExportFormats (ClientData clientData,
Tcl_Interp * interp, Tcl_Interp * interp,
int argc, tcl_const char *argv[]) int argc, tcl_const char *argv[])
{ {
NgArray<const char*> userformats;
NgArray<const char*> extensions;
RegisterUserFormats (userformats, extensions);
ostringstream fstr; ostringstream fstr;
for (int i = 1; i <= userformats.Size(); i++) UserFormatRegister::IterateFormats([&](auto & entry) {
fstr << "{ {" << userformats.Get(i) << "} {" << extensions.Get(i) << "} }\n"; fstr << "{ {" << entry.format << "} {" << entry.extensions[0];
for(auto ext : entry.extensions.Range(1, entry.extensions.Size()))
fstr << ' ' << ext;
fstr << "} }\n";
}, false, true);
Tcl_SetResult (interp, const_cast<char*>(fstr.str().c_str()), TCL_VOLATILE); Tcl_SetResult (interp, const_cast<char*>(fstr.str().c_str()), TCL_VOLATILE);
return TCL_OK; return TCL_OK;
@ -333,11 +349,12 @@ namespace netgen
int argc, tcl_const char *argv[]) int argc, tcl_const char *argv[])
{ {
const string filename (argv[1]); const string filename (argv[1]);
const string format (argv[2]);
PrintMessage (1, "import mesh from ", filename); PrintMessage (1, "import mesh from ", filename);
mesh = make_shared<Mesh>(); mesh = make_shared<Mesh>();
ReadFile (*mesh, filename); ReadUserFormat (*mesh, filename, format);
PrintMessage (2, mesh->GetNP(), " Points, ", PrintMessage (2, mesh->GetNP(), " Points, ",
mesh->GetNE(), " Elements."); mesh->GetNE(), " Elements.");
@ -2877,6 +2894,10 @@ void PlayAnimFile(const char* name, int speed, int maxcnt)
(ClientData)NULL, (ClientData)NULL,
(Tcl_CmdDeleteProc*) NULL); (Tcl_CmdDeleteProc*) NULL);
Tcl_CreateCommand (interp, "Ng_GetImportFormats", Ng_GetImportFormats,
(ClientData)NULL,
(Tcl_CmdDeleteProc*) NULL);
Tcl_CreateCommand (interp, "Ng_GetExportFormats", Ng_GetExportFormats, Tcl_CreateCommand (interp, "Ng_GetExportFormats", Ng_GetExportFormats,
(ClientData)NULL, (ClientData)NULL,
(Tcl_CmdDeleteProc*) NULL); (Tcl_CmdDeleteProc*) NULL);

View File

@ -250,6 +250,7 @@ DLL_HEADER const char * ngscript[] = {""
,"set status_filename 0\n" ,"set status_filename 0\n"
,"set status_tetqualclasses \"10 20 30 40 10 20 30 40 10 20 30 40 10 20 30 40 10 20 30 40\"\n" ,"set status_tetqualclasses \"10 20 30 40 10 20 30 40 10 20 30 40 10 20 30 40 10 20 30 40\"\n"
,"set exportfiletype \"Neutral Format\"\n" ,"set exportfiletype \"Neutral Format\"\n"
,"set importfiletype \"Neutral Format\"\n"
,"set preproc.facenr 0\n" ,"set preproc.facenr 0\n"
,"set preproc.selectmode query\n" ,"set preproc.selectmode query\n"
,"set preproc.numtrig 0\n" ,"set preproc.numtrig 0\n"
@ -860,8 +861,14 @@ DLL_HEADER const char * ngscript[] = {""
,"Ng_ReadStatus;\n" ,"Ng_ReadStatus;\n"
,"}\n" ,"}\n"
,"}\n" ,"}\n"
,"set meshimportformats [Ng_GetImportFormats]\n"
,".ngmenu.file add command -label \"Import Mesh...\" \\\n" ,".ngmenu.file add command -label \"Import Mesh...\" \\\n"
,"-command {\n" ,"-command {\n"
,"foreach importformat $meshimportformats {\n"
,"if { [lindex $importformat 0] == $importfiletype } {\n"
,"set extension [lindex $importformat 1]\n"
,"}\n"
,"}\n"
,"set types {\n" ,"set types {\n"
,"{\"Neutral format\" {.mesh .emt} }\n" ,"{\"Neutral format\" {.mesh .emt} }\n"
,"{\"Surface mesh format\" {.surf} }\n" ,"{\"Surface mesh format\" {.surf} }\n"
@ -872,9 +879,9 @@ DLL_HEADER const char * ngscript[] = {""
,"{\"Pro/ENGINEER neutral format\" {.fnf} }\n" ,"{\"Pro/ENGINEER neutral format\" {.fnf} }\n"
,"{\"CFD General Notation System\" {.cgns} }\n" ,"{\"CFD General Notation System\" {.cgns} }\n"
,"}\n" ,"}\n"
,"set file [tk_getOpenFile -filetypes $types ]\n" ,"set file [tk_getOpenFile -filetypes $meshimportformats -typevariable importfiletype]\n"
,"if {$file != \"\"} {\n" ,"if {$file != \"\"} {\n"
,"Ng_ImportMesh $file\n" ,"Ng_ImportMesh $file $importfiletype\n"
,"set selectvisual mesh\n" ,"set selectvisual mesh\n"
,"Ng_SetVisParameters\n" ,"Ng_SetVisParameters\n"
,"redraw\n" ,"redraw\n"

View File

@ -232,6 +232,7 @@ set status_filename 0
set status_tetqualclasses "10 20 30 40 10 20 30 40 10 20 30 40 10 20 30 40 10 20 30 40" set status_tetqualclasses "10 20 30 40 10 20 30 40 10 20 30 40 10 20 30 40 10 20 30 40"
set exportfiletype "Neutral Format" set exportfiletype "Neutral Format"
set importfiletype "Neutral Format"
set preproc.facenr 0 set preproc.facenr 0
set preproc.selectmode query set preproc.selectmode query