diff --git a/src/Mod/Mesh/App/Core/MeshIO.cpp b/src/Mod/Mesh/App/Core/MeshIO.cpp index a2c5c6d09b..8a69c3371a 100644 --- a/src/Mod/Mesh/App/Core/MeshIO.cpp +++ b/src/Mod/Mesh/App/Core/MeshIO.cpp @@ -1772,7 +1772,7 @@ std::vector MeshOutput::supportedMeshFormats() fmt.emplace_back("off"); fmt.emplace_back("smf"); fmt.emplace_back("x3d"); - fmt.emplace_back("html"); + fmt.emplace_back("xhtml"); fmt.emplace_back("wrl"); fmt.emplace_back("wrz"); fmt.emplace_back("amf"); @@ -1813,8 +1813,8 @@ MeshIO::Format MeshOutput::GetFormat(const char* FileName) else if (file.hasExtension("x3d")) { return MeshIO::X3D; } - else if (file.hasExtension("html")) { - return MeshIO::HTML; + else if (file.hasExtension("xhtml")) { + return MeshIO::X3DOM; } else if (file.hasExtension("py")) { return MeshIO::PY; @@ -1928,10 +1928,10 @@ bool MeshOutput::SaveAny(const char* FileName, MeshIO::Format format) const if (!SaveX3D(str)) throw Base::FileException("Export of X3D failed",FileName); } - else if (fileformat == MeshIO::HTML) { + else if (fileformat == MeshIO::X3DOM) { // write file - if (!SaveHTML(str)) - throw Base::FileException("Export of HTML failed",FileName); + if (!SaveX3DOM(str)) + throw Base::FileException("Export of X3DOM failed",FileName); } else if (fileformat == MeshIO::PY) { // write file @@ -1996,8 +1996,8 @@ bool MeshOutput::SaveFormat(std::ostream &str, MeshIO::Format fmt) const return SaveInventor(str); case MeshIO::X3D: return SaveX3D(str); - case MeshIO::HTML: - return SaveHTML(str); + case MeshIO::X3DOM: + return SaveX3DOM(str); case MeshIO::VRML: return SaveVRML(str); case MeshIO::WRZ: @@ -3021,11 +3021,11 @@ bool MeshOutput::SaveX3D (std::ostream &out) const // XML header info out << "\n"; - return SaveX3DContent(out); + return SaveX3DContent(out, false); } /** Writes an X3D file. */ -bool MeshOutput::SaveX3DContent (std::ostream &out) const +bool MeshOutput::SaveX3DContent (std::ostream &out, bool exportViewpoints) const { if ((!out) || (out.bad() == true) || (_rclMesh.CountFacets() == 0)) return false; @@ -3036,6 +3036,16 @@ bool MeshOutput::SaveX3DContent (std::ostream &out) const if (apply_transform) bbox = bbox.Transformed(_transform); + App::Color mat(0.65f, 0.65f, 0.65f); + if (_material && _material->binding == MeshIO::Binding::OVERALL) { + if (!_material->diffuseColor.empty()) + mat = _material->diffuseColor.front(); + } + bool saveVertexColor = (_material && _material->binding == MeshIO::PER_VERTEX && + _material->diffuseColor.size() == pts.size()); + bool saveFaceColor = (_material && _material->binding == MeshIO::PER_FACE && + _material->diffuseColor.size() == fts.size()); + Base::SequencerLauncher seq("Saving...", _rclMesh.CountFacets() + 1); out.precision(6); out.setf(std::ios::fixed | std::ios::showpoint); @@ -3051,33 +3061,35 @@ bool MeshOutput::SaveX3DContent (std::ostream &out) const << " \n"; // Beginning - out << " \n"; + out << " \n"; - auto viewpoint = [&out](const char* text, const Base::Vector3f& cnt, - const Base::Vector3f& pos, const Base::Vector3f& axis, float angle) { - out << " " - << "\n"; - }; + if (exportViewpoints) { + auto viewpoint = [&out](const char* text, const Base::Vector3f& cnt, + const Base::Vector3f& pos, const Base::Vector3f& axis, float angle) { + out << " " + << "\n"; + }; - Base::Vector3f cnt = bbox.GetCenter(); - float minx = bbox.MinX; - float maxx = bbox.MaxX; - float miny = bbox.MinY; - float maxy = bbox.MaxY; - float minz = bbox.MinZ; - float maxz = bbox.MaxZ; - float len = bbox.CalcDiagonalLength(); + Base::Vector3f cnt = bbox.GetCenter(); + float minx = bbox.MinX; + float maxx = bbox.MaxX; + float miny = bbox.MinY; + float maxy = bbox.MaxY; + float minz = bbox.MinZ; + float maxz = bbox.MaxZ; + float len = bbox.CalcDiagonalLength(); - viewpoint("Front", cnt, Base::Vector3f(cnt.x, miny-len, cnt.z), Base::Vector3f(1.0f, 0.0f, 0.0f), 1.5707964f); - viewpoint("Back", cnt, Base::Vector3f(cnt.x, maxy+len, cnt.z), Base::Vector3f(0.0f, 0.707106f, 0.707106f), 3.141592f); - viewpoint("Right", cnt, Base::Vector3f(maxx+len, cnt.y, cnt.z), Base::Vector3f(0.577350f, 0.577350f, 0.577350f), 2.094395f); - viewpoint("Left", cnt, Base::Vector3f(minx-len, cnt.y, cnt.z), Base::Vector3f(-0.577350f, 0.577350f, 0.577350f), 4.188790f); - viewpoint("Top", cnt, Base::Vector3f(cnt.x, cnt.y, maxz+len), Base::Vector3f(0.0f, 0.0f, 1.0f), 0.0f); - viewpoint("Bottom", cnt, Base::Vector3f(cnt.x, cnt.y, minz-len), Base::Vector3f(1.0f, 0.0f, 0.0f), 3.141592f); + viewpoint("Front", cnt, Base::Vector3f(cnt.x, miny-len, cnt.z), Base::Vector3f(1.0f, 0.0f, 0.0f), 1.5707964f); + viewpoint("Back", cnt, Base::Vector3f(cnt.x, maxy+len, cnt.z), Base::Vector3f(0.0f, 0.707106f, 0.707106f), 3.141592f); + viewpoint("Right", cnt, Base::Vector3f(maxx+len, cnt.y, cnt.z), Base::Vector3f(0.577350f, 0.577350f, 0.577350f), 2.094395f); + viewpoint("Left", cnt, Base::Vector3f(minx-len, cnt.y, cnt.z), Base::Vector3f(-0.577350f, 0.577350f, 0.577350f), 4.188790f); + viewpoint("Top", cnt, Base::Vector3f(cnt.x, cnt.y, maxz+len), Base::Vector3f(0.0f, 0.0f, 1.0f), 0.0f); + viewpoint("Bottom", cnt, Base::Vector3f(cnt.x, cnt.y, minz-len), Base::Vector3f(1.0f, 0.0f, 0.0f), 3.141592f); + } if (apply_transform) { Base::Placement p(_transform); @@ -3100,10 +3112,19 @@ bool MeshOutput::SaveX3DContent (std::ostream &out) const out << " \n"; } out << " \n"; - out << " \n"; + out << " \n" + " \n" + " \n"; - out << " _aulPoints[0] << " " << it->_aulPoints[1] << " " << it->_aulPoints[2] << " -1 "; } @@ -3115,6 +3136,15 @@ bool MeshOutput::SaveX3DContent (std::ostream &out) const } out << "\"/>\n"; + // write colors per vertex or face + if (saveVertexColor || saveFaceColor) { + out << " diffuseColor) { + out << c.r << " " << c.g << " " << c.b << ", "; + } + out << "\"/>\n"; + } + // End out << " \n" << " \n" @@ -3127,13 +3157,18 @@ bool MeshOutput::SaveX3DContent (std::ostream &out) const return true; } -/** Writes an HTML file. */ -bool MeshOutput::SaveHTML (std::ostream &out) const +/** Writes an X3DOM file. */ +bool MeshOutput::SaveX3DOM (std::ostream &out) const { if ((!out) || (out.bad() == true) || (_rclMesh.CountFacets() == 0)) return false; - out << "\n" + // See: + // https://stackoverflow.com/questions/31976056/unable-to-color-faces-using-indexedfaceset-in-x3dom + // + out << "\n" + << "\n"; + out << "\n" << " \n" << " \n" << " \n" @@ -3149,7 +3184,7 @@ bool MeshOutput::SaveHTML (std::ostream &out) const #endif - SaveX3DContent(out); + SaveX3DContent(out, true); auto onclick = [&out](const char* text) { out << " \n"; diff --git a/src/Mod/Mesh/App/Core/MeshIO.h b/src/Mod/Mesh/App/Core/MeshIO.h index 905ecc9ef5..e52b28fd03 100644 --- a/src/Mod/Mesh/App/Core/MeshIO.h +++ b/src/Mod/Mesh/App/Core/MeshIO.h @@ -50,7 +50,7 @@ namespace MeshIO { MGL, IV, X3D, - HTML, + X3DOM, VRML, WRZ, NAS, @@ -202,8 +202,8 @@ public: bool SaveInventor (std::ostream &rstrOut) const; /** Writes an X3D file. */ bool SaveX3D (std::ostream &rstrOut) const; - /** Writes an HTML file. */ - bool SaveHTML (std::ostream &rstrOut) const; + /** Writes an X3dom file. */ + bool SaveX3DOM (std::ostream &rstrOut) const; /** Writes a VRML file. */ bool SaveVRML (std::ostream &rstrOut) const; /** Writes a Nastran file. */ @@ -217,7 +217,7 @@ public: protected: /** Writes an X3D file. */ - bool SaveX3DContent (std::ostream &rstrOut) const; + bool SaveX3DContent (std::ostream &rstrOut, bool exportViewpoints) const; protected: const MeshKernel &_rclMesh; /**< reference to mesh data structure */ diff --git a/src/Mod/Mesh/App/MeshPyImp.cpp b/src/Mod/Mesh/App/MeshPyImp.cpp index 4bcd3474f7..541c94efc6 100644 --- a/src/Mod/Mesh/App/MeshPyImp.cpp +++ b/src/Mod/Mesh/App/MeshPyImp.cpp @@ -210,26 +210,26 @@ PyObject* MeshPy::write(PyObject *args, PyObject *kwds) MeshCore::MeshIO::Format format = MeshCore::MeshIO::Undefined; std::map ext; - ext["BMS" ] = MeshCore::MeshIO::BMS; - ext["STL" ] = MeshCore::MeshIO::BSTL; - ext["AST" ] = MeshCore::MeshIO::ASTL; - ext["OBJ" ] = MeshCore::MeshIO::OBJ; - ext["SMF" ] = MeshCore::MeshIO::SMF; - ext["OFF" ] = MeshCore::MeshIO::OFF; - ext["IDTF"] = MeshCore::MeshIO::IDTF; - ext["MGL" ] = MeshCore::MeshIO::MGL; - ext["IV" ] = MeshCore::MeshIO::IV; - ext["X3D" ] = MeshCore::MeshIO::X3D; - ext["HTML"] = MeshCore::MeshIO::HTML; - ext["VRML"] = MeshCore::MeshIO::VRML; - ext["WRL" ] = MeshCore::MeshIO::VRML; - ext["WRZ" ] = MeshCore::MeshIO::WRZ; - ext["NAS" ] = MeshCore::MeshIO::NAS; - ext["BDF" ] = MeshCore::MeshIO::NAS; - ext["PLY" ] = MeshCore::MeshIO::PLY; - ext["APLY"] = MeshCore::MeshIO::APLY; - ext["PY" ] = MeshCore::MeshIO::PY; - ext["ASY" ] = MeshCore::MeshIO::ASY; + ext["BMS" ] = MeshCore::MeshIO::BMS; + ext["STL" ] = MeshCore::MeshIO::BSTL; + ext["AST" ] = MeshCore::MeshIO::ASTL; + ext["OBJ" ] = MeshCore::MeshIO::OBJ; + ext["SMF" ] = MeshCore::MeshIO::SMF; + ext["OFF" ] = MeshCore::MeshIO::OFF; + ext["IDTF" ] = MeshCore::MeshIO::IDTF; + ext["MGL" ] = MeshCore::MeshIO::MGL; + ext["IV" ] = MeshCore::MeshIO::IV; + ext["X3D" ] = MeshCore::MeshIO::X3D; + ext["X3DOM"] = MeshCore::MeshIO::X3DOM; + ext["VRML" ] = MeshCore::MeshIO::VRML; + ext["WRL" ] = MeshCore::MeshIO::VRML; + ext["WRZ" ] = MeshCore::MeshIO::WRZ; + ext["NAS" ] = MeshCore::MeshIO::NAS; + ext["BDF" ] = MeshCore::MeshIO::NAS; + ext["PLY" ] = MeshCore::MeshIO::PLY; + ext["APLY" ] = MeshCore::MeshIO::APLY; + ext["PY" ] = MeshCore::MeshIO::PY; + ext["ASY" ] = MeshCore::MeshIO::ASY; static char* keywords_path[] = {"Filename","Format","Name","Material",NULL}; if (PyArg_ParseTupleAndKeywords(args, kwds, "et|ssO", keywords_path, "utf-8", diff --git a/src/Mod/Mesh/Gui/Command.cpp b/src/Mod/Mesh/Gui/Command.cpp index 5260c9409a..1e57b26b40 100644 --- a/src/Mod/Mesh/Gui/Command.cpp +++ b/src/Mod/Mesh/Gui/Command.cpp @@ -516,7 +516,7 @@ void CmdMeshExport::activated(int) ext << qMakePair(QString::fromLatin1("%1 (*.off)").arg(QObject::tr("Object File Format")), "OFF"); ext << qMakePair(QString::fromLatin1("%1 (*.iv)").arg(QObject::tr("Inventor V2.1 ascii")), "IV"); ext << qMakePair(QString::fromLatin1("%1 (*.x3d)").arg(QObject::tr("X3D Extensible 3D")), "X3D"); - ext << qMakePair(QString::fromLatin1("%1 (*.html)").arg(QObject::tr("WebGL/X3D")), "HTML"); + ext << qMakePair(QString::fromLatin1("%1 (*.xhtml)").arg(QObject::tr("WebGL/X3D")), "X3DOM"); ext << qMakePair(QString::fromLatin1("%1 (*.ply)").arg(QObject::tr("Stanford Polygon")), "PLY"); ext << qMakePair(QString::fromLatin1("%1 (*.wrl *.vrml)").arg(QObject::tr("VRML V2.0")), "VRML"); ext << qMakePair(QString::fromLatin1("%1 (*.wrz)").arg(QObject::tr("Compressed VRML 2.0")), "WRZ");