From 2775c2b7d34412925b56421691e6d4cb412e20c4 Mon Sep 17 00:00:00 2001 From: mpv Date: Tue, 11 Aug 2015 15:33:36 +0300 Subject: [PATCH] Issue #517: make sketch sub-elements are numbered (for naming) independently on features outside of the sketch. Just a number of created element in the sketch. For this the list of sketch sub-elements is not reduced, even if the element was removed. --- src/Model/Model_AttributeRefList.cpp | 45 ++++++++++++++++++++---- src/Model/Model_AttributeRefList.h | 10 ++++-- src/ModelAPI/ModelAPI_AttributeRefList.h | 22 +++++++----- src/PartSet/PartSet_Tools.cpp | 2 +- src/SketchPlugin/SketchPlugin_Sketch.cpp | 30 +++++++++++++--- src/SketchPlugin/SketchPlugin_Sketch.h | 2 +- 6 files changed, 88 insertions(+), 23 deletions(-) diff --git a/src/Model/Model_AttributeRefList.cpp b/src/Model/Model_AttributeRefList.cpp index 534e52750..9b8db073d 100644 --- a/src/Model/Model_AttributeRefList.cpp +++ b/src/Model/Model_AttributeRefList.cpp @@ -60,9 +60,16 @@ void Model_AttributeRefList::clear() } } -int Model_AttributeRefList::size() const +int Model_AttributeRefList::size(const bool theWithEmpty) const { - return myRef->Extent(); + if (theWithEmpty) + return myRef->Extent(); + int aResult = 0; + const TDF_LabelList& aList = myRef->List(); + for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) { + if (!aLIter.Value().IsNull()) aResult++; + } + return aResult; } bool Model_AttributeRefList::isInitialized() @@ -81,7 +88,9 @@ list Model_AttributeRefList::list() if (aDoc) { const TDF_LabelList& aList = myRef->List(); for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) { - ObjectPtr anObj = aDoc->objects()->object(aLIter.Value()); + ObjectPtr anObj; + if (!aLIter.Value().IsNull()) + anObj = aDoc->objects()->object(aLIter.Value()); aResult.push_back(anObj); } } @@ -108,14 +117,16 @@ bool Model_AttributeRefList::isInList(const ObjectPtr& theObj) return false; } -ObjectPtr Model_AttributeRefList::object(const int theIndex) const +ObjectPtr Model_AttributeRefList::object(const int theIndex, const bool theWithEmpty) const { std::shared_ptr aDoc = std::dynamic_pointer_cast( owner()->document()); if (aDoc) { const TDF_LabelList& aList = myRef->List(); - int anIndex = 0; - for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next(), anIndex++) { + int anIndex = -1; + for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) { + if (theWithEmpty || !aLIter.Value().IsNull()) + anIndex++; if (anIndex == theIndex) return aDoc->objects()->object(aLIter.Value()); } @@ -123,6 +134,28 @@ ObjectPtr Model_AttributeRefList::object(const int theIndex) const return ObjectPtr(); } +void Model_AttributeRefList::substitute(const ObjectPtr& theCurrent, const ObjectPtr& theNew) +{ + std::shared_ptr aDoc = std::dynamic_pointer_cast( + owner()->document()); + if (aDoc) { + std::shared_ptr aData = std::dynamic_pointer_cast(theCurrent->data()); + if (aData.get() && aData->isValid()) { + TDF_Label aCurrentLab = aData->label().Father(); + TDF_Label aNewLab; + if (theNew.get() && theNew->data()->isValid()) { // the new may be null + std::shared_ptr aNewData = + std::dynamic_pointer_cast(theNew->data()); + aNewLab = aNewData->label().Father(); + } + // do the substitution + if (myRef->InsertAfter(aNewLab, aCurrentLab)) { + myRef->Remove(aCurrentLab); + } + } + } +} + Model_AttributeRefList::Model_AttributeRefList(TDF_Label& theLabel) { myIsInitialized = theLabel.FindAttribute(TDataStd_ReferenceList::GetID(), myRef) == Standard_True; diff --git a/src/Model/Model_AttributeRefList.h b/src/Model/Model_AttributeRefList.h index 778b6956d..c7d909b6b 100644 --- a/src/Model/Model_AttributeRefList.h +++ b/src/Model/Model_AttributeRefList.h @@ -30,7 +30,8 @@ class Model_AttributeRefList : public ModelAPI_AttributeRefList MODEL_EXPORT virtual void remove(ObjectPtr theObject); /// Returns number of features in the list - MODEL_EXPORT virtual int size() const; + ///\param theWithEmpty if it is false, returns the number of not-empty referenced objects + MODEL_EXPORT virtual int size(const bool theWithEmpty = true) const; /// Removes all references from the list MODEL_EXPORT virtual void clear(); @@ -42,7 +43,12 @@ class Model_AttributeRefList : public ModelAPI_AttributeRefList MODEL_EXPORT virtual bool isInList(const ObjectPtr& theObj); /// Returns the list of features - MODEL_EXPORT virtual ObjectPtr object(const int theIndex) const; + ///\param theIndex zero-based index in the list + ///\param theWithEmpty if it is false, counts the not-empty referenced objects only + MODEL_EXPORT virtual ObjectPtr object(const int theIndex, const bool theWithEmpty = true) const; + + /// Substitutes the feature by another one. Does nothing if such object is not found. + MODEL_EXPORT virtual void substitute(const ObjectPtr& theCurrent, const ObjectPtr& theNew); /// Returns true if attribute was initialized by some value MODEL_EXPORT virtual bool isInitialized(); diff --git a/src/ModelAPI/ModelAPI_AttributeRefList.h b/src/ModelAPI/ModelAPI_AttributeRefList.h index 8b556d595..91c2741cf 100644 --- a/src/ModelAPI/ModelAPI_AttributeRefList.h +++ b/src/ModelAPI/ModelAPI_AttributeRefList.h @@ -29,25 +29,31 @@ class ModelAPI_AttributeRefList : public ModelAPI_Attribute MODELAPI_EXPORT virtual std::string attributeType(); /// Appends the feature to the end of a list - MODELAPI_EXPORT virtual void append(ObjectPtr theObject) = 0; + virtual void append(ObjectPtr theObject) = 0; /// Erases the first meet of the feature in the list - MODELAPI_EXPORT virtual void remove(ObjectPtr theObject) = 0; + virtual void remove(ObjectPtr theObject) = 0; /// Removes all references from the list - MODELAPI_EXPORT virtual void clear() = 0; + virtual void clear() = 0; /// Returns number of features in the list - MODELAPI_EXPORT virtual int size() const = 0; + ///\param theWithEmpty if it is false, returns the number of not-empty referenced objects + virtual int size(const bool theWithEmpty = true) const = 0; /// Returns the list of features - MODELAPI_EXPORT virtual std::list list() = 0; + virtual std::list list() = 0; /// Returns true if the object is in list - MODELAPI_EXPORT virtual bool isInList(const ObjectPtr& theObj) = 0; + virtual bool isInList(const ObjectPtr& theObj) = 0; - /// Returns the referenced object by the zero-based index - MODELAPI_EXPORT virtual ObjectPtr object(const int theIndex) const = 0; + /// Returns the referenced object by the zero-based index + ///\param theIndex zero-based index in the list + ///\param theWithEmpty if it is false, counts the not-empty referenced objects only + virtual ObjectPtr object(const int theIndex, const bool theWithEmpty = true) const = 0; + + /// Substitutes the feature by another one. Does nothing if such object is not found. + virtual void substitute(const ObjectPtr& theCurrent, const ObjectPtr& theNew) = 0; MODELAPI_EXPORT virtual ~ModelAPI_AttributeRefList(); protected: diff --git a/src/PartSet/PartSet_Tools.cpp b/src/PartSet/PartSet_Tools.cpp index b883dda35..f9c42efa5 100644 --- a/src/PartSet/PartSet_Tools.cpp +++ b/src/PartSet/PartSet_Tools.cpp @@ -392,7 +392,7 @@ void PartSet_Tools::setConstraints(CompositeFeaturePtr theSketch, FeaturePtr the new GeomAPI_Pnt2d(theClickedX, theClickedY)); for (; anIt != aLast; anIt++) { FeaturePtr aFeature = std::dynamic_pointer_cast(*anIt); - if (theFeature == aFeature) + if (!aFeature.get() || theFeature == aFeature) continue; // find the given point in the feature attributes anAttiributes = aFeature->data()->attributes(GeomDataAPI_Point2D::typeId()); diff --git a/src/SketchPlugin/SketchPlugin_Sketch.cpp b/src/SketchPlugin/SketchPlugin_Sketch.cpp index d332177c3..ceaf6dd09 100644 --- a/src/SketchPlugin/SketchPlugin_Sketch.cpp +++ b/src/SketchPlugin/SketchPlugin_Sketch.cpp @@ -140,6 +140,10 @@ void SketchPlugin_Sketch::removeFeature(std::shared_ptr theFea { if (!data()->isValid()) // sketch is already removed (case on undo of sketch), sync is not needed return; + // to keep the persistent sub-elements indexing, do not remove elements from list, + // but substitute by nulls + reflist(SketchPlugin_Sketch::FEATURES_ID())->substitute(theFeature, ObjectPtr()); + /* list aSubs = data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->list(); list::iterator aSubIt = aSubs.begin(), aLastIt = aSubs.end(); bool isRemoved = false; @@ -157,27 +161,42 @@ void SketchPlugin_Sketch::removeFeature(std::shared_ptr theFea // Find the first empty element and remove it if (!isRemoved && aHasEmtpyFeature) data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->remove(ObjectPtr()); + */ } int SketchPlugin_Sketch::numberOfSubs(bool forTree) const { if (forTree) return 0; - return data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->size(); + return data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->size(false); } -std::shared_ptr SketchPlugin_Sketch::subFeature(const int theIndex, bool forTree) const +std::shared_ptr SketchPlugin_Sketch::subFeature( + const int theIndex, bool forTree) const { if (forTree) return FeaturePtr(); - ObjectPtr anObj = data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->object(theIndex); + ObjectPtr anObj = data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->object(theIndex, false); return std::dynamic_pointer_cast(anObj); } int SketchPlugin_Sketch::subFeatureId(const int theIndex) const { - return subFeature(theIndex)->data()->featureId(); + std::shared_ptr aRefList = std::dynamic_pointer_cast< + ModelAPI_AttributeRefList>(data()->attribute(SketchPlugin_Sketch::FEATURES_ID())); + std::list aFeatures = aRefList->list(); + std::list::const_iterator anIt = aFeatures.begin(); + int aResultIndex = 1; // number of the counted (created) features, started from 1 + int aFeatureIndex = -1; // number of the not-empty features in the list + for (; anIt != aFeatures.end(); anIt++) { + if (anIt->get()) + aFeatureIndex++; + if (aFeatureIndex == theIndex) + break; + aResultIndex++; + } + return aResultIndex; } bool SketchPlugin_Sketch::isSub(ObjectPtr theObject) const @@ -256,7 +275,8 @@ void SketchPlugin_Sketch::attributeChanged(const std::string& theID) { std::list aSubs = data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->list(); std::list::iterator aSub = aSubs.begin(); for(; aSub != aSubs.end(); aSub++) { - ModelAPI_EventCreator::get()->sendUpdated(*aSub, anUpdateEvent); + if (aSub->get()) + ModelAPI_EventCreator::get()->sendUpdated(*aSub, anUpdateEvent); } } } diff --git a/src/SketchPlugin/SketchPlugin_Sketch.h b/src/SketchPlugin/SketchPlugin_Sketch.h index 0512b12e9..c9c474f73 100644 --- a/src/SketchPlugin/SketchPlugin_Sketch.h +++ b/src/SketchPlugin/SketchPlugin_Sketch.h @@ -186,7 +186,7 @@ class SketchPlugin_Sketch : public ModelAPI_CompositeFeature, public GeomAPI_ICu SKETCHPLUGIN_EXPORT virtual std::shared_ptr subFeature(const int theIndex, bool forTree = false) const; - /// Returns the sub-feature unique identifier in this composite feature by zero-base index + /// Returns the sub-feature unique identifier in this composite feature by index SKETCHPLUGIN_EXPORT virtual int subFeatureId(const int theIndex) const; /// Returns true if feature or reuslt belong to this composite feature as subs -- 2.39.2