1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2014 OPEN CASCADE SAS
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 //
7 // This file is part of Open CASCADE Technology software library.
8 //
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
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.
14 //
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
17 //
18 #include <BOPAlgo_Builder.hxx>
19 //
20 #include <Precision.hxx>
21 //
22 #include <Bnd_Box.hxx>
23 #include <TopAbs_State.hxx>
24 //
25 #include <TopoDS.hxx>
26 #include <TopoDS_AlertWithShape.hxx>
27 #include <TopoDS_Iterator.hxx>
28 #include <TopoDS_Solid.hxx>
29 #include <TopoDS_Shape.hxx>
30 #include <TopoDS_Face.hxx>
31 #include <TopoDS_Edge.hxx>
32 #include <TopoDS_Solid.hxx>
33 #include <TopoDS_Shell.hxx>
34 #include <TopoDS_Compound.hxx>
35 //
36 #include <TopExp.hxx>
37 #include <TopExp_Explorer.hxx>
38 //
39 #include <BRep_Builder.hxx>
40 //
41 #include <BOPAlgo_Tools.hxx>
42 #include <BOPAlgo_BuilderSolid.hxx>
43 //
44 #include <IntTools_Context.hxx>
45 //
46 #include <BOPDS_DS.hxx>
47 #include <BOPDS_ShapeInfo.hxx>
48 //
49 #include <BOPTools_AlgoTools.hxx>
50 #include <BOPTools_MapOfSet.hxx>
51 #include <BOPTools_Set.hxx>
52 #include <BOPTools_Parallel.hxx>
53 //
54 #include <BOPAlgo_Tools.hxx>
55 #include <NCollection_Array1.hxx>
56 #include <NCollection_IncAllocator.hxx>
57 #include <NCollection_Vector.hxx>
58
59 #include <TopTools_IndexedMapOfShape.hxx>
60 #include <TopTools_MapOfShape.hxx>
61 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
62 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
63 #include <TopTools_ListOfShape.hxx>
64
65 #include <algorithm>
66
67 static
68 void OwnInternalShapes(const TopoDS_Shape& ,
69 TopTools_IndexedMapOfShape& );
70
71
72 //=======================================================================
73 //function : FillImagesSolids
74 //purpose :
75 //=======================================================================
FillImagesSolids(const Message_ProgressRange & theRange)76 void BOPAlgo_Builder::FillImagesSolids(const Message_ProgressRange& theRange)
77 {
78 Standard_Integer i = 0, aNbS = myDS->NbSourceShapes();
79 for (i = 0; i < aNbS; ++i) {
80 const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
81 if (aSI.ShapeType() == TopAbs_SOLID)
82 {
83 break;
84 }
85 }
86 if (i >= aNbS) {
87 return;
88 }
89
90 Message_ProgressScope aPS(theRange, "Building splits of solids", 10);
91 // Draft solids
92 TopTools_DataMapOfShapeShape aDraftSolids;
93 // Find all IN faces for all IN faces
94 FillIn3DParts(aDraftSolids, aPS.Next(4));
95 if (HasErrors())
96 {
97 return;
98 }
99 // Build split of the solids
100 BuildSplitSolids(aDraftSolids, aPS.Next(5));
101 if (HasErrors())
102 {
103 return;
104 }
105 // Fill solids with internal parts
106 FillInternalShapes(aPS.Next());
107 }
108 //=======================================================================
109 //function : FillIn3DParts
110 //purpose :
111 //=======================================================================
FillIn3DParts(TopTools_DataMapOfShapeShape & theDraftSolids,const Message_ProgressRange & theRange)112 void BOPAlgo_Builder::FillIn3DParts(TopTools_DataMapOfShapeShape& theDraftSolids,
113 const Message_ProgressRange& theRange)
114 {
115 Message_ProgressScope aPS(theRange, NULL, 2);
116
117 Handle(NCollection_BaseAllocator) anAlloc = new NCollection_IncAllocator;
118
119 // Find all faces that are IN solids
120
121 // Store boxes of the shapes into a map
122 TopTools_DataMapOfShapeBox aShapeBoxMap(1, anAlloc);
123
124 // Fence map
125 TopTools_MapOfShape aMFence(1, anAlloc);
126
127 // Get all faces
128 TopTools_ListOfShape aLFaces(anAlloc);
129
130 Standard_Integer i, aNbS = myDS->NbSourceShapes();
131 for (i = 0; i < aNbS; ++i)
132 {
133 const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
134 if (aSI.ShapeType() != TopAbs_FACE)
135 continue;
136
137 if (UserBreak(aPS))
138 {
139 return;
140 }
141
142 const TopoDS_Shape& aS = aSI.Shape();
143 const TopTools_ListOfShape* pLSIm = myImages.Seek(aS);
144
145 if (pLSIm)
146 {
147 TopTools_ListIteratorOfListOfShape aItLSIm(*pLSIm);
148 for (; aItLSIm.More(); aItLSIm.Next())
149 {
150 const TopoDS_Shape& aSIm = aItLSIm.Value();
151 if (aMFence.Add(aSIm))
152 aLFaces.Append(aSIm);
153 }
154 }
155 else
156 {
157 aLFaces.Append(aS);
158 aShapeBoxMap.Bind(aS, aSI.Box());
159 }
160 }
161
162 BRep_Builder aBB;
163
164 // Get all solids
165 TopTools_ListOfShape aLSolids(anAlloc);
166 // Keep INTERNAL faces of the solids
167 TopTools_DataMapOfShapeListOfShape aSolidsIF(1, anAlloc);
168 // Draft solids
169 TopTools_IndexedDataMapOfShapeShape aDraftSolid(1, anAlloc);
170
171 for (i = 0; i < aNbS; ++i)
172 {
173 BOPDS_ShapeInfo& aSI = myDS->ChangeShapeInfo(i);
174 if (aSI.ShapeType() != TopAbs_SOLID)
175 {
176 continue;
177 }
178 if (UserBreak(aPS))
179 {
180 return;
181 }
182 const TopoDS_Shape& aS = aSI.Shape();
183 const TopoDS_Solid& aSolid = (*(TopoDS_Solid*)(&aS));
184 //
185 // Bounding box for the solid aS
186 Bnd_Box& aBoxS = aSI.ChangeBox();
187 if (aBoxS.IsVoid())
188 myDS->BuildBndBoxSolid(i, aBoxS, myCheckInverted);
189
190 // Build Draft Solid
191 TopTools_ListOfShape aLIF;
192 TopoDS_Solid aSD;
193 aBB.MakeSolid(aSD);
194 BuildDraftSolid(aSolid, aSD, aLIF);
195
196 aLSolids.Append(aSD);
197 aSolidsIF.Bind(aSD, aLIF);
198 aShapeBoxMap.Bind(aSD, aBoxS);
199 aDraftSolid.Add(aS, aSD);
200 }
201
202 // Perform classification of the faces
203 TopTools_IndexedDataMapOfShapeListOfShape anInParts;
204
205 BOPAlgo_Tools::ClassifyFaces(aLFaces, aLSolids, myRunParallel,
206 myContext, anInParts, aShapeBoxMap,
207 aSolidsIF, aPS.Next());
208
209 // Analyze the results of classification
210 Standard_Integer aNbSol = aDraftSolid.Extent();
211 for (i = 1; i <= aNbSol; ++i)
212 {
213 if (UserBreak(aPS))
214 {
215 return;
216 }
217 const TopoDS_Solid& aSolid = TopoDS::Solid(aDraftSolid.FindKey(i));
218 const TopoDS_Solid& aSDraft = TopoDS::Solid(aDraftSolid(i));
219 const TopTools_ListOfShape& aLInFaces = anInParts.FindFromKey(aSDraft);
220 const TopTools_ListOfShape& aLInternal = aSolidsIF.Find(aSDraft);
221
222 Standard_Integer aNbIN = aLInFaces.Extent();
223
224 if (!aNbIN)
225 {
226 Standard_Boolean bHasImage = Standard_False;
227 // Check if the shells of the solid have image
228 for (TopoDS_Iterator it(aSolid); it.More() && !bHasImage; it.Next())
229 bHasImage = myImages.IsBound(it.Value());
230
231 if (!bHasImage)
232 // no need to split the solid
233 continue;
234 }
235
236 theDraftSolids.Bind(aSolid, aSDraft);
237
238 Standard_Integer aNbInt = aLInternal.Extent();
239 if (aNbInt || aNbIN)
240 {
241 // Combine the lists
242 TopTools_ListOfShape *pLIN = myInParts.Bound(aSolid, TopTools_ListOfShape());
243
244 TopTools_ListIteratorOfListOfShape aItLS(aLInFaces);
245 for (; aItLS.More(); aItLS.Next())
246 pLIN->Append(aItLS.Value());
247
248 aItLS.Initialize(aLInternal);
249 for (; aItLS.More(); aItLS.Next())
250 pLIN->Append(aItLS.Value());
251 }
252 }
253 }
254 //=======================================================================
255 //function : BuildDraftSolid
256 //purpose :
257 //=======================================================================
BuildDraftSolid(const TopoDS_Shape & theSolid,TopoDS_Shape & theDraftSolid,TopTools_ListOfShape & theLIF)258 void BOPAlgo_Builder::BuildDraftSolid(const TopoDS_Shape& theSolid,
259 TopoDS_Shape& theDraftSolid,
260 TopTools_ListOfShape& theLIF)
261 {
262 Standard_Boolean bToReverse;
263 Standard_Integer iFlag;
264 TopAbs_Orientation aOrF, aOrSh, aOrSd;
265 TopoDS_Iterator aIt1, aIt2;
266 TopoDS_Shell aShD;
267 TopoDS_Shape aFx;
268 BRep_Builder aBB;
269 TopTools_ListIteratorOfListOfShape aItS;
270 //
271 aOrSd=theSolid.Orientation();
272 theDraftSolid.Orientation(aOrSd);
273 //
274 aIt1.Initialize(theSolid);
275 for (; aIt1.More(); aIt1.Next()) {
276 const TopoDS_Shape& aSh=aIt1.Value();
277 if(aSh.ShapeType()!=TopAbs_SHELL) {
278 continue; // mb internal edges,vertices
279 }
280 //
281 aOrSh=aSh.Orientation();
282 aBB.MakeShell(aShD);
283 aShD.Orientation(aOrSh);
284 iFlag=0;
285 //
286 aIt2.Initialize(aSh);
287 for (; aIt2.More(); aIt2.Next()) {
288 const TopoDS_Shape& aF=aIt2.Value();
289 aOrF=aF.Orientation();
290 //
291 if (myImages.IsBound(aF)) {
292 const TopTools_ListOfShape& aLSp=myImages.Find(aF);
293 aItS.Initialize(aLSp);
294 for (; aItS.More(); aItS.Next()) {
295 aFx=aItS.Value();
296 //
297 if (myShapesSD.IsBound(aFx)) {
298 //
299 if (aOrF==TopAbs_INTERNAL) {
300 aFx.Orientation(aOrF);
301 theLIF.Append(aFx);
302 }
303 else {
304 bToReverse=BOPTools_AlgoTools::IsSplitToReverseWithWarn
305 (aFx, aF, myContext, myReport);
306 if (bToReverse) {
307 aFx.Reverse();
308 }
309 //
310 iFlag=1;
311 aBB.Add(aShD, aFx);
312 }
313 }//if (myShapesSD.IsBound(aFx)) {
314 else {
315 aFx.Orientation(aOrF);
316 if (aOrF==TopAbs_INTERNAL) {
317 theLIF.Append(aFx);
318 }
319 else{
320 iFlag=1;
321 aBB.Add(aShD, aFx);
322 }
323 }
324 }
325 } // if (myImages.IsBound(aF)) {
326 //
327 else {
328 if (aOrF==TopAbs_INTERNAL) {
329 theLIF.Append(aF);
330 }
331 else{
332 iFlag=1;
333 aBB.Add(aShD, aF);
334 }
335 }
336 } //for (; aIt2.More(); aIt2.Next()) {
337 //
338 if (iFlag) {
339 aShD.Closed (BRep_Tool::IsClosed (aShD));
340 aBB.Add(theDraftSolid, aShD);
341 }
342 } //for (; aIt1.More(); aIt1.Next()) {
343 }
344
345 //=======================================================================
346
347 //=======================================================================
348 //class : BOPAlgo_SplitSolid
349 //purpose : Auxiliary class to extend the BOPAlgo_BuilderSolid with the solid to split
350 //=======================================================================
351 class BOPAlgo_SplitSolid : public BOPAlgo_BuilderSolid
352 {
353 public:
354 //! Sets the solid
SetSolid(const TopoDS_Solid & theSolid)355 void SetSolid(const TopoDS_Solid& theSolid) { mySolid = theSolid; }
356
357 //! Returns the solid
Solid() const358 const TopoDS_Solid& Solid() const { return mySolid; }
359
360 //! Sets progress range
SetProgressRange(const Message_ProgressRange & theRange)361 void SetProgressRange(const Message_ProgressRange& theRange)
362 {
363 myRange = theRange;
364 }
365
366 // New perform method, using own progress range
Perform()367 void Perform()
368 {
369 Message_ProgressScope aPS(myRange, NULL, 1);
370 if (!aPS.More())
371 {
372 return;
373 }
374 BOPAlgo_BuilderSolid::Perform(aPS.Next());
375 }
376
377 private:
378 //! Disable the range enabled method
Perform(const Message_ProgressRange &)379 virtual void Perform(const Message_ProgressRange&/* theRange*/) {}
380
381 private:
382 TopoDS_Solid mySolid; //!< Solid to split
383 Message_ProgressRange myRange;
384 };
385
386 // Vector of Solid Builders
387 typedef NCollection_Vector<BOPAlgo_SplitSolid> BOPAlgo_VectorOfBuilderSolid;
388
389 //=======================================================================
390 //function : BuildSplitSolids
391 //purpose :
392 //=======================================================================
BuildSplitSolids(TopTools_DataMapOfShapeShape & theDraftSolids,const Message_ProgressRange & theRange)393 void BOPAlgo_Builder::BuildSplitSolids(TopTools_DataMapOfShapeShape& theDraftSolids,
394 const Message_ProgressRange& theRange)
395 {
396 Standard_Boolean bFlagSD;
397 Standard_Integer i, aNbS;
398 TopExp_Explorer aExp;
399 TopTools_ListIteratorOfListOfShape aIt;
400 //
401 Handle(NCollection_BaseAllocator) aAlr0;
402 aAlr0=NCollection_BaseAllocator::CommonBaseAllocator();
403 //
404 TopTools_ListOfShape aSFS(aAlr0), aLSEmpty(aAlr0);
405 TopTools_MapOfShape aMFence(100, aAlr0);
406 BOPTools_MapOfSet aMST(100, aAlr0);
407 BOPAlgo_VectorOfBuilderSolid aVBS;
408 //
409 Message_ProgressScope aPSOuter (theRange, NULL, 10);
410 // 0. Find same domain solids for non-interfered solids
411 aNbS=myDS->NbSourceShapes();
412 for (i=0; i<aNbS; ++i) {
413 const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
414 //
415 if (aSI.ShapeType()!=TopAbs_SOLID) {
416 continue;
417 }
418 if (UserBreak(aPSOuter))
419 {
420 return;
421 }
422 //
423 const TopoDS_Shape& aS=aSI.Shape();
424 if (!aMFence.Add(aS)) {
425 continue;
426 }
427 if(theDraftSolids.IsBound(aS)) {
428 continue;
429 }
430 //
431 BOPTools_Set aST;
432 //
433 aST.Add(aS, TopAbs_FACE);
434 aMST.Add(aST);
435 //
436 } //for (i=1; i<=aNbS; ++i)
437 //
438 // Build temporary map of solids images to avoid rebuilding
439 // of the solids without internal faces
440 TopTools_IndexedDataMapOfShapeListOfShape aSolidsIm;
441 // 1. Build solids for interfered source solids
442 for (i = 0; i < aNbS; ++i) {
443 const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
444 if (aSI.ShapeType() != TopAbs_SOLID)
445 continue;
446
447 const TopoDS_Shape& aS = aSI.Shape();
448 const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS));
449 if (!theDraftSolids.IsBound(aS))
450 continue;
451
452 const TopoDS_Shape& aSD = theDraftSolids.Find(aS);
453 const TopTools_ListOfShape* pLFIN = myInParts.Seek(aS);
454 if (!pLFIN || pLFIN->IsEmpty())
455 {
456 aSolidsIm(aSolidsIm.Add(aS, TopTools_ListOfShape())).Append(aSD);
457 continue;
458 }
459
460 aSFS.Clear();
461 //
462 // 1.1 Fill Shell Faces Set
463 aExp.Init(aSD, TopAbs_FACE);
464 for (; aExp.More(); aExp.Next()) {
465 const TopoDS_Shape& aF = aExp.Current();
466 aSFS.Append(aF);
467 }
468 //
469 // 1.2 Fill internal faces
470 aIt.Initialize(*pLFIN);
471 for (; aIt.More(); aIt.Next()) {
472 TopoDS_Shape aF = aIt.Value();
473 //
474 aF.Orientation(TopAbs_FORWARD);
475 aSFS.Append(aF);
476 aF.Orientation(TopAbs_REVERSED);
477 aSFS.Append(aF);
478 }
479 //
480 // 1.3 Build new solids
481 BOPAlgo_SplitSolid& aBS=aVBS.Appended();
482 aBS.SetSolid(aSolid);
483 aBS.SetShapes(aSFS);
484 aBS.SetRunParallel(myRunParallel);
485 }//for (i=0; i<aNbS; ++i) {
486 //
487 Standard_Integer k, aNbBS;
488 //
489 aNbBS=aVBS.Length();
490 // Set progress range for each task to be run in parallel
491 Message_ProgressScope aPSParallel(aPSOuter.Next(9), "Splitting solids", aNbBS);
492 for (Standard_Integer iS = 0; iS < aNbBS; iS++)
493 {
494 BOPAlgo_SplitSolid& aSplitSolid = aVBS.ChangeValue(iS);
495 aSplitSolid.SetProgressRange(aPSParallel.Next());
496 }
497 //
498 //===================================================
499 BOPTools_Parallel::Perform (myRunParallel, aVBS);
500 //===================================================
501 if (UserBreak(aPSOuter))
502 {
503 return;
504 }
505 //
506 for (k = 0; k < aNbBS; ++k)
507 {
508 BOPAlgo_SplitSolid& aBS = aVBS(k);
509 aSolidsIm.Add(aBS.Solid(), aBS.Areas());
510
511 // Merge BuilderSolid's report into main report,
512 // assigning the solid with the warnings/errors which
513 // have been generated for it.
514 // Convert all errors of BuilderSolid into warnings for main report.
515 const Handle(Message_Report)& aBSReport = aBS.GetReport();
516 Message_Gravity anAlertTypes[2] = { Message_Warning, Message_Fail };
517 for (Standard_Integer iGravity = 0; iGravity < 2; iGravity++)
518 {
519 const Message_ListOfAlert& anLAlerts = aBSReport->GetAlerts(anAlertTypes[iGravity]);
520 for (Message_ListOfAlert::Iterator itA(anLAlerts); itA.More(); itA.Next())
521 {
522 Handle(Message_Alert) anAlert = itA.Value();
523
524 Handle(TopoDS_AlertWithShape) anAlertWithShape = Handle(TopoDS_AlertWithShape)::DownCast(itA.Value());
525 if (!anAlertWithShape.IsNull())
526 {
527 TopoDS_Shape aWarnShape;
528 BRep_Builder().MakeCompound(TopoDS::Compound(aWarnShape));
529 BRep_Builder().Add(aWarnShape, aBS.Solid());
530 BRep_Builder().Add(aWarnShape, anAlertWithShape->GetShape());
531
532 anAlertWithShape->SetShape(aWarnShape);
533 AddWarning(anAlertWithShape);
534 }
535 else
536 AddWarning(anAlert);
537 }
538 }
539 }
540 //
541 // Add new solids to images map
542 aNbBS = aSolidsIm.Extent();
543 for (k = 1; k <= aNbBS; ++k)
544 {
545 const TopoDS_Shape& aS = aSolidsIm.FindKey(k);
546 const TopTools_ListOfShape& aLSR = aSolidsIm(k);
547 //
548 if (!myImages.IsBound(aS)) {
549 TopTools_ListOfShape* pLSx = myImages.Bound(aS, TopTools_ListOfShape());
550 //
551 aIt.Initialize(aLSR);
552 for (; aIt.More(); aIt.Next()) {
553 BOPTools_Set aST;
554 //
555 const TopoDS_Shape& aSR=aIt.Value();
556 aST.Add(aSR, TopAbs_FACE);
557 //
558 bFlagSD=aMST.Contains(aST);
559 //
560 const BOPTools_Set& aSTx=aMST.Added(aST);
561 const TopoDS_Shape& aSx=aSTx.Shape();
562 pLSx->Append(aSx);
563 //
564 TopTools_ListOfShape* pLOr = myOrigins.ChangeSeek(aSx);
565 if (!pLOr) {
566 pLOr = myOrigins.Bound(aSx, TopTools_ListOfShape());
567 }
568 pLOr->Append(aS);
569 //
570 if (bFlagSD) {
571 myShapesSD.Bind(aSR, aSx);
572 }
573 }
574 }
575 }
576 }
577 //=======================================================================
578 //function :FillInternalShapes
579 //purpose :
580 //=======================================================================
FillInternalShapes(const Message_ProgressRange & theRange)581 void BOPAlgo_Builder::FillInternalShapes(const Message_ProgressRange& theRange)
582 {
583 Standard_Integer i, j, aNbS, aNbSI, aNbSx;
584 TopAbs_ShapeEnum aType;
585 TopAbs_State aState;
586 TopoDS_Iterator aItS;
587 BRep_Builder aBB;
588 TopTools_ListIteratorOfListOfShape aIt, aIt1;
589 //
590 Handle(NCollection_BaseAllocator) aAllocator;
591 //-----------------------------------------------------scope f
592 aAllocator=NCollection_BaseAllocator::CommonBaseAllocator();
593 //
594 TopTools_IndexedDataMapOfShapeListOfShape aMSx(100, aAllocator);
595 TopTools_IndexedMapOfShape aMx(100, aAllocator);
596 TopTools_IndexedMapOfShape aMSI(100, aAllocator);
597 TopTools_MapOfShape aMFence(100, aAllocator);
598 TopTools_MapOfShape aMSOr(100, aAllocator);
599 TopTools_ListOfShape aLSd(aAllocator);
600 TopTools_ListOfShape aLArgs(aAllocator);
601 TopTools_ListOfShape aLSC(aAllocator);
602 TopTools_ListOfShape aLSI(aAllocator);
603
604 Message_ProgressScope aPS(theRange, NULL, 10);
605 //
606 // 1. Shapes to process
607 //
608 // 1.1 Shapes from pure arguments aMSI
609 // 1.1.1 vertex, edge, wire
610 //
611 const TopTools_ListOfShape& aArguments=myDS->Arguments();
612 aIt.Initialize(aArguments);
613 for (; aIt.More(); aIt.Next()) {
614 const TopoDS_Shape& aS=aIt.Value();
615 BOPTools_AlgoTools::TreatCompound(aS, aLSC, &aMFence);
616 }
617 aIt.Initialize(aLSC);
618 for (; aIt.More(); aIt.Next()) {
619 const TopoDS_Shape& aS=aIt.Value();
620 aType=aS.ShapeType();
621 if (aType==TopAbs_WIRE) {
622 aItS.Initialize(aS);
623 for(; aItS.More(); aItS.Next()) {
624 const TopoDS_Shape& aE=aItS.Value();
625 if (aMFence.Add(aE)) {
626 aLArgs.Append(aE);
627 }
628 }
629 }
630 else if (aType==TopAbs_VERTEX || aType==TopAbs_EDGE){
631 aLArgs.Append(aS);
632 }
633 }
634 aMFence.Clear();
635 //
636 aIt.Initialize(aLArgs);
637 for (; aIt.More(); aIt.Next()) {
638 const TopoDS_Shape& aS=aIt.Value();
639 aType=aS.ShapeType();
640 if (aType==TopAbs_VERTEX ||
641 aType==TopAbs_EDGE ||
642 aType==TopAbs_WIRE) {
643 if (aMFence.Add(aS)) {
644 if (myImages.IsBound(aS)) {
645 const TopTools_ListOfShape &aLSp=myImages.Find(aS);
646 aIt1.Initialize(aLSp);
647 for (; aIt1.More(); aIt1.Next()) {
648 const TopoDS_Shape& aSp=aIt1.Value();
649 aMSI.Add(aSp);
650 }
651 }
652 else {
653 aMSI.Add(aS);
654 }
655 }
656 }
657 }
658 if (UserBreak(aPS))
659 {
660 return;
661 }
662
663 aNbSI=aMSI.Extent();
664 //
665 // 2. Internal vertices, edges from source solids
666 aMFence.Clear();
667 aLSd.Clear();
668 //
669 aNbS=myDS->NbSourceShapes();
670 for (i=0; i<aNbS; ++i) {
671 const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
672 //
673 if (aSI.ShapeType()!=TopAbs_SOLID) {
674 continue;
675 }
676 if (UserBreak(aPS))
677 {
678 return;
679 }
680 //
681 const TopoDS_Shape& aS=aSI.Shape();
682 //
683 aMx.Clear();
684 OwnInternalShapes(aS, aMx);
685 //
686 aNbSx=aMx.Extent();
687 for (j=1; j<=aNbSx; ++j) {
688 const TopoDS_Shape& aSi=aMx(j);
689 if (myImages.IsBound(aSi)) {
690 const TopTools_ListOfShape &aLSp=myImages.Find(aSi);
691 aIt1.Initialize(aLSp);
692 for (; aIt1.More(); aIt1.Next()) {
693 const TopoDS_Shape& aSp=aIt1.Value();
694 aMSI.Add(aSp);
695 }
696 }
697 else {
698 aMSI.Add(aSi);
699 }
700 }
701 //
702 // build aux map from splits of solids
703 if (myImages.IsBound(aS)) {
704 const TopTools_ListOfShape &aLSp=myImages.Find(aS);
705 aIt.Initialize(aLSp);
706 for (; aIt.More(); aIt.Next()) {
707 const TopoDS_Shape& aSp=aIt.Value();
708 if (aMFence.Add(aSp)) {
709 TopExp::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_EDGE, aMSx);
710 TopExp::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_FACE, aMSx);
711 TopExp::MapShapesAndAncestors(aSp, TopAbs_EDGE , TopAbs_FACE, aMSx);
712 aLSd.Append(aSp);
713 }
714 }
715 }
716 else {
717 if (aMFence.Add(aS)) {
718 TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aMSx);
719 TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aMSx);
720 TopExp::MapShapesAndAncestors(aS, TopAbs_EDGE , TopAbs_FACE, aMSx);
721 aLSd.Append(aS);
722 aMSOr.Add(aS);
723 }
724 }
725 }// for (i=0; i<aNbS; ++i) {
726 //
727 // 3. Some shapes of aMSI can be already tied with faces of
728 // split solids
729 aNbSI = aMSI.Extent();
730 for (i = 1; i <= aNbSI; ++i) {
731 const TopoDS_Shape& aSI = aMSI(i);
732 if (aMSx.Contains(aSI)) {
733 const TopTools_ListOfShape &aLSx=aMSx.FindFromKey(aSI);
734 aNbSx = aLSx.Extent();
735 if (!aNbSx) {
736 aLSI.Append(aSI);
737 }
738 }
739 else {
740 aLSI.Append(aSI);
741 }
742 }
743 //
744 // 4. Just check it
745 aNbSI = aLSI.Extent();
746 if (!aNbSI) {
747 return;
748 }
749
750 aPS.Next();
751 //
752 // 5 Settle internal vertices and edges into solids
753 aMx.Clear();
754
755 Message_ProgressScope aPSLoop(aPS.Next(9), "Looking for internal shapes", aLSd.Size());
756
757 aIt.Initialize(aLSd);
758 for (; aIt.More(); aIt.Next(), aPSLoop.Next()) {
759 TopoDS_Solid aSd=TopoDS::Solid(aIt.Value());
760 //
761 aIt1.Initialize(aLSI);
762 for (; aIt1.More();) {
763 TopoDS_Shape aSI = aIt1.Value();
764 aSI.Orientation(TopAbs_INTERNAL);
765 //
766 aState=BOPTools_AlgoTools::ComputeStateByOnePoint
767 (aSI, aSd, 1.e-11, myContext);
768 //
769 if (aState != TopAbs_IN) {
770 aIt1.Next();
771 continue;
772 }
773 //
774 if (aMSOr.Contains(aSd)) {
775 // make new solid
776 TopoDS_Solid aSdx;
777 //
778 aBB.MakeSolid(aSdx);
779 aItS.Initialize(aSd);
780 for (; aItS.More(); aItS.Next()) {
781 const TopoDS_Shape& aSh=aItS.Value();
782 aBB.Add(aSdx, aSh);
783 }
784 //
785 aBB.Add(aSdx, aSI);
786 //
787 // no need to check for images of aSd as aMSOr contains only original solids
788 TopTools_ListOfShape* pLS = myImages.Bound(aSd, TopTools_ListOfShape());
789 pLS->Append(aSdx);
790 //
791 TopTools_ListOfShape* pLOr = myOrigins.Bound(aSdx, TopTools_ListOfShape());
792 pLOr->Append(aSd);
793 //
794 aMSOr.Remove(aSd);
795 aSd=aSdx;
796 }
797 else {
798 aBB.Add(aSd, aSI);
799 }
800 //
801 aLSI.Remove(aIt1);
802 }//for (; aIt1.More();) {
803 }//for (; aIt.More(); aIt.Next()) {
804 //
805 //-----------------------------------------------------scope t
806 aLArgs.Clear();
807 aLSd.Clear();
808 aMSOr.Clear();
809 aMFence.Clear();
810 aMSI.Clear();
811 aMx.Clear();
812 aMSx.Clear();
813 }
814 //=======================================================================
815 //function : OwnInternalShapes
816 //purpose :
817 //=======================================================================
OwnInternalShapes(const TopoDS_Shape & theS,TopTools_IndexedMapOfShape & theMx)818 void OwnInternalShapes(const TopoDS_Shape& theS,
819 TopTools_IndexedMapOfShape& theMx)
820 {
821 TopoDS_Iterator aIt;
822 //
823 aIt.Initialize(theS);
824 for (; aIt.More(); aIt.Next()) {
825 const TopoDS_Shape& aSx=aIt.Value();
826 if (aSx.ShapeType()!=TopAbs_SHELL) {
827 theMx.Add(aSx);
828 }
829 }
830 }
831