From 898e0fb359c143bea4ce93d0ef85d0c839ed3dce Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 26 Nov 2015 15:27:40 +0100 Subject: [PATCH] + make API of InventorBuilder more flexible and add new methods --- src/Base/Builder3D.cpp | 119 +++++++++++++++++++++---------- src/Base/Builder3D.h | 101 ++++++++++++++++++++++---- src/Mod/Mesh/App/Core/MeshIO.cpp | 93 ++++++++---------------- src/Mod/Mesh/App/MeshPyImp.cpp | 8 ++- src/Mod/Part/App/TopoShape.cpp | 8 ++- 5 files changed, 214 insertions(+), 115 deletions(-) diff --git a/src/Base/Builder3D.cpp b/src/Base/Builder3D.cpp index 3c4956cff..7ced84820 100644 --- a/src/Base/Builder3D.cpp +++ b/src/Base/Builder3D.cpp @@ -331,7 +331,8 @@ void Builder3D::saveToFile(const char* FileName) // ----------------------------------------------------------------------------- InventorBuilder::InventorBuilder(std::ostream& output) - : result(output),bStartEndOpen(false),bClosed(false), indent(0) + : result(output) + , indent(0) { result << "#Inventor V2.1 ascii " << std::endl << std::endl; beginSeparator(); @@ -344,8 +345,8 @@ InventorBuilder:: ~InventorBuilder() void InventorBuilder::close() { - if (!bClosed) { - bClosed = true; + if (indent > 0) { + indent = 0; endSeparator(); } } @@ -362,6 +363,28 @@ void InventorBuilder::endSeparator() result << Base::blanks(indent) << "}" << std::endl; } +void InventorBuilder::addInfo(const char* text) +{ + result << Base::blanks(indent) << "Info { " << std::endl; + result << Base::blanks(indent) << " string \"" << text << "\"" << std::endl; + result << Base::blanks(indent) << "} " << std::endl; +} + +void InventorBuilder::addLabel(const char* text) +{ + result << Base::blanks(indent) << "Label { " << std::endl; + result << Base::blanks(indent) << " label \"" << text << "\"" << std::endl; + result << Base::blanks(indent) << "} " << std::endl; +} + +void InventorBuilder::addBaseColor(float color_r,float color_g,float color_b) +{ + result << Base::blanks(indent) << "BaseColor { " << std::endl; + result << Base::blanks(indent) << " rgb " + << color_r << " "<< color_g << " "<< color_b << std::endl; + result << Base::blanks(indent) << "} " << std::endl; +} + void InventorBuilder::addMaterial(float color_r,float color_g,float color_b) { result << Base::blanks(indent) << "Material { " << std::endl; @@ -386,6 +409,13 @@ void InventorBuilder::addDrawStyle(short pointSize, short lineWidth, unsigned sh << Base::blanks(indent) << "}" << std::endl; } +void InventorBuilder::addShapeHints(float crease) +{ + result << Base::blanks(indent) << "ShapeHints {" << std::endl + << Base::blanks(indent) << " creaseAngle " << crease << std::endl + << Base::blanks(indent) << "}" << std::endl; +} + //************************************************************************** // points handling @@ -400,7 +430,7 @@ void InventorBuilder::beginPoints() { result << Base::blanks(indent) << "Coordinate3 { " << std::endl; indent += 2; - result << Base::blanks(indent) << "point [ "; + result << Base::blanks(indent) << "point [ " << std::endl; indent += 2; } @@ -416,11 +446,17 @@ void InventorBuilder::addPoint(const Vector3f &vec) addPoint(vec.x,vec.y,vec.z); } +void InventorBuilder::addPoints(const std::vector &vec) +{ + for (std::vector::const_iterator it = vec.begin(); it != vec.end(); ++it) + addPoint(it->x, it->y, it->z); +} + /** * Ends the point set operations and write the resulting inventor string. * @see startPoints() */ -void InventorBuilder::endPoints(void) +void InventorBuilder::endPoints() { indent -= 2; result << Base::blanks(indent) << "]" << std::endl; @@ -435,7 +471,7 @@ void InventorBuilder::endPoints(void) * @see beginPoints() * @see endPoints() */ -void InventorBuilder::addPointSet(void) +void InventorBuilder::addPointSet() { result << Base::blanks(indent) << "PointSet { } " << std::endl; } @@ -447,7 +483,7 @@ void InventorBuilder::addPointSet(void) * @see beginPoints() * @see endPoints() */ -void InventorBuilder::addLineSet(void) +void InventorBuilder::addLineSet() { result << Base::blanks(indent) << "LineSet { } " << std::endl; } @@ -467,9 +503,6 @@ void InventorBuilder::addLineSet(void) */ void InventorBuilder::addText(float pos_x, float pos_y , float pos_z,const char * text, float color_r,float color_g,float color_b) { - // addSinglePoint() not between startXXX() and endXXX() allowed - assert( bStartEndOpen == false ); - result << Base::blanks(indent) << "Separator { " << std::endl << Base::blanks(indent) << " Material { diffuseColor " << color_r << " "<< color_g << " "<< color_b << "} " << std::endl @@ -598,39 +631,53 @@ void InventorBuilder::addLineSet(const std::vector& points, short line //************************************************************************** // triangle handling -void InventorBuilder::addIndexedFaceSet(const std::vector& points, const std::vector& indices, float crease) +void InventorBuilder::addIndexedFaceSet(const std::vector& indices) { - if (points.empty() || indices.size() < 4) + if (indices.size() < 4) return; - result << " Separator { " << std::endl - << " ShapeHints {" << std::endl - << " creaseAngle " << crease << std::endl - << " }" << std::endl - << " Coordinate3 { " << std::endl - << " point [ "; - std::vector::const_iterator it_last_p = points.end()-1; - for (std::vector::const_iterator it = points.begin(); it != points.end(); ++it) { - if (it != it_last_p) - result << it->x << " " << it->y << " " << it->z << "," << std::endl; - else - result << it->x << " " << it->y << " " << it->z << " ] " << std::endl; - } - result << " } " << std::endl - << " IndexedFaceSet { " << std::endl - << " coordIndex [ "; + result << Base::blanks(indent) << "IndexedFaceSet { " << std::endl + << Base::blanks(indent) << " coordIndex [ " << std::endl; + + indent += 4; std::vector::const_iterator it_last_f = indices.end()-1; int index=0; for (std::vector::const_iterator it = indices.begin(); it != indices.end(); ++it) { - if (it != it_last_f) - result << *it << ", "; - else - result << *it << " ] "; - if (++index%8==0) - result << std::endl; + if (index % 8 == 0) + result << Base::blanks(indent); + if (it != it_last_f) + result << *it << ", "; + else + result << *it << " ] " << std::endl; + if (++index % 8 == 0) + result << std::endl; } - result << " } " << std::endl - << " } " << std::endl; + indent -= 4; + + result << Base::blanks(indent) << "} " << std::endl; +} + +void InventorBuilder::beginNormal() +{ + result << Base::blanks(indent) << "Normal { " << std::endl; + indent += 2; + result << Base::blanks(indent) << "vector [ " << std::endl; + indent += 2; +} + +void InventorBuilder::endNormal() +{ + indent -= 2; + result << Base::blanks(indent) << "]" << std::endl; + indent -= 2; + result << Base::blanks(indent) << "}" << std::endl; +} + +void InventorBuilder::addNormalBinding(const char* binding) +{ + result << Base::blanks(indent) << "NormalBinding {" << std::endl + << Base::blanks(indent) << " value " << binding << std::endl + << Base::blanks(indent) << "}" << std::endl; } void InventorBuilder::addSingleTriangle(const Vector3f& pt0, const Vector3f& pt1, const Vector3f& pt2, diff --git a/src/Base/Builder3D.h b/src/Base/Builder3D.h index 11e5a2510..bee4327a7 100644 --- a/src/Base/Builder3D.h +++ b/src/Base/Builder3D.h @@ -141,33 +141,104 @@ private: class BaseExport InventorBuilder { public: - /// Construction - InventorBuilder(std::ostream&); - /// Destruction + /*! + * \brief Construction of an InventorBuilder instance. + * This automatically opens a separator node. + * \param str - stream to write the content into + */ + InventorBuilder(std::ostream& str); + /*! + * \brief Destruction of an InventorBuilder instance + */ virtual ~InventorBuilder(); + /*! + * \brief If needed closes the first opened separator node. + * This method must not be used more than one time for an instance. + */ void close(); + /*! + * \brief Sets a separator node. + */ void beginSeparator(); + /*! + * \brief Closes the last added separator node. + */ void endSeparator(); + /*! + * \brief Sets an info node. + * \param str - text set to the info node + */ + void addInfo(const char* str); + /*! + * \brief Sets a label node. + * \param str - text set to the label node + */ + void addLabel(const char* str); + /*! + * \brief Sets a base color node. The colors are in the range [0, 1]. + * \param color_r - red color + * \param color_g - green color + * \param color_b - blue color + */ + void addBaseColor(float color_r,float color_g,float color_b); + /*! + * \brief Sets a material node. The colors are in the range [0, 1]. + * \param color_r - red color + * \param color_g - green color + * \param color_b - blue color + */ void addMaterial(float color_r,float color_g,float color_b); - void addMaterialBinding(const char* = "OVERALL"); + /*! + * \brief Sets a material binding node. + * \param binding - binding of the material. Allowed values are: + * OVERALL, PER_PART, PER_PART_INDEXED, PER_FACE, PER_FACE_INDEXED, PER_VERTEX, + * PER_VERTEX_INDEXED and DEFAULT. + */ + void addMaterialBinding(const char* binding = "OVERALL"); + /*! + * \brief Sets a draw style node. + * \param pointSize - the point size + * \param lineWidth - the line width + * \param linePattern - the line pattern + * \param style - the draw style + */ void addDrawStyle(short pointSize, short lineWidth, unsigned short linePattern = 0xffff, const char* style="FILLED"); + /*! + * \brief Sets a shape hints node. + * \param crease - the crease angle in radians + */ + void addShapeHints(float crease=0.0f); + + /** @name Add coordinates */ + //@{ + /// add a single point + void addPoint(float x, float y, float z); + /// add a single point + void addPoint(const Vector3f &vec); + /// add a list of points + void addPoints(const std::vector &vec); + //@} /** @name Point set handling */ //@{ /// starts a point set void beginPoints(); - /// insert a point in an point set - void addPoint(float x, float y, float z); - /// add a vector to a point set - void addPoint(const Vector3f &vec); /// ends the points set operation - void endPoints(void); + void endPoints(); /// add an SoPointSet node - void addPointSet(void); - /// add an SoLineSet node - void addLineSet(void); + void addPointSet(); + //@} + + /** @name Normal handling */ + //@{ + /// starts a point set + void beginNormal(); + /// ends the points set operation + void endNormal(); + /// add normal binding node + void addNormalBinding(const char*); //@} /** @name Line/Direction handling */ @@ -181,7 +252,8 @@ public: /// add a line defined by a list of points whereat always a pair (i.e. a point and the following point) builds a line. void addLineSet(const std::vector& points, short lineSize=2, float color_r=1.0,float color_g=1.0,float color_b=1.0, unsigned short linePattern = 0xffff); - void addIndexedFaceSet(const std::vector& points, const std::vector& indices, float crease); + /// add an SoLineSet node + void addLineSet(); //@} /** @name Triangle handling */ @@ -191,6 +263,7 @@ public: float color_r=1.0,float color_g=1.0,float color_b=1.0); void addSinglePlane(const Vector3f& base, const Vector3f& eX, const Vector3f& eY, float length, float width, bool filled = true, short lineSize=2, float color_r=1.0,float color_g=1.0,float color_b=1.0); + void addIndexedFaceSet(const std::vector& indices); //@} /** @name Surface handling */ @@ -229,8 +302,6 @@ private: private: std::ostream& result; - bool bStartEndOpen; - bool bClosed; int indent; }; diff --git a/src/Mod/Mesh/App/Core/MeshIO.cpp b/src/Mod/Mesh/App/Core/MeshIO.cpp index ff627e814..81b648f9f 100644 --- a/src/Mod/Mesh/App/Core/MeshIO.cpp +++ b/src/Mod/Mesh/App/Core/MeshIO.cpp @@ -29,6 +29,7 @@ #include "MeshIO.h" #include "Builder.h" +#include #include #include #include @@ -2075,99 +2076,67 @@ bool MeshOutput::SaveInventor (std::ostream &rstrOut) const MeshPointIterator clPtIter(_rclMesh), clPtEnd(_rclMesh); clPtIter.Transform(this->_transform); const MeshGeomFacet* pclFacet; - unsigned long ulAllFacets = _rclMesh.CountFacets(); Base::SequencerLauncher seq("Saving...", _rclMesh.CountFacets() + 1); rstrOut.precision(6); rstrOut.setf(std::ios::fixed | std::ios::showpoint); // Header info - rstrOut << "#Inventor V2.1 ascii\n" << std::endl; - rstrOut << "# Created by FreeCAD " << std::endl; - rstrOut << "# Triangle mesh contains " << _rclMesh.CountPoints() << " vertices" - << " and " << _rclMesh.CountFacets() << " faces" << std::endl; - rstrOut << "Separator {\n" << std::endl; - rstrOut << " Label {" << std::endl; - rstrOut << " label \"Triangle mesh\"\n }" << std::endl; + Base::InventorBuilder builder(rstrOut); + builder.beginSeparator(); + builder.addInfo("Created by FreeCAD "); + std::stringstream str; + str << "Triangle mesh contains " + << _rclMesh.CountPoints() + << " vertices and " + << _rclMesh.CountFacets() + << " faces"; + builder.addLabel(str.str().c_str()); // write out the normals of the facets - rstrOut << " Normal { " << std::endl; - rstrOut << " vector [ "; + builder.beginNormal(); clIter.Begin(); clEnd.End(); - pclFacet = &(*clIter); - rstrOut << pclFacet->GetNormal().x << " " - << pclFacet->GetNormal().y << " " - << pclFacet->GetNormal().z; - ++clIter; - while (clIter < clEnd) { pclFacet = &(*clIter); - rstrOut << ",\n " - << pclFacet->GetNormal().x << " " - << pclFacet->GetNormal().y << " " - << pclFacet->GetNormal().z; + builder.addPoint(pclFacet->GetNormal()); ++clIter; seq.next(true); // allow to cancel } - rstrOut << " ]\n\n }" << std::endl; + builder.endNormal(); // coordinates of the vertices - rstrOut << " NormalBinding {\n value PER_FACE\n }" << std::endl; - rstrOut << " Coordinate3 {\n point [ "; + builder.addNormalBinding("PER_FACE"); + + builder.beginPoints(); clPtIter.Begin(); clPtEnd.End(); - rstrOut << clPtIter->x << " " - << clPtIter->y << " " - << clPtIter->z; - ++clPtIter; - while (clPtIter < clPtEnd) { - rstrOut << ",\n " - << clPtIter->x << " " - << clPtIter->y << " " - << clPtIter->z; + builder.addPoint(*clPtIter); ++clPtIter; seq.next(true); // allow to cancel } - rstrOut << " ]\n\n }" << std::endl; + builder.endPoints(); // and finally the facets with their point indices - rstrOut << " IndexedFaceSet {\n coordIndex [ "; - - const MeshFacet clFacet = _rclMesh.GetFacets()[0]; - rstrOut << clFacet._aulPoints[0] << ", " - << clFacet._aulPoints[1] << ", " - << clFacet._aulPoints[2] << ", -1"; - - unsigned long i = 1; - while (i < ulAllFacets) { - // write two triples per line - const MeshFacet clFacet = _rclMesh.GetFacets()[i]; - if ( i%2==0 ) { - rstrOut << ",\n " - << clFacet._aulPoints[0] << ", " - << clFacet._aulPoints[1] << ", " - << clFacet._aulPoints[2] << ", -1"; - } - else { - rstrOut << ", " - << clFacet._aulPoints[0] << ", " - << clFacet._aulPoints[1] << ", " - << clFacet._aulPoints[2] << ", -1"; - } - ++i; + const MeshFacetArray& faces = _rclMesh.GetFacets(); + std::vector indices; + indices.reserve(4*faces.size()); + for (MeshFacetArray::_TConstIterator it = faces.begin(); it != faces.end(); ++it) { + indices.push_back(static_cast(it->_aulPoints[0])); + indices.push_back(static_cast(it->_aulPoints[1])); + indices.push_back(static_cast(it->_aulPoints[2])); + indices.push_back(-1); } - - rstrOut << " ]\n\n }" << std::endl; - rstrOut << "#End of triangle mesh \n}\n" << std::endl; + builder.addIndexedFaceSet(indices); + builder.endSeparator(); return true; } @@ -2219,8 +2188,8 @@ bool MeshOutput::SaveX3D (std::ostream &out) const out << " " << std::endl; } out << " " << std::endl; - out << " " << std::endl; + out << " " << std::endl; out << "