Sketch: Fix crash when moving sketch with hidden constraints
Clicking the eye icon on the constraints panel hides all constraints. This calls SketchObject::setVirtualSpace where the existing Constraint objects will be replaced. However, the Constraint objects are also stored inside the member 'solvedSketch' but won't be replaced so that the pointers there will become dangling. If the user starts to drag the sketch the pointers are still dangling and cause a crash when calling 'solvedSketch.moveGeometries'. The crash can be reproduced with: 1. Create a sketch 2. Add a single line 3. Set a length constraint 4. Make it a non-driving constraint 5. Hide it with the eye icon or by unticking the check box 6. Move the line The same crash also occurs when calling the methods setLabelDistance() or setLabelPosition() from Python and then trying to move the sketch. Solution: To fix the problem add the lightweight method 'Sketch::updateConstraints' and call it inside SketchObject::setVirtualSpace to quickly update the pointers after invalidating them. This fixes issue 19566
This commit is contained in:
@@ -2581,6 +2581,30 @@ int Sketch::addConstraints(
|
||||
return rtn;
|
||||
}
|
||||
|
||||
bool Sketch::updateConstraints(const std::vector<int>& constrIds,
|
||||
const std::vector<Constraint*>& ConstraintList)
|
||||
{
|
||||
if (Constrs.size() != ConstraintList.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int size = static_cast<int>(ConstraintList.size());
|
||||
auto it = std::find_if(constrIds.begin(), constrIds.end(), [size](int id) {
|
||||
return id < 0 || id >= size;
|
||||
});
|
||||
if (it != constrIds.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int id : constrIds) {
|
||||
Constraint* constr = ConstraintList[id];
|
||||
Constrs[id].constr = constr;
|
||||
Constrs[id].driving = constr->isDriving;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Sketch::getBlockedGeometry(
|
||||
std::vector<bool>& blockedGeometry,
|
||||
std::vector<bool>& unenforceableConstraints,
|
||||
|
||||
@@ -250,6 +250,10 @@ public:
|
||||
/// add one constraint to the sketch
|
||||
int addConstraint(const Constraint* constraint);
|
||||
|
||||
/// Updates the internal constraints of the given indexes
|
||||
bool updateConstraints(const std::vector<int>& constrIds,
|
||||
const std::vector<Constraint*>& ConstraintList);
|
||||
|
||||
/**
|
||||
* add a fixed X coordinate constraint to a point
|
||||
*
|
||||
|
||||
@@ -1180,6 +1180,7 @@ int SketchObject::setLabelPosition(int ConstrId, float value)
|
||||
constNew->LabelPosition = value;
|
||||
newVals[ConstrId] = constNew;
|
||||
this->Constraints.setValues(std::move(newVals));
|
||||
solvedSketch.updateConstraints({ConstrId}, this->Constraints.getValues());
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1214,6 +1215,7 @@ int SketchObject::setLabelDistance(int ConstrId, float value)
|
||||
constNew->LabelDistance = value;
|
||||
newVals[ConstrId] = constNew;
|
||||
this->Constraints.setValues(std::move(newVals));
|
||||
solvedSketch.updateConstraints({ConstrId}, this->Constraints.getValues());
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1405,6 +1407,7 @@ int SketchObject::setVirtualSpace(int ConstrId, bool isinvirtualspace)
|
||||
newVals[ConstrId] = constNew;
|
||||
|
||||
this->Constraints.setValues(std::move(newVals));
|
||||
solvedSketch.updateConstraints({ConstrId}, this->Constraints.getValues());
|
||||
|
||||
// Solver didn't actually update, but we need this to inform view provider
|
||||
// to redraw
|
||||
@@ -1440,6 +1443,7 @@ int SketchObject::setVirtualSpace(std::vector<int> constrIds, bool isinvirtualsp
|
||||
}
|
||||
|
||||
this->Constraints.setValues(std::move(newVals));
|
||||
solvedSketch.updateConstraints(constrIds, this->Constraints.getValues());
|
||||
|
||||
// Solver didn't actually update, but we need this to inform view provider
|
||||
// to redraw
|
||||
@@ -1479,6 +1483,7 @@ int SketchObject::toggleVirtualSpace(int ConstrId)
|
||||
newVals[ConstrId] = constNew;
|
||||
|
||||
this->Constraints.setValues(std::move(newVals));
|
||||
solvedSketch.updateConstraints({ConstrId}, this->Constraints.getValues());
|
||||
|
||||
// Solver didn't actually update, but we need this to inform view provider
|
||||
// to redraw
|
||||
|
||||
Reference in New Issue
Block a user