0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / BRepAlgo / BRepAlgo_AsDes.cxx
1 // Created on: 1995-10-26
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <BRepAlgo_AsDes.hxx>
19 #include <Standard_ConstructionError.hxx>
20 #include <Standard_Type.hxx>
21 #include <TopoDS_Shape.hxx>
22 #include <TopTools_ListIteratorOfListOfShape.hxx>
23 #include <TopTools_MapOfOrientedShape.hxx>
24
25 IMPLEMENT_STANDARD_RTTIEXT(BRepAlgo_AsDes,Standard_Transient)
26
27 //=======================================================================
28 //function : BRepAlgo_AsDes
29 //purpose  : 
30 //=======================================================================
31 BRepAlgo_AsDes::BRepAlgo_AsDes()
32 {
33 }
34
35
36 //=======================================================================
37 //function : Add
38 //purpose  : 
39 //=======================================================================
40
41 void BRepAlgo_AsDes::Add(const TopoDS_Shape& S, const TopoDS_Shape& SS)
42 {
43   if (!down.IsBound(S)) {
44     TopTools_ListOfShape L;
45     down.Bind(S,L);
46   }
47   down(S).Append(SS);
48
49   if (!up.IsBound(SS)) {    
50     TopTools_ListOfShape L;
51     up.Bind(SS,L);
52   }
53   up(SS).Append(S);
54 }
55
56
57 //=======================================================================
58 //function : Add
59 //purpose  : 
60 //=======================================================================
61
62 void BRepAlgo_AsDes::Add(const TopoDS_Shape& S, const TopTools_ListOfShape& SS)
63 {
64   TopTools_ListIteratorOfListOfShape it(SS);
65   for ( ; it.More(); it.Next()) {
66     Add(S,it.Value());
67   }
68 }
69
70 //=======================================================================
71 //function : Clear
72 //purpose  : 
73 //=======================================================================
74
75 void BRepAlgo_AsDes::Clear() 
76 {
77   up  .Clear();
78   down.Clear();
79 }
80
81
82 //=======================================================================
83 //function : HasAscendant
84 //purpose  : 
85 //=======================================================================
86
87 Standard_Boolean BRepAlgo_AsDes::HasAscendant(const TopoDS_Shape& S) 
88 const 
89 {
90   return up.IsBound(S);
91
92
93 //=======================================================================
94 //function : HasDescendant
95 //purpose  : 
96 //=======================================================================
97
98 Standard_Boolean BRepAlgo_AsDes::HasDescendant(const TopoDS_Shape& S) 
99 const 
100 {
101   return down.IsBound(S);
102
103
104 //=======================================================================
105 //function : Ascendant
106 //purpose  : 
107 //=======================================================================
108
109 const TopTools_ListOfShape& BRepAlgo_AsDes::Ascendant(const TopoDS_Shape& S) const 
110 {
111   if (up.IsBound(S))
112     return up(S);
113   static TopTools_ListOfShape empty;
114   return empty; 
115 }
116
117
118 //=======================================================================
119 //function : Descendant
120 //purpose  : 
121 //=======================================================================
122
123 const TopTools_ListOfShape& BRepAlgo_AsDes::Descendant(const TopoDS_Shape& S) const 
124 {
125   if (down.IsBound(S)) 
126     return down(S);
127   static TopTools_ListOfShape empty;
128   return empty;
129 }
130
131 //=======================================================================
132 //function : ChangeDescendant
133 //purpose  : 
134 //=======================================================================
135
136 TopTools_ListOfShape& BRepAlgo_AsDes::ChangeDescendant(const TopoDS_Shape& S) 
137 {
138   if (down.IsBound(S)) 
139     return down.ChangeFind(S);
140   static TopTools_ListOfShape empty;
141   return empty;
142 }
143
144 //=======================================================================
145 //function : ReplaceInList
146 //purpose  : 
147 //=======================================================================
148
149 static void ReplaceInList(const TopoDS_Shape&   OldS,
150                           const TopoDS_Shape&   NewS,
151                           TopTools_ListOfShape& L)
152 {
153   TopTools_MapOfOrientedShape aMS;
154   TopTools_ListIteratorOfListOfShape it(L);
155   for (; it.More(); it.Next()) {
156     aMS.Add(it.Value());
157   }
158   it.Initialize(L);
159   while(it.More()) {
160     if (it.Value().IsSame(OldS)) {
161       TopAbs_Orientation O = it.Value().Orientation();
162       if (aMS.Add(NewS.Oriented(O))) {
163         L.InsertBefore(NewS.Oriented(O),it);
164       }
165       L.Remove(it);
166     }
167     else it.Next();
168   }
169 }
170 //=======================================================================
171 //function : RemoveInList
172 //purpose  : 
173 //=======================================================================
174
175 static void RemoveInList(const TopoDS_Shape&   S,
176                          TopTools_ListOfShape& L)
177 {
178   TopTools_ListIteratorOfListOfShape it(L);
179   while(it.More()) {
180     if (it.Value().IsSame(S)) {
181       L.Remove(it);
182       break;
183     }
184     it.Next();
185   }
186 }
187
188 //=======================================================================
189 //function : HasCommonDescendant
190 //purpose  : 
191 //=======================================================================
192
193 Standard_Boolean BRepAlgo_AsDes::HasCommonDescendant(const TopoDS_Shape& S1, 
194                                                        const TopoDS_Shape& S2, 
195                                                        TopTools_ListOfShape& LC)
196 const 
197 {
198   LC.Clear();
199   if (HasDescendant (S1) && HasDescendant (S2)) {
200     TopTools_ListIteratorOfListOfShape it1(Descendant(S1));
201     for (; it1.More(); it1.Next()) {
202       const TopoDS_Shape& DS1 = it1.Value();
203       TopTools_ListIteratorOfListOfShape it2(Ascendant(DS1));
204       for (; it2.More(); it2.Next()) {
205         const TopoDS_Shape& ADS1 = it2.Value();
206         if (ADS1.IsSame(S2)) {
207           LC.Append(DS1);
208         }
209       }
210     }
211   }
212   return (!LC.IsEmpty());
213
214
215 //=======================================================================
216 //function : BackReplace
217 //purpose  : 
218 //=======================================================================
219
220 void BRepAlgo_AsDes::BackReplace(const TopoDS_Shape&         OldS,
221                                    const TopoDS_Shape&         NewS,
222                                    const TopTools_ListOfShape& L,
223                                    const Standard_Boolean      InUp)
224 {
225   TopTools_ListIteratorOfListOfShape it(L);
226   for ( ; it.More(); it.Next()) {
227     const TopoDS_Shape& S = it.Value();
228     if (InUp) {
229       if (up.IsBound(S)) {
230         ReplaceInList(OldS,NewS,up.ChangeFind(S));
231       }
232     }
233     else {      
234       if (down.IsBound(S)) {
235         ReplaceInList(OldS,NewS,down.ChangeFind(S));
236       }
237     }
238   }
239 }
240
241 //=======================================================================
242 //function : Replace
243 //purpose  : 
244 //=======================================================================
245 void BRepAlgo_AsDes::Replace(const TopoDS_Shape& OldS,
246                              const TopoDS_Shape& NewS)
247 {
248   for (Standard_Integer i = 0; i < 2; ++i) {
249     TopTools_DataMapOfShapeListOfShape& aMap = !i ? up : down;
250     TopTools_ListOfShape* pLSOld = aMap.ChangeSeek(OldS);
251     if (!pLSOld) {
252       continue;
253     }
254     //
255     Standard_Boolean InUp = !i ? Standard_False : Standard_True;
256     BackReplace(OldS, NewS, *pLSOld, InUp);
257     //
258     TopTools_ListOfShape* pLSNew = aMap.ChangeSeek(NewS);
259     if (!pLSNew) {
260       // filter the list
261       TopTools_MapOfOrientedShape aMS;
262       TopTools_ListIteratorOfListOfShape aIt(*pLSOld);
263       for (; aIt.More(); ) {
264         if (!aMS.Add(aIt.Value())) {
265           pLSOld->Remove(aIt);
266         }
267         else {
268           aIt.Next();
269         }
270       }
271       aMap.Bind(NewS, *pLSOld);
272     }
273     else {
274       // avoid duplicates
275       TopTools_MapOfOrientedShape aMS;
276       TopTools_ListIteratorOfListOfShape aIt(*pLSNew);
277       for (; aIt.More(); aIt.Next()) {
278         aMS.Add(aIt.Value());
279       }
280       //
281       aIt.Initialize(*pLSOld);
282       for (; aIt.More(); aIt.Next()) {
283         const TopoDS_Shape& aS = aIt.Value();
284         if (aMS.Add(aS)) {
285           pLSNew->Append(aS);
286         }
287       }
288     }
289     //
290     aMap.UnBind(OldS);
291   }
292 }
293
294 //=======================================================================
295 //function : Remove
296 //purpose  : 
297 //=======================================================================
298
299 void BRepAlgo_AsDes::Remove(const TopoDS_Shape& SS)
300 {
301   if (down.IsBound(SS)) {
302     throw Standard_ConstructionError(" BRepAlgo_AsDes::Remove");
303   }
304   if (!up.IsBound(SS)) {
305     throw Standard_ConstructionError(" BRepAlgo_AsDes::Remove");
306   }
307   TopTools_ListIteratorOfListOfShape it(up(SS));
308   for (; it.More(); it.Next()) {
309     RemoveInList(SS,down.ChangeFind((it.Value())));
310   }
311   up.UnBind(SS);
312 }