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> |
19 | #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx> |
682c9d06 |
20 | #include <BOPCol_IndexedMapOfShape.hxx> |
682c9d06 |
21 | #include <BOPCol_MapOfOrientedShape.hxx> |
42cf5bc1 |
22 | #include <BOPCol_MapOfShape.hxx> |
682c9d06 |
23 | #include <BOPCol_NCVector.hxx> |
42cf5bc1 |
24 | #include <BOPCol_Parallel.hxx> |
682c9d06 |
25 | #include <BOPTools.hxx> |
26 | #include <BOPTools_AlgoTools.hxx> |
27 | #include <BOPTools_CoupleOfShape.hxx> |
42cf5bc1 |
28 | #include <BRep_Builder.hxx> |
29 | #include <IntTools_Context.hxx> |
30 | #include <TopExp_Explorer.hxx> |
093a3fe5 |
31 | #include <TopoDS.hxx> |
42cf5bc1 |
32 | #include <TopoDS_Edge.hxx> |
33 | #include <TopoDS_Shape.hxx> |
34 | #include <TopoDS_Shell.hxx> |
69b558c4 |
35 | |
69b558c4 |
36 | // |
682c9d06 |
37 | static |
38 | void MakeShell(const BOPCol_ListOfShape& , |
df80c6dd |
39 | TopoDS_Shell& ); |
69b558c4 |
40 | // |
41 | static |
a2ab2702 |
42 | void RefineShell(TopoDS_Shell& theShell, |
093a3fe5 |
43 | const BOPCol_IndexedDataMapOfShapeListOfShape& theMEF, |
a2ab2702 |
44 | BOPCol_ListOfShape& aLShX); |
0090ae85 |
45 | // |
46 | static |
47 | void MapEdgesAndFaces |
48 | (const TopoDS_Shape& aF, |
49 | BOPCol_IndexedDataMapOfShapeListOfShape& aMEF, |
50 | const Handle(NCollection_BaseAllocator)& theAllocator); |
682c9d06 |
51 | |
69b558c4 |
52 | //======================================================================= |
53 | //class : BOPAlgo_CBK |
54 | //purpose : |
55 | //======================================================================= |
56 | class BOPAlgo_CBK { |
57 | public: |
58 | BOPAlgo_CBK() : |
59 | myPCB (NULL) { |
60 | } |
61 | // |
62 | ~BOPAlgo_CBK() { |
63 | } |
64 | // |
65 | void SetConnexityBlock (const BOPTools_ConnexityBlock& aCB) { |
66 | myPCB=(BOPTools_ConnexityBlock*)&aCB; |
67 | } |
68 | // |
69 | BOPTools_ConnexityBlock& ConnexityBlock () { |
70 | return *myPCB; |
71 | } |
72 | // |
73 | void Perform() { |
74 | BOPAlgo_ShellSplitter::SplitBlock(*myPCB); |
75 | } |
76 | protected: |
77 | BOPTools_ConnexityBlock *myPCB; |
78 | }; |
79 | //======================================================================= |
80 | typedef BOPCol_NCVector |
81 | <BOPAlgo_CBK> BOPAlgo_VectorOfCBK; |
82 | // |
c7b59798 |
83 | typedef BOPCol_Functor |
69b558c4 |
84 | <BOPAlgo_CBK, |
85 | BOPAlgo_VectorOfCBK> BOPAlgo_CBKFunctor; |
86 | // |
c7b59798 |
87 | typedef BOPCol_Cnt |
69b558c4 |
88 | <BOPAlgo_CBKFunctor, |
89 | BOPAlgo_VectorOfCBK> BOPAlgo_CBKCnt; |
90 | // |
682c9d06 |
91 | //======================================================================= |
92 | //function : |
93 | //purpose : |
94 | //======================================================================= |
95 | BOPAlgo_ShellSplitter::BOPAlgo_ShellSplitter() |
96 | : |
97 | BOPAlgo_Algo(), |
98 | myStartShapes(myAllocator), |
99 | myShells(myAllocator), |
100 | myLCB(myAllocator) |
101 | { |
102 | } |
103 | //======================================================================= |
104 | //function : |
105 | //purpose : |
106 | //======================================================================= |
107 | BOPAlgo_ShellSplitter::BOPAlgo_ShellSplitter |
108 | (const Handle(NCollection_BaseAllocator)& theAllocator) |
109 | : |
110 | BOPAlgo_Algo(theAllocator), |
111 | myStartShapes(theAllocator), |
112 | myShells(theAllocator), |
113 | myLCB(myAllocator) |
114 | { |
115 | } |
116 | //======================================================================= |
117 | //function : ~ |
118 | //purpose : |
119 | //======================================================================= |
120 | BOPAlgo_ShellSplitter::~BOPAlgo_ShellSplitter() |
121 | { |
122 | } |
123 | //======================================================================= |
124 | //function : AddStartElement |
125 | //purpose : |
126 | //======================================================================= |
127 | void BOPAlgo_ShellSplitter::AddStartElement(const TopoDS_Shape& aE) |
128 | { |
129 | myStartShapes.Append(aE); |
130 | } |
131 | //======================================================================= |
132 | //function : StartElements |
133 | //purpose : |
134 | //======================================================================= |
135 | const BOPCol_ListOfShape& BOPAlgo_ShellSplitter::StartElements()const |
136 | { |
137 | return myStartShapes; |
138 | } |
139 | //======================================================================= |
140 | //function : Loops |
141 | //purpose : |
142 | //======================================================================= |
143 | const BOPCol_ListOfShape& BOPAlgo_ShellSplitter::Shells()const |
144 | { |
145 | return myShells; |
146 | } |
147 | //======================================================================= |
148 | //function : Perform |
149 | //purpose : |
150 | //======================================================================= |
151 | void BOPAlgo_ShellSplitter::Perform() |
152 | { |
33ba8565 |
153 | GetReport()->Clear(); |
682c9d06 |
154 | // |
155 | MakeConnexityBlocks(); |
33ba8565 |
156 | if (HasErrors()) { |
682c9d06 |
157 | return; |
158 | } |
159 | // |
160 | MakeShells(); |
161 | } |
162 | //======================================================================= |
163 | //function : MakeConnexityBlocks |
164 | //purpose : |
165 | //======================================================================= |
166 | void BOPAlgo_ShellSplitter::MakeConnexityBlocks() |
167 | { |
168 | Standard_Boolean bRegular; |
169 | Standard_Integer i, j, aNbE, aNbES, aNbEP, k, aNbCB; |
170 | TopoDS_Shape aFR; |
0090ae85 |
171 | TopoDS_Iterator aItF, aItW; |
682c9d06 |
172 | BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, myAllocator); |
173 | BOPCol_IndexedMapOfShape aMEP(100, myAllocator); |
174 | BOPCol_IndexedMapOfShape aMFC(100, myAllocator); |
175 | BOPCol_MapOfShape aMER(100, myAllocator); |
176 | BOPCol_MapOfShape aMFP(100, myAllocator); |
177 | BOPCol_IndexedMapOfShape aMEAdd(100, myAllocator); |
178 | BOPCol_MapOfShape aMES(100, myAllocator); |
179 | BOPCol_ListIteratorOfListOfShape aIt; |
180 | // |
682c9d06 |
181 | myLCB.Clear(); |
182 | // |
183 | const BOPCol_ListOfShape& aLSE=myStartShapes; |
184 | aIt.Initialize(aLSE); |
185 | for (i=1; aIt.More(); aIt.Next(), ++i) { |
186 | const TopoDS_Shape& aSE=aIt.Value(); |
187 | if (!aMEP.Contains(aSE)) { |
188 | aMEP.Add(aSE); |
0090ae85 |
189 | MapEdgesAndFaces(aSE, aMEF, myAllocator); |
682c9d06 |
190 | } |
191 | else { |
192 | aMER.Add(aSE); |
193 | } |
194 | } |
195 | // |
196 | // 2 |
197 | aNbE=aMEF.Extent(); |
198 | for (i=1; i<=aNbE; ++i) { |
199 | aNbES=aMES.Extent(); |
200 | if (aNbES==aNbE) { |
201 | break; |
202 | } |
203 | // |
204 | const TopoDS_Shape& aE=aMEF.FindKey(i); |
205 | // |
206 | if (!aMES.Add(aE)) { |
207 | continue; |
208 | } |
209 | // aMES - globally processed edges |
210 | // |
211 | //------------------------------------- goal: aMEC |
212 | aMFC.Clear(); // aMEC - edges of CB |
213 | aMEP.Clear(); // aMVP - edges to process right now |
214 | aMEAdd.Clear(); // aMVAdd edges to process on next step of for(;;) { |
215 | // |
216 | aMEP.Add(aE); |
217 | // |
218 | for(;;) { |
219 | aNbEP=aMEP.Extent(); |
220 | for (k=1; k<=aNbEP; ++k) { |
221 | const TopoDS_Shape& aEP=aMEP(k); |
222 | const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aEP); |
223 | aIt.Initialize(aLF); |
224 | for (; aIt.More(); aIt.Next()) { |
225 | const TopoDS_Shape& aF=aIt.Value(); |
226 | if (aMFC.Add(aF)) { |
0090ae85 |
227 | aItF.Initialize(aF); |
228 | while (aItF.More()) { |
229 | const TopoDS_Shape& aW=aItF.Value(); |
230 | if (aW.ShapeType()!=TopAbs_WIRE) { |
231 | aItF.Next(); |
232 | continue; |
233 | } |
234 | // |
235 | aItW.Initialize(aW); |
236 | while (aItW.More()) { |
237 | const TopoDS_Shape& aEF=aItW.Value(); |
238 | // |
239 | if (aMES.Add(aEF)) { |
240 | aMEAdd.Add(aEF); |
241 | } |
242 | // |
243 | aItW.Next(); |
682c9d06 |
244 | } |
0090ae85 |
245 | // |
246 | aItF.Next(); |
682c9d06 |
247 | } |
248 | } |
249 | } |
250 | } |
251 | // |
252 | aNbEP=aMEAdd.Extent(); |
253 | if (!aNbEP) { |
254 | break; // from for(;;) { |
255 | } |
256 | // |
257 | aMEP.Clear(); |
258 | // |
259 | for (k=1; k<=aNbEP; ++k) { |
260 | const TopoDS_Shape& aEF=aMEAdd(k); |
261 | aMEP.Add(aEF); |
262 | } |
263 | aMEAdd.Clear(); |
264 | }// for(;;) { |
265 | // |
266 | //------------------------------------- |
267 | BOPTools_ConnexityBlock aCB(myAllocator); |
268 | // |
269 | BOPCol_ListOfShape& aLECB=aCB.ChangeShapes(); |
270 | BOPCol_IndexedDataMapOfShapeListOfShape aMEFR(100, myAllocator); |
271 | // |
272 | bRegular=Standard_True; |
273 | aNbCB = aMFC.Extent(); |
274 | for (j=1; j<=aNbCB; ++j) { |
275 | aFR = aMFC(j); |
276 | // |
277 | if (aMER.Contains(aFR)) { |
278 | aFR.Orientation(TopAbs_FORWARD); |
279 | aLECB.Append(aFR); |
280 | aFR.Orientation(TopAbs_REVERSED); |
281 | aLECB.Append(aFR); |
282 | bRegular=Standard_False; |
283 | } |
284 | else { |
285 | aLECB.Append(aFR); |
286 | } |
287 | // |
288 | if (bRegular) { |
0090ae85 |
289 | MapEdgesAndFaces(aFR, aMEFR, myAllocator); |
682c9d06 |
290 | } |
291 | } |
292 | // |
293 | if (bRegular) { |
294 | Standard_Integer aNbER, aNbFR; |
295 | // |
296 | aNbER=aMEFR.Extent(); |
297 | for (k=1; k<=aNbER; ++k) { |
298 | const BOPCol_ListOfShape& aLFR=aMEFR(k); |
299 | aNbFR=aLFR.Extent(); |
300 | if (aNbFR>2) { |
301 | bRegular=!bRegular; |
302 | break; |
303 | } |
304 | } |
305 | } |
306 | // |
307 | aCB.SetRegular(bRegular); |
308 | myLCB.Append(aCB); |
309 | } |
310 | } |
311 | //======================================================================= |
312 | //function : SplitBlock |
313 | //purpose : |
314 | //======================================================================= |
315 | void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB) |
316 | { |
317 | Standard_Integer aNbLF, aNbOff, aNbFP; |
318 | Standard_Integer i; |
319 | TopAbs_Orientation anOr; |
320 | TopoDS_Edge aEL; |
321 | BRep_Builder aBB; |
322 | TopoDS_Iterator aItS; |
323 | TopExp_Explorer aExp; |
324 | BOPCol_ListIteratorOfListOfShape aItF; |
325 | BOPTools_CoupleOfShape aCSOff; |
326 | BOPCol_MapOfOrientedShape AddedFacesMap; |
327 | BOPCol_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP; |
a2ab2702 |
328 | Handle (IntTools_Context) aContext; |
682c9d06 |
329 | // |
a2ab2702 |
330 | aContext=new IntTools_Context; |
682c9d06 |
331 | // |
332 | const BOPCol_ListOfShape& myShapes=aCB.Shapes(); |
333 | // |
334 | BOPCol_ListOfShape& myLoops=aCB.ChangeLoops(); |
335 | myLoops.Clear(); |
336 | // |
093a3fe5 |
337 | // Copy faces into the map, for recursive search of free bounds |
338 | BOPCol_MapOfOrientedShape aMFaces; |
682c9d06 |
339 | aItF.Initialize (myShapes); |
340 | for (; aItF.More(); aItF.Next()) { |
093a3fe5 |
341 | aMFaces.Add(aItF.Value()); |
682c9d06 |
342 | } |
343 | // |
093a3fe5 |
344 | // remove the faces with free edges from processing |
345 | for (;;) { |
346 | // map the shapes |
347 | aEFMap.Clear(); |
348 | aItF.Initialize(myShapes); |
349 | for (; aItF.More(); aItF.Next()) { |
350 | const TopoDS_Shape& aF = aItF.Value(); |
351 | if (aMFaces.Contains(aF)) { |
352 | BOPTools::MapShapesAndAncestors (aF, TopAbs_EDGE, TopAbs_FACE, aEFMap); |
353 | } |
354 | } |
355 | // |
356 | Standard_Integer aNbBegin = aMFaces.Extent(); |
357 | // check the free edges |
358 | Standard_Integer aNbE = aEFMap.Extent(); |
359 | for (i = 1; i <= aNbE; ++i) { |
360 | const TopoDS_Edge& aE = TopoDS::Edge(aEFMap.FindKey(i)); |
361 | if (!(BRep_Tool::Degenerated(aE) || aE.Orientation() == TopAbs_INTERNAL)) { |
362 | const BOPCol_ListOfShape& aLF = aEFMap(i); |
363 | if (aLF.Extent() == 1) { |
364 | // remove the face |
365 | aMFaces.Remove(aLF.First()); |
366 | } |
367 | } |
368 | } |
369 | // |
370 | // check if any faces have been removed |
371 | Standard_Integer aNbEnd = aMFaces.Extent(); |
372 | if ((aNbEnd == aNbBegin) || (aNbEnd == 0)) { |
373 | break; |
374 | } |
375 | } |
376 | // |
377 | if (aMFaces.IsEmpty()) { |
378 | return; |
379 | } |
380 | // |
381 | // use only connected faces |
382 | BOPCol_ListOfShape aLFConnected; |
682c9d06 |
383 | aItF.Initialize (myShapes); |
093a3fe5 |
384 | for (; aItF.More(); aItF.Next()) { |
385 | const TopoDS_Shape& aF = aItF.Value(); |
386 | if (aMFaces.Contains(aF)) { |
387 | aLFConnected.Append(aF); |
388 | } |
389 | } |
390 | // |
391 | const Standard_Integer aNbShapes = aLFConnected.Extent(); |
392 | Standard_Boolean bAllFacesTaken = Standard_False; |
393 | // |
394 | // Build the shells |
395 | aItF.Initialize (aLFConnected); |
396 | for (i = 1; aItF.More() && !bAllFacesTaken; aItF.Next(), ++i) { |
682c9d06 |
397 | const TopoDS_Shape& aFF = aItF.Value(); |
398 | if (!AddedFacesMap.Add(aFF)) { |
399 | continue; |
400 | } |
401 | // |
402 | // make a new shell |
093a3fe5 |
403 | TopoDS_Shell aShellStart; |
404 | aBB.MakeShell(aShellStart); |
405 | aBB.Add(aShellStart, aFF); |
682c9d06 |
406 | // |
093a3fe5 |
407 | BOPCol_ListOfShape aLShells; |
408 | aLShells.Append(aShellStart); |
682c9d06 |
409 | // |
093a3fe5 |
410 | BOPCol_ListIteratorOfListOfShape aItLShells(aLShells); |
411 | for (; aItLShells.More(); aItLShells.Next()) { |
412 | TopoDS_Shell& aShell = TopoDS::Shell(aItLShells.ChangeValue()); |
682c9d06 |
413 | // |
093a3fe5 |
414 | aMEFP.Clear(); |
415 | BOPTools::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEFP); |
416 | // |
417 | // loop on faces added to Shell; |
418 | // add their neighbor faces to Shell and so on |
419 | aItS.Initialize(aShell); |
420 | for (; aItS.More(); aItS.Next()) { |
421 | const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItS.Value())); |
682c9d06 |
422 | // |
093a3fe5 |
423 | // loop on edges of aF; find a good neighbor face of aF by aE |
424 | aExp.Init(aF, TopAbs_EDGE); |
425 | for (; aExp.More(); aExp.Next()) { |
426 | const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current())); |
427 | // |
428 | // proceed only free edges in this shell |
429 | if (aMEFP.Contains(aE)) { |
430 | const BOPCol_ListOfShape& aLFP = aMEFP.FindFromKey(aE); |
431 | aNbFP = aLFP.Extent(); |
432 | if (aNbFP > 1) { |
433 | continue; |
434 | } |
435 | } |
436 | // avoid processing of internal edges |
437 | anOr = aE.Orientation(); |
438 | if (anOr == TopAbs_INTERNAL) { |
682c9d06 |
439 | continue; |
440 | } |
093a3fe5 |
441 | // avoid processing of degenerated edges |
442 | if (BRep_Tool::Degenerated(aE)) { |
682c9d06 |
443 | continue; |
093a3fe5 |
444 | } |
445 | // |
446 | // candidate faces list |
447 | const BOPCol_ListOfShape& aLF = aEFMap.FindFromKey(aE); |
448 | aNbLF = aLF.Extent(); |
449 | if (!aNbLF) { |
682c9d06 |
450 | continue; |
451 | } |
452 | // |
093a3fe5 |
453 | // prepare for selecting the next face |
454 | // take only not-processed faces as a candidates |
455 | BOPTools_ListOfCoupleOfShape aLCSOff; |
456 | // |
457 | BOPCol_ListIteratorOfListOfShape aItLF(aLF); |
458 | for (; aItLF.More(); aItLF.Next()) { |
459 | const TopoDS_Face& aFL = (*(TopoDS_Face*)(&aItLF.Value())); |
460 | if (aF.IsSame(aFL) || AddedFacesMap.Contains(aFL)) { |
461 | continue; |
462 | } |
463 | // |
464 | // find current edge in the face |
465 | if (!BOPTools_AlgoTools::GetEdgeOff(aE, aFL, aEL)) { |
466 | continue; |
467 | } |
468 | // |
469 | aCSOff.SetShape1(aEL); |
470 | aCSOff.SetShape2(aFL); |
471 | aLCSOff.Append(aCSOff); |
472 | }//for (; aItLF.More(); aItLF.Next()) { |
473 | // |
474 | aNbOff = aLCSOff.Extent(); |
475 | if (!aNbOff){ |
682c9d06 |
476 | continue; |
477 | } |
478 | // |
093a3fe5 |
479 | // among all the adjacent faces chose one with the minimal |
480 | // angle to the current one |
481 | TopoDS_Face aSelF; |
482 | if (aNbOff == 1) { |
483 | aSelF = (*(TopoDS_Face*)(&aLCSOff.First().Shape2())); |
484 | } |
485 | else if (aNbOff > 1) { |
486 | BOPTools_AlgoTools::GetFaceOff(aE, aF, aLCSOff, aSelF, aContext); |
487 | } |
488 | // |
489 | if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) { |
490 | aBB.Add(aShell, aSelF); |
491 | BOPTools::MapShapesAndAncestors(aSelF, TopAbs_EDGE, TopAbs_FACE, aMEFP); |
492 | } |
493 | } // for (; aExp.More(); aExp.Next()) { |
494 | } // for (; aItS.More(); aItS.Next()) { |
495 | // |
496 | // split the shell on multi-connected edges |
497 | BOPCol_ListOfShape aLShSp; |
498 | RefineShell(aShell, aMEFP, aLShSp); |
499 | // |
500 | // collect the not closed shells for further processing |
501 | BOPCol_ListOfShape aLShNC; |
502 | // |
503 | BOPCol_ListIteratorOfListOfShape aItLShSp(aLShSp); |
504 | for (; aItLShSp.More(); aItLShSp.Next()) { |
505 | TopoDS_Shell& aShSp = *((TopoDS_Shell*)&aItLShSp.Value()); |
682c9d06 |
506 | // |
093a3fe5 |
507 | if (BRep_Tool::IsClosed(aShSp)) { |
508 | aShSp.Closed(Standard_True); |
509 | myLoops.Append(aShSp); |
682c9d06 |
510 | } |
093a3fe5 |
511 | else { |
512 | aLShNC.Append(aShSp); |
682c9d06 |
513 | } |
093a3fe5 |
514 | } |
515 | // |
516 | bAllFacesTaken = (AddedFacesMap.Extent() == aNbShapes); |
517 | if (bAllFacesTaken) { |
518 | break; |
519 | } |
520 | // |
521 | if (aLShSp.Extent() == 1) { |
522 | // not further processing of not closed shells is needed, |
523 | // as it will not bring any new results |
524 | continue; |
525 | } |
a2ab2702 |
526 | // |
093a3fe5 |
527 | Standard_Integer aNbShNC = aLShNC.Extent(); |
528 | if (aNbShNC == 1) { |
529 | // try to complete the shell with other faces |
530 | aLShells.Append(aLShNC); |
531 | } |
532 | else if (aNbShNC > 1) { |
533 | // remove th faces of not closed shells from the map of processed faces |
534 | // and try to rebuild the shells using all not processed faces, |
535 | // because faces of one shell might be needed for building the other |
536 | BOPCol_ListIteratorOfListOfShape aItLShNC(aLShNC); |
537 | for (; aItLShNC.More(); aItLShNC.Next()) { |
538 | TopoDS_Iterator aItNC(aItLShNC.Value()); |
539 | for (; aItNC.More(); aItNC.Next()) { |
540 | AddedFacesMap.Remove(aItNC.Value()); |
541 | } |
542 | } |
69b558c4 |
543 | } |
544 | } |
682c9d06 |
545 | } // for (; aItF.More(); aItF.Next()) { |
546 | } |
547 | //======================================================================= |
69b558c4 |
548 | //function : RefineShell |
549 | //purpose : |
682c9d06 |
550 | //======================================================================= |
093a3fe5 |
551 | void RefineShell(TopoDS_Shell& theShell, |
552 | const BOPCol_IndexedDataMapOfShapeListOfShape& theMEF, |
553 | BOPCol_ListOfShape& theLShSp) |
69b558c4 |
554 | { |
093a3fe5 |
555 | TopoDS_Iterator aIt(theShell); |
69b558c4 |
556 | if(!aIt.More()) { |
557 | return; |
682c9d06 |
558 | } |
559 | // |
093a3fe5 |
560 | // Find edges with more than 2 adjacent faces - branch edges - |
561 | // edges on which the input shell should be split |
562 | BOPCol_MapOfShape aMEStop; |
69b558c4 |
563 | // |
093a3fe5 |
564 | Standard_Integer i, aNbMEF = theMEF.Extent(); |
565 | for (i = 1; i <= aNbMEF; ++i) { |
566 | const TopoDS_Edge& aE = TopoDS::Edge(theMEF.FindKey(i)); |
567 | const BOPCol_ListOfShape& aLF = theMEF(i); |
568 | if (aLF.Extent() > 2) { |
569 | aMEStop.Add(aE); |
570 | continue; |
571 | } |
572 | // |
573 | // check for internal edges - count faces, in which the edge |
574 | // is internal, twice |
575 | Standard_Integer aNbF = 0; |
576 | BOPCol_ListIteratorOfListOfShape aItLF(aLF); |
577 | for (; aItLF.More() && aNbF <= 2; aItLF.Next()) { |
578 | const TopoDS_Face& aF = TopoDS::Face(aItLF.Value()); |
579 | ++aNbF; |
580 | TopExp_Explorer aExp(aF, TopAbs_EDGE); |
581 | for (; aExp.More(); aExp.Next()) { |
582 | const TopoDS_Shape& aEF = aExp.Current(); |
583 | if (aEF.IsSame(aE)) { |
584 | if (aEF.Orientation() == TopAbs_INTERNAL) { |
585 | ++aNbF; |
586 | } |
587 | break; |
588 | } |
589 | } |
590 | } |
591 | // |
592 | if (aNbF > 2) { |
69b558c4 |
593 | aMEStop.Add(aE); |
594 | } |
595 | } |
596 | // |
597 | if (aMEStop.IsEmpty()) { |
093a3fe5 |
598 | theLShSp.Append(theShell); |
69b558c4 |
599 | return; |
600 | } |
601 | // |
093a3fe5 |
602 | TopoDS_Builder aBB; |
603 | TopExp_Explorer aExp; |
604 | BOPCol_IndexedMapOfShape aMFB; |
605 | BOPCol_MapOfOrientedShape aMFProcessed; |
606 | BOPCol_ListOfShape aLFP, aLFP1; |
607 | BOPCol_ListIteratorOfListOfShape aItLF, aItLFP; |
608 | // |
609 | // The first Face |
a2ab2702 |
610 | for (; aIt.More(); aIt.Next()) { |
093a3fe5 |
611 | const TopoDS_Shape& aF1 = aIt.Value(); |
a2ab2702 |
612 | if (!aMFProcessed.Add(aF1)) { |
613 | continue; |
614 | } |
615 | // |
616 | aMFB.Clear(); |
617 | aLFP.Clear(); |
618 | // |
619 | aMFB.Add(aF1); |
620 | aLFP.Append(aF1); |
621 | // |
622 | // Trying to reach the branch point |
0f04f1e1 |
623 | for (;;) { |
a2ab2702 |
624 | aItLFP.Initialize(aLFP); |
093a3fe5 |
625 | for (; aItLFP.More(); aItLFP.Next()) { |
626 | const TopoDS_Shape& aFP = aItLFP.Value(); |
69b558c4 |
627 | // |
a2ab2702 |
628 | aExp.Init(aFP, TopAbs_EDGE); |
629 | for (; aExp.More(); aExp.Next()) { |
093a3fe5 |
630 | const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current())); |
a2ab2702 |
631 | if (aMEStop.Contains(aE)) { |
69b558c4 |
632 | continue; |
633 | } |
a2ab2702 |
634 | // |
0f04f1e1 |
635 | if (aE.Orientation() == TopAbs_INTERNAL) { |
636 | continue; |
637 | } |
638 | // |
a2ab2702 |
639 | if (BRep_Tool::Degenerated(aE)) { |
69b558c4 |
640 | continue; |
641 | } |
a2ab2702 |
642 | // |
093a3fe5 |
643 | const BOPCol_ListOfShape& aLF = theMEF.FindFromKey(aE); |
a2ab2702 |
644 | // |
645 | aItLF.Initialize(aLF); |
093a3fe5 |
646 | for (; aItLF.More(); aItLF.Next()) { |
647 | const TopoDS_Shape& aFP1 = aItLF.Value(); |
a2ab2702 |
648 | if (aFP1.IsSame(aFP)) { |
649 | continue; |
650 | } |
651 | if (aMFB.Contains(aFP1)) { |
652 | continue; |
653 | } |
654 | // |
093a3fe5 |
655 | if (aMFProcessed.Add(aFP1)) { |
656 | aMFB.Add(aFP1); |
657 | aLFP1.Append(aFP1); |
658 | } |
a2ab2702 |
659 | }// for (; aItLF.More(); aItLF.Next()) { |
660 | }// for (; aExp.More(); aExp.Next()) { |
661 | } // for (; aItLFP.More(); aItLFP.Next()) { |
662 | // |
663 | // |
664 | if (aLFP1.IsEmpty()) { |
665 | break; |
666 | } |
667 | // |
668 | aLFP.Clear(); |
093a3fe5 |
669 | aLFP.Append(aLFP1); |
0f04f1e1 |
670 | }// for (;;) { |
69b558c4 |
671 | // |
093a3fe5 |
672 | Standard_Integer aNbMFB = aMFB.Extent(); |
a2ab2702 |
673 | if (aNbMFB) { |
093a3fe5 |
674 | TopoDS_Shell aShSp; |
675 | aBB.MakeShell(aShSp); |
a2ab2702 |
676 | // |
093a3fe5 |
677 | for (i = 1; i <= aNbMFB; ++i) { |
678 | const TopoDS_Shape& aFB = aMFB(i); |
679 | aBB.Add(aShSp, aFB); |
a2ab2702 |
680 | } |
093a3fe5 |
681 | theLShSp.Append(aShSp); |
682c9d06 |
682 | } |
a2ab2702 |
683 | }//for (; aIt.More(); aIt.Next()) { |
0f04f1e1 |
684 | } |
682c9d06 |
685 | //======================================================================= |
69b558c4 |
686 | //function : MakeShells |
682c9d06 |
687 | //purpose : |
688 | //======================================================================= |
689 | void BOPAlgo_ShellSplitter::MakeShells() |
690 | { |
691 | Standard_Boolean bIsRegular; |
69b558c4 |
692 | Standard_Integer aNbVCBK, k; |
682c9d06 |
693 | BOPTools_ListIteratorOfListOfConnexityBlock aItCB; |
694 | BOPCol_ListIteratorOfListOfShape aIt; |
69b558c4 |
695 | BOPAlgo_VectorOfCBK aVCBK; |
682c9d06 |
696 | // |
682c9d06 |
697 | myShells.Clear(); |
698 | // |
699 | aItCB.Initialize(myLCB); |
700 | for (; aItCB.More(); aItCB.Next()) { |
701 | BOPTools_ConnexityBlock& aCB=aItCB.ChangeValue(); |
702 | bIsRegular=aCB.IsRegular(); |
703 | if (bIsRegular) { |
704 | TopoDS_Shell aShell; |
705 | // |
706 | const BOPCol_ListOfShape& aLF=aCB.Shapes(); |
707 | MakeShell(aLF, aShell); |
ab860031 |
708 | aShell.Closed(Standard_True); |
682c9d06 |
709 | myShells.Append(aShell); |
710 | } |
711 | else { |
69b558c4 |
712 | BOPAlgo_CBK& aCBK=aVCBK.Append1(); |
713 | aCBK.SetConnexityBlock(aCB); |
682c9d06 |
714 | } |
715 | } |
716 | // |
69b558c4 |
717 | aNbVCBK=aVCBK.Extent(); |
682c9d06 |
718 | //=================================================== |
69b558c4 |
719 | BOPAlgo_CBKCnt::Perform(myRunParallel, aVCBK); |
682c9d06 |
720 | //=================================================== |
69b558c4 |
721 | for (k=0; k<aNbVCBK; ++k) { |
722 | BOPAlgo_CBK& aCBK=aVCBK(k); |
723 | const BOPTools_ConnexityBlock& aCB=aCBK.ConnexityBlock(); |
682c9d06 |
724 | const BOPCol_ListOfShape& aLS=aCB.Loops(); |
725 | aIt.Initialize(aLS); |
726 | for (; aIt.More(); aIt.Next()) { |
ab860031 |
727 | TopoDS_Shape& aShell=aIt.ChangeValue(); |
728 | aShell.Closed(Standard_True); |
682c9d06 |
729 | myShells.Append(aShell); |
730 | } |
731 | } |
732 | } |
733 | //======================================================================= |
682c9d06 |
734 | //function : MakeShell |
735 | //purpose : |
736 | //======================================================================= |
737 | void MakeShell(const BOPCol_ListOfShape& aLS, |
df80c6dd |
738 | TopoDS_Shell& aShell) |
682c9d06 |
739 | { |
740 | BRep_Builder aBB; |
741 | BOPCol_ListIteratorOfListOfShape aIt; |
742 | // |
743 | aBB.MakeShell(aShell); |
744 | // |
745 | aIt.Initialize(aLS); |
746 | for (; aIt.More(); aIt.Next()) { |
747 | const TopoDS_Shape& aF=aIt.Value(); |
748 | aBB.Add(aShell, aF); |
749 | } |
6fd4ffd9 |
750 | // |
751 | BOPTools_AlgoTools::OrientFacesOnShell(aShell); |
682c9d06 |
752 | } |
0090ae85 |
753 | //======================================================================= |
754 | // function: MapEdgesAndFaces |
755 | // purpose: |
756 | //======================================================================= |
757 | void MapEdgesAndFaces |
758 | (const TopoDS_Shape& aF, |
759 | BOPCol_IndexedDataMapOfShapeListOfShape& aMEF, |
760 | const Handle(NCollection_BaseAllocator)& theAllocator) |
761 | { |
762 | TopoDS_Iterator aItF, aItW; |
763 | // |
764 | aItF.Initialize(aF); |
765 | while (aItF.More()) { |
766 | const TopoDS_Shape& aW=aItF.Value(); |
767 | if (aW.ShapeType()!=TopAbs_WIRE) { |
768 | aItF.Next(); |
769 | continue; |
770 | } |
771 | // |
772 | aItW.Initialize(aW); |
773 | while (aItW.More()) { |
774 | const TopoDS_Shape& aE=aItW.Value(); |
775 | // |
776 | if (aMEF.Contains(aE)) { |
777 | BOPCol_ListOfShape& aLF=aMEF.ChangeFromKey(aE); |
778 | aLF.Append(aF); |
779 | } |
780 | else { |
781 | BOPCol_ListOfShape aLS(theAllocator); |
782 | // |
783 | aLS.Append(aF); |
784 | aMEF.Add(aE, aLS); |
785 | } |
786 | // |
787 | aItW.Next(); |
788 | } |
789 | // |
790 | aItF.Next(); |
791 | } |
792 | } |