682c9d06 |
1 | // Created by: Peter KURNEV |
2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
3 | // |
4 | // This file is part of Open CASCADE Technology software library. |
5 | // |
d5f74e42 |
6 | // This library is free software; you can redistribute it and/or modify it under |
7 | // the terms of the GNU Lesser General Public License version 2.1 as published |
682c9d06 |
8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
10 | // distribution for complete text of the license and disclaimer of any warranty. |
11 | // |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
14 | |
df80c6dd |
15 | // File: BOPAlgo_ShellSplitter.cxx |
16 | // Created: Thu Jan 16 08:33:50 2014 |
682c9d06 |
17 | |
42cf5bc1 |
18 | #include <BOPAlgo_ShellSplitter.hxx> |
682c9d06 |
19 | #include <BOPTools_AlgoTools.hxx> |
20 | #include <BOPTools_CoupleOfShape.hxx> |
1155d05a |
21 | #include <BOPTools_Parallel.hxx> |
42cf5bc1 |
22 | #include <BRep_Builder.hxx> |
23 | #include <IntTools_Context.hxx> |
1155d05a |
24 | #include <NCollection_Vector.hxx> |
25 | #include <TopExp.hxx> |
42cf5bc1 |
26 | #include <TopExp_Explorer.hxx> |
093a3fe5 |
27 | #include <TopoDS.hxx> |
42cf5bc1 |
28 | #include <TopoDS_Edge.hxx> |
29 | #include <TopoDS_Shape.hxx> |
30 | #include <TopoDS_Shell.hxx> |
1155d05a |
31 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
32 | #include <TopTools_IndexedMapOfShape.hxx> |
33 | #include <TopTools_MapOfOrientedShape.hxx> |
34 | #include <TopTools_MapOfShape.hxx> |
69b558c4 |
35 | |
69b558c4 |
36 | // |
682c9d06 |
37 | static |
1155d05a |
38 | void MakeShell(const TopTools_ListOfShape& , |
df80c6dd |
39 | TopoDS_Shell& ); |
69b558c4 |
40 | // |
41 | static |
a2ab2702 |
42 | void RefineShell(TopoDS_Shell& theShell, |
1155d05a |
43 | const TopTools_IndexedDataMapOfShapeListOfShape& theMEF, |
44 | TopTools_ListOfShape& aLShX); |
682c9d06 |
45 | |
69b558c4 |
46 | //======================================================================= |
47 | //class : BOPAlgo_CBK |
48 | //purpose : |
49 | //======================================================================= |
50 | class BOPAlgo_CBK { |
51 | public: |
52 | BOPAlgo_CBK() : |
53 | myPCB (NULL) { |
54 | } |
55 | // |
56 | ~BOPAlgo_CBK() { |
57 | } |
58 | // |
59 | void SetConnexityBlock (const BOPTools_ConnexityBlock& aCB) { |
60 | myPCB=(BOPTools_ConnexityBlock*)&aCB; |
61 | } |
62 | // |
63 | BOPTools_ConnexityBlock& ConnexityBlock () { |
64 | return *myPCB; |
65 | } |
66 | // |
67 | void Perform() { |
68 | BOPAlgo_ShellSplitter::SplitBlock(*myPCB); |
69 | } |
70 | protected: |
71 | BOPTools_ConnexityBlock *myPCB; |
72 | }; |
73 | //======================================================================= |
fc867b96 |
74 | typedef NCollection_Vector<BOPAlgo_CBK> BOPAlgo_VectorOfCBK; |
75 | |
682c9d06 |
76 | //======================================================================= |
77 | //function : |
78 | //purpose : |
79 | //======================================================================= |
80 | BOPAlgo_ShellSplitter::BOPAlgo_ShellSplitter() |
81 | : |
82 | BOPAlgo_Algo(), |
83 | myStartShapes(myAllocator), |
84 | myShells(myAllocator), |
85 | myLCB(myAllocator) |
86 | { |
87 | } |
88 | //======================================================================= |
89 | //function : |
90 | //purpose : |
91 | //======================================================================= |
92 | BOPAlgo_ShellSplitter::BOPAlgo_ShellSplitter |
93 | (const Handle(NCollection_BaseAllocator)& theAllocator) |
94 | : |
95 | BOPAlgo_Algo(theAllocator), |
96 | myStartShapes(theAllocator), |
97 | myShells(theAllocator), |
98 | myLCB(myAllocator) |
99 | { |
100 | } |
101 | //======================================================================= |
102 | //function : ~ |
103 | //purpose : |
104 | //======================================================================= |
105 | BOPAlgo_ShellSplitter::~BOPAlgo_ShellSplitter() |
106 | { |
107 | } |
108 | //======================================================================= |
109 | //function : AddStartElement |
110 | //purpose : |
111 | //======================================================================= |
112 | void BOPAlgo_ShellSplitter::AddStartElement(const TopoDS_Shape& aE) |
113 | { |
114 | myStartShapes.Append(aE); |
115 | } |
116 | //======================================================================= |
117 | //function : StartElements |
118 | //purpose : |
119 | //======================================================================= |
1155d05a |
120 | const TopTools_ListOfShape& BOPAlgo_ShellSplitter::StartElements()const |
682c9d06 |
121 | { |
122 | return myStartShapes; |
123 | } |
124 | //======================================================================= |
125 | //function : Loops |
126 | //purpose : |
127 | //======================================================================= |
1155d05a |
128 | const TopTools_ListOfShape& BOPAlgo_ShellSplitter::Shells()const |
682c9d06 |
129 | { |
130 | return myShells; |
131 | } |
132 | //======================================================================= |
133 | //function : Perform |
134 | //purpose : |
135 | //======================================================================= |
136 | void BOPAlgo_ShellSplitter::Perform() |
137 | { |
33ba8565 |
138 | GetReport()->Clear(); |
682c9d06 |
139 | // |
98b37659 |
140 | BOPTools_AlgoTools::MakeConnexityBlocks |
141 | (myStartShapes, TopAbs_EDGE, TopAbs_FACE, myLCB); |
682c9d06 |
142 | // |
143 | MakeShells(); |
144 | } |
98b37659 |
145 | |
682c9d06 |
146 | //======================================================================= |
147 | //function : SplitBlock |
148 | //purpose : |
149 | //======================================================================= |
150 | void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB) |
151 | { |
152 | Standard_Integer aNbLF, aNbOff, aNbFP; |
153 | Standard_Integer i; |
154 | TopAbs_Orientation anOr; |
155 | TopoDS_Edge aEL; |
156 | BRep_Builder aBB; |
157 | TopoDS_Iterator aItS; |
158 | TopExp_Explorer aExp; |
1155d05a |
159 | TopTools_ListIteratorOfListOfShape aItF; |
682c9d06 |
160 | BOPTools_CoupleOfShape aCSOff; |
1155d05a |
161 | TopTools_MapOfOrientedShape AddedFacesMap; |
162 | TopTools_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP; |
a2ab2702 |
163 | Handle (IntTools_Context) aContext; |
682c9d06 |
164 | // |
a2ab2702 |
165 | aContext=new IntTools_Context; |
682c9d06 |
166 | // |
1155d05a |
167 | const TopTools_ListOfShape& myShapes=aCB.Shapes(); |
682c9d06 |
168 | // |
1155d05a |
169 | TopTools_ListOfShape& myLoops=aCB.ChangeLoops(); |
682c9d06 |
170 | myLoops.Clear(); |
171 | // |
093a3fe5 |
172 | // Copy faces into the map, for recursive search of free bounds |
1155d05a |
173 | TopTools_MapOfOrientedShape aMFaces; |
682c9d06 |
174 | aItF.Initialize (myShapes); |
175 | for (; aItF.More(); aItF.Next()) { |
093a3fe5 |
176 | aMFaces.Add(aItF.Value()); |
682c9d06 |
177 | } |
178 | // |
093a3fe5 |
179 | // remove the faces with free edges from processing |
180 | for (;;) { |
181 | // map the shapes |
182 | aEFMap.Clear(); |
183 | aItF.Initialize(myShapes); |
184 | for (; aItF.More(); aItF.Next()) { |
185 | const TopoDS_Shape& aF = aItF.Value(); |
186 | if (aMFaces.Contains(aF)) { |
1155d05a |
187 | TopExp::MapShapesAndAncestors (aF, TopAbs_EDGE, TopAbs_FACE, aEFMap); |
093a3fe5 |
188 | } |
189 | } |
190 | // |
191 | Standard_Integer aNbBegin = aMFaces.Extent(); |
192 | // check the free edges |
193 | Standard_Integer aNbE = aEFMap.Extent(); |
194 | for (i = 1; i <= aNbE; ++i) { |
195 | const TopoDS_Edge& aE = TopoDS::Edge(aEFMap.FindKey(i)); |
196 | if (!(BRep_Tool::Degenerated(aE) || aE.Orientation() == TopAbs_INTERNAL)) { |
1155d05a |
197 | const TopTools_ListOfShape& aLF = aEFMap(i); |
093a3fe5 |
198 | if (aLF.Extent() == 1) { |
199 | // remove the face |
200 | aMFaces.Remove(aLF.First()); |
201 | } |
202 | } |
203 | } |
204 | // |
205 | // check if any faces have been removed |
206 | Standard_Integer aNbEnd = aMFaces.Extent(); |
207 | if ((aNbEnd == aNbBegin) || (aNbEnd == 0)) { |
208 | break; |
209 | } |
210 | } |
211 | // |
212 | if (aMFaces.IsEmpty()) { |
213 | return; |
214 | } |
215 | // |
216 | // use only connected faces |
1155d05a |
217 | TopTools_ListOfShape aLFConnected; |
682c9d06 |
218 | aItF.Initialize (myShapes); |
093a3fe5 |
219 | for (; aItF.More(); aItF.Next()) { |
220 | const TopoDS_Shape& aF = aItF.Value(); |
221 | if (aMFaces.Contains(aF)) { |
222 | aLFConnected.Append(aF); |
223 | } |
224 | } |
225 | // |
226 | const Standard_Integer aNbShapes = aLFConnected.Extent(); |
227 | Standard_Boolean bAllFacesTaken = Standard_False; |
228 | // |
229 | // Build the shells |
230 | aItF.Initialize (aLFConnected); |
231 | for (i = 1; aItF.More() && !bAllFacesTaken; aItF.Next(), ++i) { |
682c9d06 |
232 | const TopoDS_Shape& aFF = aItF.Value(); |
233 | if (!AddedFacesMap.Add(aFF)) { |
234 | continue; |
235 | } |
236 | // |
237 | // make a new shell |
093a3fe5 |
238 | TopoDS_Shell aShellStart; |
239 | aBB.MakeShell(aShellStart); |
240 | aBB.Add(aShellStart, aFF); |
682c9d06 |
241 | // |
1155d05a |
242 | TopTools_ListOfShape aLShells; |
093a3fe5 |
243 | aLShells.Append(aShellStart); |
682c9d06 |
244 | // |
1155d05a |
245 | TopTools_ListIteratorOfListOfShape aItLShells(aLShells); |
093a3fe5 |
246 | for (; aItLShells.More(); aItLShells.Next()) { |
247 | TopoDS_Shell& aShell = TopoDS::Shell(aItLShells.ChangeValue()); |
682c9d06 |
248 | // |
093a3fe5 |
249 | aMEFP.Clear(); |
1155d05a |
250 | TopExp::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEFP); |
093a3fe5 |
251 | // |
252 | // loop on faces added to Shell; |
253 | // add their neighbor faces to Shell and so on |
254 | aItS.Initialize(aShell); |
255 | for (; aItS.More(); aItS.Next()) { |
256 | const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItS.Value())); |
682c9d06 |
257 | // |
093a3fe5 |
258 | // loop on edges of aF; find a good neighbor face of aF by aE |
259 | aExp.Init(aF, TopAbs_EDGE); |
260 | for (; aExp.More(); aExp.Next()) { |
261 | const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current())); |
262 | // |
263 | // proceed only free edges in this shell |
264 | if (aMEFP.Contains(aE)) { |
1155d05a |
265 | const TopTools_ListOfShape& aLFP = aMEFP.FindFromKey(aE); |
093a3fe5 |
266 | aNbFP = aLFP.Extent(); |
267 | if (aNbFP > 1) { |
268 | continue; |
269 | } |
270 | } |
271 | // avoid processing of internal edges |
272 | anOr = aE.Orientation(); |
273 | if (anOr == TopAbs_INTERNAL) { |
682c9d06 |
274 | continue; |
275 | } |
093a3fe5 |
276 | // avoid processing of degenerated edges |
277 | if (BRep_Tool::Degenerated(aE)) { |
682c9d06 |
278 | continue; |
093a3fe5 |
279 | } |
280 | // |
281 | // candidate faces list |
1155d05a |
282 | const TopTools_ListOfShape& aLF = aEFMap.FindFromKey(aE); |
093a3fe5 |
283 | aNbLF = aLF.Extent(); |
284 | if (!aNbLF) { |
682c9d06 |
285 | continue; |
286 | } |
287 | // |
093a3fe5 |
288 | // prepare for selecting the next face |
289 | // take only not-processed faces as a candidates |
290 | BOPTools_ListOfCoupleOfShape aLCSOff; |
291 | // |
1155d05a |
292 | TopTools_ListIteratorOfListOfShape aItLF(aLF); |
093a3fe5 |
293 | for (; aItLF.More(); aItLF.Next()) { |
294 | const TopoDS_Face& aFL = (*(TopoDS_Face*)(&aItLF.Value())); |
295 | if (aF.IsSame(aFL) || AddedFacesMap.Contains(aFL)) { |
296 | continue; |
297 | } |
298 | // |
299 | // find current edge in the face |
300 | if (!BOPTools_AlgoTools::GetEdgeOff(aE, aFL, aEL)) { |
301 | continue; |
302 | } |
303 | // |
304 | aCSOff.SetShape1(aEL); |
305 | aCSOff.SetShape2(aFL); |
306 | aLCSOff.Append(aCSOff); |
307 | }//for (; aItLF.More(); aItLF.Next()) { |
308 | // |
309 | aNbOff = aLCSOff.Extent(); |
310 | if (!aNbOff){ |
682c9d06 |
311 | continue; |
312 | } |
313 | // |
093a3fe5 |
314 | // among all the adjacent faces chose one with the minimal |
315 | // angle to the current one |
316 | TopoDS_Face aSelF; |
317 | if (aNbOff == 1) { |
318 | aSelF = (*(TopoDS_Face*)(&aLCSOff.First().Shape2())); |
319 | } |
320 | else if (aNbOff > 1) { |
321 | BOPTools_AlgoTools::GetFaceOff(aE, aF, aLCSOff, aSelF, aContext); |
322 | } |
323 | // |
324 | if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) { |
325 | aBB.Add(aShell, aSelF); |
1155d05a |
326 | TopExp::MapShapesAndAncestors(aSelF, TopAbs_EDGE, TopAbs_FACE, aMEFP); |
093a3fe5 |
327 | } |
328 | } // for (; aExp.More(); aExp.Next()) { |
329 | } // for (; aItS.More(); aItS.Next()) { |
330 | // |
331 | // split the shell on multi-connected edges |
1155d05a |
332 | TopTools_ListOfShape aLShSp; |
093a3fe5 |
333 | RefineShell(aShell, aMEFP, aLShSp); |
334 | // |
335 | // collect the not closed shells for further processing |
1155d05a |
336 | TopTools_ListOfShape aLShNC; |
093a3fe5 |
337 | // |
1155d05a |
338 | TopTools_ListIteratorOfListOfShape aItLShSp(aLShSp); |
093a3fe5 |
339 | for (; aItLShSp.More(); aItLShSp.Next()) { |
340 | TopoDS_Shell& aShSp = *((TopoDS_Shell*)&aItLShSp.Value()); |
682c9d06 |
341 | // |
093a3fe5 |
342 | if (BRep_Tool::IsClosed(aShSp)) { |
343 | aShSp.Closed(Standard_True); |
344 | myLoops.Append(aShSp); |
682c9d06 |
345 | } |
093a3fe5 |
346 | else { |
347 | aLShNC.Append(aShSp); |
682c9d06 |
348 | } |
093a3fe5 |
349 | } |
350 | // |
351 | bAllFacesTaken = (AddedFacesMap.Extent() == aNbShapes); |
352 | if (bAllFacesTaken) { |
353 | break; |
354 | } |
355 | // |
356 | if (aLShSp.Extent() == 1) { |
357 | // not further processing of not closed shells is needed, |
358 | // as it will not bring any new results |
359 | continue; |
360 | } |
a2ab2702 |
361 | // |
093a3fe5 |
362 | Standard_Integer aNbShNC = aLShNC.Extent(); |
363 | if (aNbShNC == 1) { |
364 | // try to complete the shell with other faces |
365 | aLShells.Append(aLShNC); |
366 | } |
367 | else if (aNbShNC > 1) { |
368 | // remove th faces of not closed shells from the map of processed faces |
369 | // and try to rebuild the shells using all not processed faces, |
370 | // because faces of one shell might be needed for building the other |
1155d05a |
371 | TopTools_ListIteratorOfListOfShape aItLShNC(aLShNC); |
093a3fe5 |
372 | for (; aItLShNC.More(); aItLShNC.Next()) { |
373 | TopoDS_Iterator aItNC(aItLShNC.Value()); |
374 | for (; aItNC.More(); aItNC.Next()) { |
375 | AddedFacesMap.Remove(aItNC.Value()); |
376 | } |
377 | } |
69b558c4 |
378 | } |
379 | } |
682c9d06 |
380 | } // for (; aItF.More(); aItF.Next()) { |
381 | } |
382 | //======================================================================= |
69b558c4 |
383 | //function : RefineShell |
384 | //purpose : |
682c9d06 |
385 | //======================================================================= |
093a3fe5 |
386 | void RefineShell(TopoDS_Shell& theShell, |
1155d05a |
387 | const TopTools_IndexedDataMapOfShapeListOfShape& theMEF, |
388 | TopTools_ListOfShape& theLShSp) |
69b558c4 |
389 | { |
093a3fe5 |
390 | TopoDS_Iterator aIt(theShell); |
69b558c4 |
391 | if(!aIt.More()) { |
392 | return; |
682c9d06 |
393 | } |
394 | // |
093a3fe5 |
395 | // Find edges with more than 2 adjacent faces - branch edges - |
396 | // edges on which the input shell should be split |
1155d05a |
397 | TopTools_MapOfShape aMEStop; |
69b558c4 |
398 | // |
093a3fe5 |
399 | Standard_Integer i, aNbMEF = theMEF.Extent(); |
400 | for (i = 1; i <= aNbMEF; ++i) { |
401 | const TopoDS_Edge& aE = TopoDS::Edge(theMEF.FindKey(i)); |
1155d05a |
402 | const TopTools_ListOfShape& aLF = theMEF(i); |
093a3fe5 |
403 | if (aLF.Extent() > 2) { |
404 | aMEStop.Add(aE); |
405 | continue; |
406 | } |
407 | // |
408 | // check for internal edges - count faces, in which the edge |
409 | // is internal, twice |
410 | Standard_Integer aNbF = 0; |
1155d05a |
411 | TopTools_ListIteratorOfListOfShape aItLF(aLF); |
093a3fe5 |
412 | for (; aItLF.More() && aNbF <= 2; aItLF.Next()) { |
413 | const TopoDS_Face& aF = TopoDS::Face(aItLF.Value()); |
414 | ++aNbF; |
415 | TopExp_Explorer aExp(aF, TopAbs_EDGE); |
416 | for (; aExp.More(); aExp.Next()) { |
417 | const TopoDS_Shape& aEF = aExp.Current(); |
418 | if (aEF.IsSame(aE)) { |
419 | if (aEF.Orientation() == TopAbs_INTERNAL) { |
420 | ++aNbF; |
421 | } |
422 | break; |
423 | } |
424 | } |
425 | } |
426 | // |
427 | if (aNbF > 2) { |
69b558c4 |
428 | aMEStop.Add(aE); |
429 | } |
430 | } |
431 | // |
432 | if (aMEStop.IsEmpty()) { |
093a3fe5 |
433 | theLShSp.Append(theShell); |
69b558c4 |
434 | return; |
435 | } |
436 | // |
093a3fe5 |
437 | TopoDS_Builder aBB; |
438 | TopExp_Explorer aExp; |
1155d05a |
439 | TopTools_IndexedMapOfShape aMFB; |
440 | TopTools_MapOfOrientedShape aMFProcessed; |
441 | TopTools_ListOfShape aLFP, aLFP1; |
442 | TopTools_ListIteratorOfListOfShape aItLF, aItLFP; |
093a3fe5 |
443 | // |
444 | // The first Face |
a2ab2702 |
445 | for (; aIt.More(); aIt.Next()) { |
093a3fe5 |
446 | const TopoDS_Shape& aF1 = aIt.Value(); |
a2ab2702 |
447 | if (!aMFProcessed.Add(aF1)) { |
448 | continue; |
449 | } |
450 | // |
451 | aMFB.Clear(); |
452 | aLFP.Clear(); |
453 | // |
454 | aMFB.Add(aF1); |
455 | aLFP.Append(aF1); |
456 | // |
457 | // Trying to reach the branch point |
0f04f1e1 |
458 | for (;;) { |
a2ab2702 |
459 | aItLFP.Initialize(aLFP); |
093a3fe5 |
460 | for (; aItLFP.More(); aItLFP.Next()) { |
461 | const TopoDS_Shape& aFP = aItLFP.Value(); |
69b558c4 |
462 | // |
a2ab2702 |
463 | aExp.Init(aFP, TopAbs_EDGE); |
464 | for (; aExp.More(); aExp.Next()) { |
093a3fe5 |
465 | const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current())); |
a2ab2702 |
466 | if (aMEStop.Contains(aE)) { |
69b558c4 |
467 | continue; |
468 | } |
a2ab2702 |
469 | // |
0f04f1e1 |
470 | if (aE.Orientation() == TopAbs_INTERNAL) { |
471 | continue; |
472 | } |
473 | // |
a2ab2702 |
474 | if (BRep_Tool::Degenerated(aE)) { |
69b558c4 |
475 | continue; |
476 | } |
a2ab2702 |
477 | // |
1155d05a |
478 | const TopTools_ListOfShape& aLF = theMEF.FindFromKey(aE); |
a2ab2702 |
479 | // |
480 | aItLF.Initialize(aLF); |
093a3fe5 |
481 | for (; aItLF.More(); aItLF.Next()) { |
482 | const TopoDS_Shape& aFP1 = aItLF.Value(); |
a2ab2702 |
483 | if (aFP1.IsSame(aFP)) { |
484 | continue; |
485 | } |
486 | if (aMFB.Contains(aFP1)) { |
487 | continue; |
488 | } |
489 | // |
093a3fe5 |
490 | if (aMFProcessed.Add(aFP1)) { |
491 | aMFB.Add(aFP1); |
492 | aLFP1.Append(aFP1); |
493 | } |
a2ab2702 |
494 | }// for (; aItLF.More(); aItLF.Next()) { |
495 | }// for (; aExp.More(); aExp.Next()) { |
496 | } // for (; aItLFP.More(); aItLFP.Next()) { |
497 | // |
498 | // |
499 | if (aLFP1.IsEmpty()) { |
500 | break; |
501 | } |
502 | // |
503 | aLFP.Clear(); |
093a3fe5 |
504 | aLFP.Append(aLFP1); |
0f04f1e1 |
505 | }// for (;;) { |
69b558c4 |
506 | // |
093a3fe5 |
507 | Standard_Integer aNbMFB = aMFB.Extent(); |
a2ab2702 |
508 | if (aNbMFB) { |
093a3fe5 |
509 | TopoDS_Shell aShSp; |
510 | aBB.MakeShell(aShSp); |
a2ab2702 |
511 | // |
093a3fe5 |
512 | for (i = 1; i <= aNbMFB; ++i) { |
513 | const TopoDS_Shape& aFB = aMFB(i); |
514 | aBB.Add(aShSp, aFB); |
a2ab2702 |
515 | } |
093a3fe5 |
516 | theLShSp.Append(aShSp); |
682c9d06 |
517 | } |
a2ab2702 |
518 | }//for (; aIt.More(); aIt.Next()) { |
0f04f1e1 |
519 | } |
682c9d06 |
520 | //======================================================================= |
69b558c4 |
521 | //function : MakeShells |
682c9d06 |
522 | //purpose : |
523 | //======================================================================= |
524 | void BOPAlgo_ShellSplitter::MakeShells() |
525 | { |
526 | Standard_Boolean bIsRegular; |
69b558c4 |
527 | Standard_Integer aNbVCBK, k; |
682c9d06 |
528 | BOPTools_ListIteratorOfListOfConnexityBlock aItCB; |
1155d05a |
529 | TopTools_ListIteratorOfListOfShape aIt; |
69b558c4 |
530 | BOPAlgo_VectorOfCBK aVCBK; |
682c9d06 |
531 | // |
682c9d06 |
532 | myShells.Clear(); |
533 | // |
534 | aItCB.Initialize(myLCB); |
535 | for (; aItCB.More(); aItCB.Next()) { |
536 | BOPTools_ConnexityBlock& aCB=aItCB.ChangeValue(); |
537 | bIsRegular=aCB.IsRegular(); |
538 | if (bIsRegular) { |
539 | TopoDS_Shell aShell; |
540 | // |
1155d05a |
541 | const TopTools_ListOfShape& aLF=aCB.Shapes(); |
682c9d06 |
542 | MakeShell(aLF, aShell); |
ab860031 |
543 | aShell.Closed(Standard_True); |
682c9d06 |
544 | myShells.Append(aShell); |
545 | } |
546 | else { |
1155d05a |
547 | BOPAlgo_CBK& aCBK=aVCBK.Appended(); |
69b558c4 |
548 | aCBK.SetConnexityBlock(aCB); |
682c9d06 |
549 | } |
550 | } |
551 | // |
1155d05a |
552 | aNbVCBK=aVCBK.Length(); |
682c9d06 |
553 | //=================================================== |
fc867b96 |
554 | BOPTools_Parallel::Perform (myRunParallel, aVCBK); |
682c9d06 |
555 | //=================================================== |
69b558c4 |
556 | for (k=0; k<aNbVCBK; ++k) { |
557 | BOPAlgo_CBK& aCBK=aVCBK(k); |
558 | const BOPTools_ConnexityBlock& aCB=aCBK.ConnexityBlock(); |
1155d05a |
559 | const TopTools_ListOfShape& aLS=aCB.Loops(); |
682c9d06 |
560 | aIt.Initialize(aLS); |
561 | for (; aIt.More(); aIt.Next()) { |
ab860031 |
562 | TopoDS_Shape& aShell=aIt.ChangeValue(); |
563 | aShell.Closed(Standard_True); |
682c9d06 |
564 | myShells.Append(aShell); |
565 | } |
566 | } |
567 | } |
568 | //======================================================================= |
682c9d06 |
569 | //function : MakeShell |
570 | //purpose : |
571 | //======================================================================= |
1155d05a |
572 | void MakeShell(const TopTools_ListOfShape& aLS, |
df80c6dd |
573 | TopoDS_Shell& aShell) |
682c9d06 |
574 | { |
575 | BRep_Builder aBB; |
1155d05a |
576 | TopTools_ListIteratorOfListOfShape aIt; |
682c9d06 |
577 | // |
578 | aBB.MakeShell(aShell); |
579 | // |
580 | aIt.Initialize(aLS); |
581 | for (; aIt.More(); aIt.Next()) { |
582 | const TopoDS_Shape& aF=aIt.Value(); |
583 | aBB.Add(aShell, aF); |
584 | } |
6fd4ffd9 |
585 | // |
586 | BOPTools_AlgoTools::OrientFacesOnShell(aShell); |
682c9d06 |
587 | } |