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