diff --git a/src/Base/Builder3D.cpp b/src/Base/Builder3D.cpp index dc1a375152..c83835b40e 100644 --- a/src/Base/Builder3D.cpp +++ b/src/Base/Builder3D.cpp @@ -51,6 +51,25 @@ using namespace Base; //************************************************************************** // Construction/Destruction +constexpr float valueMinLegal {-1.0F}; +constexpr float valueMaxLegal {1.0F}; + +ColorRGB::ColorRGB() : Rgb{1.0F, 1.0F, 1.0F} +{ +} + +ColorRGB::ColorRGB(float red, float green, float blue) + : Rgb{valueInRange(red), + valueInRange(green), + valueInRange(blue)} +{ +} + +float ColorRGB::valueInRange(float value) +{ + return std::clamp(value, valueMinLegal, valueMaxLegal); +} + /** * A constructor. * A more elaborate description of the constructor. @@ -58,8 +77,8 @@ using namespace Base; Builder3D::Builder3D() : bStartEndOpen(false) { - result << "#Inventor V2.1 ascii \n\n"; - result << "Separator { "; + result << "#Inventor V2.1 ascii \n\n"; + result << "Separator { "; } /** @@ -78,34 +97,25 @@ Builder3D::~Builder3D() = default; * Try to put all points in one set. * @see endPoints() * @param pointSize the point size in pixel that are displayed. - * @param color_r red part of the point color (0.0 - 1.0). - * @param color_g green part of the point color (0.0 - 1.0). - * @param color_b blue part of the point color (0.0 - 1.0). + * @param ColorRGB point color. */ -void Builder3D::startPoints(short pointSize, float color_r, float color_g, float color_b) +void Builder3D::startPoints(short pointSize, const ColorRGB& color) { - bStartEndOpen = true; - result << "Separator { "; - result << "Material { "; - result << "diffuseColor " << color_r << " "<< color_g << " " << color_b; - result << "} "; - result << "MaterialBinding { value PER_PART } "; - result << "DrawStyle { pointSize " << pointSize << "} "; - result << "Coordinate3 { "; - result << "point [ "; + bStartEndOpen = true; + result << "Separator { "; + result << "Material { "; + result << "diffuseColor " << color.red() << " "<< color.green() << " " << color.blue(); + result << "} "; + result << "MaterialBinding { value PER_PART } "; + result << "DrawStyle { pointSize " << pointSize << "} "; + result << "Coordinate3 { "; + result << "point [ "; } -/// insert a point in a point set -void Builder3D::addPoint(float x, float y, float z) +/// add a point to a point set +void Builder3D::addPoint(const Vector3f &point) { - result << x << " " << y << " " << z << ","; -} - - -/// add a vector to a point set -void Builder3D::addPoint(const Vector3f &vec) -{ - addPoint(vec.x, vec.y, vec.z); + result << point.x << " " << point.y << " " << point.z << ","; } /** * Ends the point set operations and write the resulting inventor string. @@ -113,37 +123,31 @@ void Builder3D::addPoint(const Vector3f &vec) */ void Builder3D::endPoints() { - result << "] "; - result << "} "; - result << "PointSet { } "; - result << "} "; - bStartEndOpen = false; + result << "] "; + result << "} "; + result << "PointSet { } "; + result << "} "; + bStartEndOpen = false; } -void Builder3D::addSinglePoint(float x, float y, float z, short pointSize, float color_r, float color_g, float color_b) +void Builder3D::addSinglePoint(const Base::Vector3f &point, DrawStyle drawStyle, const ColorRGB& color) { - // addSinglePoint() not between startXXX() and endXXX() allowed - assert(!bStartEndOpen); + // addSinglePoint() not between startXXX() and endXXX() allowed + assert(!bStartEndOpen); - result << "Separator { "; - result << "Material { "; - result << "diffuseColor " << color_r << " "<< color_g << " "<< color_b; - result << "} "; - result << "MaterialBinding { value PER_PART } "; - result << "DrawStyle { pointSize " << pointSize << "} "; - result << "Coordinate3 { "; - result << "point [ "; - result << x << " " << y << " " << z << ","; - result << "] "; - result << "} "; - result << "PointSet { } "; - result << "} "; - -} - -void Builder3D::addSinglePoint(const Base::Vector3f &vec, short pointSize, float color_r, float color_g, float color_b) -{ - addSinglePoint(vec.x, vec.y , vec.z, pointSize, color_r, color_g, color_b); + result << "Separator { "; + result << "Material { "; + result << "diffuseColor " << color.red() << " "<< color.green() << " "<< color.blue(); + result << "} "; + result << "MaterialBinding { value PER_PART } "; + result << "DrawStyle { pointSize " << drawStyle.pointSize << "} "; + result << "Coordinate3 { "; + result << "point [ "; + result << point.x << " " << point.y << " " << point.z << ","; + result << "] "; + result << "} "; + result << "PointSet { } "; + result << "} "; } //************************************************************************** @@ -153,87 +157,77 @@ void Builder3D::addSinglePoint(const Base::Vector3f &vec, short pointSize, float /** * Add a Text with a given position to the 3D set. The origin is the * lower leftmost corner. - * @param pos_x,pos_y,pos_z origin of the text + * @param point origin of the text * @param text the text to display. - * @param color_r red part of the text color (0.0 - 1.0). - * @param color_g green part of the text color (0.0 - 1.0). - * @param color_b blue part of the text color (0.0 - 1.0). + * @param color text color. */ -void Builder3D::addText(float pos_x, float pos_y , float pos_z, const char * text, float color_r, float color_g, float color_b) +void Builder3D::addText(const Base::Vector3f& point, const char * text, const Base::ColorRGB& color) { // addSinglePoint() not between startXXX() and endXXX() allowed assert(!bStartEndOpen); result << "Separator { " - << "Material { diffuseColor " << color_r << " "<< color_g << " "<< color_b << "} " - << "Transform { translation " << pos_x << " "<< pos_y << " "<< pos_z << "} " + << "Material { diffuseColor " << color.red() << " "<< color.green() << " "<< color.blue() << "} " + << "Transform { translation " << point.x << " "<< point.y << " "<< point.z << "} " << "Text2 { string \" " << text << "\" " << "} " << "} "; } -void Builder3D::addText(const Base::Vector3f &vec, const char * text, float color_r, float color_g, float color_b) -{ - addText(vec.x, vec.y, vec.z, text, color_r, color_g, color_b); -} - void Builder3D::clear () { - // under gcc stringstream::str() returns a copy not a reference + // under gcc stringstream::str() returns a copy not a reference #if defined(_MSC_VER) - result.str().clear(); + result.str().clear(); #endif - result.clear(); + result.clear(); } //************************************************************************** // line/arrow handling -void Builder3D::addSingleLine(const Vector3f& pt1, const Vector3f& pt2, short lineSize, float color_r, float color_g, float color_b, unsigned short linePattern) +void Builder3D::addSingleLine(const Base::Line3f& line, DrawStyle drawStyle, const ColorRGB& color) { - char lp[20]; - sprintf(lp, "0x%x", linePattern); - //char lp[20] = "0x"; - //itoa(linePattern, buf, 16); - //strcat(lp, buf); + char pattern[20]; + sprintf(pattern, "0x%x", drawStyle.linePattern); - result << "Separator { " - << "Material { diffuseColor " << color_r << " "<< color_g << " "<< color_b << "} " - << "DrawStyle { lineWidth " << lineSize << " linePattern " << lp << " } " - << "Coordinate3 { " - << "point [ " - << pt1.x << " " << pt1.y << " " << pt1.z << "," - << pt2.x << " " << pt2.y << " " << pt2.z - << "] " - << "} " - << "LineSet { } " - << "} "; + result << "Separator { " + << "Material { diffuseColor " << color.red() << " "<< color.green() << " "<< color.blue() << "} " + << "DrawStyle { lineWidth " << drawStyle.lineWidth << " linePattern " << pattern << " } " + << "Coordinate3 { " + << "point [ " + << line.p1.x << " " << line.p1.y << " " << line.p1.z << "," + << line.p2.x << " " << line.p2.y << " " << line.p2.z + << "] " + << "} " + << "LineSet { } " + << "} "; } -void Builder3D::addSingleArrow(const Vector3f& pt1, const Vector3f& pt2, short lineSize, float color_r, float color_g, float color_b, unsigned short /*linePattern*/) +void Builder3D::addSingleArrow(const Base::Line3f& line, DrawStyle drawStyle, const ColorRGB& color) { - float l = (pt2 - pt1).Length(); + float l = line.Length(); float cl = l / 10.0f; float cr = cl / 2.0f; - Vector3f dir = pt2 - pt1; + Vector3f dir = line.GetDirection(); dir.Normalize(); dir.Scale(l-cl, l-cl, l-cl); - Vector3f pt2s = pt1 + dir; + Vector3f pt2s = line.p1 + dir; dir.Normalize(); dir.Scale(l-cl/2.0f, l-cl/2.0f, l-cl/2.0f); - Vector3f cpt = pt1 + dir; + Vector3f cpt = line.p1 + dir; Vector3f rot = Vector3f(0.0f, 1.0f, 0.0f) % dir; rot.Normalize(); float a = Vector3f(0.0f, 1.0f, 0.0f).GetAngle(dir); result << "Separator { " - << "Material { diffuseColor " << color_r << " "<< color_g << " "<< color_b << "} " - << "DrawStyle { lineWidth " << lineSize << "} " + << "Material { diffuseColor " << color.red() << " "<< color.green() << " "<< color.blue() << "} " + << "DrawStyle { lineWidth " << drawStyle.lineWidth << "} " << "Coordinate3 { " << "point [ " - << pt1.x << " " << pt1.y << " " << pt1.z << "," + << line.p1.x << " " << line.p1.y << " " << line.p1.z << "," << pt2s.x << " " << pt2s.y << " " << pt2s.z << "] " << "} " @@ -250,46 +244,45 @@ void Builder3D::addSingleArrow(const Vector3f& pt1, const Vector3f& pt2, short l //************************************************************************** // triangle handling -void Builder3D::addSingleTriangle(const Vector3f& pt0, const Vector3f& pt1, const Vector3f& pt2, bool filled, short lineSize, float color_r, float color_g, float color_b) +void Builder3D::addSingleTriangle(const Triangle& triangle, DrawStyle drawStyle, const ColorRGB& color) { - std::string fs = ""; - if (filled) - { - fs = "IndexedFaceSet { coordIndex[ 0, 1, 2, -1 ] } "; - } + std::string fs = ""; + if (drawStyle.style == DrawStyle::Style::Filled) { + fs = "IndexedFaceSet { coordIndex[ 0, 1, 2, -1 ] } "; + } result << "Separator { " - << "Material { diffuseColor " << color_r << " "<< color_g << " "<< color_b << "} " - << "DrawStyle { lineWidth " << lineSize << "} " - << "Coordinate3 { " - << "point [ " - << pt0.x << " " << pt0.y << " " << pt0.z << "," - << pt1.x << " " << pt1.y << " " << pt1.z << "," - << pt2.x << " " << pt2.y << " " << pt2.z << "," - << "] " - << "} " - << "LineSet { } " - << fs - << "} "; + << "Material { diffuseColor " << color.red() << " "<< color.green() << " "<< color.blue() << "} " + << "DrawStyle { lineWidth " << drawStyle.lineWidth << "} " + << "Coordinate3 { " + << "point [ " + << triangle.getPoint1().x << " " << triangle.getPoint1().y << " " << triangle.getPoint1().z << "," + << triangle.getPoint2().x << " " << triangle.getPoint2().y << " " << triangle.getPoint2().z << "," + << triangle.getPoint3().x << " " << triangle.getPoint3().y << " " << triangle.getPoint3().z << "," + << "] " + << "} " + << "LineSet { } " + << fs + << "} "; } void Builder3D::addTransformation(const Base::Matrix4D& transform) { - Base::Vector3f cAxis, cBase; - float fAngle = 0.0f, fTranslation = 0.0f; - transform.toAxisAngle(cBase, cAxis,fAngle,fTranslation); - cBase.x = static_cast(transform[0][3]); - cBase.y = static_cast(transform[1][3]); - cBase.z = static_cast(transform[2][3]); - addTransformation(cBase,cAxis,fAngle); + Base::Placement placement; + placement.fromMatrix(transform); + addTransformation(placement); } -void Builder3D::addTransformation(const Base::Vector3f& translation, const Base::Vector3f& rotationaxis, float fAngle) +void Builder3D::addTransformation(const Base::Placement& transform) { - result << "Transform {"; - result << " translation " << translation.x << " " << translation.y << " " << translation.z; - result << " rotation " << rotationaxis.x << " " << rotationaxis.y << " " << rotationaxis.z << " " << fAngle; - result << "}"; + Base::Vector3d translation = transform.getPosition(); + Base::Vector3d rotationaxis; + double angle; + transform.getRotation().getValue(rotationaxis, angle); + result << "Transform {"; + result << " translation " << translation.x << " " << translation.y << " " << translation.z; + result << " rotation " << rotationaxis.x << " " << rotationaxis.y << " " << rotationaxis.z << " " << angle; + result << "}"; } //************************************************************************** @@ -325,14 +318,14 @@ void Builder3D::saveToLog() */ void Builder3D::saveToFile(const char* FileName) { - result << "} "; - Base::FileInfo fi(FileName); - Base::ofstream file(fi); - if(!file) - throw FileException("Builder3D::saveToFile(): Can not open file..."); + result << "} "; + Base::FileInfo fi(FileName); + Base::ofstream file(fi); + if (!file) + throw FileException("Builder3D::saveToFile(): Can not open file..."); - file << "#Inventor V2.1 ascii \n"; - file << result.str(); + file << "#Inventor V2.1 ascii \n"; + file << result.str(); } // ----------------------------------------------------------------------------- diff --git a/src/Base/Builder3D.h b/src/Base/Builder3D.h index 06f5848e60..c283a77852 100644 --- a/src/Base/Builder3D.h +++ b/src/Base/Builder3D.h @@ -28,7 +28,7 @@ #include #include -#include +#include #ifndef FC_GLOBAL_H #include #endif @@ -37,6 +37,97 @@ namespace Base { class Matrix4D; +class BaseExport ColorRGB +{ +public: + ColorRGB(); + explicit ColorRGB(float red, float green, float blue); + ~ColorRGB() = default; + + float red() const { + return Rgb.red; + } + + float green() const { + return Rgb.green; + } + + float blue() const { + return Rgb.blue; + } + +protected: + /*! Returns the clamped value in range [-1, +1] */ + static float valueInRange(float value); + struct { + float red; + float green; + float blue; + } Rgb; +}; + +class BaseExport ColorRGBA : public ColorRGB +{ +public: + ColorRGBA() : _alpha {1.0F} { + } + explicit ColorRGBA(float red, float green, float blue, float alpha) + : ColorRGB(red, green, blue) + , _alpha {valueInRange(alpha)} { + } + ~ColorRGBA() = default; + float alpha() const { + return _alpha; + } + +private: + float _alpha; +}; + +class BaseExport DrawStyle +{ +public: + enum class Style { + Filled, + Lines, + Points, + Invisible + }; + + Style style = Style::Filled; + unsigned short pointSize = 2; + unsigned short lineWidth = 2; + unsigned short linePattern = 0xffff; +}; + +class BaseExport Triangle +{ +public: + explicit Triangle(const Base::Vector3f& pt1, + const Base::Vector3f& pt2, + const Base::Vector3f& pt3) + : pt1(pt1), pt2(pt2), pt3(pt3) + { + } + + const Base::Vector3f& getPoint1() const { + return pt1; + } + + const Base::Vector3f& getPoint2() const { + return pt2; + } + + const Base::Vector3f& getPoint3() const { + return pt3; + } + +private: + Base::Vector3f pt1; + Base::Vector3f pt2; + Base::Vector3f pt3; +}; + /** A Builder class for 3D representations on App level * On the application level nothing is known of the visual representation of data. * Nevertheless it's often needed to see some 3D information, e.g. points, directions, @@ -65,73 +156,64 @@ class Matrix4D; class BaseExport Builder3D { public: - /// Construction - Builder3D(); - /// Destruction - virtual ~Builder3D(); + Builder3D(); + virtual ~Builder3D(); - /** @name point set handling */ - //@{ - /// starts a point set - void startPoints(short pointSize=2, float color_r=1.0,float color_g=0.0,float color_b=0.0); - /// 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(); - /// add a singular point (without startPoints() & endPoints() ) - void addSinglePoint(float x, float y, float z, short pointSize=2, float color_r=1.0,float color_g=1.0,float color_b=1.0); - /// add a singular point (without startPoints() & endPoints() ) - void addSinglePoint(const Base::Vector3f &vec, short pointSize=2, float color_r=1.0,float color_g=1.0,float color_b=1.0); - //@} + /** @name point set handling */ + //@{ + /// starts a point set + void startPoints(short pointSize=2, const ColorRGB& color = ColorRGB{1.0F, 0.0F, 0.0F}); + /// add a point to a point set + void addPoint(const Vector3f& point); + /// ends the points set operation + void endPoints(); + /// add a single point (without startPoints() & endPoints() ) + void addSinglePoint(const Base::Vector3f& point, DrawStyle drawStyle, const ColorRGB& color = ColorRGB{1.0F, 1.0F, 1.0F}); + //@} - /** @name line/direction handling */ - //@{ - /// add a line defined by 2 Vector3D - void addSingleLine(const Vector3f& pt1, const Vector3f& pt2, short lineSize=2, float color_r=1.0,float color_g=1.0,float color_b=1.0, unsigned short linePattern = 0xffff); - /// add a arrow (directed line) by 2 Vector3D. The arrow shows in direction of point 2. - void addSingleArrow(const Vector3f& pt1, const Vector3f& pt2, short lineSize=2, float color_r=1.0,float color_g=1.0,float color_b=1.0, unsigned short linePattern = 0xffff); - //@} + /** @name line/direction handling */ + //@{ + /// add a line + void addSingleLine(const Base::Line3f& line, DrawStyle drawStyle, const ColorRGB& color = ColorRGB{1.0F, 1.0F, 1.0F}); + /// add an arrow. + void addSingleArrow(const Base::Line3f& line, DrawStyle drawStyle, const ColorRGB& color = ColorRGB{1.0F, 1.0F, 1.0F}); + //@} - /** @name triangle handling */ - //@{ - /// add a (filled) triangle defined by 3 vectors - void addSingleTriangle(const Vector3f& pt0, const Vector3f& pt1, const Vector3f& pt2, bool filled = true, short lineSize=2, float color_r=1.0,float color_g=1.0,float color_b=1.0); - //@} + /** @name triangle handling */ + //@{ + /// add a triangle + void addSingleTriangle(const Triangle& triangle, DrawStyle drawStyle, const ColorRGB& color = ColorRGB{1.0F, 1.0F, 1.0F}); + //@} - /** @name Transformation */ - //@{ - /// adds a transformation - void addTransformation(const Base::Matrix4D&); - void addTransformation(const Base::Vector3f& translation, const Base::Vector3f& rotationaxis, float fAngle); - //@} + /** @name Transformation */ + //@{ + /// adds a transformation + void addTransformation(const Base::Matrix4D&); + void addTransformation(const Base::Placement&); + //@} - /** @name text handling */ - //@{ - /// add a text - void addText(float pos_x, float pos_y , float pos_z,const char * text, float color_r=1.0,float color_g=1.0,float color_b=1.0); - /// add a text - void addText(const Base::Vector3f &vec,const char * text, float color_r=1.0,float color_g=1.0,float color_b=1.0); - //@} + /** @name text handling */ + //@{ + /// add a text + void addText(const Base::Vector3f& point, const char * text, const ColorRGB& color = ColorRGB{1.0F, 1.0F, 1.0F}); + //@} - /// clear the string buffer - void clear (); + /// clear the string buffer + void clear(); - /** @name write the result */ - //@{ - /// sends the result to the log and gui - void saveToLog(); - /// save the result to a file (*.iv) - void saveToFile(const char* FileName); - //@} + /** @name write the result */ + //@{ + /// sends the result to the log and gui + void saveToLog(); + /// save the result to a file (*.iv) + void saveToFile(const char* FileName); + //@} private: - /// the result string - std::stringstream result; - - bool bStartEndOpen; + /// the result string + std::stringstream result; + bool bStartEndOpen; }; /** diff --git a/src/Mod/Mesh/App/Mesh.cpp b/src/Mod/Mesh/App/Mesh.cpp index 8b76554614..a629056fd2 100644 --- a/src/Mod/Mesh/App/Mesh.cpp +++ b/src/Mod/Mesh/App/Mesh.cpp @@ -948,8 +948,10 @@ void MeshObject::offsetSpecial2(float fSize) unsigned int i = 0; // go through all the vertex normals - for (std::vector::iterator It= PointNormals.begin();It != PointNormals.end();++It,i++){ - builder.addSingleLine(_kernel.GetPoint(i),_kernel.GetPoint(i)+It->Normalize() * fSize); + for (std::vector::iterator It= PointNormals.begin();It != PointNormals.end();++It,i++) { + Base::Line3f line{_kernel.GetPoint(i), _kernel.GetPoint(i) + It->Normalize() * fSize}; + Base::DrawStyle drawStyle; + builder.addSingleLine(line, drawStyle); // and move each mesh point in the normal direction _kernel.MovePoint(i,It->Normalize() * fSize); } @@ -964,7 +966,9 @@ void MeshObject::offsetSpecial2(float fSize) // calculate the angle between them float angle = acos((FaceNormals[i] * it->GetNormal()) / (it->GetNormal().Length() * FaceNormals[i].Length())); if (angle > 1.6) { - builder.addSinglePoint(it->GetGravityPoint(),4,1,0,0); + Base::DrawStyle drawStyle; + drawStyle.pointSize = 4.0F; + builder.addSinglePoint(it->GetGravityPoint(), drawStyle, Base::ColorRGB{1.0F, 0.0F, 0.0F}); fliped.insert(it.Position()); } } diff --git a/src/Mod/MeshPart/App/MeshAlgos.cpp b/src/Mod/MeshPart/App/MeshAlgos.cpp index 3699437022..4c5194be30 100644 --- a/src/Mod/MeshPart/App/MeshAlgos.cpp +++ b/src/Mod/MeshPart/App/MeshAlgos.cpp @@ -69,8 +69,10 @@ void MeshAlgos::offsetSpecial2(MeshCore::MeshKernel* Mesh, float fSize) unsigned int i = 0; // go through all the Vertex normals - for(std::vector::iterator It= PointNormals.begin();It != PointNormals.end();++It,i++){ - builder.addSingleLine(Mesh->GetPoint(i),Mesh->GetPoint(i)+It->Normalize() * fSize); + for(std::vector::iterator It= PointNormals.begin();It != PointNormals.end();++It,i++) { + Base::Line3f line{Mesh->GetPoint(i), Mesh->GetPoint(i) + It->Normalize() * fSize}; + Base::DrawStyle drawStyle; + builder.addSingleLine(line, drawStyle); // and move each mesh point in the normal direction Mesh->MovePoint(i,It->Normalize() * fSize); } @@ -85,8 +87,10 @@ void MeshAlgos::offsetSpecial2(MeshCore::MeshKernel* Mesh, float fSize) continue; // calculate the angle between them float angle = acos((FaceNormals[i] * it->GetNormal()) / (it->GetNormal().Length() * FaceNormals[i].Length())); - if(angle > 1.6){ - builder.addSinglePoint(it->GetGravityPoint(),4,1,0,0); + if (angle > 1.6){ + Base::DrawStyle drawStyle; + drawStyle.pointSize = 4.0F; + builder.addSinglePoint(it->GetGravityPoint(), drawStyle, Base::ColorRGB{1.0F, 0.0F, 0.0F}); fliped.insert(it.Position()); } }