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 | // |
973c2be1 |
9 | // This library is free software; you can redistribute it and / or modify it |
10 | // under the terms of the GNU Lesser General Public version 2.1 as published |
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. |
4e57c75e |
17 | |
18 | #include <BOPAlgo_BuilderSolid.ixx> |
19 | |
20 | #include <gp_Pnt2d.hxx> |
21 | #include <gp_Pln.hxx> |
22 | #include <gp_Vec.hxx> |
23 | #include <gp_Dir.hxx> |
24 | #include <gp_Pnt.hxx> |
25 | |
26 | #include <Geom_Curve.hxx> |
27 | #include <Geom_Surface.hxx> |
28 | #include <Geom2d_Curve.hxx> |
29 | |
30 | #include <TopAbs.hxx> |
31 | |
32 | #include <TopoDS_Iterator.hxx> |
33 | #include <TopoDS_Face.hxx> |
34 | #include <TopoDS_Shape.hxx> |
35 | #include <TopoDS_Shell.hxx> |
36 | #include <TopoDS_Edge.hxx> |
37 | #include <TopoDS_Solid.hxx> |
38 | #include <TopoDS_Vertex.hxx> |
39 | #include <TopoDS_Compound.hxx> |
40 | |
41 | #include <BRep_Builder.hxx> |
42 | #include <BRep_Tool.hxx> |
43 | #include <BRepTools.hxx> |
44 | #include <BRepClass3d_SolidClassifier.hxx> |
45 | |
46 | #include <TopExp.hxx> |
47 | #include <TopExp_Explorer.hxx> |
48 | // |
49 | #include <BOPTools_AlgoTools.hxx> |
50 | #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx> |
51 | #include <BOPTools.hxx> |
52 | #include <BOPCol_ListOfShape.hxx> |
53 | #include <BOPCol_MapOfOrientedShape.hxx> |
54 | // |
55 | #include <NCollection_List.hxx> |
56 | // |
57 | #include <BOPCol_DataMapOfShapeShape.hxx> |
58 | #include <BOPCol_DataMapOfShapeListOfShape.hxx> |
59 | #include <BOPInt_Context.hxx> |
60 | #include <BOPTools_CoupleOfShape.hxx> |
61 | #include <BOPCol_MapOfShape.hxx> |
62 | |
63 | static |
64 | Standard_Boolean IsGrowthShell(const TopoDS_Shape& , |
65 | const BOPCol_IndexedMapOfShape& ); |
66 | static |
67 | Standard_Boolean IsHole(const TopoDS_Shape& , |
68 | Handle(BOPInt_Context)& ); |
69 | static |
70 | Standard_Boolean IsInside(const TopoDS_Shape& , |
71 | const TopoDS_Shape& , |
72 | Handle(BOPInt_Context)& ); |
73 | static |
74 | void MakeInternalShells(const BOPCol_MapOfShape& , |
75 | BOPCol_ListOfShape& ); |
76 | |
77 | static |
78 | Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell); |
79 | |
80 | //======================================================================= |
81 | //function : |
82 | //purpose : |
83 | //======================================================================= |
84 | BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid() |
85 | : |
86 | BOPAlgo_BuilderArea() |
87 | { |
88 | } |
89 | //======================================================================= |
90 | //function : |
91 | //purpose : |
92 | //======================================================================= |
30ecd5f8 |
93 | BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid(const Handle(NCollection_BaseAllocator)& theAllocator) |
4e57c75e |
94 | : |
95 | BOPAlgo_BuilderArea(theAllocator) |
96 | { |
97 | } |
98 | //======================================================================= |
99 | //function : ~ |
100 | //purpose : |
101 | //======================================================================= |
30ecd5f8 |
102 | BOPAlgo_BuilderSolid::~BOPAlgo_BuilderSolid() |
4e57c75e |
103 | { |
104 | } |
105 | //======================================================================= |
30ecd5f8 |
106 | //function : SetSolid |
107 | //purpose : |
108 | //======================================================================= |
109 | void BOPAlgo_BuilderSolid::SetSolid(const TopoDS_Solid& aS) |
110 | { |
111 | mySolid=aS; |
112 | } |
113 | //======================================================================= |
114 | //function : Solid |
115 | //purpose : |
116 | //======================================================================= |
117 | const TopoDS_Solid& BOPAlgo_BuilderSolid::Solid()const |
118 | { |
119 | return mySolid; |
120 | } |
121 | //======================================================================= |
4e57c75e |
122 | //function : Perform |
123 | //purpose : |
124 | //======================================================================= |
30ecd5f8 |
125 | void BOPAlgo_BuilderSolid::Perform() |
4e57c75e |
126 | { |
127 | myErrorStatus=0; |
128 | // |
129 | if (myContext.IsNull()) { |
130 | //myErrorStatus=11;// Null Context |
131 | //return; |
132 | myContext=new BOPInt_Context; |
133 | } |
134 | // |
135 | TopoDS_Compound aC; |
136 | BRep_Builder aBB; |
137 | BOPCol_ListIteratorOfListOfShape aIt; |
138 | // |
139 | aBB.MakeCompound(aC); |
140 | aIt.Initialize(myShapes); |
141 | for(; aIt.More(); aIt.Next()) { |
142 | const TopoDS_Shape& aF=aIt.Value(); |
143 | aBB.Add(aC, aF); |
144 | } |
145 | // |
146 | // |
147 | PerformShapesToAvoid(); |
148 | if (myErrorStatus) { |
149 | return; |
150 | } |
151 | // |
152 | PerformLoops(); |
153 | if (myErrorStatus) { |
154 | return; |
155 | } |
156 | PerformAreas(); |
157 | if (myErrorStatus) { |
158 | return; |
159 | } |
160 | PerformInternalShapes(); |
161 | if (myErrorStatus) { |
162 | return; |
163 | } |
164 | } |
165 | //======================================================================= |
166 | //function :PerformShapesToAvoid |
167 | //purpose : |
168 | //======================================================================= |
30ecd5f8 |
169 | void BOPAlgo_BuilderSolid::PerformShapesToAvoid() |
4e57c75e |
170 | { |
171 | Standard_Boolean bFound; |
172 | Standard_Integer i, iCnt, aNbE, aNbF; |
173 | TopAbs_Orientation aOrE; |
174 | BOPCol_IndexedDataMapOfShapeListOfShape aMEF; |
175 | BOPCol_ListIteratorOfListOfShape aIt; |
176 | // |
177 | myShapesToAvoid.Clear(); |
178 | // |
179 | iCnt=0; |
302f96fb |
180 | for(;;) { |
4e57c75e |
181 | ++iCnt; |
182 | bFound=Standard_False; |
183 | // |
184 | // 1. MEF |
185 | aMEF.Clear(); |
186 | aIt.Initialize (myShapes); |
187 | for (; aIt.More(); aIt.Next()) { |
188 | const TopoDS_Shape& aF=aIt.Value(); |
189 | if (!myShapesToAvoid.Contains(aF)) { |
190 | BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF); |
191 | } |
4e57c75e |
192 | } |
193 | aNbE=aMEF.Extent(); |
194 | // |
195 | // 2. myFacesToAvoid |
196 | for (i=1; i<=aNbE; ++i) { |
197 | const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aMEF.FindKey(i))); |
198 | if (BRep_Tool::Degenerated(aE)) { |
199 | continue; |
200 | } |
201 | // |
202 | BOPCol_ListOfShape& aLF=aMEF.ChangeFromKey(aE); |
203 | aNbF=aLF.Extent(); |
204 | if (!aNbF) { |
205 | continue; |
206 | } |
207 | // |
208 | aOrE=aE.Orientation(); |
209 | // |
210 | const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First())); |
211 | if (aNbF==1) { |
212 | if (aOrE==TopAbs_INTERNAL) { |
213 | continue; |
214 | } |
215 | bFound=Standard_True; |
216 | myShapesToAvoid.Add(aF1); |
217 | } |
218 | else if (aNbF==2) { |
219 | const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last())); |
220 | if (aF2.IsSame(aF1)) { |
221 | if (BRep_Tool::IsClosed(aE, aF1)) { |
222 | continue; |
223 | } |
224 | // |
225 | if (aOrE==TopAbs_INTERNAL) { |
226 | continue; |
227 | } |
228 | // |
229 | bFound=Standard_True; |
230 | myShapesToAvoid.Add(aF1); |
231 | myShapesToAvoid.Add(aF2); |
232 | } |
233 | } |
234 | }// for (i=1; i<=aNbE; ++i) { |
235 | // |
236 | if (!bFound) { |
237 | break; |
238 | } |
239 | // |
240 | }//while (1) |
241 | } |
242 | //======================================================================= |
243 | //function : PerformLoops |
244 | //purpose : |
245 | //======================================================================= |
30ecd5f8 |
246 | void BOPAlgo_BuilderSolid::PerformLoops() |
4e57c75e |
247 | { |
248 | myErrorStatus=0; |
249 | // |
250 | myLoops.Clear(); |
251 | // |
252 | Standard_Integer aNbLF, aNbOff, aNbFP, aNbFA; |
253 | Standard_Integer i; |
254 | TopAbs_Orientation anOr; |
255 | TopoDS_Edge aEL; |
256 | BRep_Builder aBB; |
257 | TopoDS_Iterator aItS; |
258 | // |
259 | BOPCol_ListIteratorOfListOfShape aItF, aIt; |
260 | BOPCol_MapIteratorOfMapOfOrientedShape aItM; |
261 | BOPTools_CoupleOfShape aCSOff; |
262 | // |
263 | BOPCol_MapOfOrientedShape AddedFacesMap; |
264 | BOPCol_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP; |
265 | // |
266 | //================================================= |
267 | // |
268 | // 1. Shells Usual |
269 | // |
270 | aItF.Initialize (myShapes); |
271 | for (; aItF.More(); aItF.Next()) { |
272 | const TopoDS_Shape& aFF = aItF.Value(); |
273 | BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap); |
274 | } |
275 | // |
276 | aItF.Initialize (myShapes); |
277 | for (i=1; aItF.More(); aItF.Next(), ++i) { |
278 | const TopoDS_Shape& aFF = aItF.Value(); |
279 | if (myShapesToAvoid.Contains(aFF)) { |
280 | continue; |
281 | } |
282 | if (!AddedFacesMap.Add(aFF)) { |
283 | continue; |
284 | } |
285 | // |
286 | // make a new shell |
287 | TopoDS_Shell aShell; |
288 | aBB.MakeShell(aShell); |
289 | aBB.Add(aShell, aFF); |
290 | // |
291 | aMEFP.Clear(); |
292 | BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aMEFP); |
293 | // |
294 | // loop on faces added to Shell; add their neighbor faces to Shell and so on |
295 | TopoDS_Iterator aItAddedF (aShell); |
296 | for (; aItAddedF.More(); aItAddedF.Next()) { |
297 | const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItAddedF.Value())); |
298 | // |
299 | // loop on edges of aF; find a good neighbor face of aF by aE |
300 | TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE); |
301 | for (; aEdgeExp.More(); aEdgeExp.Next()) { |
302 | const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aEdgeExp.Current())); |
303 | // |
304 | //1 |
305 | if (aMEFP.Contains(aE)) { |
306 | const BOPCol_ListOfShape& aLFP=aMEFP.FindFromKey(aE); |
307 | aNbFP=aLFP.Extent(); |
308 | if (aNbFP>1) { |
309 | continue; |
310 | } |
311 | } |
312 | //2 |
313 | anOr=aE.Orientation(); |
314 | if (anOr==TopAbs_INTERNAL) { |
315 | continue; |
316 | } |
317 | //3 |
318 | if (BRep_Tool::Degenerated(aE)) { |
319 | continue; |
320 | } |
321 | // |
322 | // candidate faces list |
323 | const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE); |
324 | aNbLF=aLF.Extent(); |
325 | if (!aNbLF) { |
326 | continue; |
327 | } |
328 | // |
329 | // try to select one of neighbors |
330 | // check if a face already added to Shell shares E |
331 | Standard_Boolean bFound; |
332 | BOPCol_ListIteratorOfListOfShape aItLF; |
333 | BOPTools_ListOfCoupleOfShape aLCSOff; |
334 | // |
335 | aItLF.Initialize(aLF); |
336 | for (; aItLF.More(); aItLF.Next()) { |
337 | const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItLF.Value())); |
338 | if (myShapesToAvoid.Contains(aFL)) { |
339 | continue; |
340 | } |
341 | if (aF.IsSame(aFL)) { |
342 | continue; |
343 | } |
344 | if (AddedFacesMap.Contains(aFL)){ |
345 | continue; |
346 | } |
347 | // |
348 | bFound=BOPTools_AlgoTools::GetEdgeOff(aE, aFL, aEL); |
349 | if (!bFound) { |
350 | continue; |
351 | } |
352 | // |
353 | aCSOff.SetShape1(aEL); |
354 | aCSOff.SetShape2(aFL); |
355 | aLCSOff.Append(aCSOff); |
356 | }//for (; aItLF.More(); aItLF.Next()) { |
357 | // |
358 | aNbOff=aLCSOff.Extent(); |
359 | if (!aNbOff){ |
360 | continue; |
361 | } |
362 | // |
363 | TopoDS_Face aSelF; |
364 | if (aNbOff==1) { |
365 | aSelF=(*(TopoDS_Face*)(&aLCSOff.First().Shape2())); |
366 | } |
367 | else if (aNbOff>1){ |
368 | BOPTools_AlgoTools::GetFaceOff(aE, aF, aLCSOff, aSelF, myContext); |
369 | } |
370 | // |
371 | if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) { |
372 | aBB.Add(aShell, aSelF); |
373 | BOPTools::MapShapesAndAncestors(aSelF, TopAbs_EDGE, TopAbs_FACE, aMEFP); |
374 | } |
375 | } // for (; aEdgeExp.More(); aEdgeExp.Next()) { |
376 | } //for (; aItAddedF.More(); aItAddedF.Next()) { |
377 | // |
378 | if (IsClosedShell(aShell)) { |
379 | myLoops.Append(aShell); |
380 | } |
381 | } // for (; aItF.More(); aItF.Next()) { |
382 | |
383 | // |
384 | // Post Treatment |
385 | BOPCol_MapOfOrientedShape aMP; |
386 | // |
387 | // a. collect all edges that are in loops |
388 | aIt.Initialize (myLoops); |
389 | for (; aIt.More(); aIt.Next()) { |
390 | const TopoDS_Shape& aS=aIt.Value(); |
391 | aItS.Initialize(aS); |
392 | for (; aItS.More(); aItS.Next()) { |
393 | const TopoDS_Shape& aF=aItS.Value(); |
394 | aMP.Add(aF); |
395 | } |
396 | } |
397 | // |
398 | // b. collect all edges that are to avoid |
399 | aItM.Initialize(myShapesToAvoid); |
400 | for (; aItM.More(); aItM.Next()) { |
401 | const TopoDS_Shape& aF=aItM.Key(); |
402 | aMP.Add(aF); |
403 | } |
404 | // |
405 | // c. add all edges that are not processed to myShapesToAvoid |
406 | aIt.Initialize (myShapes); |
407 | for (; aIt.More(); aIt.Next()) { |
408 | const TopoDS_Shape& aF=aIt.Value(); |
409 | if (!aMP.Contains(aF)) { |
410 | myShapesToAvoid.Add(aF); |
411 | } |
412 | } |
413 | //================================================= |
414 | // |
415 | // 2.Internal Shells |
416 | // |
417 | myLoopsInternal.Clear(); |
418 | // |
419 | aEFMap.Clear(); |
420 | AddedFacesMap.Clear(); |
421 | // |
422 | aNbFA=myShapesToAvoid.Extent(); |
423 | // |
424 | aItM.Initialize(myShapesToAvoid); |
425 | for (; aItM.More(); aItM.Next()) { |
426 | const TopoDS_Shape& aFF=aItM.Key(); |
427 | BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap); |
428 | } |
429 | // |
430 | aItM.Initialize(myShapesToAvoid); |
431 | for (; aItM.More(); aItM.Next()) { |
432 | const TopoDS_Shape& aFF=aItM.Key(); |
433 | if (!AddedFacesMap.Add(aFF)) { |
434 | continue; |
435 | } |
436 | // |
437 | // make a new shell |
438 | TopoDS_Shell aShell; |
439 | aBB.MakeShell(aShell); |
440 | aBB.Add(aShell, aFF); |
441 | // |
442 | TopoDS_Iterator aItAddedF (aShell); |
443 | for (; aItAddedF.More(); aItAddedF.Next()) { |
444 | const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItAddedF.Value())); |
445 | // |
446 | TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE); |
447 | for (; aEdgeExp.More(); aEdgeExp.Next()) { |
448 | const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aEdgeExp.Current())); |
449 | const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE); |
450 | aItF.Initialize(aLF); |
451 | for (; aItF.More(); aItF.Next()) { |
452 | const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItF.Value())); |
453 | if (AddedFacesMap.Add(aFL)){ |
454 | aBB.Add(aShell, aFL); |
455 | } |
456 | } |
457 | } |
458 | } |
459 | myLoopsInternal.Append(aShell); |
460 | } |
461 | } |
462 | //======================================================================= |
463 | //function : PerformAreas |
464 | //purpose : |
465 | //======================================================================= |
30ecd5f8 |
466 | void BOPAlgo_BuilderSolid::PerformAreas() |
4e57c75e |
467 | { |
468 | myErrorStatus=0; |
469 | // |
470 | Standard_Boolean bIsGrowthShell, bIsHole; |
471 | BRep_Builder aBB; |
472 | TopoDS_Shape anInfinitePointShape; |
473 | BOPCol_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH; |
474 | BOPCol_ListIteratorOfListOfShape aShellIt, aSolidIt; |
475 | // |
476 | BOPCol_ListOfShape aNewSolids, aHoleShells; |
477 | BOPCol_DataMapOfShapeShape aInOutMap; |
478 | BOPCol_DataMapOfShapeListOfShape aMSH; |
479 | BOPCol_IndexedMapOfShape aMHF; |
480 | // |
481 | myAreas.Clear(); |
482 | // |
483 | // Draft solids [aNewSolids] |
484 | aShellIt.Initialize(myLoops); |
485 | for ( ; aShellIt.More(); aShellIt.Next()) { |
486 | const TopoDS_Shape& aShell = aShellIt.Value(); |
487 | // |
488 | bIsGrowthShell=IsGrowthShell(aShell, aMHF); |
489 | if (bIsGrowthShell) { |
490 | // make a growth solid from a shell |
491 | TopoDS_Solid Solid; |
492 | aBB.MakeSolid(Solid); |
493 | aBB.Add (Solid, aShell); |
494 | // |
495 | aNewSolids.Append (Solid); |
496 | } |
497 | else{ |
498 | // check if a shell is a hole |
499 | //XX |
500 | bIsHole=IsHole(aShell, myContext); |
501 | //XX |
502 | if (bIsHole) { |
503 | aHoleShells.Append(aShell); |
504 | BOPTools::MapShapes(aShell, TopAbs_FACE, aMHF); |
505 | } |
506 | else { |
507 | // make a growth solid from a shell |
508 | TopoDS_Solid Solid; |
509 | aBB.MakeSolid(Solid); |
510 | aBB.Add (Solid, aShell); |
511 | // |
512 | aNewSolids.Append (Solid); |
513 | } |
514 | } |
515 | } |
516 | // |
517 | // 2. Find outer growth shell that is most close to each hole shell |
518 | aShellIt.Initialize(aHoleShells); |
519 | for (; aShellIt.More(); aShellIt.Next()) { |
520 | const TopoDS_Shape& aHole = aShellIt.Value(); |
521 | // |
522 | aSolidIt.Initialize(aNewSolids); |
523 | for ( ; aSolidIt.More(); aSolidIt.Next()) { |
524 | const TopoDS_Shape& aSolid = aSolidIt.Value(); |
525 | // |
526 | if (!IsInside(aHole, aSolid, myContext)){ |
527 | continue; |
528 | } |
529 | // |
530 | if ( aInOutMap.IsBound (aHole)){ |
531 | const TopoDS_Shape& aSolid2 = aInOutMap(aHole); |
532 | if (IsInside(aSolid, aSolid2, myContext)) { |
533 | aInOutMap.UnBind(aHole); |
534 | aInOutMap.Bind (aHole, aSolid); |
535 | } |
536 | } |
537 | else{ |
538 | aInOutMap.Bind (aHole, aSolid); |
539 | } |
540 | } |
541 | // |
542 | // Add aHole to a map Solid/ListOfHoles [aMSH] |
543 | if (aInOutMap.IsBound(aHole)){ |
544 | const TopoDS_Shape& aSolid=aInOutMap(aHole); |
545 | if (aMSH.IsBound(aSolid)) { |
546 | BOPCol_ListOfShape& aLH=aMSH.ChangeFind(aSolid); |
547 | aLH.Append(aHole); |
548 | } |
549 | else { |
550 | BOPCol_ListOfShape aLH; |
551 | aLH.Append(aHole); |
552 | aMSH.Bind(aSolid, aLH); |
553 | } |
554 | //aBB.Add (aSolid, aHole); |
555 | } |
556 | }// for (; aShellIt.More(); aShellIt.Next()) { |
557 | // |
558 | // 3. Add aHoles to Solids |
559 | aItMSH.Initialize(aMSH); |
560 | for (; aItMSH.More(); aItMSH.Next()) { |
561 | TopoDS_Solid aSolid=(*(TopoDS_Solid*)(&aItMSH.Key())); |
562 | // |
563 | const BOPCol_ListOfShape& aLH=aItMSH.Value(); |
564 | aShellIt.Initialize(aLH); |
565 | for (; aShellIt.More(); aShellIt.Next()) { |
566 | const TopoDS_Shape& aHole = aShellIt.Value(); |
567 | aBB.Add (aSolid, aHole); |
568 | } |
569 | // |
570 | // update classifier |
571 | BRepClass3d_SolidClassifier& aSC=myContext->SolidClassifier(aSolid); |
572 | aSC.Load(aSolid); |
573 | // |
574 | } |
575 | // |
576 | // These aNewSolids are draft solids that |
577 | // do not contain any internal shapes |
578 | // |
579 | aShellIt.Initialize(aNewSolids); |
580 | for ( ; aShellIt.More(); aShellIt.Next()) { |
581 | const TopoDS_Shape& aSx = aShellIt.Value(); |
582 | myAreas.Append(aSx); |
583 | } |
584 | |
585 | // Add holes that outside the solids to myAreas |
586 | aShellIt.Initialize(aHoleShells); |
587 | for (; aShellIt.More(); aShellIt.Next()) { |
588 | const TopoDS_Shape& aHole = aShellIt.Value(); |
589 | if (!aInOutMap.IsBound(aHole)){ |
590 | TopoDS_Solid aSolid; |
591 | aBB.MakeSolid(aSolid); |
592 | aBB.Add (aSolid, aHole); |
593 | // |
594 | myAreas.Append(aSolid); |
595 | } |
596 | } |
597 | } |
598 | //======================================================================= |
599 | //function : PerformInternalShapes |
600 | //purpose : |
601 | //======================================================================= |
30ecd5f8 |
602 | void BOPAlgo_BuilderSolid::PerformInternalShapes() |
4e57c75e |
603 | { |
604 | myErrorStatus=0; |
605 | // |
606 | Standard_Integer aNbFI=myLoopsInternal.Extent(); |
607 | if (!aNbFI) {// nothing to do |
608 | return; |
609 | } |
610 | // |
611 | BRep_Builder aBB; |
612 | TopoDS_Iterator aIt; |
613 | BOPCol_ListIteratorOfListOfShape aShellIt, aSolidIt; |
614 | BOPCol_MapIteratorOfMapOfShape aItMF; |
615 | // |
616 | BOPCol_MapOfShape aMF, aMFP, aMFx; |
617 | BOPCol_IndexedDataMapOfShapeListOfShape aMEF; |
618 | BOPCol_ListOfShape aLSI; |
619 | // |
620 | // 1. All internal faces |
621 | aShellIt.Initialize(myLoopsInternal); |
622 | for (; aShellIt.More(); aShellIt.Next()) { |
623 | const TopoDS_Shape& aShell=aShellIt.Value(); |
624 | aIt.Initialize(aShell); |
625 | for (; aIt.More(); aIt.Next()) { |
626 | const TopoDS_Shape& aF=aIt.Value(); |
627 | aMF.Add(aF); |
628 | } |
629 | } |
630 | aNbFI=aMF.Extent(); |
631 | // |
632 | // 2 Process solids |
633 | aSolidIt.Initialize(myAreas); |
634 | for ( ; aSolidIt.More(); aSolidIt.Next()) { |
635 | TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aSolidIt.Value())); |
636 | // |
637 | TopExp_Explorer anExpSol(aSolid, TopAbs_FACE);; |
638 | for (; anExpSol.More(); anExpSol.Next()) { |
639 | const TopoDS_Shape& aF = anExpSol.Current(); |
640 | TopoDS_Shape aFF=aF; |
641 | // |
642 | aFF.Orientation(TopAbs_FORWARD); |
643 | aMFx.Add(aFF); |
644 | aFF.Orientation(TopAbs_REVERSED); |
645 | aMFx.Add(aFF); |
646 | } |
647 | aMEF.Clear(); |
648 | BOPTools::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMEF); |
649 | // |
650 | // 2.1 Separate faces to process aMFP |
651 | aMFP.Clear(); |
652 | aItMF.Initialize(aMF); |
653 | for (; aItMF.More(); aItMF.Next()) { |
654 | const TopoDS_Face& aF=(*(TopoDS_Face*)(&aItMF.Key())); |
655 | if (!aMFx.Contains(aF)) { |
656 | if (BOPTools_AlgoTools::IsInternalFace(aF, aSolid, aMEF, 1.e-14, myContext)) { |
657 | aMFP.Add(aF); |
658 | } |
659 | } |
660 | } |
661 | aMFx.Clear(); |
662 | // |
663 | // 2.2 Make Internal Shells |
664 | aLSI.Clear(); |
665 | MakeInternalShells(aMFP, aLSI); |
666 | // |
667 | // 2.3 Add them to aSolid |
668 | aShellIt.Initialize(aLSI); |
669 | for (; aShellIt.More(); aShellIt.Next()) { |
670 | const TopoDS_Shape& aSI=aShellIt.Value(); |
671 | aBB.Add (aSolid, aSI); |
672 | } |
673 | // |
674 | // 2.4 Remove faces aMFP from aMF |
675 | aItMF.Initialize(aMFP); |
676 | for (; aItMF.More(); aItMF.Next()) { |
677 | const TopoDS_Shape& aF=aItMF.Key(); |
678 | aMF.Remove(aF); |
679 | } |
680 | // |
681 | aNbFI=aMF.Extent(); |
682 | if (!aNbFI) { |
683 | break; |
684 | } |
685 | } //for ( ; aSolidIt.More(); aSolidIt.Next()) { |
686 | if (aNbFI) { |
687 | TopoDS_Solid aSolid; |
688 | aBB.MakeSolid(aSolid); |
689 | // |
690 | MakeInternalShells(aMF, aLSI); |
691 | aShellIt.Initialize(aLSI); |
692 | for (; aShellIt.More(); aShellIt.Next()) { |
693 | const TopoDS_Shape& aSI=aShellIt.Value(); |
694 | aBB.Add (aSolid, aSI); |
695 | } |
696 | myAreas.Append(aSolid); |
697 | } |
698 | } |
699 | |
700 | //======================================================================= |
701 | //function : MakeInternalShells |
702 | //purpose : |
703 | //======================================================================= |
704 | void MakeInternalShells(const BOPCol_MapOfShape& theMF, |
705 | BOPCol_ListOfShape& theShells) |
706 | { |
707 | BOPCol_ListIteratorOfListOfShape aItF; |
708 | BRep_Builder aBB; |
709 | // |
710 | BOPCol_IndexedDataMapOfShapeListOfShape aMEF; |
711 | BOPCol_MapIteratorOfMapOfShape aItM; |
712 | BOPCol_MapOfShape aAddedFacesMap; |
713 | // |
714 | aItM.Initialize(theMF); |
715 | for (; aItM.More(); aItM.Next()) { |
716 | const TopoDS_Shape& aF=aItM.Key(); |
717 | BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF); |
718 | } |
719 | // |
720 | aItM.Initialize(theMF); |
721 | for (; aItM.More(); aItM.Next()) { |
722 | TopoDS_Shape aFF=aItM.Key(); |
723 | if (!aAddedFacesMap.Add(aFF)) { |
724 | continue; |
725 | } |
726 | // |
727 | // make a new shell |
728 | TopoDS_Shell aShell; |
729 | aBB.MakeShell(aShell); |
730 | aFF.Orientation(TopAbs_INTERNAL); |
731 | aBB.Add(aShell, aFF); |
732 | // |
733 | TopoDS_Iterator aItAddedF (aShell); |
734 | for (; aItAddedF.More(); aItAddedF.Next()) { |
735 | const TopoDS_Shape& aF =aItAddedF.Value(); |
736 | // |
737 | TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE); |
738 | for (; aEdgeExp.More(); aEdgeExp.Next()) { |
739 | const TopoDS_Shape& aE =aEdgeExp.Current(); |
740 | const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE); |
741 | aItF.Initialize(aLF); |
742 | for (; aItF.More(); aItF.Next()) { |
743 | TopoDS_Shape aFL=aItF.Value(); |
744 | if (aAddedFacesMap.Add(aFL)){ |
745 | aFL.Orientation(TopAbs_INTERNAL); |
746 | aBB.Add(aShell, aFL); |
747 | } |
748 | } |
749 | } |
750 | } |
751 | theShells.Append(aShell); |
752 | } |
753 | } |
754 | //======================================================================= |
755 | //function : IsHole |
756 | //purpose : |
757 | //======================================================================= |
758 | Standard_Boolean IsHole(const TopoDS_Shape& theS2, |
759 | Handle(BOPInt_Context)& theContext) |
760 | { |
761 | TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2; |
762 | BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2); |
763 | // |
764 | aClsf.PerformInfinitePoint(::RealSmall()); |
765 | // |
766 | return (aClsf.State()==TopAbs_IN); |
767 | } |
768 | //======================================================================= |
769 | //function : IsInside |
770 | //purpose : |
771 | //======================================================================= |
772 | Standard_Boolean IsInside(const TopoDS_Shape& theS1, |
773 | const TopoDS_Shape& theS2, |
774 | Handle(BOPInt_Context)& theContext) |
775 | { |
776 | TopExp_Explorer aExp; |
777 | TopAbs_State aState; |
778 | // |
779 | TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2; |
780 | // |
781 | aExp.Init(theS1, TopAbs_FACE); |
782 | if (!aExp.More()){ |
783 | BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2); |
784 | aClsf.PerformInfinitePoint(::RealSmall()); |
785 | aState=aClsf.State(); |
786 | } |
787 | else { |
788 | BOPCol_IndexedMapOfShape aBounds; |
789 | BOPTools::MapShapes(*pS2, TopAbs_EDGE, aBounds); |
790 | const TopoDS_Face& aF = (*(TopoDS_Face*)(&aExp.Current())); |
791 | aState=BOPTools_AlgoTools::ComputeState(aF, *pS2, 1.e-14, aBounds, theContext); |
792 | } |
793 | return (aState==TopAbs_IN); |
794 | } |
795 | //======================================================================= |
796 | //function : IsGrowthShell |
797 | //purpose : |
798 | //======================================================================= |
799 | Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell, |
800 | const BOPCol_IndexedMapOfShape& theMHF) |
801 | { |
802 | Standard_Boolean bRet; |
803 | TopoDS_Iterator aIt; |
804 | // |
805 | bRet=Standard_False; |
806 | if (theMHF.Extent()) { |
807 | aIt.Initialize(theShell); |
808 | for(; aIt.More(); aIt.Next()) { |
809 | const TopoDS_Shape& aF=aIt.Value(); |
810 | if (theMHF.Contains(aF)) { |
811 | return !bRet; |
812 | } |
813 | } |
814 | } |
815 | return bRet; |
816 | } |
817 | //======================================================================= |
818 | //function : IsClosedShell |
819 | //purpose : |
820 | //======================================================================= |
821 | Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell) |
822 | { |
823 | Standard_Integer aNbE; |
824 | Standard_Boolean bRet; |
825 | TopoDS_Iterator aIt; |
826 | TopExp_Explorer aExp; |
827 | // |
828 | BOPCol_MapOfShape aM; |
829 | // |
830 | bRet=Standard_False; |
831 | aIt.Initialize(theShell); |
832 | for(; aIt.More(); aIt.Next()) { |
833 | const TopoDS_Face& aF=(*(TopoDS_Face*)(&aIt.Value())); |
834 | aExp.Init(aF, TopAbs_EDGE); |
835 | for (; aExp.More(); aExp.Next()) { |
836 | const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current())); |
837 | if (BRep_Tool::Degenerated(aE)) { |
838 | continue; |
839 | } |
840 | // |
841 | if (aE.Orientation()==TopAbs_INTERNAL) { |
842 | continue; |
843 | } |
844 | if (!aM.Add(aE)) { |
845 | aM.Remove(aE); |
846 | } |
847 | } |
848 | } |
849 | // |
850 | aNbE=aM.Extent(); |
851 | if (!aNbE) { |
852 | bRet=!bRet; |
853 | } |
854 | return bRet; |
855 | } |