Sketcher: Internal Transaction Support and ensure valid constraint geometry indices
=================================================================================== On changing the geometry property (for example from Python), the constraints geometry indices was not rebuild in order to avoid redundant and unnecessary rebuilds. However, this might cause crashes, as the status of the sketch (or its properties) may be invalid. It also refactors into OnChanged common functionality. This commit does NOT solve that the user may be inserting invalid geometry indices to the First/Second/Third of Constraints (invalid input). Only makes sure that geometry indices (geometry types) of PropertyConstraintList match the geometry. Solution: 1. Force the rebuild of the constraint geometry indices upon assignment of new Geometry. 2. Force the rebuild of the constraint geometry indices upon assigment of constraints, if they result in invalid geometry indices. 3. Introduce the concept of internal transaction to avoid those rebuilds, checks and updates in case of an ongoing internal transaction, thereby preventing them as it was done before introducing 1 and 2 (in the case of SketchObject internal transactions).
This commit is contained in:
committed by
abdullahtahiriyo
parent
1fe43280ca
commit
3941b69170
@@ -141,6 +141,8 @@ SketchObject::SketchObject()
|
||||
constraintsRenamedConn = Constraints.signalConstraintsRenamed.connect(boost::bind(&Sketcher::SketchObject::constraintsRenamed, this, bp::_1));
|
||||
|
||||
analyser = new SketchAnalysis(this);
|
||||
|
||||
internaltransaction=false;
|
||||
}
|
||||
|
||||
SketchObject::~SketchObject()
|
||||
@@ -835,11 +837,11 @@ int SketchObject::addGeometry(const std::vector<Part::Geometry *> &geoList, bool
|
||||
}
|
||||
|
||||
newVals.insert(newVals.end(), copies.begin(), copies.end());
|
||||
// On setting geometry the onChanged method will call acceptGeometry(), thereby updating constraint geometry indices and rebuilding the vertex index
|
||||
Geometry.setValues(newVals);
|
||||
for (std::vector<Part::Geometry *>::iterator it = copies.begin(); it != copies.end(); ++it)
|
||||
delete *it;
|
||||
Constraints.acceptGeometry(getCompleteGeometry());
|
||||
rebuildVertexIndex();
|
||||
|
||||
|
||||
return Geometry.getSize()-1;
|
||||
}
|
||||
@@ -855,10 +857,9 @@ int SketchObject::addGeometry(const Part::Geometry *geo, bool construction/*=fal
|
||||
geoNew->Construction = construction;
|
||||
|
||||
newVals.push_back(geoNew);
|
||||
// On setting geometry the onChanged method will call acceptGeometry(), thereby updating constraint geometry indices and rebuilding the vertex index
|
||||
Geometry.setValues(newVals);
|
||||
Constraints.acceptGeometry(getCompleteGeometry());
|
||||
delete geoNew;
|
||||
rebuildVertexIndex();
|
||||
|
||||
return Geometry.getSize()-1;
|
||||
}
|
||||
@@ -914,10 +915,14 @@ int SketchObject::delGeometry(int GeoId, bool deleteinternalgeo)
|
||||
}
|
||||
}
|
||||
|
||||
this->Geometry.setValues(newVals);
|
||||
this->Constraints.setValues(std::move(newConstraints));
|
||||
this->Constraints.acceptGeometry(getCompleteGeometry());
|
||||
rebuildVertexIndex();
|
||||
// Block acceptGeometry in OnChanged to avoid unnecessary checks and updates
|
||||
{
|
||||
Base::StateLocker lock(internaltransaction, true);
|
||||
this->Geometry.setValues(newVals);
|
||||
this->Constraints.setValues(std::move(newConstraints));
|
||||
}
|
||||
// Update geometry indices and rebuild vertexindex now
|
||||
acceptGeometry();
|
||||
|
||||
if(noRecomputes) // if we do not have a recompute, the sketch must be solved to update the DoF of the solver
|
||||
solve();
|
||||
@@ -930,11 +935,14 @@ int SketchObject::deleteAllGeometry()
|
||||
std::vector< Part::Geometry * > newVals(0);
|
||||
std::vector< Constraint * > newConstraints(0);
|
||||
|
||||
this->Geometry.setValues(newVals);
|
||||
this->Constraints.setValues(newConstraints);
|
||||
// Avoid unnecessary updates and checks as this is a transaction
|
||||
{
|
||||
Base::StateLocker lock(internaltransaction, true);
|
||||
this->Geometry.setValues(newVals);
|
||||
this->Constraints.setValues(newConstraints);
|
||||
}
|
||||
|
||||
this->Constraints.acceptGeometry(getCompleteGeometry());
|
||||
rebuildVertexIndex();
|
||||
acceptGeometry();
|
||||
|
||||
if(noRecomputes) // if we do not have a recompute, the sketch must be solved to update the DoF of the solver
|
||||
solve();
|
||||
@@ -948,9 +956,6 @@ int SketchObject::deleteAllConstraints()
|
||||
|
||||
this->Constraints.setValues(newConstraints);
|
||||
|
||||
this->Constraints.acceptGeometry(getCompleteGeometry());
|
||||
rebuildVertexIndex();
|
||||
|
||||
if(noRecomputes) // if we do not have a recompute, the sketch must be solved to update the DoF of the solver
|
||||
solve();
|
||||
|
||||
@@ -972,8 +977,13 @@ int SketchObject::toggleConstruction(int GeoId)
|
||||
geoNew->Construction = !geoNew->Construction;
|
||||
newVals[GeoId]=geoNew;
|
||||
|
||||
this->Geometry.setValues(newVals);
|
||||
//this->Constraints.acceptGeometry(getCompleteGeometry()); <= This is not necessary for a toggle. Reducing redundant solving. Abdullah
|
||||
// There is not actual intertransaction going on here, however for a toggle neither the geometry indices nor the vertices need to be updated
|
||||
// so this is a convenient way of preventing it.
|
||||
{
|
||||
Base::StateLocker lock(internaltransaction, true);
|
||||
this->Geometry.setValues(newVals);
|
||||
}
|
||||
|
||||
solverNeedsUpdate=true;
|
||||
return 0;
|
||||
}
|
||||
@@ -993,8 +1003,13 @@ int SketchObject::setConstruction(int GeoId, bool on)
|
||||
geoNew->Construction = on;
|
||||
newVals[GeoId]=geoNew;
|
||||
|
||||
this->Geometry.setValues(newVals);
|
||||
//this->Constraints.acceptGeometry(getCompleteGeometry()); <= This is not necessary for a toggle. Reducing redundant solving. Abdullah
|
||||
// There is not actual intertransaction going on here, however for a toggle neither the geometry indices nor the vertices need to be updated
|
||||
// so this is a convenient way of preventing it.
|
||||
{
|
||||
Base::StateLocker lock(internaltransaction, true);
|
||||
this->Geometry.setValues(newVals);
|
||||
}
|
||||
|
||||
solverNeedsUpdate=true;
|
||||
return 0;
|
||||
}
|
||||
@@ -2137,10 +2152,10 @@ int SketchObject::trim(int GeoId, const Base::Vector3d& point)
|
||||
|
||||
std::vector< Part::Geometry * > newVals(geomlist);
|
||||
newVals[GeoId] = geoNew;
|
||||
// This is a special case, we need the geometry and the vertexindex updated here (via onChanged() )
|
||||
// this is not a transaction. if the vertexindex is not rebuild the code below will fail.
|
||||
Geometry.setValues(newVals);
|
||||
Constraints.acceptGeometry(getCompleteGeometry());
|
||||
delete geoNew;
|
||||
rebuildVertexIndex();
|
||||
|
||||
PointPos secondPos1 = Sketcher::none, secondPos2 = Sketcher::none;
|
||||
ConstraintType constrType1 = Sketcher::PointOnObject, constrType2 = Sketcher::PointOnObject;
|
||||
@@ -2252,11 +2267,10 @@ int SketchObject::trim(int GeoId, const Base::Vector3d& point)
|
||||
|
||||
std::vector< Part::Geometry * > newVals(geomlist);
|
||||
newVals[GeoId] = geoNew;
|
||||
// This is a special case, we need the geometry and the vertexindex updated here (via onChanged() )
|
||||
// this is not a transaction. if the vertexindex is not rebuild the code below will fail.
|
||||
Geometry.setValues(newVals);
|
||||
Constraints.acceptGeometry(getCompleteGeometry());
|
||||
delete geoNew;
|
||||
rebuildVertexIndex();
|
||||
|
||||
|
||||
auto handleinternalalignment = [this] (Constraint * constr, int GeoId, PointPos & secondPos) {
|
||||
if( constr->Type == Sketcher::InternalAlignment &&
|
||||
@@ -3459,107 +3473,114 @@ int SketchObject::addSymmetric(const std::vector<int> &geoIdList, int refGeoId,
|
||||
}
|
||||
|
||||
// add the geometry
|
||||
Geometry.setValues(newgeoVals);
|
||||
Constraints.acceptGeometry(getCompleteGeometry());
|
||||
rebuildVertexIndex();
|
||||
|
||||
for (std::vector<Constraint *>::const_iterator it = constrvals.begin(); it != constrvals.end(); ++it) {
|
||||
// Block acceptGeometry in OnChanged to avoid unnecessary checks and updates
|
||||
{
|
||||
Base::StateLocker lock(internaltransaction, true);
|
||||
Geometry.setValues(newgeoVals);
|
||||
|
||||
std::vector<int>::const_iterator fit=std::find(geoIdList.begin(), geoIdList.end(), (*it)->First);
|
||||
for (std::vector<Constraint *>::const_iterator it = constrvals.begin(); it != constrvals.end(); ++it) {
|
||||
|
||||
if(fit != geoIdList.end()) { // if First of constraint is in geoIdList
|
||||
std::vector<int>::const_iterator fit=std::find(geoIdList.begin(), geoIdList.end(), (*it)->First);
|
||||
|
||||
if( (*it)->Second == Constraint::GeoUndef /*&& (*it)->Third == Constraint::GeoUndef*/) {
|
||||
if( (*it)->Type != Sketcher::DistanceX &&
|
||||
(*it)->Type != Sketcher::DistanceY) {
|
||||
if(fit != geoIdList.end()) { // if First of constraint is in geoIdList
|
||||
|
||||
Constraint *constNew = (*it)->copy();
|
||||
if( (*it)->Second == Constraint::GeoUndef /*&& (*it)->Third == Constraint::GeoUndef*/) {
|
||||
if( (*it)->Type != Sketcher::DistanceX &&
|
||||
(*it)->Type != Sketcher::DistanceY) {
|
||||
|
||||
constNew->First = geoIdMap[(*it)->First];
|
||||
newconstrVals.push_back(constNew);
|
||||
}
|
||||
}
|
||||
else { // other geoids intervene in this constraint
|
||||
Constraint *constNew = (*it)->copy();
|
||||
|
||||
std::vector<int>::const_iterator sit=std::find(geoIdList.begin(), geoIdList.end(), (*it)->Second);
|
||||
|
||||
if(sit != geoIdList.end()) { // Second is also in the list
|
||||
|
||||
if( (*it)->Third == Constraint::GeoUndef ) {
|
||||
if((*it)->Type == Sketcher::Coincident ||
|
||||
(*it)->Type == Sketcher::Perpendicular ||
|
||||
(*it)->Type == Sketcher::Parallel ||
|
||||
(*it)->Type == Sketcher::Tangent ||
|
||||
(*it)->Type == Sketcher::Distance ||
|
||||
(*it)->Type == Sketcher::Equal ||
|
||||
(*it)->Type == Sketcher::Radius ||
|
||||
(*it)->Type == Sketcher::Diameter ||
|
||||
(*it)->Type == Sketcher::Angle ||
|
||||
(*it)->Type == Sketcher::PointOnObject ){
|
||||
Constraint *constNew = (*it)->copy();
|
||||
|
||||
constNew->First = geoIdMap[(*it)->First];
|
||||
constNew->Second = geoIdMap[(*it)->Second];
|
||||
if(isStartEndInverted[(*it)->First]){
|
||||
if((*it)->FirstPos == Sketcher::start)
|
||||
constNew->FirstPos = Sketcher::end;
|
||||
else if((*it)->FirstPos == Sketcher::end)
|
||||
constNew->FirstPos = Sketcher::start;
|
||||
}
|
||||
if(isStartEndInverted[(*it)->Second]){
|
||||
if((*it)->SecondPos == Sketcher::start)
|
||||
constNew->SecondPos = Sketcher::end;
|
||||
else if((*it)->SecondPos == Sketcher::end)
|
||||
constNew->SecondPos = Sketcher::start;
|
||||
}
|
||||
|
||||
if (constNew->Type == Tangent || constNew->Type == Perpendicular)
|
||||
AutoLockTangencyAndPerpty(constNew,true);
|
||||
|
||||
if( ((*it)->Type == Sketcher::Angle) && (refPosId == Sketcher::none)) {
|
||||
constNew->setValue(-(*it)->getValue());
|
||||
}
|
||||
|
||||
newconstrVals.push_back(constNew);
|
||||
}
|
||||
constNew->First = geoIdMap[(*it)->First];
|
||||
newconstrVals.push_back(constNew);
|
||||
}
|
||||
else {
|
||||
std::vector<int>::const_iterator tit=std::find(geoIdList.begin(), geoIdList.end(), (*it)->Third);
|
||||
}
|
||||
else { // other geoids intervene in this constraint
|
||||
|
||||
if(tit != geoIdList.end()) { // Third is also in the list
|
||||
Constraint *constNew = (*it)->copy();
|
||||
constNew->First = geoIdMap[(*it)->First];
|
||||
constNew->Second = geoIdMap[(*it)->Second];
|
||||
constNew->Third = geoIdMap[(*it)->Third];
|
||||
if(isStartEndInverted[(*it)->First]){
|
||||
if((*it)->FirstPos == Sketcher::start)
|
||||
constNew->FirstPos = Sketcher::end;
|
||||
else if((*it)->FirstPos == Sketcher::end)
|
||||
constNew->FirstPos = Sketcher::start;
|
||||
std::vector<int>::const_iterator sit=std::find(geoIdList.begin(), geoIdList.end(), (*it)->Second);
|
||||
|
||||
if(sit != geoIdList.end()) { // Second is also in the list
|
||||
|
||||
if( (*it)->Third == Constraint::GeoUndef ) {
|
||||
if((*it)->Type == Sketcher::Coincident ||
|
||||
(*it)->Type == Sketcher::Perpendicular ||
|
||||
(*it)->Type == Sketcher::Parallel ||
|
||||
(*it)->Type == Sketcher::Tangent ||
|
||||
(*it)->Type == Sketcher::Distance ||
|
||||
(*it)->Type == Sketcher::Equal ||
|
||||
(*it)->Type == Sketcher::Radius ||
|
||||
(*it)->Type == Sketcher::Diameter ||
|
||||
(*it)->Type == Sketcher::Angle ||
|
||||
(*it)->Type == Sketcher::PointOnObject ){
|
||||
Constraint *constNew = (*it)->copy();
|
||||
|
||||
constNew->First = geoIdMap[(*it)->First];
|
||||
constNew->Second = geoIdMap[(*it)->Second];
|
||||
if(isStartEndInverted[(*it)->First]){
|
||||
if((*it)->FirstPos == Sketcher::start)
|
||||
constNew->FirstPos = Sketcher::end;
|
||||
else if((*it)->FirstPos == Sketcher::end)
|
||||
constNew->FirstPos = Sketcher::start;
|
||||
}
|
||||
if(isStartEndInverted[(*it)->Second]){
|
||||
if((*it)->SecondPos == Sketcher::start)
|
||||
constNew->SecondPos = Sketcher::end;
|
||||
else if((*it)->SecondPos == Sketcher::end)
|
||||
constNew->SecondPos = Sketcher::start;
|
||||
}
|
||||
|
||||
if (constNew->Type == Tangent || constNew->Type == Perpendicular)
|
||||
AutoLockTangencyAndPerpty(constNew,true);
|
||||
|
||||
if( ((*it)->Type == Sketcher::Angle) && (refPosId == Sketcher::none)) {
|
||||
constNew->setValue(-(*it)->getValue());
|
||||
}
|
||||
|
||||
newconstrVals.push_back(constNew);
|
||||
}
|
||||
if(isStartEndInverted[(*it)->Second]){
|
||||
if((*it)->SecondPos == Sketcher::start)
|
||||
constNew->SecondPos = Sketcher::end;
|
||||
else if((*it)->SecondPos == Sketcher::end)
|
||||
constNew->SecondPos = Sketcher::start;
|
||||
}
|
||||
else {
|
||||
std::vector<int>::const_iterator tit=std::find(geoIdList.begin(), geoIdList.end(), (*it)->Third);
|
||||
|
||||
if(tit != geoIdList.end()) { // Third is also in the list
|
||||
Constraint *constNew = (*it)->copy();
|
||||
constNew->First = geoIdMap[(*it)->First];
|
||||
constNew->Second = geoIdMap[(*it)->Second];
|
||||
constNew->Third = geoIdMap[(*it)->Third];
|
||||
if(isStartEndInverted[(*it)->First]){
|
||||
if((*it)->FirstPos == Sketcher::start)
|
||||
constNew->FirstPos = Sketcher::end;
|
||||
else if((*it)->FirstPos == Sketcher::end)
|
||||
constNew->FirstPos = Sketcher::start;
|
||||
}
|
||||
if(isStartEndInverted[(*it)->Second]){
|
||||
if((*it)->SecondPos == Sketcher::start)
|
||||
constNew->SecondPos = Sketcher::end;
|
||||
else if((*it)->SecondPos == Sketcher::end)
|
||||
constNew->SecondPos = Sketcher::start;
|
||||
}
|
||||
if(isStartEndInverted[(*it)->Third]){
|
||||
if((*it)->ThirdPos == Sketcher::start)
|
||||
constNew->ThirdPos = Sketcher::end;
|
||||
else if((*it)->ThirdPos == Sketcher::end)
|
||||
constNew->ThirdPos = Sketcher::start;
|
||||
}
|
||||
newconstrVals.push_back(constNew);
|
||||
}
|
||||
if(isStartEndInverted[(*it)->Third]){
|
||||
if((*it)->ThirdPos == Sketcher::start)
|
||||
constNew->ThirdPos = Sketcher::end;
|
||||
else if((*it)->ThirdPos == Sketcher::end)
|
||||
constNew->ThirdPos = Sketcher::start;
|
||||
}
|
||||
newconstrVals.push_back(constNew);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( newconstrVals.size() > constrvals.size() )
|
||||
Constraints.setValues(newconstrVals);
|
||||
|
||||
}
|
||||
|
||||
// we delayed update, so trigger it now.
|
||||
acceptGeometry();
|
||||
|
||||
return Geometry.getSize()-1;
|
||||
}
|
||||
|
||||
@@ -3973,12 +3994,17 @@ int SketchObject::addCopy(const std::vector<int> &geoIdList, const Base::Vector3
|
||||
}
|
||||
}
|
||||
|
||||
Geometry.setValues(newgeoVals);
|
||||
Constraints.acceptGeometry(getCompleteGeometry());
|
||||
rebuildVertexIndex();
|
||||
// Block acceptGeometry in OnChanged to avoid unnecessary checks and updates
|
||||
{
|
||||
Base::StateLocker lock(internaltransaction, true);
|
||||
Geometry.setValues(newgeoVals);
|
||||
|
||||
if( newconstrVals.size() > constrvals.size() )
|
||||
Constraints.setValues(newconstrVals);
|
||||
if( newconstrVals.size() > constrvals.size() )
|
||||
Constraints.setValues(newconstrVals);
|
||||
}
|
||||
|
||||
// we inhibited update, so we trigger it now
|
||||
acceptGeometry();
|
||||
|
||||
return Geometry.getSize()-1;
|
||||
|
||||
@@ -4916,32 +4942,38 @@ bool SketchObject::convertToNURBS(int GeoId)
|
||||
|
||||
std::vector< Part::Geometry * > newVals(vals);
|
||||
|
||||
if (GeoId < 0) { // external geometry
|
||||
newVals.push_back(bspline);
|
||||
}
|
||||
else { // normal geometry
|
||||
// Block checks and updates in OnChanged to avoid unnecessary checks and updates
|
||||
{
|
||||
Base::StateLocker lock(internaltransaction, true);
|
||||
|
||||
newVals[GeoId] = bspline;
|
||||
|
||||
const std::vector< Sketcher::Constraint * > &cvals = Constraints.getValues();
|
||||
|
||||
std::vector< Constraint * > newcVals(cvals);
|
||||
|
||||
int index = cvals.size()-1;
|
||||
// delete constraints on this elements other than coincident constraints (bspline does not support them currently)
|
||||
for (; index >= 0; index--) {
|
||||
if (cvals[index]->Type != Sketcher::Coincident && ( cvals[index]->First == GeoId || cvals[index]->Second == GeoId || cvals[index]->Third == GeoId)) {
|
||||
|
||||
newcVals.erase(newcVals.begin()+index);
|
||||
|
||||
}
|
||||
if (GeoId < 0) { // external geometry
|
||||
newVals.push_back(bspline);
|
||||
}
|
||||
this->Constraints.setValues(newcVals);
|
||||
else { // normal geometry
|
||||
|
||||
newVals[GeoId] = bspline;
|
||||
|
||||
const std::vector< Sketcher::Constraint * > &cvals = Constraints.getValues();
|
||||
|
||||
std::vector< Constraint * > newcVals(cvals);
|
||||
|
||||
int index = cvals.size()-1;
|
||||
// delete constraints on this elements other than coincident constraints (bspline does not support them currently)
|
||||
for (; index >= 0; index--) {
|
||||
if (cvals[index]->Type != Sketcher::Coincident && ( cvals[index]->First == GeoId || cvals[index]->Second == GeoId || cvals[index]->Third == GeoId)) {
|
||||
|
||||
newcVals.erase(newcVals.begin()+index);
|
||||
|
||||
}
|
||||
}
|
||||
this->Constraints.setValues(newcVals);
|
||||
}
|
||||
|
||||
Geometry.setValues(newVals);
|
||||
}
|
||||
|
||||
Geometry.setValues(newVals);
|
||||
Constraints.acceptGeometry(getCompleteGeometry());
|
||||
rebuildVertexIndex();
|
||||
// trigger update now
|
||||
acceptGeometry();
|
||||
|
||||
delete bspline;
|
||||
|
||||
@@ -4981,9 +5013,8 @@ bool SketchObject::increaseBSplineDegree(int GeoId, int degreeincrement /*= 1*/)
|
||||
|
||||
newVals[GeoId] = bspline.release();
|
||||
|
||||
// AcceptGeometry called from onChanged
|
||||
Geometry.setValues(newVals);
|
||||
Constraints.acceptGeometry(getCompleteGeometry());
|
||||
rebuildVertexIndex();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -5127,11 +5158,15 @@ bool SketchObject::modifyBSplineKnotMultiplicity(int GeoId, int knotIndex, int m
|
||||
|
||||
newVals[GeoId] = bspline;
|
||||
|
||||
Geometry.setValues(newVals);
|
||||
Constraints.acceptGeometry(getCompleteGeometry());
|
||||
rebuildVertexIndex();
|
||||
// Block acceptGeometry in OnChanged to avoid unnecessary checks and updates
|
||||
{
|
||||
Base::StateLocker lock(internaltransaction, true);
|
||||
Geometry.setValues(newVals);
|
||||
|
||||
this->Constraints.setValues(newcVals);
|
||||
this->Constraints.setValues(newcVals);
|
||||
}
|
||||
// Trigger update now
|
||||
acceptGeometry();
|
||||
|
||||
std::sort (delGeoId.begin(), delGeoId.end());
|
||||
|
||||
@@ -5265,11 +5300,14 @@ int SketchObject::carbonCopy(App::DocumentObject * pObj, bool construction)
|
||||
newcVals.push_back(newConstr);
|
||||
}
|
||||
|
||||
Geometry.setValues(newVals);
|
||||
Constraints.acceptGeometry(getCompleteGeometry());
|
||||
rebuildVertexIndex();
|
||||
|
||||
this->Constraints.setValues(newcVals);
|
||||
// Block acceptGeometry in OnChanged to avoid unnecessary checks and updates
|
||||
{
|
||||
Base::StateLocker lock(internaltransaction, true);
|
||||
Geometry.setValues(newVals);
|
||||
this->Constraints.setValues(newcVals);
|
||||
}
|
||||
// we trigger now the update (before dealing with expressions)
|
||||
acceptGeometry();
|
||||
|
||||
int sourceid = 0;
|
||||
for (std::vector< Sketcher::Constraint * >::const_iterator it= scvals.begin(); it != scvals.end(); ++it,nextcid++,sourceid++) {
|
||||
@@ -5342,9 +5380,9 @@ int SketchObject::addExternal(App::DocumentObject *Obj, const char* SubName)
|
||||
return -1;
|
||||
}
|
||||
|
||||
acceptGeometry(); // This may need to be refactored into onChanged for ExternalGeometry
|
||||
|
||||
solverNeedsUpdate=true;
|
||||
Constraints.acceptGeometry(getCompleteGeometry());
|
||||
rebuildVertexIndex();
|
||||
return ExternalGeometry.getValues().size()-1;
|
||||
}
|
||||
|
||||
@@ -5399,8 +5437,7 @@ int SketchObject::delExternal(int ExtGeoId)
|
||||
|
||||
solverNeedsUpdate=true;
|
||||
Constraints.setValues(std::move(newConstraints));
|
||||
Constraints.acceptGeometry(getCompleteGeometry());
|
||||
rebuildVertexIndex();
|
||||
acceptGeometry(); // This may need to be refactored into OnChanged for ExternalGeometry.
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5447,8 +5484,7 @@ int SketchObject::delAllExternal()
|
||||
Constraints.setValues(newConstraints);
|
||||
for (Constraint* it : newConstraints)
|
||||
delete it;
|
||||
Constraints.acceptGeometry(getCompleteGeometry());
|
||||
rebuildVertexIndex();
|
||||
acceptGeometry(); // This may need to be refactored into OnChanged for ExternalGeometry
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5640,8 +5676,7 @@ void SketchObject::validateExternalLinks(void)
|
||||
if (rebuild) {
|
||||
ExternalGeometry.setValues(Objects,SubElements);
|
||||
rebuildExternalGeometry();
|
||||
Constraints.acceptGeometry(getCompleteGeometry());
|
||||
rebuildVertexIndex();
|
||||
acceptGeometry(); // This may need to be refactor to OnChanged for ExternalGeo
|
||||
solve(true); // we have to update this sketch and everything depending on it.
|
||||
}
|
||||
}
|
||||
@@ -6808,7 +6843,15 @@ void SketchObject::onChanged(const App::Property* prop)
|
||||
setStatus(App::PendingTransactionUpdate, true);
|
||||
}
|
||||
else {
|
||||
Constraints.checkGeometry(getCompleteGeometry());
|
||||
if(!internaltransaction) { // internal sketchobject operations changing both geometry and constraints will explicity perform an update
|
||||
if(prop == &Geometry) {
|
||||
acceptGeometry(); // if geometry changed, the constraint geometry indices must be updated
|
||||
}
|
||||
else { // Change is in Constraints
|
||||
if (Constraints.checkGeometry(getCompleteGeometry())) // if there are invalid geometry indices in the constraints, we need to update them
|
||||
acceptGeometry();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (prop == &ExternalGeometry) {
|
||||
|
||||
Reference in New Issue
Block a user