From 06d69ef06f27d1aefb1f2b5c56a4e833da59645c Mon Sep 17 00:00:00 2001 From: mpv Date: Wed, 20 Jan 2016 15:42:32 +0300 Subject: [PATCH] Implementation of AttributeRefAttrList for a fillet created in the list of points. --- src/Model/CMakeLists.txt | 2 + src/Model/Model_AttributeRefAttrList.cpp | 316 ++++++++++++++++++ src/Model/Model_AttributeRefAttrList.h | 78 +++++ src/Model/Model_Data.h | 1 + src/Model/Model_Document.h | 1 + src/ModelAPI/CMakeLists.txt | 2 + .../ModelAPI_AttributeRefAttrList.cpp | 23 ++ src/ModelAPI/ModelAPI_AttributeRefAttrList.h | 83 +++++ 8 files changed, 506 insertions(+) create mode 100755 src/Model/Model_AttributeRefAttrList.cpp create mode 100755 src/Model/Model_AttributeRefAttrList.h create mode 100755 src/ModelAPI/ModelAPI_AttributeRefAttrList.cpp create mode 100755 src/ModelAPI/ModelAPI_AttributeRefAttrList.h diff --git a/src/Model/CMakeLists.txt b/src/Model/CMakeLists.txt index 6c55e5350..2ebf396ea 100644 --- a/src/Model/CMakeLists.txt +++ b/src/Model/CMakeLists.txt @@ -14,6 +14,7 @@ SET(PROJECT_HEADERS Model_AttributeReference.h Model_AttributeRefAttr.h Model_AttributeRefList.h + Model_AttributeRefAttrList.h Model_AttributeBoolean.h Model_AttributeIntArray.h Model_AttributeString.h @@ -47,6 +48,7 @@ SET(PROJECT_SOURCES Model_AttributeReference.cpp Model_AttributeRefAttr.cpp Model_AttributeRefList.cpp + Model_AttributeRefAttrList.cpp Model_AttributeBoolean.cpp Model_AttributeIntArray.cpp Model_AttributeString.cpp diff --git a/src/Model/Model_AttributeRefAttrList.cpp b/src/Model/Model_AttributeRefAttrList.cpp new file mode 100755 index 000000000..e08420a01 --- /dev/null +++ b/src/Model/Model_AttributeRefAttrList.cpp @@ -0,0 +1,316 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: ModelAPI_AttributeRefAttrList.cxx +// Created: 8 May 2014 +// Author: Mikhail PONIKAROV + +#include "Model_AttributeRefAttrList.h" +#include "Model_Application.h" +#include "Model_Data.h" +#include "Model_Objects.h" +#include +#include +#include + +using namespace std; + +void Model_AttributeRefAttrList::append(ObjectPtr theObject) +{ + std::shared_ptr aData = std::dynamic_pointer_cast(theObject->data()); + myRef->Append(aData->label().Father()); // store label of the object + myIDs->Append(""); // for the object store an empty string + // do it before the transaction finish to make just created/removed objects know dependencies + // and reference from composite feature is removed automatically + ADD_BACK_REF(theObject); + + owner()->data()->sendAttributeUpdated(this); +} + +void Model_AttributeRefAttrList::append(AttributePtr theAttr) +{ + std::shared_ptr aData = + std::dynamic_pointer_cast(theAttr->owner()->data()); + myRef->Append(aData->label().Father()); // store label of the object + myIDs->Append(theAttr->id().c_str()); // store the ID of the referenced attribute + // do it before the transaction finish to make just created/removed objects know dependencies + // and reference from composite feature is removed automatically + ADD_BACK_REF(theAttr->owner()); + + owner()->data()->sendAttributeUpdated(this); +} + +void Model_AttributeRefAttrList::remove(ObjectPtr theObject) +{ + TDF_Label aTheObjLab; + if (theObject.get() != NULL) { + aTheObjLab = std::dynamic_pointer_cast(theObject->data())->label().Father(); + } + std::shared_ptr aDoc = + std::dynamic_pointer_cast(owner()->document()); + // remove from the both lists by clearing the list and then appending one by one + // TODO: in OCCT 7.0 there are methods for removing by index, seems will be more optimal + TDF_LabelList aRefList = myRef->List(); + myRef->Clear(); + TDataStd_ListOfExtendedString anIDList = myIDs->List(); + myIDs->Clear(); + bool aOneisDeleted = false; + TDF_ListIteratorOfLabelList aRefIter(aRefList); + TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList); + for (; aRefIter.More(); aRefIter.Next(), anIDIter.Next()) { + // append now only not removed + if (aOneisDeleted || aRefIter.Value() != aTheObjLab || !anIDIter.Value().IsEmpty() || + (aTheObjLab.IsNull() && aDoc->objects()->object(aRefIter.Value()) != NULL)) { + myRef->Append(aRefIter.Value()); + myIDs->Append(anIDIter.Value()); + } else if (aTheObjLab.IsNull() && aDoc->objects()->object(aRefIter.Value()) != NULL) { + aOneisDeleted = true; + } + } + if (aOneisDeleted) { + REMOVE_BACK_REF(theObject); + owner()->data()->sendAttributeUpdated(this); + } +} + +void Model_AttributeRefAttrList::remove(AttributePtr theAttr) +{ + TDF_Label aTheObjLab; + if (theAttr->owner().get() != NULL) { + aTheObjLab = std::dynamic_pointer_cast(theAttr->owner()->data())->label().Father(); + } + std::shared_ptr aDoc = + std::dynamic_pointer_cast(owner()->document()); + // remove from the both lists by clearing the list and then appending one by one + // TODO: in OCCT 7.0 there are methods for removing by index, seems will be more optimal + TDF_LabelList aRefList = myRef->List(); + myRef->Clear(); + TDataStd_ListOfExtendedString anIDList = myIDs->List(); + myIDs->Clear(); + bool aOneisDeleted = false; + TDF_ListIteratorOfLabelList aRefIter(aRefList); + TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList); + for (; aRefIter.More(); aRefIter.Next(), anIDIter.Next()) { + if (aOneisDeleted || anIDIter.Value() != theAttr->id().c_str() || // append now only not removed + aRefIter.Value() != aTheObjLab || // append now only not removed + (aTheObjLab.IsNull() && aDoc->objects()->object(aRefIter.Value()) != NULL)) { + myRef->Append(aRefIter.Value()); + myIDs->Append(anIDIter.Value()); + } else if (aTheObjLab.IsNull() && aDoc->objects()->object(aRefIter.Value()) != NULL) { + aOneisDeleted = true; + } + } + if (aOneisDeleted) { + REMOVE_BACK_REF(theAttr->owner()); + owner()->data()->sendAttributeUpdated(this); + } +} + +void Model_AttributeRefAttrList::clear() +{ + std::list > anOldList = list(); + myRef->Clear(); + myIDs->Clear(); + std::list >::iterator anOldIter = anOldList.begin(); + for(; anOldIter != anOldList.end(); anOldIter++) { + REMOVE_BACK_REF((anOldIter->first)); + } + owner()->data()->sendAttributeUpdated(this); +} + +int Model_AttributeRefAttrList::size() const +{ + return myRef->Extent(); +} + +bool Model_AttributeRefAttrList::isInitialized() +{ + if (size() == 0) { // empty list is not initialized list: sketch will be not valid after add/undo + return false; + } + return ModelAPI_AttributeRefAttrList::isInitialized(); +} + +std::list > Model_AttributeRefAttrList::list() +{ + std::list > aResult; + std::shared_ptr aDoc = std::dynamic_pointer_cast( + owner()->document()); + if (aDoc) { + const TDF_LabelList& aList = myRef->List(); + const TDataStd_ListOfExtendedString& anIDList = myIDs->List(); + TDF_ListIteratorOfLabelList aLIter(aList); + TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList); + for (; aLIter.More(); aLIter.Next(), anIDIter.Next()) { + ObjectPtr anObj; + if (!aLIter.Value().IsNull()) + anObj = aDoc->objects()->object(aLIter.Value()); + aResult.push_back(std::pair(anObj, + anObj->data()->attribute(TCollection_AsciiString(anIDIter.Value()).ToCString()))); + } + } + return aResult; +} + +bool Model_AttributeRefAttrList::isInList(const ObjectPtr& theObj) +{ + if(!theObj.get()) { + return false; + } + std::list aResult; + std::shared_ptr aDoc = std::dynamic_pointer_cast( + owner()->document()); + if (aDoc) { + std::shared_ptr aData = std::dynamic_pointer_cast(theObj->data()); + if (aData.get() && aData->isValid()) { + TDF_Label anObjLab = aData->label().Father(); + const TDF_LabelList& aList = myRef->List(); + const TDataStd_ListOfExtendedString& anIDList = myIDs->List(); + TDF_ListIteratorOfLabelList aLIter(aList); + TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList); + for (; aLIter.More(); aLIter.Next(), anIDIter.Next()) { + if (anIDIter.Value().IsEmpty() && aLIter.Value().IsEqual(anObjLab)) { + return true; + } + } + } + } + return false; +} + +bool Model_AttributeRefAttrList::isInList(const AttributePtr& theAttr) +{ + if (!theAttr->owner().get()) { + return false; + } + std::list aResult; + std::shared_ptr aDoc = std::dynamic_pointer_cast( + owner()->document()); + if (aDoc) { + std::shared_ptr aData = + std::dynamic_pointer_cast(theAttr->owner()->data()); + if (aData.get() && aData->isValid()) { + TDF_Label anObjLab = aData->label().Father(); + const TDF_LabelList& aList = myRef->List(); + const TDataStd_ListOfExtendedString& anIDList = myIDs->List(); + TDF_ListIteratorOfLabelList aLIter(aList); + TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList); + for (; aLIter.More(); aLIter.Next(), anIDIter.Next()) { + if (anIDIter.Value() == theAttr->id().c_str() && aLIter.Value().IsEqual(anObjLab)) { + return true; + } + } + } + } + return false; +} + +bool Model_AttributeRefAttrList::isAttribute(const int theIndex) const +{ + const TDataStd_ListOfExtendedString& anIDList = myIDs->List(); + TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList); + int anIndex = -1; + for (; anIDIter.More(); anIDIter.Next()) { + anIndex++; + if (anIndex == theIndex) { + return !anIDIter.Value().IsEmpty(); + } + } + return false; +} + +ObjectPtr Model_AttributeRefAttrList::object(const int theIndex) const +{ + std::shared_ptr aDoc = std::dynamic_pointer_cast( + owner()->document()); + if (aDoc) { + const TDF_LabelList& aList = myRef->List(); + int anIndex = -1; + for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) { + anIndex++; + if (anIndex == theIndex) { + if (aLIter.Value().IsNull()) { // null label => null sub + return ObjectPtr(); + } + return aDoc->objects()->object(aLIter.Value()); + } + } + } + return ObjectPtr(); +} + +AttributePtr Model_AttributeRefAttrList::attribute(const int theIndex) const +{ + std::shared_ptr aDoc = std::dynamic_pointer_cast( + owner()->document()); + if (aDoc) { + int anIndex = -1; + const TDF_LabelList& aList = myRef->List(); + const TDataStd_ListOfExtendedString& anIDList = myIDs->List(); + TDF_ListIteratorOfLabelList aLIter(aList); + TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList); + for (; aLIter.More(); aLIter.Next(), anIDIter.Next()) { + anIndex++; + if (anIndex == theIndex) { + if (aLIter.Value().IsNull()) { // null label => null sub + return AttributePtr(); + } + return aDoc->objects()->object(aLIter.Value())->data()-> + attribute(TCollection_AsciiString(anIDIter.Value().ToExtString()).ToCString()); + } + } + } + return AttributePtr(); +} + +void Model_AttributeRefAttrList::removeLast() +{ + // remove from the both lists by clearing the list and then appending one by one + // TODO: in OCCT 7.0 there are methods for removing by index, seems will be more optimal + std::set aLastSet; + aLastSet.insert(size() - 1); + remove(aLastSet); +} + +void Model_AttributeRefAttrList::remove(const std::set& theIndices) +{ + std::shared_ptr aDoc = std::dynamic_pointer_cast( + owner()->document()); + if (aDoc && !myRef->IsEmpty()) { + // remove from the both lists by clearing the list and then appending one by one + // TODO: in OCCT 7.0 there are methods for removing by index, seems will be more optimal + TDF_LabelList aRefList = myRef->List(); + myRef->Clear(); + TDataStd_ListOfExtendedString anIDList = myIDs->List(); + myIDs->Clear(); + bool aOneisDeleted = false; + TDF_ListIteratorOfLabelList aRefIter(aRefList); + TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList); + for (int anIndex = 0; aRefIter.More(); aRefIter.Next(), anIDIter.Next(), anIndex++) { + if (theIndices.find(anIndex) == theIndices.end()) { // not found + myRef->Append(aRefIter.Value()); + myIDs->Append(anIDIter.Value()); + } else { // found, so need to update the dependencies + aOneisDeleted = true; + ObjectPtr anObj = aDoc->objects()->object(aRefIter.Value()); + if (anObj.get()) { + myRef->Remove(aRefIter.Value()); + REMOVE_BACK_REF(anObj); + } + } + } + if (aOneisDeleted) { + owner()->data()->sendAttributeUpdated(this); + } + } +} + +Model_AttributeRefAttrList::Model_AttributeRefAttrList(TDF_Label& theLabel) +{ + myIsInitialized = theLabel.FindAttribute(TDataStd_ReferenceList::GetID(), myRef) == Standard_True; + if (!myIsInitialized) { + myRef = TDataStd_ReferenceList::Set(theLabel); + myIDs = TDataStd_ExtStringList::Set(theLabel); + } else { + theLabel.FindAttribute(TDataStd_ExtStringList::GetID(), myIDs); + } +} diff --git a/src/Model/Model_AttributeRefAttrList.h b/src/Model/Model_AttributeRefAttrList.h new file mode 100755 index 000000000..0d36c383e --- /dev/null +++ b/src/Model/Model_AttributeRefAttrList.h @@ -0,0 +1,78 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: Model_AttributeRefAttrList.h +// Created: 20 Jan 2016 +// Author: Mikhail PONIKAROV + +#ifndef Model_AttributeRefAttrList_H_ +#define Model_AttributeRefAttrList_H_ + +#include "Model.h" +#include "ModelAPI_AttributeRefAttrList.h" +#include "ModelAPI_Feature.h" + +#include +#include + +/**\class Model_AttributeRefAttrList + * \ingroup DataModel + * \brief Attribute that contains list of references to features (located in the same document) + * or references to attributes of the features (list of AttributeRefAttr) + */ + +class Model_AttributeRefAttrList : public ModelAPI_AttributeRefAttrList +{ + Handle_TDataStd_ReferenceList myRef; ///< references to the features labels + Handle_TDataStd_ExtStringList myIDs; ///< the referenced attributes IDs (empty for just object) + public: + /// Appends the feature to the end of a list + MODEL_EXPORT virtual void append(ObjectPtr theObject); + /// Appends the attribute to the end of a list + MODEL_EXPORT virtual void append(AttributePtr theAttr); + + /// Erases the first meet of the feature in the list + MODEL_EXPORT virtual void remove(ObjectPtr theObject); + /// Erases the first meet of the attribute in the list + MODEL_EXPORT virtual void remove(AttributePtr theAttr); + + /// Removes all references from the list + MODEL_EXPORT virtual void clear(); + + /// Returns number of features in the list + MODEL_EXPORT virtual int size() const; + + /// Returns the list of features and attributes (if it is reference to the attribute) + MODEL_EXPORT virtual std::list > list(); + + /// Returns true if the object is in list + MODEL_EXPORT virtual bool isInList(const ObjectPtr& theObj); + /// Returns true if the attribute is in list + MODEL_EXPORT virtual bool isInList(const AttributePtr& theObj); + + /// Returns true if this is reference to an attribute, not just object + MODEL_EXPORT virtual bool isAttribute(const int theIndex) const; + + /// Returns the referenced object by the zero-based index + ///\param theIndex zero-based index in the list + MODEL_EXPORT virtual ObjectPtr object(const int theIndex) const; + /// Returns the referenced attribute by the zero-based index + ///\param theIndex zero-based index in the list + MODEL_EXPORT virtual AttributePtr attribute(const int theIndex) const; + + /// Removes the last element in the list. + MODEL_EXPORT virtual void removeLast() = 0; + + /// Removes the elements from the list. + /// \param theIndices a list of indices of elements to be removed + MODEL_EXPORT virtual void remove(const std::set& theIndices); + + /// Returns true if attribute was initialized by some value + MODEL_EXPORT virtual bool isInitialized(); + protected: + /// Objects are created for features automatically + MODEL_EXPORT Model_AttributeRefAttrList(TDF_Label& theLabel); + + friend class Model_Data; +}; + +#endif diff --git a/src/Model/Model_Data.h b/src/Model/Model_Data.h index 136ffd557..ec219f552 100644 --- a/src/Model/Model_Data.h +++ b/src/Model/Model_Data.h @@ -70,6 +70,7 @@ class Model_Data : public ModelAPI_Data friend class Model_AttributeReference; friend class Model_AttributeRefAttr; friend class Model_AttributeRefList; + friend class Model_AttributeRefAttrList; friend class Model_AttributeSelection; friend class Model_AttributeSelectionList; diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index b3bdb63b7..25e467e71 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -265,6 +265,7 @@ class Model_Document : public ModelAPI_Document friend class Model_AttributeReference; friend class Model_AttributeRefAttr; friend class Model_AttributeRefList; + friend class Model_AttributeRefAttrList; friend class Model_AttributeSelection; friend class Model_ResultPart; friend class Model_ResultCompSolid; diff --git a/src/ModelAPI/CMakeLists.txt b/src/ModelAPI/CMakeLists.txt index 24f960f0a..696f724c2 100644 --- a/src/ModelAPI/CMakeLists.txt +++ b/src/ModelAPI/CMakeLists.txt @@ -15,6 +15,7 @@ SET(PROJECT_HEADERS ModelAPI_AttributeInteger.h ModelAPI_AttributeRefAttr.h ModelAPI_AttributeReference.h + ModelAPI_AttributeRefAttrList.h ModelAPI_AttributeRefList.h ModelAPI_AttributeSelection.h ModelAPI_AttributeSelectionList.h @@ -52,6 +53,7 @@ SET(PROJECT_SOURCES ModelAPI_AttributeInteger.cpp ModelAPI_AttributeRefAttr.cpp ModelAPI_AttributeReference.cpp + ModelAPI_AttributeRefAttrList.cpp ModelAPI_AttributeRefList.cpp ModelAPI_AttributeSelection.cpp ModelAPI_AttributeSelectionList.cpp diff --git a/src/ModelAPI/ModelAPI_AttributeRefAttrList.cpp b/src/ModelAPI/ModelAPI_AttributeRefAttrList.cpp new file mode 100755 index 000000000..5572fe559 --- /dev/null +++ b/src/ModelAPI/ModelAPI_AttributeRefAttrList.cpp @@ -0,0 +1,23 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: ModelAPI_AttributeRefAttrList.cpp +// Created: 20 Jan 2016 +// Author: Mikhail PONIKAROV + + +#include "ModelAPI_AttributeRefAttrList.h" + +std::string ModelAPI_AttributeRefAttrList::attributeType() +{ + return typeId(); +} + +ModelAPI_AttributeRefAttrList::~ModelAPI_AttributeRefAttrList() +{ + +} + +ModelAPI_AttributeRefAttrList::ModelAPI_AttributeRefAttrList() +{ +} + diff --git a/src/ModelAPI/ModelAPI_AttributeRefAttrList.h b/src/ModelAPI/ModelAPI_AttributeRefAttrList.h new file mode 100755 index 000000000..633bcb54d --- /dev/null +++ b/src/ModelAPI/ModelAPI_AttributeRefAttrList.h @@ -0,0 +1,83 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + +// File: ModelAPI_AttributeRefAttrList.h +// Created: 20 Jan 2016 +// Author: Mikhail PONIKAROV + +#ifndef ModelAPI_AttributeRefAttrList_H_ +#define ModelAPI_AttributeRefAttrList_H_ + +#include "ModelAPI_Attribute.h" +#include "ModelAPI_Feature.h" +#include + +/**\class ModelAPI_AttributeRefAttrList + * \ingroup DataModel + * \brief Attribute that contains list of references to features (located in the same document) + * or references to attributes of the features (list of AttributeRefAttr) + */ + +class ModelAPI_AttributeRefAttrList : public ModelAPI_Attribute +{ + public: + /// Returns the type of this class of attributes + MODELAPI_EXPORT static std::string typeId() + { + return "RefAttrList"; + } + + /// Returns the type of this class of attributes, not static method + MODELAPI_EXPORT virtual std::string attributeType(); + + /// Appends the feature to the end of a list + virtual void append(ObjectPtr theObject) = 0; + /// Appends the attribute to the end of a list + virtual void append(AttributePtr theAttr) = 0; + + /// Erases the first meet of the feature in the list + virtual void remove(ObjectPtr theObject) = 0; + /// Erases the first meet of the attribute in the list + virtual void remove(AttributePtr theAttr) = 0; + + /// Removes all references from the list + virtual void clear() = 0; + + /// Returns number of features in the list + ///\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 and attributes (if it is reference to the attribute) + virtual std::list > list() = 0; + + /// Returns true if the object is in list + virtual bool isInList(const ObjectPtr& theObj) = 0; + /// Returns true if the attribute is in list + virtual bool isInList(const AttributePtr& theObj) = 0; + + /// Returns true if this is reference to an attribute, not just object + virtual bool isAttribute(const int theIndex) const = 0; + + /// Returns the referenced object by the zero-based index + ///\param theIndex zero-based index in the list + virtual ObjectPtr object(const int theIndex) const = 0; + /// Returns the referenced attribute by the zero-based index + ///\param theIndex zero-based index in the list + virtual AttributePtr attribute(const int theIndex) const = 0; + + /// Removes the last element in the list. + virtual void removeLast() = 0; + + /// Removes the elements from the list. + /// \param theIndices a list of indices of elements to be removed + virtual void remove(const std::set& theIndices) = 0; + + MODELAPI_EXPORT virtual ~ModelAPI_AttributeRefAttrList(); + protected: + /// Objects are created for features automatically + MODELAPI_EXPORT ModelAPI_AttributeRefAttrList(); + +}; + +typedef std::shared_ptr AttributeRefAttrListPtr; + +#endif -- 2.39.2