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