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