bdb77438831430c1260c5b894d8788322a0c82d0
[occt.git] / src / BOP / BOP_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-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22 #include <BOP_BlockBuilder.ixx>
23
24 #include <Standard_Failure.hxx>
25
26 //=======================================================================
27 //function : BOP_BlockBuilder::BOP_BlockBuilder
28 //purpose  : 
29 //=======================================================================
30 BOP_BlockBuilder::BOP_BlockBuilder()
31 :
32   myIsDone(Standard_False)
33 {
34 }
35
36 //=======================================================================
37 //function : BOP_BlockBuilder::BOP_BlockBuilder
38 //purpose  : 
39 //=======================================================================
40   BOP_BlockBuilder::BOP_BlockBuilder (BOP_ShapeSet& SS)
41   :myIsDone(Standard_False)
42 {
43   MakeBlock(SS);
44 }
45
46 //=======================================================================
47 //function : MakeBlock
48 //purpose  : 
49 //=======================================================================
50   void BOP_BlockBuilder::MakeBlock(BOP_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, CurNei, Mextent, Eindex,
73                    EnewinM, searchneighbours, condregu;
74   Standard_Integer iiregu;
75   //
76   //
77   SS.InitStartElements();
78   for (; SS.MoreStartElements(); SS.NextStartElement()) {
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     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       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& anE = myOrientedShapeMap(Eindex);
106         CurNei = SS.MaxNumberSubShape(anE);
107         
108         condregu = (CurNei > 2) ? Standard_False : Standard_True;
109         
110         IsRegular = IsRegular && condregu;
111         //
112         // compute neighbours of E : add them to M to increase M.Extent().
113         SS.InitNeighbours(anE);
114
115         for (; SS.MoreNeighbours(); SS.NextNeighbour()) {
116           const TopoDS_Shape& N = SS.Neighbour();
117           AddElement(N);
118         }
119         
120         Eindex++;
121         Mextent = myOrientedShapeMap.Extent();
122         searchneighbours = (Eindex <= Mextent);
123         
124       } // while (searchneighbours)
125
126       iiregu = IsRegular ? 1 : 0;
127       myBlocksIsRegular.Append(iiregu);      
128     } // if (EnewinM)
129   } // for ()
130   //
131   // To value the l bound of the last connexity block created above,
132   // we create an artificial block of value = myOrientedShapeMap.Extent() + 1
133   // The real number of connexity blocks is myBlocks.Length() - 1
134   Mextent = myOrientedShapeMap.Extent();
135   myBlocks.Append(Mextent + 1);
136
137   myIsDone = Standard_True;
138 }
139
140 //=======================================================================
141 //function : InitBlock
142 //purpose  : 
143 //=======================================================================
144   void BOP_BlockBuilder::InitBlock()
145 {
146   myBlockIndex = 1;
147 }
148
149 //=======================================================================
150 //function : MoreBlock
151 //purpose  : 
152 //=======================================================================
153   Standard_Boolean BOP_BlockBuilder::MoreBlock() const
154 {
155   // the length of myBlocks is 1 + number of connexity blocks
156   Standard_Integer l =  myBlocks.Length();
157   Standard_Boolean b = (myBlockIndex < l);
158   return b;
159 }
160
161 //=======================================================================
162 //function : NextBlock
163 //purpose  : 
164 //=======================================================================
165   void BOP_BlockBuilder::NextBlock()
166 {
167   myBlockIndex++;
168 }
169
170 //=======================================================================
171 //function : BlockIterator
172 //purpose  : 
173 //=======================================================================
174   BOP_BlockIterator BOP_BlockBuilder::BlockIterator() const
175 {
176   Standard_Integer lower, upper;
177
178   lower = myBlocks(myBlockIndex);
179   upper = myBlocks(myBlockIndex+1)-1;
180
181   return BOP_BlockIterator(lower,upper);
182 }
183
184 //=======================================================================
185 //function : Element
186 //purpose  : 
187 //=======================================================================
188   const TopoDS_Shape& BOP_BlockBuilder::Element (const BOP_BlockIterator& BI) const
189 {
190   Standard_Boolean isbound = BI.More();
191   if (!isbound) {
192     Standard_Failure::Raise("OutOfRange");
193   }
194   
195   Standard_Integer index = BI.Value();
196   const TopoDS_Shape& E = myOrientedShapeMap(index);
197   return E;
198
199 //=======================================================================
200 //function : Element
201 //purpose  : 
202 //=======================================================================
203   const TopoDS_Shape& BOP_BlockBuilder::Element (const Standard_Integer index) const
204 {
205   Standard_Boolean isbound = myOrientedShapeMapIsValid.IsBound(index);
206   if (!isbound) {
207     Standard_Failure::Raise("OutOfRange");
208   }
209   const TopoDS_Shape& E = myOrientedShapeMap(index);
210   return E;
211
212 //=======================================================================
213 //function : Element
214 //purpose  : 
215 //=======================================================================
216   Standard_Integer BOP_BlockBuilder::Element (const TopoDS_Shape& E) const
217 {
218   Standard_Boolean isbound = myOrientedShapeMap.Contains(E);
219   if (!isbound) {
220     Standard_Failure::Raise("OutOfRange");
221   }
222   
223   Standard_Integer I = myOrientedShapeMap.FindIndex(E);
224   return I;
225 }
226
227 //=======================================================================
228 //function : ElementIsValid
229 //purpose  : 
230 //=======================================================================
231   Standard_Boolean BOP_BlockBuilder::ElementIsValid (const BOP_BlockIterator& BI) const 
232 {  
233   Standard_Boolean isvalid, isbound = BI.More();
234   if (!isbound) {
235     return Standard_False;
236   }
237   Standard_Integer Sindex, isb;
238   
239   Sindex = BI.Value();
240   isb = myOrientedShapeMapIsValid.Find(Sindex);
241   isvalid = (isb == 1)? Standard_True: Standard_False;
242   
243   return isvalid;
244 }
245 //=======================================================================
246 //function : ElementIsValid
247 //purpose  : 
248 //=======================================================================
249   Standard_Boolean BOP_BlockBuilder::ElementIsValid (const Standard_Integer Sindex) const
250 {  
251   Standard_Boolean isvalid, isbound = myOrientedShapeMapIsValid.IsBound(Sindex);
252   if (!isbound) return Standard_False;
253
254   Standard_Integer isb = myOrientedShapeMapIsValid.Find(Sindex);
255   isvalid = (isb == 1)? Standard_True: Standard_False;
256   
257   return isvalid;
258 }
259
260 //=======================================================================
261 //function : AddElement
262 //purpose  : 
263 //=======================================================================
264   Standard_Integer BOP_BlockBuilder::AddElement(const TopoDS_Shape& S) 
265 {
266   Standard_Integer Sindex = myOrientedShapeMap.Add(S);
267   myOrientedShapeMapIsValid.Bind(Sindex, 1);
268
269   return Sindex;
270 }
271
272 //=======================================================================
273 //function : SetValid
274 //purpose  : 
275 //=======================================================================
276   void BOP_BlockBuilder::SetValid(const BOP_BlockIterator& BI,
277                                   const Standard_Boolean isvalid)
278 {
279   Standard_Boolean isbound = BI.More();
280   if (!isbound) {
281     return;
282   }
283   Standard_Integer Sindex, i;
284   Sindex = BI.Value();
285   i = (isvalid) ? 1 : 0;
286   myOrientedShapeMapIsValid.Bind(Sindex,i);
287 }
288 //=======================================================================
289 //function : SetValid
290 //purpose  : 
291 //=======================================================================
292   void BOP_BlockBuilder::SetValid(const Standard_Integer Sindex,
293                                   const Standard_Boolean isvalid)
294 {
295   Standard_Boolean isbound = myOrientedShapeMapIsValid.IsBound(Sindex);
296   if (!isbound) {
297     return;
298   }
299
300   Standard_Integer i = (isvalid) ? 1 : 0;
301   myOrientedShapeMapIsValid.Bind(Sindex,i);
302 }
303
304 //=======================================================================
305 //function : CurrentBlockIsRegular
306 //purpose  : 
307 //=======================================================================
308   Standard_Boolean BOP_BlockBuilder::CurrentBlockIsRegular()
309 {
310   Standard_Boolean b = Standard_False;
311   Standard_Integer i = myBlocksIsRegular.Value(myBlockIndex);
312   
313   if(i == 1) {
314     b = Standard_True;
315   }
316   return b;
317 }
318
319