e096dee4123ef41e73d96ec9193d38f8a9642c00
[occt.git] / src / BOPAlgo / BOPAlgo_Builder_2.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2012 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 // The content of this file is subject to the Open CASCADE Technology Public
8 // License Version 6.5 (the "License"). You may not use the content of this file
9 // except in compliance with the License. Please obtain a copy of the License
10 // at http://www.opencascade.org and read it completely before using this file.
11 //
12 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
13 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 //
15 // The Original Code and all software distributed under the License is
16 // distributed on an "AS IS" basis, without warranty of any kind, and the
17 // Initial Developer hereby disclaims all such warranties, including without
18 // limitation, any warranties of merchantability, fitness for a particular
19 // purpose or non-infringement. Please see the License for the specific terms
20 // and conditions governing the rights and limitations under the License.
21
22 #include <BOPAlgo_Builder.ixx>
23
24 #include <NCollection_IncAllocator.hxx>
25
26 #include <TopoDS_Shape.hxx>
27 #include <TopoDS_Face.hxx>
28 #include <TopoDS_Edge.hxx>
29 #include <TopoDS_Vertex.hxx>
30 #include <TopoDS_Compound.hxx>
31
32 #include <BRep_Tool.hxx>
33 #include <BRep_Builder.hxx>
34
35 #include <TopExp_Explorer.hxx>
36
37 #include <BOPCol_ListOfShape.hxx>
38 #include <BOPCol_ListOfInteger.hxx>
39 #include <BOPCol_MapOfInteger.hxx>
40 #include <BOPCol_DataMapOfIntegerListOfShape.hxx>
41 #include <BOPCol_DataMapOfShapeShape.hxx>
42
43 #include <BOPInt_Context.hxx>
44
45 #include <BOPDS_PaveBlock.hxx>
46 #include <BOPDS_ShapeInfo.hxx>
47 #include <BOPDS_DS.hxx>
48 #include <BOPDS_FaceInfo.hxx>
49 #include <BOPDS_MapOfPaveBlock.hxx>
50 #include <BOPDS_VectorOfInterfFF.hxx>
51 #include <BOPDS_Interf.hxx>
52 #include <BOPDS_VectorOfCurve.hxx>
53 #include <BOPDS_VectorOfPoint.hxx>
54
55 #include <BOPTools.hxx>
56 #include <BOPTools_AlgoTools.hxx>
57 #include <BOPTools_AlgoTools2D.hxx>
58 #include <BOPTools_AlgoTools3D.hxx>
59 #include <BOPAlgo_BuilderFace.hxx>
60 #include <BOPTools_CoupleOfShape.hxx>
61 #include <BOPTools_ListOfCoupleOfShape.hxx>
62 #include <BOPTools_MapOfSet.hxx>
63 #include <BOPTools_DataMapOfShapeSet.hxx>
64 #include <BOPAlgo_Builder_2Cnt.hxx>
65
66 static
67   Standard_Boolean HasPaveBlocksOnIn(const BOPDS_FaceInfo& aFI1,
68                                      const BOPDS_FaceInfo& aFI2);
69 static
70   void FillMap(const TopoDS_Shape& aS1,
71                const TopoDS_Shape& aS2,
72                BOPCol_IndexedDataMapOfShapeListOfShape& aDMSLS,
73                Handle(NCollection_IncAllocator)& aAllocator);
74 static
75   void MakeBlocksCnx(const BOPCol_IndexedDataMapOfShapeListOfShape& aMILI,
76                      BOPCol_DataMapOfIntegerListOfShape& aMBlocks,
77                      Handle(NCollection_IncAllocator)& aAllocator);
78
79
80 //=======================================================================
81 //function : FillImagesFaces
82 //purpose  : 
83 //=======================================================================
84 void BOPAlgo_Builder::FillImagesFaces()
85 {
86   myErrorStatus=0;
87   //
88   BuildSplitFaces();
89   FillSameDomainFaces();
90   FillImagesFaces1();
91 }
92 //=======================================================================
93 //function : BuildSplitFaces
94 //purpose  : 
95 //=======================================================================
96 void BOPAlgo_Builder::BuildSplitFaces()
97 {
98   Standard_Boolean bHasFaceInfo, bIsClosed, bIsDegenerated, bToReverse;
99   Standard_Integer i, j, aNbS, aNbPBIn, aNbPBOn, aNbPBSc, aNbAV, nSp;
100   Standard_Boolean bRunParallel;
101   Standard_Size aNbBF, k;
102   TopoDS_Face aFF, aFSD;
103   TopoDS_Edge aSp, aEE;
104   TopAbs_Orientation anOriF, anOriE;
105   TopExp_Explorer aExp;
106   BOPCol_ListIteratorOfListOfShape aIt;
107   BOPCol_ListOfInteger aLIAV;
108   BOPCol_MapOfShape aMFence;
109   Handle(NCollection_BaseAllocator) aAllocator;
110   BOPCol_ListOfShape aLFIm(myAllocator);
111   BOPCol_MapIteratorOfMapOfShape aItMS;
112   BOPAlgo_VectorOfBuilderFace aVBF;
113   //
114   myErrorStatus=0;
115   //
116   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~scope f
117   aAllocator=new NCollection_IncAllocator();
118   //
119   BOPCol_ListOfShape aLE(aAllocator);
120   BOPCol_MapOfShape aMDE(100, aAllocator);
121   //
122   aNbS=myDS->NbSourceShapes();
123   //
124   for (i=0; i<aNbS; ++i) {
125     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
126     if (aSI.ShapeType()!=TopAbs_FACE) {
127       continue;
128     }
129     //
130     const TopoDS_Face& aF=(*(TopoDS_Face*)(&aSI.Shape()));
131     //
132     bHasFaceInfo=myDS->HasFaceInfo(i);
133     if(!bHasFaceInfo) {
134       continue;
135     }
136     //
137     const BOPDS_FaceInfo& aFI=myDS->FaceInfo(i);
138     //
139     const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
140     const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn();
141     const BOPDS_IndexedMapOfPaveBlock& aMPBSc=aFI.PaveBlocksSc();
142     aLIAV.Clear();
143     myDS->AloneVertices(i, aLIAV);
144     
145     aNbPBIn=aMPBIn.Extent();
146     aNbPBOn=aMPBOn.Extent();
147     aNbPBSc=aMPBSc.Extent();
148     aNbAV=aLIAV.Extent();
149     if (!aNbPBIn && !aNbPBOn && !aNbPBSc && !aNbAV) { // not compete
150       continue;
151     }
152     //
153     aMFence.Clear();
154     //
155     anOriF=aF.Orientation();
156     aFF=aF;
157     aFF.Orientation(TopAbs_FORWARD);
158     //
159     
160     //
161     // 1. Fill the egdes set for the face aFF -> LE
162     aLE.Clear();
163     //
164     //
165     // 1.1 Bounding edges
166     aExp.Init(aFF, TopAbs_EDGE);
167     for (; aExp.More(); aExp.Next()) {
168       const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
169       anOriE=aE.Orientation();
170       bIsDegenerated=BRep_Tool::Degenerated(aE);
171       bIsClosed=BRep_Tool::IsClosed(aE, aF);
172       //
173       if (!myImages.IsBound(aE)) {
174         if (anOriE==TopAbs_INTERNAL) {
175           aEE=aE;
176           aEE.Orientation(TopAbs_FORWARD);
177           aLE.Append(aEE);
178           aEE.Orientation(TopAbs_REVERSED);
179           aLE.Append(aEE);
180         }
181         else {
182           aLE.Append(aE);
183         }
184       }
185       else {//else 1
186         const BOPCol_ListOfShape& aLIE=myImages.Find(aE);
187         aIt.Initialize(aLIE);
188         for (; aIt.More(); aIt.Next()) {
189           aSp=(*(TopoDS_Edge*)(&aIt.Value()));
190           if (bIsDegenerated) {
191             aSp.Orientation(anOriE);
192             aLE.Append(aSp);
193             continue;
194           }
195           //
196           if (anOriE==TopAbs_INTERNAL) {
197             aSp.Orientation(TopAbs_FORWARD);
198             aLE.Append(aSp);
199             aSp.Orientation(TopAbs_REVERSED);
200             aLE.Append(aSp);
201             continue;
202           }
203           //
204           if (bIsClosed) {
205             if (aMFence.Add(aSp)) {
206               if (!BRep_Tool::IsClosed(aSp, aF)){
207                 BOPTools_AlgoTools3D::DoSplitSEAMOnFace(aSp, aF);
208                 }
209               //
210               aSp.Orientation(TopAbs_FORWARD);
211               aLE.Append(aSp);
212               aSp.Orientation(TopAbs_REVERSED);
213               aLE.Append(aSp);
214             }// if (aMFence.Add(aSp))
215             continue;
216           }// if (bIsClosed){
217           //
218           aSp.Orientation(anOriE);
219           bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aSp, aE, myContext);
220           if (bToReverse) {
221             aSp.Reverse();
222           }
223           aLE.Append(aSp);
224         }// for (; aIt.More(); aIt.Next()) {
225       }// else 1
226     }// for (; aExp.More(); aExp.Next()) {
227     // 
228     //
229     // 1.2 In edges
230     for (j=1; j<=aNbPBIn; ++j) {
231       const Handle(BOPDS_PaveBlock)& aPB=aMPBIn(j);
232       nSp=aPB->Edge();
233       aSp=(*(TopoDS_Edge*)(&myDS->Shape(nSp)));
234       //
235       aSp.Orientation(TopAbs_FORWARD);
236       aLE.Append(aSp);
237       aSp.Orientation(TopAbs_REVERSED);
238       aLE.Append(aSp);
239     }
240     //
241     //
242     // 1.3 Section edges
243     for (j=1; j<=aNbPBSc; ++j) {
244       const Handle(BOPDS_PaveBlock)& aPB=aMPBSc(j);
245       nSp=aPB->Edge();
246       aSp=(*(TopoDS_Edge*)(&myDS->Shape(nSp)));
247       //
248       aSp.Orientation(TopAbs_FORWARD);
249       aLE.Append(aSp);
250       aSp.Orientation(TopAbs_REVERSED);
251       aLE.Append(aSp);
252     }
253     //
254     BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane (aLE, aFF);
255     //
256     // 3 Build split faces
257     BOPAlgo_BuilderFace& aBF=aVBF.Append1();
258     aBF.SetFace(aF);
259     aBF.SetShapes(aLE);
260     //
261   }// for (i=0; i<aNbS; ++i) {
262   //
263   aNbBF=aVBF.Extent();
264   //
265   //===================================================
266   bRunParallel=Standard_True;
267   BOPAlgo_BuilderFaceCnt::Perform(bRunParallel, aVBF);
268   //===================================================
269   //
270   for (k=0; k<aNbBF; ++k) {
271     aLFIm.Clear();
272     //
273     BOPAlgo_BuilderFace& aBF=aVBF(k);
274     TopoDS_Face aF=aBF.Face();
275     anOriF=aBF.Orientation();
276     aF.Orientation(anOriF);
277     //
278     const BOPCol_ListOfShape& aLFR=aBF.Areas();
279     aIt.Initialize(aLFR);
280     for (; aIt.More(); aIt.Next()) {
281       TopoDS_Shape& aFR=aIt.ChangeValue();
282       if (anOriF==TopAbs_REVERSED) {
283         aFR.Orientation(TopAbs_REVERSED);
284       }
285       //aFR.Orientation(anOriF);
286       aLFIm.Append(aFR);
287     }
288     //
289     mySplits.Bind(aF, aLFIm); 
290   }// for (k=0; k<aNbBF; ++k) {
291   //
292   aAllocator.Nullify();
293   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~scope t
294 }
295 //=======================================================================
296 //function : FillSameDomainFaces
297 //purpose  : 
298 //=======================================================================
299 void BOPAlgo_Builder::FillSameDomainFaces()
300 {
301   Standard_Boolean bFlag;
302   Standard_Integer i, j, k, aNbFFs, aNbCurves, aNbPoints, nF1, nF2, aNbS;
303   Handle(NCollection_IncAllocator) aAllocator;
304   BOPCol_ListIteratorOfListOfShape aItF;
305   BOPCol_MapOfShape aMFence;
306   BOPAlgo_IndexedDataMapOfSetInteger aIDMSS;
307   BOPAlgo_VectorOfVectorOfShape aVVS;
308 //
309   myErrorStatus=0;
310   //
311   const BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
312   //
313   aNbFFs=aFFs.Extent();
314   if (!aNbFFs) {
315     return;
316   }
317   //
318   for (i=0; i<aNbFFs; ++i) {
319     const BOPDS_InterfFF& aFF=aFFs(i);
320     aFF.Indices(nF1, nF2);
321     //
322     const BOPDS_VectorOfCurve& aCurves=aFF.Curves();
323     aNbCurves=aCurves.Extent();
324     if (aNbCurves) {
325       //
326       bFlag=Standard_False;
327       for (j=0; j<aNbCurves; ++j) {
328         const BOPDS_Curve& aNC=aCurves.Value(j);
329         bFlag=aNC.HasEdge();
330         if (bFlag) {
331           break;
332         }
333       }
334       if (bFlag) {
335         continue;
336       }
337       //continue;
338     }
339     //
340     const BOPDS_VectorOfPoint& aPoints=aFF.Points();
341     aNbPoints=aPoints.Extent();
342     if (aNbPoints) {
343       continue;
344     }
345     //
346     if (!myDS->HasFaceInfo(nF1) || !myDS->HasFaceInfo(nF2) ) {
347       continue;
348     }
349     //
350     const BOPDS_FaceInfo& aFI1=myDS->FaceInfo(nF1);
351     const BOPDS_FaceInfo& aFI2=myDS->FaceInfo(nF2);
352     //
353     const TopoDS_Shape& aF1=myDS->Shape(nF1);
354     const TopoDS_Shape& aF2=myDS->Shape(nF2);
355     //
356     bFlag=HasPaveBlocksOnIn(aFI1, aFI2);
357     bFlag=bFlag && (mySplits.IsBound(aF1) && mySplits.IsBound(aF2));
358     //
359     if (bFlag) {
360       for (k=0; k<2; ++k) {
361         const TopoDS_Shape& aF=(!k) ? aF1 : aF2;
362         const BOPCol_ListOfShape& aLF=mySplits.Find(aF);
363         //
364         aItF.Initialize(aLF);
365         for (; aItF.More(); aItF.Next()) {
366           const TopoDS_Shape& aFx=aItF.Value();
367           //
368           if (aMFence.Add(aFx)) {
369             BOPTools_Set aSTx;
370             //
371             aSTx.AddEdges(aFx);
372             //
373             if (!aIDMSS.Contains(aSTx)) {
374               BOPAlgo_VectorOfShape& aVS=aVVS.Append1(); 
375               aVS.Append(aFx);
376               //
377               j=aVVS.Extent()-1;
378               aIDMSS.Add (aSTx, j);
379             }
380             else {
381               j=aIDMSS.ChangeFromKey(aSTx);
382               BOPAlgo_VectorOfShape& aVS=aVVS(j);
383               aVS.Append(aFx);
384             }
385           }
386         }
387       }
388     }// if (bFlag) {
389     else {// if (!bFlag) 
390       BOPTools_Set aST1, aST2;
391       //
392       aST1.AddEdges(aF1);
393       aST2.AddEdges(aF2);
394       //
395       if (aST1.IsEqual(aST2)) {
396         if (!aIDMSS.Contains(aST1)) {
397           BOPAlgo_VectorOfShape& aVS=aVVS.Append1(); 
398           if (aMFence.Add(aF1)) {
399             aVS.Append(aF1);
400           }
401           if (aMFence.Add(aF2)) {
402             aVS.Append(aF2);
403           }
404           //
405           k=aVVS.Extent()-1;
406           aIDMSS.Add (aST1, k);
407         }
408         else {
409           k=aIDMSS.ChangeFromKey(aST1);
410           BOPAlgo_VectorOfShape& aVS=aVVS(k);
411           if (aMFence.Add(aF1)) {
412             aVS.Append(aF1);
413           }
414           if (aMFence.Add(aF2)) {
415             aVS.Append(aF2);
416           }
417         }
418       }//if (aST1.IsEqual(aST2)) {
419     }// else {// if (!bFlag) 
420     //
421   }// for (i=0; i<aNbFFs; ++i) {
422   //
423   aIDMSS.Clear();
424   //
425   Standard_Boolean bRunParallel, bFlagSD;
426   Standard_Integer aNbVPSB, aNbVVS, aNbF, aNbF1;
427   BOPAlgo_VectorOfPairOfShapeBoolean aVPSB;
428   //
429   aNbVVS=aVVS.Extent();
430   for (i=0; i<aNbVVS; ++i) {
431     const BOPAlgo_VectorOfShape& aVS=aVVS(i);
432     aNbF=aVS.Extent();
433     if (aNbF<2) {
434       continue;
435     }
436     //
437     aNbF1=aNbF-1;
438     for (j=0; j<aNbF1; ++j) {
439       const TopoDS_Shape& aFj=aVS(j);
440       for (k=j+1; k<aNbF; ++k) {
441         const TopoDS_Shape& aFk=aVS(k);
442         BOPAlgo_PairOfShapeBoolean& aPSB=aVPSB.Append1();
443         aPSB.Shape1()=aFj;
444         aPSB.Shape2()=aFk;
445       }
446     }
447   }
448   //====================================================
449   bRunParallel=Standard_True;
450   BOPAlgo_BuilderSDFaceCnt::Perform(bRunParallel, aVPSB);
451   //====================================================
452   aAllocator=new NCollection_IncAllocator();
453   BOPCol_IndexedDataMapOfShapeListOfShape aDMSLS(100, aAllocator);
454   BOPCol_DataMapOfIntegerListOfShape aMBlocks(100, aAllocator);
455   //
456   aNbVPSB=aVPSB.Extent();
457   for (i=0; i<aNbVPSB; ++i) {
458     BOPAlgo_PairOfShapeBoolean& aPSB=aVPSB(i);
459     bFlagSD=aPSB.Flag();
460     if (bFlagSD) {
461       const TopoDS_Shape& aFj=aPSB.Shape1();
462       const TopoDS_Shape& aFk=aPSB.Shape2();
463       FillMap(aFj, aFk, aDMSLS, aAllocator);
464     }
465   }
466   aVPSB.Clear();
467   //
468   // 2. Make blocks
469   MakeBlocksCnx(aDMSLS, aMBlocks, aAllocator);
470   //
471   // 3. Fill same domain faces map -> aMSDF
472   aNbS = aMBlocks.Extent();
473   for (i=0; i<aNbS; ++i) {
474     const BOPCol_ListOfShape& aLSD=aMBlocks.Find(i);
475     if (aLSD.IsEmpty()) {
476       continue;
477     }
478     //
479     const TopoDS_Shape& aFSD1=aLSD.First();
480     aItF.Initialize(aLSD);
481     for (; aItF.More(); aItF.Next()) {
482       const TopoDS_Shape& aFSD=aItF.Value();
483       myShapesSD.Bind(aFSD, aFSD1);
484       //
485       // If the face has no splits but are SD face,
486       // it is considered as splitted face
487       if (!mySplits.IsBound(aFSD)) {
488         BOPCol_ListOfShape aLS;
489         aLS.Append(aFSD);
490         mySplits.Bind(aFSD, aLS);
491       }
492     }
493   }
494   aMBlocks.Clear();
495   aDMSLS.Clear();
496   aAllocator.Nullify();
497 }
498 //=======================================================================
499 // function: FillImagesFaces1
500 // purpose: 
501 //=======================================================================
502 void BOPAlgo_Builder::FillImagesFaces1()
503 {
504   Standard_Integer i, aNbS, iSense;
505   TopoDS_Face aFSD;
506   BOPCol_ListOfInteger aLIAV;
507   BOPCol_ListOfShape aLFIm;
508   BOPCol_ListIteratorOfListOfShape aItLS;
509   //
510   aNbS=myDS->NbSourceShapes();
511   for (i=0; i<aNbS; ++i) {
512     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
513     if (aSI.ShapeType()!=TopAbs_FACE) {
514       continue;
515     }
516     //
517     const TopoDS_Face& aF=(*(TopoDS_Face*)(&aSI.Shape()));
518     //
519     if (!mySplits.IsBound(aF)) {
520       continue;
521     }
522     //
523     aLIAV.Clear();
524     myDS->AloneVertices(i, aLIAV);
525     aLFIm.Clear();
526     //
527     const BOPCol_ListOfShape& aLSp=mySplits.Find(aF);
528     aItLS.Initialize(aLSp);
529     for (; aItLS.More(); aItLS.Next()) {
530       const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&aItLS.Value()));
531       if (!myShapesSD.IsBound(aFSp)) {
532         aLFIm.Append(aFSp);
533       }
534       else {
535         aFSD=(*(TopoDS_Face*)(&myShapesSD.Find(aFSp)));
536         iSense=BOPTools_AlgoTools::Sense(aFSp, aFSD);
537         if (iSense<0) {
538           aFSD.Reverse();
539         }
540         aLFIm.Append(aFSD);
541       }
542     }
543     //
544     FillInternalVertices(aLFIm, aLIAV);
545     //
546     myImages.Bind(aF, aLFIm); 
547     //
548     //fill myOrigins
549     aItLS.Initialize(aLFIm);
550     for (; aItLS.More(); aItLS.Next()) {
551       const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&aItLS.Value()));
552       myOrigins.Bind(aFSp, aF);
553     }
554   }// for (i=0; i<aNbS; ++i) {
555 }
556 //=======================================================================
557 // function: FillInternalVertices
558 // purpose: 
559 //=======================================================================
560 void BOPAlgo_Builder::FillInternalVertices(BOPCol_ListOfShape& aLFIm,
561                                            BOPCol_ListOfInteger& aLIAV)
562 {
563   Standard_Integer nV, iFlag;
564   Standard_Real aU1, aU2;
565   TopoDS_Vertex aV;
566   BRep_Builder aBB;
567   BOPCol_ListIteratorOfListOfInteger aItV;
568   BOPCol_ListIteratorOfListOfShape aItF;
569   //
570   aItV.Initialize(aLIAV);
571   for (; aItV.More(); aItV.Next()) {
572     nV=aItV.Value();
573     aV=(*(TopoDS_Vertex*)(&myDS->Shape(nV)));
574     aV.Orientation(TopAbs_INTERNAL);
575     //
576     aItF.Initialize(aLFIm);
577     for (; aItF.More(); aItF.Next()) {
578       TopoDS_Face& aF=(*(TopoDS_Face*)(&aItF.Value()));
579       iFlag=myContext->ComputeVF(aV, aF, aU1, aU2);
580       if (!iFlag) {
581         aBB.Add(aF, aV);
582         break;
583       }
584     }
585   }
586 }
587 //=======================================================================
588 //function : MakeBlocksCnx
589 //purpose  : 
590 //=======================================================================
591 void MakeBlocksCnx(const BOPCol_IndexedDataMapOfShapeListOfShape& aMILI,
592                    BOPCol_DataMapOfIntegerListOfShape& aMBlocks,
593                    Handle(NCollection_IncAllocator)& aAllocator)
594 {
595   Standard_Integer aNbV, aNbVS, aNbVP, aNbEC, k, i, j;
596   BOPCol_ListIteratorOfListOfShape aItLI;
597   //
598   BOPCol_MapOfShape aMVS(100, aAllocator);
599   BOPCol_IndexedMapOfShape aMEC(100, aAllocator);
600   BOPCol_IndexedMapOfShape aMVP(100, aAllocator);
601   BOPCol_IndexedMapOfShape aMVAdd(100, aAllocator);
602   //
603   aNbV=aMILI.Extent();
604   //
605   for (k=0,i=1; i<=aNbV; ++i) {
606     aNbVS=aMVS.Extent();
607     if (aNbVS==aNbV) {
608       break;
609     }
610     //
611     const TopoDS_Shape& nV=aMILI.FindKey(i);
612     if (aMVS.Contains(nV)){
613       continue;
614     }
615     aMVS.Add(nV);
616     //
617     aMEC.Clear();
618     aMVP.Clear();
619     aMVAdd.Clear();
620     //
621     aMVP.Add(nV);
622     for(;;) {
623       aNbVP=aMVP.Extent();
624       for (j=1; j<=aNbVP; ++j) {
625         const TopoDS_Shape& nVP=aMVP(j);
626         const BOPCol_ListOfShape& aLV=aMILI.FindFromKey(nVP);
627         aItLI.Initialize(aLV);
628         for (; aItLI.More(); aItLI.Next()) {
629           const TopoDS_Shape& nVx=aItLI.Value();
630           if (aMEC.Contains(nVx)) {
631             continue;
632           }
633           //
634           aMVS.Add(nVx);
635           aMEC.Add(nVx);
636           aMVAdd.Add(nVx);
637         }
638       }
639       //
640       aNbVP=aMVAdd.Extent();
641       if (!aNbVP) {
642         break; // from while(1)
643       }
644       //
645       aMVP.Clear();
646       for (j=1; j<=aNbVP; ++j) {
647         aMVP.Add(aMVAdd(j));
648       }
649       aMVAdd.Clear();
650     }//while(1) {
651     //
652     BOPCol_ListOfShape aLIx(aAllocator);
653     //
654     aNbEC = aMEC.Extent();
655     for (j=1; j<=aNbEC; ++j) {
656       const TopoDS_Shape& nVx=aMEC(j);
657       aLIx.Append(nVx);
658     }
659     //
660     aMBlocks.Bind(k, aLIx);
661     ++k;
662   }//for (k=0,i=1; i<=aNbV; ++i)
663   aMVAdd.Clear();
664   aMVP.Clear();
665   aMEC.Clear();
666   aMVS.Clear();
667 }
668
669 //=======================================================================
670 //function : FillMap
671 //purpose  : 
672 //=======================================================================
673 void FillMap(const TopoDS_Shape& aS1,
674              const TopoDS_Shape& aS2,
675              BOPCol_IndexedDataMapOfShapeListOfShape& aDMSLS,
676              Handle(NCollection_IncAllocator)& aAllocator)
677 {
678   if (aDMSLS.Contains(aS1)) {
679     BOPCol_ListOfShape& aLS=aDMSLS.ChangeFromKey(aS1);
680     aLS.Append(aS2);
681   }
682   else {
683     BOPCol_ListOfShape aLS(aAllocator);
684     aLS.Append(aS2);
685     aDMSLS.Add(aS1, aLS);
686   }
687   //
688   if (aDMSLS.Contains(aS2)) {
689     BOPCol_ListOfShape& aLS=aDMSLS.ChangeFromKey(aS2);
690     aLS.Append(aS1);
691   }
692   else {
693     BOPCol_ListOfShape aLS(aAllocator);
694     aLS.Append(aS1);
695     aDMSLS.Add(aS2, aLS);
696   }
697 }
698 //=======================================================================
699 //function :HasPaveBlocksOnIn
700 //purpose  : 
701 //=======================================================================
702 Standard_Boolean HasPaveBlocksOnIn(const BOPDS_FaceInfo& aFI1,
703                                    const BOPDS_FaceInfo& aFI2)
704 {
705   Standard_Boolean bRet;
706   BOPDS_MapIteratorOfMapOfPaveBlock aItMPB;
707   //
708   bRet=Standard_False;
709   const BOPDS_IndexedMapOfPaveBlock& aMPBOn1=aFI1.PaveBlocksOn();
710   const BOPDS_IndexedMapOfPaveBlock& aMPBIn1=aFI1.PaveBlocksIn();
711   //
712   const BOPDS_IndexedMapOfPaveBlock& aMPBOn2=aFI2.PaveBlocksOn();
713   aItMPB.Initialize(aMPBOn2);
714   for (; aItMPB.More(); aItMPB.Next()) {
715     const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
716     bRet=aMPBOn1.Contains(aPB) || aMPBIn1.Contains(aPB);
717     if (bRet) {
718       return bRet;
719     }
720   }
721   //
722   const BOPDS_IndexedMapOfPaveBlock& aMPBIn2=aFI2.PaveBlocksIn();
723   aItMPB.Initialize(aMPBIn2);
724   for (; aItMPB.More(); aItMPB.Next()) {
725     const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
726     bRet=aMPBOn1.Contains(aPB) || aMPBIn1.Contains(aPB);
727     if (bRet) {
728       return bRet;
729     }
730   }
731   return bRet;
732 }
733 /*
734 //DEBf
735     {
736       TopoDS_Compound aCx;
737       BRep_Builder aBBx;
738       BOPCol_ListIteratorOfListOfShape aItx;
739       //
740       aBBx.MakeCompound(aCx);
741       aBBx.Add(aCx, aFF);
742       aItx.Initialize(aLE);
743       for (; aItx.More(); aItx.Next()) {
744       const TopoDS_Shape& aEx=aItx.Value();
745       aBBx.Add(aCx, aEx);
746       }
747       int a=0;
748     }
749     //DEBt
750 */