1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: ModelAPI_AttributeRefAttrList.cxx
5 // Author: Mikhail PONIKAROV
7 #include "Model_AttributeRefAttrList.h"
8 #include "Model_Application.h"
9 #include "Model_Data.h"
10 #include "Model_Objects.h"
11 #include <ModelAPI_Feature.h>
12 #include <TDF_ListIteratorOfLabelList.hxx>
13 #include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
17 void Model_AttributeRefAttrList::append(ObjectPtr theObject)
19 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theObject->data());
20 myRef->Append(aData->label().Father()); // store label of the object
21 myIDs->Append(""); // for the object store an empty string
22 // do it before the transaction finish to make just created/removed objects know dependencies
23 // and reference from composite feature is removed automatically
24 ADD_BACK_REF(theObject);
26 owner()->data()->sendAttributeUpdated(this);
29 void Model_AttributeRefAttrList::append(AttributePtr theAttr)
31 std::shared_ptr<Model_Data> aData =
32 std::dynamic_pointer_cast<Model_Data>(theAttr->owner()->data());
33 myRef->Append(aData->label().Father()); // store label of the object
34 myIDs->Append(theAttr->id().c_str()); // store the ID of the referenced attribute
35 // do it before the transaction finish to make just created/removed objects know dependencies
36 // and reference from composite feature is removed automatically
37 ADD_BACK_REF(theAttr->owner());
39 owner()->data()->sendAttributeUpdated(this);
42 void Model_AttributeRefAttrList::remove(ObjectPtr theObject)
45 if (theObject.get() != NULL) {
46 aTheObjLab = std::dynamic_pointer_cast<Model_Data>(theObject->data())->label().Father();
48 std::shared_ptr<Model_Document> aDoc =
49 std::dynamic_pointer_cast<Model_Document>(owner()->document());
50 // remove from the both lists by clearing the list and then appending one by one
51 // TODO: in OCCT 7.0 there are methods for removing by index, seems will be more optimal
52 TDF_LabelList aRefList = myRef->List();
54 TDataStd_ListOfExtendedString anIDList = myIDs->List();
56 bool aOneisDeleted = false;
57 TDF_ListIteratorOfLabelList aRefIter(aRefList);
58 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
59 for (; aRefIter.More(); aRefIter.Next(), anIDIter.Next()) {
60 // append now only not removed
61 if (aOneisDeleted || aRefIter.Value() != aTheObjLab || !anIDIter.Value().IsEmpty() ||
62 (aTheObjLab.IsNull() && aDoc->objects()->object(aRefIter.Value()) != NULL)) {
63 myRef->Append(aRefIter.Value());
64 myIDs->Append(anIDIter.Value());
65 } else if (aTheObjLab.IsNull() && aDoc->objects()->object(aRefIter.Value()) != NULL) {
70 REMOVE_BACK_REF(theObject);
71 owner()->data()->sendAttributeUpdated(this);
75 void Model_AttributeRefAttrList::remove(AttributePtr theAttr)
78 if (theAttr->owner().get() != NULL) {
79 aTheObjLab = std::dynamic_pointer_cast<Model_Data>(theAttr->owner()->data())->label().Father();
81 std::shared_ptr<Model_Document> aDoc =
82 std::dynamic_pointer_cast<Model_Document>(owner()->document());
83 // remove from the both lists by clearing the list and then appending one by one
84 // TODO: in OCCT 7.0 there are methods for removing by index, seems will be more optimal
85 TDF_LabelList aRefList = myRef->List();
87 TDataStd_ListOfExtendedString anIDList = myIDs->List();
89 bool aOneisDeleted = false;
90 TDF_ListIteratorOfLabelList aRefIter(aRefList);
91 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
92 for (; aRefIter.More(); aRefIter.Next(), anIDIter.Next()) {
93 if (aOneisDeleted || anIDIter.Value() != theAttr->id().c_str() ||
94 // append now only not removed
95 aRefIter.Value() != aTheObjLab || // append now only not removed
96 (aTheObjLab.IsNull() && aDoc->objects()->object(aRefIter.Value()) != NULL)) {
97 myRef->Append(aRefIter.Value());
98 myIDs->Append(anIDIter.Value());
100 aOneisDeleted = true;
104 REMOVE_BACK_REF(theAttr->owner());
105 owner()->data()->sendAttributeUpdated(this);
109 void Model_AttributeRefAttrList::clear()
111 std::list<std::pair<ObjectPtr, AttributePtr> > anOldList = list();
114 std::list<std::pair<ObjectPtr, AttributePtr> >::iterator anOldIter = anOldList.begin();
115 for(; anOldIter != anOldList.end(); anOldIter++) {
116 REMOVE_BACK_REF((anOldIter->first));
118 owner()->data()->sendAttributeUpdated(this);
121 int Model_AttributeRefAttrList::size() const
123 return myRef->Extent();
126 bool Model_AttributeRefAttrList::isInitialized()
128 if (size() == 0) { // empty list is not initialized list: sketch will be not valid after add/undo
131 return ModelAPI_AttributeRefAttrList::isInitialized();
134 std::list<std::pair<ObjectPtr, AttributePtr> > Model_AttributeRefAttrList::list()
136 std::list<std::pair<ObjectPtr, AttributePtr> > aResult;
137 std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
138 owner()->document());
140 const TDF_LabelList& aList = myRef->List();
141 const TDataStd_ListOfExtendedString& anIDList = myIDs->List();
142 TDF_ListIteratorOfLabelList aLIter(aList);
143 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
144 for (; aLIter.More(); aLIter.Next(), anIDIter.Next()) {
146 if (!aLIter.Value().IsNull()) {
147 anObj = aDoc->objects()->object(aLIter.Value());
148 aResult.push_back(std::pair<ObjectPtr, AttributePtr>(anObj,
149 anObj->data()->attribute(TCollection_AsciiString(anIDIter.Value()).ToCString())));
151 aResult.push_back(std::pair<ObjectPtr, AttributePtr>(ObjectPtr(), AttributePtr()));
158 bool Model_AttributeRefAttrList::isInList(const ObjectPtr& theObj)
163 std::list<ObjectPtr> aResult;
164 std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
165 owner()->document());
167 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theObj->data());
168 if (aData.get() && aData->isValid()) {
169 TDF_Label anObjLab = aData->label().Father();
170 const TDF_LabelList& aList = myRef->List();
171 const TDataStd_ListOfExtendedString& anIDList = myIDs->List();
172 TDF_ListIteratorOfLabelList aLIter(aList);
173 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
174 for (; aLIter.More(); aLIter.Next(), anIDIter.Next()) {
175 if (anIDIter.Value().IsEmpty() && aLIter.Value().IsEqual(anObjLab)) {
184 bool Model_AttributeRefAttrList::isInList(const AttributePtr& theAttr)
186 if (!theAttr->owner().get()) {
189 std::list<ObjectPtr> aResult;
190 std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
191 owner()->document());
193 std::shared_ptr<Model_Data> aData =
194 std::dynamic_pointer_cast<Model_Data>(theAttr->owner()->data());
195 if (aData.get() && aData->isValid()) {
196 TDF_Label anObjLab = aData->label().Father();
197 const TDF_LabelList& aList = myRef->List();
198 const TDataStd_ListOfExtendedString& anIDList = myIDs->List();
199 TDF_ListIteratorOfLabelList aLIter(aList);
200 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
201 for (; aLIter.More(); aLIter.Next(), anIDIter.Next()) {
202 if (anIDIter.Value() == theAttr->id().c_str() && aLIter.Value().IsEqual(anObjLab)) {
211 bool Model_AttributeRefAttrList::isAttribute(const int theIndex) const
213 const TDataStd_ListOfExtendedString& anIDList = myIDs->List();
214 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
216 for (; anIDIter.More(); anIDIter.Next()) {
218 if (anIndex == theIndex) {
219 return !anIDIter.Value().IsEmpty();
225 ObjectPtr Model_AttributeRefAttrList::object(const int theIndex) const
227 std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
228 owner()->document());
230 const TDF_LabelList& aList = myRef->List();
232 for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) {
234 if (anIndex == theIndex) {
235 if (aLIter.Value().IsNull()) { // null label => null sub
238 return aDoc->objects()->object(aLIter.Value());
245 AttributePtr Model_AttributeRefAttrList::attribute(const int theIndex) const
247 std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
248 owner()->document());
251 const TDF_LabelList& aList = myRef->List();
252 const TDataStd_ListOfExtendedString& anIDList = myIDs->List();
253 TDF_ListIteratorOfLabelList aLIter(aList);
254 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
255 for (; aLIter.More(); aLIter.Next(), anIDIter.Next()) {
257 if (anIndex == theIndex) {
258 if (aLIter.Value().IsNull()) { // null label => null sub
259 return AttributePtr();
261 return aDoc->objects()->object(aLIter.Value())->data()->
262 attribute(TCollection_AsciiString(anIDIter.Value().ToExtString()).ToCString());
266 return AttributePtr();
269 void Model_AttributeRefAttrList::removeLast()
271 // remove from the both lists by clearing the list and then appending one by one
272 // TODO: in OCCT 7.0 there are methods for removing by index, seems will be more optimal
273 std::set<int> aLastSet;
274 aLastSet.insert(size() - 1);
278 void Model_AttributeRefAttrList::remove(const std::set<int>& theIndices)
280 std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
281 owner()->document());
282 if (aDoc && !myRef->IsEmpty()) {
283 // remove from the both lists by clearing the list and then appending one by one
284 // TODO: in OCCT 7.0 there are methods for removing by index, seems will be more optimal
285 TDF_LabelList aRefList = myRef->List();
287 TDataStd_ListOfExtendedString anIDList = myIDs->List();
289 bool aOneisDeleted = false;
290 TDF_ListIteratorOfLabelList aRefIter(aRefList);
291 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
292 for (int anIndex = 0; aRefIter.More(); aRefIter.Next(), anIDIter.Next(), anIndex++) {
293 if (theIndices.find(anIndex) == theIndices.end()) { // not found
294 myRef->Append(aRefIter.Value());
295 myIDs->Append(anIDIter.Value());
296 } else { // found, so need to update the dependencies
297 aOneisDeleted = true;
298 ObjectPtr anObj = aDoc->objects()->object(aRefIter.Value());
300 REMOVE_BACK_REF(anObj);
305 owner()->data()->sendAttributeUpdated(this);
310 Model_AttributeRefAttrList::Model_AttributeRefAttrList(TDF_Label& theLabel)
316 void Model_AttributeRefAttrList::reinit()
318 myIsInitialized = myLab.FindAttribute(TDataStd_ReferenceList::GetID(), myRef) == Standard_True;
319 if (!myIsInitialized) {
320 myRef = TDataStd_ReferenceList::Set(myLab);
321 myIDs = TDataStd_ExtStringList::Set(myLab);
323 myLab.FindAttribute(TDataStd_ExtStringList::GetID(), myIDs);