23
#include "PreCompiled.h"
29
#include "Core/Evaluation.h"
30
#include "Core/MeshKernel.h"
31
#include <Base/Tools.h>
36
using namespace MeshCore;
38
Writer3MF::Writer3MF(std::ostream& str)
41
zip.putNextEntry("3D/3dmodel.model");
45
Writer3MF::Writer3MF(const std::string& filename)
48
zip.putNextEntry("3D/3dmodel.model");
52
void Writer3MF::SetForceModel(bool model)
57
void Writer3MF::Initialize(std::ostream& str)
59
str << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
60
"<model unit=\"millimeter\" xml:lang=\"en-US\" "
61
"xmlns=\"http://schemas.microsoft.com/3dmanufacturing/core/2015/02\">\n"
62
" <metadata name=\"Application\">FreeCAD</metadata>\n";
63
str << Base::blanks(1) << "<resources>\n";
66
void Writer3MF::Finish(std::ostream& str)
68
str << Base::blanks(1) << "</resources>\n";
69
str << Base::blanks(1) << "<build>\n";
70
for (const auto& it : items) {
71
str << Base::blanks(2) << it;
73
str << Base::blanks(1) << "</build>\n";
77
bool Writer3MF::AddMesh(const MeshKernel& mesh, const Base::Matrix4D& mat)
79
int id = ++objectIndex;
80
SaveBuildItem(id, mat);
81
return SaveObject(zip, id, mesh);
84
void Writer3MF::AddResource(const Resource3MF& res)
86
resources.emplace_back(res);
94
zip.putNextEntry("_rels/.rels");
100
zip.putNextEntry("[Content_Types].xml");
101
if (!SaveContent(zip)) {
105
for (const auto& it : resources) {
106
zip.putNextEntry(it.fileNameInZip);
107
zip.write(it.fileContent.data(), static_cast<std::streamsize>(it.fileContent.size()));
114
bool Writer3MF::SaveObject(std::ostream& str, int id, const MeshKernel& mesh) const
117
const MeshPointArray& rPoints = mesh.GetPoints();
118
const MeshFacetArray& rFacets = mesh.GetFacets();
120
if (!str || str.bad()) {
124
str << Base::blanks(2) << "<object id=\"" << id << "\" type=\"" << GetType(mesh) << "\">\n";
125
str << Base::blanks(3) << "<mesh>\n";
128
str << Base::blanks(4) << "<vertices>\n";
129
std::size_t index = 0;
130
for (auto it = rPoints.begin(); it != rPoints.end(); ++it, ++index) {
131
str << Base::blanks(5) << "<vertex x=\"" << it->x << "\" y=\"" << it->y << "\" z=\""
132
<< it->z << "\" />\n";
134
str << Base::blanks(4) << "</vertices>\n";
137
str << Base::blanks(4) << "<triangles>\n";
138
for (const auto& it : rFacets) {
139
str << Base::blanks(5) << "<triangle v1=\"" << it._aulPoints[0] << "\" v2=\""
140
<< it._aulPoints[1] << "\" v3=\"" << it._aulPoints[2] << "\" />\n";
142
str << Base::blanks(4) << "</triangles>\n";
144
str << Base::blanks(3) << "</mesh>\n";
145
str << Base::blanks(2) << "</object>\n";
151
std::string Writer3MF::GetType(const MeshKernel& mesh) const
153
bool isSolid = (forceModel || MeshEvalSolid(mesh).Evaluate());
154
return isSolid ? "model" : "surface";
157
void Writer3MF::SaveBuildItem(int id, const Base::Matrix4D& mat)
159
std::stringstream str;
160
str << "<item objectid=\"" << id << "\" transform=\"" << DumpMatrix(mat) << "\" />\n";
161
items.push_back(str.str());
164
std::string Writer3MF::DumpMatrix(const Base::Matrix4D& mat)
172
std::stringstream str;
173
str << mat[0][0] << " " << mat[1][0] << " " << mat[2][0] << " " << mat[0][1] << " " << mat[1][1]
174
<< " " << mat[2][1] << " " << mat[0][2] << " " << mat[1][2] << " " << mat[2][2] << " "
175
<< mat[0][3] << " " << mat[1][3] << " " << mat[2][3];
180
bool Writer3MF::SaveRels(std::ostream& str) const
184
str << "<?xml version='1.0' encoding='UTF-8'?>\n"
186
"xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n"
187
<< " <Relationship Target=\"/3D/3dmodel.model\" Id=\"rel0\""
188
<< " Type=\"http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel\" />\n";
189
for (const auto& it : resources) {
190
str << " <Relationship Target=\"" << it.relationshipTarget << "\" Id=\"rel" << ++ids
191
<< "\" Type=\"" << it.relationshipType << "\" />\n";
193
str << "</Relationships>\n";
198
bool Writer3MF::SaveContent(std::ostream& str) const
200
str << "<?xml version='1.0' encoding='UTF-8'?>\n"
201
<< "<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">\n"
202
<< " <Default Extension=\"rels\" "
203
"ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>\n"
204
<< " <Default Extension=\"model\" "
205
"ContentType=\"application/vnd.ms-package.3dmanufacturing-3dmodel+xml\"/>\n";
206
for (const auto& it : resources) {
207
str << " <Default Extension=\"" << it.extension << "\" ContentType=\"" << it.contentType