0024157: Parallelization of Assembly part of BO
[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, aNbFFs, aNbCurves, aNbPoints, nF1, nF2, aNbS;
303   Standard_Integer j;
304   Handle(NCollection_IncAllocator) aAllocator;
305   BOPCol_ListIteratorOfListOfShape aItF1, aItF2;
306   BOPTools_ListOfCoupleOfShape aLCS;  
307   BOPCol_ListIteratorOfListOfShape aItLS;
308   BOPCol_MapOfShape aMF;
309   BOPCol_MapIteratorOfMapOfShape aItMF;
310   //
311   myErrorStatus=0;
312   //
313   const BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
314   //
315   aNbFFs=aFFs.Extent();
316   if (!aNbFFs) {
317     return;
318   }
319   //-----------------------------------------------------scope f
320   aAllocator=new NCollection_IncAllocator();
321   BOPCol_IndexedDataMapOfShapeListOfShape aDMSLS(100, aAllocator);
322   BOPCol_DataMapOfIntegerListOfShape aMBlocks(100, aAllocator);
323   BOPTools_DataMapOfShapeSet aMSST(100, aAllocator);
324   //
325   BOPCol_ListOfShape aLFIm;
326   //
327   for (i=0; i<aNbFFs; ++i) {
328     const BOPDS_InterfFF& aFF=aFFs(i);
329     aFF.Indices(nF1, nF2);
330     //
331     const BOPDS_VectorOfCurve& aCurves=aFF.Curves();
332     aNbCurves=aCurves.Extent();
333     if (aNbCurves) {
334       //
335       bFlag=Standard_False;
336       for (j=0; j<aNbCurves; ++j) {
337         const BOPDS_Curve& aNC=aCurves.Value(j);
338         bFlag=aNC.HasEdge();
339         if (bFlag) {
340           break;
341         }
342       }
343       if (bFlag) {
344         continue;
345       }
346       //continue;
347     }
348     //
349     const BOPDS_VectorOfPoint& aPoints=aFF.Points();
350     aNbPoints=aPoints.Extent();
351     if (aNbPoints) {
352       continue;
353     }
354     //
355     if (!myDS->HasFaceInfo(nF1) || !myDS->HasFaceInfo(nF2) ) {
356       continue;
357     }
358     //
359     const BOPDS_FaceInfo& aFI1=myDS->FaceInfo(nF1);
360     const BOPDS_FaceInfo& aFI2=myDS->FaceInfo(nF2);
361     bFlag=HasPaveBlocksOnIn(aFI1, aFI2);
362     //
363     const TopoDS_Face& aF1=(*(TopoDS_Face*)(&myDS->Shape(nF1)));
364     const TopoDS_Face& aF2=(*(TopoDS_Face*)(&myDS->Shape(nF2)));
365     bFlag=bFlag && (mySplits.IsBound(aF1) && mySplits.IsBound(aF2));
366     //
367     if (!bFlag) {
368       //case when the faces have shared bounds
369       if (!aMSST.IsBound(aF1)) {
370         BOPTools_Set aST1(aAllocator);
371         aMSST.Bind(aF1, aST1);
372         BOPTools_Set& aST=aMSST.ChangeFind(aF1);
373         aST.AddEdges(aF1);
374       }
375       //
376       if (!aMSST.IsBound(aF2)) {
377         BOPTools_Set aST2(aAllocator);
378         aMSST.Bind(aF2, aST2);
379         BOPTools_Set& aST=aMSST.ChangeFind(aF2);
380         aST.AddEdges(aF2);
381       }
382       //
383       const BOPTools_Set& aST1=aMSST.Find(aF1);
384       const BOPTools_Set& aST2=aMSST.Find(aF2);
385       if (aST1.IsEqual(aST2)) {
386         bFlag=BOPTools_AlgoTools::AreFacesSameDomain(aF1, aF2, myContext);
387         if (bFlag) {
388           FillMap(aF1, aF2, aDMSLS, aAllocator);
389           aMF.Add(aF1);
390           aMF.Add(aF2);
391         }
392       }
393       continue;
394     }
395     //
396     const BOPCol_ListOfShape& aLF1=mySplits.Find(aF1);
397     const BOPCol_ListOfShape& aLF2=mySplits.Find(aF2);
398     //
399     aItF1.Initialize(aLF1);
400     for (; aItF1.More(); aItF1.Next()) {
401       const TopoDS_Face& aF1x=(*(TopoDS_Face*)(&aItF1.Value()));
402       if (!aMSST.IsBound(aF1x)) {
403         BOPTools_Set aST1(aAllocator);
404         //
405         aMSST.Bind(aF1x, aST1);
406         BOPTools_Set& aST=aMSST.ChangeFind(aF1x);
407         aST.AddEdges(aF1x);
408       }
409       //
410       aItF2.Initialize(aLF2);
411       for (; aItF2.More(); aItF2.Next()) {
412         const TopoDS_Face& aF2y=(*(TopoDS_Face*)(&aItF2.Value()));
413         if (!aMSST.IsBound(aF2y)) {
414           BOPTools_Set aST2(aAllocator);
415           //
416           aMSST.Bind(aF2y, aST2);
417           BOPTools_Set& aST=aMSST.ChangeFind(aF2y);
418           aST.AddEdges(aF2y);
419         }
420         //
421         const BOPTools_Set& aST1=aMSST.Find(aF1x);
422         const BOPTools_Set& aST2=aMSST.Find(aF2y);
423         //
424         if (aST1.IsEqual(aST2)) {
425           bFlag=BOPTools_AlgoTools::AreFacesSameDomain(aF1x, aF2y, myContext);
426           if (bFlag) {
427             FillMap(aF1x, aF2y, aDMSLS, aAllocator);
428           }
429         }
430       }
431     }  
432   } // for (i=0; i<aNbFFs; ++i) {
433   //
434   // 2. Make blocks
435   MakeBlocksCnx(aDMSLS, aMBlocks, aAllocator);
436   //
437   // 3. Fill same domain faces map -> aMSDF
438   aNbS = aMBlocks.Extent();
439   for (i=0; i<aNbS; ++i) {
440     const BOPCol_ListOfShape& aLSD=aMBlocks.Find(i);
441     if (aLSD.Extent()) {
442       const TopoDS_Shape& aFSD1=aLSD.First();
443       aItLS.Initialize(aLSD);
444       for (; aItLS.More(); aItLS.Next()) {
445         const TopoDS_Shape& aFSD=aItLS.Value();
446         myShapesSD.Bind(aFSD, aFSD1);
447       }
448     }
449   }
450   //
451   aItMF.Initialize(aMF);
452   for (; aItMF.More(); aItMF.Next()){
453     const TopoDS_Shape& aF = aItMF.Value();
454     //
455     BOPCol_ListOfShape aLS;
456     aLS.Append(aF);
457     mySplits.Bind(aF, aLS);
458   }
459   //-----------------------------------------------------scope t
460   aMSST.Clear();
461   aMBlocks.Clear();
462   aDMSLS.Clear();
463   aAllocator.Nullify();
464 }
465 //=======================================================================
466 // function: FillImagesFaces1
467 // purpose: 
468 //=======================================================================
469 void BOPAlgo_Builder::FillImagesFaces1()
470 {
471   Standard_Integer i, aNbS, iSense;
472   TopoDS_Face aFSD;
473   BOPCol_ListOfInteger aLIAV;
474   BOPCol_ListOfShape aLFIm;
475   BOPCol_ListIteratorOfListOfShape aItLS;
476   //
477   aNbS=myDS->NbSourceShapes();
478   for (i=0; i<aNbS; ++i) {
479     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
480     if (aSI.ShapeType()!=TopAbs_FACE) {
481       continue;
482     }
483     //
484     const TopoDS_Face& aF=(*(TopoDS_Face*)(&aSI.Shape()));
485     //
486     if (!mySplits.IsBound(aF)) {
487       continue;
488     }
489     //
490     aLIAV.Clear();
491     myDS->AloneVertices(i, aLIAV);
492     aLFIm.Clear();
493     //
494     const BOPCol_ListOfShape& aLSp=mySplits.Find(aF);
495     aItLS.Initialize(aLSp);
496     for (; aItLS.More(); aItLS.Next()) {
497       const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&aItLS.Value()));
498       if (!myShapesSD.IsBound(aFSp)) {
499         aLFIm.Append(aFSp);
500       }
501       else {
502         aFSD=(*(TopoDS_Face*)(&myShapesSD.Find(aFSp)));
503         iSense=BOPTools_AlgoTools::Sense(aFSp, aFSD);
504         if (iSense<0) {
505           aFSD.Reverse();
506         }
507         aLFIm.Append(aFSD);
508       }
509     }
510     //
511     FillInternalVertices(aLFIm, aLIAV);
512     //
513     myImages.Bind(aF, aLFIm); 
514     //
515     //fill myOrigins
516     aItLS.Initialize(aLFIm);
517     for (; aItLS.More(); aItLS.Next()) {
518       const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&aItLS.Value()));
519       myOrigins.Bind(aFSp, aF);
520     }
521   }// for (i=0; i<aNbS; ++i) {
522 }
523 //=======================================================================
524 // function: FillInternalVertices
525 // purpose: 
526 //=======================================================================
527 void BOPAlgo_Builder::FillInternalVertices(BOPCol_ListOfShape& aLFIm,
528                                            BOPCol_ListOfInteger& aLIAV)
529 {
530   Standard_Integer nV, iFlag;
531   Standard_Real aU1, aU2;
532   TopoDS_Vertex aV;
533   BRep_Builder aBB;
534   BOPCol_ListIteratorOfListOfInteger aItV;
535   BOPCol_ListIteratorOfListOfShape aItF;
536   //
537   aItV.Initialize(aLIAV);
538   for (; aItV.More(); aItV.Next()) {
539     nV=aItV.Value();
540     aV=(*(TopoDS_Vertex*)(&myDS->Shape(nV)));
541     aV.Orientation(TopAbs_INTERNAL);
542     //
543     aItF.Initialize(aLFIm);
544     for (; aItF.More(); aItF.Next()) {
545       TopoDS_Face& aF=(*(TopoDS_Face*)(&aItF.Value()));
546       iFlag=myContext->ComputeVF(aV, aF, aU1, aU2);
547       if (!iFlag) {
548         aBB.Add(aF, aV);
549         break;
550       }
551     }
552   }
553 }
554 //=======================================================================
555 //function : MakeBlocksCnx
556 //purpose  : 
557 //=======================================================================
558 void MakeBlocksCnx(const BOPCol_IndexedDataMapOfShapeListOfShape& aMILI,
559                    BOPCol_DataMapOfIntegerListOfShape& aMBlocks,
560                    Handle(NCollection_IncAllocator)& aAllocator)
561 {
562   Standard_Integer aNbV, aNbVS, aNbVP, aNbEC, k, i, j;
563   BOPCol_ListIteratorOfListOfShape aItLI;
564   //
565   BOPCol_MapOfShape aMVS(100, aAllocator);
566   BOPCol_IndexedMapOfShape aMEC(100, aAllocator);
567   BOPCol_IndexedMapOfShape aMVP(100, aAllocator);
568   BOPCol_IndexedMapOfShape aMVAdd(100, aAllocator);
569   //
570   aNbV=aMILI.Extent();
571   //
572   for (k=0,i=1; i<=aNbV; ++i) {
573     aNbVS=aMVS.Extent();
574     if (aNbVS==aNbV) {
575       break;
576     }
577     //
578     const TopoDS_Shape& nV=aMILI.FindKey(i);
579     if (aMVS.Contains(nV)){
580       continue;
581     }
582     aMVS.Add(nV);
583     //
584     aMEC.Clear();
585     aMVP.Clear();
586     aMVAdd.Clear();
587     //
588     aMVP.Add(nV);
589     for(;;) {
590       aNbVP=aMVP.Extent();
591       for (j=1; j<=aNbVP; ++j) {
592         const TopoDS_Shape& nVP=aMVP(j);
593         const BOPCol_ListOfShape& aLV=aMILI.FindFromKey(nVP);
594         aItLI.Initialize(aLV);
595         for (; aItLI.More(); aItLI.Next()) {
596           const TopoDS_Shape& nVx=aItLI.Value();
597           if (aMEC.Contains(nVx)) {
598             continue;
599           }
600           //
601           aMVS.Add(nVx);
602           aMEC.Add(nVx);
603           aMVAdd.Add(nVx);
604         }
605       }
606       //
607       aNbVP=aMVAdd.Extent();
608       if (!aNbVP) {
609         break; // from while(1)
610       }
611       //
612       aMVP.Clear();
613       for (j=1; j<=aNbVP; ++j) {
614         aMVP.Add(aMVAdd(j));
615       }
616       aMVAdd.Clear();
617     }//while(1) {
618     //
619     BOPCol_ListOfShape aLIx(aAllocator);
620     //
621     aNbEC = aMEC.Extent();
622     for (j=1; j<=aNbEC; ++j) {
623       const TopoDS_Shape& nVx=aMEC(j);
624       aLIx.Append(nVx);
625     }
626     //
627     aMBlocks.Bind(k, aLIx);
628     ++k;
629   }//for (k=0,i=1; i<=aNbV; ++i)
630   aMVAdd.Clear();
631   aMVP.Clear();
632   aMEC.Clear();
633   aMVS.Clear();
634 }
635
636 //=======================================================================
637 //function : FillMap
638 //purpose  : 
639 //=======================================================================
640 void FillMap(const TopoDS_Shape& aS1,
641              const TopoDS_Shape& aS2,
642              BOPCol_IndexedDataMapOfShapeListOfShape& aDMSLS,
643              Handle(NCollection_IncAllocator)& aAllocator)
644 {
645   if (aDMSLS.Contains(aS1)) {
646     BOPCol_ListOfShape& aLS=aDMSLS.ChangeFromKey(aS1);
647     aLS.Append(aS2);
648   }
649   else {
650     BOPCol_ListOfShape aLS(aAllocator);
651     aLS.Append(aS2);
652     aDMSLS.Add(aS1, aLS);
653   }
654   //
655   if (aDMSLS.Contains(aS2)) {
656     BOPCol_ListOfShape& aLS=aDMSLS.ChangeFromKey(aS2);
657     aLS.Append(aS1);
658   }
659   else {
660     BOPCol_ListOfShape aLS(aAllocator);
661     aLS.Append(aS1);
662     aDMSLS.Add(aS2, aLS);
663   }
664 }
665 //=======================================================================
666 //function :HasPaveBlocksOnIn
667 //purpose  : 
668 //=======================================================================
669 Standard_Boolean HasPaveBlocksOnIn(const BOPDS_FaceInfo& aFI1,
670                                    const BOPDS_FaceInfo& aFI2)
671 {
672   Standard_Boolean bRet;
673   BOPDS_MapIteratorOfMapOfPaveBlock aItMPB;
674   //
675   bRet=Standard_False;
676   const BOPDS_IndexedMapOfPaveBlock& aMPBOn1=aFI1.PaveBlocksOn();
677   const BOPDS_IndexedMapOfPaveBlock& aMPBIn1=aFI1.PaveBlocksIn();
678   //
679   const BOPDS_IndexedMapOfPaveBlock& aMPBOn2=aFI2.PaveBlocksOn();
680   aItMPB.Initialize(aMPBOn2);
681   for (; aItMPB.More(); aItMPB.Next()) {
682     const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
683     bRet=aMPBOn1.Contains(aPB) || aMPBIn1.Contains(aPB);
684     if (bRet) {
685       return bRet;
686     }
687   }
688   //
689   const BOPDS_IndexedMapOfPaveBlock& aMPBIn2=aFI2.PaveBlocksIn();
690   aItMPB.Initialize(aMPBIn2);
691   for (; aItMPB.More(); aItMPB.Next()) {
692     const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
693     bRet=aMPBOn1.Contains(aPB) || aMPBIn1.Contains(aPB);
694     if (bRet) {
695       return bRet;
696     }
697   }
698   return bRet;
699 }
700 /*
701 //DEBf
702     {
703       TopoDS_Compound aCx;
704       BRep_Builder aBBx;
705       BOPCol_ListIteratorOfListOfShape aItx;
706       //
707       aBBx.MakeCompound(aCx);
708       aBBx.Add(aCx, aFF);
709       aItx.Initialize(aLE);
710       for (; aItx.More(); aItx.Next()) {
711       const TopoDS_Shape& aEx=aItx.Value();
712       aBBx.Add(aCx, aEx);
713       }
714       int a=0;
715     }
716     //DEBt
717 */