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>
15 void Model_AttributeRefAttrList::append(ObjectPtr theObject)
17 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theObject->data());
18 myRef->Append(aData->label().Father()); // store label of the object
19 myIDs->Append(""); // for the object store an empty string
20 // do it before the transaction finish to make just created/removed objects know dependencies
21 // and reference from composite feature is removed automatically
22 ADD_BACK_REF(theObject);
24 owner()->data()->sendAttributeUpdated(this);
27 void Model_AttributeRefAttrList::append(AttributePtr theAttr)
29 std::shared_ptr<Model_Data> aData =
30 std::dynamic_pointer_cast<Model_Data>(theAttr->owner()->data());
31 myRef->Append(aData->label().Father()); // store label of the object
32 myIDs->Append(theAttr->id().c_str()); // store the ID of the referenced attribute
33 // do it before the transaction finish to make just created/removed objects know dependencies
34 // and reference from composite feature is removed automatically
35 ADD_BACK_REF(theAttr->owner());
37 owner()->data()->sendAttributeUpdated(this);
40 void Model_AttributeRefAttrList::remove(ObjectPtr theObject)
43 if (theObject.get() != NULL) {
44 aTheObjLab = std::dynamic_pointer_cast<Model_Data>(theObject->data())->label().Father();
46 std::shared_ptr<Model_Document> aDoc =
47 std::dynamic_pointer_cast<Model_Document>(owner()->document());
48 // remove from the both lists by clearing the list and then appending one by one
49 // TODO: in OCCT 7.0 there are methods for removing by index, seems will be more optimal
50 TDF_LabelList aRefList = myRef->List();
52 TDataStd_ListOfExtendedString anIDList = myIDs->List();
54 bool aOneisDeleted = false;
55 TDF_ListIteratorOfLabelList aRefIter(aRefList);
56 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
57 for (; aRefIter.More(); aRefIter.Next(), anIDIter.Next()) {
58 // append now only not removed
59 if (aOneisDeleted || aRefIter.Value() != aTheObjLab || !anIDIter.Value().IsEmpty() ||
60 (aTheObjLab.IsNull() && aDoc->objects()->object(aRefIter.Value()) != NULL)) {
61 myRef->Append(aRefIter.Value());
62 myIDs->Append(anIDIter.Value());
63 } else if (aTheObjLab.IsNull() && aDoc->objects()->object(aRefIter.Value()) != NULL) {
68 REMOVE_BACK_REF(theObject);
69 owner()->data()->sendAttributeUpdated(this);
73 void Model_AttributeRefAttrList::remove(AttributePtr theAttr)
76 if (theAttr->owner().get() != NULL) {
77 aTheObjLab = std::dynamic_pointer_cast<Model_Data>(theAttr->owner()->data())->label().Father();
79 std::shared_ptr<Model_Document> aDoc =
80 std::dynamic_pointer_cast<Model_Document>(owner()->document());
81 // remove from the both lists by clearing the list and then appending one by one
82 // TODO: in OCCT 7.0 there are methods for removing by index, seems will be more optimal
83 TDF_LabelList aRefList = myRef->List();
85 TDataStd_ListOfExtendedString anIDList = myIDs->List();
87 bool aOneisDeleted = false;
88 TDF_ListIteratorOfLabelList aRefIter(aRefList);
89 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
90 for (; aRefIter.More(); aRefIter.Next(), anIDIter.Next()) {
91 if (aOneisDeleted || anIDIter.Value() != theAttr->id().c_str() ||
92 // append now only not removed
93 aRefIter.Value() != aTheObjLab || // append now only not removed
94 (aTheObjLab.IsNull() && aDoc->objects()->object(aRefIter.Value()) != NULL)) {
95 myRef->Append(aRefIter.Value());
96 myIDs->Append(anIDIter.Value());
102 REMOVE_BACK_REF(theAttr->owner());
103 owner()->data()->sendAttributeUpdated(this);
107 void Model_AttributeRefAttrList::clear()
109 std::list<std::pair<ObjectPtr, AttributePtr> > anOldList = list();
112 std::list<std::pair<ObjectPtr, AttributePtr> >::iterator anOldIter = anOldList.begin();
113 for(; anOldIter != anOldList.end(); anOldIter++) {
114 REMOVE_BACK_REF((anOldIter->first));
116 owner()->data()->sendAttributeUpdated(this);
119 int Model_AttributeRefAttrList::size() const
121 return myRef->Extent();
124 bool Model_AttributeRefAttrList::isInitialized()
126 if (size() == 0) { // empty list is not initialized list: sketch will be not valid after add/undo
129 return ModelAPI_AttributeRefAttrList::isInitialized();
132 std::list<std::pair<ObjectPtr, AttributePtr> > Model_AttributeRefAttrList::list()
134 std::list<std::pair<ObjectPtr, AttributePtr> > aResult;
135 std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
136 owner()->document());
138 const TDF_LabelList& aList = myRef->List();
139 const TDataStd_ListOfExtendedString& anIDList = myIDs->List();
140 TDF_ListIteratorOfLabelList aLIter(aList);
141 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
142 for (; aLIter.More(); aLIter.Next(), anIDIter.Next()) {
144 if (!aLIter.Value().IsNull()) {
145 anObj = aDoc->objects()->object(aLIter.Value());
146 aResult.push_back(std::pair<ObjectPtr, AttributePtr>(anObj,
147 anObj->data()->attribute(TCollection_AsciiString(anIDIter.Value()).ToCString())));
149 aResult.push_back(std::pair<ObjectPtr, AttributePtr>(ObjectPtr(), AttributePtr()));
156 bool Model_AttributeRefAttrList::isInList(const ObjectPtr& theObj)
161 std::list<ObjectPtr> aResult;
162 std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
163 owner()->document());
165 std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(theObj->data());
166 if (aData.get() && aData->isValid()) {
167 TDF_Label anObjLab = aData->label().Father();
168 const TDF_LabelList& aList = myRef->List();
169 const TDataStd_ListOfExtendedString& anIDList = myIDs->List();
170 TDF_ListIteratorOfLabelList aLIter(aList);
171 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
172 for (; aLIter.More(); aLIter.Next(), anIDIter.Next()) {
173 if (anIDIter.Value().IsEmpty() && aLIter.Value().IsEqual(anObjLab)) {
182 bool Model_AttributeRefAttrList::isInList(const AttributePtr& theAttr)
184 if (!theAttr->owner().get()) {
187 std::list<ObjectPtr> aResult;
188 std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
189 owner()->document());
191 std::shared_ptr<Model_Data> aData =
192 std::dynamic_pointer_cast<Model_Data>(theAttr->owner()->data());
193 if (aData.get() && aData->isValid()) {
194 TDF_Label anObjLab = aData->label().Father();
195 const TDF_LabelList& aList = myRef->List();
196 const TDataStd_ListOfExtendedString& anIDList = myIDs->List();
197 TDF_ListIteratorOfLabelList aLIter(aList);
198 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
199 for (; aLIter.More(); aLIter.Next(), anIDIter.Next()) {
200 if (anIDIter.Value() == theAttr->id().c_str() && aLIter.Value().IsEqual(anObjLab)) {
209 bool Model_AttributeRefAttrList::isAttribute(const int theIndex) const
211 const TDataStd_ListOfExtendedString& anIDList = myIDs->List();
212 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
214 for (; anIDIter.More(); anIDIter.Next()) {
216 if (anIndex == theIndex) {
217 return !anIDIter.Value().IsEmpty();
223 ObjectPtr Model_AttributeRefAttrList::object(const int theIndex) const
225 std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
226 owner()->document());
228 const TDF_LabelList& aList = myRef->List();
230 for (TDF_ListIteratorOfLabelList aLIter(aList); aLIter.More(); aLIter.Next()) {
232 if (anIndex == theIndex) {
233 if (aLIter.Value().IsNull()) { // null label => null sub
236 return aDoc->objects()->object(aLIter.Value());
243 AttributePtr Model_AttributeRefAttrList::attribute(const int theIndex) const
245 std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
246 owner()->document());
249 const TDF_LabelList& aList = myRef->List();
250 const TDataStd_ListOfExtendedString& anIDList = myIDs->List();
251 TDF_ListIteratorOfLabelList aLIter(aList);
252 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
253 for (; aLIter.More(); aLIter.Next(), anIDIter.Next()) {
255 if (anIndex == theIndex) {
256 if (aLIter.Value().IsNull()) { // null label => null sub
257 return AttributePtr();
259 return aDoc->objects()->object(aLIter.Value())->data()->
260 attribute(TCollection_AsciiString(anIDIter.Value().ToExtString()).ToCString());
264 return AttributePtr();
267 void Model_AttributeRefAttrList::removeLast()
269 // remove from the both lists by clearing the list and then appending one by one
270 // TODO: in OCCT 7.0 there are methods for removing by index, seems will be more optimal
271 std::set<int> aLastSet;
272 aLastSet.insert(size() - 1);
276 void Model_AttributeRefAttrList::remove(const std::set<int>& theIndices)
278 std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
279 owner()->document());
280 if (aDoc && !myRef->IsEmpty()) {
281 // remove from the both lists by clearing the list and then appending one by one
282 // TODO: in OCCT 7.0 there are methods for removing by index, seems will be more optimal
283 TDF_LabelList aRefList = myRef->List();
285 TDataStd_ListOfExtendedString anIDList = myIDs->List();
287 bool aOneisDeleted = false;
288 TDF_ListIteratorOfLabelList aRefIter(aRefList);
289 TDataStd_ListIteratorOfListOfExtendedString anIDIter(anIDList);
290 for (int anIndex = 0; aRefIter.More(); aRefIter.Next(), anIDIter.Next(), anIndex++) {
291 if (theIndices.find(anIndex) == theIndices.end()) { // not found
292 myRef->Append(aRefIter.Value());
293 myIDs->Append(anIDIter.Value());
294 } else { // found, so need to update the dependencies
295 aOneisDeleted = true;
296 ObjectPtr anObj = aDoc->objects()->object(aRefIter.Value());
298 REMOVE_BACK_REF(anObj);
303 owner()->data()->sendAttributeUpdated(this);
308 Model_AttributeRefAttrList::Model_AttributeRefAttrList(TDF_Label& theLabel)
314 void Model_AttributeRefAttrList::reinit()
316 myIsInitialized = myLab.FindAttribute(TDataStd_ReferenceList::GetID(), myRef) == Standard_True;
317 if (!myIsInitialized) {
318 myRef = TDataStd_ReferenceList::Set(myLab);
319 myIDs = TDataStd_ExtStringList::Set(myLab);
321 myLab.FindAttribute(TDataStd_ExtStringList::GetID(), myIDs);