Mesh: refactor mesh exporter classes

This commit is contained in:
wmayer
2022-08-31 10:07:57 +02:00
parent 60a230805c
commit f557920414
3 changed files with 98 additions and 72 deletions

View File

@@ -266,12 +266,14 @@ private:
meta[App::Application::Config()["ExeName"] + "-buildRevisionHash"] =
App::Application::Config()["BuildRevisionHash"];
exporter.reset( new AmfExporter(outputFileName, meta, exportAmfCompressed) );
exporter.reset( new ExporterAMF(outputFileName, meta, exportAmfCompressed) );
} else if (exportFormat != MeshIO::Undefined) {
}
else if (exportFormat != MeshIO::Undefined) {
exporter.reset( new MergeExporter(outputFileName, exportFormat) );
} else {
}
else {
std::string exStr("Can't determine mesh format from file name: '");
exStr += outputFileName + "'";
throw Py::ValueError(exStr.c_str());
@@ -280,6 +282,7 @@ private:
for (auto it : objectList) {
exporter->addObject(it, fTolerance);
}
exporter.reset(); // deletes Exporter, mesh file is written by destructor
return Py::None();

View File

@@ -141,12 +141,19 @@ int Exporter::addObject(App::DocumentObject *obj, float tol)
return count;
}
// ----------------------------------------------------------------------------
MergeExporter::MergeExporter(std::string fileName, MeshIO::Format)
:fName(fileName)
{
}
MergeExporter::~MergeExporter()
{
write();
}
void MergeExporter::write()
{
// if we have more than one segment set the 'save' flag
if (mergingMesh.countSegments() > 1) {
@@ -163,7 +170,6 @@ MergeExporter::~MergeExporter()
}
}
bool MergeExporter::addMesh(const char *name, const MeshObject & mesh)
{
const auto & kernel = mesh.getKernel();
@@ -209,7 +215,9 @@ bool MergeExporter::addMesh(const char *name, const MeshObject & mesh)
return true;
}
AmfExporter::AmfExporter( std::string fileName,
// ----------------------------------------------------------------------------
ExporterAMF::ExporterAMF( std::string fileName,
const std::map<std::string, std::string> &meta,
bool compress ) :
outputStreamPtr(nullptr), nextObjectIndex(0)
@@ -246,7 +254,12 @@ AmfExporter::AmfExporter( std::string fileName,
}
}
AmfExporter::~AmfExporter()
ExporterAMF::~ExporterAMF()
{
write();
}
void ExporterAMF::write()
{
if (outputStreamPtr) {
*outputStreamPtr << "\t<constellation id=\"0\">\n";
@@ -263,7 +276,28 @@ AmfExporter::~AmfExporter()
}
}
bool AmfExporter::addMesh(const char *name, const MeshObject & mesh)
class ExporterAMF::VertLess
{
public:
bool operator()(const Base::Vector3f &a, const Base::Vector3f &b) const
{
if (a.x == b.x) {
if (a.y == b.y) {
if (a.z == b.z) {
return false;
} else {
return a.z < b.z;
}
} else {
return a.y < b.y;
}
} else {
return a.x < b.x;
}
}
};
bool ExporterAMF::addMesh(const char *name, const MeshObject & mesh)
{
const auto & kernel = mesh.getKernel();
@@ -292,8 +326,8 @@ bool AmfExporter::addMesh(const char *name, const MeshObject & mesh)
// Iterate through all facets of the mesh, and construct a:
// * Cache (map) of used vertices, outputting each new unique vertex to
// the output stream as we find it
// * Vector of the vertices, referred to by the indices from 1
std::map<Base::Vector3f, unsigned long, AmfExporter::VertLess> vertices;
// * Vector of the vertices, referred to by the indices from 1
std::map<Base::Vector3f, unsigned long, ExporterAMF::VertLess> vertices;
auto vertItr(vertices.begin());
auto vertexCount(0UL);
@@ -354,4 +388,3 @@ bool AmfExporter::addMesh(const char *name, const MeshObject & mesh)
++nextObjectIndex;
return true;
}

View File

