0028775: Code duplication removal across the BOPAlgo_PaveFiller algorithm
[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_Tools.hxx>
22 #include <BOPCol_NCVector.hxx>
23 #include <BOPCol_Parallel.hxx>
24 #include <BOPDS_CommonBlock.hxx>
25 #include <BOPDS_CoupleOfPaveBlocks.hxx>
26 #include <BOPDS_DS.hxx>
27 #include <BOPDS_Interf.hxx>
28 #include <BOPDS_Iterator.hxx>
29 #include <BOPDS_MapOfPaveBlock.hxx>
30 #include <BOPDS_Pave.hxx>
31 #include <BOPDS_PaveBlock.hxx>
32 #include <BOPDS_VectorOfInterfEE.hxx>
33 #include <BOPTools_AlgoTools.hxx>
34 #include <BndLib_Add3dCurve.hxx>
35 #include <BRep_Tool.hxx>
36 #include <BRepAdaptor_Curve.hxx>
37 #include <gp_Pnt.hxx>
38 #include <IntTools_CommonPrt.hxx>
39 #include <IntTools_Context.hxx>
40 #include <IntTools_EdgeEdge.hxx>
41 #include <IntTools_Range.hxx>
42 #include <IntTools_SequenceOfCommonPrts.hxx>
43 #include <IntTools_SequenceOfRanges.hxx>
44 #include <IntTools_ShrunkRange.hxx>
45 #include <IntTools_Tools.hxx>
46 #include <Precision.hxx>
47 #include <TopoDS.hxx>
48 #include <TopoDS_Edge.hxx>
49 #include <TopoDS_Vertex.hxx>
50
51 /////////////////////////////////////////////////////////////////////////
52 //=======================================================================
53 //class    : BOPAlgo_EdgeEdge
54 //purpose  : 
55 //=======================================================================
56 class BOPAlgo_EdgeEdge : 
57   public IntTools_EdgeEdge,
58   public BOPAlgo_Algo {
59  
60  public:
61
62   DEFINE_STANDARD_ALLOC
63   //
64   BOPAlgo_EdgeEdge(): 
65     IntTools_EdgeEdge(),
66     BOPAlgo_Algo() {
67   };
68   //
69   virtual ~BOPAlgo_EdgeEdge(){
70   };
71   //
72   void SetPaveBlock1(const Handle(BOPDS_PaveBlock)& aPB) {
73     myPB1=aPB;
74   }
75   //
76   Handle(BOPDS_PaveBlock)& PaveBlock1() {
77     return myPB1;
78   }
79   //
80   void SetPaveBlock2(const Handle(BOPDS_PaveBlock)& aPB) {
81     myPB2=aPB;
82   }
83   //
84   Handle(BOPDS_PaveBlock)& PaveBlock2() {
85     return myPB2;
86   }
87   // 
88   void SetFuzzyValue(const Standard_Real theFuzz) {
89     IntTools_EdgeEdge::SetFuzzyValue(theFuzz);
90   }
91   //
92   virtual void Perform() {
93     BOPAlgo_Algo::UserBreak();
94     IntTools_EdgeEdge::Perform();
95   }
96   //
97  protected:
98   Handle(BOPDS_PaveBlock) myPB1;
99   Handle(BOPDS_PaveBlock) myPB2;
100 };
101 //
102 //=======================================================================
103 typedef BOPCol_NCVector
104   <BOPAlgo_EdgeEdge> BOPAlgo_VectorOfEdgeEdge; 
105 //
106 typedef BOPCol_Functor 
107   <BOPAlgo_EdgeEdge,
108   BOPAlgo_VectorOfEdgeEdge> BOPAlgo_EdgeEdgeFunctor;
109 //
110 typedef BOPCol_Cnt 
111   <BOPAlgo_EdgeEdgeFunctor,
112   BOPAlgo_VectorOfEdgeEdge> BOPAlgo_EdgeEdgeCnt;
113 //
114 /////////////////////////////////////////////////////////////////////////
115 //=======================================================================
116 // function: PerformEE
117 // purpose: 
118 //=======================================================================
119 void BOPAlgo_PaveFiller::PerformEE()
120 {
121   Standard_Integer iSize;
122   //
123   myErrorStatus=0;
124   //
125   FillShrunkData(TopAbs_EDGE, TopAbs_EDGE);
126   //
127   myIterator->Initialize(TopAbs_EDGE, TopAbs_EDGE);
128   iSize=myIterator->ExpectedLength();
129   if (!iSize) {
130     return; 
131   }
132   //
133   Standard_Boolean bExpressCompute, bIsPBSplittable1, bIsPBSplittable2;
134   Standard_Integer i, iX, nE1, nE2, aNbCPrts, k, aNbEdgeEdge;
135   Standard_Integer nV11, nV12, nV21, nV22;
136   Standard_Real aTS11, aTS12, aTS21, aTS22, aT11, aT12, aT21, aT22;
137   TopAbs_ShapeEnum aType;
138   BOPDS_ListIteratorOfListOfPaveBlock aIt1, aIt2;
139   Handle(NCollection_BaseAllocator) aAllocator;
140   BOPAlgo_VectorOfEdgeEdge aVEdgeEdge;
141   BOPDS_MapIteratorOfMapOfPaveBlock aItPB; 
142   // keep modified edges for further update
143   BOPCol_MapOfInteger aMEdges;
144   //
145   aAllocator=NCollection_BaseAllocator::CommonBaseAllocator();
146   //-----------------------------------------------------scope f
147   BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock aMPBLPB(100, aAllocator);
148   BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMVCPB(100, aAllocator);
149   BOPAlgo_DataMapOfPaveBlockBndBox aDMPBBox(100, aAllocator);
150   //
151   BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
152   aEEs.SetIncrement(iSize);
153   //
154   for (; myIterator->More(); myIterator->Next()) {
155     myIterator->Value(nE1, nE2);
156     //
157     const BOPDS_ShapeInfo& aSIE1=myDS->ShapeInfo(nE1);
158     if (aSIE1.HasFlag()){
159       continue;
160     }
161     const BOPDS_ShapeInfo& aSIE2=myDS->ShapeInfo(nE2);
162     if (aSIE2.HasFlag()){
163       continue;
164     }
165     //
166     BOPDS_ListOfPaveBlock& aLPB1 = myDS->ChangePaveBlocks(nE1);
167     if (aLPB1.IsEmpty()) {
168       continue;
169     }
170     //
171     BOPDS_ListOfPaveBlock& aLPB2 = myDS->ChangePaveBlocks(nE2);
172     if (aLPB2.IsEmpty()) {
173       continue;
174     }
175     //
176     const TopoDS_Edge& aE1=(*(TopoDS_Edge *)(&aSIE1.Shape()));
177     const TopoDS_Edge& aE2=(*(TopoDS_Edge *)(&aSIE2.Shape()));
178     //
179     aIt1.Initialize(aLPB1);
180     for (; aIt1.More(); aIt1.Next()) {
181       Bnd_Box aBB1;
182       //
183       Handle(BOPDS_PaveBlock)& aPB1=aIt1.ChangeValue();
184       //
185       if (!GetPBBox(aE1, aPB1, aDMPBBox, aT11, aT12, aTS11, aTS12, aBB1)) {
186         continue;
187       }
188       //
189       aPB1->Indices(nV11, nV12);
190       //
191       aIt2.Initialize(aLPB2);
192       for (; aIt2.More(); aIt2.Next()) {
193         Bnd_Box aBB2;
194         //
195         Handle(BOPDS_PaveBlock)& aPB2=aIt2.ChangeValue();
196         //
197         if (!GetPBBox(aE2, aPB2, aDMPBBox, aT21, aT22, aTS21, aTS22, aBB2)) {
198           continue;
199         }
200         //
201         if (aBB1.IsOut(aBB2)) {
202           continue;
203         }
204         //
205         aPB2->Indices(nV21, nV22);
206         //
207         bExpressCompute=((nV11==nV21 && nV12==nV22) ||
208                          (nV12==nV21 && nV11==nV22));
209         //
210         BOPAlgo_EdgeEdge& anEdgeEdge=aVEdgeEdge.Append1();
211         //
212         anEdgeEdge.UseQuickCoincidenceCheck(bExpressCompute);
213         //
214         anEdgeEdge.SetPaveBlock1(aPB1);
215         anEdgeEdge.SetPaveBlock2(aPB2);
216         //
217         anEdgeEdge.SetEdge1(aE1, aT11, aT12);
218         anEdgeEdge.SetEdge2(aE2, aT21, aT22);
219         anEdgeEdge.SetFuzzyValue(myFuzzyValue);
220         anEdgeEdge.SetProgressIndicator(myProgressIndicator);
221       }//for (; aIt2.More(); aIt2.Next()) {
222     }//for (; aIt1.More(); aIt1.Next()) {
223   }//for (; myIterator->More(); myIterator->Next()) {
224   //
225   aNbEdgeEdge=aVEdgeEdge.Extent();
226   //======================================================
227   BOPAlgo_EdgeEdgeCnt::Perform(myRunParallel, aVEdgeEdge);
228   //======================================================
229   //
230   for (k = 0; k < aNbEdgeEdge; ++k) {
231     Bnd_Box aBB1, aBB2;
232     //
233     BOPAlgo_EdgeEdge& anEdgeEdge=aVEdgeEdge(k);
234     if (!anEdgeEdge.IsDone()) {
235       continue;
236     }
237     //
238     const IntTools_SequenceOfCommonPrts& aCPrts = anEdgeEdge.CommonParts();
239     aNbCPrts = aCPrts.Length();
240     if (!aNbCPrts) {
241       continue;
242     }
243     //--------------------------------------------
244     Handle(BOPDS_PaveBlock)& aPB1=anEdgeEdge.PaveBlock1();
245     nE1=aPB1->OriginalEdge();
246     aPB1->Range(aT11, aT12);
247     if (!aPB1->HasShrunkData()) {
248       aTS11 = aT11;
249       aTS12 = aT12;
250       bIsPBSplittable1 = Standard_False;
251     }
252     else {
253       aPB1->ShrunkData(aTS11, aTS12, aBB1, bIsPBSplittable1);
254     }
255     //
256     Handle(BOPDS_PaveBlock)& aPB2=anEdgeEdge.PaveBlock2();
257     nE2=aPB2->OriginalEdge();
258     aPB2->Range(aT21, aT22);
259     if (!aPB2->HasShrunkData()) {
260       aTS21 = aT21;
261       aTS22 = aT22;
262       bIsPBSplittable2 = Standard_False;
263     }
264     else {
265       aPB2->ShrunkData(aTS21, aTS22, aBB2, bIsPBSplittable2);
266     }
267     //
268     //--------------------------------------------
269     IntTools_Range aR11(aT11, aTS11), aR12(aTS12, aT12),
270                    aR21(aT21, aTS21), aR22(aTS22, aT22);
271     //
272     Standard_Boolean bAnalytical = Standard_False;
273     {
274       const TopoDS_Edge& aOE1 = *(TopoDS_Edge*)&myDS->Shape(nE1);
275       const TopoDS_Edge& aOE2 = *(TopoDS_Edge*)&myDS->Shape(nE2);
276       //
277       BRepAdaptor_Curve aBAC1(aOE1), aBAC2(aOE2);
278       //
279       GeomAbs_CurveType aType1 = aBAC1.GetType();
280       GeomAbs_CurveType aType2 = aBAC2.GetType();
281       //
282       bAnalytical = (((aType1 == GeomAbs_Line) &&
283                       (aType2 == GeomAbs_Line ||
284                        aType2 == GeomAbs_Circle)) ||
285                      ((aType2 == GeomAbs_Line) &&
286                       (aType1 == GeomAbs_Line ||
287                        aType1 == GeomAbs_Circle)));
288     }
289     //
290     for (i=1; i<=aNbCPrts; ++i) {
291       const IntTools_CommonPrt& aCPart=aCPrts(i);
292       //
293       const TopoDS_Edge& aE1=aCPart.Edge1();
294       const TopoDS_Edge& aE2=aCPart.Edge2();
295       //
296       aType=aCPart.Type();
297       switch (aType) {
298         case TopAbs_VERTEX:  { 
299           if (!bIsPBSplittable1 || !bIsPBSplittable2) {
300             continue;
301           }
302           //
303           Standard_Boolean bIsOnPave[4], bFlag;
304           Standard_Integer nV[4], j;
305           Standard_Real aT1, aT2, aTol;
306           TopoDS_Vertex aVnew;
307           IntTools_Range aCR1, aCR2;
308           //
309           IntTools_Tools::VertexParameters(aCPart, aT1, aT2);
310           aTol = Precision::Confusion();
311           aCR1 = aCPart.Range1();
312           aCR2 = aCPart.Ranges2()(1);
313           // 
314           //decide to keep the pave or not
315           bIsOnPave[0] = IntTools_Tools::IsOnPave1(aT1, aR11, aTol) ||
316             IntTools_Tools::IsOnPave1(aR11.First(), aCR1, aTol);
317           bIsOnPave[1] = IntTools_Tools::IsOnPave1(aT1, aR12, aTol) || 
318             IntTools_Tools::IsOnPave1(aR12.Last(), aCR1, aTol);
319           bIsOnPave[2] = IntTools_Tools::IsOnPave1(aT2, aR21, aTol) ||
320             IntTools_Tools::IsOnPave1(aR21.First(), aCR2, aTol);
321           bIsOnPave[3] = IntTools_Tools::IsOnPave1(aT2, aR22, aTol) ||
322             IntTools_Tools::IsOnPave1(aR22.Last(), aCR2, aTol);
323           //
324           aPB1->Indices(nV[0], nV[1]);
325           aPB2->Indices(nV[2], nV[3]);
326           //
327           if((bIsOnPave[0] && bIsOnPave[2]) || 
328              (bIsOnPave[0] && bIsOnPave[3]) ||
329              (bIsOnPave[1] && bIsOnPave[2]) || 
330              (bIsOnPave[1] && bIsOnPave[3])) {
331             continue;
332           }
333           //
334           bFlag = Standard_False;
335           for (j = 0; j < 4; ++j) {
336             if (bIsOnPave[j]) {
337               //add interf VE(nV[j], nE)
338               Handle(BOPDS_PaveBlock)& aPB = (j < 2) ? aPB2 : aPB1;
339               ForceInterfVE(nV[j], aPB, aMEdges);
340               bFlag = Standard_True;
341               break;
342             }
343           }
344           if (bFlag) {
345             BOPDS_InterfEE& aEE = aEEs.Append1();
346             aEE.SetIndices(nE1, nE2);
347             aEE.SetCommonPart(aCPart);
348             continue;
349           }
350           //
351           BOPTools_AlgoTools::MakeNewVertex(aE1, aT1, aE2, aT2, aVnew);
352           Standard_Real aTolVnew = BRep_Tool::Tolerance(aVnew);
353           if (bAnalytical) {
354             // increase tolerance for Line/Line intersection, but do not update 
355             // the vertex till its intersection with some other shape
356             Standard_Real aTolMin = (BRepAdaptor_Curve(aE1).GetType() == GeomAbs_Line) ?
357               (aCR1.Last() - aCR1.First()) / 2. : (aCR2.Last() - aCR2.First()) / 2.;
358             if (aTolMin > aTolVnew) {
359               aTolVnew = aTolMin;
360             }
361           }
362           // <-LXBR
363           {
364             Standard_Integer nVS[2], iFound;
365             Standard_Real aTolVx, aD2, aDT2;
366             BOPCol_MapOfInteger aMV;
367             gp_Pnt aPnew, aPx;
368             //
369             iFound=0;
370             j=-1;
371             aMV.Add(nV[0]);
372             aMV.Add(nV[1]);
373             //
374             if (aMV.Contains(nV[2])) {
375               ++j;
376               nVS[j]=nV[2];
377             }
378             if (aMV.Contains(nV[3])) {
379               ++j;
380               nVS[j]=nV[3];
381             }
382             //
383             aPnew=BRep_Tool::Pnt(aVnew);
384             //
385             for (Standard_Integer k1=0; k1<=j; ++k1) {
386               const TopoDS_Vertex& aVx= *(TopoDS_Vertex*)&(myDS->Shape(nVS[k1]));
387               aTolVx=BRep_Tool::Tolerance(aVx);
388               aPx=BRep_Tool::Pnt(aVx);
389               aD2=aPnew.SquareDistance(aPx);
390               //
391               aDT2=100.*(aTolVnew+aTolVx)*(aTolVnew+aTolVx);
392               //
393               if (aD2<aDT2) {
394                 iFound=1;
395                 break;
396               }
397             }
398             //
399             if (iFound) {
400               continue;
401             }
402           }
403           //
404           // 1
405           BOPDS_InterfEE& aEE=aEEs.Append1();
406           iX=aEEs.Extent()-1;
407           aEE.SetIndices(nE1, nE2);
408           aEE.SetCommonPart(aCPart);
409           // 2
410           myDS->AddInterf(nE1, nE2);
411           //
412           BOPDS_CoupleOfPaveBlocks aCPB;
413           //
414           aCPB.SetPaveBlocks(aPB1, aPB2);
415           aCPB.SetIndexInterf(iX);
416           aCPB.SetTolerance(aTolVnew);
417           aMVCPB.Add(aVnew, aCPB);
418         }//case TopAbs_VERTEX: 
419           break;
420             //
421         case TopAbs_EDGE: {
422           if (aNbCPrts > 1) {
423             break;
424           }
425           //
426           Standard_Boolean bHasSameBounds;
427           bHasSameBounds=aPB1->HasSameBounds(aPB2);
428           if (!bHasSameBounds) {
429             break;
430           }
431           // 1
432           BOPDS_InterfEE& aEE=aEEs.Append1();
433           iX=aEEs.Extent()-1;
434           aEE.SetIndices(nE1, nE2);
435           aEE.SetCommonPart(aCPart);
436           // 2
437           myDS->AddInterf(nE1, nE2);
438           //
439           BOPAlgo_Tools::FillMap<Handle(BOPDS_PaveBlock), TColStd_MapTransientHasher>(aPB1, aPB2, aMPBLPB, aAllocator);
440         }//case TopAbs_EDGE
441           break;
442         default:
443           break;
444       }//switch (aType) {
445     }//for (i=1; i<=aNbCPrts; i++) {
446   }//for (k=0; k < aNbFdgeEdge; ++k) {
447   // 
448   //=========================================
449   // post treatment
450   //=========================================
451   BOPAlgo_Tools::PerformCommonBlocks(aMPBLPB, aAllocator, myDS);
452   PerformNewVertices(aMVCPB, aAllocator);
453   //
454   if (aMEdges.Extent()) {
455     Standard_Integer aNbV = aMVCPB.Extent();
456     for (i = 1; i <= aNbV; ++i) {
457       Handle(BOPDS_PaveBlock) aPB1, aPB2;
458       const BOPDS_CoupleOfPaveBlocks& aCPB = aMVCPB.FindFromIndex(i);
459       aCPB.PaveBlocks(aPB1, aPB2);
460       //
461       aMEdges.Remove(aPB1->OriginalEdge());
462       aMEdges.Remove(aPB2->OriginalEdge());
463     }
464     //
465     SplitPaveBlocks(aMEdges, Standard_False);
466   }
467   //
468   //-----------------------------------------------------scope t
469   aMPBLPB.Clear();
470   aMVCPB.Clear();
471 }
472 //=======================================================================
473 //function : PerformVerticesEE
474 //purpose  : 
475 //=======================================================================
476 void BOPAlgo_PaveFiller::PerformNewVertices
477   (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB,
478    const Handle(NCollection_BaseAllocator)& theAllocator,
479    const Standard_Boolean bIsEEIntersection)
480 {
481   Standard_Integer aNbV = theMVCPB.Extent();
482   if (!aNbV) {
483     return;
484   }
485   //
486   Standard_Real aTolAdd = myFuzzyValue / 2.;
487   //
488   // 1. Fuse the new vertices
489   BOPCol_IndexedDataMapOfShapeListOfShape aImages;
490   TreatNewVertices(theMVCPB, aImages);
491   //
492   // 2. Add new vertices to myDS and connect indices to CPB structure
493   BOPDS_VectorOfInterfEE& aEEs = myDS->InterfEE();
494   BOPDS_VectorOfInterfEF& aEFs = myDS->InterfEF();
495   //
496   Standard_Integer i, aNb = aImages.Extent();
497   for (i = 1; i <= aNb; ++i) {
498     const TopoDS_Vertex& aV = TopoDS::Vertex(aImages.FindKey(i));
499     const BOPCol_ListOfShape& aLVSD = aImages.FindFromIndex(i);
500     //
501     BOPDS_ShapeInfo aSI;
502     aSI.SetShapeType(TopAbs_VERTEX);
503     aSI.SetShape(aV);
504     Standard_Integer iV = myDS->Append(aSI);
505     //
506     BOPDS_ShapeInfo& aSIDS = myDS->ChangeShapeInfo(iV);
507     Bnd_Box& aBox = aSIDS.ChangeBox();
508     aBox.Add(BRep_Tool::Pnt(aV));
509     aBox.SetGap(BRep_Tool::Tolerance(aV) + aTolAdd);
510     //
511     BOPCol_ListIteratorOfListOfShape aItLS(aLVSD);
512     for (; aItLS.More(); aItLS.Next()) {
513       const TopoDS_Shape& aVx = aItLS.Value();
514       BOPDS_CoupleOfPaveBlocks &aCPB = theMVCPB.ChangeFromKey(aVx);
515       aCPB.SetIndex(iV);
516       // update interference
517       Standard_Integer iX = aCPB.IndexInterf();
518       BOPDS_Interf *aInt = bIsEEIntersection ? (BOPDS_Interf*)(&aEEs(iX)) : (BOPDS_Interf*) (&aEFs(iX));
519       aInt->SetIndexNew(iV);
520     }
521   }
522   //
523   // 3. Map PaveBlock/ListOfVertices to add to this PaveBlock ->aMPBLI
524   BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, theAllocator);
525   for (i = 1; i <= aNbV; ++i) {
526     const BOPDS_CoupleOfPaveBlocks& aCPB = theMVCPB.FindFromIndex(i);
527     Standard_Integer iV = aCPB.Index();
528     //
529     Handle(BOPDS_PaveBlock) aPB[2];
530     aCPB.PaveBlocks(aPB[0], aPB[1]);
531     for (Standard_Integer j = 0; j < 2; ++j) {
532       BOPCol_ListOfInteger *pLI = aMPBLI.ChangeSeek(aPB[j]);
533       if (!pLI) {
534         pLI = &aMPBLI(aMPBLI.Add(aPB[j], BOPCol_ListOfInteger(theAllocator)));
535       }
536       pLI->Append(iV);
537       //
538       if (aPB[0] == aPB[1]) {
539         break;
540       }
541     }
542   }
543   //
544   // 4. Compute Extra Paves and split Pave blocks by the Extra paves
545   IntersectVE(aMPBLI, Standard_False);
546 }
547 //=======================================================================
548 //function : TreatNewVertices
549 //purpose  : 
550 //=======================================================================
551 void BOPAlgo_PaveFiller::TreatNewVertices
552   (const BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB,
553    BOPCol_IndexedDataMapOfShapeListOfShape& myImages)
554 {
555   //
556   // Prepare for intersection
557   BOPCol_IndexedDataMapOfShapeReal aVerts;
558   Standard_Integer i, aNbV = theMVCPB.Extent();
559   for (i = 1; i <= aNbV; ++i) {
560     const TopoDS_Shape& aV = theMVCPB.FindKey(i);
561     Standard_Real aTol = theMVCPB.FindFromIndex(i).Tolerance();
562     aVerts.Add(aV, aTol);
563   }
564   //
565   // Perform intersection
566   BOPCol_ListOfListOfShape aChains;
567   BOPAlgo_Tools::IntersectVertices(aVerts, myRunParallel, myFuzzyValue, aChains);
568   //
569   // Treat the results - make new vertices for each chain
570   BOPCol_ListOfListOfShape::Iterator aItC(aChains);
571   for (; aItC.More(); aItC.Next()) {
572     const BOPCol_ListOfShape& aLVSD = aItC.Value();
573     //
574     TopoDS_Vertex aVNew;
575     BOPTools_AlgoTools::MakeVertex(aLVSD, aVNew);
576     myImages.Add(aVNew, aLVSD);
577   }
578 }
579 //=======================================================================
580 //function : FillShrunkData
581 //purpose  : 
582 //=======================================================================
583 void BOPAlgo_PaveFiller::FillShrunkData(Handle(BOPDS_PaveBlock)& thePB)
584 {
585   Standard_Integer nE, nV1, nV2;
586   Standard_Real aT1, aT2, aTS1, aTS2;
587   IntTools_ShrunkRange aSR;
588   //
589   myErrorStatus=0;
590   myWarningStatus = 0;
591   //
592   const BOPDS_Pave& aPave1=thePB->Pave1();
593   nV1=aPave1.Index();
594   aT1=aPave1.Parameter();
595   const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1))); 
596   //
597   const BOPDS_Pave& aPave2=thePB->Pave2();
598   nV2=aPave2.Index();
599   aT2=aPave2.Parameter();
600   const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2))); 
601   //
602   nE=thePB->OriginalEdge();
603   const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
604   //
605   aSR.SetContext(myContext);
606   aSR.SetData(aE, aT1, aT2, aV1, aV2);
607   //
608   aSR.Perform();
609   if (!aSR.IsDone()) {
610     myWarningStatus = 1;
611     return;
612   }
613   //
614   aSR.ShrunkRange(aTS1, aTS2);
615   const Bnd_Box& aBox=aSR.BndBox();
616   Standard_Boolean bIsSplittable = aSR.IsSplittable();
617   //
618   thePB->SetShrunkData(aTS1, aTS2, aBox, bIsSplittable);
619 }
620 //=======================================================================
621 //function : ForceInterfVE
622 //purpose  : 
623 //=======================================================================
624 void BOPAlgo_PaveFiller::ForceInterfVE(const Standard_Integer nV,
625                                        Handle(BOPDS_PaveBlock)& aPB,
626                                        BOPCol_MapOfInteger& theMEdges)
627 {
628   Standard_Integer nE, nVx, nVSD, iFlag;
629   Standard_Real aT, aTolVNew;
630   //
631   nE = aPB->OriginalEdge();
632   //
633   const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
634   if (aSIE.HasSubShape(nV)) {
635     return;
636   }
637   //
638   if (myDS->HasInterf(nV, nE)) {
639     return;
640   }   
641   //
642   if (myDS->HasInterfShapeSubShapes(nV, nE)) {
643     return;
644   }
645   //
646   if (aPB->Pave1().Index() == nV || 
647       aPB->Pave2().Index() == nV) {
648     return;
649   }
650   //
651   nVx = nV;
652   if (myDS->HasShapeSD(nV, nVSD)) {
653     nVx = nVSD;
654   }
655   //
656   const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nVx);
657   const TopoDS_Edge&   aE = *(TopoDS_Edge*)  &myDS->Shape(nE);
658   //
659   iFlag = myContext->ComputeVE(aV, aE, aT, aTolVNew, myFuzzyValue);
660   if (iFlag == 0 || iFlag == -4) {
661     BOPDS_Pave aPave;
662     //
663     //
664     BOPDS_VectorOfInterfVE& aVEs=myDS->InterfVE();
665     aVEs.SetIncrement(10);
666     // 1
667     BOPDS_InterfVE& aVE=aVEs.Append1();
668     aVE.SetIndices(nV, nE);
669     aVE.SetParameter(aT);
670     // 2
671     myDS->AddInterf(nV, nE);
672     //
673     // 3 update vertex V/E if necessary
674     nVx=UpdateVertex(nV, aTolVNew);
675     // 4
676     if (myDS->IsNewShape(nVx)) {
677       aVE.SetIndexNew(nVx);
678     }
679     // 5 append ext pave to pave block
680     aPave.SetIndex(nVx);
681     aPave.SetParameter(aT);
682     aPB->AppendExtPave(aPave);
683     //
684     theMEdges.Add(nE);
685   }
686 }
687
688 //=======================================================================
689 //function : GetPBBox
690 //purpose  : 
691 //=======================================================================
692 Standard_Boolean BOPAlgo_PaveFiller::GetPBBox(const TopoDS_Edge& theE,
693                                               const Handle(BOPDS_PaveBlock)& thePB,
694                                               BOPAlgo_DataMapOfPaveBlockBndBox& thePBBox,
695                                               Standard_Real& theFirst,
696                                               Standard_Real& theLast,
697                                               Standard_Real& theSFirst,
698                                               Standard_Real& theSLast,
699                                               Bnd_Box& theBox)
700 {
701   thePB->Range(theFirst, theLast);
702   // check the validity of PB's range
703   Standard_Boolean bValid = theLast - theFirst > Precision::PConfusion();
704   if (!bValid) {
705     return bValid;
706   }
707   //
708   // check shrunk data
709   if (thePB->HasShrunkData()) {
710     Standard_Boolean bIsSplittable;
711     thePB->ShrunkData(theSFirst, theSLast, theBox, bIsSplittable);
712     return bValid;
713   }
714   //
715   theSFirst = theFirst;
716   theSLast = theLast;
717   // check the map
718   if (thePBBox.IsBound(thePB)) {
719     theBox = thePBBox.Find(thePB);
720   }
721   else {
722     // build bounding box
723     BRepAdaptor_Curve aBAC(theE);
724     Standard_Real aTol = BRep_Tool::Tolerance(theE) + Precision::Confusion();
725     BndLib_Add3dCurve::Add(aBAC, theSFirst, theSLast, aTol, theBox);
726     thePBBox.Bind(thePB, theBox);
727   }
728   return bValid;
729 }