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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
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>
24 //=======================================================================
25 //function : TopOpeBRepBuild_BlockBuilder
27 //=======================================================================
28 TopOpeBRepBuild_BlockBuilder::TopOpeBRepBuild_BlockBuilder()
29 :myIsDone(Standard_False)
33 //=======================================================================
34 //function : TopOpeBRepBuild_BlockBuilder
36 //=======================================================================
38 TopOpeBRepBuild_BlockBuilder::TopOpeBRepBuild_BlockBuilder
39 (TopOpeBRepBuild_ShapeSet& SS)
40 :myIsDone(Standard_False)
45 //=======================================================================
46 //function : MakeBlock
48 //=======================================================================
50 void TopOpeBRepBuild_BlockBuilder::MakeBlock(TopOpeBRepBuild_ShapeSet& SS)
52 // Compute the set of connexity blocks of elements of element set SS
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.
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 :
65 // l = myBlocks(i+1) - 1
67 myOrientedShapeMap.Clear();
68 myOrientedShapeMapIsValid.Clear();
70 myBlocksIsRegular.Clear();
72 Standard_Boolean IsRegular;
73 Standard_Integer CurNei;
74 Standard_Integer Mextent;
75 Standard_Integer Eindex;
77 for (SS.InitStartElements();SS.MoreStartElements();SS.NextStartElement()) {
79 const TopoDS_Shape& E = SS.StartElement();
80 Mextent = myOrientedShapeMap.Extent();
81 Eindex = AddElement(E);
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
87 Standard_Boolean EnewinM = (Eindex > Mextent);
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
98 Mextent = myOrientedShapeMap.Extent();
99 Standard_Boolean searchneighbours = (Eindex <= Mextent);
100 while (searchneighbours) {
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);
113 for (; SS.MoreNeighbours(); SS.NextNeighbour()) {
114 const TopoDS_Shape& N = SS.Neighbour();
119 Mextent = myOrientedShapeMap.Extent();
120 searchneighbours = (Eindex <= Mextent);
122 } // while (searchneighbours)
123 Standard_Integer iiregu = IsRegular ? 1 : 0;
124 myBlocksIsRegular.Append(iiregu);
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;
137 myOrientedShapeMap.Clear();
138 myOrientedShapeMapIsValid.Clear();
140 while (SS.MoreStartElements()) {
141 Standard_Integer last = myOrientedShapeMap.Extent();
142 Standard_Integer index =AddElement(SS.StartElement());
144 myBlocks.Append(index);
145 while (index <= myOrientedShapeMap.Extent()) {
146 for (SS.InitNeighbours(myOrientedShapeMap(index));
148 SS.NextNeighbour()) {
149 AddElement(SS.Neighbour());
154 SS.NextStartElement();
156 myBlocks.Append(myOrientedShapeMap.Extent()+1);
161 //=======================================================================
162 //function : InitBlock
164 //=======================================================================
166 void TopOpeBRepBuild_BlockBuilder::InitBlock()
171 //=======================================================================
172 //function : MoreBlock
174 //=======================================================================
176 Standard_Boolean TopOpeBRepBuild_BlockBuilder::MoreBlock() const
178 // the length of myBlocks is 1 + number of connexity blocks
179 Standard_Integer l = myBlocks.Length();
180 Standard_Boolean b = (myBlockIndex < l);
184 //=======================================================================
185 //function : NextBlock
187 //=======================================================================
189 void TopOpeBRepBuild_BlockBuilder::NextBlock()
194 //=======================================================================
195 //function : BlockIterator
197 //=======================================================================
199 TopOpeBRepBuild_BlockIterator TopOpeBRepBuild_BlockBuilder::BlockIterator() const
201 Standard_Integer lower = myBlocks(myBlockIndex);
202 Standard_Integer upper = myBlocks(myBlockIndex+1)-1;
203 return TopOpeBRepBuild_BlockIterator(lower,upper);
206 //=======================================================================
209 //=======================================================================
211 const TopoDS_Shape& TopOpeBRepBuild_BlockBuilder::Element
212 (const TopOpeBRepBuild_BlockIterator& BI) const
214 Standard_Boolean isbound = BI.More();
215 if (!isbound) throw Standard_Failure("OutOfRange");
217 Standard_Integer index = BI.Value();
218 const TopoDS_Shape& E = myOrientedShapeMap(index);
222 const TopoDS_Shape& TopOpeBRepBuild_BlockBuilder::Element
223 (const Standard_Integer index) const
225 Standard_Boolean isbound = myOrientedShapeMapIsValid.IsBound(index);
226 if (!isbound) throw Standard_Failure("OutOfRange");
228 const TopoDS_Shape& E = myOrientedShapeMap(index);
232 Standard_Integer TopOpeBRepBuild_BlockBuilder::Element
233 (const TopoDS_Shape& E) const
235 Standard_Boolean isbound = myOrientedShapeMap.Contains(E);
236 if (!isbound) throw Standard_Failure("OutOfRange");
238 Standard_Integer I = myOrientedShapeMap.FindIndex(E);
242 //=======================================================================
243 //function : ElementIsValid
245 //=======================================================================
247 Standard_Boolean TopOpeBRepBuild_BlockBuilder::ElementIsValid
248 (const TopOpeBRepBuild_BlockIterator& BI) const
250 Standard_Boolean isbound = BI.More();
251 if (!isbound) return Standard_False;
253 Standard_Integer Sindex = BI.Value();
254 Standard_Integer isb = myOrientedShapeMapIsValid.Find(Sindex);
255 Standard_Boolean isvalid = (isb == 1)? Standard_True: Standard_False;
260 Standard_Boolean TopOpeBRepBuild_BlockBuilder::ElementIsValid
261 (const Standard_Integer Sindex) const
263 Standard_Boolean isbound = myOrientedShapeMapIsValid.IsBound(Sindex);
264 if (!isbound) return Standard_False;
266 Standard_Integer isb = myOrientedShapeMapIsValid.Find(Sindex);
267 Standard_Boolean isvalid = (isb == 1)? Standard_True: Standard_False;
272 //=======================================================================
273 //function : AddElement
275 //=======================================================================
277 Standard_Integer TopOpeBRepBuild_BlockBuilder::AddElement(const TopoDS_Shape& S)
279 Standard_Integer Sindex = myOrientedShapeMap.Add(S);
280 myOrientedShapeMapIsValid.Bind(Sindex, 1);
285 //=======================================================================
286 //function : SetValid
288 //=======================================================================
290 void TopOpeBRepBuild_BlockBuilder::SetValid
291 (const TopOpeBRepBuild_BlockIterator& BI,
292 const Standard_Boolean isvalid)
294 Standard_Boolean isbound = BI.More();
295 if (!isbound) return;
297 Standard_Integer Sindex = BI.Value();
298 Standard_Integer i = (isvalid) ? 1 : 0;
299 myOrientedShapeMapIsValid.Bind(Sindex,i);
302 void TopOpeBRepBuild_BlockBuilder::SetValid
303 (const Standard_Integer Sindex,
304 const Standard_Boolean isvalid)
306 Standard_Boolean isbound = myOrientedShapeMapIsValid.IsBound(Sindex);
307 if (!isbound) return;
309 Standard_Integer i = (isvalid) ? 1 : 0;
310 myOrientedShapeMapIsValid.Bind(Sindex,i);
313 //=======================================================================
314 //function : CurrentBlockIsRegular
316 //=======================================================================
318 Standard_Boolean TopOpeBRepBuild_BlockBuilder::CurrentBlockIsRegular()
320 Standard_Boolean b = Standard_False;
321 Standard_Integer i = myBlocksIsRegular.Value(myBlockIndex);