0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / BRepAlgo / BRepAlgo_Image.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_Image.hxx>
19 #include <Standard_ConstructionError.hxx>
20 #include <TopExp_Explorer.hxx>
21 #include <TopoDS_Shape.hxx>
22 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
23 #include <TopTools_ListIteratorOfListOfShape.hxx>
24 #include <TopTools_MapOfShape.hxx>
25
26 //=======================================================================
27 //function : BRepAlgo_Image
28 //purpose  : 
29 //=======================================================================
30 BRepAlgo_Image::BRepAlgo_Image()
31 {
32 }
33
34
35 //=======================================================================
36 //function : SetRoot
37 //purpose  : 
38 //=======================================================================
39
40 void BRepAlgo_Image::SetRoot(const TopoDS_Shape& S)
41 {
42   roots.Append(S);
43 }
44
45 //=======================================================================
46 //function : Bind
47 //purpose  : 
48 //=======================================================================
49
50 void BRepAlgo_Image::Bind(const TopoDS_Shape& OldS, 
51                             const TopoDS_Shape& NewS)
52 {
53   if (down.IsBound(OldS)) {
54     throw Standard_ConstructionError(" BRepAlgo_Image::Bind");
55     return;
56   }
57   TopTools_ListOfShape L;
58   down.Bind(OldS,L);
59   down(OldS).Append(NewS);
60   up.Bind(NewS,OldS);
61 }
62
63
64 //=======================================================================
65 //function : Bind
66 //purpose  : 
67 //=======================================================================
68
69 void BRepAlgo_Image::Bind(const TopoDS_Shape& OldS, 
70                             const TopTools_ListOfShape& L)
71 {  
72   if (HasImage(OldS)) {
73     throw Standard_ConstructionError(" BRepAlgo_Image::Bind");
74     return; 
75   }
76   TopTools_ListIteratorOfListOfShape it(L);
77   for (; it.More(); it.Next()) {
78     if (!HasImage(OldS))
79       Bind(OldS, it.Value());
80     else 
81       Add (OldS, it.Value());
82   }
83 }
84
85 //=======================================================================
86 //function : Clear
87 //purpose  : 
88 //=======================================================================
89
90 void BRepAlgo_Image::Clear()
91 {
92   roots.Clear();
93   up   .Clear();
94   down .Clear();
95 }
96
97 //=======================================================================
98 //function : Add
99 //purpose  : 
100 //=======================================================================
101
102 void BRepAlgo_Image::Add(const TopoDS_Shape& OldS, const TopoDS_Shape& NewS)
103 {
104   if (!HasImage(OldS)) {    
105     throw Standard_ConstructionError(" BRepAlgo_Image::Add");
106   }
107   down(OldS).Append(NewS);
108   up.Bind(NewS,OldS);
109 }
110
111 //=======================================================================
112 //function : Add
113 //purpose  : 
114 //=======================================================================
115
116 void BRepAlgo_Image::Add(const TopoDS_Shape&         OldS, 
117                            const TopTools_ListOfShape& L)
118 {
119   TopTools_ListIteratorOfListOfShape it(L);
120   for (; it.More(); it.Next()) { 
121     Add(OldS,it.Value());
122   }
123 }
124
125
126 //=======================================================================
127 //function : Remove
128 //purpose  : 
129 //=======================================================================
130
131 void BRepAlgo_Image::Remove(const TopoDS_Shape& S)
132 {
133   if (!up.IsBound(S)) {
134     throw Standard_ConstructionError(" BRepAlgo_Image::Remove");
135   }
136   const TopoDS_Shape& OldS = up(S);
137   TopTools_ListOfShape& L = down(OldS);
138   TopTools_ListIteratorOfListOfShape it(L);
139   while (it.More()) {
140     if (it.Value().IsSame(S)) {
141       L.Remove(it);
142       break;
143     }
144     it.Next();
145   }
146   if (L.IsEmpty()) down.UnBind(OldS);
147   up.UnBind(S);
148 }
149
150
151 //=======================================================================
152 //function : TopTools_ListOfShape&
153 //purpose  : 
154 //=======================================================================
155
156 const TopTools_ListOfShape& BRepAlgo_Image::Roots() const 
157 {
158   return roots;
159 }
160
161 //=======================================================================
162 //function : IsImage
163 //purpose  : 
164 //=======================================================================
165
166 Standard_Boolean  BRepAlgo_Image::IsImage(const TopoDS_Shape& S) const 
167 {
168   return up.IsBound(S);
169 }
170
171 //=======================================================================
172 //function : ImageFrom
173 //purpose  : 
174 //=======================================================================
175
176 const TopoDS_Shape&  BRepAlgo_Image::ImageFrom(const TopoDS_Shape& S) const 
177 {
178   if (!up.IsBound(S)) {
179     throw Standard_ConstructionError(" BRepAlgo_Image::ImageFrom");
180   }  
181   return up(S);
182 }
183
184 //=======================================================================
185 //function : FirstImageFrom
186 //purpose  : 
187 //=======================================================================
188
189 const TopoDS_Shape&  BRepAlgo_Image::Root(const TopoDS_Shape& S) 
190 const 
191 {
192   if (!up.IsBound(S)) {
193     throw Standard_ConstructionError(" BRepAlgo_Image::FirstImageFrom");
194   }
195
196   TopoDS_Shape S1 = up(S);
197   TopoDS_Shape S2 = S;
198
199   if ( S1.IsSame(S2)) 
200     return up(S);
201
202   while ( up.IsBound(S1)) {
203     S2 = S1;
204     S1 = up(S1);
205     if ( S1.IsSame(S2)) break;
206   }
207   return up(S2);
208 }
209
210 //=======================================================================
211 //function : HasImage
212 //purpose  : 
213 //=======================================================================
214
215 Standard_Boolean  BRepAlgo_Image::HasImage(const TopoDS_Shape& S) const 
216 {
217   return down.IsBound(S);
218 }
219
220 //=======================================================================
221 //function : TopTools_ListOfShape&
222 //purpose  : 
223 //=======================================================================
224
225 const TopTools_ListOfShape& BRepAlgo_Image::Image(const TopoDS_Shape& S) const 
226 {
227   if (!HasImage(S)) { 
228     static TopTools_ListOfShape L;
229     L.Append(S);
230     return L;
231   }
232   return down(S);
233 }
234
235
236 //=======================================================================
237 //function : TopTools_ListOfShape&
238 //purpose  : 
239 //=======================================================================
240 void BRepAlgo_Image::LastImage(const TopoDS_Shape&  S,
241                                   TopTools_ListOfShape& L) const 
242 {
243   if (!down.IsBound(S)) {
244     L.Append(S);
245   }
246   else {
247     TopTools_ListIteratorOfListOfShape it(down(S));
248     for (; it.More(); it.Next()) {
249       if (it.Value().IsSame(S)) {
250         L.Append(S);
251       }
252       else {
253         LastImage(it.Value(),L);
254       }
255     }
256   }
257 }
258
259
260 //=======================================================================
261 //function : Compact
262 //purpose  : 
263 //=======================================================================
264
265 void BRepAlgo_Image::Compact()
266 {
267   TopTools_DataMapOfShapeListOfShape M;
268   TopTools_ListIteratorOfListOfShape it(roots);
269   for (; it.More(); it.Next()) {
270     const TopoDS_Shape&   S = it.Value();
271     TopTools_ListOfShape  LI;
272     if (HasImage(S)) LastImage(S,LI);
273     M.Bind   (S,LI);
274   }
275   up.Clear();
276   down.Clear();
277   for (it.Initialize(roots); it.More(); it.Next()) {
278     if (M.IsBound(it.Value())) {
279       Bind(it.Value(), M(it.Value()));
280     }
281   }
282 }
283
284 //=======================================================================
285 //function : Filter
286 //purpose  : 
287 //=======================================================================
288
289 void BRepAlgo_Image::Filter(const TopoDS_Shape&     S,
290                               const TopAbs_ShapeEnum  T)
291
292 {
293   TopExp_Explorer      exp(S,T) ;
294   TopTools_MapOfShape  M;
295   for (; exp.More(); exp.Next()) {M.Add(exp.Current());}
296   Standard_Boolean Change = Standard_True;
297   while (Change) {
298     Change = Standard_False;
299     TopTools_DataMapIteratorOfDataMapOfShapeShape mit(up);
300     for (; mit.More(); mit.Next()) {
301       const TopoDS_Shape& aS = mit.Key();
302       if (aS.ShapeType() == T && !M.Contains(aS)) {
303         Remove(aS);
304         Change = Standard_True;
305         break;
306       }
307     }
308   }
309   
310 }
311