Skip to content

Commit

Permalink
Sketch: [skip ci] handle possible crashes when decreasing degree of a…
Browse files Browse the repository at this point in the history
… spline
  • Loading branch information
wwmayer committed Oct 23, 2020
1 parent fc89f4e commit 4a8201a
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 12 deletions.
14 changes: 13 additions & 1 deletion src/Mod/Sketcher/App/SketchObject.cpp
Expand Up @@ -5219,7 +5219,11 @@ bool SketchObject::decreaseBSplineDegree(int GeoId, int degreedecrement /*= 1*/)
try {
int cdegree = bspline->getDegree();

bool ok = bspline->approximate(Precision::Confusion(), 20, cdegree-degreedecrement, 0);
// degree must be >= 1
int maxdegree = cdegree - degreedecrement;
if (maxdegree == 0)
return false;
bool ok = bspline->approximate(Precision::Confusion(), 20, maxdegree, 0);
if (!ok)
return false;
}
Expand All @@ -5228,6 +5232,9 @@ bool SketchObject::decreaseBSplineDegree(int GeoId, int degreedecrement /*= 1*/)
return false;
}

// FIXME: Avoid to delete the whole geometry but only delete invalid constraints
// and unused construction geometries
#if 0
const std::vector< Part::Geometry * > &vals = getInternalGeometry();

std::vector< Part::Geometry * > newVals(vals);
Expand All @@ -5236,6 +5243,11 @@ bool SketchObject::decreaseBSplineDegree(int GeoId, int degreedecrement /*= 1*/)

// AcceptGeometry called from onChanged
Geometry.setValues(newVals);
#else
delGeometry(GeoId);
int newId = addGeometry(bspline.release());
exposeInternalGeometry(newId);
#endif

return true;
}
Expand Down
16 changes: 5 additions & 11 deletions src/Mod/Sketcher/App/SketchObjectPyImp.cpp
Expand Up @@ -1399,19 +1399,13 @@ PyObject* SketchObjectPy::increaseBSplineDegree(PyObject *args)
PyObject* SketchObjectPy::decreaseBSplineDegree(PyObject *args)
{
int GeoId;
int incr = 1;
int decr = 1;

if (!PyArg_ParseTuple(args, "i|i", &GeoId, &incr))
return 0;
if (!PyArg_ParseTuple(args, "i|i", &GeoId, &decr))
return nullptr;

if (this->getSketchObjectPtr()->decreaseBSplineDegree(GeoId, incr)==false) {
std::stringstream str;
str << "Degree decrease failed for: " << GeoId;
PyErr_SetString(PyExc_ValueError, str.str().c_str());
return 0;
}

Py_Return;
bool ok = this->getSketchObjectPtr()->decreaseBSplineDegree(GeoId, decr);
return Py_BuildValue("O", (ok ? Py_True : Py_False));
}

PyObject* SketchObjectPy::modifyBSplineKnotMultiplicity(PyObject *args)
Expand Down
5 changes: 5 additions & 0 deletions src/Mod/Sketcher/Gui/CommandSketcherBSpline.cpp
Expand Up @@ -500,6 +500,8 @@ void CmdSketcherDecreaseDegree::activated(int iMsg)
return;
}

getSelection().clearSelection();

// get the needed lists and objects
const std::vector<std::string> &SubNames = selection[0].getSubNames();
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());
Expand All @@ -517,7 +519,10 @@ void CmdSketcherDecreaseDegree::activated(int iMsg)
if (geo->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) {
Gui::cmdAppObjectArgs(selection[0].getObject(), "decreaseBSplineDegree(%d) ", GeoId);
// add new control points
// Currently exposeInternalGeometry is called from within decreaseBSplineDegree because
// the old spline is deleted and a new one is added so that the GeoId is invalid afterwards
//Gui::cmdAppObjectArgs(selection[0].getObject(), "exposeInternalGeometry(%d)", GeoId);
break; // cannot handle more than spline because the GeoIds will be invalidated after the first change
}
else {
ignored = true;
Expand Down

0 comments on commit 4a8201a

Please sign in to comment.