Sketcher: DrawSketchHandler draw multiple edit curves

=====================================================

Extension of the framework to draw an arbitrary curve in draw sketch handlers, so that
a plurality of curves can be handled.

DrawSketchHandler is extended to additionally offer drawing several curves:
- void drawEdit(const std::list<std::vector<Base::Vector2d>> &list);
- void drawEdit(const std::vector<Part::Geometry *> &geometries);

A new class, CurveConverter, enables to convert individual Part::Geometry or vectors of them
to appropriate vectors or list of vectors of Vector2d representing the curves. This can be
used in a specific DrawSketchHandler to combine Part::Geometries and arbritary curves.
This commit is contained in:
Abdullah Tahiri
2022-03-14 15:47:46 +01:00
parent 75fee12d7b
commit 89bf7f3d0b
6 changed files with 183 additions and 1 deletions

View File

@@ -86,6 +86,11 @@ inline void ViewProviderSketchDrawSketchHandlerAttorney::drawEdit(ViewProviderSk
vp.drawEdit(EditCurve);
}
inline void ViewProviderSketchDrawSketchHandlerAttorney::drawEdit(ViewProviderSketch &vp, const std::list<std::vector<Base::Vector2d>> &list)
{
vp.drawEdit(list);
}
inline void ViewProviderSketchDrawSketchHandlerAttorney::drawEditMarkers(ViewProviderSketch &vp, const std::vector<Base::Vector2d> &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<Base::Vector2d> CurveConverter::toVector2D(const Part::Geometry * geometry)
{
std::vector<Base::Vector2d> 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<const Part::GeomLineSegment *>(geometry);
emplaceasvector2d(geo->getStartPoint());
emplaceasvector2d(geo->getEndPoint());
}
else if ( isconic || isbounded ) {
auto geo = static_cast<const Part::GeomConic *>(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<std::vector<Base::Vector2d>> CurveConverter::toVector2DList(const std::vector<Part::Geometry *> &geometries)
{
std::list<std::vector<Base::Vector2d>> 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<const char*> &rCaller, const char * sReason)
{
(void) rCaller;
if(strcmp(sReason, "SegmentsPerGeometry") == 0) {
updateCurvedEdgeCountSegmentsParameter();
}
}
/**************************** DrawSketchHandler *******************************************/
@@ -800,6 +900,20 @@ void DrawSketchHandler::drawEdit(const std::vector<Base::Vector2d> &EditCurve)
ViewProviderSketchDrawSketchHandlerAttorney::drawEdit(*sketchgui, EditCurve);
}
void DrawSketchHandler::drawEdit(const std::list<std::vector<Base::Vector2d>> &list)
{
ViewProviderSketchDrawSketchHandlerAttorney::drawEdit(*sketchgui, list);
}
void DrawSketchHandler::drawEdit(const std::vector<Part::Geometry *> &geometries)
{
static CurveConverter c;
auto list = c.toVector2DList(geometries);
drawEdit(list);
}
void DrawSketchHandler::drawEditMarkers(const std::vector<Base::Vector2d> &EditMarkers, unsigned int augmentationlevel)
{
ViewProviderSketchDrawSketchHandlerAttorney::drawEditMarkers(*sketchgui, EditMarkers, augmentationlevel);

View File

@@ -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<Base::Vector2d> toVector2D(const Part::Geometry * geometry);
std::list<std::vector<Base::Vector2d>> toVector2DList(const std::vector<Part::Geometry *> &geometries);
private:
void updateCurvedEdgeCountSegmentsParameter();
/** Observer for parameter group. */
virtual void OnChange(Base::Subject<const char*> &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<Base::Vector2d> &EditCurve);
static inline void drawEdit(ViewProviderSketch &vp, const std::list<std::vector<Base::Vector2d>> &list);
static inline void drawEditMarkers(ViewProviderSketch &vp, const std::vector<Base::Vector2d> &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<Base::Vector2d> &EditCurve);
void drawEdit(const std::list<std::vector<Base::Vector2d>> &list);
void drawEdit(const std::vector<Part::Geometry *> &geometries);
void drawEditMarkers(const std::vector<Base::Vector2d> &EditMarkers, unsigned int augmentationlevel = 0);
void setAxisPickStyle(bool on);

View File

@@ -452,6 +452,38 @@ void EditModeCoinManager::drawEdit(const std::vector<Base::Vector2d> &EditCurve)
editModeScenegraphNodes.EditCurvesMaterials->diffuseColor.finishEditing();
}
void EditModeCoinManager::drawEdit(const std::list<std::vector<Base::Vector2d>> &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;

View File

@@ -191,6 +191,7 @@ public:
//@{
void drawEditMarkers(const std::vector<Base::Vector2d> &EditMarkers, unsigned int augmentationlevel);
void drawEdit(const std::vector<Base::Vector2d> &EditCurve);
void drawEdit(const std::list<std::vector<Base::Vector2d>> &list);
void setPositionText(const Base::Vector2d &Pos, const SbString &txt);
void setPositionText(const Base::Vector2d &Pos);
void resetPositionText(void);

View File

@@ -2586,6 +2586,11 @@ void ViewProviderSketch::drawEdit(const std::vector<Base::Vector2d> &EditCurve)
editCoinManager->drawEdit(EditCurve);
}
void ViewProviderSketch::drawEdit(const std::list<std::vector<Base::Vector2d>> &list)
{
editCoinManager->drawEdit(list);
}
void ViewProviderSketch::drawEditMarkers(const std::vector<Base::Vector2d> &EditMarkers, unsigned int augmentationlevel)
{
editCoinManager->drawEditMarkers(EditMarkers, augmentationlevel);

View File

@@ -707,6 +707,7 @@ private:
/// draw the edit curve
void drawEdit(const std::vector<Base::Vector2d> &EditCurve);
void drawEdit(const std::list<std::vector<Base::Vector2d>> &list);
/// draw the edit markers
void drawEditMarkers(const std::vector<Base::Vector2d> &EditMarkers, unsigned int augmentationlevel = 0);
/// set the pick style of the sketch coordinate axes