4e57c75e |
1 | // Created by: Peter KURNEV |
973c2be1 |
2 | // Copyright (c) 2010-2014 OPEN CASCADE SAS |
4e57c75e |
3 | // Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE |
4 | // Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, |
5 | // EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS |
6 | // |
973c2be1 |
7 | // This file is part of Open CASCADE Technology software library. |
4e57c75e |
8 | // |
d5f74e42 |
9 | // This library is free software; you can redistribute it and/or modify it under |
10 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
11 | // by the Free Software Foundation, with special exception defined in the file |
12 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
13 | // distribution for complete text of the license and disclaimer of any warranty. |
4e57c75e |
14 | // |
973c2be1 |
15 | // Alternatively, this file may be used under the terms of Open CASCADE |
16 | // commercial license or contractual agreement. |
465d1fba |
17 | // |
42cf5bc1 |
18 | #include <BOPAlgo_BuilderSolid.hxx> |
19 | #include <BOPAlgo_ShellSplitter.hxx> |
20 | #include <BOPCol_BoxBndTree.hxx> |
21 | #include <BOPCol_DataMapOfShapeListOfShape.hxx> |
22 | #include <BOPCol_DataMapOfShapeShape.hxx> |
23 | #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx> |
319da2e4 |
24 | #include <BOPCol_IndexedDataMapOfShapeShape.hxx> |
42cf5bc1 |
25 | #include <BOPCol_ListOfInteger.hxx> |
26 | #include <BOPCol_ListOfShape.hxx> |
27 | #include <BOPCol_MapOfOrientedShape.hxx> |
28 | #include <BOPCol_MapOfShape.hxx> |
29 | #include <BOPCol_NCVector.hxx> |
30 | #include <BOPCol_Parallel.hxx> |
31 | #include <BOPTools.hxx> |
32 | #include <BOPTools_AlgoTools.hxx> |
33 | #include <BOPTools_AlgoTools3D.hxx> |
34 | #include <BOPTools_CoupleOfShape.hxx> |
35 | #include <BRep_Builder.hxx> |
36 | #include <BRep_Tool.hxx> |
37 | #include <BRepBndLib.hxx> |
38 | #include <BRepClass3d_SolidClassifier.hxx> |
39 | #include <Geom2d_Curve.hxx> |
40 | #include <Geom_Curve.hxx> |
41 | #include <Geom_Surface.hxx> |
4e57c75e |
42 | #include <gp_Dir.hxx> |
42cf5bc1 |
43 | #include <gp_Pln.hxx> |
4e57c75e |
44 | #include <gp_Pnt.hxx> |
42cf5bc1 |
45 | #include <gp_Pnt2d.hxx> |
46 | #include <gp_Vec.hxx> |
47 | #include <IntTools_Context.hxx> |
48 | #include <NCollection_DataMap.hxx> |
49 | #include <NCollection_IncAllocator.hxx> |
50 | #include <NCollection_List.hxx> |
51 | #include <NCollection_UBTreeFiller.hxx> |
682c9d06 |
52 | #include <TColStd_MapIntegerHasher.hxx> |
4e57c75e |
53 | #include <TopAbs.hxx> |
42cf5bc1 |
54 | #include <TopExp.hxx> |
55 | #include <TopExp_Explorer.hxx> |
56 | #include <TopoDS_Compound.hxx> |
57 | #include <TopoDS_Edge.hxx> |
4e57c75e |
58 | #include <TopoDS_Face.hxx> |
42cf5bc1 |
59 | #include <TopoDS_Iterator.hxx> |
4e57c75e |
60 | #include <TopoDS_Shape.hxx> |
61 | #include <TopoDS_Shell.hxx> |
4e57c75e |
62 | #include <TopoDS_Solid.hxx> |
63 | #include <TopoDS_Vertex.hxx> |
4e57c75e |
64 | |
42cf5bc1 |
65 | // |
4e57c75e |
66 | static |
67 | Standard_Boolean IsGrowthShell(const TopoDS_Shape& , |
68 | const BOPCol_IndexedMapOfShape& ); |
69 | static |
70 | Standard_Boolean IsHole(const TopoDS_Shape& , |
1e143abb |
71 | Handle(IntTools_Context)& ); |
4e57c75e |
72 | static |
73 | Standard_Boolean IsInside(const TopoDS_Shape& , |
74 | const TopoDS_Shape& , |
1e143abb |
75 | Handle(IntTools_Context)& ); |
4e57c75e |
76 | static |
319da2e4 |
77 | void MakeInternalShells(const BOPCol_IndexedMapOfShape& , |
4e57c75e |
78 | BOPCol_ListOfShape& ); |
79 | |
682c9d06 |
80 | //======================================================================= |
81 | //class : BOPAlgo_BuilderSolid_ShapeBox |
82 | //purpose : Auxiliary class |
83 | //======================================================================= |
84 | class BOPAlgo_BuilderSolid_ShapeBox { |
85 | public: |
86 | BOPAlgo_BuilderSolid_ShapeBox() { |
87 | myIsHole=Standard_False; |
88 | }; |
89 | // |
90 | ~BOPAlgo_BuilderSolid_ShapeBox() { |
91 | }; |
92 | // |
93 | void SetShape(const TopoDS_Shape& aS) { |
94 | myShape=aS; |
95 | }; |
96 | // |
97 | const TopoDS_Shape& Shape()const { |
98 | return myShape; |
99 | }; |
100 | // |
101 | void SetBox(const Bnd_Box& aBox) { |
102 | myBox=aBox; |
103 | }; |
104 | // |
105 | const Bnd_Box& Box()const { |
106 | return myBox; |
107 | }; |
108 | // |
109 | void SetIsHole(const Standard_Boolean bFlag) { |
110 | myIsHole=bFlag; |
111 | }; |
112 | // |
113 | Standard_Boolean IsHole()const { |
114 | return myIsHole; |
115 | }; |
116 | // |
117 | protected: |
118 | Standard_Boolean myIsHole; |
119 | TopoDS_Shape myShape; |
120 | Bnd_Box myBox; |
121 | }; |
122 | // |
465d1fba |
123 | typedef NCollection_DataMap |
124 | <Standard_Integer, |
125 | BOPAlgo_BuilderSolid_ShapeBox, |
126 | TColStd_MapIntegerHasher> BOPAlgo_DataMapOfIntegerBSSB; |
682c9d06 |
127 | // |
465d1fba |
128 | typedef BOPAlgo_DataMapOfIntegerBSSB::Iterator |
682c9d06 |
129 | BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB; |
130 | // |
4e57c75e |
131 | //======================================================================= |
465d1fba |
132 | //function : BOPAlgo_FacePnt |
133 | //purpose : |
134 | //======================================================================= |
135 | class BOPAlgo_FacePnt { |
136 | public: |
137 | BOPAlgo_FacePnt() { |
138 | } |
139 | // |
140 | virtual ~BOPAlgo_FacePnt() { |
141 | } |
142 | // |
143 | void SetFace(const TopoDS_Face& aFace) { |
144 | myFace=aFace; |
145 | } |
146 | // |
147 | const TopoDS_Face& Face()const { |
148 | return myFace; |
149 | } |
150 | // |
151 | void SetPnt(const gp_Pnt& aPnt) { |
152 | myPnt=aPnt; |
153 | } |
154 | // |
155 | const gp_Pnt& Pnt()const { |
156 | return myPnt; |
157 | } |
158 | // |
159 | protected: |
160 | gp_Pnt myPnt; |
161 | TopoDS_Face myFace; |
162 | }; |
163 | // |
164 | typedef BOPCol_NCVector |
165 | <BOPAlgo_FacePnt> BOPAlgo_VectorOfFacePnt; |
166 | // |
167 | //======================================================================= |
168 | //function : BOPAlgo_FaceSolid |
169 | //purpose : |
170 | //======================================================================= |
171 | class BOPAlgo_FaceSolid : public BOPAlgo_Algo { |
172 | public: |
173 | DEFINE_STANDARD_ALLOC |
174 | |
175 | BOPAlgo_FaceSolid() : |
176 | myIsInternalFace(Standard_False) { |
177 | } |
178 | // |
179 | virtual ~BOPAlgo_FaceSolid() { |
180 | } |
181 | // |
182 | void SetFace(const TopoDS_Face& aFace) { |
183 | myFace=aFace; |
184 | } |
185 | // |
186 | const TopoDS_Face& Face()const { |
187 | return myFace; |
188 | } |
189 | // |
190 | void SetSolid(const TopoDS_Solid& aSolid) { |
191 | mySolid=aSolid; |
192 | } |
193 | // |
194 | const TopoDS_Solid& Solid()const { |
195 | return mySolid; |
196 | } |
197 | // |
198 | void SetPnt(const gp_Pnt& aPnt) { |
199 | myPnt=aPnt; |
200 | } |
201 | // |
202 | const gp_Pnt& Pnt()const { |
203 | return myPnt; |
204 | } |
205 | void SetContext(const Handle(IntTools_Context)& aContext) { |
206 | myContext=aContext; |
207 | } |
208 | // |
209 | const Handle(IntTools_Context)& Context()const { |
210 | return myContext; |
211 | } |
212 | // |
213 | Standard_Boolean IsInternalFace() const { |
214 | return myIsInternalFace; |
215 | } |
216 | // |
217 | virtual void Perform () { |
218 | TopAbs_State aState; |
219 | // |
220 | BOPAlgo_Algo::UserBreak(); |
221 | // |
92ae0f2f |
222 | aState=BOPTools_AlgoTools::ComputeState(myPnt, mySolid, |
223 | Precision::Confusion(), |
224 | myContext); |
465d1fba |
225 | // |
226 | myIsInternalFace=(aState==TopAbs_IN); |
227 | } |
228 | // |
229 | protected: |
230 | Standard_Boolean myIsInternalFace; |
231 | gp_Pnt myPnt; |
232 | TopoDS_Face myFace; |
233 | TopoDS_Solid mySolid; |
234 | Handle(IntTools_Context) myContext; |
235 | }; |
236 | //======================================================================= |
237 | typedef BOPCol_NCVector |
238 | <BOPAlgo_FaceSolid> BOPAlgo_VectorOfFaceSolid; |
239 | // |
c7b59798 |
240 | typedef BOPCol_ContextFunctor |
465d1fba |
241 | <BOPAlgo_FaceSolid, |
242 | BOPAlgo_VectorOfFaceSolid, |
243 | Handle(IntTools_Context), |
244 | IntTools_Context> BOPAlgo_FaceSolidFunctor; |
245 | // |
c7b59798 |
246 | typedef BOPCol_ContextCnt |
465d1fba |
247 | <BOPAlgo_FaceSolidFunctor, |
248 | BOPAlgo_VectorOfFaceSolid, |
249 | Handle(IntTools_Context)> BOPAlgo_FaceSolidCnt; |
250 | // |
251 | //======================================================================= |
465d1fba |
252 | |
465d1fba |
253 | //======================================================================= |
4e57c75e |
254 | //function : |
255 | //purpose : |
256 | //======================================================================= |
682c9d06 |
257 | BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid() |
4e57c75e |
258 | : |
259 | BOPAlgo_BuilderArea() |
260 | { |
261 | } |
262 | //======================================================================= |
263 | //function : |
264 | //purpose : |
265 | //======================================================================= |
682c9d06 |
266 | BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid |
267 | (const Handle(NCollection_BaseAllocator)& theAllocator) |
4e57c75e |
268 | : |
269 | BOPAlgo_BuilderArea(theAllocator) |
270 | { |
271 | } |
272 | //======================================================================= |
273 | //function : ~ |
274 | //purpose : |
275 | //======================================================================= |
30ecd5f8 |
276 | BOPAlgo_BuilderSolid::~BOPAlgo_BuilderSolid() |
4e57c75e |
277 | { |
278 | } |
279 | //======================================================================= |
30ecd5f8 |
280 | //function : SetSolid |
281 | //purpose : |
282 | //======================================================================= |
283 | void BOPAlgo_BuilderSolid::SetSolid(const TopoDS_Solid& aS) |
284 | { |
285 | mySolid=aS; |
286 | } |
287 | //======================================================================= |
288 | //function : Solid |
289 | //purpose : |
290 | //======================================================================= |
291 | const TopoDS_Solid& BOPAlgo_BuilderSolid::Solid()const |
292 | { |
293 | return mySolid; |
294 | } |
295 | //======================================================================= |
4e57c75e |
296 | //function : Perform |
297 | //purpose : |
298 | //======================================================================= |
30ecd5f8 |
299 | void BOPAlgo_BuilderSolid::Perform() |
4e57c75e |
300 | { |
301 | myErrorStatus=0; |
302 | // |
303 | if (myContext.IsNull()) { |
1e143abb |
304 | myContext=new IntTools_Context; |
4e57c75e |
305 | } |
306 | // |
307 | TopoDS_Compound aC; |
308 | BRep_Builder aBB; |
309 | BOPCol_ListIteratorOfListOfShape aIt; |
310 | // |
311 | aBB.MakeCompound(aC); |
312 | aIt.Initialize(myShapes); |
313 | for(; aIt.More(); aIt.Next()) { |
314 | const TopoDS_Shape& aF=aIt.Value(); |
315 | aBB.Add(aC, aF); |
316 | } |
317 | // |
36f4947b |
318 | UserBreak(); |
4e57c75e |
319 | // |
320 | PerformShapesToAvoid(); |
321 | if (myErrorStatus) { |
322 | return; |
323 | } |
324 | // |
36f4947b |
325 | UserBreak(); |
326 | // |
4e57c75e |
327 | PerformLoops(); |
328 | if (myErrorStatus) { |
329 | return; |
330 | } |
36f4947b |
331 | // |
332 | UserBreak(); |
333 | // |
4e57c75e |
334 | PerformAreas(); |
335 | if (myErrorStatus) { |
336 | return; |
337 | } |
36f4947b |
338 | // |
339 | UserBreak(); |
340 | // |
4e57c75e |
341 | PerformInternalShapes(); |
342 | if (myErrorStatus) { |
343 | return; |
344 | } |
345 | } |
346 | //======================================================================= |
347 | //function :PerformShapesToAvoid |
348 | //purpose : |
349 | //======================================================================= |
30ecd5f8 |
350 | void BOPAlgo_BuilderSolid::PerformShapesToAvoid() |
4e57c75e |
351 | { |
352 | Standard_Boolean bFound; |
353 | Standard_Integer i, iCnt, aNbE, aNbF; |
354 | TopAbs_Orientation aOrE; |
355 | BOPCol_IndexedDataMapOfShapeListOfShape aMEF; |
356 | BOPCol_ListIteratorOfListOfShape aIt; |
357 | // |
358 | myShapesToAvoid.Clear(); |
359 | // |
360 | iCnt=0; |
302f96fb |
361 | for(;;) { |
4e57c75e |
362 | ++iCnt; |
363 | bFound=Standard_False; |
364 | // |
365 | // 1. MEF |
366 | aMEF.Clear(); |
367 | aIt.Initialize (myShapes); |
368 | for (; aIt.More(); aIt.Next()) { |
369 | const TopoDS_Shape& aF=aIt.Value(); |
370 | if (!myShapesToAvoid.Contains(aF)) { |
465d1fba |
371 | BOPTools::MapShapesAndAncestors(aF, |
372 | TopAbs_EDGE, |
373 | TopAbs_FACE, |
374 | aMEF); |
4e57c75e |
375 | } |
4e57c75e |
376 | } |
377 | aNbE=aMEF.Extent(); |
378 | // |
379 | // 2. myFacesToAvoid |
380 | for (i=1; i<=aNbE; ++i) { |
381 | const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aMEF.FindKey(i))); |
382 | if (BRep_Tool::Degenerated(aE)) { |
383 | continue; |
384 | } |
385 | // |
386 | BOPCol_ListOfShape& aLF=aMEF.ChangeFromKey(aE); |
387 | aNbF=aLF.Extent(); |
388 | if (!aNbF) { |
389 | continue; |
390 | } |
391 | // |
392 | aOrE=aE.Orientation(); |
393 | // |
394 | const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First())); |
395 | if (aNbF==1) { |
396 | if (aOrE==TopAbs_INTERNAL) { |
397 | continue; |
398 | } |
399 | bFound=Standard_True; |
400 | myShapesToAvoid.Add(aF1); |
401 | } |
402 | else if (aNbF==2) { |
403 | const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last())); |
404 | if (aF2.IsSame(aF1)) { |
405 | if (BRep_Tool::IsClosed(aE, aF1)) { |
406 | continue; |
407 | } |
408 | // |
409 | if (aOrE==TopAbs_INTERNAL) { |
410 | continue; |
411 | } |
412 | // |
413 | bFound=Standard_True; |
414 | myShapesToAvoid.Add(aF1); |
415 | myShapesToAvoid.Add(aF2); |
416 | } |
417 | } |
418 | }// for (i=1; i<=aNbE; ++i) { |
419 | // |
420 | if (!bFound) { |
421 | break; |
422 | } |
423 | // |
682c9d06 |
424 | }//for(;;) { |
4e57c75e |
425 | } |
426 | //======================================================================= |
427 | //function : PerformLoops |
428 | //purpose : |
429 | //======================================================================= |
30ecd5f8 |
430 | void BOPAlgo_BuilderSolid::PerformLoops() |
4e57c75e |
431 | { |
319da2e4 |
432 | Standard_Integer iErr, i, aNbSh; |
682c9d06 |
433 | BOPCol_ListIteratorOfListOfShape aIt; |
4e57c75e |
434 | TopoDS_Iterator aItS; |
0090ae85 |
435 | Handle(NCollection_BaseAllocator) aAlr; |
682c9d06 |
436 | // |
437 | myErrorStatus=0; |
438 | myLoops.Clear(); |
4e57c75e |
439 | // |
0090ae85 |
440 | aAlr=new NCollection_IncAllocator(); |
441 | BOPAlgo_ShellSplitter aSSp(aAlr); |
442 | // |
4e57c75e |
443 | // 1. Shells Usual |
682c9d06 |
444 | aIt.Initialize (myShapes); |
445 | for (; aIt.More(); aIt.Next()) { |
f47b8d2b |
446 | const TopoDS_Face& aF=*((TopoDS_Face*)&aIt.Value()); |
447 | if (myContext->IsInfiniteFace(aF)) { |
448 | TopoDS_Shell aSh; |
449 | BRep_Builder aBB; |
450 | // |
451 | aBB.MakeShell(aSh); |
452 | aBB.Add(aSh, aF); |
453 | myLoops.Append(aSh); |
454 | continue; |
455 | } |
456 | // |
682c9d06 |
457 | if (!myShapesToAvoid.Contains(aF)) { |
458 | aSSp.AddStartElement(aF); |
459 | } |
460 | } |
4e57c75e |
461 | // |
682c9d06 |
462 | aSSp.SetRunParallel(myRunParallel); |
463 | aSSp.Perform(); |
464 | iErr=aSSp.ErrorStatus(); |
465 | if (iErr) { |
466 | return; |
4e57c75e |
467 | } |
468 | // |
682c9d06 |
469 | const BOPCol_ListOfShape& aLSh=aSSp.Shells(); |
470 | aIt.Initialize (aLSh); |
471 | for (; aIt.More(); aIt.Next()) { |
472 | const TopoDS_Shape& aSh=aIt.Value(); |
473 | myLoops.Append(aSh); |
474 | } |
475 | //================================================= |
4e57c75e |
476 | // |
682c9d06 |
477 | // 2. Post Treatment |
682c9d06 |
478 | BRep_Builder aBB; |
479 | BOPCol_MapOfOrientedShape AddedFacesMap; |
480 | BOPCol_IndexedDataMapOfShapeListOfShape aEFMap; |
4e57c75e |
481 | BOPCol_MapOfOrientedShape aMP; |
682c9d06 |
482 | // |
4e57c75e |
483 | // a. collect all edges that are in loops |
484 | aIt.Initialize (myLoops); |
485 | for (; aIt.More(); aIt.Next()) { |
486 | const TopoDS_Shape& aS=aIt.Value(); |
487 | aItS.Initialize(aS); |
488 | for (; aItS.More(); aItS.Next()) { |
489 | const TopoDS_Shape& aF=aItS.Value(); |
490 | aMP.Add(aF); |
491 | } |
492 | } |
493 | // |
494 | // b. collect all edges that are to avoid |
319da2e4 |
495 | aNbSh = myShapesToAvoid.Extent(); |
496 | for (i = 1; i <= aNbSh; ++i) { |
497 | const TopoDS_Shape& aF = myShapesToAvoid(i); |
4e57c75e |
498 | aMP.Add(aF); |
499 | } |
500 | // |
501 | // c. add all edges that are not processed to myShapesToAvoid |
502 | aIt.Initialize (myShapes); |
503 | for (; aIt.More(); aIt.Next()) { |
f47b8d2b |
504 | const TopoDS_Face& aF=*((TopoDS_Face*)&aIt.Value()); |
505 | if (!myContext->IsInfiniteFace(aF)) { |
506 | if (!aMP.Contains(aF)) { |
507 | myShapesToAvoid.Add(aF); |
508 | } |
4e57c75e |
509 | } |
510 | } |
511 | //================================================= |
512 | // |
682c9d06 |
513 | // 3.Internal Shells |
4e57c75e |
514 | myLoopsInternal.Clear(); |
515 | // |
516 | aEFMap.Clear(); |
517 | AddedFacesMap.Clear(); |
518 | // |
319da2e4 |
519 | aNbSh = myShapesToAvoid.Extent(); |
520 | for (i = 1; i <= aNbSh; ++i) { |
521 | const TopoDS_Shape& aFF = myShapesToAvoid(i); |
682c9d06 |
522 | BOPTools::MapShapesAndAncestors(aFF, |
1e143abb |
523 | TopAbs_EDGE, TopAbs_FACE, |
524 | aEFMap); |
4e57c75e |
525 | } |
526 | // |
319da2e4 |
527 | for (i = 1; i <= aNbSh; ++i) { |
528 | const TopoDS_Shape& aFF = myShapesToAvoid(i); |
4e57c75e |
529 | if (!AddedFacesMap.Add(aFF)) { |
530 | continue; |
531 | } |
532 | // |
533 | // make a new shell |
0090ae85 |
534 | TopExp_Explorer aExp; |
4e57c75e |
535 | TopoDS_Shell aShell; |
536 | aBB.MakeShell(aShell); |
537 | aBB.Add(aShell, aFF); |
538 | // |
0090ae85 |
539 | aItS.Initialize(aShell); |
540 | for (; aItS.More(); aItS.Next()) { |
541 | const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItS.Value())); |
4e57c75e |
542 | // |
0090ae85 |
543 | aExp.Init(aF, TopAbs_EDGE); |
544 | for (; aExp.More(); aExp.Next()) { |
545 | const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current())); |
4e57c75e |
546 | const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE); |
682c9d06 |
547 | aIt.Initialize(aLF); |
548 | for (; aIt.More(); aIt.Next()) { |
549 | const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aIt.Value())); |
4e57c75e |
550 | if (AddedFacesMap.Add(aFL)){ |
551 | aBB.Add(aShell, aFL); |
552 | } |
553 | } |
554 | } |
555 | } |
ab860031 |
556 | aShell.Closed (BRep_Tool::IsClosed (aShell)); |
4e57c75e |
557 | myLoopsInternal.Append(aShell); |
558 | } |
559 | } |
560 | //======================================================================= |
561 | //function : PerformAreas |
562 | //purpose : |
563 | //======================================================================= |
30ecd5f8 |
564 | void BOPAlgo_BuilderSolid::PerformAreas() |
4e57c75e |
565 | { |
682c9d06 |
566 | Standard_Boolean bIsGrowth, bIsHole; |
319da2e4 |
567 | Standard_Integer i, k, aNbInOut, aNbMSH; |
4e57c75e |
568 | BRep_Builder aBB; |
682c9d06 |
569 | BOPCol_ListIteratorOfListOfShape aItLS; |
4e57c75e |
570 | BOPCol_ListOfShape aNewSolids, aHoleShells; |
319da2e4 |
571 | BOPCol_IndexedDataMapOfShapeShape aInOutMap; |
4e57c75e |
572 | BOPCol_IndexedMapOfShape aMHF; |
682c9d06 |
573 | BOPCol_ListIteratorOfListOfInteger aItLI; |
574 | BOPCol_BoxBndTreeSelector aSelector; |
575 | BOPCol_BoxBndTree aBBTree; |
465d1fba |
576 | NCollection_UBTreeFiller |
577 | <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree); |
682c9d06 |
578 | BOPAlgo_DataMapOfIntegerBSSB aDMISB(100); |
319da2e4 |
579 | BOPCol_IndexedDataMapOfShapeListOfShape aMSH; |
682c9d06 |
580 | BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB aItDMISB; |
682c9d06 |
581 | // |
582 | myErrorStatus=0; |
4e57c75e |
583 | // |
584 | myAreas.Clear(); |
585 | // |
586 | // Draft solids [aNewSolids] |
682c9d06 |
587 | aItLS.Initialize(myLoops); |
588 | for (k=0; aItLS.More(); aItLS.Next(), ++k) { |
589 | TopoDS_Solid aSolid; |
590 | Bnd_Box aBox; |
591 | BOPAlgo_BuilderSolid_ShapeBox aSB; |
592 | // |
593 | const TopoDS_Shape& aShell = aItLS.Value(); |
594 | aSB.SetShape(aShell); |
595 | // |
596 | BRepBndLib::Add(aShell, aBox); |
597 | bIsHole=Standard_False; |
4e57c75e |
598 | // |
682c9d06 |
599 | bIsGrowth=IsGrowthShell(aShell, aMHF); |
600 | if (bIsGrowth) { |
4e57c75e |
601 | // make a growth solid from a shell |
682c9d06 |
602 | aBB.MakeSolid(aSolid); |
603 | aBB.Add (aSolid, aShell); |
4e57c75e |
604 | // |
682c9d06 |
605 | aNewSolids.Append (aSolid); |
606 | aSB.SetShape(aSolid); |
4e57c75e |
607 | } |
608 | else{ |
609 | // check if a shell is a hole |
4e57c75e |
610 | bIsHole=IsHole(aShell, myContext); |
4e57c75e |
611 | if (bIsHole) { |
612 | aHoleShells.Append(aShell); |
613 | BOPTools::MapShapes(aShell, TopAbs_FACE, aMHF); |
1e143abb |
614 | aSB.SetShape(aShell); |
4e57c75e |
615 | } |
616 | else { |
617 | // make a growth solid from a shell |
682c9d06 |
618 | aBB.MakeSolid(aSolid); |
619 | aBB.Add (aSolid, aShell); |
4e57c75e |
620 | // |
682c9d06 |
621 | aNewSolids.Append (aSolid); |
1e143abb |
622 | aSB.SetShape(aSolid); |
4e57c75e |
623 | } |
624 | } |
682c9d06 |
625 | // |
626 | aSB.SetBox(aBox); |
627 | aSB.SetIsHole(bIsHole); |
628 | aDMISB.Bind(k, aSB); |
629 | } |
630 | // |
631 | // 2. Prepare TreeFiller |
632 | aItDMISB.Initialize(aDMISB); |
633 | for (; aItDMISB.More(); aItDMISB.Next()) { |
634 | k=aItDMISB.Key(); |
635 | const BOPAlgo_BuilderSolid_ShapeBox& aSB=aItDMISB.Value(); |
636 | // |
637 | bIsHole=aSB.IsHole(); |
638 | if (bIsHole) { |
639 | const Bnd_Box& aBox=aSB.Box(); |
640 | aTreeFiller.Add(k, aBox); |
641 | } |
4e57c75e |
642 | } |
643 | // |
682c9d06 |
644 | // 3. Shake TreeFiller |
645 | aTreeFiller.Fill(); |
646 | // |
647 | // 4. Find outer growth shell that is most close |
648 | // to each hole shell |
649 | aItDMISB.Initialize(aDMISB); |
650 | for (; aItDMISB.More(); aItDMISB.Next()) { |
651 | k=aItDMISB.Key(); |
652 | const BOPAlgo_BuilderSolid_ShapeBox& aSB=aItDMISB.Value(); |
653 | bIsHole=aSB.IsHole(); |
654 | if (bIsHole) { |
655 | continue; |
656 | } |
657 | // |
658 | const TopoDS_Shape aSolid=aSB.Shape(); |
659 | const Bnd_Box& aBoxSolid=aSB.Box(); |
4e57c75e |
660 | // |
682c9d06 |
661 | aSelector.Clear(); |
662 | aSelector.SetBox(aBoxSolid); |
663 | // |
bcf50875 |
664 | aBBTree.Select(aSelector); |
682c9d06 |
665 | // |
666 | const BOPCol_ListOfInteger& aLI=aSelector.Indices(); |
667 | // |
668 | aItLI.Initialize(aLI); |
669 | for (; aItLI.More(); aItLI.Next()) { |
670 | k=aItLI.Value(); |
671 | const BOPAlgo_BuilderSolid_ShapeBox& aSBk=aDMISB.Find(k); |
672 | const TopoDS_Shape& aHole=aSBk.Shape(); |
4e57c75e |
673 | // |
674 | if (!IsInside(aHole, aSolid, myContext)){ |
675 | continue; |
676 | } |
677 | // |
319da2e4 |
678 | if (aInOutMap.Contains (aHole)){ |
679 | const TopoDS_Shape& aSolidWas = aInOutMap.FindFromKey(aHole); |
e83c01bf |
680 | if (IsInside(aSolid, aSolidWas, myContext)) { |
319da2e4 |
681 | aInOutMap.ChangeFromKey(aHole) = aSolid; |
4e57c75e |
682 | } |
683 | } |
684 | else{ |
319da2e4 |
685 | aInOutMap.Add(aHole, aSolid); |
4e57c75e |
686 | } |
687 | } |
319da2e4 |
688 | }//for (i = 1; i <= aNbDMISB; ++i) { |
682c9d06 |
689 | // |
690 | // 5. Map [Solid/Holes] -> aMSH |
319da2e4 |
691 | aNbInOut = aInOutMap.Extent(); |
692 | for (i = 1; i <= aNbInOut; ++i) { |
693 | const TopoDS_Shape& aHole = aInOutMap.FindKey(i); |
694 | const TopoDS_Shape& aSolid = aInOutMap(i); |
4e57c75e |
695 | // |
319da2e4 |
696 | if (aMSH.Contains(aSolid)) { |
697 | BOPCol_ListOfShape& aLH = aMSH.ChangeFromKey(aSolid); |
682c9d06 |
698 | aLH.Append(aHole); |
699 | } |
700 | else { |
701 | BOPCol_ListOfShape aLH; |
702 | aLH.Append(aHole); |
319da2e4 |
703 | aMSH.Add(aSolid, aLH); |
4e57c75e |
704 | } |
682c9d06 |
705 | } |
4e57c75e |
706 | // |
682c9d06 |
707 | // 6. Add aHoles to Solids |
319da2e4 |
708 | aNbMSH = aMSH.Extent(); |
709 | for (i = 1; i <= aNbMSH; ++i) { |
710 | TopoDS_Solid aSolid=(*(TopoDS_Solid*)(&(aMSH.FindKey(i)))); |
711 | const BOPCol_ListOfShape& aLH = aMSH(i); |
4e57c75e |
712 | // |
682c9d06 |
713 | aItLS.Initialize(aLH); |
714 | for (; aItLS.More(); aItLS.Next()) { |
715 | const TopoDS_Shape& aHole = aItLS.Value(); |
4e57c75e |
716 | aBB.Add (aSolid, aHole); |
717 | } |
718 | // |
719 | // update classifier |
682c9d06 |
720 | BRepClass3d_SolidClassifier& aSC= |
721 | myContext->SolidClassifier(aSolid); |
4e57c75e |
722 | aSC.Load(aSolid); |
723 | // |
724 | } |
725 | // |
682c9d06 |
726 | // 7. These aNewSolids are draft solids that |
4e57c75e |
727 | // do not contain any internal shapes |
682c9d06 |
728 | aItLS.Initialize(aNewSolids); |
729 | for ( ; aItLS.More(); aItLS.Next()) { |
730 | const TopoDS_Shape& aSx=aItLS.Value(); |
4e57c75e |
731 | myAreas.Append(aSx); |
732 | } |
4e57c75e |
733 | // Add holes that outside the solids to myAreas |
682c9d06 |
734 | aItLS.Initialize(aHoleShells); |
735 | for (; aItLS.More(); aItLS.Next()) { |
736 | const TopoDS_Shape& aHole = aItLS.Value(); |
319da2e4 |
737 | if (!aInOutMap.Contains(aHole)){ |
4e57c75e |
738 | TopoDS_Solid aSolid; |
682c9d06 |
739 | // |
4e57c75e |
740 | aBB.MakeSolid(aSolid); |
741 | aBB.Add (aSolid, aHole); |
742 | // |
743 | myAreas.Append(aSolid); |
744 | } |
745 | } |
746 | } |
747 | //======================================================================= |
748 | //function : PerformInternalShapes |
749 | //purpose : |
750 | //======================================================================= |
30ecd5f8 |
751 | void BOPAlgo_BuilderSolid::PerformInternalShapes() |
4e57c75e |
752 | { |
753 | myErrorStatus=0; |
754 | // |
755 | Standard_Integer aNbFI=myLoopsInternal.Extent(); |
756 | if (!aNbFI) {// nothing to do |
757 | return; |
758 | } |
759 | // |
465d1fba |
760 | Standard_Boolean bIsInternalFace; |
bcf50875 |
761 | Standard_Integer k, aNbVFS, aNbSLF, aNbVFP, aNbA; |
4e57c75e |
762 | BRep_Builder aBB; |
763 | TopoDS_Iterator aIt; |
465d1fba |
764 | TopExp_Explorer aExp; |
765 | BOPCol_ListIteratorOfListOfShape aItLS; |
319da2e4 |
766 | BOPCol_IndexedMapOfShape aMFs; |
4e57c75e |
767 | BOPCol_ListOfShape aLSI; |
465d1fba |
768 | BOPAlgo_VectorOfFaceSolid aVFS; |
769 | BOPAlgo_VectorOfFacePnt aVFP; |
770 | BOPCol_ListIteratorOfListOfInteger aItLI; |
771 | BOPCol_BoxBndTreeSelector aSelector; |
772 | BOPCol_BoxBndTree aBBTree; |
773 | NCollection_UBTreeFiller |
774 | <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree); |
775 | // |
776 | aNbA=myAreas.Extent(); |
4e57c75e |
777 | // |
465d1fba |
778 | // 1. aVFP |
779 | aItLS.Initialize(myLoopsInternal); |
780 | for (; aItLS.More(); aItLS.Next()) { |
781 | const TopoDS_Shape& aShell=aItLS.Value(); |
4e57c75e |
782 | aIt.Initialize(aShell); |
783 | for (; aIt.More(); aIt.Next()) { |
465d1fba |
784 | const TopoDS_Face& aF=*((TopoDS_Face*)&aIt.Value()); |
785 | // |
319da2e4 |
786 | if (!aMFs.Contains(aF)) { |
787 | aMFs.Add(aF); |
788 | // |
465d1fba |
789 | gp_Pnt aP; |
790 | gp_Pnt2d aP2D; |
791 | // |
792 | if (aNbA) { |
793 | BOPTools_AlgoTools3D::PointInFace(aF, aP, aP2D, myContext); |
794 | } |
795 | // |
796 | BOPAlgo_FacePnt& aFP=aVFP.Append1(); |
797 | aFP.SetFace(aF); |
798 | aFP.SetPnt(aP); |
799 | } |
4e57c75e |
800 | } |
801 | } |
4e57c75e |
802 | // |
465d1fba |
803 | if (!aNbA) { |
804 | // 7b. "Rest" faces treatment |
805 | TopoDS_Solid aSolid; |
806 | aBB.MakeSolid(aSolid); |
4e57c75e |
807 | // |
465d1fba |
808 | MakeInternalShells(aMFs, aLSI); |
809 | // |
810 | aItLS.Initialize(aLSI); |
811 | for (; aItLS.More(); aItLS.Next()) { |
812 | const TopoDS_Shape& aSI=aItLS.Value(); |
813 | aBB.Add (aSolid, aSI); |
4e57c75e |
814 | } |
465d1fba |
815 | myAreas.Append(aSolid); |
4e57c75e |
816 | // |
465d1fba |
817 | return; // => |
818 | }//if (!aNbA) { |
819 | // |
820 | // 2. Prepare TreeFiller |
821 | aNbVFP=aVFP.Extent(); |
822 | for(k=0; k<aNbVFP; ++k) { |
823 | Bnd_Box aBox; |
824 | // |
825 | const BOPAlgo_FacePnt& aFP=aVFP(k); |
826 | const TopoDS_Face& aF=aFP.Face(); |
827 | // |
828 | BRepBndLib::Add(aF, aBox); |
829 | aTreeFiller.Add(k, aBox); |
830 | } |
831 | // |
832 | aTreeFiller.Fill(); |
833 | // |
834 | // 3. Face/Solid candidates: aVFS |
835 | aItLS.Initialize(myAreas); |
836 | for (; aItLS.More(); aItLS.Next()) { |
837 | Bnd_Box aBox; |
838 | // |
839 | TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aItLS.Value())); |
840 | BRepBndLib::Add(aSolid, aBox); |
841 | // |
842 | aMFs.Clear(); |
843 | aExp.Init(aSolid, TopAbs_FACE); |
844 | for (; aExp.More(); aExp.Next()) { |
845 | const TopoDS_Shape& aFs=aExp.Current(); |
846 | aMFs.Add(aFs); |
847 | } |
848 | // |
849 | aSelector.Clear(); |
850 | aSelector.SetBox(aBox); |
851 | // |
bcf50875 |
852 | aBBTree.Select(aSelector); |
465d1fba |
853 | // |
854 | const BOPCol_ListOfInteger& aLI=aSelector.Indices(); |
855 | aItLI.Initialize(aLI); |
856 | for (; aItLI.More(); aItLI.Next()) { |
857 | k=aItLI.Value(); |
858 | const BOPAlgo_FacePnt& aFP=aVFP(k); |
859 | const TopoDS_Face& aF=aFP.Face(); |
860 | if (aMFs.Contains(aF)) { |
861 | continue; |
4e57c75e |
862 | } |
465d1fba |
863 | // |
864 | const gp_Pnt& aP=aFP.Pnt(); |
865 | // |
866 | BOPAlgo_FaceSolid& aFS=aVFS.Append1(); |
867 | aFS.SetPnt(aP); |
868 | aFS.SetFace(aF); |
869 | aFS.SetSolid(aSolid); |
4e57c75e |
870 | } |
465d1fba |
871 | } |
872 | // |
873 | aNbVFS=aVFS.Extent(); |
874 | if (!aNbVFS) { |
875 | return; |
876 | } |
877 | // 4. Refine candidares |
878 | //============================================================= |
879 | BOPAlgo_FaceSolidCnt::Perform(myRunParallel, aVFS, myContext); |
880 | //============================================================= |
881 | // |
882 | // 5. Solid/Faces: aMSLF |
883 | BOPCol_IndexedDataMapOfShapeListOfShape aMSLF; |
884 | BOPCol_MapOfShape aMFProcessed; |
885 | // |
886 | for (k=0; k < aNbVFS; ++k) { |
887 | const BOPAlgo_FaceSolid& aFS=aVFS(k); |
4e57c75e |
888 | // |
465d1fba |
889 | const TopoDS_Solid& aSolid=aFS.Solid(); |
890 | const TopoDS_Face& aF=aFS.Face(); |
4e57c75e |
891 | // |
465d1fba |
892 | bIsInternalFace=aFS.IsInternalFace(); |
893 | if (!bIsInternalFace) { |
894 | continue; |
4e57c75e |
895 | } |
896 | // |
465d1fba |
897 | if (aMSLF.Contains(aSolid)) { |
898 | BOPCol_ListOfShape& aLF=aMSLF.ChangeFromKey(aSolid); |
899 | aLF.Append(aF); |
900 | } |
901 | else { |
902 | BOPCol_ListOfShape aLF; |
903 | // |
904 | aLF.Append(aF); |
905 | aMSLF.Add(aSolid, aLF); |
4e57c75e |
906 | } |
465d1fba |
907 | }// for (k=0; k < aNbVE; ++k) { |
908 | // |
909 | // 6. Update Solids by internal Faces |
910 | aNbSLF=aMSLF.Extent(); |
911 | for (k=1; k <= aNbSLF; ++k) { |
912 | const TopoDS_Shape& aSolid=aMSLF.FindKey(k); |
913 | TopoDS_Shape *pSolid=(TopoDS_Shape*)&aSolid; |
4e57c75e |
914 | // |
465d1fba |
915 | const BOPCol_ListOfShape& aLF=aMSLF(k); |
916 | // |
917 | aMFs.Clear(); |
918 | aItLS.Initialize(aLF); |
919 | for (; aItLS.More(); aItLS.Next()) { |
920 | const TopoDS_Shape& aF=aItLS.Value(); |
921 | aMFs.Add(aF); |
922 | aMFProcessed.Add(aF); |
4e57c75e |
923 | } |
465d1fba |
924 | // |
925 | aLSI.Clear(); |
926 | MakeInternalShells(aMFs, aLSI); |
927 | // |
928 | aItLS.Initialize(aLSI); |
929 | for (; aItLS.More(); aItLS.Next()) { |
930 | const TopoDS_Shape& aSI=aItLS.Value(); |
931 | aBB.Add (*pSolid, aSI); |
932 | } |
933 | } |
934 | // |
935 | // 7. "Rest" faces treatment (if there are) |
936 | aMFs.Clear(); |
937 | for (k=0; k < aNbVFS; ++k) { |
938 | const BOPAlgo_FaceSolid& aFS=aVFS(k); |
939 | // |
940 | const TopoDS_Face& aF=aFS.Face(); |
941 | if (!aMFProcessed.Contains(aF)) { |
942 | aMFs.Add(aF); |
943 | } |
944 | } |
945 | // |
946 | aNbFI=aMFs.Extent(); |
4e57c75e |
947 | if (aNbFI) { |
948 | TopoDS_Solid aSolid; |
949 | aBB.MakeSolid(aSolid); |
950 | // |
465d1fba |
951 | aLSI.Clear(); |
952 | MakeInternalShells(aMFs, aLSI); |
953 | // |
954 | aItLS.Initialize(aLSI); |
955 | for (; aItLS.More(); aItLS.Next()) { |
956 | const TopoDS_Shape& aSI=aItLS.Value(); |
4e57c75e |
957 | aBB.Add (aSolid, aSI); |
958 | } |
959 | myAreas.Append(aSolid); |
960 | } |
961 | } |
4e57c75e |
962 | //======================================================================= |
963 | //function : MakeInternalShells |
964 | //purpose : |
965 | //======================================================================= |
319da2e4 |
966 | void MakeInternalShells(const BOPCol_IndexedMapOfShape& theMF, |
4e57c75e |
967 | BOPCol_ListOfShape& theShells) |
968 | { |
319da2e4 |
969 | Standard_Integer i, aNbF; |
4e57c75e |
970 | BRep_Builder aBB; |
319da2e4 |
971 | BOPCol_ListIteratorOfListOfShape aItF; |
4e57c75e |
972 | BOPCol_IndexedDataMapOfShapeListOfShape aMEF; |
4e57c75e |
973 | BOPCol_MapOfShape aAddedFacesMap; |
974 | // |
319da2e4 |
975 | aNbF = theMF.Extent(); |
976 | for (i = 1; i <= aNbF; ++i) { |
977 | TopoDS_Shape aF = theMF(i); |
682c9d06 |
978 | BOPTools::MapShapesAndAncestors(aF, |
1e143abb |
979 | TopAbs_EDGE, TopAbs_FACE, |
980 | aMEF); |
4e57c75e |
981 | } |
982 | // |
319da2e4 |
983 | for (i = 1; i <= aNbF; ++i) { |
984 | TopoDS_Shape aFF = theMF(i); |
4e57c75e |
985 | if (!aAddedFacesMap.Add(aFF)) { |
986 | continue; |
987 | } |
988 | // |
989 | // make a new shell |
990 | TopoDS_Shell aShell; |
991 | aBB.MakeShell(aShell); |
992 | aFF.Orientation(TopAbs_INTERNAL); |
993 | aBB.Add(aShell, aFF); |
994 | // |
995 | TopoDS_Iterator aItAddedF (aShell); |
996 | for (; aItAddedF.More(); aItAddedF.Next()) { |
997 | const TopoDS_Shape& aF =aItAddedF.Value(); |
998 | // |
999 | TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE); |
1000 | for (; aEdgeExp.More(); aEdgeExp.Next()) { |
1001 | const TopoDS_Shape& aE =aEdgeExp.Current(); |
1002 | const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE); |
1003 | aItF.Initialize(aLF); |
1004 | for (; aItF.More(); aItF.Next()) { |
1005 | TopoDS_Shape aFL=aItF.Value(); |
1006 | if (aAddedFacesMap.Add(aFL)){ |
1007 | aFL.Orientation(TopAbs_INTERNAL); |
1008 | aBB.Add(aShell, aFL); |
1009 | } |
1010 | } |
1011 | } |
1012 | } |
ab860031 |
1013 | aShell.Closed (BRep_Tool::IsClosed (aShell)); |
4e57c75e |
1014 | theShells.Append(aShell); |
1015 | } |
1016 | } |
1017 | //======================================================================= |
1018 | //function : IsHole |
1019 | //purpose : |
1020 | //======================================================================= |
1021 | Standard_Boolean IsHole(const TopoDS_Shape& theS2, |
1e143abb |
1022 | Handle(IntTools_Context)& theContext) |
4e57c75e |
1023 | { |
1024 | TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2; |
1025 | BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2); |
1026 | // |
1027 | aClsf.PerformInfinitePoint(::RealSmall()); |
1028 | // |
1029 | return (aClsf.State()==TopAbs_IN); |
1030 | } |
1031 | //======================================================================= |
1032 | //function : IsInside |
1033 | //purpose : |
1034 | //======================================================================= |
1035 | Standard_Boolean IsInside(const TopoDS_Shape& theS1, |
1036 | const TopoDS_Shape& theS2, |
1e143abb |
1037 | Handle(IntTools_Context)& theContext) |
4e57c75e |
1038 | { |
1039 | TopExp_Explorer aExp; |
1040 | TopAbs_State aState; |
1041 | // |
1042 | TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2; |
1043 | // |
1044 | aExp.Init(theS1, TopAbs_FACE); |
1045 | if (!aExp.More()){ |
1046 | BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2); |
1047 | aClsf.PerformInfinitePoint(::RealSmall()); |
1048 | aState=aClsf.State(); |
1049 | } |
1050 | else { |
1051 | BOPCol_IndexedMapOfShape aBounds; |
1052 | BOPTools::MapShapes(*pS2, TopAbs_EDGE, aBounds); |
1053 | const TopoDS_Face& aF = (*(TopoDS_Face*)(&aExp.Current())); |
92ae0f2f |
1054 | aState=BOPTools_AlgoTools::ComputeState(aF, *pS2, |
1055 | Precision::Confusion(), |
1e143abb |
1056 | aBounds, theContext); |
4e57c75e |
1057 | } |
1058 | return (aState==TopAbs_IN); |
1059 | } |
1060 | //======================================================================= |
1061 | //function : IsGrowthShell |
1062 | //purpose : |
1063 | //======================================================================= |
1064 | Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell, |
1065 | const BOPCol_IndexedMapOfShape& theMHF) |
1066 | { |
1067 | Standard_Boolean bRet; |
1068 | TopoDS_Iterator aIt; |
1069 | // |
1070 | bRet=Standard_False; |
1071 | if (theMHF.Extent()) { |
1072 | aIt.Initialize(theShell); |
1073 | for(; aIt.More(); aIt.Next()) { |
1074 | const TopoDS_Shape& aF=aIt.Value(); |
1075 | if (theMHF.Contains(aF)) { |
1076 | return !bRet; |
1077 | } |
1078 | } |
1079 | } |
1080 | return bRet; |
1081 | } |