0028786: Refactoring of the Warning/Error reporting system of Boolean Operations...
[occt.git] / src / BOPAlgo / BOPAlgo_Builder_2.cxx
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
19 #include <BOPAlgo_Builder.hxx>
20 #include <BOPAlgo_BuilderFace.hxx>
21 #include <BOPAlgo_PaveFiller.hxx>
22 #include <BOPAlgo_Tools.hxx>
23 #include <BOPCol_DataMapOfIntegerListOfShape.hxx>
24 #include <BOPCol_DataMapOfShapeShape.hxx>
25 #include <BOPCol_ListOfInteger.hxx>
26 #include <BOPCol_ListOfShape.hxx>
27 #include <BOPCol_MapOfInteger.hxx>
28 #include <BOPCol_NCVector.hxx>
29 #include <BOPCol_Parallel.hxx>
30 #include <BOPDS_DS.hxx>
31 #include <BOPDS_FaceInfo.hxx>
32 #include <BOPDS_Interf.hxx>
33 #include <BOPDS_MapOfPaveBlock.hxx>
34 #include <BOPDS_PaveBlock.hxx>
35 #include <BOPDS_ShapeInfo.hxx>
36 #include <BOPDS_VectorOfCurve.hxx>
37 #include <BOPDS_VectorOfInterfFF.hxx>
38 #include <BOPDS_VectorOfPoint.hxx>
39 #include <BOPTools.hxx>
40 #include <BOPTools_AlgoTools.hxx>
41 #include <BOPTools_AlgoTools2D.hxx>
42 #include <BOPTools_AlgoTools3D.hxx>
43 #include <BOPTools_CoupleOfShape.hxx>
44 #include <BOPTools_DataMapOfShapeSet.hxx>
45 #include <BOPTools_ListOfCoupleOfShape.hxx>
46 #include <BOPTools_MapOfSet.hxx>
47 #include <BRep_Builder.hxx>
48 #include <BRep_Tool.hxx>
49 #include <GeomAdaptor_Surface.hxx>
50 #include <GeomLib.hxx>
51 #include <Precision.hxx>
52 #include <IntTools_Context.hxx>
53 #include <TopExp_Explorer.hxx>
54 #include <TopoDS_Compound.hxx>
55 #include <TopoDS_Edge.hxx>
56 #include <TopoDS_Face.hxx>
57 #include <TopoDS_Shape.hxx>
58 #include <TopoDS_Vertex.hxx>
59
60 //
61 static
62   Standard_Boolean HasPaveBlocksOnIn(const BOPDS_FaceInfo& aFI1,
63                                      const BOPDS_FaceInfo& aFI2);
64 //
65 typedef BOPCol_NCVector<TopoDS_Shape> BOPAlgo_VectorOfShape;
66 //
67 typedef BOPCol_NCVector<BOPAlgo_VectorOfShape> \
68   BOPAlgo_VectorOfVectorOfShape;
69 //
70 typedef NCollection_IndexedDataMap\
71   <BOPTools_Set, Standard_Integer, BOPTools_SetMapHasher> \
72     BOPAlgo_IndexedDataMapOfSetInteger;
73 //
74 //=======================================================================
75 //class    : BOPAlgo_PairOfShapeBoolean
76 //purpose  : 
77 //=======================================================================
78 class BOPAlgo_PairOfShapeBoolean : public BOPAlgo_Algo {
79
80  public:
81   DEFINE_STANDARD_ALLOC
82
83   BOPAlgo_PairOfShapeBoolean() : 
84     BOPAlgo_Algo(),
85     myFlag(Standard_False) {
86   }
87   //
88   virtual ~BOPAlgo_PairOfShapeBoolean() {
89   }
90   //
91   TopoDS_Shape& Shape1() {
92     return myShape1;
93   }
94   //
95   TopoDS_Shape& Shape2() {
96     return myShape2;
97   }
98   //
99   Standard_Boolean& Flag() {
100     return myFlag;
101   }
102   //
103   void SetContext(const Handle(IntTools_Context)& aContext) {
104     myContext=aContext;
105   }
106   //
107   const Handle(IntTools_Context)& Context()const {
108     return myContext;
109   }
110   //
111   virtual void Perform() {
112     BOPAlgo_Algo::UserBreak();
113     //  
114     const TopoDS_Face& aFj=*((TopoDS_Face*)&myShape1);
115     const TopoDS_Face& aFk=*((TopoDS_Face*)&myShape2);
116     myFlag=BOPTools_AlgoTools::AreFacesSameDomain(aFj, aFk, myContext, myFuzzyValue);
117   }
118   //
119  protected: 
120   Standard_Boolean myFlag;
121   TopoDS_Shape myShape1;
122   TopoDS_Shape myShape2;
123   Handle(IntTools_Context) myContext;
124 };
125 //
126 typedef BOPCol_NCVector<BOPAlgo_PairOfShapeBoolean> \
127   BOPAlgo_VectorOfPairOfShapeBoolean;
128 //
129 typedef BOPCol_ContextFunctor 
130   <BOPAlgo_PairOfShapeBoolean,
131   BOPAlgo_VectorOfPairOfShapeBoolean,
132   Handle(IntTools_Context), 
133   IntTools_Context> BOPCol_BuilderSDFaceFunctor;
134 //
135 typedef BOPCol_ContextCnt 
136   <BOPCol_BuilderSDFaceFunctor,
137   BOPAlgo_VectorOfPairOfShapeBoolean,
138   Handle(IntTools_Context)> BOPAlgo_BuilderSDFaceCnt;
139 //
140 //=======================================================================
141 // BuilderFace
142 //
143 typedef BOPCol_NCVector<BOPAlgo_BuilderFace> BOPAlgo_VectorOfBuilderFace;
144 //
145 typedef BOPCol_Functor 
146   <BOPAlgo_BuilderFace,
147   BOPAlgo_VectorOfBuilderFace> BOPAlgo_BuilderFaceFunctor;
148 //
149 typedef BOPCol_Cnt 
150   <BOPAlgo_BuilderFaceFunctor,
151   BOPAlgo_VectorOfBuilderFace> BOPAlgo_BuilderFaceCnt;
152 //
153 //=======================================================================
154 //class    : BOPAlgo_VFI
155 //purpose  : 
156 //=======================================================================
157 class BOPAlgo_VFI : public BOPAlgo_Algo {
158
159  public:
160   DEFINE_STANDARD_ALLOC
161   
162   BOPAlgo_VFI() :
163     BOPAlgo_Algo(),
164     myFlag(-1) {
165   }
166   //
167   virtual ~BOPAlgo_VFI(){
168   }
169   //
170   void SetVertex(const TopoDS_Vertex& aV) {
171     myV=aV;
172   }
173   //
174   TopoDS_Vertex& Vertex() {
175     return myV;
176   }
177   //
178   void SetFace(const TopoDS_Face& aF) {
179     myF=aF;
180   }
181   //
182   TopoDS_Face& Face() {
183     return myF;
184   }
185   //
186   Standard_Integer Flag()const {
187     return myFlag;
188   }
189   //
190   void SetContext(const Handle(IntTools_Context)& aContext) {
191     myContext=aContext;
192   }
193   //
194   const Handle(IntTools_Context)& Context()const {
195     return myContext;
196   }
197   //
198   virtual void Perform() {
199     Standard_Real aT1, aT2, dummy;
200     //
201     BOPAlgo_Algo::UserBreak();
202     myFlag = myContext->ComputeVF(myV, myF, aT1, aT2, dummy, myFuzzyValue);
203   }
204   //
205  protected:
206   Standard_Integer myFlag;
207   TopoDS_Vertex myV;
208   TopoDS_Face myF;
209   Handle(IntTools_Context) myContext;
210 };
211 //
212 typedef BOPCol_NCVector<BOPAlgo_VFI> BOPAlgo_VectorOfVFI; 
213 //
214 typedef BOPCol_ContextFunctor 
215   <BOPAlgo_VFI,
216   BOPAlgo_VectorOfVFI,
217   Handle(IntTools_Context), 
218   IntTools_Context> BOPAlgo_VFIFunctor;
219 //
220 typedef BOPCol_ContextCnt 
221   <BOPAlgo_VFIFunctor,
222   BOPAlgo_VectorOfVFI,
223   Handle(IntTools_Context)> BOPAlgo_VFICnt;
224 //
225 //=======================================================================
226 //function : FillImagesFaces
227 //purpose  : 
228 //=======================================================================
229 void BOPAlgo_Builder::FillImagesFaces()
230 {
231   BuildSplitFaces();
232   FillSameDomainFaces();
233   FillImagesFaces1();
234 }
235 //=======================================================================
236 //function : BuildSplitFaces
237 //purpose  : 
238 //=======================================================================
239 void BOPAlgo_Builder::BuildSplitFaces()
240 {
241   Standard_Boolean bHasFaceInfo, bIsClosed, bIsDegenerated, bToReverse;
242   Standard_Integer i, j, k, aNbS, aNbPBIn, aNbPBOn, aNbPBSc, aNbAV, nSp;
243   Standard_Size aNbBF;
244   TopoDS_Face aFF, aFSD;
245   TopoDS_Edge aSp, aEE;
246   TopAbs_Orientation anOriF, anOriE;
247   TopExp_Explorer aExp;
248   BOPCol_ListIteratorOfListOfShape aIt;
249   BOPCol_ListOfInteger aLIAV;
250   BOPCol_MapOfShape aMFence;
251   Handle(NCollection_BaseAllocator) aAllocator;
252   BOPCol_ListOfShape aLFIm(myAllocator);
253   BOPAlgo_VectorOfBuilderFace aVBF;
254   //
255   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~scope f
256   aAllocator=
257     NCollection_BaseAllocator::CommonBaseAllocator();
258   //
259   BOPCol_ListOfShape aLE(aAllocator);
260   BOPCol_MapOfShape aMDE(100, aAllocator);
261   //
262   aNbS=myDS->NbSourceShapes();
263   //
264   for (i=0; i<aNbS; ++i) {
265     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
266     if (aSI.ShapeType()!=TopAbs_FACE) {
267       continue;
268     }
269     //
270     const TopoDS_Face& aF=(*(TopoDS_Face*)(&aSI.Shape()));
271     Standard_Boolean isUClosed = Standard_False,
272                      isVClosed = Standard_False,
273                      isChecked = Standard_False;
274     //
275     bHasFaceInfo=myDS->HasFaceInfo(i);
276     if(!bHasFaceInfo) {
277       continue;
278     }
279     //
280     const BOPDS_FaceInfo& aFI=myDS->FaceInfo(i);
281     //
282     const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
283     const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn();
284     const BOPDS_IndexedMapOfPaveBlock& aMPBSc=aFI.PaveBlocksSc();
285     aLIAV.Clear();
286     myDS->AloneVertices(i, aLIAV);
287     
288     aNbPBIn=aMPBIn.Extent();
289     aNbPBOn=aMPBOn.Extent();
290     aNbPBSc=aMPBSc.Extent();
291     aNbAV=aLIAV.Extent();
292     if (!aNbPBIn && !aNbPBOn && !aNbPBSc && !aNbAV) { // not compete
293       continue;
294     }
295     //
296     aMFence.Clear();
297     //
298     anOriF=aF.Orientation();
299     aFF=aF;
300     aFF.Orientation(TopAbs_FORWARD);
301     //
302     // 1. Fill the egdes set for the face aFF -> LE
303     aLE.Clear();
304     //
305     //
306     // 1.1 Bounding edges
307     aExp.Init(aFF, TopAbs_EDGE);
308     for (; aExp.More(); aExp.Next()) {
309       const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
310       anOriE=aE.Orientation();
311       //
312       if (!myImages.IsBound(aE)) {
313         if (anOriE==TopAbs_INTERNAL) {
314           aEE=aE;
315           aEE.Orientation(TopAbs_FORWARD);
316           aLE.Append(aEE);
317           aEE.Orientation(TopAbs_REVERSED);
318           aLE.Append(aEE);
319         }
320         else {
321           aLE.Append(aE);
322         }
323
324         continue;
325       }
326
327       if(!isChecked)
328       {
329         const Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aF);
330         GeomLib::IsClosed(aSurf, BRep_Tool::Tolerance(aE),
331           isUClosed, isVClosed);
332
333         isChecked = Standard_True;
334       }
335
336       bIsClosed = Standard_False;
337
338       if((isUClosed || isVClosed) && BRep_Tool::IsClosed(aE, aF)) 
339       {
340
341         Standard_Boolean isUIso = Standard_False, isVIso = Standard_False;
342         BOPTools_AlgoTools2D::IsEdgeIsoline(aE, aF, isUIso, isVIso);
343
344         bIsClosed = ((isUClosed && isUIso) || (isVClosed && isVIso));
345       }
346
347       bIsDegenerated=BRep_Tool::Degenerated(aE);
348
349       const BOPCol_ListOfShape& aLIE=myImages.Find(aE);
350       aIt.Initialize(aLIE);
351       for (; aIt.More(); aIt.Next()) {
352         aSp=(*(TopoDS_Edge*)(&aIt.Value()));
353         if (bIsDegenerated) {
354           aSp.Orientation(anOriE);
355           aLE.Append(aSp);
356           continue;
357         }
358         //
359         if (anOriE==TopAbs_INTERNAL) {
360           aSp.Orientation(TopAbs_FORWARD);
361           aLE.Append(aSp);
362           aSp.Orientation(TopAbs_REVERSED);
363           aLE.Append(aSp);
364           continue;
365         }
366           //
367         if (bIsClosed) {
368           if (aMFence.Add(aSp)) {
369             if (!BRep_Tool::IsClosed(aSp, aF)){
370               BOPTools_AlgoTools3D::DoSplitSEAMOnFace(aSp, aF);
371             }
372             //
373             aSp.Orientation(TopAbs_FORWARD);
374             aLE.Append(aSp);
375             aSp.Orientation(TopAbs_REVERSED);
376             aLE.Append(aSp);
377           }// if (aMFence.Add(aSp))
378           continue;
379         }// if (bIsClosed){
380         //
381         aSp.Orientation(anOriE);
382         bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aSp, aE, myContext);
383         if (bToReverse) {
384           aSp.Reverse();
385         }
386         aLE.Append(aSp);
387       }// for (; aIt.More(); aIt.Next()) {
388     }// for (; aExp.More(); aExp.Next()) {
389     // 
390     //
391     // 1.2 In edges
392     for (j=1; j<=aNbPBIn; ++j) {
393       const Handle(BOPDS_PaveBlock)& aPB=aMPBIn(j);
394       nSp=aPB->Edge();
395       aSp=(*(TopoDS_Edge*)(&myDS->Shape(nSp)));
396       //
397       aSp.Orientation(TopAbs_FORWARD);
398       aLE.Append(aSp);
399       aSp.Orientation(TopAbs_REVERSED);
400       aLE.Append(aSp);
401     }
402     //
403     //
404     // 1.3 Section edges
405     for (j=1; j<=aNbPBSc; ++j) {
406       const Handle(BOPDS_PaveBlock)& aPB=aMPBSc(j);
407       nSp=aPB->Edge();
408       aSp=(*(TopoDS_Edge*)(&myDS->Shape(nSp)));
409       //
410       aSp.Orientation(TopAbs_FORWARD);
411       aLE.Append(aSp);
412       aSp.Orientation(TopAbs_REVERSED);
413       aLE.Append(aSp);
414     }
415     //
416     if (!myPaveFiller->NonDestructive()) {
417       // speed up for planar faces
418       BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane (aLE, aFF);
419     }
420     // 3 Build split faces
421     BOPAlgo_BuilderFace& aBF=aVBF.Append1();
422     aBF.SetFace(aF);
423     aBF.SetShapes(aLE);
424     aBF.SetRunParallel(myRunParallel);
425     aBF.SetProgressIndicator(myProgressIndicator);
426     //
427   }// for (i=0; i<aNbS; ++i) {
428   //
429   aNbBF=aVBF.Extent();
430   //
431   //===================================================
432   BOPAlgo_BuilderFaceCnt::Perform(myRunParallel, aVBF);
433   //===================================================
434   //
435   for (k=0; k<(Standard_Integer)aNbBF; ++k) {
436     aLFIm.Clear();
437     //
438     BOPAlgo_BuilderFace& aBF=aVBF(k);
439     TopoDS_Face aF=aBF.Face();
440     anOriF=aBF.Orientation();
441     aF.Orientation(anOriF);
442     //
443     const BOPCol_ListOfShape& aLFR=aBF.Areas();
444     aIt.Initialize(aLFR);
445     for (; aIt.More(); aIt.Next()) {
446       TopoDS_Shape& aFR=aIt.ChangeValue();
447       if (anOriF==TopAbs_REVERSED) {
448         aFR.Orientation(TopAbs_REVERSED);
449       }
450       //aFR.Orientation(anOriF);
451       aLFIm.Append(aFR);
452     }
453     //
454     mySplits.Bind(aF, aLFIm); 
455   }// for (k=0; k<aNbBF; ++k) {
456   //
457   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~scope t
458 }
459 //=======================================================================
460 //function : FillSameDomainFaces
461 //purpose  : 
462 //=======================================================================
463 void BOPAlgo_Builder::FillSameDomainFaces()
464 {
465   Standard_Boolean bFlag;
466   Standard_Integer i, j, k, aNbFFs, nF1, nF2;
467   Handle(NCollection_BaseAllocator) aAllocator;
468   BOPCol_ListIteratorOfListOfShape aItF;
469   BOPCol_MapOfShape aMFence;
470   BOPAlgo_IndexedDataMapOfSetInteger aIDMSS;
471   BOPAlgo_VectorOfVectorOfShape aVVS;
472   //
473   const BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
474   //
475   aNbFFs=aFFs.Extent();
476   if (!aNbFFs) {
477     return;
478   }
479   //
480   for (i=0; i<aNbFFs; ++i) {
481     const BOPDS_InterfFF& aFF=aFFs(i);
482     aFF.Indices(nF1, nF2);
483     //
484     if (!myDS->HasFaceInfo(nF1) || !myDS->HasFaceInfo(nF2) ) {
485       continue;
486     }
487     //
488     const BOPDS_FaceInfo& aFI1=myDS->FaceInfo(nF1);
489     const BOPDS_FaceInfo& aFI2=myDS->FaceInfo(nF2);
490     //
491     const TopoDS_Shape& aF1=myDS->Shape(nF1);
492     const TopoDS_Shape& aF2=myDS->Shape(nF2);
493     //
494     bFlag=HasPaveBlocksOnIn(aFI1, aFI2);
495     bFlag=bFlag && (mySplits.IsBound(aF1) && mySplits.IsBound(aF2));
496     //
497     if (bFlag) {
498       for (k=0; k<2; ++k) {
499         const TopoDS_Shape& aF=(!k) ? aF1 : aF2;
500         const BOPCol_ListOfShape& aLF=mySplits.Find(aF);
501         //
502         aItF.Initialize(aLF);
503         for (; aItF.More(); aItF.Next()) {
504           const TopoDS_Shape& aFx=aItF.Value();
505           //
506           if (aMFence.Add(aFx)) {
507             BOPTools_Set aSTx;
508             //
509             aSTx.Add(aFx, TopAbs_EDGE);
510             //
511             if (!aIDMSS.Contains(aSTx)) {
512               BOPAlgo_VectorOfShape& aVS=aVVS.Append1(); 
513               aVS.Append(aFx);
514               //
515               j=aVVS.Extent()-1;
516               aIDMSS.Add (aSTx, j);
517             }
518             else {
519               j=aIDMSS.ChangeFromKey(aSTx);
520               BOPAlgo_VectorOfShape& aVS=aVVS(j);
521               aVS.Append(aFx);
522             }
523           }
524         }
525       }
526     }// if (bFlag) {
527     else {// if (!bFlag) 
528       BOPTools_Set aST1, aST2;
529       //
530       aST1.Add(aF1, TopAbs_EDGE);
531       aST2.Add(aF2, TopAbs_EDGE);
532       //
533       if (aST1.IsEqual(aST2)) {
534         if (!aIDMSS.Contains(aST1)) {
535           BOPAlgo_VectorOfShape& aVS=aVVS.Append1(); 
536           if (aMFence.Add(aF1)) {
537             aVS.Append(aF1);
538           }
539           if (aMFence.Add(aF2)) {
540             aVS.Append(aF2);
541           }
542           //
543           k=aVVS.Extent()-1;
544           aIDMSS.Add (aST1, k);
545         }
546         else {
547           k=aIDMSS.ChangeFromKey(aST1);
548           BOPAlgo_VectorOfShape& aVS=aVVS(k);
549           if (aMFence.Add(aF1)) {
550             aVS.Append(aF1);
551           }
552           if (aMFence.Add(aF2)) {
553             aVS.Append(aF2);
554           }
555         }
556       }//if (aST1.IsEqual(aST2)) {
557     }// else {// if (!bFlag) 
558     //
559   }// for (i=0; i<aNbFFs; ++i) {
560   //
561   aIDMSS.Clear();
562   //
563   Standard_Boolean bFlagSD;
564   Standard_Integer aNbVPSB, aNbVVS, aNbF, aNbF1;
565   BOPAlgo_VectorOfPairOfShapeBoolean aVPSB;
566   //
567   aNbVVS=aVVS.Extent();
568   for (i=0; i<aNbVVS; ++i) {
569     const BOPAlgo_VectorOfShape& aVS=aVVS(i);
570     aNbF=aVS.Extent();
571     if (aNbF<2) {
572       continue;
573     }
574     //
575     aNbF1=aNbF-1;
576     for (j=0; j<aNbF1; ++j) {
577       const TopoDS_Shape& aFj=aVS(j);
578       for (k=j+1; k<aNbF; ++k) {
579         const TopoDS_Shape& aFk=aVS(k);
580         BOPAlgo_PairOfShapeBoolean& aPSB=aVPSB.Append1();
581         aPSB.Shape1()=aFj;
582         aPSB.Shape2()=aFk;
583         aPSB.SetFuzzyValue(myFuzzyValue);
584         aPSB.SetProgressIndicator(myProgressIndicator);
585       }
586     }
587   }
588   //================================================================
589   BOPAlgo_BuilderSDFaceCnt::Perform(myRunParallel, aVPSB, myContext);
590   //================================================================
591   aAllocator=
592     NCollection_BaseAllocator::CommonBaseAllocator();
593   BOPCol_IndexedDataMapOfShapeListOfShape aDMSLS(100, aAllocator);
594   NCollection_List<BOPCol_ListOfShape> aMBlocks(aAllocator);
595   //
596   aNbVPSB=aVPSB.Extent();
597   for (i=0; i<aNbVPSB; ++i) {
598     BOPAlgo_PairOfShapeBoolean& aPSB=aVPSB(i);
599     bFlagSD=aPSB.Flag();
600     if (bFlagSD) {
601       const TopoDS_Shape& aFj=aPSB.Shape1();
602       const TopoDS_Shape& aFk=aPSB.Shape2();
603       BOPAlgo_Tools::FillMap<TopoDS_Shape, TopTools_ShapeMapHasher>(aFj, aFk, aDMSLS, aAllocator);
604     }
605   }
606   aVPSB.Clear();
607   //
608   // 2. Make blocks
609   BOPAlgo_Tools::MakeBlocks<TopoDS_Shape, TopTools_ShapeMapHasher>(aDMSLS, aMBlocks, aAllocator);
610   //
611   // 3. Fill same domain faces map -> aMSDF
612   NCollection_List<BOPCol_ListOfShape>::Iterator aItB(aMBlocks);
613   for (; aItB.More(); aItB.Next()) {
614     const BOPCol_ListOfShape& aLSD = aItB.Value();
615     //
616     const TopoDS_Shape& aFSD1=aLSD.First();
617     aItF.Initialize(aLSD);
618     for (; aItF.More(); aItF.Next()) {
619       const TopoDS_Shape& aFSD=aItF.Value();
620       myShapesSD.Bind(aFSD, aFSD1);
621       //
622       // If the face has no splits but are SD face,
623       // it is considered as splitted face
624       if (!mySplits.IsBound(aFSD)) {
625         BOPCol_ListOfShape aLS;
626         aLS.Append(aFSD);
627         mySplits.Bind(aFSD, aLS);
628       }
629     }
630   }
631   aMBlocks.Clear();
632   aDMSLS.Clear();
633 }
634 //=======================================================================
635 // function: FillImagesFaces1
636 // purpose: 
637 //=======================================================================
638 void BOPAlgo_Builder::FillImagesFaces1()
639 {
640   Standard_Integer i, aNbS, iSense, nVx, aNbVFI, iFlag;
641   TopoDS_Face aFSD;
642   TopoDS_Vertex aVx;
643   BRep_Builder aBB;
644   BOPCol_ListOfInteger aLIAV;
645   BOPCol_ListOfShape aLFIm;
646   BOPCol_ListIteratorOfListOfInteger aItV;
647   BOPCol_ListIteratorOfListOfShape aItLS, aItF;
648   BOPAlgo_VectorOfVFI aVVFI;
649   //
650   aNbS=myDS->NbSourceShapes();
651   for (i=0; i<aNbS; ++i) {
652     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
653     if (aSI.ShapeType()!=TopAbs_FACE) {
654       continue;
655     }
656     //
657     const TopoDS_Face& aF=(*(TopoDS_Face*)(&aSI.Shape()));
658     //
659     if (!mySplits.IsBound(aF)) {
660       continue;
661     }
662     // 
663     // 1.
664     aLIAV.Clear();
665     myDS->AloneVertices(i, aLIAV);
666     aLFIm.Clear();
667     //
668     const BOPCol_ListOfShape& aLSp=mySplits.Find(aF);
669     aItLS.Initialize(aLSp);
670     for (; aItLS.More(); aItLS.Next()) {
671       const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&aItLS.Value()));
672       if (!myShapesSD.IsBound(aFSp)) {
673         aLFIm.Append(aFSp);
674       }
675       else {
676         aFSD=(*(TopoDS_Face*)(&myShapesSD.Find(aFSp)));
677         iSense=BOPTools_AlgoTools::Sense(aFSp, aFSD, myContext);
678         if (iSense<0) {
679           aFSD.Reverse();
680         }
681         aLFIm.Append(aFSD);
682       }
683     }
684     //
685     //FillInternalVertices(aLFIm, aLIAV);
686     //
687     myImages.Bind(aF, aLFIm); 
688     //
689     // 2. fill myOrigins
690     aItLS.Initialize(aLFIm);
691     for (; aItLS.More(); aItLS.Next()) {
692       const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&aItLS.Value()));
693       //
694       BOPCol_ListOfShape* pLOr = myOrigins.ChangeSeek(aFSp);
695       if (!pLOr) {
696         pLOr = myOrigins.Bound(aFSp, BOPCol_ListOfShape());
697       }
698       pLOr->Append(aF);
699     }
700     //
701     // 3.
702     aItV.Initialize(aLIAV);
703     for (; aItV.More(); aItV.Next()) {
704       nVx=aItV.Value();
705       aVx=(*(TopoDS_Vertex*)(&myDS->Shape(nVx)));
706       aVx.Orientation(TopAbs_INTERNAL);
707       //
708       aItF.Initialize(aLFIm);
709       for (; aItF.More(); aItF.Next()) {
710         TopoDS_Face& aFy=(*(TopoDS_Face*)(&aItF.Value()));
711         //
712         BOPAlgo_VFI& aVFI=aVVFI.Append1();
713         aVFI.SetVertex(aVx);
714         aVFI.SetFace(aFy);
715         aVFI.SetFuzzyValue(myFuzzyValue);
716         aVFI.SetProgressIndicator(myProgressIndicator);
717       }
718     }
719   }// for (i=0; i<aNbS; ++i) {
720   //
721   // 4. 
722   aNbVFI=aVVFI.Extent();
723   //================================================================
724   BOPAlgo_VFICnt::Perform(myRunParallel, aVVFI, myContext);
725   //================================================================
726   //
727   for (i=0; i < aNbVFI; ++i) {
728     BOPAlgo_VFI& aVFI=aVVFI(i);
729     //
730     iFlag=aVFI.Flag();
731     if (!iFlag) {
732       TopoDS_Vertex& aVertex=aVFI.Vertex();
733       TopoDS_Face& aFy=aVFI.Face(); 
734       aBB.Add(aFy, aVertex);
735     }
736   }
737 }
738 //=======================================================================
739 //function :HasPaveBlocksOnIn
740 //purpose  : 
741 //=======================================================================
742 Standard_Boolean HasPaveBlocksOnIn(const BOPDS_FaceInfo& aFI1,
743                                    const BOPDS_FaceInfo& aFI2)
744 {
745   Standard_Boolean bRet;
746   Standard_Integer i, aNbPB;
747   //
748   bRet=Standard_False;
749   const BOPDS_IndexedMapOfPaveBlock& aMPBOn1 = aFI1.PaveBlocksOn();
750   const BOPDS_IndexedMapOfPaveBlock& aMPBIn1 = aFI1.PaveBlocksIn();
751   //
752   const BOPDS_IndexedMapOfPaveBlock& aMPBOn2 = aFI2.PaveBlocksOn();
753   aNbPB = aMPBOn2.Extent();
754   for (i = 1; i <= aNbPB; ++i) {
755     const Handle(BOPDS_PaveBlock)& aPB = aMPBOn2(i);
756     bRet = aMPBOn1.Contains(aPB) || aMPBIn1.Contains(aPB);
757     if (bRet) {
758       return bRet;
759     }
760   }
761   //
762   const BOPDS_IndexedMapOfPaveBlock& aMPBIn2 = aFI2.PaveBlocksIn();
763   aNbPB = aMPBIn2.Extent();
764   for (i = 1; i <= aNbPB; ++i) {
765     const Handle(BOPDS_PaveBlock)& aPB = aMPBIn2(i);
766     bRet = aMPBOn1.Contains(aPB) || aMPBIn1.Contains(aPB);
767     if (bRet) {
768       return bRet;
769     }
770   }
771   return bRet;
772 }