0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / TopOpeBRepBuild / TopOpeBRepBuild_BlockBuilder.cxx
1 // Created on: 1993-03-11
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1993-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 <Standard_Failure.hxx>
19 #include <TopoDS_Shape.hxx>
20 #include <TopOpeBRepBuild_BlockBuilder.hxx>
21 #include <TopOpeBRepBuild_BlockIterator.hxx>
22 #include <TopOpeBRepBuild_ShapeSet.hxx>
23
24 //=======================================================================
25 //function : TopOpeBRepBuild_BlockBuilder
26 //purpose  : 
27 //=======================================================================
28 TopOpeBRepBuild_BlockBuilder::TopOpeBRepBuild_BlockBuilder()
29 :myIsDone(Standard_False)
30 {
31 }
32
33 //=======================================================================
34 //function : TopOpeBRepBuild_BlockBuilder
35 //purpose  : 
36 //=======================================================================
37
38 TopOpeBRepBuild_BlockBuilder::TopOpeBRepBuild_BlockBuilder 
39 (TopOpeBRepBuild_ShapeSet& SS)
40 :myIsDone(Standard_False)
41 {
42   MakeBlock(SS);
43 }
44
45 //=======================================================================
46 //function : MakeBlock
47 //purpose  : 
48 //=======================================================================
49
50 void TopOpeBRepBuild_BlockBuilder::MakeBlock(TopOpeBRepBuild_ShapeSet& SS)
51 {
52   // Compute the set of connexity blocks of elements of element set SS
53   //
54   // Logic : 
55   // - A block is a set of connex elements of SS
56   // - We assume that any element of SS appears in only 1 connexity block.
57   //
58   // Implementation :
59   // - All the elements of all the blocks are stored in map myOrientedShapeMap(M).
60   // - A connexity block is a segment [f,l] of element indices of M.
61   // - myBlocks is a sequence of integer; each integer is the index of the 
62   //   first element (in M) of a connexity block.
63   // - Bounds [f,l] of a connexity block are : 
64   //    f = myBlocks(i)
65   //    l = myBlocks(i+1) - 1
66
67   myOrientedShapeMap.Clear();
68   myOrientedShapeMapIsValid.Clear();
69   myBlocks.Clear();
70   myBlocksIsRegular.Clear();
71   
72   Standard_Boolean IsRegular;
73   Standard_Integer CurNei;
74   Standard_Integer Mextent;
75   Standard_Integer Eindex;
76
77   for (SS.InitStartElements();SS.MoreStartElements();SS.NextStartElement()) {
78
79     const TopoDS_Shape& E = SS.StartElement(); 
80     Mextent = myOrientedShapeMap.Extent();
81     Eindex = AddElement(E); 
82
83     // E = current element of the element set SS
84     // Mextent = index of last element stored in map M, before E is added. 
85     // Eindex  = index of E added to M : Eindex > Mextent => E is new in M
86
87     Standard_Boolean EnewinM = (Eindex > Mextent);
88     if (EnewinM) {
89
90       // make a new block starting at element Eindex
91       myBlocks.Append(Eindex);
92       IsRegular = Standard_True; CurNei = 0;
93       // put in current block all the elements connex to E :
94       // while an element E has been added to M
95       //    - compute neighbours of E : N(E)
96       //    - add each element N of N(E) to M
97
98       Mextent = myOrientedShapeMap.Extent();
99       Standard_Boolean searchneighbours = (Eindex <= Mextent);
100       while (searchneighbours) {
101
102         // E = element of M on which neighbours must be searched
103         // first step : Eindex = index of starting element of SS
104         // next steps : Eindex = index of neighbours of starting element of SS 
105         const TopoDS_Shape& E1 = myOrientedShapeMap(Eindex);
106         CurNei = SS.MaxNumberSubShape(E1);
107         Standard_Boolean condregu = Standard_True;
108         if (CurNei > 2) condregu = Standard_False;
109         IsRegular = IsRegular && condregu;
110         // compute neighbours of E : add them to M to increase M.Extent().
111         SS.InitNeighbours(E1);
112
113         for (; SS.MoreNeighbours(); SS.NextNeighbour()) {
114           const TopoDS_Shape& N = SS.Neighbour();
115           AddElement(N);
116         }
117         
118         Eindex++;
119         Mextent = myOrientedShapeMap.Extent();
120         searchneighbours = (Eindex <= Mextent);
121         
122       } // while (searchneighbours)
123       Standard_Integer iiregu = IsRegular ? 1 : 0;
124       myBlocksIsRegular.Append(iiregu);      
125     } // if (EnewinM)
126   } // for ()
127   
128   // To value the l bound of the last connexity block created above,
129   // we create an artificial block of value = myOrientedShapeMap.Extent() + 1
130   // The real number of connexity blocks is myBlocks.Length() - 1
131   Mextent = myOrientedShapeMap.Extent();
132   myBlocks.Append(Mextent + 1);
133   myIsDone = Standard_True;
134
135 #if 0
136 // version seche
137   myOrientedShapeMap.Clear();
138   myOrientedShapeMapIsValid.Clear();
139   myBlocks.Clear();
140   while (SS.MoreStartElements()) {
141     Standard_Integer last = myOrientedShapeMap.Extent();
142     Standard_Integer index =AddElement(SS.StartElement());
143     if (index > last) {
144       myBlocks.Append(index);
145       while (index <= myOrientedShapeMap.Extent()) {
146         for (SS.InitNeighbours(myOrientedShapeMap(index));
147              SS.MoreNeighbours();
148              SS.NextNeighbour()) {
149          AddElement(SS.Neighbour());
150         }
151         index++;
152       }
153     }
154     SS.NextStartElement();
155   }
156   myBlocks.Append(myOrientedShapeMap.Extent()+1);
157   myBlockIndex = 1;
158 #endif
159 }
160
161 //=======================================================================
162 //function : InitBlock
163 //purpose  : 
164 //=======================================================================
165
166 void TopOpeBRepBuild_BlockBuilder::InitBlock()
167 {
168   myBlockIndex = 1;
169 }
170
171 //=======================================================================
172 //function : MoreBlock
173 //purpose  : 
174 //=======================================================================
175
176 Standard_Boolean TopOpeBRepBuild_BlockBuilder::MoreBlock() const
177 {
178   // the length of myBlocks is 1 + number of connexity blocks
179   Standard_Integer l =  myBlocks.Length();
180   Standard_Boolean b = (myBlockIndex < l);
181   return b;
182 }
183
184 //=======================================================================
185 //function : NextBlock
186 //purpose  : 
187 //=======================================================================
188
189 void TopOpeBRepBuild_BlockBuilder::NextBlock()
190 {
191   myBlockIndex++;
192 }
193
194 //=======================================================================
195 //function : BlockIterator
196 //purpose  : 
197 //=======================================================================
198
199 TopOpeBRepBuild_BlockIterator TopOpeBRepBuild_BlockBuilder::BlockIterator() const
200 {
201   Standard_Integer lower = myBlocks(myBlockIndex);
202   Standard_Integer upper = myBlocks(myBlockIndex+1)-1;
203   return TopOpeBRepBuild_BlockIterator(lower,upper);
204 }
205
206 //=======================================================================
207 //function : Element
208 //purpose  : 
209 //=======================================================================
210
211 const TopoDS_Shape& TopOpeBRepBuild_BlockBuilder::Element 
212 (const TopOpeBRepBuild_BlockIterator& BI) const
213 {
214   Standard_Boolean isbound = BI.More();
215   if (!isbound) throw Standard_Failure("OutOfRange");
216
217   Standard_Integer index = BI.Value();
218   const TopoDS_Shape& E = myOrientedShapeMap(index);
219   return E;
220
221
222 const TopoDS_Shape& TopOpeBRepBuild_BlockBuilder::Element 
223 (const Standard_Integer index) const
224 {
225   Standard_Boolean isbound = myOrientedShapeMapIsValid.IsBound(index);
226   if (!isbound) throw Standard_Failure("OutOfRange");
227
228   const TopoDS_Shape& E = myOrientedShapeMap(index);
229   return E;
230
231
232 Standard_Integer TopOpeBRepBuild_BlockBuilder::Element 
233 (const TopoDS_Shape& E) const
234 {
235   Standard_Boolean isbound = myOrientedShapeMap.Contains(E);
236   if (!isbound) throw Standard_Failure("OutOfRange");
237
238   Standard_Integer I = myOrientedShapeMap.FindIndex(E);
239   return I;
240 }
241
242 //=======================================================================
243 //function : ElementIsValid
244 //purpose  : 
245 //=======================================================================
246
247 Standard_Boolean TopOpeBRepBuild_BlockBuilder::ElementIsValid
248 (const TopOpeBRepBuild_BlockIterator& BI) const 
249 {  
250   Standard_Boolean isbound = BI.More();
251   if (!isbound) return Standard_False;
252
253   Standard_Integer Sindex = BI.Value();
254   Standard_Integer isb = myOrientedShapeMapIsValid.Find(Sindex);
255   Standard_Boolean isvalid = (isb == 1)? Standard_True: Standard_False;
256   
257   return isvalid;
258 }
259
260 Standard_Boolean TopOpeBRepBuild_BlockBuilder::ElementIsValid
261 (const Standard_Integer Sindex) const
262 {  
263   Standard_Boolean isbound = myOrientedShapeMapIsValid.IsBound(Sindex);
264   if (!isbound) return Standard_False;
265
266   Standard_Integer isb = myOrientedShapeMapIsValid.Find(Sindex);
267   Standard_Boolean isvalid = (isb == 1)? Standard_True: Standard_False;
268   
269   return isvalid;
270 }
271
272 //=======================================================================
273 //function : AddElement
274 //purpose  : 
275 //=======================================================================
276
277 Standard_Integer TopOpeBRepBuild_BlockBuilder::AddElement(const TopoDS_Shape& S) 
278 {
279   Standard_Integer Sindex = myOrientedShapeMap.Add(S);
280   myOrientedShapeMapIsValid.Bind(Sindex, 1);
281
282   return Sindex;
283 }
284
285 //=======================================================================
286 //function : SetValid
287 //purpose  : 
288 //=======================================================================
289
290 void TopOpeBRepBuild_BlockBuilder::SetValid
291 (const TopOpeBRepBuild_BlockIterator& BI,
292  const Standard_Boolean isvalid)
293 {
294   Standard_Boolean isbound = BI.More();
295   if (!isbound) return;
296
297   Standard_Integer Sindex = BI.Value();
298   Standard_Integer i = (isvalid) ? 1 : 0;
299   myOrientedShapeMapIsValid.Bind(Sindex,i);
300 }
301
302 void TopOpeBRepBuild_BlockBuilder::SetValid
303 (const Standard_Integer Sindex,
304  const Standard_Boolean isvalid)
305 {
306   Standard_Boolean isbound = myOrientedShapeMapIsValid.IsBound(Sindex);
307   if (!isbound) return;
308
309   Standard_Integer i = (isvalid) ? 1 : 0;
310   myOrientedShapeMapIsValid.Bind(Sindex,i);
311 }
312
313 //=======================================================================
314 //function : CurrentBlockIsRegular
315 //purpose  : 
316 //=======================================================================
317
318 Standard_Boolean TopOpeBRepBuild_BlockBuilder::CurrentBlockIsRegular()
319 {
320   Standard_Boolean b = Standard_False;
321   Standard_Integer i = myBlocksIsRegular.Value(myBlockIndex);
322   if(i == 1)
323     b = Standard_True;
324   return b;
325 }