Mesh: add support of thumbnails of 3MF format

This commit is contained in:
wmayer
2022-09-01 16:49:00 +02:00
parent fbfac41c82
commit 086ce2d34c
10 changed files with 281 additions and 15 deletions

View File

@@ -76,6 +76,11 @@ bool Writer3MF::AddMesh(const MeshKernel& mesh, const Base::Matrix4D& mat)
return SaveObject(zip, id, mesh);
}
void Writer3MF::AddResource(const Resource3MF& res)
{
resources.emplace_back(res);
}
bool Writer3MF::Save()
{
Finish(zip);
@@ -90,6 +95,12 @@ bool Writer3MF::Save()
if (!SaveContent(zip))
return false;
zip.closeEntry();
for (const auto& it : resources) {
zip.putNextEntry(it.fileNameInZip);
zip.write(it.fileContent.data(), it.fileContent.size());
zip.closeEntry();
}
return true;
}
@@ -163,19 +174,24 @@ std::string Writer3MF::DumpMatrix(const Base::Matrix4D& mat) const
bool Writer3MF::SaveRels(std::ostream &str) const
{
int ids = 1;
str << "<?xml version='1.0' encoding='UTF-8'?>\n"
<< "<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">"
"<Relationship Id=\"rel0\" Target=\"/3D/3dmodel.model\" Type=\"http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel\" />"
"</Relationships>";
<< "<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n"
<< " <Relationship Target=\"/3D/3dmodel.model\" Id=\"rel0\" Type=\"http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel\" />\n";
for (const auto& it : resources)
str << " <Relationship Target=\"" << it.relationshipTarget << "\" Id=\"rel" << ++ids << "\" Type=\"" << it.relationshipType << "\" />\n";
str << "</Relationships>\n";
return true;
}
bool Writer3MF::SaveContent(std::ostream &str) const
{
str << "<?xml version='1.0' encoding='UTF-8'?>\n"
<< "<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">"
"<Default ContentType=\"application/vnd.openxmlformats-package.relationships+xml\" Extension=\"rels\" />"
"<Default ContentType=\"application/vnd.ms-package.3dmanufacturing-3dmodel+xml\" Extension=\"model\" />"
"</Types>";
<< "<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">\n"
<< " <Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>\n"
<< " <Default Extension=\"model\" ContentType=\"application/vnd.ms-package.3dmanufacturing-3dmodel+xml\"/>\n";
for (const auto& it : resources)
str << " <Default Extension=\"" << it.extension << "\" ContentType=\"" << it.contentType << "\"/>\n";
str << "</Types>";
return true;
}

View File

@@ -25,14 +25,26 @@
#define MESH_IO_WRITER_3MF_H
#include <iosfwd>
#include "Core/Elements.h"
#include <zipios++/zipoutputstream.h>
#include <Mod/Mesh/MeshGlobal.h>
namespace Base {
class Matrix4D;
}
namespace MeshCore
{
class MeshKernel;
struct Resource3MF {
std::string extension;
std::string contentType;
std::string relationshipTarget;
std::string relationshipType;
std::string fileNameInZip;
std::string fileContent;
};
/** Saves the mesh object into 3MF format. */
class MeshExport Writer3MF
{
@@ -58,6 +70,11 @@ public:
* \return true if the added mesh could be written successfully, false otherwise.
*/
bool AddMesh(const MeshKernel& mesh, const Base::Matrix4D& mat);
/*!
* \brief AddResource
* Add an additional resource to the 3MF file.
*/
void AddResource(const Resource3MF&);
/*!
* \brief After having added the mesh objects with \ref AddMesh save the meta-information
* to the 3MF file.
@@ -79,6 +96,7 @@ private:
zipios::ZipOutputStream zip;
int objectIndex;
std::vector<std::string> items;
std::vector<Resource3MF> resources;
};
} // namespace MeshCore

View File

@@ -229,12 +229,29 @@ bool MergeExporter::addMesh(const char *name, const MeshObject & mesh)
// ----------------------------------------------------------------------------
void Extension3MFFactory::addProducer(AbstractExtensionProducer* ext)
{
producer.emplace_back(ext);
}
std::vector<Extension3MFPtr> Extension3MFFactory::create()
{
std::vector<Extension3MFPtr> ext;
for (const auto& it : producer)
ext.emplace_back(it->create());
return ext;
}
std::vector<AbstractExtensionProducerPtr> Extension3MFFactory::producer;
class Exporter3MF::Private {
public:
Private(const std::string& filename)
: writer3mf(filename) {
ext = Extension3MFFactory::create();
}
MeshCore::Writer3MF writer3mf;
std::vector<Extension3MFPtr> ext;
};
Exporter3MF::Exporter3MF(std::string fileName)
@@ -251,7 +268,14 @@ Exporter3MF::~Exporter3MF()
bool Exporter3MF::addMesh(const char *name, const MeshObject & mesh)
{
boost::ignore_unused(name);
return d->writer3mf.AddMesh(mesh.getKernel(), mesh.getTransform());
bool ok = d->writer3mf.AddMesh(mesh.getKernel(), mesh.getTransform());
if (ok) {
for (const auto& it : d->ext) {
d->writer3mf.AddResource(it->addMesh(mesh));
}
}
return ok;
}
void Exporter3MF::write()
@@ -410,7 +434,7 @@ bool ExporterAMF::addMesh(const char *name, const MeshObject & mesh)
*outputStreamPtr << "\t\t\t</vertices>\n"
<< "\t\t\t<volume>\n";
// Now that we've output all the vertices, we can
// output the facets that refer to them!
for (auto triItr(facets.begin()); triItr != facets.end(); ) {

View File

@@ -34,6 +34,7 @@
#include "MeshFeature.h"
#include "Core/MeshIO.h"
#include "Core/MeshKernel.h"
#include "Core/IO/Writer3MF.h"
namespace Mesh
{
@@ -91,6 +92,50 @@ protected:
std::string fName;
};
/*!
* \brief The Extension3MF class
* Abstract base class for 3MF extensions
*/
class MeshExport Extension3MF
{
public:
using Resource = MeshCore::Resource3MF;
Extension3MF() = default;
virtual ~Extension3MF() = default;
virtual Resource addMesh(const MeshObject & mesh) = 0;
};
using Extension3MFPtr = std::shared_ptr<Extension3MF>;
/*!
* \brief The AbstractExtensionProducer class
* Abstract base class to create an instance of an Extension3MF.
*/
class MeshExport AbstractExtensionProducer
{
public:
AbstractExtensionProducer() = default;
virtual ~AbstractExtensionProducer() = default;
virtual Extension3MFPtr create() const = 0;
};
using AbstractExtensionProducerPtr = std::shared_ptr<AbstractExtensionProducer>;
/*!
* \brief The Extension3MFFactory class
* Factor class to manage the producers of Extension3MF
*/
class MeshExport Extension3MFFactory
{
public:
static void addProducer(AbstractExtensionProducer* ext);
static std::vector<Extension3MFPtr> create();
private:
static std::vector<AbstractExtensionProducerPtr> producer;
};
/// Used for exporting to 3D Manufacturing Format (3MF)
/*!
* The constructor and destructor write the beginning and end of the 3MF,