0028599: Replacement of old Boolean operations with new ones in BRepProj_Projection...
[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 <Bnd_Box.hxx>
20 #include <BOPAlgo_PaveFiller.hxx>
21 #include <BOPAlgo_Alerts.hxx>
22 #include <BOPAlgo_Tools.hxx>
23 #include <BOPDS_CommonBlock.hxx>
24 #include <BOPDS_CoupleOfPaveBlocks.hxx>
25 #include <BOPDS_Curve.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 <BOPTools_AlgoTools.hxx>
33 #include <BOPTools_Parallel.hxx>
34 #include <BRep_Builder.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_EdgeFace.hxx>
41 #include <IntTools_Range.hxx>
42 #include <IntTools_SequenceOfCommonPrts.hxx>
43 #include <IntTools_Tools.hxx>
44 #include <NCollection_Vector.hxx>
45 #include <Precision.hxx>
46 #include <TColStd_MapOfInteger.hxx>
47 #include <TopoDS.hxx>
48 #include <TopoDS_Edge.hxx>
49 #include <TopoDS_Face.hxx>
50 #include <TopoDS_Vertex.hxx>
51
52 //=======================================================================
53 //class    : BOPAlgo_EdgeFace
54 //purpose  : 
55 //=======================================================================
56 class BOPAlgo_EdgeFace : 
57   public IntTools_EdgeFace,
58   public BOPAlgo_Algo {
59  
60  public:
61   DEFINE_STANDARD_ALLOC
62   
63   BOPAlgo_EdgeFace() : 
64     IntTools_EdgeFace(), 
65     BOPAlgo_Algo(),
66     myIE(-1), myIF(-1) {
67   };
68   //
69   virtual ~BOPAlgo_EdgeFace(){
70   };
71   //
72   void SetIndices(const Standard_Integer nE,
73                   const Standard_Integer nF) {
74     myIE=nE;
75     myIF=nF;
76   }
77   //
78   void Indices(Standard_Integer& nE,
79                Standard_Integer& nF) {
80     nE=myIE;
81     nF=myIF;
82   }
83   //
84   void SetNewSR(const IntTools_Range& aR){
85     myNewSR=aR;
86   }
87   //
88   IntTools_Range& NewSR(){
89     return myNewSR;
90   }
91   //
92   void SetPaveBlock(const Handle(BOPDS_PaveBlock)& aPB) {
93     myPB=aPB;
94   }
95   //
96   Handle(BOPDS_PaveBlock)& PaveBlock() {
97     return myPB;
98   }
99   //
100   void SetFuzzyValue(const Standard_Real theFuzz) {
101     IntTools_EdgeFace::SetFuzzyValue(theFuzz);
102   }
103   //
104   virtual void Perform() {
105     BOPAlgo_Algo::UserBreak();
106     try
107     {
108       OCC_CATCH_SIGNALS
109
110       IntTools_EdgeFace::Perform();
111     }
112     catch (Standard_Failure)
113     {
114       AddError(new BOPAlgo_AlertIntersectionFailed);
115     }
116   }
117   //
118  protected:
119   Standard_Integer myIE;
120   Standard_Integer myIF;
121   IntTools_Range myNewSR;
122   Handle(BOPDS_PaveBlock) myPB;
123 };
124 //
125 //=======================================================================
126 typedef NCollection_Vector<BOPAlgo_EdgeFace> BOPAlgo_VectorOfEdgeFace; 
127 //
128 typedef BOPTools_ContextFunctor 
129   <BOPAlgo_EdgeFace,
130   BOPAlgo_VectorOfEdgeFace,
131   Handle(IntTools_Context), 
132   IntTools_Context> BOPAlgo_EdgeFaceFunctor;
133 //
134 typedef BOPTools_ContextCnt 
135   <BOPAlgo_EdgeFaceFunctor,
136   BOPAlgo_VectorOfEdgeFace,
137   Handle(IntTools_Context)> BOPAlgo_EdgeFaceCnt;
138 //
139 //=======================================================================
140 //function : PerformEF
141 //purpose  : 
142 //=======================================================================
143 void BOPAlgo_PaveFiller::PerformEF()
144 {
145   FillShrunkData(TopAbs_EDGE, TopAbs_FACE);
146   //
147   myIterator->Initialize(TopAbs_EDGE, TopAbs_FACE);
148   Standard_Integer iSize = myIterator->ExpectedLength();
149   if (!iSize) {
150     return; 
151   }
152   //
153   Standard_Integer nE, nF;
154   //
155   if (myGlue == BOPAlgo_GlueFull) {
156     // there is no need to intersect edges with faces in this mode
157     // just initialize FaceInfo for faces
158     for (; myIterator->More(); myIterator->Next()) {
159       myIterator->Value(nE, nF);
160       if (!myDS->ShapeInfo(nE).HasFlag()) {
161         myDS->ChangeFaceInfo(nF);
162       }
163     }
164     return;
165   }
166   //
167   Standard_Boolean bV[2], bIsPBSplittable;
168   Standard_Boolean bV1, bV2, bExpressCompute;
169   Standard_Integer nV1, nV2;
170   Standard_Integer i, aNbCPrts, iX, nV[2];
171   Standard_Integer aNbEdgeFace, k;
172   Standard_Real aTolE, aTolF, aTS1, aTS2, aT1, aT2;
173   Handle(NCollection_BaseAllocator) aAllocator;
174   TopAbs_ShapeEnum aType;
175   BOPDS_ListIteratorOfListOfPaveBlock aIt;
176   BOPAlgo_VectorOfEdgeFace aVEdgeFace; 
177   //-----------------------------------------------------scope f
178   //
179   aAllocator=NCollection_BaseAllocator::CommonBaseAllocator();
180   //
181   TColStd_MapOfInteger aMIEFC(100, aAllocator);
182   BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMVCPB(100, aAllocator);
183   BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, aAllocator);
184   BOPAlgo_DataMapOfPaveBlockBndBox aDMPBBox(100, aAllocator);
185   //
186   BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
187   aEFs.SetIncrement(iSize);
188   //
189   for (; myIterator->More(); myIterator->Next()) {
190     myIterator->Value(nE, nF);
191     //
192     const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
193     if (aSIE.HasFlag()){//degenerated 
194       continue;
195     }
196     //
197     const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aSIE.Shape()));
198     const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF)));
199     const Bnd_Box& aBBF=myDS->ShapeInfo(nF).Box(); 
200     //
201     BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
202     const BOPDS_IndexedMapOfPaveBlock& aMPBF=aFI.PaveBlocksOn();
203     //
204     const TColStd_MapOfInteger& aMVIn=aFI.VerticesIn();
205     const TColStd_MapOfInteger& aMVOn=aFI.VerticesOn();
206     //
207     aTolE=BRep_Tool::Tolerance(aE);
208     aTolF=BRep_Tool::Tolerance(aF);
209     //
210     BOPDS_ListOfPaveBlock& aLPB=myDS->ChangePaveBlocks(nE);
211     aIt.Initialize(aLPB);
212     for (; aIt.More(); aIt.Next()) {
213       Handle(BOPDS_PaveBlock)& aPB=aIt.ChangeValue();
214       //
215       const Handle(BOPDS_PaveBlock) aPBR=myDS->RealPaveBlock(aPB);
216       if (aMPBF.Contains(aPBR)) {
217         continue;
218       }
219       //
220       Bnd_Box aBBE;
221       if (!GetPBBox(aE, aPB, aDMPBBox, aT1, aT2, aTS1, aTS2, aBBE)) {
222         continue;
223       }
224       //
225       if (aBBF.IsOut (aBBE)) {
226         continue;
227       }
228       //
229       aPBR->Indices(nV1, nV2);
230       bV1=aMVIn.Contains(nV1) || aMVOn.Contains(nV1);
231       bV2=aMVIn.Contains(nV2) || aMVOn.Contains(nV2);
232       bExpressCompute=bV1 && bV2;
233       //
234       BOPAlgo_EdgeFace& aEdgeFace=aVEdgeFace.Appended();
235       //
236       aEdgeFace.SetIndices(nE, nF);
237       aEdgeFace.SetPaveBlock(aPB);
238       //
239       aEdgeFace.SetEdge (aE);
240       aEdgeFace.SetFace (aF);
241       aEdgeFace.SetFuzzyValue(myFuzzyValue);
242       aEdgeFace.UseQuickCoincidenceCheck(bExpressCompute);
243       //
244       IntTools_Range aSR(aTS1, aTS2);
245       IntTools_Range anewSR=aSR;
246       BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, anewSR);
247       aEdgeFace.SetNewSR(anewSR);
248       //
249       IntTools_Range aPBRange(aT1, aT2);
250       aSR = aPBRange;
251       BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, aPBRange);
252       aEdgeFace.SetRange (aPBRange);
253       aEdgeFace.SetProgressIndicator(myProgressIndicator);
254       //
255     }//for (; aIt.More(); aIt.Next()) {
256   }//for (; myIterator->More(); myIterator->Next()) {
257   //
258   aNbEdgeFace=aVEdgeFace.Length();
259   //=================================================================
260   BOPAlgo_EdgeFaceCnt::Perform(myRunParallel, aVEdgeFace, myContext);
261   //=================================================================
262   //
263   for (k=0; k < aNbEdgeFace; ++k) {
264     BOPAlgo_EdgeFace& aEdgeFace=aVEdgeFace(k);
265     if (!aEdgeFace.IsDone() || aEdgeFace.HasErrors()) {
266       // Warn about failed intersection of sub-shapes
267       AddIntersectionFailedWarning(aEdgeFace.Edge(), aEdgeFace.Face());
268       continue;
269     }
270     //
271     const IntTools_SequenceOfCommonPrts& aCPrts=aEdgeFace.CommonParts();
272     aNbCPrts = aCPrts.Length();
273     if (!aNbCPrts) {
274       continue;
275     }
276     //
277     aEdgeFace.Indices(nE, nF);
278     //
279     const TopoDS_Edge& aE=aEdgeFace.Edge();
280     const TopoDS_Face& aF=aEdgeFace.Face();
281     //
282     aTolE=BRep_Tool::Tolerance(aE);
283     aTolF=BRep_Tool::Tolerance(aF);
284     const IntTools_Range& anewSR=aEdgeFace.NewSR();
285     Handle(BOPDS_PaveBlock)& aPB=aEdgeFace.PaveBlock();
286     //
287     aPB->Range(aT1, aT2);
288     aPB->Indices(nV[0], nV[1]);
289     bIsPBSplittable = aPB->IsSplittable();
290     //
291     anewSR.Range(aTS1, aTS2);
292     //
293     if (aCPrts(1).Type() == TopAbs_VERTEX) {
294       // for the intersection type VERTEX
295       // extend vertices ranges using Edge/Edge intersections
296       // between the edge aE and the edges of the face aF.
297       // thereby the edge's intersection range is reduced
298       ReduceIntersectionRange(nV[0], nV[1], nE, nF, aTS1, aTS2);
299     }
300     //
301     IntTools_Range aR1(aT1, aTS1), aR2(aTS2, aT2);
302     //
303     BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
304     const TColStd_MapOfInteger& aMIFOn=aFI.VerticesOn();
305     const TColStd_MapOfInteger& aMIFIn=aFI.VerticesIn();
306     //
307     Standard_Boolean bLinePlane = Standard_False;
308     if (aNbCPrts) {
309       BRepAdaptor_Curve aBAC(aE);
310       bLinePlane = (aBAC.GetType() == GeomAbs_Line &&
311                     myContext->SurfaceAdaptor(aF).GetType() == GeomAbs_Plane);
312     }
313     //
314     for (i=1; i<=aNbCPrts; ++i) {
315       const IntTools_CommonPrt& aCPart=aCPrts(i);
316       aType=aCPart.Type();
317       switch (aType) {
318         case TopAbs_VERTEX: {
319           Standard_Boolean bIsOnPave[2];
320           Standard_Integer j;
321           Standard_Real aT, aTolToDecide; 
322           TopoDS_Vertex aVnew;
323           //
324           IntTools_Tools::VertexParameter(aCPart, aT);
325           BOPTools_AlgoTools::MakeNewVertex(aE, aT, aF, aVnew);
326           //
327           const IntTools_Range& aR=aCPart.Range1();
328           aTolToDecide=5.e-8;
329           //
330           bIsOnPave[0]=IntTools_Tools::IsInRange(aR1, aR, aTolToDecide); 
331           bIsOnPave[1]=IntTools_Tools::IsInRange(aR2, aR, aTolToDecide); 
332           //
333           if ((bIsOnPave[0] && bIsOnPave[1]) || 
334               (bLinePlane && (bIsOnPave[0] || bIsOnPave[1]))) {
335             bV[0]=CheckFacePaves(nV[0], aMIFOn, aMIFIn);
336             bV[1]=CheckFacePaves(nV[1], aMIFOn, aMIFIn);
337             if (bV[0] && bV[1]) {
338               IntTools_CommonPrt aCP = aCPart;
339               aCP.SetType(TopAbs_EDGE);
340               BOPDS_InterfEF& aEF=aEFs.Appended();
341               iX=aEFs.Length()-1;
342               aEF.SetIndices(nE, nF);
343               aEF.SetCommonPart(aCP);
344               myDS->AddInterf(nE, nF);
345               //
346               aMIEFC.Add(nF);
347               //           
348               BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, aAllocator);
349               break;
350             }
351           }
352           //
353           if (!bIsPBSplittable) {
354             continue;
355           }
356           //
357           for (j=0; j<2; ++j) {
358             if (bIsOnPave[j]) {
359               bV[j]=CheckFacePaves(nV[j], aMIFOn, aMIFIn);
360               if (bV[j]) {
361                 const TopoDS_Vertex& aV=
362                   (*(TopoDS_Vertex *)(&myDS->Shape(nV[j])));
363                 //
364                 Standard_Real f, l, aTolVnew, aDistPP, aTolPC, aTolV;
365                 //
366                 const Handle(Geom_Curve)& aCur = BRep_Tool::Curve(aE, f, l);
367                 //
368                 gp_Pnt aP1 = BRep_Tool::Pnt(aV);
369                 gp_Pnt aP2 = aCur->Value(aT);
370                 //
371                 aDistPP=aP1.Distance(aP2);
372                 //
373                 aTolPC=Precision::PConfusion();
374                 aTolV=BRep_Tool::Tolerance(aV);
375                 if (aDistPP > (aTolV+aTolPC)) {
376                   aTolVnew=Max(aTolE, aDistPP);
377                   UpdateVertex(nV[j], aTolVnew);
378                 }
379               }
380               else {
381                 bIsOnPave[j] = ForceInterfVF(nV[j], nF);
382               }
383             }
384           }
385           //
386           if (!bIsOnPave[0] && !bIsOnPave[1]) {
387             if (CheckFacePaves(aVnew, aMIFOn)) {
388               continue;
389             }
390             //
391             Standard_Real aTolVnew = BRep_Tool::Tolerance(aVnew);
392             aTolVnew = Max(aTolVnew, Max(aTolE, aTolF));
393             BRep_Builder().UpdateVertex(aVnew, aTolVnew);
394             if (bLinePlane) {
395               // increase tolerance for Line/Plane intersection, but do not update 
396               // the vertex till its intersection with some other shape
397               IntTools_Range aCR = aCPart.Range1();
398               aTolVnew = Max(aTolVnew, (aCR.Last() - aCR.First()) / 2.);
399             }
400             //
401             const gp_Pnt& aPnew = BRep_Tool::Pnt(aVnew);
402             //
403             if (!myContext->IsPointInFace(aPnew, aF, aTolVnew)) {
404               continue;
405             }
406             //
407             aMIEFC.Add(nF);
408             // 1
409             BOPDS_InterfEF& aEF=aEFs.Appended();
410             iX=aEFs.Length()-1;
411             aEF.SetIndices(nE, nF);
412             aEF.SetCommonPart(aCPart);
413             // 2
414             myDS->AddInterf(nE, nF);
415             // 3
416             BOPDS_CoupleOfPaveBlocks aCPB;
417             //
418             aCPB.SetPaveBlocks(aPB, aPB);
419             aCPB.SetIndexInterf(iX);
420             aCPB.SetTolerance(aTolVnew);
421             aMVCPB.Add(aVnew, aCPB);
422           }
423         }
424           break;
425         case TopAbs_EDGE:  {
426           aMIEFC.Add(nF);
427           //
428           // 1
429           BOPDS_InterfEF& aEF=aEFs.Appended();
430           iX=aEFs.Length()-1;
431           aEF.SetIndices(nE, nF);
432           //
433           bV[0]=CheckFacePaves(nV[0], aMIFOn, aMIFIn);
434           bV[1]=CheckFacePaves(nV[1], aMIFOn, aMIFIn);
435           if (!bV[0] || !bV[1]) {
436             myDS->AddInterf(nE, nF);
437             break;
438           }
439           aEF.SetCommonPart(aCPart);
440           // 2
441           myDS->AddInterf(nE, nF);
442           // 3
443           BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, aAllocator);
444           
445         }
446           break; 
447         default:
448           break; 
449       }//switch (aType) {
450     }//for (i=1; i<=aNbCPrts; ++i) {
451   }// for (k=0; k < aNbEdgeEdge; ++k) {
452   // 
453   //=========================================
454   // post treatment
455   //=========================================
456   BOPAlgo_Tools::PerformCommonBlocks(aMPBLI, aAllocator, myDS);
457   PerformNewVertices(aMVCPB, aAllocator, Standard_False);
458   //
459   // Update FaceInfoIn for all faces having EF common parts
460   TColStd_MapIteratorOfMapOfInteger aItMI;
461   aItMI.Initialize(aMIEFC);
462   for (; aItMI.More(); aItMI.Next()) {
463     nF=aItMI.Value();
464     myDS->UpdateFaceInfoIn(nF);
465   }
466   //-----------------------------------------------------scope t
467   aMIEFC.Clear();
468   aMVCPB.Clear();
469   aMPBLI.Clear();
470   ////aAllocator.Nullify();
471 }
472 //=======================================================================
473 // function: CheckFacePaves
474 // purpose: 
475 //=======================================================================
476 Standard_Boolean BOPAlgo_PaveFiller::CheckFacePaves 
477   (const Standard_Integer nVx,
478    const TColStd_MapOfInteger& aMIFOn,
479    const TColStd_MapOfInteger& aMIFIn)
480 {
481   Standard_Boolean bRet;
482   Standard_Integer nV;
483   TColStd_MapIteratorOfMapOfInteger aIt;
484   //
485   bRet=Standard_False;
486   //
487   aIt.Initialize(aMIFOn);
488   for (; aIt.More(); aIt.Next()) {
489     nV=aIt.Value();
490     if (nV==nVx) {
491       bRet=!bRet;
492       return bRet;
493     }
494   }
495   aIt.Initialize(aMIFIn);
496   for (; aIt.More(); aIt.Next()) {
497     nV=aIt.Value();
498     if (nV==nVx) {
499       bRet=!bRet;
500       return bRet;
501     }
502   }
503   //
504   return bRet;
505 }
506 //=======================================================================
507 // function: CheckFacePaves
508 // purpose: 
509 //=======================================================================
510 Standard_Boolean BOPAlgo_PaveFiller::CheckFacePaves 
511   (const TopoDS_Vertex& aVnew,
512    const TColStd_MapOfInteger& aMIF)
513 {
514   Standard_Boolean bRet;
515   Standard_Integer nV, iFlag;
516   TColStd_MapIteratorOfMapOfInteger aIt;
517   //
518   bRet=Standard_True;
519   //
520   aIt.Initialize(aMIF);
521   for (; aIt.More(); aIt.Next()) {
522     nV=aIt.Value();
523     const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&myDS->Shape(nV)));
524     iFlag=BOPTools_AlgoTools::ComputeVV(aVnew, aV);
525     if (!iFlag) {
526       return bRet;
527     }
528   }
529   //
530   return !bRet;
531 }
532 //=======================================================================
533 //function : ForceInterfVF
534 //purpose  : 
535 //=======================================================================
536 Standard_Boolean BOPAlgo_PaveFiller::ForceInterfVF
537   (const Standard_Integer nV, 
538    const Standard_Integer nF)
539 {
540   Standard_Boolean bRet;
541   Standard_Integer iFlag, nVx;
542   Standard_Real U, V, aTolVNew;
543   //
544   bRet = Standard_False;
545   const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV);
546   const TopoDS_Face&   aF = *(TopoDS_Face*)  &myDS->Shape(nF);
547   //
548   iFlag = myContext->ComputeVF(aV, aF, U, V, aTolVNew, myFuzzyValue);
549   if (iFlag == 0 || iFlag == -2) {
550     bRet=!bRet;
551   //
552     BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF();
553     aVFs.SetIncrement(10);
554     // 1
555     BOPDS_InterfVF& aVF=aVFs.Appended();
556     //
557     aVF.SetIndices(nV, nF);
558     aVF.SetUV(U, V);
559     // 2
560     myDS->AddInterf(nV, nF);
561     //
562     // 3 update vertex V/F if necessary
563     nVx=UpdateVertex(nV, aTolVNew);
564     // 4
565     if (myDS->IsNewShape(nVx)) {
566       aVF.SetIndexNew(nVx);
567     }
568     //
569     BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
570     TColStd_MapOfInteger& aMVIn=aFI.ChangeVerticesIn();
571     aMVIn.Add(nVx);
572     //
573     // check for self-interference
574     Standard_Integer iRV = myDS->Rank(nV);
575     if (iRV >= 0 && iRV == myDS->Rank(nF)) {
576       // add warning status
577       TopoDS_Compound aWC;
578       BRep_Builder().MakeCompound(aWC);
579       BRep_Builder().Add(aWC, aV);
580       BRep_Builder().Add(aWC, aF);
581       AddWarning (new BOPAlgo_AlertSelfInterferingShape (aWC));
582     }
583
584   }
585   return bRet;
586 }
587 //=======================================================================
588 //function : ReduceIntersectionRange
589 //purpose  : 
590 //=======================================================================
591 void BOPAlgo_PaveFiller::ReduceIntersectionRange(const Standard_Integer theV1,
592                                                  const Standard_Integer theV2,
593                                                  const Standard_Integer theE,
594                                                  const Standard_Integer theF,
595                                                  Standard_Real& theTS1,
596                                                  Standard_Real& theTS2)
597 {
598   if (!myDS->IsNewShape(theV1) &&
599       !myDS->IsNewShape(theV2)) {
600     return;
601   }
602   //
603   if (!myDS->HasInterfShapeSubShapes(theE, theF)) {
604     return;
605   }
606   //
607   BOPDS_VectorOfInterfEE& aEEs = myDS->InterfEE();
608   Standard_Integer aNbEEs = aEEs.Length();
609   if (!aNbEEs) {
610     return;
611   }
612   //
613   Standard_Integer i, nV, nE1, nE2;
614   Standard_Real aTR1, aTR2;
615   //
616   // get face's edges to check that E/E contains the edge from the face
617   TColStd_MapOfInteger aMFE;
618   const TColStd_ListOfInteger& aLI = myDS->ShapeInfo(theF).SubShapes();
619   TColStd_ListIteratorOfListOfInteger aItLI(aLI);
620   for (; aItLI.More(); aItLI.Next()) {
621     nE1 = aItLI.Value();
622     if (myDS->ShapeInfo(nE1).ShapeType() == TopAbs_EDGE) {
623       aMFE.Add(nE1);
624     }
625   }
626   //
627   for (i = 0; i < aNbEEs; ++i) {
628     BOPDS_InterfEE& aEE = aEEs(i);
629     if (!aEE.HasIndexNew()) {
630       continue;
631     }
632     //
633     // check the vertex
634     nV = aEE.IndexNew();
635     if (nV != theV1 && nV != theV2) {
636       continue;
637     }
638     //
639     // check that the intersection is between the edge
640     // and one of the face's edge
641     aEE.Indices(nE1, nE2);
642     if (((theE != nE1) && (theE != nE2)) ||
643         (!aMFE.Contains(nE1) && !aMFE.Contains(nE2))) {
644       continue;
645     }
646     //
647     // update the intersection range
648     const IntTools_CommonPrt& aCPart = aEE.CommonPart();
649     const IntTools_Range& aCRange = 
650       (theE == nE1) ? aCPart.Range1() : aCPart.Ranges2().First();
651     aCRange.Range(aTR1, aTR2);
652     //
653     if (nV == theV1) {
654       if (theTS1 < aTR2) {
655         theTS1 = aTR2;
656       }
657     }
658     else {
659       if (theTS2 > aTR1) {
660         theTS2 = aTR1;
661       }
662     }
663   }
664 }