0025112: Undo of modification of the attribute TDataStd_IntPackedMap works wrong
[occt.git] / src / TDataStd / TDataStd_DeltaOnModificationOfIntPackedMap.cxx
1 // Created on: 2008-01-23
2 // Created by: Sergey ZARITCHNY
3 // Copyright (c) 2008-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <TDataStd_DeltaOnModificationOfIntPackedMap.ixx>
17 #include <TDF_DeltaOnModification.hxx>
18 #include <TDF_Label.hxx>
19 #include <TColStd_PackedMapOfInteger.hxx>
20 #include <TColStd_HPackedMapOfInteger.hxx>
21 #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
22
23 #ifdef DEB
24 #define MAXUP 1000
25 #endif
26
27 //=======================================================================
28 //function : TDataStd_DeltaOnModificationOfIntPackedMap
29 //purpose  : 
30 //=======================================================================
31
32 TDataStd_DeltaOnModificationOfIntPackedMap::TDataStd_DeltaOnModificationOfIntPackedMap(
33                              const Handle(TDataStd_IntPackedMap)& OldAtt)
34 : TDF_DeltaOnModification(OldAtt)
35 {
36   Handle(TDataStd_IntPackedMap) CurrAtt;
37   if (Label().FindAttribute(OldAtt->ID(), CurrAtt))
38   {
39     Handle(TColStd_HPackedMapOfInteger) aMap1, aMap2;
40     aMap1 = OldAtt->GetHMap();
41     aMap2 = CurrAtt->GetHMap();
42 #ifdef DEB_disable
43     if (aMap1.IsNull())
44       cout <<"DeltaOnModificationOfIntPackedMap:: Old Map is Null" <<endl;
45     if (aMap2.IsNull())
46       cout <<"DeltaOnModificationOfIntPackedMap:: Current Map is Null" <<endl;
47 #endif
48       
49     if (aMap1.IsNull() || aMap2.IsNull()) return;
50     if (aMap1 != aMap2) {
51       const TColStd_PackedMapOfInteger& map1 = aMap1->Map();
52       const TColStd_PackedMapOfInteger& map2 = aMap2->Map();
53       if (map1.IsSubset(map2)) {
54         myDeletion = new TColStd_HPackedMapOfInteger();
55         myDeletion->ChangeMap().Subtraction(map2, map1);
56       } else if (map2.IsSubset(map1)) { 
57         myAddition = new TColStd_HPackedMapOfInteger();
58         myAddition->ChangeMap().Subtraction(map1, map2);
59       } else if (map1.HasIntersection(map2)) {
60         myAddition = new TColStd_HPackedMapOfInteger();
61         myAddition->ChangeMap().Subtraction(map1, map2);
62         myDeletion = new TColStd_HPackedMapOfInteger();
63         myDeletion->ChangeMap().Subtraction(map2, map1);
64       } else {
65         myAddition = new TColStd_HPackedMapOfInteger(map1);
66         myDeletion = new TColStd_HPackedMapOfInteger(map2);
67       }
68     }
69   }
70 }
71
72
73 //=======================================================================
74 //function : Apply
75 //purpose  : 
76 //=======================================================================
77
78 void TDataStd_DeltaOnModificationOfIntPackedMap::Apply()
79 {
80
81   Handle(TDF_Attribute) aTDFAttribute = Attribute();
82   Handle(TDataStd_IntPackedMap) aBackAtt = (*((Handle(TDataStd_IntPackedMap)*)&aTDFAttribute));
83   if(aBackAtt.IsNull()) {
84 #ifdef DEB
85     cout << "DeltaOnModificationOfIntPAckedMap::Apply: OldAtt is Null" <<endl;
86 #endif
87     return;
88   }
89   
90   Handle(TDataStd_IntPackedMap) aCurAtt;
91   if (!Label().FindAttribute(aBackAtt->ID(),aCurAtt)) {
92
93     Label().AddAttribute(aBackAtt);
94   }
95
96   if(aCurAtt.IsNull()) {
97 #ifdef DEB
98     cout << "DeltaOnModificationOfIntAPckedMAp::Apply: CurAtt is Null" <<endl;
99 #endif
100     return;
101   }
102   else 
103     aCurAtt->Backup();
104
105   
106   
107   Handle(TColStd_HPackedMapOfInteger) IntMap = aCurAtt->GetHMap();
108   if (IntMap.IsNull()) return;
109
110   if (myDeletion.IsNull() && myAddition.IsNull())
111     return;
112
113   if (!myDeletion.IsNull()) {
114     if (myDeletion->Map().Extent())
115       IntMap->ChangeMap().Subtract(myDeletion->Map());
116   }
117   if (!myAddition.IsNull()) {
118     if (myAddition->Map().Extent())
119       IntMap->ChangeMap().Unite(myAddition->Map());
120   }
121   
122 #ifdef DEB_disable
123   cout << " << Map Dump after Delta Apply >>" <<endl;
124   Handle(TColStd_HPackedMapOfInteger) aIntMap = aCurAtt->GetHMap();
125   TColStd_MapIteratorOfPackedMapOfInteger it(aIntMap->Map());
126   for (Standard_Integer i=1;it.More() && i <= MAXUP; it.Next(), i++) 
127     cout << it.Key() << "  ";
128   cout <<endl;
129 #endif
130 }