0027804: Two breps cause intersections to loop for too long/infinitely
[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 #include <BndLib_Add3dCurve.hxx>
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, bExpressCompute, bIsPBSplittable1, bIsPBSplittable2;
285   Standard_Integer i, iX, nE1, nE2, aNbCPrts, k, aNbEdgeEdge;
286   Standard_Integer nV11, nV12, nV21, nV22;
287   Standard_Real aTS11, aTS12, aTS21, aTS22, aT11, aT12, aT21, aT22;
288   TopAbs_ShapeEnum aType;
289   BOPDS_ListIteratorOfListOfPaveBlock aIt1, aIt2;
290   Handle(NCollection_BaseAllocator) aAllocator;
291   BOPDS_MapOfPaveBlock aMPBToUpdate;
292   BOPAlgo_VectorOfEdgeEdge aVEdgeEdge;
293   BOPDS_MapIteratorOfMapOfPaveBlock aItPB; 
294   //
295   aAllocator=NCollection_BaseAllocator::CommonBaseAllocator();
296   //-----------------------------------------------------scope f
297   BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock aMPBLPB(100, aAllocator);
298   BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMVCPB(100, aAllocator);
299   BOPAlgo_DataMapOfPaveBlockBndBox aDMPBBox(100, aAllocator);
300   //
301   BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
302   aEEs.SetIncrement(iSize);
303   //
304   for (; myIterator->More(); myIterator->Next()) {
305     myIterator->Value(nE1, nE2, bJustAdd);
306     if(bJustAdd) {
307       continue;
308     }
309     //
310     const BOPDS_ShapeInfo& aSIE1=myDS->ShapeInfo(nE1);
311     if (aSIE1.HasFlag()){
312       continue;
313     }
314     const BOPDS_ShapeInfo& aSIE2=myDS->ShapeInfo(nE2);
315     if (aSIE2.HasFlag()){
316       continue;
317     }
318     //
319     const TopoDS_Edge& aE1=(*(TopoDS_Edge *)(&aSIE1.Shape()));
320     const TopoDS_Edge& aE2=(*(TopoDS_Edge *)(&aSIE2.Shape()));
321     //
322     BOPDS_ListOfPaveBlock& aLPB1=myDS->ChangePaveBlocks(nE1);
323     BOPDS_ListOfPaveBlock& aLPB2=myDS->ChangePaveBlocks(nE2);
324     //
325     aIt1.Initialize(aLPB1);
326     for (; aIt1.More(); aIt1.Next()) {
327       Bnd_Box aBB1;
328       //
329       Handle(BOPDS_PaveBlock)& aPB1=aIt1.ChangeValue();
330       //
331       if (!GetPBBox(aE1, aPB1, aDMPBBox, aT11, aT12, aTS11, aTS12, aBB1)) {
332         continue;
333       }
334       //
335       aPB1->Indices(nV11, nV12);
336       //
337       aIt2.Initialize(aLPB2);
338       for (; aIt2.More(); aIt2.Next()) {
339         Bnd_Box aBB2;
340         //
341         Handle(BOPDS_PaveBlock)& aPB2=aIt2.ChangeValue();
342         //
343         if (!GetPBBox(aE2, aPB2, aDMPBBox, aT21, aT22, aTS21, aTS22, aBB2)) {
344           continue;
345         }
346         //
347         if (aBB1.IsOut(aBB2)) {
348           continue;
349         }
350         //
351         aPB2->Indices(nV21, nV22);
352         //
353         bExpressCompute=((nV11==nV21 && nV12==nV22) ||
354                          (nV12==nV21 && nV11==nV22));
355         //
356         BOPAlgo_EdgeEdge& anEdgeEdge=aVEdgeEdge.Append1();
357         //
358         anEdgeEdge.UseQuickCoincidenceCheck(bExpressCompute);
359         //
360         anEdgeEdge.SetPaveBlock1(aPB1);
361         anEdgeEdge.SetPaveBlock2(aPB2);
362         //
363         anEdgeEdge.SetEdge1(aE1, aT11, aT12);
364         anEdgeEdge.SetEdge2(aE2, aT21, aT22);
365         anEdgeEdge.SetProgressIndicator(myProgressIndicator);
366       }//for (; aIt2.More(); aIt2.Next()) {
367     }//for (; aIt1.More(); aIt1.Next()) {
368   }//for (; myIterator->More(); myIterator->Next()) {
369   //
370   aNbEdgeEdge=aVEdgeEdge.Extent();
371   //======================================================
372   BOPAlgo_EdgeEdgeCnt::Perform(myRunParallel, aVEdgeEdge);
373   //======================================================
374   //
375   for (k = 0; k < aNbEdgeEdge; ++k) {
376     Bnd_Box aBB1, aBB2;
377     //
378     BOPAlgo_EdgeEdge& anEdgeEdge=aVEdgeEdge(k);
379     if (!anEdgeEdge.IsDone()) {
380       continue;
381     }
382     //
383     //--------------------------------------------
384     Handle(BOPDS_PaveBlock)& aPB1=anEdgeEdge.PaveBlock1();
385     nE1=aPB1->OriginalEdge();
386     aPB1->Range(aT11, aT12);
387     if (!aPB1->HasShrunkData()) {
388       aTS11 = aT11;
389       aTS12 = aT12;
390       bIsPBSplittable1 = Standard_False;
391     }
392     else {
393       aPB1->ShrunkData(aTS11, aTS12, aBB1, bIsPBSplittable1);
394     }
395     //
396     Handle(BOPDS_PaveBlock)& aPB2=anEdgeEdge.PaveBlock2();
397     nE2=aPB2->OriginalEdge();
398     aPB2->Range(aT21, aT22);
399     if (!aPB2->HasShrunkData()) {
400       aTS21 = aT21;
401       aTS22 = aT22;
402       bIsPBSplittable2 = Standard_False;
403     }
404     else {
405       aPB2->ShrunkData(aTS21, aTS22, aBB2, bIsPBSplittable2);
406     }
407     //
408     //--------------------------------------------
409     IntTools_Range aR11(aT11, aTS11), aR12(aTS12, aT12),
410                    aR21(aT21, aTS21), aR22(aTS22, aT22);
411     //
412     const IntTools_SequenceOfCommonPrts& aCPrts = anEdgeEdge.CommonParts();
413     aNbCPrts = aCPrts.Length();
414     //
415     Standard_Boolean bAnalytical = Standard_False;
416     if (aNbCPrts) {
417       const TopoDS_Edge& aOE1 = *(TopoDS_Edge*)&myDS->Shape(nE1);
418       const TopoDS_Edge& aOE2 = *(TopoDS_Edge*)&myDS->Shape(nE2);
419       //
420       BRepAdaptor_Curve aBAC1(aOE1), aBAC2(aOE2);
421       //
422       GeomAbs_CurveType aType1 = aBAC1.GetType();
423       GeomAbs_CurveType aType2 = aBAC2.GetType();
424       //
425       bAnalytical = (((aType1 == GeomAbs_Line) &&
426                       (aType2 == GeomAbs_Line ||
427                        aType2 == GeomAbs_Circle)) ||
428                      ((aType2 == GeomAbs_Line) &&
429                       (aType1 == GeomAbs_Line ||
430                        aType1 == GeomAbs_Circle)));
431     }
432     //
433     for (i=1; i<=aNbCPrts; ++i) {
434       const IntTools_CommonPrt& aCPart=aCPrts(i);
435       //
436       const TopoDS_Edge& aE1=aCPart.Edge1();
437       const TopoDS_Edge& aE2=aCPart.Edge2();
438       //
439       aType=aCPart.Type();
440       switch (aType) {
441         case TopAbs_VERTEX:  { 
442           if (!bIsPBSplittable1 || !bIsPBSplittable2) {
443             continue;
444           }
445           //
446           Standard_Boolean bIsOnPave[4], bFlag;
447           Standard_Integer nV[4], j;
448           Standard_Real aT1, aT2, aTol;
449           TopoDS_Vertex aVnew;
450           IntTools_Range aCR1, aCR2;
451           //
452           IntTools_Tools::VertexParameters(aCPart, aT1, aT2);
453           aTol = Precision::Confusion();
454           aCR1 = aCPart.Range1();
455           aCR2 = aCPart.Ranges2()(1);
456           // 
457           //decide to keep the pave or not
458           bIsOnPave[0] = IntTools_Tools::IsOnPave1(aT1, aR11, aTol) ||
459             IntTools_Tools::IsOnPave1(aR11.First(), aCR1, aTol);
460           bIsOnPave[1] = IntTools_Tools::IsOnPave1(aT1, aR12, aTol) || 
461             IntTools_Tools::IsOnPave1(aR12.Last(), aCR1, aTol);
462           bIsOnPave[2] = IntTools_Tools::IsOnPave1(aT2, aR21, aTol) ||
463             IntTools_Tools::IsOnPave1(aR21.First(), aCR2, aTol);
464           bIsOnPave[3] = IntTools_Tools::IsOnPave1(aT2, aR22, aTol) ||
465             IntTools_Tools::IsOnPave1(aR22.Last(), aCR2, aTol);
466           //
467           aPB1->Indices(nV[0], nV[1]);
468           aPB2->Indices(nV[2], nV[3]);
469           //
470           if((bIsOnPave[0] && bIsOnPave[2]) || 
471              (bIsOnPave[0] && bIsOnPave[3]) ||
472              (bIsOnPave[1] && bIsOnPave[2]) || 
473              (bIsOnPave[1] && bIsOnPave[3])) {
474             continue;
475           }
476           //
477           bFlag = Standard_False;
478           for (j = 0; j < 4; ++j) {
479             if (bIsOnPave[j]) {
480               //add interf VE(nV[j], nE)
481               Handle(BOPDS_PaveBlock)& aPB = (j < 2) ? aPB2 : aPB1;
482               ForceInterfVE(nV[j], aPB, aMPBToUpdate);
483               bFlag = Standard_True;
484               break;
485             }
486           }
487           if (bFlag) {
488             continue;
489           }
490           //
491           BOPTools_AlgoTools::MakeNewVertex(aE1, aT1, aE2, aT2, aVnew);
492           Standard_Real aTolVnew = BRep_Tool::Tolerance(aVnew);
493           if (bAnalytical) {
494             // increase tolerance for Line/Line intersection, but do not update 
495             // the vertex till its intersection with some other shape
496             Standard_Real aTolMin = (BRepAdaptor_Curve(aE1).GetType() == GeomAbs_Line) ?
497               (aCR1.Last() - aCR1.First()) / 2. : (aCR2.Last() - aCR2.First()) / 2.;
498             if (aTolMin > aTolVnew) {
499               aTolVnew = aTolMin;
500             }
501           }
502           // <-LXBR
503           {
504             Standard_Integer nVS[2], iFound;
505             Standard_Real aTolVx, aD2, aDT2;
506             BOPCol_MapOfInteger aMV;
507             gp_Pnt aPnew, aPx;
508             //
509             iFound=0;
510             j=-1;
511             aMV.Add(nV[0]);
512             aMV.Add(nV[1]);
513             //
514             if (aMV.Contains(nV[2])) {
515               ++j;
516               nVS[j]=nV[2];
517             }
518             if (aMV.Contains(nV[3])) {
519               ++j;
520               nVS[j]=nV[3];
521             }
522             //
523             aPnew=BRep_Tool::Pnt(aVnew);
524             //
525             for (Standard_Integer k1=0; k1<=j; ++k1) {
526               const TopoDS_Vertex& aVx= *(TopoDS_Vertex*)&(myDS->Shape(nVS[k1]));
527               aTolVx=BRep_Tool::Tolerance(aVx);
528               aPx=BRep_Tool::Pnt(aVx);
529               aD2=aPnew.SquareDistance(aPx);
530               //
531               aDT2=100.*(aTolVnew+aTolVx)*(aTolVnew+aTolVx);
532               //
533               if (aD2<aDT2) {
534                 iFound=1;
535                 break;
536               }
537             }
538             //
539             if (iFound) {
540               continue;
541             }
542           }
543           //
544           // 1
545           BOPDS_InterfEE& aEE=aEEs.Append1();
546           iX=aEEs.Extent()-1;
547           aEE.SetIndices(nE1, nE2);
548           aEE.SetCommonPart(aCPart);
549           // 2
550           myDS->AddInterf(nE1, nE2);
551           //
552           BOPDS_CoupleOfPaveBlocks aCPB;
553           //
554           aCPB.SetPaveBlocks(aPB1, aPB2);
555           aCPB.SetIndexInterf(iX);
556           aCPB.SetTolerance(aTolVnew);
557           aMVCPB.Add(aVnew, aCPB);
558         }//case TopAbs_VERTEX: 
559           break;
560             //
561         case TopAbs_EDGE: {
562           if (aNbCPrts > 1) {
563             break;
564           }
565           //
566           Standard_Boolean bHasSameBounds;
567           bHasSameBounds=aPB1->HasSameBounds(aPB2);
568           if (!bHasSameBounds) {
569             break;
570           }
571           // 1
572           BOPDS_InterfEE& aEE=aEEs.Append1();
573           iX=aEEs.Extent()-1;
574           aEE.SetIndices(nE1, nE2);
575           aEE.SetCommonPart(aCPart);
576           // 2
577           myDS->AddInterf(nE1, nE2);
578           //
579           BOPAlgo_Tools::FillMap(aPB1, aPB2, aMPBLPB, aAllocator);
580         }//case TopAbs_EDGE
581           break;
582         default:
583           break;
584       }//switch (aType) {
585     }//for (i=1; i<=aNbCPrts; i++) {
586   }//for (k=0; k < aNbFdgeEdge; ++k) {
587   // 
588   //=========================================
589   // post treatment
590   //=========================================
591   {
592     Standard_Integer aNbV;
593     Handle(BOPDS_PaveBlock) aPB1, aPB2;
594     //
595     aNbV=aMVCPB.Extent();
596     for (i=1; i<=aNbV; ++i) {
597       const BOPDS_CoupleOfPaveBlocks& aCPB=aMVCPB.FindFromIndex(i);
598       aCPB.PaveBlocks(aPB1, aPB2); 
599       //
600       aMPBToUpdate.Remove(aPB1);
601       aMPBToUpdate.Remove(aPB2);
602     }
603   }
604   //
605   aItPB.Initialize(aMPBToUpdate);
606   for (; aItPB.More(); aItPB.Next()) {
607     Handle(BOPDS_PaveBlock) aPB=aItPB.Value();
608     if (!myDS->IsCommonBlock(aPB)) {
609       myDS->UpdatePaveBlock(aPB);
610     }
611     else {
612       const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
613       myDS->UpdateCommonBlock(aCB);
614     }
615   }
616   //
617   BOPAlgo_Tools::PerformCommonBlocks(aMPBLPB, aAllocator, myDS);
618   PerformVerticesEE(aMVCPB, aAllocator);
619   //-----------------------------------------------------scope t
620   aMPBLPB.Clear();
621   aMVCPB.Clear();
622   aMPBToUpdate.Clear();
623 }
624 //=======================================================================
625 //function : PerformVerticesEE
626 //purpose  : 
627 //=======================================================================
628 Standard_Integer BOPAlgo_PaveFiller::PerformVerticesEE
629   (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB,
630    const Handle(NCollection_BaseAllocator)& theAllocator)
631 {
632   Standard_Integer aNbV, iRet;
633   //
634   iRet=0;
635   aNbV=theMVCPB.Extent();
636   if (!aNbV) {
637     return iRet;
638   }
639   //
640   Standard_Integer nVx, iV, j, nE, iFlag, iX, i, aNb; 
641   Standard_Real aT;
642   BOPCol_ListIteratorOfListOfShape aItLS;
643   BOPCol_ListIteratorOfListOfInteger aItLI;
644   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
645   BOPDS_ShapeInfo aSI;
646   BOPDS_Pave aPave;
647   //
648   BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, theAllocator);
649   BOPCol_ListOfShape aLS(theAllocator);
650   BOPCol_IndexedDataMapOfShapeInteger aMVI(100, theAllocator);
651   BOPCol_IndexedDataMapOfShapeListOfShape aImages;
652   //
653   aSI.SetShapeType(TopAbs_VERTEX);
654   BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
655   //
656   // 1 prepare arguments
657   // 2 Fuse vertices
658   TreatNewVertices(theMVCPB, aImages);
659   //
660   // 3 Add new vertices to myDS; 
661   //   connect indices to CPB structure
662   aNb = aImages.Extent();
663   for (i=1; i<=aNb; ++i) {
664     const TopoDS_Vertex& aV=(*(TopoDS_Vertex*)(&aImages.FindKey(i)));
665     const BOPCol_ListOfShape& aLVSD=aImages.FindFromIndex(i);
666     //
667     aSI.SetShape(aV);
668     iV=myDS->Append(aSI);
669     //
670     BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(iV);
671     Bnd_Box& aBox=aSIDS.ChangeBox();
672     BRepBndLib::Add(aV, aBox);
673     aBox.SetGap(aBox.GetGap() + Precision::Confusion());
674     //
675     aItLS.Initialize(aLVSD);
676     for (; aItLS.More(); aItLS.Next()) {
677       const TopoDS_Shape& aVx = aItLS.Value();
678       BOPDS_CoupleOfPaveBlocks &aCPB=theMVCPB.ChangeFromKey(aVx);
679       aCPB.SetIndex(iV);
680       // update EE interference
681       iX=aCPB.IndexInterf();
682       BOPDS_InterfEE& aEE=aEEs(iX);
683       aEE.SetIndexNew(iV);
684     }
685   }
686   //
687   // 4 Map PaveBlock/ListOfVertices to add to this PaveBlock ->aMPBLI
688   {
689     Handle(BOPDS_PaveBlock) aPB[2];
690     //
691     for (i=1; i<=aNbV; ++i) {
692       const BOPDS_CoupleOfPaveBlocks& aCPB=theMVCPB.FindFromIndex(i);
693       iV=aCPB.Index();
694       aCPB.PaveBlocks(aPB[0], aPB[1]);
695       for (j=0; j<2; ++j) {
696         if (aMPBLI.Contains(aPB[j])) {
697           BOPCol_ListOfInteger& aLI=aMPBLI.ChangeFromKey(aPB[j]);
698           aLI.Append(iV);
699         }
700         else {
701           BOPCol_ListOfInteger aLI(theAllocator);
702           aLI.Append(iV);
703           aMPBLI.Add(aPB[j], aLI);
704         }
705       }
706     }
707   }
708   // 5 
709   // 5.1  Compute Extra Paves and 
710   // 5.2. Add Extra Paves to the PaveBlocks
711   //-------------------------------------------------------------
712   Standard_Integer k, aNbVPVE;
713   BOPAlgo_VectorOfPVE aVPVE;
714   //
715   aNb=aMPBLI.Extent();
716   for(i=1; i<=aNb; ++i) {
717     Handle(BOPDS_PaveBlock) aPB=aMPBLI.FindKey(i);
718     nE=aPB->OriginalEdge();
719     const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
720     // 1,2
721     const BOPCol_ListOfInteger& aLI=aMPBLI.FindFromIndex(i);
722     aItLI.Initialize(aLI);
723     for (; aItLI.More(); aItLI.Next()) {
724       nVx=aItLI.Value();
725       const TopoDS_Vertex& aVx=(*(TopoDS_Vertex *)(&myDS->Shape(nVx)));
726       //
727       BOPAlgo_PVE& aPVE=aVPVE.Append1();
728       aPVE.SetIndices(nVx, nE);
729       aPVE.SetVertex(aVx);
730       aPVE.SetEdge(aE);
731       aPVE.SetPaveBlock(aPB);
732     }
733   }
734   //
735   aNbVPVE=aVPVE.Extent();
736   //=============================================================
737   BOPAlgo_PVECnt::Perform(myRunParallel, aVPVE, myContext);
738   //=============================================================
739   //
740   for (k=0; k < aNbVPVE; ++k) {
741     BOPAlgo_PVE& aPVE=aVPVE(k);
742     iFlag=aPVE.Flag();
743     if (!iFlag) {
744       aPVE.Indices(nVx, nE);
745       aT=aPVE.Parameter();
746       Handle(BOPDS_PaveBlock)& aPB=aPVE.PaveBlock();
747       //
748       aPave.SetIndex(nVx);
749       aPave.SetParameter(aT);
750       aPB->AppendExtPave(aPave);
751     }
752   }
753   // 6  Split PaveBlocksa
754   aNb=aMPBLI.Extent();
755   for(i=1; i<=aNb; ++i) {
756     Handle(BOPDS_PaveBlock) aPB=aMPBLI.FindKey(i);
757     nE=aPB->OriginalEdge();
758     // 3
759     if (!myDS->IsCommonBlock(aPB)) {
760       myDS->UpdatePaveBlock(aPB);
761     }
762     else {
763       const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
764       myDS->UpdateCommonBlock(aCB);
765     }    
766   }//for (; aItMPBLI.More(); aItMPBLI.Next()) {
767   //
768   return iRet;
769 }
770 //=======================================================================
771 //function : TreatNewVertices
772 //purpose  : 
773 //=======================================================================
774 void BOPAlgo_PaveFiller::TreatNewVertices
775 (const BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB,
776    BOPCol_IndexedDataMapOfShapeListOfShape& myImages)
777 {
778   Standard_Integer  i, aNbV;//, aNbVSD;
779   Standard_Real aTol;
780   TopoDS_Vertex aVnew;
781   BOPCol_IndexedMapOfShape aMVProcessed;
782   BOPCol_MapOfInteger aMFence;
783   BOPCol_ListIteratorOfListOfInteger aIt;
784   NCollection_Vector<BOPCol_ListOfShape> aVecOfLVSD;
785   //
786   BOPCol_BoxBndTree aBBTree;
787   NCollection_UBTreeFiller <Standard_Integer, 
788                             Bnd_Box> aTreeFiller(aBBTree);
789   BOPAlgo_VectorOfTNV aVTNV;
790   //
791   Standard_Real aTolAdd = Precision::Confusion() / 2.;
792   aNbV = theMVCPB.Extent();
793   for (i=1; i<=aNbV; ++i) {
794     const TopoDS_Vertex& aV = *((TopoDS_Vertex*)&theMVCPB.FindKey(i));
795     Bnd_Box aBox;
796     //
797     aTol = theMVCPB.FindFromIndex(i).Tolerance();
798     aBox.Add(BRep_Tool::Pnt(aV));
799     aBox.SetGap(aTol + aTolAdd);
800     //
801     aTreeFiller.Add(i, aBox);
802     //
803     BOPAlgo_TNV& aTNV=aVTNV.Append1();
804     aTNV.SetTree(aBBTree);
805     aTNV.SetBox(aBox);
806     aTNV.SetVertex(aV);
807   }
808   //
809   aTreeFiller.Fill();
810   //
811   //===========================================
812   BOPAlgo_TNVCnt::Perform(myRunParallel, aVTNV);
813   //===========================================
814   //
815   // Chains
816   for (i=1; i<=aNbV; ++i) {
817     if (!aMFence.Add(i)) {
818       continue;
819     }
820     //
821     Standard_Integer aIP, aNbIP1, aIP1;
822     BOPCol_ListOfShape aLVSD;
823     BOPCol_ListOfInteger aLIP, aLIP1, aLIPC;
824     BOPCol_ListIteratorOfListOfInteger aItLIP;
825     //
826     aLIPC.Append(i);
827     aLIP.Append(i);
828     for(;;) {
829       aItLIP.Initialize(aLIP);
830       for(; aItLIP.More(); aItLIP.Next()) {
831         aIP=aItLIP.Value();
832         //
833         BOPAlgo_TNV& aTNV=aVTNV(aIP-1);
834         const BOPCol_ListOfInteger& aLI=aTNV.Indices();
835         aIt.Initialize(aLI);
836         for (; aIt.More(); aIt.Next()) {
837           aIP1=aIt.Value();
838           if (!aMFence.Add(aIP1)) {
839             continue;
840           }
841           aLIP1.Append(aIP1);
842         } //for (; aIt.More(); aIt.Next()) {
843       }//for(; aIt1.More(); aIt1.Next()) {
844       //
845       aNbIP1=aLIP1.Extent();
846       if (!aNbIP1) {
847         break; // from for(;;) 
848       }
849       //
850       aLIP = aLIP1;
851       aLIPC.Append(aLIP1); // items of aLIP1 are moved to aLIPC
852     }// for(;;) {
853     //
854     aItLIP.Initialize(aLIPC);
855     for(; aItLIP.More(); aItLIP.Next()) {
856       aIP=aItLIP.Value();
857       const TopoDS_Vertex& aVP=aVTNV(aIP-1).Vertex(); 
858       aLVSD.Append(aVP);
859     }
860     aVecOfLVSD.Append(aLVSD);
861   }// for (i=1; i<=aNbV; ++i) {
862
863   // Make new vertices
864   aNbV = aVecOfLVSD.Size();
865   for (i = 0; i < aNbV; ++i) {
866     const BOPCol_ListOfShape& aLVSD = aVecOfLVSD(i);
867     BOPTools_AlgoTools::MakeVertex(aLVSD, aVnew);
868     myImages.Add(aVnew, aLVSD);
869   }
870 }
871 //=======================================================================
872 //function : FillShrunkData
873 //purpose  : 
874 //=======================================================================
875 void BOPAlgo_PaveFiller::FillShrunkData(Handle(BOPDS_PaveBlock)& thePB)
876 {
877   Standard_Integer nE, nV1, nV2;
878   Standard_Real aT1, aT2, aTS1, aTS2;
879   IntTools_ShrunkRange aSR;
880   //
881   myErrorStatus=0;
882   myWarningStatus = 0;
883   //
884   const BOPDS_Pave& aPave1=thePB->Pave1();
885   nV1=aPave1.Index();
886   aT1=aPave1.Parameter();
887   const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1))); 
888   //
889   const BOPDS_Pave& aPave2=thePB->Pave2();
890   nV2=aPave2.Index();
891   aT2=aPave2.Parameter();
892   const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2))); 
893   //
894   nE=thePB->OriginalEdge();
895   const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
896   //
897   aSR.SetContext(myContext);
898   aSR.SetData(aE, aT1, aT2, aV1, aV2);
899   //
900   aSR.Perform();
901   if (!aSR.IsDone()) {
902     myWarningStatus = 1;
903     return;
904   }
905   //
906   aSR.ShrunkRange(aTS1, aTS2);
907   const Bnd_Box& aBox=aSR.BndBox();
908   Standard_Boolean bIsSplittable = aSR.IsSplittable();
909   //
910   thePB->SetShrunkData(aTS1, aTS2, aBox, bIsSplittable);
911 }
912 //=======================================================================
913 //function : ForceInterfVE
914 //purpose  : 
915 //=======================================================================
916 void BOPAlgo_PaveFiller::ForceInterfVE(const Standard_Integer nV,
917                                        Handle(BOPDS_PaveBlock)& aPB,
918                                        BOPDS_MapOfPaveBlock& aMPBToUpdate)
919 {
920   Standard_Integer nE, nVx, nVSD, iFlag;
921   Standard_Real aT, aTolVNew;
922   //
923   nE = aPB->OriginalEdge();
924   //
925   const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
926   if (aSIE.HasSubShape(nV)) {
927     return;
928   }
929   //
930   if (myDS->HasInterf(nV, nE)) {
931     return;
932   }   
933   //
934   if (myDS->HasInterfShapeSubShapes(nV, nE)) {
935     return;
936   }
937   //
938   if (aPB->Pave1().Index() == nV || 
939       aPB->Pave2().Index() == nV) {
940     return;
941   }
942   //
943   nVx = nV;
944   if (myDS->HasShapeSD(nV, nVSD)) {
945     nVx = nVSD;
946   }
947   //
948   const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nVx);
949   const TopoDS_Edge&   aE = *(TopoDS_Edge*)  &myDS->Shape(nE);
950   //
951   iFlag = myContext->ComputeVE(aV, aE, aT, aTolVNew);
952   if (iFlag == 0 || iFlag == -4) {
953     BOPDS_Pave aPave;
954     //
955     //
956     BOPDS_VectorOfInterfVE& aVEs=myDS->InterfVE();
957     aVEs.SetIncrement(10);
958     // 1
959     BOPDS_InterfVE& aVE=aVEs.Append1();
960     aVE.SetIndices(nV, nE);
961     aVE.SetParameter(aT);
962     // 2
963     myDS->AddInterf(nV, nE);
964     //
965     // 3 update vertex V/E if necessary
966     nVx=UpdateVertex(nV, aTolVNew);
967     // 4
968     if (myDS->IsNewShape(nVx)) {
969       aVE.SetIndexNew(nVx);
970     }
971     // 5 append ext pave to pave block
972     aPave.SetIndex(nVx);
973     aPave.SetParameter(aT);
974     aPB->AppendExtPave(aPave);
975     //
976     aMPBToUpdate.Add(aPB);
977   }
978 }
979
980 //=======================================================================
981 //function : GetPBBox
982 //purpose  : 
983 //=======================================================================
984 Standard_Boolean BOPAlgo_PaveFiller::GetPBBox(const TopoDS_Edge& theE,
985                                               const Handle(BOPDS_PaveBlock)& thePB,
986                                               BOPAlgo_DataMapOfPaveBlockBndBox& thePBBox,
987                                               Standard_Real& theFirst,
988                                               Standard_Real& theLast,
989                                               Standard_Real& theSFirst,
990                                               Standard_Real& theSLast,
991                                               Bnd_Box& theBox)
992 {
993   thePB->Range(theFirst, theLast);
994   // check the validity of PB's range
995   Standard_Boolean bValid = theLast - theFirst > Precision::PConfusion();
996   if (!bValid) {
997     return bValid;
998   }
999   //
1000   // check shrunk data
1001   if (thePB->HasShrunkData()) {
1002     Standard_Boolean bIsSplittable;
1003     thePB->ShrunkData(theSFirst, theSLast, theBox, bIsSplittable);
1004     return bValid;
1005   }
1006   //
1007   theSFirst = theFirst;
1008   theSLast = theLast;
1009   // check the map
1010   if (thePBBox.IsBound(thePB)) {
1011     theBox = thePBBox.Find(thePB);
1012   }
1013   else {
1014     // build bounding box
1015     BRepAdaptor_Curve aBAC(theE);
1016     Standard_Real aTol = BRep_Tool::Tolerance(theE) + Precision::Confusion();
1017     BndLib_Add3dCurve::Add(aBAC, theSFirst, theSLast, aTol, theBox);
1018     thePBBox.Bind(thePB, theBox);
1019   }
1020   return bValid;
1021 }