@@ -48,91 +48,81 @@ namespace Mesh
*/
class Exporter
{
public:
Exporter();
virtual ~Exporter() = default;
public:
Exporter();
virtual ~Exporter() = default;
/// Add object and all subobjects and links etc. Returns the number of stuff added.
/*!
* @param obj The object to export. If this is a group like object, its
* sub-objects will be added.
* @param tol The tolerance/accuracy with which to generate the triangle mesh
* @return The number of objects/subobjects that was exported from the document.
See the parameter `accuracy` of ComplexGeoData::getFaces
*/
int addObject(App::DocumentObject *obj, float tol);
/// Add object and all subobjects and links etc. Returns the number of stuff added.
/*!
* @param obj The object to export. If this is a group like object, its
* sub-objects will be added.
* @param tol The tolerance/accuracy with which to generate the triangle mesh
* @return The number of objects/subobjects that was exported from the document.
See the parameter `accuracy` of ComplexGeoData::getFaces
*/
int addObject(App::DocumentObject *obj, float tol);
virtual bool addMesh(const char *name, const MeshObject & mesh) = 0;
virtual bool addMesh(const char *name, const MeshObject & mesh) = 0;
protected:
/// Does some simple escaping of characters for XML-type exports
static std::string xmlEscape(const std::string &input);
protected:
/// Does some simple escaping of characters for XML-type exports
static std::string xmlEscape(const std::string &input);
std::map<const App::DocumentObject *, std::vector<std::string> > subObjectNameCache;
std::map<const App::DocumentObject *, MeshObject> meshCache;
std::map<const App::DocumentObject *, std::vector<std::string> > subObjectNameCache;
std::map<const App::DocumentObject *, MeshObject> meshCache;
};
/// Creates a single mesh, in a file, from one or more objects
class MergeExporter : public Exporter
{
public:
MergeExporter(std::string fileName, MeshCore::MeshIO::Format fmt);
~MergeExporter() override;
public:
MergeExporter(std::string fileName, MeshCore::MeshIO::Format fmt);
~MergeExporter() override;
bool addMesh(const char *name, const MeshObject & mesh) override;
bool addMesh(const char *name, const MeshObject & mesh) override;
protected:
MeshObject mergingMesh;
std::string fName;
private:
/// Write the meshes of the added objects to the output file
void write();
protected:
MeshObject mergingMesh;
std::string fName;
};
/// Used for exporting to Additive Manufacturing File (AMF) format
/*!
* The constructor and destructor write the beginning and end of the AMF,
* add____() is used to add geometry
* addObject() is used to add geometry
*/
class AmfExporter : public Exporter
class ExporterAMF : public Exporter
{
public:
/// Writes AMF header
/*!
* meta information passed in is applied at the <amf> tag level
*/
AmfExporter(std::string fileName,
const std::map<std::string, std::string> &meta,
bool compress = true);
public:
/// Writes AMF header
/*!
* meta information passed in is applied at the <amf> tag level
*/
ExporterAMF(std::string fileName,
const std::map<std::string, std::string> &meta,
bool compress = true);
/// Writes AMF footer
~AmfExporter() override;
/// Writes AMF footer
~ExporterAMF() override;
bool addMesh(const char *name, const MeshObject & mesh) override;
bool addMesh(const char *name, const MeshObject & mesh) override;
private:
std::ostream *outputStreamPtr;
int nextObjectIndex;
private:
/// Write the meshes of the added objects to the output file
void write();
private:
std::ostream *outputStreamPtr;
int nextObjectIndex;
/// Helper for putting Base::Vector3f objects into a std::map in addMesh()
class VertLess
{
public:
bool operator()(const Base::Vector3f &a, const Base::Vector3f &b) const
{
if (a.x == b.x) {
if (a.y == b.y) {
if (a.z == b.z) {
return false;
} else {
return a.z < b.z;
}
} else {
return a.y < b.y;
}
} else {
return a.x < b.x;
}
}
};
}; // class AmfExporter
class VertLess;
}; // class ExporterAMF
} // namespace Mesh
#endif // MESH_EXPORTER_H