diff --git a/src/Mod/Sketcher/Gui/DrawSketchHandler.cpp b/src/Mod/Sketcher/Gui/DrawSketchHandler.cpp index d67bda66fc..f4a74247cc 100644 --- a/src/Mod/Sketcher/Gui/DrawSketchHandler.cpp +++ b/src/Mod/Sketcher/Gui/DrawSketchHandler.cpp @@ -86,6 +86,11 @@ inline void ViewProviderSketchDrawSketchHandlerAttorney::drawEdit(ViewProviderSk vp.drawEdit(EditCurve); } +inline void ViewProviderSketchDrawSketchHandlerAttorney::drawEdit(ViewProviderSketch &vp, const std::list> &list) +{ + vp.drawEdit(list); +} + inline void ViewProviderSketchDrawSketchHandlerAttorney::drawEditMarkers(ViewProviderSketch &vp, const std::vector &EditMarkers, unsigned int augmentationlevel) { vp.drawEditMarkers(EditMarkers, augmentationlevel); @@ -111,6 +116,101 @@ inline int ViewProviderSketchDrawSketchHandlerAttorney::getPreselectCross(const return vp.getPreselectCross(); } + +/**************************** CurveConverter **********************************************/ + +CurveConverter::CurveConverter() +{ + try { + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View"); + hGrp->Attach(this); + } + catch(const Base::ValueError & e) { // ensure that if parameter strings are not well-formed, the exception is not propagated + Base::Console().Error("CurveConverter: Malformed parameter string: %s\n", e.what()); + } + + updateCurvedEdgeCountSegmentsParameter(); +} + +CurveConverter::~CurveConverter() +{ + try { + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View"); + hGrp->Detach(this); + } + catch(const Base::ValueError & e) {// ensure that if parameter strings are not well-formed, the program is not terminated when calling the noexcept destructor. + Base::Console().Error("CurveConverter: Malformed parameter string: %s\n", e.what()); + } +} + +std::vector CurveConverter::toVector2D(const Part::Geometry * geometry) +{ + std::vector vector2d; + + const auto type = geometry->getTypeId(); + + auto emplaceasvector2d = [&vector2d](const Base::Vector3d & point) { + vector2d.emplace_back(point.x,point.y); + }; + + auto isconic = type.isDerivedFrom(Part::GeomConic::getClassTypeId()); + auto isbounded = type.isDerivedFrom(Part::GeomBoundedCurve::getClassTypeId()); + + if (type == Part::GeomLineSegment::getClassTypeId()) { // add a line + auto geo = static_cast(geometry); + + emplaceasvector2d(geo->getStartPoint()); + emplaceasvector2d(geo->getEndPoint()); + } + else if ( isconic || isbounded ) { + + auto geo = static_cast(geometry); + + double segment = (geo->getLastParameter() - geo->getFirstParameter()) / curvedEdgeCountSegments; + + for (int i=0; i < curvedEdgeCountSegments; i++) + emplaceasvector2d(geo->value(i*segment)); + + // either close the curve for untrimmed conic or set the last point for bounded curves + emplaceasvector2d(isconic ? geo->value(0) : geo->value(geo->getLastParameter())); + } + + return vector2d; +} + +std::list> CurveConverter::toVector2DList(const std::vector &geometries) +{ + std::list> list; + + for(const auto & geo : geometries) + list.push_back(toVector2D(geo)); + + return list; +} + +void CurveConverter::updateCurvedEdgeCountSegmentsParameter() +{ + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View"); + int stdcountsegments = hGrp->GetInt("SegmentsPerGeometry", 50); + + // value cannot be smaller than 6 + if (stdcountsegments < 6) + stdcountsegments = 6; + + curvedEdgeCountSegments = stdcountsegments; +}; + +/** Observer for parameter group. */ +void CurveConverter::OnChange(Base::Subject &rCaller, const char * sReason) +{ + (void) rCaller; + + if(strcmp(sReason, "SegmentsPerGeometry") == 0) { + updateCurvedEdgeCountSegmentsParameter(); + } + +} + /**************************** DrawSketchHandler *******************************************/ @@ -800,6 +900,20 @@ void DrawSketchHandler::drawEdit(const std::vector &EditCurve) ViewProviderSketchDrawSketchHandlerAttorney::drawEdit(*sketchgui, EditCurve); } +void DrawSketchHandler::drawEdit(const std::list> &list) +{ + ViewProviderSketchDrawSketchHandlerAttorney::drawEdit(*sketchgui, list); +} + +void DrawSketchHandler::drawEdit(const std::vector &geometries) +{ + static CurveConverter c; + + auto list = c.toVector2DList(geometries); + + drawEdit(list); +} + void DrawSketchHandler::drawEditMarkers(const std::vector &EditMarkers, unsigned int augmentationlevel) { ViewProviderSketchDrawSketchHandlerAttorney::drawEditMarkers(*sketchgui, EditMarkers, augmentationlevel); diff --git a/src/Mod/Sketcher/Gui/DrawSketchHandler.h b/src/Mod/Sketcher/Gui/DrawSketchHandler.h index 2901071db9..8830555356 100644 --- a/src/Mod/Sketcher/Gui/DrawSketchHandler.h +++ b/src/Mod/Sketcher/Gui/DrawSketchHandler.h @@ -39,6 +39,33 @@ namespace SketcherGui { class ViewProviderSketch; + + +/** + * Class to convert Part::Geometry to Vector2d based collections + */ +class CurveConverter final : public ParameterGrp::ObserverType { + +public: + CurveConverter(); + + ~CurveConverter(); + + std::vector toVector2D(const Part::Geometry * geometry); + + std::list> toVector2DList(const std::vector &geometries); + +private: + void updateCurvedEdgeCountSegmentsParameter(); + + /** Observer for parameter group. */ + virtual void OnChange(Base::Subject &rCaller, const char * sReason) override; + +private: + int curvedEdgeCountSegments; +}; + + /** * In order to enforce a certain degree of encapsulation and promote a not * too tight coupling, while still allowing well defined collaboration, @@ -51,6 +78,7 @@ private: static inline void setPositionText(ViewProviderSketch &vp, const Base::Vector2d &Pos); static inline void resetPositionText(ViewProviderSketch &vp); static inline void drawEdit(ViewProviderSketch &vp, const std::vector &EditCurve); + static inline void drawEdit(ViewProviderSketch &vp, const std::list> &list); static inline void drawEditMarkers(ViewProviderSketch &vp, const std::vector &EditMarkers, unsigned int augmentationlevel = 0); static inline void setAxisPickStyle(ViewProviderSketch &vp, bool on); @@ -61,7 +89,6 @@ private: friend class DrawSketchHandler; }; - // A Simple data type to hold basic information for suggested constraints struct AutoConstraint { @@ -154,6 +181,8 @@ protected: void setCrosshairCursor(const char* svgName); void drawEdit(const std::vector &EditCurve); + void drawEdit(const std::list> &list); + void drawEdit(const std::vector &geometries); void drawEditMarkers(const std::vector &EditMarkers, unsigned int augmentationlevel = 0); void setAxisPickStyle(bool on); diff --git a/src/Mod/Sketcher/Gui/EditModeCoinManager.cpp b/src/Mod/Sketcher/Gui/EditModeCoinManager.cpp index f48f6a968d..88988058ce 100644 --- a/src/Mod/Sketcher/Gui/EditModeCoinManager.cpp +++ b/src/Mod/Sketcher/Gui/EditModeCoinManager.cpp @@ -452,6 +452,38 @@ void EditModeCoinManager::drawEdit(const std::vector &EditCurve) editModeScenegraphNodes.EditCurvesMaterials->diffuseColor.finishEditing(); } +void EditModeCoinManager::drawEdit(const std::list> &list) +{ + int ncoords = 0; + + for(const auto & v : list) + ncoords += v.size(); + + editModeScenegraphNodes.EditCurveSet->numVertices.setNum(list.size()); + editModeScenegraphNodes.EditCurvesCoordinate->point.setNum(ncoords); + editModeScenegraphNodes.EditCurvesMaterials->diffuseColor.setNum(ncoords); + SbVec3f *verts = editModeScenegraphNodes.EditCurvesCoordinate->point.startEditing(); + int32_t *index = editModeScenegraphNodes.EditCurveSet->numVertices.startEditing(); + SbColor *color = editModeScenegraphNodes.EditCurvesMaterials->diffuseColor.startEditing(); + + int coordindex=0; + int indexindex=0; + for(const auto & v : list) { + for (const auto & p : v) { + verts[coordindex].setValue(p.x, p.y, drawingParameters.zEdit); + color[coordindex] = drawingParameters.CreateCurveColor; + coordindex++; + } + index[indexindex] = v.size(); + indexindex++; + } + + editModeScenegraphNodes.EditCurvesCoordinate->point.finishEditing(); + editModeScenegraphNodes.EditCurveSet->numVertices.finishEditing(); + editModeScenegraphNodes.EditCurvesMaterials->diffuseColor.finishEditing(); + +} + void EditModeCoinManager::setPositionText(const Base::Vector2d &Pos, const SbString &text) { editModeScenegraphNodes.textX->string = text; diff --git a/src/Mod/Sketcher/Gui/EditModeCoinManager.h b/src/Mod/Sketcher/Gui/EditModeCoinManager.h index 416b6561c9..fb30f63631 100644 --- a/src/Mod/Sketcher/Gui/EditModeCoinManager.h +++ b/src/Mod/Sketcher/Gui/EditModeCoinManager.h @@ -191,6 +191,7 @@ public: //@{ void drawEditMarkers(const std::vector &EditMarkers, unsigned int augmentationlevel); void drawEdit(const std::vector &EditCurve); + void drawEdit(const std::list> &list); void setPositionText(const Base::Vector2d &Pos, const SbString &txt); void setPositionText(const Base::Vector2d &Pos); void resetPositionText(void); diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index 87f64dc70d..67af2d64cf 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -2586,6 +2586,11 @@ void ViewProviderSketch::drawEdit(const std::vector &EditCurve) editCoinManager->drawEdit(EditCurve); } +void ViewProviderSketch::drawEdit(const std::list> &list) +{ + editCoinManager->drawEdit(list); +} + void ViewProviderSketch::drawEditMarkers(const std::vector &EditMarkers, unsigned int augmentationlevel) { editCoinManager->drawEditMarkers(EditMarkers, augmentationlevel); diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.h b/src/Mod/Sketcher/Gui/ViewProviderSketch.h index 26a461791a..8aff6694b7 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.h +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.h @@ -707,6 +707,7 @@ private: /// draw the edit curve void drawEdit(const std::vector &EditCurve); + void drawEdit(const std::list> &list); /// draw the edit markers void drawEditMarkers(const std::vector &EditMarkers, unsigned int augmentationlevel = 0); /// set the pick style of the sketch coordinate axes