diff --git a/src/Base/Builder3D.cpp b/src/Base/Builder3D.cpp index 3708b20741..bb32456d08 100644 --- a/src/Base/Builder3D.cpp +++ b/src/Base/Builder3D.cpp @@ -166,6 +166,62 @@ std::ostream& InventorOutput::writeLine(const std::string& str) return result; } +void InventorOutput::increaseIndent() +{ + indent.increaseIndent(); +} + +void InventorOutput::decreaseIndent() +{ + indent.decreaseIndent(); +} + +// ----------------------------------------------------------------------------- + +void NodeItem::writeField(const char* field, const std::vector& rgb, InventorOutput& out) const +{ + if (rgb.empty()) + return; + + if (rgb.size() == 1) { + out.increaseIndent(); + out.write() << field << " " << rgb[0].red() << " " << rgb[0].green() << " " << rgb[0].blue() << '\n'; + out.decreaseIndent(); + } + else { + out.increaseIndent(); + out.write() << field << " [\n"; + out.increaseIndent(); + for (auto it : rgb) { + out.write() << it.red() << " " << it.green() << " " << it.blue() << '\n'; + } + out.decreaseIndent(); + out.decreaseIndent(); + } +} + +void NodeItem::writeField(const char* field, const std::vector& value, InventorOutput& out) const +{ + if (value.empty()) + return; + + if (value.size() == 1) { + out.increaseIndent(); + out.write() << field << " " << value[0] << '\n'; + out.decreaseIndent(); + } + else { + out.increaseIndent(); + out.write() << field << " [\n"; + out.increaseIndent(); + for (auto it : value) { + out.write() << it << '\n'; + } + out.decreaseIndent(); + out.decreaseIndent(); + } +} + // ----------------------------------------------------------------------------- LabelItem::LabelItem(const std::string& text) : text(text) @@ -262,6 +318,160 @@ void LineItem::write(InventorOutput& out) const // ----------------------------------------------------------------------------- +void MaterialItem::setAmbientColor(const std::vector& rgb) +{ + ambientColor = rgb; +} + +void MaterialItem::setDiffuseColor(const std::vector& rgb) +{ + diffuseColor = rgb; +} + +void MaterialItem::setSpecularColor(const std::vector& rgb) +{ + specularColor = rgb; +} + +void MaterialItem::setEmissiveColor(const std::vector& rgb) +{ + emissiveColor = rgb; +} + +void MaterialItem::setShininess(const std::vector& value) +{ + shininess = value; +} + +void MaterialItem::setTransparency(const std::vector& value) +{ + transparency = value; +} + +void MaterialItem::write(InventorOutput& out) const +{ + beginMaterial(out); + writeAmbientColor(out); + writeDiffuseColor(out); + writeSpecularColor(out); + writeEmissiveColor(out); + writeShininess(out); + writeTransparency(out); + endMaterial(out); +} + +void MaterialItem::beginMaterial(InventorOutput& out) const +{ + out.writeLine("Material {"); + out.increaseIndent(); +} + +void MaterialItem::endMaterial(InventorOutput& out) const +{ + out.decreaseIndent(); + out.writeLine("}"); +} + +void MaterialItem::writeAmbientColor(InventorOutput& out) const +{ + writeField("ambientColor", ambientColor, out); +} + +void MaterialItem::writeDiffuseColor(InventorOutput& out) const +{ + writeField("diffuseColor", diffuseColor, out); +} + +void MaterialItem::writeSpecularColor(InventorOutput& out) const +{ + writeField("specularColor", specularColor, out); +} + +void MaterialItem::writeEmissiveColor(InventorOutput& out) const +{ + writeField("emissiveColor", emissiveColor, out); +} + +void MaterialItem::writeShininess(InventorOutput& out) const +{ + writeField("shininess", shininess, out); +} + +void MaterialItem::writeTransparency(InventorOutput& out) const +{ + writeField("transparency", transparency, out); +} + +// ----------------------------------------------------------------------------- + +MaterialBindingItem::MaterialBindingItem(MaterialBinding bind) : bind(bind) +{ + +} + +void MaterialBindingItem::write(InventorOutput& out) const +{ + out.write() << "MaterialBinding { value " + << bind.bindingAsString() << " } \n"; +} + +// ----------------------------------------------------------------------------- + +DrawStyleItem::DrawStyleItem(DrawStyle style) : style(style) +{ + +} + +void DrawStyleItem::write(InventorOutput& out) const +{ + out.write() << "DrawStyle {\n"; + out.write() << " style " << style.styleAsString() << '\n'; + out.write() << " pointSize " << style.pointSize << '\n'; + out.write() << " lineWidth " << style.lineWidth << '\n'; + out.write() << " linePattern " << style.linePattern << '\n'; + out.write() << "}\n"; +} + +// ----------------------------------------------------------------------------- + +ShapeHintsItem::ShapeHintsItem(float creaseAngle) : creaseAngle(creaseAngle) +{ + +} + +void ShapeHintsItem::write(InventorOutput& out) const +{ + out.write() << "ShapeHints {\n"; + out.write() << " creaseAngle " << creaseAngle << '\n'; + out.write() << "}\n"; +} + +// ----------------------------------------------------------------------------- + +PolygonOffsetItem::PolygonOffsetItem(PolygonOffset offset) : offset(offset) +{ + +} + +void PolygonOffsetItem::write(InventorOutput& out) const +{ + out.write() << "PolygonOffset {\n"; + out.write() << " factor " << offset.factor << '\n'; + out.write() << " units " << offset.units << '\n'; + out.write() << " styles " << offset.styleAsString() << '\n'; + out.write() << " on " << (offset.on ? "TRUE" : "FALSE") << '\n'; + out.write() << "}\n"; +} + +// ----------------------------------------------------------------------------- + +void PointSetItem::write(InventorOutput& out) const +{ + out.writeLine("PointSet { }"); +} + +// ----------------------------------------------------------------------------- + InventorBuilder::InventorBuilder(std::ostream& output) : result(output) { diff --git a/src/Base/Builder3D.h b/src/Base/Builder3D.h index bc7192fcab..fc92f4f346 100644 --- a/src/Base/Builder3D.h +++ b/src/Base/Builder3D.h @@ -177,6 +177,8 @@ public: std::ostream& writeLine(); std::ostream& writeLine(const char*); std::ostream& writeLine(const std::string&); + void increaseIndent(); + void decreaseIndent(); private: std::ostream& result; @@ -188,8 +190,15 @@ class BaseExport NodeItem public: virtual ~NodeItem() = default; virtual void write(InventorOutput& out) const = 0; + +protected: + void writeField(const char* field, const std::vector& rgb, InventorOutput& out) const; + void writeField(const char* field, const std::vector& value, InventorOutput& out) const; }; +/*! + * \brief The LabelItem class supports the SoLabel node. + */ class BaseExport LabelItem : public NodeItem { public: @@ -200,6 +209,9 @@ private: std::string text; }; +/*! + * \brief The InfoItem class supports the SoInfo node. + */ class BaseExport InfoItem : public NodeItem { public: @@ -210,6 +222,9 @@ private: std::string text; }; +/*! + * \brief The BaseColorItem class supports the SoBaseColor node. + */ class BaseExport BaseColorItem : public NodeItem { public: @@ -244,6 +259,100 @@ private: ColorRGB rgb; }; +/*! + * \brief The MaterialItem class supports the SoMaterial node. + */ +class BaseExport MaterialItem : public NodeItem +{ +public: + void setAmbientColor(const std::vector& rgb); + void setDiffuseColor(const std::vector& rgb); + void setSpecularColor(const std::vector& rgb); + void setEmissiveColor(const std::vector& rgb); + void setShininess(const std::vector& value); + void setTransparency(const std::vector& value); + void write(InventorOutput& out) const override; + +private: + void beginMaterial(InventorOutput& out) const; + void endMaterial(InventorOutput& out) const; + void writeAmbientColor(InventorOutput& out) const; + void writeDiffuseColor(InventorOutput& out) const; + void writeSpecularColor(InventorOutput& out) const; + void writeEmissiveColor(InventorOutput& out) const; + void writeShininess(InventorOutput& out) const; + void writeTransparency(InventorOutput& out) const; + +private: + std::vector ambientColor; + std::vector diffuseColor; + std::vector specularColor; + std::vector emissiveColor; + std::vector shininess; + std::vector transparency; +}; + +/*! + * \brief The MaterialBindingItem class supports the SoMaterialBinding node. + */ +class BaseExport MaterialBindingItem : public NodeItem +{ +public: + explicit MaterialBindingItem(MaterialBinding bind); + void write(InventorOutput& out) const override; + +private: + MaterialBinding bind; +}; + +/*! + * \brief The DrawStyleItem class supports the SoDrawStyle node. + */ +class BaseExport DrawStyleItem : public NodeItem +{ +public: + explicit DrawStyleItem(DrawStyle style); + void write(InventorOutput& out) const override; + +private: + DrawStyle style; +}; + +/*! + * \brief The ShapeHintsItem class supports the SoShapeHints node. + */ +class BaseExport ShapeHintsItem : public NodeItem +{ +public: + explicit ShapeHintsItem(float creaseAngle); + void write(InventorOutput& out) const override; + +private: + float creaseAngle; +}; + +/*! + * \brief The PolygonOffsetItem class supports the SoPolygonOffset node. + */ +class BaseExport PolygonOffsetItem : public NodeItem +{ +public: + explicit PolygonOffsetItem(PolygonOffset offset); + void write(InventorOutput& out) const override; + +private: + PolygonOffset offset; +}; + +/*! + * \brief The PointSetItem class supports the SoPointSet node. + */ +class BaseExport PointSetItem : public NodeItem +{ +public: + void write(InventorOutput& out) const override; +}; + /** * This class does basically the same as Builder3D except that it writes the data * directly into a given stream without buffering the output data in a string stream. @@ -257,7 +366,6 @@ class BaseExport InventorBuilder public: /*! * \brief Construction of an InventorBuilder instance. - * This automatically opens a separator node. * \param str - stream to write the content into */ explicit InventorBuilder(std::ostream& str); @@ -265,7 +373,10 @@ public: * \brief Destruction of an InventorBuilder instance */ virtual ~InventorBuilder(); - + /*! + * \brief addNode + * Writes the content of the added node to the output stream. + */ void addNode(const NodeItem&); /*! * \brief Sets a separator node. diff --git a/src/Mod/Mesh/App/Mesh.cpp b/src/Mod/Mesh/App/Mesh.cpp index 48319d3dd6..dd43f88e5d 100644 --- a/src/Mod/Mesh/App/Mesh.cpp +++ b/src/Mod/Mesh/App/Mesh.cpp @@ -552,7 +552,8 @@ void MeshObject::writeInventor(std::ostream& str, float creaseangle) const Base::InventorBuilder builder(str); builder.beginSeparator(); builder.addTransformation(getTransform()); - builder.addShapeHints(creaseangle); + Base::ShapeHintsItem shapeHints{creaseangle}; + builder.addNode(shapeHints); builder.beginPoints(); builder.addPoints(coords); builder.endPoints(); diff --git a/src/Mod/Part/App/TopoShape.cpp b/src/Mod/Part/App/TopoShape.cpp index 5d5be9ee3b..f02815ae6e 100644 --- a/src/Mod/Part/App/TopoShape.cpp +++ b/src/Mod/Part/App/TopoShape.cpp @@ -1089,10 +1089,14 @@ void TopoShape::exportFaceSet(double dev, double ca, } builder.beginSeparator(); - builder.addShapeHints((float)ca); + Base::ShapeHintsItem shapeHints{static_cast(ca)}; + builder.addNode(shapeHints); if (supportFaceColors) { App::Color c = colors[index]; - builder.addMaterial(Base::ColorRGB{c.r, c.g, c.b}, c.a); + Base::MaterialItem material; + material.setDiffuseColor({Base::ColorRGB{c.r, c.g, c.b}}); + material.setTransparency({c.a}); + builder.addNode(material); } builder.beginPoints();