0028486: Fuse of several solids fails due to presence of common zones between faces
[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, 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     if (!myDS->HasFaceInfo(nF1) || !myDS->HasFaceInfo(nF2) ) {
499       continue;
500     }
501     //
502     const BOPDS_FaceInfo& aFI1=myDS->FaceInfo(nF1);
503     const BOPDS_FaceInfo& aFI2=myDS->FaceInfo(nF2);
504     //
505     const TopoDS_Shape& aF1=myDS->Shape(nF1);
506     const TopoDS_Shape& aF2=myDS->Shape(nF2);
507     //
508     bFlag=HasPaveBlocksOnIn(aFI1, aFI2);
509     bFlag=bFlag && (mySplits.IsBound(aF1) && mySplits.IsBound(aF2));
510     //
511     if (bFlag) {
512       for (k=0; k<2; ++k) {
513         const TopoDS_Shape& aF=(!k) ? aF1 : aF2;
514         const BOPCol_ListOfShape& aLF=mySplits.Find(aF);
515         //
516         aItF.Initialize(aLF);
517         for (; aItF.More(); aItF.Next()) {
518           const TopoDS_Shape& aFx=aItF.Value();
519           //
520           if (aMFence.Add(aFx)) {
521             BOPTools_Set aSTx;
522             //
523             aSTx.Add(aFx, TopAbs_EDGE);
524             //
525             if (!aIDMSS.Contains(aSTx)) {
526               BOPAlgo_VectorOfShape& aVS=aVVS.Append1(); 
527               aVS.Append(aFx);
528               //
529               j=aVVS.Extent()-1;
530               aIDMSS.Add (aSTx, j);
531             }
532             else {
533               j=aIDMSS.ChangeFromKey(aSTx);
534               BOPAlgo_VectorOfShape& aVS=aVVS(j);
535               aVS.Append(aFx);
536             }
537           }
538         }
539       }
540     }// if (bFlag) {
541     else {// if (!bFlag) 
542       BOPTools_Set aST1, aST2;
543       //
544       aST1.Add(aF1, TopAbs_EDGE);
545       aST2.Add(aF2, TopAbs_EDGE);
546       //
547       if (aST1.IsEqual(aST2)) {
548         if (!aIDMSS.Contains(aST1)) {
549           BOPAlgo_VectorOfShape& aVS=aVVS.Append1(); 
550           if (aMFence.Add(aF1)) {
551             aVS.Append(aF1);
552           }
553           if (aMFence.Add(aF2)) {
554             aVS.Append(aF2);
555           }
556           //
557           k=aVVS.Extent()-1;
558           aIDMSS.Add (aST1, k);
559         }
560         else {
561           k=aIDMSS.ChangeFromKey(aST1);
562           BOPAlgo_VectorOfShape& aVS=aVVS(k);
563           if (aMFence.Add(aF1)) {
564             aVS.Append(aF1);
565           }
566           if (aMFence.Add(aF2)) {
567             aVS.Append(aF2);
568           }
569         }
570       }//if (aST1.IsEqual(aST2)) {
571     }// else {// if (!bFlag) 
572     //
573   }// for (i=0; i<aNbFFs; ++i) {
574   //
575   aIDMSS.Clear();
576   //
577   Standard_Boolean bFlagSD;
578   Standard_Integer aNbVPSB, aNbVVS, aNbF, aNbF1;
579   BOPAlgo_VectorOfPairOfShapeBoolean aVPSB;
580   //
581   aNbVVS=aVVS.Extent();
582   for (i=0; i<aNbVVS; ++i) {
583     const BOPAlgo_VectorOfShape& aVS=aVVS(i);
584     aNbF=aVS.Extent();
585     if (aNbF<2) {
586       continue;
587     }
588     //
589     aNbF1=aNbF-1;
590     for (j=0; j<aNbF1; ++j) {
591       const TopoDS_Shape& aFj=aVS(j);
592       for (k=j+1; k<aNbF; ++k) {
593         const TopoDS_Shape& aFk=aVS(k);
594         BOPAlgo_PairOfShapeBoolean& aPSB=aVPSB.Append1();
595         aPSB.Shape1()=aFj;
596         aPSB.Shape2()=aFk;
597         aPSB.SetFuzzyValue(myFuzzyValue);
598         aPSB.SetProgressIndicator(myProgressIndicator);
599       }
600     }
601   }
602   //================================================================
603   BOPAlgo_BuilderSDFaceCnt::Perform(myRunParallel, aVPSB, myContext);
604   //================================================================
605   aAllocator=
606     NCollection_BaseAllocator::CommonBaseAllocator();
607   BOPCol_IndexedDataMapOfShapeListOfShape aDMSLS(100, aAllocator);
608   BOPCol_DataMapOfIntegerListOfShape aMBlocks(100, aAllocator);
609   //
610   aNbVPSB=aVPSB.Extent();
611   for (i=0; i<aNbVPSB; ++i) {
612     BOPAlgo_PairOfShapeBoolean& aPSB=aVPSB(i);
613     bFlagSD=aPSB.Flag();
614     if (bFlagSD) {
615       const TopoDS_Shape& aFj=aPSB.Shape1();
616       const TopoDS_Shape& aFk=aPSB.Shape2();
617       FillMap(aFj, aFk, aDMSLS, aAllocator);
618     }
619   }
620   aVPSB.Clear();
621   //
622   // 2. Make blocks
623   MakeBlocksCnx(aDMSLS, aMBlocks, aAllocator);
624   //
625   // 3. Fill same domain faces map -> aMSDF
626   aNbS = aMBlocks.Extent();
627   for (i=0; i<aNbS; ++i) {
628     const BOPCol_ListOfShape& aLSD=aMBlocks.Find(i);
629     if (aLSD.IsEmpty()) {
630       continue;
631     }
632     //
633     const TopoDS_Shape& aFSD1=aLSD.First();
634     aItF.Initialize(aLSD);
635     for (; aItF.More(); aItF.Next()) {
636       const TopoDS_Shape& aFSD=aItF.Value();
637       myShapesSD.Bind(aFSD, aFSD1);
638       //
639       // If the face has no splits but are SD face,
640       // it is considered as splitted face
641       if (!mySplits.IsBound(aFSD)) {
642         BOPCol_ListOfShape aLS;
643         aLS.Append(aFSD);
644         mySplits.Bind(aFSD, aLS);
645       }
646     }
647   }
648   aMBlocks.Clear();
649   aDMSLS.Clear();
650 }
651 //=======================================================================
652 // function: FillImagesFaces1
653 // purpose: 
654 //=======================================================================
655 void BOPAlgo_Builder::FillImagesFaces1()
656 {
657   Standard_Integer i, aNbS, iSense, nVx, aNbVFI, iFlag;
658   TopoDS_Face aFSD;
659   TopoDS_Vertex aVx;
660   BRep_Builder aBB;
661   BOPCol_ListOfInteger aLIAV;
662   BOPCol_ListOfShape aLFIm;
663   BOPCol_ListIteratorOfListOfInteger aItV;
664   BOPCol_ListIteratorOfListOfShape aItLS, aItF;
665   BOPAlgo_VectorOfVFI aVVFI;
666   //
667   aNbS=myDS->NbSourceShapes();
668   for (i=0; i<aNbS; ++i) {
669     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
670     if (aSI.ShapeType()!=TopAbs_FACE) {
671       continue;
672     }
673     //
674     const TopoDS_Face& aF=(*(TopoDS_Face*)(&aSI.Shape()));
675     //
676     if (!mySplits.IsBound(aF)) {
677       continue;
678     }
679     // 
680     // 1.
681     aLIAV.Clear();
682     myDS->AloneVertices(i, aLIAV);
683     aLFIm.Clear();
684     //
685     const BOPCol_ListOfShape& aLSp=mySplits.Find(aF);
686     aItLS.Initialize(aLSp);
687     for (; aItLS.More(); aItLS.Next()) {
688       const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&aItLS.Value()));
689       if (!myShapesSD.IsBound(aFSp)) {
690         aLFIm.Append(aFSp);
691       }
692       else {
693         aFSD=(*(TopoDS_Face*)(&myShapesSD.Find(aFSp)));
694         iSense=BOPTools_AlgoTools::Sense(aFSp, aFSD, myContext);
695         if (iSense<0) {
696           aFSD.Reverse();
697         }
698         aLFIm.Append(aFSD);
699       }
700     }
701     //
702     //FillInternalVertices(aLFIm, aLIAV);
703     //
704     myImages.Bind(aF, aLFIm); 
705     //
706     // 2. fill myOrigins
707     aItLS.Initialize(aLFIm);
708     for (; aItLS.More(); aItLS.Next()) {
709       const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&aItLS.Value()));
710       myOrigins.Bind(aFSp, aF);
711     }
712     //
713     // 3.
714     aItV.Initialize(aLIAV);
715     for (; aItV.More(); aItV.Next()) {
716       nVx=aItV.Value();
717       aVx=(*(TopoDS_Vertex*)(&myDS->Shape(nVx)));
718       aVx.Orientation(TopAbs_INTERNAL);
719       //
720       aItF.Initialize(aLFIm);
721       for (; aItF.More(); aItF.Next()) {
722         TopoDS_Face& aFy=(*(TopoDS_Face*)(&aItF.Value()));
723         //
724         BOPAlgo_VFI& aVFI=aVVFI.Append1();
725         aVFI.SetVertex(aVx);
726         aVFI.SetFace(aFy);
727         aVFI.SetFuzzyValue(myFuzzyValue);
728         aVFI.SetProgressIndicator(myProgressIndicator);
729       }
730     }
731   }// for (i=0; i<aNbS; ++i) {
732   //
733   // 4. 
734   aNbVFI=aVVFI.Extent();
735   //================================================================
736   BOPAlgo_VFICnt::Perform(myRunParallel, aVVFI, myContext);
737   //================================================================
738   //
739   for (i=0; i < aNbVFI; ++i) {
740     BOPAlgo_VFI& aVFI=aVVFI(i);
741     //
742     iFlag=aVFI.Flag();
743     if (!iFlag) {
744       TopoDS_Vertex& aVertex=aVFI.Vertex();
745       TopoDS_Face& aFy=aVFI.Face(); 
746       aBB.Add(aFy, aVertex);
747     }
748   }
749 }
750 //=======================================================================
751 //function : MakeBlocksCnx
752 //purpose  : 
753 //=======================================================================
754 void MakeBlocksCnx(const BOPCol_IndexedDataMapOfShapeListOfShape& aMILI,
755                    BOPCol_DataMapOfIntegerListOfShape& aMBlocks,
756                    Handle(NCollection_BaseAllocator)& aAllocator)
757 {
758   Standard_Integer aNbV, aNbVS, aNbVP, aNbEC, k, i, j;
759   BOPCol_ListIteratorOfListOfShape aItLI;
760   //
761   BOPCol_MapOfShape aMVS(100, aAllocator);
762   BOPCol_IndexedMapOfShape aMEC(100, aAllocator);
763   BOPCol_IndexedMapOfShape aMVP(100, aAllocator);
764   BOPCol_IndexedMapOfShape aMVAdd(100, aAllocator);
765   //
766   aNbV=aMILI.Extent();
767   //
768   for (k=0,i=1; i<=aNbV; ++i) {
769     aNbVS=aMVS.Extent();
770     if (aNbVS==aNbV) {
771       break;
772     }
773     //
774     const TopoDS_Shape& nV=aMILI.FindKey(i);
775     if (aMVS.Contains(nV)){
776       continue;
777     }
778     aMVS.Add(nV);
779     //
780     aMEC.Clear();
781     aMVP.Clear();
782     aMVAdd.Clear();
783     //
784     aMVP.Add(nV);
785     for(;;) {
786       aNbVP=aMVP.Extent();
787       for (j=1; j<=aNbVP; ++j) {
788         const TopoDS_Shape& nVP=aMVP(j);
789         const BOPCol_ListOfShape& aLV=aMILI.FindFromKey(nVP);
790         aItLI.Initialize(aLV);
791         for (; aItLI.More(); aItLI.Next()) {
792           const TopoDS_Shape& nVx=aItLI.Value();
793           if (aMEC.Contains(nVx)) {
794             continue;
795           }
796           //
797           aMVS.Add(nVx);
798           aMEC.Add(nVx);
799           aMVAdd.Add(nVx);
800         }
801       }
802       //
803       aNbVP=aMVAdd.Extent();
804       if (!aNbVP) {
805         break; // from while(1)
806       }
807       //
808       aMVP.Clear();
809       for (j=1; j<=aNbVP; ++j) {
810         aMVP.Add(aMVAdd(j));
811       }
812       aMVAdd.Clear();
813     }//while(1) {
814     //
815     BOPCol_ListOfShape aLIx(aAllocator);
816     //
817     aNbEC = aMEC.Extent();
818     for (j=1; j<=aNbEC; ++j) {
819       const TopoDS_Shape& nVx=aMEC(j);
820       aLIx.Append(nVx);
821     }
822     //
823     aMBlocks.Bind(k, aLIx);
824     ++k;
825   }//for (k=0,i=1; i<=aNbV; ++i)
826   aMVAdd.Clear();
827   aMVP.Clear();
828   aMEC.Clear();
829   aMVS.Clear();
830 }
831 //=======================================================================
832 //function : FillMap
833 //purpose  : 
834 //=======================================================================
835 void FillMap(const TopoDS_Shape& aS1,
836              const TopoDS_Shape& aS2,
837              BOPCol_IndexedDataMapOfShapeListOfShape& aDMSLS,
838              Handle(NCollection_BaseAllocator)& aAllocator)
839 {
840   if (aDMSLS.Contains(aS1)) {
841     BOPCol_ListOfShape& aLS=aDMSLS.ChangeFromKey(aS1);
842     aLS.Append(aS2);
843   }
844   else {
845     BOPCol_ListOfShape aLS(aAllocator);
846     aLS.Append(aS2);
847     aDMSLS.Add(aS1, aLS);
848   }
849   //
850   if (aDMSLS.Contains(aS2)) {
851     BOPCol_ListOfShape& aLS=aDMSLS.ChangeFromKey(aS2);
852     aLS.Append(aS1);
853   }
854   else {
855     BOPCol_ListOfShape aLS(aAllocator);
856     aLS.Append(aS1);
857     aDMSLS.Add(aS2, aLS);
858   }
859 }
860 //=======================================================================
861 //function :HasPaveBlocksOnIn
862 //purpose  : 
863 //=======================================================================
864 Standard_Boolean HasPaveBlocksOnIn(const BOPDS_FaceInfo& aFI1,
865                                    const BOPDS_FaceInfo& aFI2)
866 {
867   Standard_Boolean bRet;
868   Standard_Integer i, aNbPB;
869   //
870   bRet=Standard_False;
871   const BOPDS_IndexedMapOfPaveBlock& aMPBOn1 = aFI1.PaveBlocksOn();
872   const BOPDS_IndexedMapOfPaveBlock& aMPBIn1 = aFI1.PaveBlocksIn();
873   //
874   const BOPDS_IndexedMapOfPaveBlock& aMPBOn2 = aFI2.PaveBlocksOn();
875   aNbPB = aMPBOn2.Extent();
876   for (i = 1; i <= aNbPB; ++i) {
877     const Handle(BOPDS_PaveBlock)& aPB = aMPBOn2(i);
878     bRet = aMPBOn1.Contains(aPB) || aMPBIn1.Contains(aPB);
879     if (bRet) {
880       return bRet;
881     }
882   }
883   //
884   const BOPDS_IndexedMapOfPaveBlock& aMPBIn2 = aFI2.PaveBlocksIn();
885   aNbPB = aMPBIn2.Extent();
886   for (i = 1; i <= aNbPB; ++i) {
887     const Handle(BOPDS_PaveBlock)& aPB = aMPBIn2(i);
888     bRet = aMPBOn1.Contains(aPB) || aMPBIn1.Contains(aPB);
889     if (bRet) {
890       return bRet;
891     }
892   }
893   return bRet;
894 }
895
896 /*
897 //DEBf
898     {
899       TopoDS_Compound aCx;
900       BRep_Builder aBBx;
901       BOPCol_ListIteratorOfListOfShape aItx;
902       //
903       aBBx.MakeCompound(aCx);
904       aBBx.Add(aCx, aFF);
905       aItx.Initialize(aLE);
906       for (; aItx.More(); aItx.Next()) {
907       const TopoDS_Shape& aEx=aItx.Value();
908       aBBx.Add(aCx, aEx);
909       }
910       int a=0;
911     }
912     //DEBt
913 */