Added some metadata to exported AMF

This commit is contained in:
Ian Rees 2015-12-20 13:35:09 +13:00 committed by wmayer
parent 0bd3e5d4ab
commit e178d93c61
3 changed files with 72 additions and 18 deletions

View File

@ -24,6 +24,7 @@
#ifndef _PreComp_
# include <algorithm>
# include <memory>
# include <map>
#endif
#include <CXX/Extensions.hxx>
@ -305,7 +306,13 @@ private:
std::unique_ptr<Exporter> exporter;
if (exportFormat == MeshIO::AMF) {
exporter.reset( new AmfExporter(EncodedName) );
std::map<std::string, std::string> meta;
meta["cad"] = App::Application::Config()["ExeName"] + " " +
App::Application::Config()["ExeVersion"];
meta[App::Application::Config()["ExeName"] + "-buildRevisionHash"] =
App::Application::Config()["BuildRevisionHash"];
exporter.reset( new AmfExporter(EncodedName, meta) );
} else {
// TODO: How do we handle unknown exportFormats?
exporter.reset( new MergeExporter(EncodedName, exportFormat) );
@ -323,7 +330,7 @@ private:
if (obj->getTypeId().isDerivedFrom(meshId)) {
exporter->addMesh( static_cast<Mesh::Feature*>(obj) );
} else if (obj->getTypeId().isDerivedFrom(partId)) {
exporter->addShape( obj->getPropertyByName("Shape"), fTolerance );
exporter->addPart( obj, fTolerance );
} else {
Base::Console().Message("'%s' is not a mesh or shape, export will be ignored.\n", obj->Label.getValue());
}

View File

@ -23,8 +23,8 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <algorithm>
#include <map>
#include <vector>
#include <boost/algorithm/string/replace.hpp>
#endif // #ifndef _PreComp_
#include "Exporter.h"
@ -42,6 +42,17 @@
using namespace Mesh;
using namespace MeshCore;
//static
std::string Exporter::xmlEscape(const std::string &input)
{
std::string out(input);
boost::replace_all(out, "&", "&amp;");
boost::replace_all(out, "\"", "&quot;");
boost::replace_all(out, "'", "&apos;");
boost::replace_all(out, "<", "&lt;");
boost::replace_all(out, ">", "&gt;");
return out;
}
MergeExporter::MergeExporter(std::string fileName, MeshIO::Format fmt)
:fName(fileName)
@ -110,8 +121,9 @@ bool MergeExporter::addMesh(Mesh::Feature *meshFeat)
return true;
}
bool MergeExporter::addShape(App::Property *shape, float tol)
bool MergeExporter::addPart(App::DocumentObject *obj, float tol)
{
auto *shape(obj->getPropertyByName("Shape"));
if (shape && shape->getTypeId().isDerivedFrom(App::PropertyComplexGeoData::getClassTypeId())) {
Base::Reference<MeshObject> mesh(new MeshObject());
@ -145,7 +157,9 @@ bool MergeExporter::addShape(App::Property *shape, float tol)
return false;
}
AmfExporter::AmfExporter(std::string fileName, bool compress) :
AmfExporter::AmfExporter( std::string fileName,
const std::map<std::string, std::string> &meta,
bool compress ) :
outputStreamPtr(nullptr), nextObjectIndex(0)
{
// ask for write permission
@ -173,6 +187,10 @@ AmfExporter::AmfExporter(std::string fileName, bool compress) :
if (outputStreamPtr) {
*outputStreamPtr << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
<< "<amf unit=\"millimeter\">\n";
for (auto const &metaEntry : meta) {
*outputStreamPtr << "\t<metadata type=\"" << metaEntry.first
<< "\">" << metaEntry.second << "</metadata>\n";
}
}
}
@ -193,9 +211,10 @@ AmfExporter::~AmfExporter()
}
}
bool AmfExporter::addShape(App::Property *shape, float tol)
bool AmfExporter::addPart(App::DocumentObject *obj, float tol)
{
// TODO: Add meta info, look into a different way to extract mesh with vertex normals
auto *shape(obj->getPropertyByName("Shape"));
// TODO: Look into a different way to extract mesh with vertex normals
if (shape && shape->getTypeId().isDerivedFrom(App::PropertyComplexGeoData::getClassTypeId())) {
Base::Reference<MeshObject> mesh(new MeshObject());
@ -213,7 +232,10 @@ bool AmfExporter::addShape(App::Property *shape, float tol)
MeshCore::MeshKernel kernel = mesh->getKernel();
kernel.Transform(mesh->getTransform());
return addMesh(kernel);
std::map<std::string, std::string> meta;
meta["name"] = xmlEscape(obj->Label.getStrValue());
return addMesh(kernel, meta);
}
return false;
}
@ -225,10 +247,14 @@ bool AmfExporter::addMesh(Mesh::Feature *meshFeat)
MeshCore::MeshKernel kernel( mesh.getKernel() );
kernel.Transform(mesh.getTransform());
return addMesh(kernel);
std::map<std::string, std::string> meta;
meta["name"] = xmlEscape(meshFeat->Label.getStrValue());
return addMesh(kernel, meta);
}
bool AmfExporter::addMesh(const MeshCore::MeshKernel &kernel)
bool AmfExporter::addMesh(const MeshCore::MeshKernel &kernel,
const std::map<std::string, std::string> &meta)
{
if (!outputStreamPtr || outputStreamPtr->bad()) {
return false;
@ -244,8 +270,13 @@ bool AmfExporter::addMesh(const MeshCore::MeshKernel &kernel)
Base::SequencerLauncher seq("Saving...", 2 * numFacets + 1);
*outputStreamPtr << "\t<object id=\"" << nextObjectIndex << "\">\n"
<< "\t\t<mesh>\n"
*outputStreamPtr << "\t<object id=\"" << nextObjectIndex << "\">\n";
for (auto const &metaEntry : meta) {
*outputStreamPtr << "\t\t<metadata type=\"" << metaEntry.first
<< "\">" << metaEntry.second << "</metadata>\n";
}
*outputStreamPtr << "\t\t<mesh>\n"
<< "\t\t\t<vertices>\n";
const MeshCore::MeshGeomFacet *facet;

View File

@ -25,6 +25,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <map>
#include <ostream>
#endif // #ifndef _PreComp_
@ -42,7 +43,7 @@ namespace Mesh
* Constructors of derived classes are expected to be required, for passing
* in the name of output file.
*
* Objects are added using the addMesh(), addShape(), etc.
* Objects are added using the addMesh(), addPart(), etc.
*
* If objects are meant to be combined into a single file, then the file should
* be saved from the derived class' destructor.
@ -51,8 +52,13 @@ class Exporter
{
public:
virtual bool addMesh(Mesh::Feature *meshFeat) = 0;
virtual bool addShape(App::Property *shape, float tol) = 0;
virtual bool addPart(App::DocumentObject *obj, float tol) = 0;
virtual ~Exporter() {};
protected:
/// Does some simple escaping of characters for XML-type exports
//TODO: Use xerces or something instead?
static std::string xmlEscape(const std::string &input);
};
/// Creates a single mesh, in a file, from one or more objects
@ -65,7 +71,7 @@ class MergeExporter : public Exporter
/// Directly adds a mesh
bool addMesh(Mesh::Feature *meshFeat);
/// Converts the a Part::Feature to a mesh, adds that mesh
bool addShape(App::Property *shape, float tol);
bool addPart(App::DocumentObject *obj, float tol);
protected:
MeshObject mergingMesh;
std::string fName;
@ -80,14 +86,24 @@ class AmfExporter : public Exporter
{
public:
/// Writes AMF header
AmfExporter(std::string fileName, bool compress = true);
/*!
* 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 = false);
/// Writes AMF footer
~AmfExporter();
bool addMesh(Mesh::Feature *meshFeat);
bool addMesh(const MeshCore::MeshKernel &kernel);
bool addShape(App::Property *shape, float tol);
/*!
* meta is included for the AMF object created
*/
bool addMesh(const MeshCore::MeshKernel &kernel,
const std::map<std::string, std::string> &meta);
bool addPart(App::DocumentObject *obj, float tol);
private:
std::ostream *outputStreamPtr;