From e5c63bc3d08ed0c3dd608beab1bd9115d0b0dec4 Mon Sep 17 00:00:00 2001 From: wmayer Date: Sun, 8 Nov 2020 12:18:44 +0100 Subject: [PATCH] Part: [skip ci] implement extension ViewProviderSplineExtension --- src/Mod/Part/Gui/AppPartGui.cpp | 1 + src/Mod/Part/Gui/ViewProviderSpline.cpp | 240 ++++++++++++++++++++++++ src/Mod/Part/Gui/ViewProviderSpline.h | 25 +++ 3 files changed, 266 insertions(+) diff --git a/src/Mod/Part/Gui/AppPartGui.cpp b/src/Mod/Part/Gui/AppPartGui.cpp index b16805d213..c3520182fa 100644 --- a/src/Mod/Part/Gui/AppPartGui.cpp +++ b/src/Mod/Part/Gui/AppPartGui.cpp @@ -155,6 +155,7 @@ PyMOD_INIT_FUNC(PartGui) PartGui::SoFCControlPoints ::initClass(); PartGui::ViewProviderAttachExtension ::init(); PartGui::ViewProviderAttachExtensionPython ::init(); + PartGui::ViewProviderSplineExtension ::init(); PartGui::ViewProviderPartExt ::init(); PartGui::ViewProviderPart ::init(); PartGui::ViewProviderPrimitive ::init(); diff --git a/src/Mod/Part/Gui/ViewProviderSpline.cpp b/src/Mod/Part/Gui/ViewProviderSpline.cpp index d856f2c0c4..16dcb66ae0 100644 --- a/src/Mod/Part/Gui/ViewProviderSpline.cpp +++ b/src/Mod/Part/Gui/ViewProviderSpline.cpp @@ -291,6 +291,246 @@ void ViewProviderSpline::showControlPointsOfFace(const TopoDS_Face& face) coords->point.finishEditing(); + SoFCControlPoints* control = new SoFCControlPoints(); + control->numPolesU = nCtU; + control->numPolesV = nCtV; + + //if (knots.size() > 0) { + // control->numKnotsU = nKnU; + // control->numKnotsV = nKnV; + //} + + SoSeparator* nodes = new SoSeparator(); + nodes->addChild(coords); + nodes->addChild(control); + + pcControlPoints->addChild(nodes); +} + +// ---------------------------------------------------------------------------- + +EXTENSION_PROPERTY_SOURCE(PartGui::ViewProviderSplineExtension, Gui::ViewProviderExtension) + + +ViewProviderSplineExtension::ViewProviderSplineExtension() + : pcControlPoints(nullptr) +{ + initExtensionType(ViewProviderSplineExtension::getExtensionClassTypeId()); + EXTENSION_ADD_PROPERTY(ControlPoints,(false)); +} + +void ViewProviderSplineExtension::toggleControlPoints(bool on) +{ + ControlPoints.setValue(on); +} + +void ViewProviderSplineExtension::setupContextMenu(QMenu* menu) +{ + // toggle command to display components + Gui::ActionFunction* func = new Gui::ActionFunction(menu); + QAction* act = menu->addAction(QObject::tr("Show control points")); + act->setCheckable(true); + act->setChecked(ControlPoints.getValue()); + func->toggle(act, boost::bind(&ViewProviderSplineExtension::toggleControlPoints, this, bp::_1)); +} + +void ViewProviderSplineExtension::extensionUpdateData(const App::Property* prop) +{ + Gui::ViewProviderExtension::extensionUpdateData(prop); + if (prop->getTypeId() == Part::PropertyPartShape::getClassTypeId() && strcmp(prop->getName(), "Shape") == 0) { + // update control points if there + if (pcControlPoints) { + Gui::coinRemoveAllChildren(pcControlPoints); + showControlPoints(this->ControlPoints.getValue(), prop); + } + } +} + +void ViewProviderSplineExtension::extensionOnChanged(const App::Property* prop) +{ + if (prop == &ControlPoints) { + App::DocumentObject* obj = getExtendedViewProvider()->getObject(); + App::Property* shape = obj->getPropertyByName("Shape"); + showControlPoints(ControlPoints.getValue(), shape); + } + else { + Gui::ViewProviderExtension::extensionOnChanged(prop); + } +} + +void ViewProviderSplineExtension::showControlPoints(bool show, const App::Property* prop) +{ + if (!pcControlPoints && show) { + pcControlPoints = new SoSwitch(); + SoSeparator* root = getExtendedViewProvider()->getRoot(); + root->addChild(pcControlPoints); + } + + if (pcControlPoints) { + pcControlPoints->whichChild = (show ? SO_SWITCH_ALL : SO_SWITCH_NONE); + } + + if (!show || !pcControlPoints || pcControlPoints->getNumChildren() > 0) + return; + + // ask for the property we are interested in + if (prop && prop->getTypeId() == Part::PropertyPartShape::getClassTypeId()) { + const TopoDS_Shape& shape = static_cast(prop)->getValue(); + if (shape.IsNull()) + return; // empty shape + + for (TopExp_Explorer xp(shape, TopAbs_SHELL); xp.More(); xp.Next()) { + const TopoDS_Shell& shell = TopoDS::Shell(xp.Current()); + for (TopExp_Explorer xp2(shell, TopAbs_FACE); xp2.More(); xp2.Next()) { + const TopoDS_Face& face = TopoDS::Face(xp2.Current()); + showControlPointsOfFace(face); + } + } + for (TopExp_Explorer xp(shape, TopAbs_FACE, TopAbs_SHELL); xp.More(); xp.Next()) { + const TopoDS_Face& face = TopoDS::Face(xp.Current()); + showControlPointsOfFace(face); + } + for (TopExp_Explorer xp(shape, TopAbs_WIRE, TopAbs_FACE); xp.More(); xp.Next()) { + const TopoDS_Wire& wire = TopoDS::Wire(xp.Current()); + for (TopExp_Explorer xp2(wire, TopAbs_EDGE); xp2.More(); xp2.Next()) { + const TopoDS_Edge& edge = TopoDS::Edge(xp2.Current()); + showControlPointsOfEdge(edge); + } + } + for (TopExp_Explorer xp(shape, TopAbs_EDGE, TopAbs_WIRE); xp.More(); xp.Next()) { + const TopoDS_Edge& edge = TopoDS::Edge(xp.Current()); + showControlPointsOfEdge(edge); + } + } +} + +void ViewProviderSplineExtension::showControlPointsOfEdge(const TopoDS_Edge& edge) +{ + std::list poles, knots; + Standard_Integer nCt=0; + BRepAdaptor_Curve curve(edge); + switch (curve.GetType()) + { + case GeomAbs_BezierCurve: + { + Handle(Geom_BezierCurve) hBezier = curve.Bezier(); + nCt = hBezier->NbPoles(); + for (Standard_Integer i = 1; i <= nCt; i++) + poles.push_back(hBezier->Pole(i)); + if (hBezier->IsClosed()) { + nCt++; + poles.push_back(hBezier->Pole(1)); + } + } break; + case GeomAbs_BSplineCurve: + { + Handle(Geom_BSplineCurve) hBSpline = curve.BSpline(); + nCt = hBSpline->NbPoles(); + for (Standard_Integer i = 1; i <= nCt; i++) + poles.push_back(hBSpline->Pole(i)); + if (hBSpline->IsClosed()) { + nCt++; + poles.push_back(hBSpline->Pole(1)); + } + for (Standard_Integer i = hBSpline->FirstUKnotIndex()+1; i <= hBSpline->LastUKnotIndex()-1; i++) + knots.push_back(hBSpline->Value(hBSpline->Knot(i))); + } break; + default: + break; + } + + if (poles.empty()) + return; // nothing to do + + SoCoordinate3 * controlcoords = new SoCoordinate3; + controlcoords->point.setNum(nCt + knots.size()); + + int index=0; + SbVec3f* verts = controlcoords->point.startEditing(); + for (std::list::iterator p = poles.begin(); p != poles.end(); ++p) { + verts[index++].setValue((float)p->X(), (float)p->Y(), (float)p->Z()); + } + for (std::list::iterator k = knots.begin(); k != knots.end(); ++k) { + verts[index++].setValue((float)k->X(), (float)k->Y(), (float)k->Z()); + } + controlcoords->point.finishEditing(); + + + SoFCControlPoints* controlpoints = new SoFCControlPoints(); + controlpoints->numPolesU = nCt; + controlpoints->numPolesV = 1; + + SoSeparator* nodes = new SoSeparator(); + nodes->addChild(controlcoords); + nodes->addChild(controlpoints); + + pcControlPoints->addChild(nodes); +} + +void ViewProviderSplineExtension::showControlPointsOfFace(const TopoDS_Face& face) +{ + std::list knots; + std::vector > poles; + Standard_Integer nCtU=0, nCtV=0; + BRepAdaptor_Surface surface(face); + + BRepAdaptor_Surface clSurface(face); + switch (clSurface.GetType()) + { + case GeomAbs_BezierSurface: + { + Handle(Geom_BezierSurface) hBezier = surface.Bezier(); + nCtU = hBezier->NbUPoles(); + nCtV = hBezier->NbVPoles(); + poles.resize(nCtU); + for (Standard_Integer u = 1; u <= nCtU; u++) { + poles[u-1].resize(nCtV); + for (Standard_Integer v = 1; v <= nCtV; v++) + poles[u-1][v-1] = hBezier->Pole(u, v); + } + } break; + case GeomAbs_BSplineSurface: + { + Handle(Geom_BSplineSurface) hBSpline = surface.BSpline(); + nCtU = hBSpline->NbUPoles(); + nCtV = hBSpline->NbVPoles(); + poles.resize(nCtU); + for (Standard_Integer u = 1; u <= nCtU; u++) { + poles[u-1].resize(nCtV); + for (Standard_Integer v = 1; v <= nCtV; v++) + poles[u-1][v-1] = hBSpline->Pole(u, v); + } + + //Standard_Integer nKnU = hBSpline->NbUKnots(); + //Standard_Integer nKnV = hBSpline->NbVKnots(); + for (Standard_Integer u = 1; u <= hBSpline->NbUKnots(); u++) { + for (Standard_Integer v = 1; v <= hBSpline->NbVKnots(); v++) + knots.push_back(hBSpline->Value(hBSpline->UKnot(u), hBSpline->VKnot(v))); + } + } break; + default: + break; + } + + if (poles.empty()) + return; // nothing to do + + SoCoordinate3 * coords = new SoCoordinate3; + coords->point.setNum(nCtU * nCtV + knots.size()); + + int index=0; + SbVec3f* verts = coords->point.startEditing(); + for (std::vector >::iterator u = poles.begin(); u != poles.end(); ++u) { + for (std::vector::iterator v = u->begin(); v != u->end(); ++v) { + verts[index++].setValue((float)v->X(), (float)v->Y(), (float)v->Z()); + } + } + for (std::list::iterator k = knots.begin(); k != knots.end(); ++k) { + verts[index++].setValue((float)k->X(), (float)k->Y(), (float)k->Z()); + } + coords->point.finishEditing(); + + SoFCControlPoints* control = new SoFCControlPoints(); control->numPolesU = nCtU; control->numPolesV = nCtV; diff --git a/src/Mod/Part/Gui/ViewProviderSpline.h b/src/Mod/Part/Gui/ViewProviderSpline.h index 8ba3ccb70c..11195c78bb 100644 --- a/src/Mod/Part/Gui/ViewProviderSpline.h +++ b/src/Mod/Part/Gui/ViewProviderSpline.h @@ -24,6 +24,7 @@ #define PARTGUI_VIEWPROVIDERPARTSPLINE_H #include "ViewProviderExt.h" +#include namespace PartGui { @@ -55,6 +56,30 @@ protected: SoSwitch *pcControlPoints; }; +class PartGuiExport ViewProviderSplineExtension : public Gui::ViewProviderExtension +{ + EXTENSION_PROPERTY_HEADER_WITH_OVERRIDE(PartGui::ViewProviderSplineExtension); + +public: + /// Constructor + ViewProviderSplineExtension(void); + virtual ~ViewProviderSplineExtension() = default; + + App::PropertyBool ControlPoints; + + virtual void extensionUpdateData(const App::Property*) override; + void setupContextMenu(QMenu* menu); + +protected: + virtual void extensionOnChanged(const App::Property* p) override; + void toggleControlPoints(bool); + void showControlPoints(bool, const App::Property* prop); + void showControlPointsOfEdge(const TopoDS_Edge&); + void showControlPointsOfFace(const TopoDS_Face&); + + SoSwitch *pcControlPoints; +}; + } //namespace PartGui