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