From afd761041d50b48b6513980788d6d15e36d53f03 Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Thu, 16 Feb 2017 17:20:55 +0100 Subject: [PATCH] Sketcher: BSpline Increase Degree tool --- src/Mod/Part/App/Geometry.cpp | 13 ++++ src/Mod/Part/App/Geometry.h | 2 + src/Mod/Sketcher/App/SketchObject.cpp | 41 +++++++++++++ src/Mod/Sketcher/App/SketchObject.h | 15 ++++- .../Sketcher/Gui/CommandSketcherBSpline.cpp | 61 ++++++++++++++++++- src/Mod/Sketcher/Gui/Workbench.cpp | 6 +- 6 files changed, 134 insertions(+), 4 deletions(-) diff --git a/src/Mod/Part/App/Geometry.cpp b/src/Mod/Part/App/Geometry.cpp index 45060326b..00aa1acfa 100644 --- a/src/Mod/Part/App/Geometry.cpp +++ b/src/Mod/Part/App/Geometry.cpp @@ -892,6 +892,19 @@ void GeomBSplineCurve::makeC1Continuous(double tol, double ang_tol) GeomConvert::C0BSplineToC1BSplineCurve(this->myCurve, tol, ang_tol); } +void GeomBSplineCurve::increaseDegree(const double Degree) +{ + try { + Handle_Geom_BSplineCurve curve = Handle_Geom_BSplineCurve::DownCast(this->handle()); + curve->IncreaseDegree(Degree); + return; + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + throw Base::RuntimeError(e->GetMessageString()); + } +} + // Persistence implementer unsigned int GeomBSplineCurve::getMemSize (void) const { diff --git a/src/Mod/Part/App/Geometry.h b/src/Mod/Part/App/Geometry.h index 6da1b5c7c..cad394648 100644 --- a/src/Mod/Part/App/Geometry.h +++ b/src/Mod/Part/App/Geometry.h @@ -228,6 +228,8 @@ public: bool join(const Handle_Geom_BSplineCurve&); void makeC1Continuous(double, double); std::list toBiArcs(double tolerance) const; + + void increaseDegree(const double Degree); // Persistence implementer --------------------- virtual unsigned int getMemSize(void) const; diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index 40d7cf07b..686270c78 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -3803,6 +3803,47 @@ bool SketchObject::ConvertToNURBS(int GeoId) } +bool SketchObject::IncreaseBSplineDegree(int GeoId, int degreeincrement /*= 1*/) +{ + if (GeoId < 0 || GeoId > getHighestCurveIndex()) + return -1; + + const Part::Geometry *geo = getGeometry(GeoId); + + if(geo->getTypeId() != Part::GeomBSplineCurve::getClassTypeId()) + return -1; + + const Part::GeomBSplineCurve *bsp = static_cast(geo); + + const Handle_Geom_BSplineCurve curve = Handle_Geom_BSplineCurve::DownCast(bsp->handle()); + + Part::GeomBSplineCurve *bspline = new Part::GeomBSplineCurve(curve); + + + try { + int cdegree = bspline->getDegree(); + + bspline->increaseDegree(cdegree+degreeincrement); + } + catch (const Base::Exception& e) { + Base::Console().Error("%s\n", e.what()); + return false; + } + + const std::vector< Part::Geometry * > &vals = getInternalGeometry(); + + std::vector< Part::Geometry * > newVals(vals); + + newVals[GeoId] = bspline; + + Geometry.setValues(newVals); + Constraints.acceptGeometry(getCompleteGeometry()); + rebuildVertexIndex(); + + return true; + +} + int SketchObject::addExternal(App::DocumentObject *Obj, const char* SubName) { // so far only externals to the support of the sketch and datum features diff --git a/src/Mod/Sketcher/App/SketchObject.h b/src/Mod/Sketcher/App/SketchObject.h index 09f20c754..f8d922962 100644 --- a/src/Mod/Sketcher/App/SketchObject.h +++ b/src/Mod/Sketcher/App/SketchObject.h @@ -196,8 +196,21 @@ public: \retval int - returns -1 on error, otherwise the number of deleted elements */ int DeleteUnusedInternalGeometry(int GeoId, bool delgeoid=false); - + /*! + \brief Approximates the given geometry with a B-Spline + \param GeoId - the geometry to approximate + \param delgeoid - if true in addition to the unused internal geometry also deletes the GeoId geometry + \retval bool - returns true if the approximation succeeded, or false if it did not succeed. + */ bool ConvertToNURBS(int GeoId); + + /*! + \brief Increases the degree of a BSpline by degreeincrement, which defaults to 1 + \param GeoId - the geometry of type bspline to increase the degree + \param degreeincrement - the increment in number of degrees to effect + \retval bool - returns true if the increase in degree succeeded, or false if it did not succeed. + */ + bool IncreaseBSplineDegree(int GeoId, int degreeincrement = 1); /// retrieves for a Vertex number the corresponding GeoId and PosId void getGeoVertexIndex(int VertexId, int &GeoId, PointPos &PosId) const; diff --git a/src/Mod/Sketcher/Gui/CommandSketcherBSpline.cpp b/src/Mod/Sketcher/Gui/CommandSketcherBSpline.cpp index f7cf1c7e2..10825846c 100644 --- a/src/Mod/Sketcher/Gui/CommandSketcherBSpline.cpp +++ b/src/Mod/Sketcher/Gui/CommandSketcherBSpline.cpp @@ -351,7 +351,65 @@ void CmdSketcherConvertToNURB::activated(int iMsg) bool CmdSketcherConvertToNURB::isActive(void) { - return isSketcherBSplineActive( getActiveGuiDocument(), false ); + return isSketcherBSplineActive( getActiveGuiDocument(), true ); +} + +// Convert to NURB +DEF_STD_CMD_A(CmdSketcherIncreaseDegree); + +CmdSketcherIncreaseDegree::CmdSketcherIncreaseDegree() +:Command("Sketcher_BSplineIncreaseDegree") +{ + sAppModule = "Sketcher"; + sGroup = QT_TR_NOOP("Sketcher"); + sMenuText = QT_TR_NOOP("Increase degree"); + sToolTipText = QT_TR_NOOP("Increases the degree of the B-Spline"); + sWhatsThis = "Sketcher_IncreaseDegree"; + sStatusTip = sToolTipText; + sPixmap = "Sketcher_IncreaseDegree"; + sAccel = ""; + eType = ForEdit; +} + +void CmdSketcherIncreaseDegree::activated(int iMsg) +{ + Q_UNUSED(iMsg); + + // get the selection + std::vector selection = getSelection().getSelectionEx(); + + // only one sketch with its subelements are allowed to be selected + if (selection.size() != 1) { + return; + } + + // get the needed lists and objects + const std::vector &SubNames = selection[0].getSubNames(); + Sketcher::SketchObject* Obj = static_cast(selection[0].getObject()); + + for (unsigned int i=0; i 4 && SubNames[i].substr(0,4) == "Edge") { + + int GeoId = std::atoi(SubNames[i].substr(4,4000).c_str()) - 1; + + Obj->IncreaseBSplineDegree(GeoId); + } + } + + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher"); + bool autoRecompute = hGrp->GetBool("AutoRecompute",false); + + if (autoRecompute) + Gui::Command::updateActive(); + else + Obj->solve(); + +} + +bool CmdSketcherIncreaseDegree::isActive(void) +{ + return isSketcherBSplineActive( getActiveGuiDocument(), true ); } @@ -364,4 +422,5 @@ void CreateSketcherCommandsBSpline(void) rcCmdMgr.addCommand(new CmdSketcherBSplineComb()); rcCmdMgr.addCommand(new CmdSketcherCompBSplineShowHideGeometryInformation()); rcCmdMgr.addCommand(new CmdSketcherConvertToNURB()); + rcCmdMgr.addCommand(new CmdSketcherIncreaseDegree()); } diff --git a/src/Mod/Sketcher/Gui/Workbench.cpp b/src/Mod/Sketcher/Gui/Workbench.cpp index f36926558..1b47fcf35 100644 --- a/src/Mod/Sketcher/Gui/Workbench.cpp +++ b/src/Mod/Sketcher/Gui/Workbench.cpp @@ -286,13 +286,15 @@ inline void SketcherAddWorkbenchBSplines(Gui::MenuItem& bspline){ bspline << "Sketcher_BSplineDegree" << "Sketcher_BSplinePolygon" << "Sketcher_BSplineComb" - << "Sketcher_BSplineConvertToNURB"; + << "Sketcher_BSplineConvertToNURB" + << "Sketcher_BSplineIncreaseDegree"; } template <> inline void SketcherAddWorkbenchBSplines(Gui::ToolBarItem& bspline){ bspline << "Sketcher_CompBSplineShowHideGeometryInformation" - << "Sketcher_BSplineConvertToNURB"; + << "Sketcher_BSplineConvertToNURB" + << "Sketcher_BSplineIncreaseDegree"; } template