9e5b247a3500778f3728e984b29696c1d3cb800b
[occt.git] / src / BRepExtrema / BRepExtrema_DistanceSS.cxx
1 // File:    BRepExtrema_DistanceSS.cxx
2 // Created: Mon Apr 22 17:03:37 1996
3 // Author:      Maria PUMBORIOS
4 // Author:  Herve LOUESSARD 
5
6 // Modified: Sergey ZERCHANINOV
7
8 #include <BRepExtrema_DistanceSS.hxx>
9
10 #include <TopTools_IndexedMapOfShape.hxx>
11 #include <TopExp.hxx>
12 #include <gp_Pnt.hxx>
13 #include <gp_Pnt2d.hxx>
14 #include <BRep_Tool.hxx>
15 #include <BRepExtrema_SupportType.hxx>
16 #include <Standard_Real.hxx>
17 #include <BRepExtrema_SolutionElem.hxx>
18 #include <BRepExtrema_SeqOfSolution.hxx>
19 #include <Standard_Boolean.hxx>
20 #include <Standard_Integer.hxx> 
21 #include <TopAbs_ShapeEnum.hxx>
22 #include <TopoDS.hxx>
23 #include <Bnd_Box.hxx>
24 #include <BRepExtrema_ExtPC.hxx>
25 #include <BRepExtrema_ExtPF.hxx>
26 #include <Extrema_ExtFlag.hxx>
27 #include <BRepExtrema_ExtCC.hxx>
28 #include <BRepExtrema_ExtCF.hxx>
29 #include <BRepExtrema_ExtFF.hxx>
30 #include <BRepClass_FaceClassifier.hxx>
31 #include <TopAbs.hxx>
32 #include <Geom_Curve.hxx>
33 #include <GeomAbs_Shape.hxx>
34 #include <GeomAdaptor_Curve.hxx>
35 #include <TColStd_Array1OfReal.hxx>
36 #include <BRepBuilderAPI_MakeVertex.hxx>
37 #include <BRepBuilderAPI_MakeEdge.hxx>
38 #include <BRepBuilderAPI_MakeFace.hxx>
39 #include <Geom_Surface.hxx>
40 #include <GeomAPI_ProjectPointOnSurf.hxx>
41 #include <GeomAPI_ProjectPointOnCurve.hxx>
42 #include <Geom_RectangularTrimmedSurface.hxx>
43 #include <Geom_TrimmedCurve.hxx>
44 #include <BRepBndLib.hxx>
45 #include <BRepTools.hxx>
46 #include <TColgp_Array1OfPnt.hxx>
47
48
49 /*********************************************************************************/
50
51 //------------------------------------------------------------------------------
52 // function: TRI_SOLUTION
53 //------------------------------------------------------------------------------
54 static Standard_Boolean TRI_SOLUTION (const BRepExtrema_SeqOfSolution& SeqSol, const gp_Pnt& Pt)
55 {
56   const Standard_Integer Nbsol = SeqSol.Length();
57   for (Standard_Integer i = 1; i <= Nbsol; i++)
58   {
59     const Standard_Real dst = SeqSol.Value(i).Point().Distance(Pt);
60     if (dst <= Precision::Confusion()) return Standard_False;
61   }
62   return Standard_True;
63 }  
64
65 //------------------------------------------------------------------------------
66 // function: MIN_SOLUTION
67 //------------------------------------------------------------------------------
68 static void MIN_SOLUTION (const BRepExtrema_SeqOfSolution& SeqSol1,
69                           const BRepExtrema_SeqOfSolution& SeqSol2,
70                           const Standard_Real DstRef,
71                           const Standard_Real Eps,
72                           BRepExtrema_SeqOfSolution& seqSol1,
73                           BRepExtrema_SeqOfSolution& seqSol2)
74 {
75   const Standard_Integer nbSol = SeqSol1.Length();
76   for (Standard_Integer i = 1; i <= nbSol; i++)
77   {
78     const Standard_Real dst1 = SeqSol1.Value(i).Dist();
79     if (fabs(dst1 - DstRef) < Eps)
80         {         
81       seqSol1.Append(SeqSol1.Value(i));
82       seqSol2.Append(SeqSol2.Value(i));
83         }
84   }
85 }
86
87 //------------------------------------------------------------------------------
88 // function: TRIM_INFINIT_EDGE
89 //------------------------------------------------------------------------------
90 static void TRIM_INFINIT_EDGE(const TopoDS_Edge& S1, const TopoDS_Edge& S2, TopoDS_Edge& aResEdge,
91                               Standard_Boolean& bIsTrim1, Standard_Boolean& bIsTrim2)
92 {
93   if ( BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2) )
94     return;
95
96   aResEdge = S2;
97   Standard_Real aFirst1, aLast1, aFirst2, aLast2;
98   Handle(Geom_Curve) pCurv1 = BRep_Tool::Curve(S1, aFirst1, aLast1);
99   Handle(Geom_Curve) pCurv2 = BRep_Tool::Curve(S2, aFirst2, aLast2);
100
101   if (Precision::IsInfinite(aFirst1) &&
102       Precision::IsInfinite(aLast1)  &&
103       Precision::IsInfinite(aFirst2) &&
104       Precision::IsInfinite(aLast2))
105     return;
106   
107   Standard_Real Umin, Umax;
108   Standard_Boolean bUmin, bUmax;
109   bUmin = bUmax = Standard_False;
110
111   Handle(Geom_Curve) pCurv;
112   if ( !pCurv1.IsNull() && (Precision::IsInfinite(aFirst1) || Precision::IsInfinite(aLast1)) )
113   {
114     pCurv = pCurv1;
115     bIsTrim1 = Standard_True;
116     if (!Precision::IsInfinite(aFirst1))
117     {
118       bUmin = Standard_True;
119       Umin = aFirst1;
120     }
121     else if (!Precision::IsInfinite(aLast1))
122     {
123       bUmax = Standard_True;
124       Umax = aLast1;
125     }
126   }
127   else if ( !pCurv2.IsNull() && (Precision::IsInfinite(aFirst2) || Precision::IsInfinite(aLast2)) )
128   {
129     pCurv = pCurv2;
130     bIsTrim2 = Standard_True;
131     if (!Precision::IsInfinite(aFirst2))
132     {
133       bUmin = Standard_True;
134       Umin = aFirst2;
135     }
136     else if (!Precision::IsInfinite(aLast2))
137     {
138       bUmax = Standard_True;
139       Umax = aLast2;
140     }
141   }
142   if (bIsTrim1 || bIsTrim2)
143   {
144     Bnd_Box aEdgeBox;
145     if (bIsTrim1)
146       BRepBndLib::Add(S2, aEdgeBox);
147     if (bIsTrim2)
148       BRepBndLib::Add(S1, aEdgeBox);
149     Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
150     aEdgeBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
151
152     const gp_Pnt aPnt0(Xmin, Ymin, Zmin);
153     const gp_Pnt aPnt1(Xmin, Ymax, Zmin);
154     const gp_Pnt aPnt2(Xmin, Ymax, Zmax);
155     const gp_Pnt aPnt3(Xmin, Ymin, Zmax);
156     const gp_Pnt aPnt4(Xmax, Ymax, Zmin);
157     const gp_Pnt aPnt5(Xmax, Ymax, Zmax);
158     const gp_Pnt aPnt6(Xmax, Ymin, Zmax);
159     const gp_Pnt aPnt7(Xmax, Ymin, Zmin);
160
161         Standard_Real arrU[8];
162     GeomAPI_ProjectPointOnCurve aProj(aPnt0, pCurv);
163     /*szv:aProj.Perform(aPnt0);*/ arrU[0] = aProj.LowerDistanceParameter();
164     aProj.Perform(aPnt1); arrU[1] = aProj.LowerDistanceParameter();
165     aProj.Perform(aPnt2); arrU[2] = aProj.LowerDistanceParameter();
166     aProj.Perform(aPnt3); arrU[3] = aProj.LowerDistanceParameter();
167     aProj.Perform(aPnt4); arrU[4] = aProj.LowerDistanceParameter();
168     aProj.Perform(aPnt5); arrU[5] = aProj.LowerDistanceParameter();
169     aProj.Perform(aPnt6); arrU[6] = aProj.LowerDistanceParameter();
170     aProj.Perform(aPnt7); arrU[7] = aProj.LowerDistanceParameter();
171     
172     if (!bUmin)
173       Umin = arrU[0];
174         
175     if (!bUmax)
176       Umax = arrU[0];
177
178     Standard_Integer i = 0;
179     while (i < 8)
180         {
181       const Standard_Real aU = arrU[i++];
182           if (aU < Umin)
183             Umin = aU;
184           else if (aU > Umax)
185             Umax = aU;
186         }
187
188     Standard_Real tol = Precision::Confusion();
189     if (bIsTrim1)
190       tol = BRep_Tool::Tolerance(S1);
191     else if (bIsTrim2)
192       tol = BRep_Tool::Tolerance(S2);
193
194     const Standard_Real EpsU = GeomAdaptor_Curve(pCurv).Resolution(3.*tol);
195     if (fabs(Umin - Umax) < EpsU)
196     {
197       Umin -= EpsU;
198       Umax += EpsU;
199     }
200
201     Handle(Geom_Curve) result = new Geom_TrimmedCurve(pCurv, Umin, Umax);
202     aResEdge = BRepBuilderAPI_MakeEdge(result);
203   }
204 }
205
206 //------------------------------------------------------------------------------
207 // function: TRIM_INFINIT_FACE
208 //------------------------------------------------------------------------------
209 static void TRIM_INFINIT_FACE(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
210                               TopoDS_Face& aResFace, Standard_Boolean& bIsInfinit)
211 {
212   bIsInfinit = Standard_False;
213
214   TopAbs_ShapeEnum Type1 = S1.ShapeType();     
215   TopAbs_ShapeEnum Type2 = S2.ShapeType();
216
217   TopoDS_Edge aE;
218   TopoDS_Face aF;
219   
220   if (Type1 == TopAbs_EDGE && Type2 == TopAbs_FACE)
221   {
222     aE = TopoDS::Edge(S1);
223     if ( BRep_Tool::Degenerated(aE) )
224       return;
225     aF = TopoDS::Face(S2);
226   }
227   else if (Type2 == TopAbs_EDGE && Type1 == TopAbs_FACE)
228   {
229     aE = TopoDS::Edge(S2);
230     if ( BRep_Tool::Degenerated(aE) )
231       return;
232     aF = TopoDS::Face(S1);
233   }
234   else
235   {
236     bIsInfinit = Standard_False;
237     return;
238   }
239
240   aResFace = aF;
241   Handle(Geom_Surface) pSurf = BRep_Tool::Surface(aF);
242  
243   const Standard_Boolean bRestrict = BRep_Tool::NaturalRestriction(aF);
244
245   Standard_Real U1, V1, U2, V2;
246   Standard_Real Umin, Umax, Vmin, Vmax;
247   Standard_Boolean bUmin, bUmax, bVmin, bVmax;
248   bUmin = bUmax = bVmin = bVmax = Standard_False;
249   Standard_Boolean bIsTrim = Standard_False;
250
251   if (bRestrict)
252   {
253     pSurf->Bounds(U1, U2, V1, V2);
254     if (Precision::IsInfinite(U1))
255       bIsTrim = Standard_True;
256     else
257     {
258       Umin = U1;
259       bUmin = Standard_True;
260     }
261
262     if (Precision::IsInfinite(U2))
263       bIsTrim = Standard_True;
264     else
265     {
266       Umax = U2;
267       bUmax = Standard_True;
268     }
269
270     if (Precision::IsInfinite(V1))
271       bIsTrim = Standard_True;
272     else
273         {
274       Vmin = V1;
275       bVmin = Standard_True;
276         }
277       
278     if (Precision::IsInfinite(V2))
279       bIsTrim = Standard_True;
280     else
281         {
282       Vmax = V2;
283       bVmax = Standard_True;
284     }
285   }
286   else
287   {
288     BRepTools::UVBounds(aF, U1, U2, V1, V2);
289     if (Precision::IsInfinite(U1) &&
290         Precision::IsInfinite(U2) &&
291         Precision::IsInfinite(V1) &&
292         Precision::IsInfinite(V2))
293       bIsTrim = Standard_True;
294   }
295
296   if (bIsTrim)
297   {      
298     Bnd_Box aEdgeBox;
299     BRepBndLib::Add(aE, aEdgeBox);
300
301     if(aEdgeBox.IsWhole())
302       return;
303
304     Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
305     aEdgeBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
306
307     const gp_Pnt aPnt0(Xmin, Ymin, Zmin);
308     const gp_Pnt aPnt1(Xmin, Ymax, Zmin);
309     const gp_Pnt aPnt2(Xmin, Ymax, Zmax);
310     const gp_Pnt aPnt3(Xmin, Ymin, Zmax);
311     const gp_Pnt aPnt4(Xmax, Ymax, Zmin);
312     const gp_Pnt aPnt5(Xmax, Ymax, Zmax);
313     const gp_Pnt aPnt6(Xmax, Ymin, Zmax);
314     const gp_Pnt aPnt7(Xmax, Ymin, Zmin);
315
316     Standard_Real arrU[8], arrV[8];
317     GeomAPI_ProjectPointOnSurf aProj(aPnt0, pSurf);
318     /*szv:aProj.Perform(aPnt0);*/ if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[0],arrV[0]);
319     aProj.Perform(aPnt1); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[1],arrV[1]);
320     aProj.Perform(aPnt2); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[2],arrV[2]);
321     aProj.Perform(aPnt3); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[3],arrV[3]);
322     aProj.Perform(aPnt4); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[4],arrV[4]);
323     aProj.Perform(aPnt5); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[5],arrV[5]);
324     aProj.Perform(aPnt6); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[6],arrV[6]);
325     aProj.Perform(aPnt7); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[7],arrV[7]);
326
327     if (!bUmin)
328       Umin = arrU[0];
329     if (!bUmax)
330       Umax = arrU[0];
331     if (!bVmin)
332       Vmin = arrV[0];
333     if (!bVmax)
334       Vmax = arrV[0];
335
336     Standard_Integer i = 0;
337     while (i < 8)
338         {
339       const Standard_Real aU = arrU[i];
340           if (aU < Umin)
341             Umin = aU;
342           else if (aU > Umax)
343             Umax = aU;
344
345       const Standard_Real aV = arrV[i];
346           if (aV < Vmin)
347             Vmin = aV;
348           else if (aV > Vmax)
349             Vmax = aV;
350
351       i++;
352         }
353       
354     GeomAdaptor_Surface aGAS(pSurf);
355     const Standard_Real tol = BRep_Tool::Tolerance(aF);
356
357     const Standard_Real EpsU = aGAS.UResolution(3.*tol);
358     if (fabs(Umin - Umax) < EpsU)
359     {
360       Umin -= EpsU;
361       Umax += EpsU;
362     }
363
364     const Standard_Real EpsV = aGAS.VResolution(3.*tol);
365     if (fabs(Vmin - Vmax) < EpsV)
366     {
367       Vmin -= EpsV;
368       Vmax += EpsV;
369     }
370
371     Handle(Geom_Surface) result = new Geom_RectangularTrimmedSurface(pSurf, Umin, Umax, Vmin, Vmax);
372     aResFace = BRepBuilderAPI_MakeFace(result);
373
374     bIsInfinit = Standard_True;
375   }
376   else
377     bIsInfinit = Standard_False;
378 }
379
380 //------------------------------------------------------------------------------
381 // static function: PERFORM_C0
382 //------------------------------------------------------------------------------
383 static void PERFORM_C0(const TopoDS_Edge &S1, const TopoDS_Edge &S2,
384                        BRepExtrema_SeqOfSolution& SeqSol1,
385                        BRepExtrema_SeqOfSolution& SeqSol2,
386                        const Standard_Real DstRef,
387                        Standard_Real& mDstRef,
388                        const Standard_Real Eps)
389 {
390   if ( BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2) )
391     return;
392
393   Standard_Integer iE;
394   for (iE = 0; iE < 2; iE++)
395   {
396     TopoDS_Edge E, Eother;
397     if (iE == 0)
398         {
399           E      = S1;
400           Eother = S2;
401         }
402     else
403         {
404           E      = S2;
405           Eother = S1;
406         }
407
408     Standard_Real aFirst, aLast;
409     Handle(Geom_Curve) pCurv = BRep_Tool::Curve(E, aFirst, aLast);
410
411     Standard_Real aFOther, aLOther;
412     Handle(Geom_Curve) pCurvOther = BRep_Tool::Curve(Eother, aFOther, aLOther);
413
414     if (pCurv->Continuity() == GeomAbs_C0)
415         {
416       const Standard_Real epsP = Precision::PConfusion();
417
418       GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
419       const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
420
421       TColStd_Array1OfReal arrInter(1,1+nbIntervals);
422       aAdaptorCurve.Intervals(arrInter, GeomAbs_C1);
423
424       GeomAdaptor_Curve aAdaptorCurveOther(pCurvOther, aFOther, aLOther);
425       const Standard_Integer nbIntervalsOther = aAdaptorCurveOther.NbIntervals(GeomAbs_C1);
426       TColStd_Array1OfReal arrInterOther(1,1+nbIntervalsOther);
427       aAdaptorCurveOther.Intervals(arrInterOther, GeomAbs_C1);
428
429       Standard_Real Udeb,Ufin;
430       BRep_Tool::Range(Eother,Udeb,Ufin);
431
432       gp_Pnt P1,Pt;
433       Standard_Integer i, ii;  
434       BRepClass_FaceClassifier classifier;
435       for (i = 1; i <= arrInter.Length(); i++)
436       {
437         const Standard_Real aParameter = arrInter(i);
438         const gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
439         const TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
440
441         BRepExtrema_ExtPC Ext(V1,Eother);
442         const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
443         if ( NbExtrema > 0 )
444                 { 
445           // Search minimum distance dstmin
446           Standard_Real Dstmin = Ext.SquareDistance(1);
447           for (ii = 2; ii <= NbExtrema; ii++)
448           {
449             const Standard_Real sDst = Ext.SquareDistance(ii);
450             if (sDst<Dstmin)
451               Dstmin=sDst;
452           }
453           Dstmin = sqrt(Dstmin);
454
455           if ((Dstmin < DstRef - Eps) || (fabs(Dstmin-DstRef) < Eps))
456             for (ii = 1; ii <= NbExtrema; ii++)
457             {
458               if (fabs(Dstmin-sqrt(Ext.SquareDistance(ii)))<Eps)
459               {
460                 Pt=Ext.Point(ii);
461                 if (TRI_SOLUTION(SeqSol2,Pt))
462                 {
463                   // Check if the parameter does not correspond to a vertex
464                   const Standard_Real t = Ext.Parameter(ii);
465                   if ((fabs(t-Udeb)>=epsP)&&(fabs(t-Ufin)>epsP))
466                   {
467                     if (mDstRef > Dstmin)
468                       mDstRef=Dstmin;
469                     const BRepExtrema_SolutionElem Sol1(Dstmin,aPnt,BRepExtrema_IsOnEdge,E,aParameter);
470                     const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsOnEdge,Eother,t);
471                     SeqSol1.Append(iE == 0 ? Sol1 : Sol2);
472                     SeqSol2.Append(iE == 0 ? Sol2 : Sol1);
473                   }
474                 }
475               }
476             }
477         }
478         for (Standard_Integer i2 = 1; i2<=arrInterOther.Length(); i2++)
479         {
480           const Standard_Real aParameterOther = arrInterOther(i2);
481           const gp_Pnt aPntOther = aAdaptorCurveOther.Value(aParameterOther);
482           const Standard_Real Dst = aPnt.Distance(aPntOther);
483           if ((Dst < DstRef - Eps) || (fabs(Dst-DstRef) < Eps))
484           {             
485             if (mDstRef > Dst)
486               mDstRef=Dst;
487             const BRepExtrema_SolutionElem Sol1(Dst,aPnt,BRepExtrema_IsOnEdge,E,aParameter);
488             const BRepExtrema_SolutionElem Sol2(Dst,aPntOther,BRepExtrema_IsOnEdge,Eother,aParameterOther);
489             SeqSol1.Append(iE == 0 ? Sol1 : Sol2);
490             SeqSol2.Append(iE == 0 ? Sol2 : Sol1);
491           }               
492         }
493       }
494     }
495   }
496 }
497
498 /*********************************************************************************/
499
500 void BRepExtrema_DistanceSS::Perform(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
501                                      const Bnd_Box& B1, const Bnd_Box& B2)
502 {
503   SeqSolShape1.Clear();
504   SeqSolShape2.Clear();
505   myModif=Standard_False;
506
507   switch (S1.ShapeType())
508   {
509     case TopAbs_VERTEX :
510     {
511       TopoDS_Vertex V1 = TopoDS::Vertex(S1);
512       switch (S2.ShapeType())
513       {
514         case TopAbs_VERTEX :
515         {
516           TopoDS_Vertex V2 = TopoDS::Vertex(S2);
517           Perform( V1, V2 );
518           break;
519         }
520         case TopAbs_EDGE :
521         {
522           TopoDS_Edge E2 = TopoDS::Edge(S2);
523           Perform( V1, E2, B1, B2 );
524           break;
525         }
526         case TopAbs_FACE :
527         {
528           TopoDS_Face F2 = TopoDS::Face(S2);
529           Perform( V1, F2, B1, B2 );
530           break;
531         }
532       }
533       break;
534     }
535
536     case TopAbs_EDGE :
537     {
538       TopoDS_Edge E1 = TopoDS::Edge(S1);
539       switch (S2.ShapeType())
540       {
541         case TopAbs_VERTEX :
542         {
543           TopoDS_Vertex V2 = TopoDS::Vertex(S2);
544           Perform( E1, V2, B1, B2 );
545           break;
546         }
547         case TopAbs_EDGE :
548         {
549           TopoDS_Edge E2 = TopoDS::Edge(S2);
550           TopoDS_Edge aTrimEdge;
551           Standard_Boolean bIsTrim1 = Standard_False;
552           Standard_Boolean bIsTrim2 = Standard_False;
553           TRIM_INFINIT_EDGE( E1, E2, aTrimEdge, bIsTrim1, bIsTrim2 );
554           if (bIsTrim1)
555             E1 = aTrimEdge;
556           if (bIsTrim2)
557             E2 = aTrimEdge;
558           Perform( E1, E2, B1, B2 );
559           break;
560         }
561         case TopAbs_FACE :
562         {
563           TopoDS_Face F2 = TopoDS::Face(S2);
564           TopoDS_Face aTrimFace;
565           Standard_Boolean bIsInfinit;
566           TRIM_INFINIT_FACE( E1, F2, aTrimFace, bIsInfinit );
567           if (bIsInfinit)
568             F2 = aTrimFace;
569           Perform( E1, F2, B1, B2 );
570           break;
571         }
572       }
573       break;
574     }
575
576     case TopAbs_FACE :
577     {
578       TopoDS_Face F1 = TopoDS::Face(S1);
579       switch (S2.ShapeType())
580       {
581         case TopAbs_VERTEX :
582         {
583           TopoDS_Vertex V2 = TopoDS::Vertex(S2);
584           Perform( F1, V2, B1, B2 );
585           break;
586         }
587         case TopAbs_EDGE :
588         {
589           TopoDS_Edge E2 = TopoDS::Edge(S2);
590           TopoDS_Face aTrimFace;
591           Standard_Boolean bIsInfinit;
592           TRIM_INFINIT_FACE( F1, E2, aTrimFace, bIsInfinit );
593           if (bIsInfinit)
594             F1 = aTrimFace;
595           Perform( F1, E2, B1, B2 );
596           break;
597         }
598         case TopAbs_FACE :
599         {
600           TopoDS_Face F2 = TopoDS::Face(S2);
601           Perform( F1, F2, B1, B2 );
602           break;
603         }
604       }
605       break;
606     }
607   }
608 }
609
610 /*********************************************************************************/
611
612 void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Vertex& S2)
613 {     
614   const gp_Pnt P1 = BRep_Tool::Pnt(S1);
615   const gp_Pnt P2 = BRep_Tool::Pnt(S2);
616
617   const Standard_Real Dst = P1.Distance(P2);
618   if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
619   { 
620     if (myDstRef > Dst)
621       myDstRef=Dst;
622     myModif=Standard_True;
623     const BRepExtrema_SolutionElem Sol1(Dst,P1,BRepExtrema_IsVertex,S1);
624     const BRepExtrema_SolutionElem Sol2(Dst,P2,BRepExtrema_IsVertex,S2);
625     SeqSolShape1.Append(Sol1);
626     SeqSolShape2.Append(Sol2);
627   }
628 }
629
630 /*********************************************************************************/
631
632 void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Edge& S2,
633                                      const Bnd_Box& B1, const Bnd_Box& B2)
634
635   if (BRep_Tool::Degenerated(S2))
636     return;
637
638   const Standard_Real Dst=B1.Distance(B2);
639   if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
640   {
641     BRepExtrema_ExtPC Ext(S1,S2);
642     const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
643     if ( NbExtrema > 0 )
644     {
645       // Search minimum distance Dstmin
646       Standard_Integer i;
647       Standard_Real Dstmin = Ext.SquareDistance(1);
648       for (i = 2; i <= NbExtrema; i++)
649       {
650         const Standard_Real sDst = Ext.SquareDistance(i);
651         if (sDst<Dstmin)
652           Dstmin=sDst;
653           }
654       Dstmin = sqrt(Dstmin);
655       if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
656       {
657         Standard_Real Udeb,Ufin;
658         BRep_Tool::Range(S2,Udeb,Ufin);
659
660         gp_Pnt Pt,P1=BRep_Tool::Pnt(S1);
661         const Standard_Real epsP=Precision::PConfusion();
662
663         for (i = 1; i <= NbExtrema; i++)
664         {
665           if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
666           {
667             Pt=Ext.Point(i);
668             if (TRI_SOLUTION(SeqSolShape2,Pt))
669             {
670               // Check if the parameter does not correspond to a vertex
671               const Standard_Real t = Ext.Parameter(i);
672               if ( (fabs(t-Udeb)>=epsP) && (fabs(t-Ufin)>epsP) )
673               {
674                 if (myDstRef > Dstmin)
675                   myDstRef=Dstmin;
676                 myModif=Standard_True;
677                 const BRepExtrema_SolutionElem Sol1(Dstmin,P1,BRepExtrema_IsVertex,S1);
678                 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsOnEdge,S2,t);
679                 SeqSolShape1.Append(Sol1);
680                 SeqSolShape2.Append(Sol2);
681               }
682             }
683           }
684         }
685       }
686     }
687   }
688 }
689
690 void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1,const TopoDS_Vertex& S2,
691                                      const Bnd_Box& B1,const Bnd_Box& B2)
692 {
693   if (BRep_Tool::Degenerated(S1))
694     return;
695
696   const Standard_Real Dst=B1.Distance(B2);
697   if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
698   {
699     BRepExtrema_ExtPC Ext(S2,S1);
700     const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
701     if ( NbExtrema > 0 )
702     {
703       // Search minimum distance Dstmin
704       Standard_Integer i;
705       Standard_Real Dstmin = Ext.SquareDistance(1);
706       for (i = 2; i <= NbExtrema; i++)
707       {
708         const Standard_Real sDst = Ext.SquareDistance(i);
709         if (sDst<Dstmin)
710           Dstmin=sDst;
711           }
712       Dstmin = sqrt(Dstmin);
713       if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
714       {
715         Standard_Real Udeb,Ufin;
716         BRep_Tool::Range(S1,Udeb,Ufin);
717
718         gp_Pnt Pt,P1=BRep_Tool::Pnt(S2);
719         const Standard_Real epsP=Precision::PConfusion();
720
721         for (i = 1; i <= NbExtrema; i++)
722         {
723           if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
724           {
725             Pt=Ext.Point(i);
726             if (TRI_SOLUTION(SeqSolShape1,Pt))
727             {
728               // Check if the parameter does not correspond to a vertex
729               const Standard_Real t = Ext.Parameter(i);
730               if ( (fabs(t-Udeb)>=epsP) && (fabs(t-Ufin)>epsP) )
731               {
732                 if (myDstRef > Dstmin)
733                   myDstRef=Dstmin;
734                 myModif=Standard_True;
735                 const BRepExtrema_SolutionElem Sol1(Dstmin,P1,BRepExtrema_IsOnEdge,S1,t);
736                 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsVertex,S2);
737                 SeqSolShape1.Append(Sol1);
738                 SeqSolShape2.Append(Sol2);
739               }
740             }
741           }
742         }
743       }
744     }
745   }
746 }
747
748 /*********************************************************************************/
749
750 void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Face& S2, 
751                                      const Bnd_Box& B1, const Bnd_Box& B2)
752 {
753   const Standard_Real Dst=B1.Distance(B2);
754   if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
755   { 
756     BRepExtrema_ExtPF Ext(S1,S2,myFlag,myAlgo);
757     const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
758     if ( NbExtrema > 0 )
759     {
760       // Search minimum distance Dstmin
761       Standard_Integer i;
762       Standard_Real Dstmin = Ext.SquareDistance(1);
763       for (i = 2; i <= NbExtrema; i++)
764       {
765         const Standard_Real sDst = Ext.SquareDistance(i);
766         if (sDst<Dstmin) 
767           Dstmin=sDst;
768       }
769       Dstmin = sqrt(Dstmin);
770       if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
771       {
772         Standard_Real U,V;
773         gp_Pnt Pt,P1=BRep_Tool::Pnt(S1);
774         BRepClass_FaceClassifier classifier;
775         const Standard_Real tol = BRep_Tool::Tolerance(S2);
776         const Standard_Real epsP = Precision::PConfusion();
777  
778         for (i = 1; i <= NbExtrema; i++)
779         {
780           if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
781           {
782             Pt=Ext.Point(i);
783             if (TRI_SOLUTION(SeqSolShape2,Pt))
784             {
785               // Check if the parameter does not correspond to a vertex
786               Ext.Parameter(i,U,V);
787               const gp_Pnt2d PUV(U,V);
788               classifier.Perform(S2,PUV,tol);
789               if (classifier.State()==TopAbs_IN)
790               {
791                 if (myDstRef > Dstmin)
792                   myDstRef=Dstmin;
793                 myModif=Standard_True;
794                 const BRepExtrema_SolutionElem Sol1(Dstmin,P1,BRepExtrema_IsVertex,S1);
795                 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsInFace,S2,U,V);
796                 SeqSolShape1.Append(Sol1);
797                 SeqSolShape2.Append(Sol2);                
798               }
799             }
800           }
801         }
802       }
803     }
804   }
805 }
806
807 void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Vertex& S2, 
808                                      const Bnd_Box& B1, const Bnd_Box& B2)
809 {
810   const Standard_Real Dst=B1.Distance(B2);
811   if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
812   { 
813     BRepExtrema_ExtPF Ext(S2,S1,myFlag,myAlgo);
814     const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
815     if ( NbExtrema > 0 )
816     {
817       // Search minimum distance Dstmin
818       Standard_Integer i;
819       Standard_Real Dstmin = Ext.SquareDistance(1);
820       for (i = 2; i <= NbExtrema; i++)
821       {
822         const Standard_Real sDst = Ext.SquareDistance(i);
823         if (sDst<Dstmin) 
824           Dstmin=sDst;
825       }
826       Dstmin = sqrt(Dstmin);
827       if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
828       {
829         Standard_Real U,V;
830         gp_Pnt Pt,P1=BRep_Tool::Pnt(S2);
831         BRepClass_FaceClassifier classifier;
832         const Standard_Real tol = BRep_Tool::Tolerance(S1);
833         const Standard_Real epsP = Precision::PConfusion();
834  
835         for (i = 1; i <= NbExtrema; i++)
836         {
837           if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
838           {
839             Pt=Ext.Point(i);
840             if (TRI_SOLUTION(SeqSolShape1,Pt))
841             {
842               // Check if the parameter does not correspond to a vertex
843               Ext.Parameter(i,U,V);
844               const gp_Pnt2d PUV(U,V);
845               classifier.Perform(S1,PUV,tol);
846               if (classifier.State()==TopAbs_IN)
847               {
848                 if (myDstRef > Dstmin)
849                   myDstRef=Dstmin;
850                 myModif=Standard_True;
851                 const BRepExtrema_SolutionElem Sol1(Dstmin,P1,BRepExtrema_IsInFace,S1,U,V);
852                 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsVertex,S2);
853                 SeqSolShape1.Append(Sol1);
854                 SeqSolShape2.Append(Sol2);                
855               }
856             }
857           }
858         }
859       }
860     }
861   }
862 }
863
864 /*********************************************************************************/
865
866 void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Edge& S2,
867                                      const Bnd_Box& B1, const Bnd_Box& B2)
868 {
869   if (BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2))
870     return;
871
872   const Standard_Real Dst=B1.Distance(B2);
873   if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
874   {
875     const Standard_Real DstRef = myDstRef;
876
877     BRepExtrema_ExtCC Ext(S1,S2);
878         const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
879     if ( NbExtrema > 0 )
880     {
881       // Search minimum distance Dstmin
882       Standard_Integer i;
883       Standard_Real Dstmin = Ext.SquareDistance(1);
884       for (i = 2; i <= NbExtrema; i++)
885       {
886         const Standard_Real sDst = Ext.SquareDistance(i);
887         if (sDst<Dstmin) 
888           Dstmin=sDst;
889           }
890       Dstmin = sqrt(Dstmin);
891       if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
892       {
893         Standard_Real Udeb1,Ufin1,Udeb2,Ufin2;
894         BRep_Tool::Range(S1,Udeb1,Ufin1);
895         BRep_Tool::Range(S2,Udeb2,Ufin2);
896
897         gp_Pnt Pt1,Pt2;
898         const Standard_Real epsP=Precision::PConfusion();
899
900         for (i=1;i<=NbExtrema;i++)
901         {
902           if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
903           {
904             Pt1=Ext.PointOnE1(i);
905             Pt2=Ext.PointOnE2(i);
906             if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
907             {
908               // Check if the parameters do not correspond to a vertex
909               const Standard_Real t1 = Ext.ParameterOnE1(i);
910               const Standard_Real t2 = Ext.ParameterOnE2(i);
911               if ((fabs(t1-Udeb1)>=epsP)&&(fabs(t1-Ufin1)>epsP)&&(fabs(t2-Udeb2)>=epsP)&&(fabs(t2-Ufin2)>epsP))
912               {
913                 if (myDstRef > Dstmin)
914                   myDstRef=Dstmin;
915                 myModif=Standard_True;
916                 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsOnEdge,S1,t1);
917                 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsOnEdge,S2,t2);
918                 SeqSolShape1.Append(Sol1);
919                 SeqSolShape2.Append(Sol2);
920               }
921             }
922           }
923         }
924       }
925     }
926
927     BRepExtrema_SeqOfSolution SeqSolution1;
928     BRepExtrema_SeqOfSolution SeqSolution2;
929
930     PERFORM_C0(S1, S2, SeqSolution1, SeqSolution2, DstRef, myDstRef, myEps);
931      
932     BRepExtrema_SeqOfSolution seqSol1;
933     BRepExtrema_SeqOfSolution seqSol2;
934         
935     if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
936       MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
937      
938     if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
939     {
940       SeqSolShape1.Append(seqSol1);
941       SeqSolShape2.Append(seqSol2);     
942       myModif = Standard_True;
943     }
944   }
945 }
946
947 /*********************************************************************************/
948
949 void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Face& S2,
950                                      const Bnd_Box& B1, const Bnd_Box& B2)
951 {
952   if (BRep_Tool::Degenerated(S1))
953     return;
954     
955   const Standard_Real Dst=B1.Distance(B2);
956   if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
957   {
958     BRepClass_FaceClassifier classifier;
959
960     BRepExtrema_ExtCF Ext(S1,S2);
961         const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
962     if ( NbExtrema > 0 )
963     {
964       // Search minimum distance Dstmin
965       Standard_Integer i;
966       Standard_Real Dstmin = Ext.SquareDistance(1);
967       for (i = 2; i <= NbExtrema; i++)
968       {
969         const Standard_Real sDst = Ext.SquareDistance(i);
970         if (sDst<Dstmin) 
971           Dstmin=sDst;
972       }
973       Dstmin = sqrt(Dstmin);
974       if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
975       {
976         Standard_Real Udeb,Ufin,U,V;
977         BRep_Tool::Range(S1,Udeb,Ufin);
978         const Standard_Real tol=BRep_Tool::Tolerance(S2);
979
980         gp_Pnt Pt1,Pt2;
981         const Standard_Real epsP=Precision::PConfusion();
982
983         for (i = 1; i <= NbExtrema; i++)
984         {
985           if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
986           {
987             Pt1=Ext.PointOnEdge(i);
988             Pt2=Ext.PointOnFace(i);
989             if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
990             {
991               // Check if the parameter does not correspond to a vertex
992               const Standard_Real t1 = Ext.ParameterOnEdge(i);
993               if ((fabs(t1-Udeb)>=epsP)&&(fabs(t1-Ufin)>epsP))
994               {
995                 Ext.ParameterOnFace(i,U,V);
996                 const gp_Pnt2d PUV(U,V);
997                 classifier.Perform(S2,PUV,tol);
998                 if (classifier.State()==TopAbs_IN)
999                 {
1000                   if (myDstRef > Dstmin)
1001                     myDstRef=Dstmin;
1002                   myModif=Standard_True;
1003                   const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsOnEdge,S1,t1);
1004                   const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsInFace,S2,U,V);
1005                   SeqSolShape1.Append(Sol1);
1006                   SeqSolShape2.Append(Sol2);              
1007                 }
1008               }
1009             }
1010           }
1011         }
1012       }
1013     }
1014
1015     Standard_Real aFirst, aLast;
1016     Handle(Geom_Curve) pCurv = BRep_Tool::Curve(S1, aFirst, aLast);
1017     if (pCurv->Continuity() == GeomAbs_C0)
1018     {
1019       BRepExtrema_SeqOfSolution SeqSolution1;
1020       BRepExtrema_SeqOfSolution SeqSolution2;
1021
1022       GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
1023       const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
1024
1025       TColStd_Array1OfReal arrInter(1,1+nbIntervals);
1026       aAdaptorCurve.Intervals(arrInter, GeomAbs_C1);
1027
1028       gp_Pnt Pt;
1029       Standard_Real U,V;
1030       const Standard_Real tol = BRep_Tool::Tolerance(S2);
1031
1032       Standard_Integer i;
1033       for (i = 1; i <= arrInter.Length(); i++)
1034       {
1035         const Standard_Real aParameter = arrInter(i);
1036         gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
1037         TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
1038
1039         BRepExtrema_ExtPF ExtPF(V1,S2);
1040         const Standard_Integer NbExtrema = ExtPF.IsDone()? ExtPF.NbExt() : 0;
1041         if ( NbExtrema > 0 )
1042         {
1043           // Search minimum distance Dstmin
1044           Standard_Integer ii;
1045           Standard_Real Dstmin = ExtPF.SquareDistance(1);
1046           for (ii = 2; ii <= NbExtrema; ii++)
1047           {
1048             const Standard_Real sDst = ExtPF.SquareDistance(ii);
1049             if (sDst<Dstmin)
1050               Dstmin=sDst;
1051           }
1052           Dstmin = sqrt(Dstmin);
1053
1054           if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1055           {
1056             for (ii = 1; ii <= NbExtrema; ii++)
1057             { 
1058               if (fabs(Dstmin-sqrt(ExtPF.SquareDistance(ii)))<myEps)
1059               { 
1060                 // Check if the parameter does not correspond to a vertex
1061                 ExtPF.Parameter(ii,U,V);
1062                 const gp_Pnt2d PUV(U,V);
1063                                 classifier.Perform(S2,PUV,tol);
1064                 if (classifier.State()==TopAbs_IN)
1065                 {
1066                   if (myDstRef > Dstmin)
1067                     myDstRef=Dstmin;
1068                   myModif=Standard_True;
1069                   const BRepExtrema_SolutionElem Sol1(Dstmin,aPnt,BRepExtrema_IsOnEdge,S1,aParameter);
1070                   const BRepExtrema_SolutionElem Sol2(Dstmin,ExtPF.Point(ii),BRepExtrema_IsInFace,S2,U,V);
1071                   SeqSolution1.Append(Sol1);
1072                   SeqSolution2.Append(Sol2);
1073                 }
1074               }
1075             }
1076           }
1077         }
1078       }
1079
1080       BRepExtrema_SeqOfSolution seqSol1;
1081       BRepExtrema_SeqOfSolution seqSol2;
1082       Standard_Boolean bIsMini = Standard_False;
1083       if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
1084         MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
1085             
1086       if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
1087       {
1088         SeqSolShape1.Append(seqSol1);
1089         SeqSolShape2.Append(seqSol2);
1090       }
1091     }
1092   }
1093 }
1094
1095 void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Edge& S2,
1096                                      const Bnd_Box& B1, const Bnd_Box& B2)
1097 {
1098   if (BRep_Tool::Degenerated(S2))
1099     return;
1100     
1101   const Standard_Real Dst=B1.Distance(B2);
1102   if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
1103   {
1104     BRepClass_FaceClassifier classifier;
1105
1106     BRepExtrema_ExtCF Ext(S2,S1);
1107         const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
1108     if ( NbExtrema > 0 )
1109     {
1110       // Search minimum distance Dstmin
1111       Standard_Integer i;
1112       Standard_Real Dstmin = Ext.SquareDistance(1);
1113       for (i = 2; i <= NbExtrema; i++)
1114       {
1115         const Standard_Real sDst = Ext.SquareDistance(i);
1116         if (sDst<Dstmin) 
1117           Dstmin=sDst;
1118       }
1119       Dstmin = sqrt(Dstmin);
1120       if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1121       {
1122         Standard_Real Udeb,Ufin,U,V;
1123         BRep_Tool::Range(S2,Udeb,Ufin);
1124         const Standard_Real tol=BRep_Tool::Tolerance(S1);
1125
1126         gp_Pnt Pt1,Pt2;
1127         const Standard_Real epsP=Precision::PConfusion();
1128
1129         for (i = 1; i <= NbExtrema; i++)
1130         {
1131           if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
1132           {
1133             Pt1=Ext.PointOnEdge(i);
1134             Pt2=Ext.PointOnFace(i);
1135             if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
1136             {
1137               // Check if the parameter does not correspond to a vertex
1138               const Standard_Real t1 = Ext.ParameterOnEdge(i);
1139               if ((fabs(t1-Udeb)>=epsP)&&(fabs(t1-Ufin)>epsP))
1140               {
1141                 Ext.ParameterOnFace(i,U,V);
1142                 const gp_Pnt2d PUV(U,V);
1143                 classifier.Perform(S1,PUV,tol);
1144                 if (classifier.State()==TopAbs_IN)
1145                 {
1146                   if (myDstRef > Dstmin)
1147                     myDstRef=Dstmin;
1148                   myModif=Standard_True;
1149                   const BRepExtrema_SolutionElem Sol2(Dstmin,Pt1,BRepExtrema_IsOnEdge,S2,t1);
1150                   const BRepExtrema_SolutionElem Sol1(Dstmin,Pt2,BRepExtrema_IsInFace,S1,U,V);
1151                   SeqSolShape1.Append(Sol1);
1152                   SeqSolShape2.Append(Sol2);              
1153                 }
1154               }
1155             }
1156           }
1157         }
1158       }
1159     }
1160
1161     Standard_Real aFirst, aLast;
1162     Handle(Geom_Curve) pCurv = BRep_Tool::Curve(S2, aFirst, aLast);
1163     if (pCurv->Continuity() == GeomAbs_C0)
1164     {
1165       BRepExtrema_SeqOfSolution SeqSolution1;
1166       BRepExtrema_SeqOfSolution SeqSolution2;
1167
1168       GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
1169       const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
1170
1171       TColStd_Array1OfReal arrInter(1,1+nbIntervals);
1172       aAdaptorCurve.Intervals(arrInter, GeomAbs_C1);
1173
1174       gp_Pnt Pt;
1175       Standard_Real U,V;
1176       const Standard_Real tol = BRep_Tool::Tolerance(S1);
1177
1178       Standard_Integer i;
1179       for (i = 1; i <= arrInter.Length(); i++)
1180       {
1181         const Standard_Real aParameter = arrInter(i);
1182         gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
1183         TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
1184
1185         BRepExtrema_ExtPF ExtPF(V1,S1);
1186         const Standard_Integer NbExtrema = ExtPF.IsDone()? ExtPF.NbExt() : 0;
1187         if ( NbExtrema > 0 )
1188         {
1189           // Search minimum distance Dstmin
1190           Standard_Integer ii;
1191           Standard_Real Dstmin = ExtPF.SquareDistance(1);
1192           for (ii = 2; ii <= NbExtrema; ii++)
1193           {
1194             const Standard_Real sDst = ExtPF.SquareDistance(ii);
1195             if (sDst<Dstmin)
1196               Dstmin=sDst;
1197           }
1198           Dstmin = sqrt(Dstmin);
1199
1200           if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1201           {
1202             for (ii = 1; ii <= NbExtrema; ii++)
1203             { 
1204               if (fabs(Dstmin-sqrt(ExtPF.SquareDistance(ii)))<myEps)
1205               { 
1206                 // Check if the parameter does not correspond to a vertex
1207                 ExtPF.Parameter(ii,U,V);
1208                 const gp_Pnt2d PUV(U,V);
1209                                 classifier.Perform(S1,PUV,tol);
1210                 if (classifier.State()==TopAbs_IN)
1211                 {
1212                   if (myDstRef > Dstmin)
1213                     myDstRef=Dstmin;
1214                   myModif=Standard_True;
1215                   const BRepExtrema_SolutionElem Sol2(Dstmin,aPnt,BRepExtrema_IsOnEdge,S2,aParameter);
1216                   const BRepExtrema_SolutionElem Sol1(Dstmin,ExtPF.Point(ii),BRepExtrema_IsInFace,S1,U,V);
1217                   SeqSolution1.Append(Sol1);
1218                   SeqSolution2.Append(Sol2);
1219                 }
1220               }
1221             }
1222           }
1223         }
1224       }
1225
1226       BRepExtrema_SeqOfSolution seqSol1;
1227       BRepExtrema_SeqOfSolution seqSol2;
1228       Standard_Boolean bIsMini = Standard_False;
1229       if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
1230         MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
1231             
1232       if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
1233       {
1234         SeqSolShape1.Append(seqSol1);
1235         SeqSolShape2.Append(seqSol2);
1236       }
1237     }
1238   }
1239 }
1240
1241 /*********************************************************************************/
1242
1243 void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Face& S2,
1244                                      const Bnd_Box& B1, const Bnd_Box& B2)
1245 {
1246   const Standard_Real Dst=B1.Distance(B2);
1247   if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
1248   { 
1249     BRepExtrema_ExtFF Ext(S1,S2);
1250         const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
1251     if ( NbExtrema > 0 )
1252     {
1253       // Search minimum distance Dstmin
1254       Standard_Integer i;
1255       Standard_Real Dstmin = Ext.SquareDistance(1);
1256       for (i = 2; i <= NbExtrema; i++)
1257       {
1258         const Standard_Real sDst = Ext.SquareDistance(i);
1259         if (sDst<Dstmin)
1260           Dstmin=sDst;
1261       }
1262       Dstmin = sqrt(Dstmin);
1263       if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1264       {
1265         const Standard_Real tol1=BRep_Tool::Tolerance(S1);
1266         const Standard_Real tol2=BRep_Tool::Tolerance(S2);
1267
1268         gp_Pnt Pt1,Pt2;
1269         gp_Pnt2d PUV;
1270         Standard_Real U1,V1,U2,V2;
1271         BRepClass_FaceClassifier classifier;
1272         const Standard_Real epsP=Precision::PConfusion();
1273  
1274         for (i = 1; i <= NbExtrema; i++)
1275         {
1276           if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
1277           {
1278             Pt1=Ext.PointOnFace1(i);
1279             Pt2=Ext.PointOnFace2(i); 
1280             if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
1281             {
1282               // Check if the parameter does not correspond to a vertex
1283               Ext.ParameterOnFace1(i,U1,V1);
1284               PUV.SetCoord(U1,V1);
1285               classifier.Perform(S1,PUV,tol1);
1286               if (classifier.State()==TopAbs_IN)
1287               {
1288                 Ext.ParameterOnFace2(i,U2,V2);
1289                 PUV.SetCoord(U2,V2);
1290                 classifier.Perform(S2,PUV,tol2);
1291                 if (classifier.State()==TopAbs_IN)
1292                 {
1293                   if (myDstRef > Dstmin)
1294                     myDstRef=Dstmin;
1295                   myModif=Standard_True;
1296                   const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsInFace,S1,U1,V1);
1297                   const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsInFace,S2,U2,V2);
1298                   SeqSolShape1.Append(Sol1);
1299                   SeqSolShape2.Append(Sol2);
1300                 }
1301               }
1302             }
1303           }
1304         }
1305       }
1306     }
1307   }
1308 }
1309
1310 /*********************************************************************************/