0026738: Make Boolean operations safely treating arguments when running with fuzzy...
[occt.git] / src / BOPAlgo / BOPAlgo_PaveFiller_5.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 <Precision.hxx>
20
21 #include <Bnd_Box.hxx>
22 #include <BOPAlgo_PaveFiller.hxx>
23 #include <BOPAlgo_SectionAttribute.hxx>
24 #include <BOPAlgo_Tools.hxx>
25 #include <BOPCol_MapOfInteger.hxx>
26 #include <BOPCol_NCVector.hxx>
27 #include <BOPCol_Parallel.hxx>
28 #include <BOPCol_DataMapOfShapeReal.hxx>
29 #include <BOPDS_CommonBlock.hxx>
30 #include <BOPDS_CoupleOfPaveBlocks.hxx>
31 #include <BOPDS_Curve.hxx>
32 #include <BOPDS_DataMapOfPaveBlockListOfInteger.hxx>
33 #include <BOPDS_DS.hxx>
34 #include <BOPDS_Interf.hxx>
35 #include <BOPDS_Iterator.hxx>
36 #include <BOPDS_MapOfPaveBlock.hxx>
37 #include <BOPDS_Pave.hxx>
38 #include <BOPDS_PaveBlock.hxx>
39 #include <BOPTools_AlgoTools.hxx>
40 #include <BndLib_Add3dCurve.hxx>
41 #include <BRep_Builder.hxx>
42 #include <BRep_Tool.hxx>
43 #include <BRepAdaptor_Curve.hxx>
44 #include <BRepBndLib.hxx>
45 #include <GeomAPI_ProjectPointOnSurf.hxx>
46 #include <gp_Pnt.hxx>
47 #include <IntTools_CommonPrt.hxx>
48 #include <IntTools_Context.hxx>
49 #include <IntTools_EdgeFace.hxx>
50 #include <IntTools_Range.hxx>
51 #include <IntTools_SequenceOfCommonPrts.hxx>
52 #include <IntTools_Tools.hxx>
53 #include <TopoDS.hxx>
54 #include <TopoDS_Edge.hxx>
55 #include <TopoDS_Face.hxx>
56 #include <TopoDS_Vertex.hxx>
57
58 //=======================================================================
59 //class    : BOPAlgo_EdgeFace
60 //purpose  : 
61 //=======================================================================
62 class BOPAlgo_EdgeFace : 
63   public IntTools_EdgeFace,
64   public BOPAlgo_Algo {
65  
66  public:
67   DEFINE_STANDARD_ALLOC
68   
69   BOPAlgo_EdgeFace() : 
70     IntTools_EdgeFace(), 
71     BOPAlgo_Algo(),
72     myIE(-1), myIF(-1) {
73   };
74   //
75   virtual ~BOPAlgo_EdgeFace(){
76   };
77   //
78   void SetIndices(const Standard_Integer nE,
79                   const Standard_Integer nF) {
80     myIE=nE;
81     myIF=nF;
82   }
83   //
84   void Indices(Standard_Integer& nE,
85                Standard_Integer& nF) {
86     nE=myIE;
87     nF=myIF;
88   }
89   //
90   void SetNewSR(const IntTools_Range& aR){
91     myNewSR=aR;
92   }
93   //
94   IntTools_Range& NewSR(){
95     return myNewSR;
96   }
97   //
98   void SetPaveBlock(const Handle(BOPDS_PaveBlock)& aPB) {
99     myPB=aPB;
100   }
101   //
102   Handle(BOPDS_PaveBlock)& PaveBlock() {
103     return myPB;
104   }
105   //
106   void SetFuzzyValue(const Standard_Real theFuzz) {
107     IntTools_EdgeFace::SetFuzzyValue(theFuzz);
108   }
109   //
110   virtual void Perform() {
111     BOPAlgo_Algo::UserBreak();
112     IntTools_EdgeFace::Perform();
113   }
114   //
115  protected:
116   Standard_Integer myIE;
117   Standard_Integer myIF;
118   IntTools_Range myNewSR;
119   Handle(BOPDS_PaveBlock) myPB;
120 };
121 //
122 //=======================================================================
123 typedef BOPCol_NCVector<BOPAlgo_EdgeFace> BOPAlgo_VectorOfEdgeFace; 
124 //
125 typedef BOPCol_ContextFunctor 
126   <BOPAlgo_EdgeFace,
127   BOPAlgo_VectorOfEdgeFace,
128   Handle(IntTools_Context), 
129   IntTools_Context> BOPAlgo_EdgeFaceFunctor;
130 //
131 typedef BOPCol_ContextCnt 
132   <BOPAlgo_EdgeFaceFunctor,
133   BOPAlgo_VectorOfEdgeFace,
134   Handle(IntTools_Context)> BOPAlgo_EdgeFaceCnt;
135 //
136 //=======================================================================
137 //function : PerformEF
138 //purpose  : 
139 //=======================================================================
140 void BOPAlgo_PaveFiller::PerformEF()
141 {
142   Standard_Integer iSize;
143   //
144   myErrorStatus=0;
145   //
146   FillShrunkData(TopAbs_EDGE, TopAbs_FACE);
147   //
148   myIterator->Initialize(TopAbs_EDGE, TopAbs_FACE);
149   iSize=myIterator->ExpectedLength();
150   if (!iSize) {
151     return; 
152   }
153   //
154   Standard_Boolean bJustAdd, bV[2], bIsPBSplittable;
155   Standard_Boolean bV1, bV2, bExpressCompute;
156   Standard_Integer nV1, nV2;
157   Standard_Integer nE, nF, aDiscretize, i, aNbCPrts, iX, nV[2];
158   Standard_Integer aNbEdgeFace, k;
159   Standard_Real aTolE, aTolF, aTS1, aTS2, aT1, aT2, aDeflection;
160   Handle(NCollection_BaseAllocator) aAllocator;
161   TopAbs_ShapeEnum aType;
162   BOPDS_ListIteratorOfListOfPaveBlock aIt;
163   BOPAlgo_VectorOfEdgeFace aVEdgeFace; 
164   //-----------------------------------------------------scope f
165   //
166   aAllocator=NCollection_BaseAllocator::CommonBaseAllocator();
167   //
168   BOPCol_MapOfInteger aMIEFC(100, aAllocator);
169   BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMVCPB(100, aAllocator);
170   BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, aAllocator);
171   BOPAlgo_DataMapOfPaveBlockBndBox aDMPBBox(100, aAllocator);
172   //
173   aDiscretize=35;
174   aDeflection=0.01;
175   //
176   BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
177   aEFs.SetIncrement(iSize);
178   //
179   for (; myIterator->More(); myIterator->Next()) {
180     myIterator->Value(nE, nF, bJustAdd);
181     if(bJustAdd) {
182       continue;
183     }
184     //
185     const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
186     if (aSIE.HasFlag()){//degenerated 
187       continue;
188     }
189     //
190     const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aSIE.Shape()));
191     const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF)));
192     const Bnd_Box& aBBF=myDS->ShapeInfo(nF).Box(); 
193     //
194     BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
195     const BOPDS_IndexedMapOfPaveBlock& aMPBF=aFI.PaveBlocksOn();
196     //
197     const BOPCol_MapOfInteger& aMVIn=aFI.VerticesIn();
198     const BOPCol_MapOfInteger& aMVOn=aFI.VerticesOn();
199     //
200     aTolE=BRep_Tool::Tolerance(aE);
201     aTolF=BRep_Tool::Tolerance(aF);
202     //
203     BOPDS_ListOfPaveBlock& aLPB=myDS->ChangePaveBlocks(nE);
204     aIt.Initialize(aLPB);
205     for (; aIt.More(); aIt.Next()) {
206       Handle(BOPDS_PaveBlock)& aPB=aIt.ChangeValue();
207       //
208       const Handle(BOPDS_PaveBlock) aPBR=myDS->RealPaveBlock(aPB);
209       if (aMPBF.Contains(aPBR)) {
210         continue;
211       }
212       //
213       Bnd_Box aBBE;
214       if (!GetPBBox(aE, aPB, aDMPBBox, aT1, aT2, aTS1, aTS2, aBBE)) {
215         continue;
216       }
217       //
218       if (aBBF.IsOut (aBBE)) {
219         continue;
220       }
221       //
222       aPBR->Indices(nV1, nV2);
223       bV1=aMVIn.Contains(nV1) || aMVOn.Contains(nV1);
224       bV2=aMVIn.Contains(nV2) || aMVOn.Contains(nV2);
225       bExpressCompute=bV1 && bV2;
226       //
227       BOPAlgo_EdgeFace& aEdgeFace=aVEdgeFace.Append1();
228       //
229       aEdgeFace.SetIndices(nE, nF);
230       aEdgeFace.SetPaveBlock(aPB);
231       //
232       aEdgeFace.SetEdge (aE);
233       aEdgeFace.SetFace (aF);
234       aEdgeFace.SetFuzzyValue(myFuzzyValue);
235       aEdgeFace.SetDiscretize (aDiscretize);
236       aEdgeFace.SetDeflection (aDeflection);
237       aEdgeFace.UseQuickCoincidenceCheck(bExpressCompute);
238       //
239       IntTools_Range aSR(aTS1, aTS2);
240       IntTools_Range anewSR=aSR;
241       BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, anewSR);
242       aEdgeFace.SetNewSR(anewSR);
243       //
244       IntTools_Range aPBRange(aT1, aT2);
245       aSR = aPBRange;
246       BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, aPBRange);
247       aEdgeFace.SetRange (aPBRange);
248       aEdgeFace.SetProgressIndicator(myProgressIndicator);
249       //
250     }//for (; aIt.More(); aIt.Next()) {
251   }//for (; myIterator->More(); myIterator->Next()) {
252   //
253   aNbEdgeFace=aVEdgeFace.Extent();
254   //=================================================================
255   BOPAlgo_EdgeFaceCnt::Perform(myRunParallel, aVEdgeFace, myContext);
256   //=================================================================
257   //
258   for (k=0; k < aNbEdgeFace; ++k) {
259     BOPAlgo_EdgeFace& aEdgeFace=aVEdgeFace(k);
260     if (!aEdgeFace.IsDone()) {
261       continue;
262     }
263     //~~~
264     aEdgeFace.Indices(nE, nF);
265     //
266     const TopoDS_Edge& aE=aEdgeFace.Edge();
267     const TopoDS_Face& aF=aEdgeFace.Face();
268     //
269     aTolE=BRep_Tool::Tolerance(aE);
270     aTolF=BRep_Tool::Tolerance(aF);
271     const IntTools_Range& anewSR=aEdgeFace.NewSR();
272     Handle(BOPDS_PaveBlock)& aPB=aEdgeFace.PaveBlock();
273     //
274     aPB->Range(aT1, aT2);
275     aPB->Indices(nV[0], nV[1]);
276     bIsPBSplittable = aPB->IsSplittable();
277     //
278     anewSR.Range(aTS1, aTS2);
279     //
280     // extend vertices ranges using Edge/Edge intersections
281     // between the edge aE and the edges of the face aF.
282     // thereby the edge's intersection range is reduced
283     ReduceIntersectionRange(nV[0], nV[1], nE, nF, aTS1, aTS2);
284     //
285     IntTools_Range aR1(aT1, aTS1), aR2(aTS2, aT2);
286     //
287     BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
288     const BOPCol_MapOfInteger& aMIFOn=aFI.VerticesOn();
289     const BOPCol_MapOfInteger& aMIFIn=aFI.VerticesIn();
290     //~~~
291     const IntTools_SequenceOfCommonPrts& aCPrts=aEdgeFace.CommonParts();
292     aNbCPrts = aCPrts.Length();
293     //
294     Standard_Boolean bLinePlane = Standard_False;
295     if (aNbCPrts) {
296       BRepAdaptor_Curve aBAC(aE);
297       BRepAdaptor_Surface aBAS(aF, Standard_False);
298       //
299       bLinePlane = (aBAC.GetType() == GeomAbs_Line &&
300                     aBAS.GetType() == GeomAbs_Plane);
301     }
302
303     for (i=1; i<=aNbCPrts; ++i) {
304       const IntTools_CommonPrt& aCPart=aCPrts(i);
305       aType=aCPart.Type();
306       switch (aType) {
307         case TopAbs_VERTEX: {
308           Standard_Boolean bIsOnPave[2];
309           Standard_Integer j;
310           Standard_Real aT, aTolToDecide; 
311           TopoDS_Vertex aVnew;
312           //
313           IntTools_Tools::VertexParameter(aCPart, aT);
314           BOPTools_AlgoTools::MakeNewVertex(aE, aT, aF, aVnew);
315           //
316           const IntTools_Range& aR=aCPart.Range1();
317           aTolToDecide=5.e-8;
318           //
319           bIsOnPave[0]=IntTools_Tools::IsInRange(aR1, aR, aTolToDecide); 
320           bIsOnPave[1]=IntTools_Tools::IsInRange(aR2, aR, aTolToDecide); 
321           //
322           if ((bIsOnPave[0] && bIsOnPave[1]) || 
323               (bLinePlane && (bIsOnPave[0] || bIsOnPave[1]))) {
324             bV[0]=CheckFacePaves(nV[0], aMIFOn, aMIFIn);
325             bV[1]=CheckFacePaves(nV[1], aMIFOn, aMIFIn);
326             if (bV[0] && bV[1]) {
327               IntTools_CommonPrt aCP = aCPart;
328               aCP.SetType(TopAbs_EDGE);
329               BOPDS_InterfEF& aEF=aEFs.Append1();
330               iX=aEFs.Extent()-1;
331               aEF.SetIndices(nE, nF);
332               aEF.SetCommonPart(aCP);
333               myDS->AddInterf(nE, nF);
334               //
335               aMIEFC.Add(nF);
336               //           
337               BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, aAllocator);
338               break;
339             }
340           }
341           //
342           if (!bIsPBSplittable) {
343             continue;
344           }
345           //
346           for (j=0; j<2; ++j) {
347             if (bIsOnPave[j]) {
348               bV[j]=CheckFacePaves(nV[j], aMIFOn, aMIFIn);
349               if (bV[j]) {
350                 const TopoDS_Vertex& aV=
351                   (*(TopoDS_Vertex *)(&myDS->Shape(nV[j])));
352                 //
353                 Standard_Real f, l, aTolVnew, aDistPP, aTolPC, aTolV;
354                 //
355                 const Handle(Geom_Curve)& aCur = BRep_Tool::Curve(aE, f, l);
356                 //
357                 gp_Pnt aP1 = BRep_Tool::Pnt(aV);
358                 gp_Pnt aP2 = aCur->Value(aT);
359                 //
360                 aDistPP=aP1.Distance(aP2);
361                 //
362                 aTolPC=Precision::PConfusion();
363                 aTolV=BRep_Tool::Tolerance(aV);
364                 if (aDistPP > (aTolV+aTolPC)) {
365                   aTolVnew=Max(aTolE, aDistPP);
366                   UpdateVertex(nV[j], aTolVnew);
367                 }
368               }
369               else {
370                 bIsOnPave[j] = ForceInterfVF(nV[j], nF);
371               }
372             }
373           }
374           //
375           if (!bIsOnPave[0] && !bIsOnPave[1]) {
376             if (CheckFacePaves(aVnew, aMIFOn)) {
377               continue;
378             }
379             //
380             Standard_Real aTolVnew = BRep_Tool::Tolerance(aVnew);
381             aTolVnew = Max(aTolVnew, Max(aTolE, aTolF));
382             BRep_Builder().UpdateVertex(aVnew, aTolVnew);
383             if (bLinePlane) {
384               // increase tolerance for Line/Plane intersection, but do not update 
385               // the vertex till its intersection with some other shape
386               IntTools_Range aCR = aCPart.Range1();
387               aTolVnew = Max(aTolVnew, (aCR.Last() - aCR.First()) / 2.);
388             }
389             //
390             const gp_Pnt& aPnew = BRep_Tool::Pnt(aVnew);
391             //
392             if (!myContext->IsPointInFace(aPnew, aF, aTolVnew)) {
393               continue;
394             }
395             //
396             aMIEFC.Add(nF);
397             // 1
398             BOPDS_InterfEF& aEF=aEFs.Append1();
399             iX=aEFs.Extent()-1;
400             aEF.SetIndices(nE, nF);
401             aEF.SetCommonPart(aCPart);
402             // 2
403             myDS->AddInterf(nE, nF);
404             // 3
405             BOPDS_CoupleOfPaveBlocks aCPB;
406             //
407             aCPB.SetPaveBlocks(aPB, aPB);
408             aCPB.SetIndexInterf(iX);
409             aCPB.SetTolerance(aTolVnew);
410             aMVCPB.Add(aVnew, aCPB);
411           }
412         }
413           break;
414         case TopAbs_EDGE:  {
415           aMIEFC.Add(nF);
416           //
417           // 1
418           BOPDS_InterfEF& aEF=aEFs.Append1();
419           iX=aEFs.Extent()-1;
420           aEF.SetIndices(nE, nF);
421           //
422           bV[0]=CheckFacePaves(nV[0], aMIFOn, aMIFIn);
423           bV[1]=CheckFacePaves(nV[1], aMIFOn, aMIFIn);
424           if (!bV[0] || !bV[1]) {
425             myDS->AddInterf(nE, nF);
426             break;
427           }
428           aEF.SetCommonPart(aCPart);
429           // 2
430           myDS->AddInterf(nE, nF);
431           // 3
432           BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, aAllocator);
433           
434         }
435           break; 
436         default:
437           break; 
438       }//switch (aType) {
439     }//for (i=1; i<=aNbCPrts; ++i) {
440   }// for (k=0; k < aNbEdgeEdge; ++k) {
441   // 
442   //=========================================
443   // post treatment
444   //=========================================
445   BOPAlgo_Tools::PerformCommonBlocks(aMPBLI, aAllocator, myDS);
446   PerformVerticesEF(aMVCPB, aAllocator);
447   //
448   // Update FaceInfoIn for all faces having EF common parts
449   BOPCol_MapIteratorOfMapOfInteger aItMI;
450   aItMI.Initialize(aMIEFC);
451   for (; aItMI.More(); aItMI.Next()) {
452     nF=aItMI.Value();
453     myDS->UpdateFaceInfoIn(nF);
454   }
455   // Refine FaceInfoOn to remove all formal pave blocks 
456   // made during EF processing 
457   //myDS->RefineFaceInfoOn();
458   //-----------------------------------------------------scope t
459   aMIEFC.Clear();
460   aMVCPB.Clear();
461   aMPBLI.Clear();
462   ////aAllocator.Nullify();
463 }
464 //=======================================================================
465 //function : PerformVerticesEF
466 //purpose  : 
467 //=======================================================================
468 Standard_Integer BOPAlgo_PaveFiller::PerformVerticesEF
469   (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB,
470    const Handle(NCollection_BaseAllocator)& theAllocator)
471 {
472   Standard_Integer aNbV, iRet;
473   //
474   iRet=0;
475   aNbV=theMVCPB.Extent();
476   if (!aNbV) {
477     return iRet;
478   }
479   //
480   Standard_Integer nVx, nVSD, iV, iErr, nE, iFlag, iX, i, aNbPBLI;
481   Standard_Real aT, dummy;
482   BOPCol_ListIteratorOfListOfShape aItLS;
483   BOPCol_ListIteratorOfListOfInteger aItLI;
484   BOPDS_PDS aPDS;
485   BOPDS_ShapeInfo aSI;
486   BOPDS_Pave aPave;
487   //
488   BOPCol_ListOfShape aLS(theAllocator);
489   BOPCol_DataMapOfShapeInteger aMVI(100, theAllocator);
490   BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, theAllocator);
491   BOPAlgo_PaveFiller aPF(theAllocator); 
492   BOPCol_DataMapOfShapeReal aMVIniTol;
493   //
494   aSI.SetShapeType(TopAbs_VERTEX);
495   BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
496   //
497   // 1 prepare arguments
498   for (i=1; i<=aNbV; ++i) {
499     const TopoDS_Vertex& aV = TopoDS::Vertex(theMVCPB.FindKey(i));
500     aLS.Append(aV);
501     // if an enlarged tolerance is associated with the vertex then update it 
502     // remembering its initial tolerance
503     Standard_Real aTolEnlarged = theMVCPB.FindFromIndex(i).Tolerance();
504     Standard_Real aIniTol = BRep_Tool::Tolerance(aV);
505     if (aTolEnlarged > aIniTol) {
506       aMVIniTol.Bind(aV, aIniTol);
507       BRep_Builder().UpdateVertex(aV, aTolEnlarged);
508     }
509   }
510   //
511   // 2 Fuse vertices
512   aPF.SetIsPrimary(Standard_False);
513   aPF.SetNonDestructive(myNonDestructive);
514   aPF.SetArguments(aLS);
515   aPF.Perform();
516   iErr=aPF.ErrorStatus();
517   if (iErr) {
518     iRet=1;
519     return iRet;
520   }
521   aPDS=aPF.PDS();
522   //
523   // Recompute common vertex for each SD group containing enlarged vertex;
524   // for that first fill in the map of SD vertex -> its counterparts
525   BOPCol_IndexedDataMapOfShapeListOfShape aImages;
526   aItLS.Initialize(aLS);
527   for (; aItLS.More(); aItLS.Next()) {
528     const TopoDS_Shape& aVx = aItLS.Value();
529     nVx = aPDS->Index(aVx);
530     //
531     const TopoDS_Shape& aV = (aPDS->HasShapeSD(nVx, nVSD) ? aPDS->Shape(nVSD) : aVx);
532     BOPCol_ListOfShape* pLst = aImages.ChangeSeek(aV);
533     if (!pLst) {
534       pLst = &aImages.ChangeFromIndex(aImages.Add(aV, BOPCol_ListOfShape()));
535     }
536     pLst->Append(aVx);
537   }
538   // 3 Add new vertices to theDS; 
539   for (i = 1; i <= aImages.Extent(); i++) {
540     TopoDS_Vertex aV = TopoDS::Vertex(aImages.FindKey(i));
541     const BOPCol_ListOfShape& aLVSD = aImages.FindFromIndex(i);
542     Standard_Boolean isReset = Standard_False;
543     BOPCol_ListIteratorOfListOfShape it(aLVSD);
544     for (; it.More(); it.Next()) {
545       const TopoDS_Vertex& aVx = TopoDS::Vertex(it.Value());
546       const Standard_Real* pTolIni = aMVIniTol.Seek(aVx);
547       if (pTolIni) {
548         // reset enlarged vertex tolerance to the initial value
549         reinterpret_cast<BRep_TVertex*>(aVx.TShape().operator->())->Tolerance(*pTolIni);
550         isReset = Standard_True;
551       }
552     }
553     TopoDS_Vertex aVnew = aV;
554     if (isReset && aLVSD.Extent() > 1) {
555       // make new vertex again
556       BOPTools_AlgoTools::MakeVertex(aLVSD, aVnew);
557     }
558     // index of new vertex in theDS -> iV
559     aSI.SetShape(aVnew);
560     iV = myDS->Append(aSI);
561     //
562     BOPDS_ShapeInfo& aSIDS = myDS->ChangeShapeInfo(iV);
563     Bnd_Box& aBox = aSIDS.ChangeBox();
564     BRepBndLib::Add(aVnew, aBox);
565     aBox.SetGap(aBox.GetGap() + Precision::Confusion());
566     //
567     aMVI.Bind(aV, iV);
568   }
569   //
570   // 4 Map PaveBlock/ListOfVertices to add to this PaveBlock ->aMPBLI
571   aItLS.Initialize(aLS);
572   for (; aItLS.More(); aItLS.Next()) {
573     const TopoDS_Shape& aVx=aItLS.Value();
574     nVx=aPDS->Index(aVx);
575     //
576     const TopoDS_Shape& aV = (aPDS->HasShapeSD(nVx, nVSD) ? aPDS->Shape(nVSD) : aVx);
577     iV = aMVI.Find(aV);
578     //
579     BOPDS_CoupleOfPaveBlocks &aCPB=theMVCPB.ChangeFromKey(aVx);
580     aCPB.SetIndex(iV);
581     // update EF interference
582     iX=aCPB.IndexInterf();
583     BOPDS_InterfEF& aEF=aEFs(iX);
584     aEF.SetIndexNew(iV);
585     // map aMPBLI
586     const Handle(BOPDS_PaveBlock)& aPB=aCPB.PaveBlock1();
587     if (aMPBLI.Contains(aPB)) {
588       BOPCol_ListOfInteger& aLI=aMPBLI.ChangeFromKey(aPB);
589       aLI.Append(iV);
590     }
591     else {
592       BOPCol_ListOfInteger aLI(theAllocator);
593       aLI.Append(iV);
594       aMPBLI.Add(aPB, aLI);
595     }
596   }
597   //
598   // 5 
599   // 5.1  Compute Extra Paves and 
600   // 5.2. Add Extra Paves to the PaveBlocks
601   aNbPBLI=aMPBLI.Extent();
602   for (i=1; i<=aNbPBLI; ++i) {
603     Handle(BOPDS_PaveBlock) aPB=aMPBLI.FindKey(i);
604     const BOPCol_ListOfInteger& aLI=aMPBLI.FindFromIndex(i);
605     nE=aPB->OriginalEdge();
606     const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
607     // 
608     aItLI.Initialize(aLI);
609     for (; aItLI.More(); aItLI.Next()) {
610       nVx=aItLI.Value();
611       const TopoDS_Vertex& aVx=(*(TopoDS_Vertex *)(&myDS->Shape(nVx)));
612       //
613       iFlag=myContext->ComputeVE (aVx, aE, aT, dummy, myFuzzyValue);
614       if (!iFlag) {
615         aPave.SetIndex(nVx);
616         aPave.SetParameter(aT);
617         aPB->AppendExtPave(aPave);
618       }
619     }
620   }
621   // 6  Split PaveBlocks
622   for (i=1; i<=aNbPBLI; ++i) {
623     Handle(BOPDS_PaveBlock) aPB=aMPBLI.FindKey(i);
624     nE=aPB->OriginalEdge();
625     // 3
626     if (!myDS->IsCommonBlock(aPB)) {
627       myDS->UpdatePaveBlock(aPB);
628     }
629     else {
630       const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
631       myDS->UpdateCommonBlock(aCB, myFuzzyValue);
632     }    
633   }//for (; aItMPBLI.More(); aItMPBLI.Next()) {
634   // 
635   return iRet;
636 }
637 //=======================================================================
638 // function: CheckFacePaves
639 // purpose: 
640 //=======================================================================
641 Standard_Boolean BOPAlgo_PaveFiller::CheckFacePaves 
642   (const Standard_Integer nVx,
643    const BOPCol_MapOfInteger& aMIFOn,
644    const BOPCol_MapOfInteger& aMIFIn)
645 {
646   Standard_Boolean bRet;
647   Standard_Integer nV;
648   BOPCol_MapIteratorOfMapOfInteger aIt;
649   //
650   bRet=Standard_False;
651   //
652   aIt.Initialize(aMIFOn);
653   for (; aIt.More(); aIt.Next()) {
654     nV=aIt.Value();
655     if (nV==nVx) {
656       bRet=!bRet;
657       return bRet;
658     }
659   }
660   aIt.Initialize(aMIFIn);
661   for (; aIt.More(); aIt.Next()) {
662     nV=aIt.Value();
663     if (nV==nVx) {
664       bRet=!bRet;
665       return bRet;
666     }
667   }
668   //
669   return bRet;
670 }
671 //=======================================================================
672 // function: CheckFacePaves
673 // purpose: 
674 //=======================================================================
675 Standard_Boolean BOPAlgo_PaveFiller::CheckFacePaves 
676   (const TopoDS_Vertex& aVnew,
677    const BOPCol_MapOfInteger& aMIF)
678 {
679   Standard_Boolean bRet;
680   Standard_Integer nV, iFlag;
681   BOPCol_MapIteratorOfMapOfInteger aIt;
682   //
683   bRet=Standard_True;
684   //
685   aIt.Initialize(aMIF);
686   for (; aIt.More(); aIt.Next()) {
687     nV=aIt.Value();
688     const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&myDS->Shape(nV)));
689     iFlag=BOPTools_AlgoTools::ComputeVV(aVnew, aV);
690     if (!iFlag) {
691       return bRet;
692     }
693   }
694   //
695   return !bRet;
696 }
697 //=======================================================================
698 //function : ForceInterfVF
699 //purpose  : 
700 //=======================================================================
701 Standard_Boolean BOPAlgo_PaveFiller::ForceInterfVF
702   (const Standard_Integer nV, 
703    const Standard_Integer nF)
704 {
705   Standard_Boolean bRet;
706   Standard_Integer iFlag, nVx;
707   Standard_Real U, V, aTolVNew;
708   //
709   bRet = Standard_False;
710   const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV);
711   const TopoDS_Face&   aF = *(TopoDS_Face*)  &myDS->Shape(nF);
712   //
713   iFlag = myContext->ComputeVF(aV, aF, U, V, aTolVNew, myFuzzyValue);
714   if (iFlag == 0 || iFlag == -2) {
715     bRet=!bRet;
716   //
717     BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF();
718     aVFs.SetIncrement(10);
719     // 1
720     BOPDS_InterfVF& aVF=aVFs.Append1();
721     //
722     aVF.SetIndices(nV, nF);
723     aVF.SetUV(U, V);
724     // 2
725     myDS->AddInterf(nV, nF);
726     //
727     // 3 update vertex V/F if necessary
728     nVx=UpdateVertex(nV, aTolVNew);
729     // 4
730     if (myDS->IsNewShape(nVx)) {
731       aVF.SetIndexNew(nVx);
732     }
733     //
734     BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
735     BOPCol_MapOfInteger& aMVIn=aFI.ChangeVerticesIn();
736     aMVIn.Add(nVx);
737   }
738   return bRet;
739 }
740 //=======================================================================
741 //function : ReduceIntersectionRange
742 //purpose  : 
743 //=======================================================================
744 void BOPAlgo_PaveFiller::ReduceIntersectionRange(const Standard_Integer theV1,
745                                                  const Standard_Integer theV2,
746                                                  const Standard_Integer theE,
747                                                  const Standard_Integer theF,
748                                                  Standard_Real& theTS1,
749                                                  Standard_Real& theTS2)
750 {
751   if (!myDS->IsNewShape(theV1) &&
752       !myDS->IsNewShape(theV2)) {
753     return;
754   }
755   //
756   BOPDS_VectorOfInterfEE& aEEs = myDS->InterfEE();
757   Standard_Integer aNbEEs = aEEs.Extent();
758   if (!aNbEEs) {
759     return;
760   }
761   //
762   Standard_Integer i, nV, nE1, nE2;
763   Standard_Real aTR1, aTR2;
764   //
765   // get face's edges to check that E/E contains the edge from the face
766   BOPCol_MapOfInteger aMFE;
767   const BOPCol_ListOfInteger& aLI = myDS->ShapeInfo(theF).SubShapes();
768   BOPCol_ListIteratorOfListOfInteger aItLI(aLI);
769   for (; aItLI.More(); aItLI.Next()) {
770     nE1 = aItLI.Value();
771     if (myDS->ShapeInfo(nE1).ShapeType() == TopAbs_EDGE) {
772       aMFE.Add(nE1);
773     }
774   }
775   //
776   for (i = 0; i < aNbEEs; ++i) {
777     BOPDS_InterfEE& aEE = aEEs(i);
778     if (!aEE.HasIndexNew()) {
779       continue;
780     }
781     //
782     // check the vertex
783     nV = aEE.IndexNew();
784     if (nV != theV1 && nV != theV2) {
785       continue;
786     }
787     //
788     // check that the intersection is between the edge
789     // and one of the face's edge
790     aEE.Indices(nE1, nE2);
791     if (((theE != nE1) && (theE != nE2)) ||
792         (!aMFE.Contains(nE1) && !aMFE.Contains(nE2))) {
793       continue;
794     }
795     //
796     // update the intersection range
797     const IntTools_CommonPrt& aCPart = aEE.CommonPart();
798     const IntTools_Range& aCRange = 
799       (theE == nE1) ? aCPart.Range1() : aCPart.Ranges2().First();
800     aCRange.Range(aTR1, aTR2);
801     //
802     if (nV == theV1) {
803       if (theTS1 < aTR2) {
804         theTS1 = aTR2;
805       }
806     }
807     else {
808       if (theTS2 > aTR1) {
809         theTS2 = aTR1;
810       }
811     }
812   }
813 }