diff --git a/src/Mod/Sketcher/App/PropertyConstraintList.cpp b/src/Mod/Sketcher/App/PropertyConstraintList.cpp index 23cb85040..11d0ab6ab 100644 --- a/src/Mod/Sketcher/App/PropertyConstraintList.cpp +++ b/src/Mod/Sketcher/App/PropertyConstraintList.cpp @@ -52,7 +52,7 @@ TYPESYSTEM_SOURCE(Sketcher::PropertyConstraintList, App::PropertyLists); // Construction/Destruction -PropertyConstraintList::PropertyConstraintList() +PropertyConstraintList::PropertyConstraintList() : validGeometryKeys(0), invalidGeometry(true) { } @@ -174,6 +174,9 @@ void PropertyConstraintList::Restore(Base::XMLReader &reader) Property *PropertyConstraintList::Copy(void) const { PropertyConstraintList *p = new PropertyConstraintList(); + p->setValidGeometryKeys(validGeometryKeys); + if (invalidGeometry) + p->invalidateGeometry(); p->setValues(_lValueList); return p; } @@ -181,6 +184,9 @@ Property *PropertyConstraintList::Copy(void) const void PropertyConstraintList::Paste(const Property &from) { const PropertyConstraintList& FromList = dynamic_cast(from); + setValidGeometryKeys(FromList.validGeometryKeys); + if (FromList.invalidGeometry) + invalidateGeometry(); setValues(FromList._lValueList); } @@ -191,3 +197,51 @@ unsigned int PropertyConstraintList::getMemSize(void) const size += _lValueList[i]->getMemSize(); return size; } + +void PropertyConstraintList::acceptGeometry(const std::vector &GeoList) +{ + aboutToSetValue(); + validGeometryKeys.clear(); + validGeometryKeys.reserve(GeoList.size()); + for (std::vector< Part::Geometry * >::const_iterator it=GeoList.begin(); + it != GeoList.end(); ++it) + validGeometryKeys.push_back((*it)->getTypeId().getKey()); + invalidGeometry = false; + hasSetValue(); +} + +void PropertyConstraintList::setValidGeometryKeys(const std::vector &keys) +{ + validGeometryKeys = keys; + invalidGeometry = false; +} + +void PropertyConstraintList::invalidateGeometry() +{ + invalidGeometry = true; +} + +void PropertyConstraintList::checkGeometry(const std::vector &GeoList) +{ + if (validGeometryKeys.size() != GeoList.size()) { + invalidGeometry = true; + return; + } + + unsigned int i=0; + for (std::vector< Part::Geometry * >::const_iterator it=GeoList.begin(); + it != GeoList.end(); ++it, i++) { + if (validGeometryKeys[i] != (*it)->getTypeId().getKey()) { + invalidGeometry = true; + return; + } + } + + if (invalidGeometry) { + aboutToSetValue(); + invalidGeometry = false; + hasSetValue(); + } +} + +std::vector PropertyConstraintList::_emptyValueList(0); diff --git a/src/Mod/Sketcher/App/PropertyConstraintList.h b/src/Mod/Sketcher/App/PropertyConstraintList.h index 4843a96f7..54336bf5b 100644 --- a/src/Mod/Sketcher/App/PropertyConstraintList.h +++ b/src/Mod/Sketcher/App/PropertyConstraintList.h @@ -30,6 +30,7 @@ #include #include #include +#include #include "Constraint.h" namespace Base { @@ -67,11 +68,11 @@ public: /// index operator const Constraint *operator[] (const int idx) const { - return _lValueList[idx]; + return invalidGeometry ? 0 : _lValueList[idx]; } const std::vector &getValues(void) const { - return _lValueList; + return invalidGeometry ? _emptyValueList : _lValueList; } virtual PyObject *getPyObject(void); @@ -85,8 +86,19 @@ public: virtual unsigned int getMemSize(void) const; + void acceptGeometry(const std::vector &GeoList); + void invalidateGeometry(); + void checkGeometry(const std::vector &GeoList); + private: - std::vector _lValueList; + std::vector _lValueList; + + std::vector validGeometryKeys; + bool invalidGeometry; + + void setValidGeometryKeys(const std::vector &keys); + + static std::vector _emptyValueList; }; } // namespace Sketcher diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index 0d9cb38b9..3fd949b40 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -228,6 +228,7 @@ int SketchObject::addGeometry(const Part::Geometry *geo) Part::Geometry *geoNew = geo->clone(); newVals.push_back(geoNew); Geometry.setValues(newVals); + Constraints.acceptGeometry(Geometry.getValues()); delete geoNew; rebuildVertexIndex(); return Geometry.getSize()-1; @@ -256,13 +257,9 @@ int SketchObject::delGeometry(int GeoNbr) } } - // temporarily empty constraints list in order to avoid invalid constraints - // during manipulation of the geometry list - std::vector< Constraint * > emptyConstraints(0); - this->Constraints.setValues(emptyConstraints); - this->Geometry.setValues(newVals); this->Constraints.setValues(newConstraints); + this->Constraints.acceptGeometry(this->Geometry.getValues()); rebuildVertexIndex(); return 0; } @@ -280,6 +277,7 @@ int SketchObject::toggleConstruction(int GeoNbr) newVals[GeoNbr]=geoNew; this->Geometry.setValues(newVals); + this->Constraints.acceptGeometry(this->Geometry.getValues()); return 0; } @@ -758,6 +756,8 @@ int SketchObject::trim(int GeoId, const Base::Vector3d& point) delete newConstr; + Constraints.acceptGeometry(Geometry.getValues()); + return 0; } @@ -1066,9 +1066,17 @@ void SketchObject::Restore(XMLReader &reader) { // read the father classes Part::Part2DObject::Restore(reader); + Constraints.acceptGeometry(Geometry.getValues()); rebuildVertexIndex(); } +void SketchObject::onChanged(const App::Property* prop) +{ + if (prop == &Geometry || prop == &Constraints) + Constraints.checkGeometry(Geometry.getValues()); + DocumentObject::onChanged(prop); +} + void SketchObject::getGeoVertexIndex(int VertexId, int &GeoId, PointPos &PosId) { if (VertexId < 0 || VertexId >= (int)VertexId2GeoId.size()) { diff --git a/src/Mod/Sketcher/App/SketchObject.h b/src/Mod/Sketcher/App/SketchObject.h index 91883ec02..210ee6ae0 100644 --- a/src/Mod/Sketcher/App/SketchObject.h +++ b/src/Mod/Sketcher/App/SketchObject.h @@ -44,9 +44,9 @@ public: SketchObject(); /// Property + Part ::PropertyGeometryList Geometry; Sketcher::PropertyConstraintList Constraints; App ::PropertyLinkSubList ExternalConstraints; - Part ::PropertyGeometryList Geometry; /** @name methods overide Feature */ //@{ /// recalculate the Feature @@ -123,6 +123,10 @@ public: virtual void Save(Base::Writer &/*writer*/) const; virtual void Restore(Base::XMLReader &/*reader*/); +protected: + /// get called by the container when a property has changed + virtual void onChanged(const App::Property* /*prop*/); + private: std::vector VertexId2GeoId; std::vector VertexId2PosId;