cf54ded8a084ea52668b5607988f66003b64a062
[occt.git] / src / BOPAlgo / BOPAlgo_PaveFiller_3.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 <Bnd_Box.hxx>
20 #include <BOPAlgo_PaveFiller.hxx>
21 #include <BOPAlgo_SectionAttribute.hxx>
22 #include <BOPAlgo_Tools.hxx>
23 #include <BOPCol_BoxBndTree.hxx>
24 #include <BOPCol_DataMapOfIntegerShape.hxx>
25 #include <BOPCol_DataMapOfShapeInteger.hxx>
26 #include <BOPCol_DataMapOfShapeListOfShape.hxx>
27 #include <BOPCol_IndexedDataMapOfShapeBox.hxx>
28 #include <BOPCol_NCVector.hxx>
29 #include <BOPCol_Parallel.hxx>
30 #include <BOPDS_CommonBlock.hxx>
31 #include <BOPDS_CoupleOfPaveBlocks.hxx>
32 #include <BOPDS_Curve.hxx>
33 #include <BOPDS_DataMapOfPaveBlockListOfInteger.hxx>
34 #include <BOPDS_DataMapOfPaveBlockListOfPaveBlock.hxx>
35 #include <BOPDS_DS.hxx>
36 #include <BOPDS_Interf.hxx>
37 #include <BOPDS_Iterator.hxx>
38 #include <BOPDS_MapOfPaveBlock.hxx>
39 #include <BOPDS_Pave.hxx>
40 #include <BOPDS_PaveBlock.hxx>
41 #include <BOPDS_VectorOfInterfEE.hxx>
42 #include <BOPTools_AlgoTools.hxx>
43
44 #include <BRep_Tool.hxx>
45 #include <BRepBndLib.hxx>
46 #include <BRepTools.hxx>
47 #include <BRepAdaptor_Curve.hxx>
48 #include <GeomAPI_ProjectPointOnCurve.hxx>
49 #include <gp_Pnt.hxx>
50 #include <IntTools_CommonPrt.hxx>
51 #include <IntTools_Context.hxx>
52 #include <IntTools_EdgeEdge.hxx>
53 #include <IntTools_Range.hxx>
54 #include <IntTools_SequenceOfCommonPrts.hxx>
55 #include <IntTools_SequenceOfRanges.hxx>
56 #include <IntTools_ShrunkRange.hxx>
57 #include <IntTools_Tools.hxx>
58 #include <NCollection_UBTreeFiller.hxx>
59 #include <Precision.hxx>
60 #include <TopoDS_Compound.hxx>
61 #include <TopoDS_Edge.hxx>
62 #include <TopoDS_Face.hxx>
63 #include <TopoDS_Vertex.hxx>
64
65 /////////////////////////////////////////////////////////////////////////
66 //=======================================================================
67 //class    : BOPAlgo_EdgeEdge
68 //purpose  : 
69 //=======================================================================
70 class BOPAlgo_EdgeEdge : 
71   public IntTools_EdgeEdge,
72   public BOPAlgo_Algo {
73  
74  public:
75
76   DEFINE_STANDARD_ALLOC
77   //
78   BOPAlgo_EdgeEdge(): 
79     IntTools_EdgeEdge(),
80     BOPAlgo_Algo() {
81   };
82   //
83   virtual ~BOPAlgo_EdgeEdge(){
84   };
85   //
86   void SetPaveBlock1(const Handle(BOPDS_PaveBlock)& aPB) {
87     myPB1=aPB;
88   }
89   //
90   Handle(BOPDS_PaveBlock)& PaveBlock1() {
91     return myPB1;
92   }
93   //
94   void SetPaveBlock2(const Handle(BOPDS_PaveBlock)& aPB) {
95     myPB2=aPB;
96   }
97   //
98   Handle(BOPDS_PaveBlock)& PaveBlock2() {
99     return myPB2;
100   }
101   // 
102   virtual void Perform() {
103     BOPAlgo_Algo::UserBreak();
104     IntTools_EdgeEdge::Perform();
105   }
106   //
107  protected:
108   Handle(BOPDS_PaveBlock) myPB1;
109   Handle(BOPDS_PaveBlock) myPB2;
110 };
111 //
112 //=======================================================================
113 typedef BOPCol_NCVector
114   <BOPAlgo_EdgeEdge> BOPAlgo_VectorOfEdgeEdge; 
115 //
116 typedef BOPCol_Functor 
117   <BOPAlgo_EdgeEdge,
118   BOPAlgo_VectorOfEdgeEdge> BOPAlgo_EdgeEdgeFunctor;
119 //
120 typedef BOPCol_Cnt 
121   <BOPAlgo_EdgeEdgeFunctor,
122   BOPAlgo_VectorOfEdgeEdge> BOPAlgo_EdgeEdgeCnt;
123 //
124 /////////////////////////////////////////////////////////////////////////
125 //=======================================================================
126 //class    : BOPAlgo_TNV
127 //purpose  : 
128 //=======================================================================
129 class BOPAlgo_TNV : public BOPCol_BoxBndTreeSelector{
130  public:
131   BOPAlgo_TNV() 
132     : BOPCol_BoxBndTreeSelector(), myTree(NULL) {
133   };
134   //
135   ~BOPAlgo_TNV(){
136   };
137   //
138   void SetVertex(const TopoDS_Vertex& aV) {
139     myV=aV;
140   }
141   //
142   const TopoDS_Vertex& Vertex()const {
143     return myV;
144   }
145   //
146   void SetTree(BOPCol_BoxBndTree& aTree) {
147     myTree=&aTree;
148   }
149   //
150   void Perform() {
151     myTree->Select(*this);
152   }
153   //
154  protected:
155   TopoDS_Vertex myV;
156   BOPCol_BoxBndTree *myTree;
157 };
158 //
159 //=======================================================================
160 typedef BOPCol_NCVector
161   <BOPAlgo_TNV> BOPAlgo_VectorOfTNV; 
162 //
163 typedef BOPCol_Functor 
164   <BOPAlgo_TNV,
165   BOPAlgo_VectorOfTNV> BOPAlgo_TNVFunctor;
166 //
167 typedef BOPCol_Cnt 
168   <BOPAlgo_TNVFunctor,
169   BOPAlgo_VectorOfTNV> BOPAlgo_TNVCnt;
170 /////////////////////////////////////////////////////////////////////////
171 //=======================================================================
172 //class    : BOPAlgo_PVE
173 //purpose  : 
174 //=======================================================================
175 class BOPAlgo_PVE {
176  public:
177   BOPAlgo_PVE()
178     : myIV(-1), myIE(-1), myFlag(-1), myT(-1.) {
179   };
180   //
181   ~BOPAlgo_PVE(){
182   };
183   //
184   void SetIndices(const Standard_Integer nV,
185                   const Standard_Integer nE){
186     myIV=nV;
187     myIE=nE;
188   }
189   //
190   void Indices(Standard_Integer& nV,
191                Standard_Integer& nE) const {
192     nV=myIV;
193     nE=myIE;
194   }
195   //
196   void SetVertex(const TopoDS_Vertex& aV) {
197     myV=aV;
198   }
199   //
200   const TopoDS_Vertex& Vertex()const {
201     return myV;
202   }
203   //
204   void SetEdge(const TopoDS_Edge& aE) {
205     myE=aE;
206   }
207   //
208   const TopoDS_Edge& Edge()const {
209     return myE;
210   }
211   //
212   void SetPaveBlock(const Handle(BOPDS_PaveBlock)& aPB) {
213     myPB=aPB;
214   }
215   //
216   Handle(BOPDS_PaveBlock)& PaveBlock() {
217     return myPB;
218   }
219   //
220   Standard_Integer Flag()const {
221     return myFlag;
222   }
223   //
224   Standard_Real Parameter()const {
225     return myT;
226   }
227   //
228   void SetContext(const Handle(IntTools_Context)& aContext) {
229     myContext=aContext;
230   }
231   //
232   const Handle(IntTools_Context)& Context()const {
233     return myContext;
234   }
235   //
236   void Perform() {
237     Standard_Real dummy;
238     myFlag = myContext->ComputeVE(myV, myE, myT, dummy);
239   };
240   //
241  protected:
242   Standard_Integer myIV;
243   Standard_Integer myIE;
244   Standard_Integer myFlag;
245   Standard_Real myT;
246   TopoDS_Vertex myV;
247   TopoDS_Edge myE;
248   Handle(BOPDS_PaveBlock) myPB;
249   Handle(IntTools_Context) myContext;
250 };
251 //=======================================================================
252 typedef BOPCol_NCVector
253   <BOPAlgo_PVE> BOPAlgo_VectorOfPVE; 
254 //
255 typedef BOPCol_ContextFunctor 
256   <BOPAlgo_PVE,
257   BOPAlgo_VectorOfPVE,
258   Handle(IntTools_Context), 
259   IntTools_Context> BOPAlgo_PVEFunctor;
260 //
261 typedef BOPCol_ContextCnt 
262   <BOPAlgo_PVEFunctor,
263   BOPAlgo_VectorOfPVE,
264   Handle(IntTools_Context)> BOPAlgo_PVECnt;
265 /////////////////////////////////////////////////////////////////////////
266 //=======================================================================
267 // function: PerformEE
268 // purpose: 
269 //=======================================================================
270 void BOPAlgo_PaveFiller::PerformEE()
271 {
272   Standard_Integer iSize;
273   //
274   myErrorStatus=0;
275   //
276   FillShrunkData(TopAbs_EDGE, TopAbs_EDGE);
277   //
278   myIterator->Initialize(TopAbs_EDGE, TopAbs_EDGE);
279   iSize=myIterator->ExpectedLength();
280   if (!iSize) {
281     return; 
282   }
283   //
284   Standard_Boolean bJustAdd;
285   Standard_Integer i, iX, nE1, nE2, aNbCPrts, k, aNbFdgeEdge;
286   Standard_Real aTS11, aTS12, aTS21, aTS22, aT11, aT12, aT21, aT22;
287   TopAbs_ShapeEnum aType;
288   BOPDS_ListIteratorOfListOfPaveBlock aIt1, aIt2;
289   Handle(NCollection_BaseAllocator) aAllocator;
290   BOPDS_MapOfPaveBlock aMPBToUpdate;
291   BOPAlgo_VectorOfEdgeEdge aVEdgeEdge;
292   BOPDS_MapIteratorOfMapOfPaveBlock aItPB; 
293   //
294   aAllocator=NCollection_BaseAllocator::CommonBaseAllocator();
295   //-----------------------------------------------------scope f
296   BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock aMPBLPB(100, aAllocator);
297   BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMVCPB(100, aAllocator);
298   //
299   BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
300   aEEs.SetIncrement(iSize);
301   //
302   for (; myIterator->More(); myIterator->Next()) {
303     myIterator->Value(nE1, nE2, bJustAdd);
304     if(bJustAdd) {
305       continue;
306     }
307     //
308     const BOPDS_ShapeInfo& aSIE1=myDS->ShapeInfo(nE1);
309     if (aSIE1.HasFlag()){
310       continue;
311     }
312     const BOPDS_ShapeInfo& aSIE2=myDS->ShapeInfo(nE2);
313     if (aSIE2.HasFlag()){
314       continue;
315     }
316     //
317     const TopoDS_Edge& aE1=(*(TopoDS_Edge *)(&aSIE1.Shape()));
318     const TopoDS_Edge& aE2=(*(TopoDS_Edge *)(&aSIE2.Shape()));  
319     //
320     BOPDS_ListOfPaveBlock& aLPB1=myDS->ChangePaveBlocks(nE1);
321     BOPDS_ListOfPaveBlock& aLPB2=myDS->ChangePaveBlocks(nE2);
322     //
323     aIt1.Initialize(aLPB1);
324     for (; aIt1.More(); aIt1.Next()) {
325       Bnd_Box aBB1;
326       //
327       Handle(BOPDS_PaveBlock)& aPB1=aIt1.ChangeValue();
328       if (!aPB1->HasShrunkData()) {
329         continue;
330       }
331       aPB1->ShrunkData(aTS11, aTS12, aBB1);
332       //
333       aIt2.Initialize(aLPB2);
334       for (; aIt2.More(); aIt2.Next()) {
335         Bnd_Box aBB2;
336         //
337         Handle(BOPDS_PaveBlock)& aPB2=aIt2.ChangeValue();
338         if (!aPB2->HasShrunkData()) {
339           continue;
340         }
341         aPB2->ShrunkData(aTS21, aTS22, aBB2);
342         //
343         if (aBB1.IsOut(aBB2)) {
344           continue;
345         }
346         //
347         aPB1->Range(aT11, aT12);
348         aPB2->Range(aT21, aT22);
349         //
350         BOPAlgo_EdgeEdge& anEdgeEdge=aVEdgeEdge.Append1();
351         // 
352         anEdgeEdge.SetPaveBlock1(aPB1);
353         anEdgeEdge.SetPaveBlock2(aPB2);
354         //
355         anEdgeEdge.SetEdge1(aE1, aT11, aT12);
356         anEdgeEdge.SetEdge2(aE2, aT21, aT22);
357         anEdgeEdge.SetProgressIndicator(myProgressIndicator);
358       }//for (; aIt2.More(); aIt2.Next()) {
359     }//for (; aIt1.More(); aIt1.Next()) {
360   }//for (; myIterator->More(); myIterator->Next()) {
361   //
362   aNbFdgeEdge=aVEdgeEdge.Extent();
363   //======================================================
364   BOPAlgo_EdgeEdgeCnt::Perform(myRunParallel, aVEdgeEdge);
365   //======================================================
366   //
367   for (k=0; k < aNbFdgeEdge; ++k) {
368     Bnd_Box aBB1, aBB2;
369     //
370     BOPAlgo_EdgeEdge& anEdgeEdge=aVEdgeEdge(k);
371     if (!anEdgeEdge.IsDone()) {
372       continue;
373     }
374     //
375     //--------------------------------------------
376     Handle(BOPDS_PaveBlock)& aPB1=anEdgeEdge.PaveBlock1();
377     nE1=aPB1->OriginalEdge();
378     aPB1->Range(aT11, aT12);
379     aPB1->ShrunkData(aTS11, aTS12, aBB1);
380     //
381     Handle(BOPDS_PaveBlock)& aPB2=anEdgeEdge.PaveBlock2();
382     nE2=aPB2->OriginalEdge();
383     aPB2->Range(aT21, aT22);
384     aPB2->ShrunkData(aTS21, aTS22, aBB2);
385     //
386     //--------------------------------------------
387     IntTools_Range aR11(aT11, aTS11), aR12(aTS12, aT12),
388                    aR21(aT21, aTS21), aR22(aTS22, aT22);
389     //
390     const IntTools_SequenceOfCommonPrts& aCPrts = anEdgeEdge.CommonParts();
391     aNbCPrts = aCPrts.Length();
392     //
393     Standard_Boolean bLineLine = Standard_False;
394     if (aNbCPrts) {
395       const TopoDS_Edge& aOE1 = *(TopoDS_Edge*)&myDS->Shape(nE1);
396       const TopoDS_Edge& aOE2 = *(TopoDS_Edge*)&myDS->Shape(nE2);
397       //
398       BRepAdaptor_Curve aBAC1(aOE1), aBAC2(aOE2);
399       //
400       bLineLine = (aBAC1.GetType() == GeomAbs_Line &&
401                    aBAC2.GetType() == GeomAbs_Line);
402     }
403     //
404     for (i=1; i<=aNbCPrts; ++i) {
405       const IntTools_CommonPrt& aCPart=aCPrts(i);
406       //
407       const TopoDS_Edge& aE1=aCPart.Edge1();
408       const TopoDS_Edge& aE2=aCPart.Edge2();
409       //
410       aType=aCPart.Type();
411       switch (aType) {
412         case TopAbs_VERTEX:  { 
413           Standard_Boolean bIsOnPave[4], bFlag;
414           Standard_Integer nV[4], j;
415           Standard_Real aT1, aT2, aTol;
416           TopoDS_Vertex aVnew;
417           IntTools_Range aCR1, aCR2;
418           //
419           IntTools_Tools::VertexParameters(aCPart, aT1, aT2);
420           aTol = Precision::Confusion();
421           aCR1 = aCPart.Range1();
422           aCR2 = aCPart.Ranges2()(1);
423           // 
424           //decide to keep the pave or not
425           bIsOnPave[0] = IntTools_Tools::IsOnPave1(aT1, aR11, aTol) ||
426             IntTools_Tools::IsOnPave1(aR11.First(), aCR1, aTol);
427           bIsOnPave[1] = IntTools_Tools::IsOnPave1(aT1, aR12, aTol) || 
428             IntTools_Tools::IsOnPave1(aR12.Last(), aCR1, aTol);
429           bIsOnPave[2] = IntTools_Tools::IsOnPave1(aT2, aR21, aTol) ||
430             IntTools_Tools::IsOnPave1(aR21.First(), aCR2, aTol);
431           bIsOnPave[3] = IntTools_Tools::IsOnPave1(aT2, aR22, aTol) ||
432             IntTools_Tools::IsOnPave1(aR22.Last(), aCR2, aTol);
433           //
434           aPB1->Indices(nV[0], nV[1]);
435           aPB2->Indices(nV[2], nV[3]);
436           //
437           if((bIsOnPave[0] && bIsOnPave[2]) || 
438              (bIsOnPave[0] && bIsOnPave[3]) ||
439              (bIsOnPave[1] && bIsOnPave[2]) || 
440              (bIsOnPave[1] && bIsOnPave[3])) {
441             continue;
442           }
443           //
444           bFlag = Standard_False;
445           for (j = 0; j < 4; ++j) {
446             if (bIsOnPave[j]) {
447               //add interf VE(nV[j], nE)
448               Handle(BOPDS_PaveBlock)& aPB = (j < 2) ? aPB2 : aPB1;
449               ForceInterfVE(nV[j], aPB, aMPBToUpdate);
450               bFlag = Standard_True;
451               break;
452             }
453           }
454           if (bFlag) {
455             continue;
456           }
457           //
458           BOPTools_AlgoTools::MakeNewVertex(aE1, aT1, aE2, aT2, aVnew);
459           Standard_Real aTolVnew = BRep_Tool::Tolerance(aVnew);
460           if (bLineLine) {
461             // increase tolerance for Line/Line intersection, but do not update 
462             // the vertex till its intersection with some other shape
463             Standard_Real aTol = (aCR1.Last() - aCR1.First()) / 2.;
464             if (aTol > aTolVnew) {
465               aTolVnew = aTol;
466             }
467           }
468           // <-LXBR
469           {
470             Standard_Integer nVS[2], iFound;
471             Standard_Real aTolVx, aD2, aDT2;
472             BOPCol_MapOfInteger aMV;
473             gp_Pnt aPnew, aPx;
474             //
475             iFound=0;
476             j=-1;
477             aMV.Add(nV[0]);
478             aMV.Add(nV[1]);
479             //
480             if (aMV.Contains(nV[2])) {
481               ++j;
482               nVS[j]=nV[2];
483             }
484             if (aMV.Contains(nV[3])) {
485               ++j;
486               nVS[j]=nV[3];
487             }
488             //
489             aPnew=BRep_Tool::Pnt(aVnew);
490             //
491             for (Standard_Integer k1=0; k1<=j; ++k1) {
492               const TopoDS_Vertex& aVx= *(TopoDS_Vertex*)&(myDS->Shape(nVS[k1]));
493               aTolVx=BRep_Tool::Tolerance(aVx);
494               aPx=BRep_Tool::Pnt(aVx);
495               aD2=aPnew.SquareDistance(aPx);
496               //
497               aDT2=100.*(aTolVnew+aTolVx)*(aTolVnew+aTolVx);
498               //
499               if (aD2<aDT2) {
500                 iFound=1;
501                 break;
502               }
503             }
504             //
505             if (iFound) {
506               continue;
507             }
508           }
509           //
510           // 1
511           BOPDS_InterfEE& aEE=aEEs.Append1();
512           iX=aEEs.Extent()-1;
513           aEE.SetIndices(nE1, nE2);
514           aEE.SetCommonPart(aCPart);
515           // 2
516           myDS->AddInterf(nE1, nE2);
517           //
518           BOPDS_CoupleOfPaveBlocks aCPB;
519           //
520           aCPB.SetPaveBlocks(aPB1, aPB2);
521           aCPB.SetIndexInterf(iX);
522           aCPB.SetTolerance(aTolVnew);
523           aMVCPB.Add(aVnew, aCPB);
524         }//case TopAbs_VERTEX: 
525           break;
526             //
527         case TopAbs_EDGE: {
528           if (aNbCPrts > 1) {
529             break;
530           }
531           //
532           Standard_Boolean bHasSameBounds;
533           bHasSameBounds=aPB1->HasSameBounds(aPB2);
534           if (!bHasSameBounds) {
535             break;
536           }
537           // 1
538           BOPDS_InterfEE& aEE=aEEs.Append1();
539           iX=aEEs.Extent()-1;
540           aEE.SetIndices(nE1, nE2);
541           aEE.SetCommonPart(aCPart);
542           // 2
543           myDS->AddInterf(nE1, nE2);
544           //
545           BOPAlgo_Tools::FillMap(aPB1, aPB2, aMPBLPB, aAllocator);
546         }//case TopAbs_EDGE
547           break;
548         default:
549           break;
550       }//switch (aType) {
551     }//for (i=1; i<=aNbCPrts; i++) {
552   }//for (k=0; k < aNbFdgeEdge; ++k) {
553   // 
554   //=========================================
555   // post treatment
556   //=========================================
557   {
558     Standard_Integer aNbV;
559     Handle(BOPDS_PaveBlock) aPB1, aPB2;
560     //
561     aNbV=aMVCPB.Extent();
562     for (i=1; i<=aNbV; ++i) {
563       const BOPDS_CoupleOfPaveBlocks& aCPB=aMVCPB.FindFromIndex(i);
564       aCPB.PaveBlocks(aPB1, aPB2); 
565       //
566       aMPBToUpdate.Remove(aPB1);
567       aMPBToUpdate.Remove(aPB2);
568     }
569   }
570   //
571   aItPB.Initialize(aMPBToUpdate);
572   for (; aItPB.More(); aItPB.Next()) {
573     Handle(BOPDS_PaveBlock) aPB=aItPB.Value();
574     if (!myDS->IsCommonBlock(aPB)) {
575       myDS->UpdatePaveBlock(aPB);
576     }
577     else {
578       const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
579       myDS->UpdateCommonBlock(aCB);
580     }
581   }
582   //
583   BOPAlgo_Tools::PerformCommonBlocks(aMPBLPB, aAllocator, myDS);
584   PerformVerticesEE(aMVCPB, aAllocator);
585   //-----------------------------------------------------scope t
586   aMPBLPB.Clear();
587   aMVCPB.Clear();
588   aMPBToUpdate.Clear();
589 }
590 //=======================================================================
591 //function : PerformVerticesEE
592 //purpose  : 
593 //=======================================================================
594 Standard_Integer BOPAlgo_PaveFiller::PerformVerticesEE
595   (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB,
596    const Handle(NCollection_BaseAllocator)& theAllocator)
597 {
598   Standard_Integer aNbV, iRet;
599   //
600   iRet=0;
601   aNbV=theMVCPB.Extent();
602   if (!aNbV) {
603     return iRet;
604   }
605   //
606   Standard_Integer nVx, iV, j, nE, iFlag, iX, i, aNb; 
607   Standard_Real aT;
608   BOPCol_ListIteratorOfListOfShape aItLS;
609   BOPCol_ListIteratorOfListOfInteger aItLI;
610   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
611   BOPDS_ShapeInfo aSI;
612   BOPDS_Pave aPave;
613   //
614   BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, theAllocator);
615   BOPCol_ListOfShape aLS(theAllocator);
616   BOPCol_IndexedDataMapOfShapeInteger aMVI(100, theAllocator);
617   BOPCol_IndexedDataMapOfShapeListOfShape aImages;
618   //
619   aSI.SetShapeType(TopAbs_VERTEX);
620   BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
621   //
622   // 1 prepare arguments
623   // 2 Fuse vertices
624   TreatNewVertices(theMVCPB, aImages);
625   //
626   // 3 Add new vertices to myDS; 
627   //   connect indices to CPB structure
628   aNb = aImages.Extent();
629   for (i=1; i<=aNb; ++i) {
630     const TopoDS_Vertex& aV=(*(TopoDS_Vertex*)(&aImages.FindKey(i)));
631     const BOPCol_ListOfShape& aLVSD=aImages.FindFromIndex(i);
632     //
633     aSI.SetShape(aV);
634     iV=myDS->Append(aSI);
635     //
636     BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(iV);
637     Bnd_Box& aBox=aSIDS.ChangeBox();
638     BRepBndLib::Add(aV, aBox);
639     aBox.SetGap(aBox.GetGap() + Precision::Confusion());
640     //
641     aItLS.Initialize(aLVSD);
642     for (; aItLS.More(); aItLS.Next()) {
643       const TopoDS_Shape& aVx = aItLS.Value();
644       BOPDS_CoupleOfPaveBlocks &aCPB=theMVCPB.ChangeFromKey(aVx);
645       aCPB.SetIndex(iV);
646       // update EE interference
647       iX=aCPB.IndexInterf();
648       BOPDS_InterfEE& aEE=aEEs(iX);
649       aEE.SetIndexNew(iV);
650     }
651   }
652   //
653   // 4 Map PaveBlock/ListOfVertices to add to this PaveBlock ->aMPBLI
654   {
655     Handle(BOPDS_PaveBlock) aPB[2];
656     //
657     for (i=1; i<=aNbV; ++i) {
658       const BOPDS_CoupleOfPaveBlocks& aCPB=theMVCPB.FindFromIndex(i);
659       iV=aCPB.Index();
660       aCPB.PaveBlocks(aPB[0], aPB[1]);
661       for (j=0; j<2; ++j) {
662         if (aMPBLI.Contains(aPB[j])) {
663           BOPCol_ListOfInteger& aLI=aMPBLI.ChangeFromKey(aPB[j]);
664           aLI.Append(iV);
665         }
666         else {
667           BOPCol_ListOfInteger aLI(theAllocator);
668           aLI.Append(iV);
669           aMPBLI.Add(aPB[j], aLI);
670         }
671       }
672     }
673   }
674   // 5 
675   // 5.1  Compute Extra Paves and 
676   // 5.2. Add Extra Paves to the PaveBlocks
677   //-------------------------------------------------------------
678   Standard_Integer k, aNbVPVE;
679   BOPAlgo_VectorOfPVE aVPVE;
680   //
681   aNb=aMPBLI.Extent();
682   for(i=1; i<=aNb; ++i) {
683     Handle(BOPDS_PaveBlock) aPB=aMPBLI.FindKey(i);
684     nE=aPB->OriginalEdge();
685     const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
686     // 1,2
687     const BOPCol_ListOfInteger& aLI=aMPBLI.FindFromIndex(i);
688     aItLI.Initialize(aLI);
689     for (; aItLI.More(); aItLI.Next()) {
690       nVx=aItLI.Value();
691       const TopoDS_Vertex& aVx=(*(TopoDS_Vertex *)(&myDS->Shape(nVx)));
692       //
693       BOPAlgo_PVE& aPVE=aVPVE.Append1();
694       aPVE.SetIndices(nVx, nE);
695       aPVE.SetVertex(aVx);
696       aPVE.SetEdge(aE);
697       aPVE.SetPaveBlock(aPB);
698     }
699   }
700   //
701   aNbVPVE=aVPVE.Extent();
702   //=============================================================
703   BOPAlgo_PVECnt::Perform(myRunParallel, aVPVE, myContext);
704   //=============================================================
705   //
706   for (k=0; k < aNbVPVE; ++k) {
707     BOPAlgo_PVE& aPVE=aVPVE(k);
708     iFlag=aPVE.Flag();
709     if (!iFlag) {
710       aPVE.Indices(nVx, nE);
711       aT=aPVE.Parameter();
712       Handle(BOPDS_PaveBlock)& aPB=aPVE.PaveBlock();
713       //
714       aPave.SetIndex(nVx);
715       aPave.SetParameter(aT);
716       aPB->AppendExtPave(aPave);
717     }
718   }
719   // 6  Split PaveBlocksa
720   aNb=aMPBLI.Extent();
721   for(i=1; i<=aNb; ++i) {
722     Handle(BOPDS_PaveBlock) aPB=aMPBLI.FindKey(i);
723     nE=aPB->OriginalEdge();
724     // 3
725     if (!myDS->IsCommonBlock(aPB)) {
726       myDS->UpdatePaveBlock(aPB);
727     }
728     else {
729       const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
730       myDS->UpdateCommonBlock(aCB);
731     }    
732   }//for (; aItMPBLI.More(); aItMPBLI.Next()) {
733   //
734   return iRet;
735 }
736 //=======================================================================
737 //function : TreatNewVertices
738 //purpose  : 
739 //=======================================================================
740 void BOPAlgo_PaveFiller::TreatNewVertices
741 (const BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB,
742    BOPCol_IndexedDataMapOfShapeListOfShape& myImages)
743 {
744   Standard_Integer  i, aNbV;//, aNbVSD;
745   Standard_Real aTol;
746   TopoDS_Vertex aVnew;
747   BOPCol_IndexedMapOfShape aMVProcessed;
748   BOPCol_MapOfInteger aMFence;
749   BOPCol_ListIteratorOfListOfInteger aIt;
750   NCollection_Vector<BOPCol_ListOfShape> aVecOfLVSD;
751   //
752   BOPCol_BoxBndTree aBBTree;
753   NCollection_UBTreeFiller <Standard_Integer, 
754                             Bnd_Box> aTreeFiller(aBBTree);
755   BOPAlgo_VectorOfTNV aVTNV;
756   //
757   aNbV = theMVCPB.Extent();
758   for (i=1; i<=aNbV; ++i) {
759     const TopoDS_Vertex& aV = *((TopoDS_Vertex*)&theMVCPB.FindKey(i));
760     Bnd_Box aBox;
761     //
762     aTol = theMVCPB.FindFromIndex(i).Tolerance();
763     aBox.Add(BRep_Tool::Pnt(aV));
764     aBox.SetGap(aTol);
765     //
766     aTreeFiller.Add(i, aBox);
767     //
768     BOPAlgo_TNV& aTNV=aVTNV.Append1();
769     aTNV.SetTree(aBBTree);
770     aTNV.SetBox(aBox);
771     aTNV.SetVertex(aV);
772   }
773   //
774   aTreeFiller.Fill();
775   //
776   //===========================================
777   BOPAlgo_TNVCnt::Perform(myRunParallel, aVTNV);
778   //===========================================
779   //
780   // Chains
781   for (i=1; i<=aNbV; ++i) {
782     if (!aMFence.Add(i)) {
783       continue;
784     }
785     //
786     Standard_Integer aIP, aNbIP1, aIP1;
787     BOPCol_ListOfShape aLVSD;
788     BOPCol_ListOfInteger aLIP, aLIP1, aLIPC;
789     BOPCol_ListIteratorOfListOfInteger aItLIP;
790     //
791     aLIPC.Append(i);
792     aLIP.Append(i);
793     for(;;) {
794       aItLIP.Initialize(aLIP);
795       for(; aItLIP.More(); aItLIP.Next()) {
796         aIP=aItLIP.Value();
797         //
798         BOPAlgo_TNV& aTNV=aVTNV(aIP-1);
799         const BOPCol_ListOfInteger& aLI=aTNV.Indices();
800         aIt.Initialize(aLI);
801         for (; aIt.More(); aIt.Next()) {
802           aIP1=aIt.Value();
803           if (!aMFence.Add(aIP1)) {
804             continue;
805           }
806           aLIP1.Append(aIP1);
807         } //for (; aIt.More(); aIt.Next()) {
808       }//for(; aIt1.More(); aIt1.Next()) {
809       //
810       aNbIP1=aLIP1.Extent();
811       if (!aNbIP1) {
812         break; // from for(;;) 
813       }
814       //
815       aLIP = aLIP1;
816       aLIPC.Append(aLIP1); // items of aLIP1 are moved to aLIPC
817     }// for(;;) {
818     //
819     aItLIP.Initialize(aLIPC);
820     for(; aItLIP.More(); aItLIP.Next()) {
821       aIP=aItLIP.Value();
822       const TopoDS_Vertex& aVP=aVTNV(aIP-1).Vertex(); 
823       aLVSD.Append(aVP);
824     }
825     aVecOfLVSD.Append(aLVSD);
826   }// for (i=1; i<=aNbV; ++i) {
827
828   // Make new vertices
829   aNbV = aVecOfLVSD.Size();
830   for (i = 0; i < aNbV; ++i) {
831     const BOPCol_ListOfShape& aLVSD = aVecOfLVSD(i);
832     BOPTools_AlgoTools::MakeVertex(aLVSD, aVnew);
833     myImages.Add(aVnew, aLVSD);
834   }
835 }
836 //=======================================================================
837 //function : FillShrunkData
838 //purpose  : 
839 //=======================================================================
840 void BOPAlgo_PaveFiller::FillShrunkData(Handle(BOPDS_PaveBlock)& thePB)
841 {
842   Standard_Integer nE, nV1, nV2, iErr;
843   Standard_Real aT1, aT2, aTS1, aTS2;
844   IntTools_ShrunkRange aSR;
845   //
846   myErrorStatus=0;
847   myWarningStatus = 0;
848   //
849   const BOPDS_Pave& aPave1=thePB->Pave1();
850   nV1=aPave1.Index();
851   aT1=aPave1.Parameter();
852   const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1))); 
853   //
854   const BOPDS_Pave& aPave2=thePB->Pave2();
855   nV2=aPave2.Index();
856   aT2=aPave2.Parameter();
857   const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2))); 
858   //
859   nE=thePB->OriginalEdge();
860   const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
861   //
862   aSR.SetContext(myContext);
863   aSR.SetData(aE, aT1, aT2, aV1, aV2);
864   //
865   aSR.Perform();
866   iErr=aSR.ErrorStatus();
867   if (iErr) {
868     myWarningStatus = 1;
869     //myErrorStatus=40;
870     return;
871   }
872   //
873   aSR.ShrunkRange(aTS1, aTS2);
874   const Bnd_Box& aBox=aSR.BndBox();
875   //
876   thePB->SetShrunkData(aTS1, aTS2, aBox);
877 }
878 //=======================================================================
879 //function : ForceInterfVE
880 //purpose  : 
881 //=======================================================================
882 void BOPAlgo_PaveFiller::ForceInterfVE(const Standard_Integer nV,
883                                        Handle(BOPDS_PaveBlock)& aPB,
884                                        BOPDS_MapOfPaveBlock& aMPBToUpdate)
885 {
886   Standard_Integer nE, nVx, nVSD, iFlag;
887   Standard_Real aT, aTolVNew;
888   //
889   nE = aPB->OriginalEdge();
890   //
891   const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
892   if (aSIE.HasSubShape(nV)) {
893     return;
894   }
895   //
896   if (myDS->HasInterf(nV, nE)) {
897     return;
898   }   
899   //
900   if (myDS->HasInterfShapeSubShapes(nV, nE)) {
901     return;
902   }
903   //
904   if (aPB->Pave1().Index() == nV || 
905       aPB->Pave2().Index() == nV) {
906     return;
907   }
908   //
909   nVx = nV;
910   if (myDS->HasShapeSD(nV, nVSD)) {
911     nVx = nVSD;
912   }
913   //
914   const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nVx);
915   const TopoDS_Edge&   aE = *(TopoDS_Edge*)  &myDS->Shape(nE);
916   //
917   iFlag = myContext->ComputeVE(aV, aE, aT, aTolVNew);
918   if (iFlag == 0 || iFlag == -4) {
919     BOPDS_Pave aPave;
920     //
921     //
922     BOPDS_VectorOfInterfVE& aVEs=myDS->InterfVE();
923     aVEs.SetIncrement(10);
924     // 1
925     BOPDS_InterfVE& aVE=aVEs.Append1();
926     aVE.SetIndices(nV, nE);
927     aVE.SetParameter(aT);
928     // 2
929     myDS->AddInterf(nV, nE);
930     //
931     // 3 update vertex V/E if necessary
932     nVx=UpdateVertex(nV, aTolVNew);
933     // 4
934     if (myDS->IsNewShape(nVx)) {
935       aVE.SetIndexNew(nVx);
936     }
937     // 5 append ext pave to pave block
938     aPave.SetIndex(nVx);
939     aPave.SetParameter(aT);
940     aPB->AppendExtPave(aPave);
941     //
942     aMPBToUpdate.Add(aPB);
943   }
944 }