Mesh: refactor mesh exporter classes
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user