0024648: Different types of intersection curves between Cone and Torus with a differe...
[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 #include <BOPAlgo_PaveFiller.ixx>
19
20 #include <Precision.hxx>
21 #include <NCollection_IncAllocator.hxx>
22 #include <NCollection_UBTreeFiller.hxx>
23
24 #include <Bnd_Box.hxx>
25
26 #include <GeomAPI_ProjectPointOnCurve.hxx>
27
28 #include <TopoDS_Edge.hxx>
29 #include <TopoDS_Vertex.hxx>
30 #include <TopoDS_Compound.hxx>
31 #include <BRep_Tool.hxx>
32 #include <BRep_Builder.hxx>
33 #include <BRepTools.hxx>
34 #include <BRepBndLib.hxx>
35 //
36 #include <IntTools_EdgeEdge.hxx>
37 #include <IntTools_Range.hxx>
38 #include <IntTools_SequenceOfCommonPrts.hxx>
39 #include <IntTools_CommonPrt.hxx>
40 #include <IntTools_SequenceOfRanges.hxx>
41 //
42 #include <BOPTools_AlgoTools.hxx>
43 //
44 #include <BOPCol_DataMapOfShapeInteger.hxx>
45 #include <BOPCol_DataMapOfIntegerShape.hxx>
46 #include <BOPCol_IndexedDataMapOfShapeBox.hxx>
47 #include <BOPCol_BoxBndTree.hxx>
48 //
49 #include <BOPInt_Context.hxx>
50 #include <BOPInt_ShrunkRange.hxx>
51 #include <BOPInt_Tools.hxx>
52 //
53 #include <BOPDS_DataMapOfPaveBlockListOfPaveBlock.hxx>
54 #include <BOPDS_MapOfPaveBlock.hxx>
55 #include <BOPDS_CommonBlock.hxx>
56 #include <BOPDS_CoupleOfPaveBlocks.hxx>
57 #include <BOPDS_DataMapOfPaveBlockListOfInteger.hxx>
58 #include <BOPDS_Iterator.hxx>
59 #include <BOPDS_VectorOfInterfEE.hxx>
60 #include <BOPDS_Interf.hxx>
61 #include <BOPDS_Pave.hxx>
62 //
63 #include <BOPAlgo_Tools.hxx>
64
65
66 //=======================================================================
67 // function: PerformEE
68 // purpose: 
69 //=======================================================================
70 void BOPAlgo_PaveFiller::PerformEE()
71 {
72   Standard_Boolean bJustAdd;
73   Standard_Integer i, iX, iSize, nE1, nE2;
74   Standard_Integer aNbCPrts;
75   Standard_Real aTS11, aTS12, aTS21, aTS22,
76                 aT11, aT12, aT21, aT22;
77   TopAbs_ShapeEnum aType;
78   BOPDS_ListIteratorOfListOfPaveBlock aIt1, aIt2;
79   Handle(NCollection_IncAllocator) aAllocator;
80   BOPDS_MapOfPaveBlock aMPBToUpdate;
81   BOPDS_MapIteratorOfMapOfPaveBlock aItPB;
82   //
83   myErrorStatus=0;
84   //
85   myIterator->Initialize(TopAbs_EDGE, TopAbs_EDGE);
86   iSize=myIterator->ExpectedLength();
87   if (!iSize) {
88     return; 
89   }
90   //
91   //-----------------------------------------------------scope f
92   aAllocator=new NCollection_IncAllocator();
93   BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock aMPBLPB(100, aAllocator);
94   BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMVCPB(100, aAllocator);
95   //
96   BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
97   aEEs.SetStartSize(iSize);
98   aEEs.SetIncrement(iSize);
99   aEEs.Init();
100   //
101   for (; myIterator->More(); myIterator->Next()) {
102     myIterator->Value(nE1, nE2, bJustAdd);
103     if(bJustAdd) {
104       continue;
105     }
106     //
107     const BOPDS_ShapeInfo& aSIE1=myDS->ShapeInfo(nE1);
108     if (aSIE1.HasFlag()){
109       continue;
110     }
111     const BOPDS_ShapeInfo& aSIE2=myDS->ShapeInfo(nE2);
112     if (aSIE2.HasFlag()){
113       continue;
114     }
115     //
116     const TopoDS_Edge& aE1=(*(TopoDS_Edge *)(&aSIE1.Shape()));
117     const TopoDS_Edge& aE2=(*(TopoDS_Edge *)(&aSIE2.Shape()));  
118     //
119     BOPDS_ListOfPaveBlock& aLPB1=myDS->ChangePaveBlocks(nE1);
120     BOPDS_ListOfPaveBlock& aLPB2=myDS->ChangePaveBlocks(nE2);
121     //
122     aIt1.Initialize(aLPB1);
123     for (; aIt1.More(); aIt1.Next()) {
124       Bnd_Box aBB1;
125       //
126       Handle(BOPDS_PaveBlock)& aPB1=aIt1.ChangeValue();
127       if (!aPB1->HasShrunkData()) {
128         FillShrunkData(aPB1);
129         if (myWarningStatus) {
130           continue;
131         }
132       }
133       aPB1->ShrunkData(aTS11, aTS12, aBB1);
134       //
135       aIt2.Initialize(aLPB2);
136       for (; aIt2.More(); aIt2.Next()) {
137         Bnd_Box aBB2;
138         //
139         Handle(BOPDS_PaveBlock)& aPB2=aIt2.ChangeValue();
140         if (!aPB2->HasShrunkData()) {
141           FillShrunkData(aPB2);
142           if (myWarningStatus) {
143             continue;
144           }
145         }
146         aPB2->ShrunkData(aTS21, aTS22, aBB2);
147         //
148         if (aBB1.IsOut(aBB2)) {
149           continue;
150         }
151         //
152         IntTools_EdgeEdge anEdgeEdge;
153         //
154         aPB1->Range(aT11, aT12);
155         aPB2->Range(aT21, aT22);
156         //
157         anEdgeEdge.SetEdge1(aE1, aT11, aT12);
158         anEdgeEdge.SetEdge2(aE2, aT21, aT22);
159         //
160         anEdgeEdge.Perform();
161         if (!anEdgeEdge.IsDone()) {
162           continue;
163         }
164         //
165         IntTools_Range aR11(aT11, aTS11), aR12(aTS12, aT12),
166                        aR21(aT21, aTS21), aR22(aTS22, aT22);
167         //
168         const IntTools_SequenceOfCommonPrts& aCPrts = anEdgeEdge.CommonParts();
169         aNbCPrts=aCPrts.Length();
170         for (i=1; i<=aNbCPrts; ++i) {
171           const IntTools_CommonPrt& aCPart=aCPrts(i);
172           aType=aCPart.Type();
173           switch (aType) {
174             case TopAbs_VERTEX:  { 
175               Standard_Boolean bIsOnPave[4], bFlag;
176               Standard_Integer nV[4], j;
177               Standard_Real aT1, aT2, aTol;
178               TopoDS_Vertex aVnew;
179               IntTools_Range aCR1, aCR2;
180               //
181               BOPInt_Tools::VertexParameters(aCPart, aT1, aT2);
182               aTol = Precision::Confusion();
183               aCR1 = aCPart.Range1();
184               aCR2 = aCPart.Ranges2()(1);
185               // 
186               //decide to keep the pave or not
187               bIsOnPave[0] = BOPInt_Tools::IsOnPave1(aT1, aR11, aTol) ||
188                 BOPInt_Tools::IsOnPave1(aR11.First(), aCR1, aTol);
189               bIsOnPave[1] = BOPInt_Tools::IsOnPave1(aT1, aR12, aTol) || 
190                 BOPInt_Tools::IsOnPave1(aR12.Last(), aCR1, aTol);
191               bIsOnPave[2] = BOPInt_Tools::IsOnPave1(aT2, aR21, aTol) ||
192                 BOPInt_Tools::IsOnPave1(aR21.First(), aCR2, aTol);
193               bIsOnPave[3] = BOPInt_Tools::IsOnPave1(aT2, aR22, aTol) ||
194                 BOPInt_Tools::IsOnPave1(aR22.Last(), aCR2, aTol);
195               //
196               aPB1->Indices(nV[0], nV[1]);
197               aPB2->Indices(nV[2], nV[3]);
198               //
199               if((bIsOnPave[0] && bIsOnPave[2]) || (bIsOnPave[0] && bIsOnPave[3]) ||
200                  (bIsOnPave[1] && bIsOnPave[2]) || (bIsOnPave[1] && bIsOnPave[3])) {
201                 continue;
202               }
203               //
204               bFlag = Standard_False;
205               for (j = 0; j < 4; ++j) {
206                 if (bIsOnPave[j]) {
207                   //add interf VE(nV[j], nE)
208                   Handle(BOPDS_PaveBlock)& aPB = (j < 2) ? aPB2 : aPB1;
209                   ForceInterfVE(nV[j], aPB, aMPBToUpdate);
210                   bFlag = Standard_True;
211                   break;
212                 }
213               }
214               if (bFlag) {
215                 continue;
216               }
217               //
218               BOPTools_AlgoTools::MakeNewVertex(aE1, aT1, aE2, aT2, aVnew);
219               // <-LXBR
220               {
221                 Standard_Integer nVS[2], iFound, k;
222                 Standard_Real aTolVx, aTolVnew, aD2, aDT2;
223                 BOPCol_MapOfInteger aMV;
224                 gp_Pnt aPnew, aPx;
225                 //
226                 iFound=0;
227                 j=-1;
228                 aMV.Add(nV[0]);
229                 aMV.Add(nV[1]);
230                 //
231                 if (aMV.Contains(nV[2])) {
232                   ++j;
233                   nVS[j]=nV[2];
234                 }
235                 if (aMV.Contains(nV[3])) {
236                   ++j;
237                   nVS[j]=nV[3];
238                 }
239                 //
240                 aTolVnew=BRep_Tool::Tolerance(aVnew);
241                 aPnew=BRep_Tool::Pnt(aVnew);
242                 //
243                 for (k=0; k<=j; ++k) {
244                   const TopoDS_Vertex& aVx= *(TopoDS_Vertex*)&(myDS->Shape(nVS[k]));
245                   aTolVx=BRep_Tool::Tolerance(aVx);
246                   aPx=BRep_Tool::Pnt(aVx);
247                   aD2=aPnew.SquareDistance(aPx);
248                   //
249                   aDT2=100.*(aTolVnew+aTolVx)*(aTolVnew+aTolVx);
250                   //
251                   if (aD2<aDT2) {
252                     iFound=1;
253                     break;
254                   }
255                 }
256                 //
257                 if (iFound) {
258                   continue;
259                 }
260               }
261               
262               // 1
263               iX=aEEs.Append()-1;
264               BOPDS_InterfEE& aEE=aEEs(iX);
265               aEE.SetIndices(nE1, nE2);
266               aEE.SetCommonPart(aCPart);
267               // 2
268               myDS->AddInterf(nE1, nE2);
269               //
270               BOPDS_CoupleOfPaveBlocks aCPB;
271               //
272               aCPB.SetPaveBlocks(aPB1, aPB2);
273               aCPB.SetIndexInterf(iX);
274               aMVCPB.Add(aVnew, aCPB);
275             }//case TopAbs_VERTEX: 
276             break;
277             //
278             case TopAbs_EDGE: {
279               if (aNbCPrts > 1) {
280                 break;
281               }
282               //
283               Standard_Boolean bHasSameBounds;
284               bHasSameBounds=aPB1->HasSameBounds(aPB2);
285               if (!bHasSameBounds) {
286                 break;
287               }
288               // 1
289               iX=aEEs.Append()-1;
290               BOPDS_InterfEE& aEE=aEEs(iX);
291               aEE.SetIndices(nE1, nE2);
292               aEE.SetCommonPart(aCPart);
293               // 2
294               myDS->AddInterf(nE1, nE2);
295               //
296               BOPAlgo_Tools::FillMap(aPB1, aPB2, aMPBLPB, aAllocator);
297             }//case TopAbs_EDGE
298             break;
299             default:
300               break;
301           }//switch (aType) {
302         }//for (i=1; i<=aNbCPrts; i++) {
303         // -----------t
304         //
305       }// for (; aIt2.More(); aIt2.Next()) {
306     }// for (; aIt1.More(); aIt1.Next()) {
307   }
308   // 
309   //=========================================
310   // post treatment
311   //=========================================
312   aItPB.Initialize(aMPBToUpdate);
313   for (; aItPB.More(); aItPB.Next()) {
314     Handle(BOPDS_PaveBlock) aPB=aItPB.Value();
315     if (!myDS->IsCommonBlock(aPB)) {
316       myDS->UpdatePaveBlock(aPB);
317     }
318     else {
319       const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
320       myDS->UpdateCommonBlock(aCB);
321     }
322   }
323   //
324   BOPAlgo_Tools::PerformCommonBlocks(aMPBLPB, aAllocator, myDS);
325   PerformVerticesEE(aMVCPB, aAllocator);
326   //-----------------------------------------------------scope t
327   aMPBLPB.Clear();
328   aMVCPB.Clear();
329   aMPBToUpdate.Clear();
330   aAllocator.Nullify();
331 }
332 //=======================================================================
333 //function : PerformVertices
334 //purpose  : 
335 //=======================================================================
336 Standard_Integer BOPAlgo_PaveFiller::PerformVerticesEE
337   (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB,
338    Handle(NCollection_BaseAllocator)& theAllocator)
339 {
340   Standard_Integer aNbV, iRet;
341   //
342   iRet=0;
343   aNbV=theMVCPB.Extent();
344   if (!aNbV) {
345     return iRet;
346   }
347   //
348   Standard_Integer nVx, iV, j, nE, iFlag, iX, i, aNb; 
349   Standard_Real aT;
350   TopoDS_Shape aV;
351   BOPCol_ListIteratorOfListOfShape aItLS;
352   BOPCol_ListIteratorOfListOfInteger aItLI;
353   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
354   BOPDS_ShapeInfo aSI;
355   BOPDS_Pave aPave;
356   //
357   BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, theAllocator);
358   BOPCol_ListOfShape aLS(theAllocator);
359   BOPCol_IndexedDataMapOfShapeInteger aMVI(100, theAllocator);
360   BOPCol_IndexedDataMapOfShapeListOfShape aImages;
361   //
362   aSI.SetShapeType(TopAbs_VERTEX);
363   BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
364   //
365   // 1 prepare arguments
366   //
367   // <- DEB
368   for (i=1; i<=aNbV; ++i) {
369     const TopoDS_Shape& aS=theMVCPB.FindKey(i);
370     const BOPDS_CoupleOfPaveBlocks& aCPB=theMVCPB.FindFromIndex(i);
371     iV=aCPB.IndexInterf();
372     aMVI.Add(aS, iV);
373   }
374   //
375   // 2 Fuse vertices
376   TreatNewVertices(aMVI, aImages);
377   //
378   // 3 Add new vertices to myDS; 
379   //   connect indices to CPB structure
380   aNb = aImages.Extent();
381   for (i=1; i<=aNb; ++i) {
382     const TopoDS_Vertex& aV=(*(TopoDS_Vertex*)(&aImages.FindKey(i)));
383     const BOPCol_ListOfShape& aLVSD=aImages.FindFromIndex(i);
384     //
385     aSI.SetShape(aV);
386     iV=myDS->Append(aSI);
387     //
388     BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(iV);
389     Bnd_Box& aBox=aSIDS.ChangeBox();
390     BRepBndLib::Add(aV, aBox);
391     //
392     aItLS.Initialize(aLVSD);
393     for (; aItLS.More(); aItLS.Next()) {
394       const TopoDS_Shape& aVx = aItLS.Value();
395       BOPDS_CoupleOfPaveBlocks &aCPB=theMVCPB.ChangeFromKey(aVx);
396       aCPB.SetIndex(iV);
397       // update EE interference
398       iX=aCPB.IndexInterf();
399       BOPDS_InterfEE& aEE=aEEs(iX);
400       aEE.SetIndexNew(iV);
401     }
402   }
403   //
404   // 4 Map PaveBlock/ListOfVertices to add to this PaveBlock ->aMPBLI
405   {
406     Handle(BOPDS_PaveBlock) aPB[2];
407     //
408     for (i=1; i<=aNbV; ++i) {
409       const BOPDS_CoupleOfPaveBlocks& aCPB=theMVCPB.FindFromIndex(i);
410       iV=aCPB.Index();
411       aCPB.PaveBlocks(aPB[0], aPB[1]);
412       for (j=0; j<2; ++j) {
413         if (aMPBLI.Contains(aPB[j])) {
414           BOPCol_ListOfInteger& aLI=aMPBLI.ChangeFromKey(aPB[j]);
415           aLI.Append(iV);
416         }
417         else {
418           BOPCol_ListOfInteger aLI(theAllocator);
419           aLI.Append(iV);
420           aMPBLI.Add(aPB[j], aLI);
421         }
422       }
423     }
424   }
425   //
426   // 5 
427   // 5.1  Compute Extra Paves and 
428   // 5.2. Add Extra Paves to the PaveBlocks
429   aNb=aMPBLI.Extent();
430   for(i=1; i<=aNb; ++i) {
431     Handle(BOPDS_PaveBlock) aPB=aMPBLI.FindKey(i);
432     nE=aPB->OriginalEdge();
433     const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
434     // 1,2
435     const BOPCol_ListOfInteger& aLI=aMPBLI.FindFromIndex(i);
436     aItLI.Initialize(aLI);
437     for (; aItLI.More(); aItLI.Next()) {
438       nVx=aItLI.Value();
439       const TopoDS_Vertex& aVx=(*(TopoDS_Vertex *)(&myDS->Shape(nVx)));
440       //
441       iFlag=myContext->ComputeVE (aVx, aE, aT);
442       if (!iFlag) {
443         aPave.SetIndex(nVx);
444         aPave.SetParameter(aT);
445         aPB->AppendExtPave(aPave);
446       }
447     }
448   }
449   // 6  Split PaveBlocksa
450   aNb=aMPBLI.Extent();
451   for(i=1; i<=aNb; ++i) {
452     Handle(BOPDS_PaveBlock) aPB=aMPBLI.FindKey(i);
453     nE=aPB->OriginalEdge();
454     // 3
455     if (!myDS->IsCommonBlock(aPB)) {
456       myDS->UpdatePaveBlock(aPB);
457     }
458     else {
459       const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
460       myDS->UpdateCommonBlock(aCB);
461     }    
462   }//for (; aItMPBLI.More(); aItMPBLI.Next()) {
463   //
464   return iRet;
465 }
466
467 //=======================================================================
468 //function : TreatNewVertices
469 //purpose  : 
470 //=======================================================================
471 void BOPAlgo_PaveFiller::TreatNewVertices
472   (const BOPCol_IndexedDataMapOfShapeInteger& aMapVI,
473    BOPCol_IndexedDataMapOfShapeListOfShape& myImages)
474 {
475   Standard_Integer j, i, aNbV, aNbVSD;
476   Standard_Real aTol;
477   TopoDS_Shape aVF;
478   TopoDS_Vertex aVnew;
479   BOPCol_IndexedMapOfShape aMVProcessed;
480
481   BOPCol_ListIteratorOfListOfInteger aIt;
482   BOPCol_IndexedDataMapOfShapeListOfShape aMVLV;
483   BOPCol_DataMapOfIntegerShape aMIS;
484   BOPCol_IndexedDataMapOfShapeBox aMSB;
485   //
486   BOPCol_BoxBndTreeSelector aSelector;
487   BOPCol_BoxBndTree aBBTree;
488   NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
489   //
490   aNbV = aMapVI.Extent();
491   for (i=1; i<=aNbV; ++i) {
492     const TopoDS_Shape& aV=aMapVI.FindKey(i);
493     Bnd_Box aBox;
494     //
495     aTol=BRep_Tool::Tolerance(*(TopoDS_Vertex*)(&aV));
496     aBox.SetGap(aTol);
497     BRepBndLib::Add(aV, aBox);
498     //
499     aTreeFiller.Add(i, aBox);
500     //
501     aMIS.Bind(i, aV);
502     aMSB.Add(aV, aBox);
503   }
504   //
505   aTreeFiller.Fill();
506
507   // Chains
508   for (i=1; i<=aNbV; ++i) {
509     const TopoDS_Shape& aV=aMapVI.FindKey(i);
510     //
511     if (aMVProcessed.Contains(aV)) {
512       continue;
513     }
514     //
515     Standard_Integer aNbIP, aIP, aNbIP1, aIP1;
516     BOPCol_ListOfShape aLVSD;
517     BOPCol_MapOfInteger aMIP, aMIP1, aMIPC;
518     BOPCol_MapIteratorOfMapOfInteger aIt1;
519     //
520     aMIP.Add(i);
521     for(;;) {
522       aNbIP=aMIP.Extent();
523       aIt1.Initialize(aMIP);
524       for(; aIt1.More(); aIt1.Next()) {
525         aIP=aIt1.Key();
526         if (aMIPC.Contains(aIP)) {
527           continue;
528         }
529         //
530         const TopoDS_Shape& aVP=aMIS.Find(aIP);
531         const Bnd_Box& aBoxVP=aMSB.FindFromKey(aVP);
532         //
533         aSelector.Clear();
534         aSelector.SetBox(aBoxVP);
535         //
536         aNbVSD=aBBTree.Select(aSelector);
537         if (!aNbVSD) {
538           continue;  // it must not be
539         }
540         //
541         const BOPCol_ListOfInteger& aLI=aSelector.Indices();
542         aIt.Initialize(aLI);
543         for (; aIt.More(); aIt.Next()) {
544           aIP1=aIt.Value();
545           if (aMIP.Contains(aIP1)) {
546             continue;
547           }
548           aMIP1.Add(aIP1);
549         } //for (; aIt.More(); aIt.Next()) {
550       }//for(; aIt1.More(); aIt1.Next()) {
551       //
552       aNbIP1=aMIP1.Extent();
553       if (!aNbIP1) {
554         break; // from while(1)
555       }
556       //
557       aIt1.Initialize(aMIP);
558       for(; aIt1.More(); aIt1.Next()) {
559         aIP=aIt1.Key();
560         aMIPC.Add(aIP);
561       }
562       //
563       aMIP.Clear();
564       aIt1.Initialize(aMIP1);
565       for(; aIt1.More(); aIt1.Next()) {
566         aIP=aIt1.Key();
567         aMIP.Add(aIP);
568       }
569       aMIP1.Clear();
570     }// while(1)
571     //...
572     aNbIP=aMIPC.Extent();
573     if (!aNbIP) {
574       aMIPC.Add(i);
575     }
576     //
577     aIt1.Initialize(aMIPC);
578     for(j=0; aIt1.More(); aIt1.Next(), ++j) {
579       aIP=aIt1.Key();
580       const TopoDS_Shape& aVP=aMIS.Find(aIP);
581       if (!j) {
582         aVF=aVP;
583       }
584       aLVSD.Append(aVP);
585       aMVProcessed.Add(aVP);
586     }
587     aMVLV.Add(aVF, aLVSD);
588   }// for (i=1; i<=aNbV; ++i) {
589
590   // Make new vertices
591   aNbV=aMVLV.Extent();
592   for (i=1; i<=aNbV; ++i) {
593     const TopoDS_Shape& aV=aMVLV.FindKey(i);
594     BOPCol_ListOfShape& aLVSD=aMVLV.ChangeFromIndex(i);
595     aNbVSD=aLVSD.Extent();
596     if (aNbVSD>1) {
597       BOPTools_AlgoTools::MakeVertex(aLVSD, aVnew);
598       myImages.Add(aVnew, aLVSD);
599     } else {
600       myImages.Add(aV, aLVSD);
601     }
602   }
603 }
604
605 //=======================================================================
606 //function : FillShrunkData
607 //purpose  : 
608 //=======================================================================
609 void BOPAlgo_PaveFiller::FillShrunkData(Handle(BOPDS_PaveBlock)& thePB)
610 {
611   Standard_Integer nE, nV1, nV2, iErr;
612   Standard_Real aT1, aT2, aTS1, aTS2;
613   BOPInt_ShrunkRange aSR;
614   //
615   myErrorStatus=0;
616   myWarningStatus = 0;
617   //
618   const BOPDS_Pave& aPave1=thePB->Pave1();
619   nV1=aPave1.Index();
620   aT1=aPave1.Parameter();
621   const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1))); 
622   //
623   const BOPDS_Pave& aPave2=thePB->Pave2();
624   nV2=aPave2.Index();
625   aT2=aPave2.Parameter();
626   const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2))); 
627   //
628   nE=thePB->OriginalEdge();
629   const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
630   //
631   aSR.SetData(aE, aT1, aT2, aV1, aV2, myContext);
632   //
633   aSR.Perform();
634   iErr=aSR.ErrorStatus();
635   if (iErr) {
636     myWarningStatus = 1;
637     //myErrorStatus=40;
638     return;
639   }
640   //
641   aSR.ShrunkRange(aTS1, aTS2);
642   const Bnd_Box& aBox=aSR.BndBox();
643   //
644   thePB->SetShrunkData(aTS1, aTS2, aBox);
645 }
646 //=======================================================================
647 //function : ForceInterfVE
648 //purpose  : 
649 //=======================================================================
650 void BOPAlgo_PaveFiller::ForceInterfVE(const Standard_Integer nV,
651                                        Handle(BOPDS_PaveBlock)& aPB,
652                                        BOPDS_MapOfPaveBlock& aMPBToUpdate)
653 {
654   Standard_Integer aNbPnt, nE;
655   gp_Pnt aP;
656   //
657   nE = aPB->OriginalEdge();
658   //
659   const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
660   if (aSIE.HasSubShape(nV)) {
661     return;
662   }
663   //
664   if (myDS->HasInterf(nV, nE)) {
665     return;
666   }   
667   //
668   if (myDS->HasInterfShapeSubShapes(nV, nE)) {
669     return;
670   }
671   //
672   if (aPB->Pave1().Index() == nV || aPB->Pave2().Index() == nV) {
673     return;
674   }
675   //
676   const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV);
677   const TopoDS_Edge&   aE = *(TopoDS_Edge*)  &myDS->Shape(nE);
678   aP=BRep_Tool::Pnt(aV);
679   //
680   GeomAPI_ProjectPointOnCurve& aProjector=myContext->ProjPC(aE);
681   aProjector.Perform(aP);
682   //
683   aNbPnt = aProjector.NbPoints();
684   if (aNbPnt) {
685     Standard_Real aT, aDist;
686     Standard_Integer i;
687     BRep_Builder aBB;
688     BOPDS_Pave aPave;
689     //
690     aDist=aProjector.LowerDistance();
691     aT=aProjector.LowerDistanceParameter();
692     //
693     BOPDS_VectorOfInterfVE& aVEs=myDS->InterfVE();
694     if (aVEs.Extent() == 0) {
695       aVEs.Init();
696     }
697     //
698     i=aVEs.Append()-1;
699     BOPDS_InterfVE& aVE=aVEs(i);
700     aVE.SetIndices(nV, nE);
701     aVE.SetParameter(aT);
702     //
703     myDS->AddInterf(nV, nE);
704     //
705     aBB.UpdateVertex(aV, aDist);
706     BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV);
707     Bnd_Box& aBox=aSIDS.ChangeBox();
708     BRepBndLib::Add(aV, aBox);
709     //
710     aPave.SetIndex(nV);
711     aPave.SetParameter(aT);
712     aPB->AppendExtPave(aPave);
713     //
714     aMPBToUpdate.Add(aPB);
715   }
716 }
717
718  /*
719   // DEBf
720   { 
721     TopoDS_Compound aCx;
722     BRep_Builder aBBx;
723     aBBx.MakeCompound(aCx);
724     aItMVCPB.Initialize(theMVCPB);
725     for (; aItMVCPB.More(); aItMVCPB.Next()) {
726       const TopoDS_Shape& aS=aItMVCPB.Key();
727       aBBx.Add(aCx, aS);
728     }
729     BRepTools::Write(aCx, "cx");
730   }
731   // DEBt
732   */