+ fixes #0001060: Editing sketch crashes FreeCAD
This commit is contained in:
parent
16a8965038
commit
6a211b9dbe
|
@ -2160,6 +2160,110 @@ void SketchObject::appendRedundantMsg(const std::vector<int> &redundant, std::st
|
|||
msg = ss.str();
|
||||
}
|
||||
|
||||
bool SketchObject::evaluateConstraints() const
|
||||
{
|
||||
int intGeoCount = getHighestCurveIndex() + 1;
|
||||
int extGeoCount = getExternalGeometryCount();
|
||||
|
||||
std::vector<Part::Geometry *> geometry = getCompleteGeometry();
|
||||
const std::vector<Sketcher::Constraint *>& constraints = Constraints.getValues();
|
||||
if (static_cast<int>(geometry.size()) != extGeoCount + intGeoCount)
|
||||
return false;
|
||||
if (geometry.size() < 2)
|
||||
return false;
|
||||
|
||||
std::vector<Sketcher::Constraint *>::const_iterator it;
|
||||
for (it = constraints.begin(); it != constraints.end(); ++it) {
|
||||
switch ((*it)->Type) {
|
||||
case Horizontal:
|
||||
case Vertical:
|
||||
case Radius:
|
||||
case Distance:
|
||||
case DistanceX:
|
||||
case DistanceY:
|
||||
if ((*it)->First < -extGeoCount || (*it)->First >= intGeoCount)
|
||||
return false;
|
||||
break;
|
||||
case Perpendicular:
|
||||
case Parallel:
|
||||
case Equal:
|
||||
case PointOnObject:
|
||||
case Tangent:
|
||||
case Symmetric:
|
||||
if ((*it)->First < -extGeoCount || (*it)->First >= intGeoCount)
|
||||
return false;
|
||||
if ((*it)->Second < -extGeoCount || (*it)->Second >= intGeoCount)
|
||||
return false;
|
||||
break;
|
||||
case Angle:
|
||||
if ((*it)->First < -extGeoCount || (*it)->First >= intGeoCount)
|
||||
return false;
|
||||
if (((*it)->Second < -extGeoCount || (*it)->Second >= intGeoCount) &&
|
||||
(*it)->Second != Constraint::GeoUndef)
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SketchObject::validateConstraints()
|
||||
{
|
||||
int intGeoCount = getHighestCurveIndex() + 1;
|
||||
int extGeoCount = getExternalGeometryCount();
|
||||
|
||||
std::vector<Part::Geometry *> geometry = getCompleteGeometry();
|
||||
const std::vector<Sketcher::Constraint *>& constraints = Constraints.getValues();
|
||||
|
||||
std::vector<Sketcher::Constraint *> newConstraints;
|
||||
std::vector<Sketcher::Constraint *>::const_iterator it;
|
||||
for (it = constraints.begin(); it != constraints.end(); ++it) {
|
||||
bool valid = true;
|
||||
switch ((*it)->Type) {
|
||||
case Horizontal:
|
||||
case Vertical:
|
||||
case Radius:
|
||||
case Distance:
|
||||
case DistanceX:
|
||||
case DistanceY:
|
||||
if ((*it)->First < -extGeoCount || (*it)->First >= intGeoCount)
|
||||
valid = false;
|
||||
break;
|
||||
case Perpendicular:
|
||||
case Parallel:
|
||||
case Equal:
|
||||
case PointOnObject:
|
||||
case Tangent:
|
||||
case Symmetric:
|
||||
if ((*it)->First < -extGeoCount || (*it)->First >= intGeoCount)
|
||||
valid = false;
|
||||
if ((*it)->Second < -extGeoCount || (*it)->Second >= intGeoCount)
|
||||
valid = false;
|
||||
break;
|
||||
case Angle:
|
||||
if ((*it)->First < -extGeoCount || (*it)->First >= intGeoCount)
|
||||
valid = false;
|
||||
if (((*it)->Second < -extGeoCount || (*it)->Second >= intGeoCount) &&
|
||||
(*it)->Second != Constraint::GeoUndef)
|
||||
valid = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (valid)
|
||||
newConstraints.push_back(*it);
|
||||
}
|
||||
|
||||
if (newConstraints.size() != constraints.size()) {
|
||||
Constraints.setValues(newConstraints);
|
||||
acceptGeometry();
|
||||
}
|
||||
}
|
||||
|
||||
PyObject *SketchObject::getPyObject(void)
|
||||
{
|
||||
if (PythonObject.is(Py::_None())) {
|
||||
|
|
|
@ -164,6 +164,10 @@ public:
|
|||
virtual Base::Axis getAxis(int axId) const;
|
||||
/// verify and accept the assigned geometry
|
||||
virtual void acceptGeometry();
|
||||
/// Check for constraints with invalid indexes
|
||||
bool evaluateConstraints() const;
|
||||
/// Remove constraints with invalid indexes
|
||||
void validateConstraints();
|
||||
|
||||
protected:
|
||||
/// get called by the container when a property has changed
|
||||
|
|
|
@ -61,6 +61,7 @@ SketcherValidation::SketcherValidation(Sketcher::SketchObject* Obj, QWidget* par
|
|||
{
|
||||
ui->setupUi(this);
|
||||
ui->fixButton->setEnabled(false);
|
||||
ui->fixConstraint->setEnabled(false);
|
||||
double tolerances[8] = {
|
||||
Precision::Confusion() / 100,
|
||||
Precision::Confusion() / 10,
|
||||
|
@ -316,6 +317,26 @@ void SketcherValidation::on_fixButton_clicked()
|
|||
doc->recompute();
|
||||
}
|
||||
|
||||
void SketcherValidation::on_findConstraint_clicked()
|
||||
{
|
||||
if (sketch->evaluateConstraints()) {
|
||||
QMessageBox::information(this, tr("No invalid constraints"),
|
||||
tr("No invalid constraints found"));
|
||||
ui->fixConstraint->setEnabled(false);
|
||||
}
|
||||
else {
|
||||
QMessageBox::warning(this, tr("Invalid constraints"),
|
||||
tr("Invalid constraints found"));
|
||||
ui->fixConstraint->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void SketcherValidation::on_fixConstraint_clicked()
|
||||
{
|
||||
sketch->validateConstraints();
|
||||
ui->fixConstraint->setEnabled(false);
|
||||
}
|
||||
|
||||
void SketcherValidation::showPoints(const std::vector<Base::Vector3d>& pts)
|
||||
{
|
||||
SoCoordinate3 * coords = new SoCoordinate3();
|
||||
|
|
|
@ -49,6 +49,8 @@ protected:
|
|||
private Q_SLOTS:
|
||||
void on_findButton_clicked();
|
||||
void on_fixButton_clicked();
|
||||
void on_findConstraint_clicked();
|
||||
void on_fixConstraint_clicked();
|
||||
|
||||
private:
|
||||
void showPoints(const std::vector<Base::Vector3d>&);
|
||||
|
|
|
@ -7,13 +7,13 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>242</width>
|
||||
<height>137</height>
|
||||
<height>192</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Sketcher validation</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
|
@ -47,6 +47,29 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Invalid constraints</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="findConstraint">
|
||||
<property name="text">
|
||||
<string>Find</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="fixConstraint">
|
||||
<property name="text">
|
||||
<string>Fix</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
|
|
|
@ -3967,6 +3967,13 @@ bool ViewProviderSketch::setEdit(int ModNum)
|
|||
return false;
|
||||
}
|
||||
|
||||
Sketcher::SketchObject* sketch = getSketchObject();
|
||||
if (!sketch->evaluateConstraints()) {
|
||||
QMessageBox::critical(Gui::getMainWindow(), tr("Invalid sketch"),
|
||||
tr("The sketch is invalid and cannot be edited.\nUse the sketch validation tool."));
|
||||
return false;
|
||||
}
|
||||
|
||||
// clear the selection (convenience)
|
||||
Gui::Selection().clearSelection();
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user