0032552: Modeling Algorithms - BRepExtrema_DistShapeShape algorithm consumes too...
[occt.git] / src / BRepExtrema / BRepExtrema_DistShapeShape.cxx
1 // Created on: 1996-04-22
2 // Created by: Herve LOUESSARD
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 // Modified: Mps(10-04-97) portage WNT
18
19 #include <BRepExtrema_DistShapeShape.hxx>
20
21 #include <Standard_OStream.hxx>
22 #include <TopTools_IndexedMapOfShape.hxx>
23 #include <BRepBndLib.hxx>
24 #include <Bnd_Box.hxx>
25 #include <TopExp.hxx>
26 #include <BRepExtrema_DistanceSS.hxx>
27 #include <TopoDS.hxx>
28 #include <TopAbs.hxx>
29 #include <TopoDS_Vertex.hxx>
30 #include <TopoDS_Edge.hxx>
31 #include <TopoDS_Face.hxx>
32 #include <TopAbs_ShapeEnum.hxx>
33 #include <Precision.hxx>
34 #include <Bnd_SeqOfBox.hxx>
35 #include <BRepExtrema_UnCompatibleShape.hxx>
36 #include <BRep_Tool.hxx>
37 #include <BRepClass3d_SolidClassifier.hxx>
38 #include <NCollection_Vector.hxx>
39 #include <StdFail_NotDone.hxx>
40
41 #include <algorithm>
42 namespace
43 {
44
45   static void Decomposition(const TopoDS_Shape&         S,
46                             TopTools_IndexedMapOfShape& MapV,
47                             TopTools_IndexedMapOfShape& MapE,
48                             TopTools_IndexedMapOfShape& MapF)
49   {
50     MapV.Clear();
51     MapE.Clear();
52     MapF.Clear();
53     TopExp::MapShapes(S,TopAbs_VERTEX,MapV);
54     TopExp::MapShapes(S,TopAbs_EDGE,MapE);
55     TopExp::MapShapes(S,TopAbs_FACE,MapF);
56   }
57
58   static void BoxCalculation(const TopTools_IndexedMapOfShape& Map,
59                              Bnd_SeqOfBox&                     SBox)
60   {
61     for (Standard_Integer i = 1; i <= Map.Extent(); i++)
62     {
63       Bnd_Box box;
64       BRepBndLib::Add(Map(i), box);
65       SBox.Append(box);
66     }
67   }
68
69   inline Standard_Real DistanceInitiale(const TopoDS_Vertex V1,
70                                         const TopoDS_Vertex V2)
71   {
72     return (BRep_Tool::Pnt(V1).Distance(BRep_Tool::Pnt(V2)));
73   }
74
75   //! Pair of objects to check extrema.
76   struct BRepExtrema_CheckPair
77   {
78     Standard_Integer Index1;   //!< Index of the 1st sub-shape
79     Standard_Integer Index2;   //!< Index of the 2nd sub-shape
80     Standard_Real    Distance; //!< Distance between sub-shapes
81
82     //! Uninitialized constructor for collection.
83     BRepExtrema_CheckPair()
84     : Index1(0),
85       Index2(0),
86       Distance(0.0)
87     {
88     }
89
90     //! Creates new pair of sub-shapes.
91     BRepExtrema_CheckPair (Standard_Integer theIndex1,
92                            Standard_Integer theIndex2,
93                            Standard_Real    theDistance)
94     : Index1   (theIndex1),
95       Index2   (theIndex2),
96       Distance (theDistance) {}
97   };
98
99   // Used by std::sort function
100   static Standard_Boolean BRepExtrema_CheckPair_Comparator (const BRepExtrema_CheckPair& theLeft,
101                                                             const BRepExtrema_CheckPair& theRight)
102   {
103     return (theLeft.Distance < theRight.Distance);
104   }
105 }
106
107 //=======================================================================
108 //function : DistanceMapMap
109 //purpose  : 
110 //=======================================================================
111
112 Standard_Boolean BRepExtrema_DistShapeShape::DistanceMapMap (const TopTools_IndexedMapOfShape& theMap1,
113                                                              const TopTools_IndexedMapOfShape& theMap2,
114                                                              const Bnd_SeqOfBox&               theLBox1,
115                                                              const Bnd_SeqOfBox&               theLBox2,
116                                                              const Message_ProgressRange&      theRange)
117 {
118   NCollection_Vector<BRepExtrema_CheckPair> aPairList;
119   const Standard_Integer aCount1 = theMap1.Extent();
120   const Standard_Integer aCount2 = theMap2.Extent();
121
122   Message_ProgressScope aTwinScope(theRange, NULL, 1.0);
123   Message_ProgressRange aBoxRange(aTwinScope.Next(0.3));
124   Message_ProgressScope aBoxScope(aBoxRange, NULL, aCount1);
125
126   for (Standard_Integer anIdx1 = 1; anIdx1 <= aCount1; ++anIdx1)
127   {
128     aBoxScope.Next();
129     if (!aBoxScope.More())
130     {
131       return Standard_False;
132     }
133     for (Standard_Integer anIdx2 = 1; anIdx2 <= aCount2; ++anIdx2)
134     {
135       const Bnd_Box& aBox1 = theLBox1.Value (anIdx1);
136       const Bnd_Box& aBox2 = theLBox2.Value (anIdx2);
137       if (aBox1.IsVoid()
138        || aBox2.IsVoid())
139       {
140         continue;
141       }
142
143       const Standard_Real aDist = aBox1.Distance (aBox2);
144       if (aDist < myDistRef - myEps || fabs (aDist - myDistRef) < myEps)
145       {
146         aPairList.Append (BRepExtrema_CheckPair (anIdx1, anIdx2, aDist));
147       }
148     }
149   }
150   std::stable_sort(aPairList.begin(), aPairList.end(), BRepExtrema_CheckPair_Comparator);
151   Message_ProgressRange aDistRange(aTwinScope.Next(0.7));
152   Message_ProgressScope aDistScope(aDistRange, NULL, aPairList.Size());
153   for (NCollection_Vector<BRepExtrema_CheckPair>::Iterator aPairIter (aPairList);
154        aPairIter.More(); aPairIter.Next())
155   {
156     aDistScope.Next();
157     if (!aDistScope.More())
158     {
159       return Standard_False;
160     }
161     const BRepExtrema_CheckPair& aPair = aPairIter.Value();
162     if (aPair.Distance > myDistRef + myEps)
163     {
164       break; // early search termination
165     }
166
167     const Bnd_Box& aBox1 = theLBox1.Value (aPair.Index1);
168     const Bnd_Box& aBox2 = theLBox2.Value (aPair.Index2);
169
170     const TopoDS_Shape& aShape1 = theMap1 (aPair.Index1);
171     const TopoDS_Shape& aShape2 = theMap2 (aPair.Index2);
172
173     BRepExtrema_DistanceSS aDistTool (aShape1, aShape2, aBox1, aBox2, myDistRef, myEps);
174     if (aDistTool.IsDone())
175     {
176       if (aDistTool.DistValue() < myDistRef - myEps)
177       {
178         mySolutionsShape1.Clear();
179         mySolutionsShape2.Clear();
180
181         BRepExtrema_SeqOfSolution aSeq1 = aDistTool.Seq1Value();
182         BRepExtrema_SeqOfSolution aSeq2 = aDistTool.Seq2Value();
183
184         mySolutionsShape1.Append (aSeq1);
185         mySolutionsShape2.Append (aSeq2);
186
187         myDistRef = aDistTool.DistValue();
188       }
189       else if (fabs (aDistTool.DistValue() - myDistRef) < myEps)
190       {
191         BRepExtrema_SeqOfSolution aSeq1 = aDistTool.Seq1Value();
192         BRepExtrema_SeqOfSolution aSeq2 = aDistTool.Seq2Value();
193
194         mySolutionsShape1.Append (aSeq1);
195         mySolutionsShape2.Append (aSeq2);
196
197         if (myDistRef > aDistTool.DistValue())
198         {
199           myDistRef = aDistTool.DistValue();
200         }
201       }
202     }
203   }
204   return Standard_True;
205 }
206
207 //=======================================================================
208 //function : DistanceVertVert
209 //purpose  : 
210 //=======================================================================
211
212 Standard_Boolean BRepExtrema_DistShapeShape::DistanceVertVert(const TopTools_IndexedMapOfShape& theMap1,
213                                                               const TopTools_IndexedMapOfShape& theMap2,
214                                                               const Message_ProgressRange& theRange)
215 {
216   const Standard_Integer aCount1 = theMap1.Extent();
217   const Standard_Integer aCount2 = theMap2.Extent();
218
219   Message_ProgressScope aScope(theRange, NULL, aCount1);
220
221   for (Standard_Integer anIdx1 = 1; anIdx1 <= aCount1; ++anIdx1)
222   {
223     aScope.Next();
224     if (!aScope.More())
225     {
226       return Standard_False;
227     }
228     const TopoDS_Vertex& aVertex1 = TopoDS::Vertex(theMap1.FindKey(anIdx1));
229     const gp_Pnt aPoint1 = BRep_Tool::Pnt(aVertex1);
230     for (Standard_Integer anIdx2 = 1; anIdx2 <= aCount2; ++anIdx2)
231     {
232       const TopoDS_Vertex& aVertex2 = TopoDS::Vertex(theMap2.FindKey(anIdx2));
233       const gp_Pnt aPoint2 = BRep_Tool::Pnt(aVertex2);
234
235       const Standard_Real aDist = aPoint1.Distance(aPoint2);
236       if (aDist < myDistRef - myEps)
237       {
238         mySolutionsShape1.Clear();
239         mySolutionsShape2.Clear();
240
241         const BRepExtrema_SolutionElem Sol1(aDist, aPoint1, BRepExtrema_IsVertex, aVertex1);
242         const BRepExtrema_SolutionElem Sol2(aDist, aPoint2, BRepExtrema_IsVertex, aVertex2);
243         mySolutionsShape1.Append(Sol1);
244         mySolutionsShape2.Append(Sol2);
245
246         myDistRef = aDist;
247       }
248       else if (fabs(aDist - myDistRef) < myEps)
249       {
250         const BRepExtrema_SolutionElem Sol1(aDist, aPoint1, BRepExtrema_IsVertex, aVertex1);
251         const BRepExtrema_SolutionElem Sol2(aDist, aPoint2, BRepExtrema_IsVertex, aVertex2);
252         mySolutionsShape1.Append(Sol1);
253         mySolutionsShape2.Append(Sol2);
254
255         if (myDistRef > aDist)
256         {
257           myDistRef = aDist;
258         }
259       }
260     }
261   }
262   return Standard_True;
263 }
264
265 //=======================================================================
266 //function : BRepExtrema_DistShapeShape
267 //purpose  : 
268 //=======================================================================
269
270 BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape()
271 : myDistRef (0.0),
272   myIsDone (Standard_False),
273   myInnerSol (Standard_False),
274   myEps (Precision::Confusion()),
275   myIsInitS1 (Standard_False),
276   myIsInitS2 (Standard_False),
277   myFlag (Extrema_ExtFlag_MINMAX),
278   myAlgo (Extrema_ExtAlgo_Grad)
279 {
280   //
281 }
282
283 //=======================================================================
284 //function : BRepExtrema_DistShapeShape
285 //purpose  : 
286 //=======================================================================
287 BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape(const TopoDS_Shape& Shape1,
288                                                        const TopoDS_Shape& Shape2,
289                                                        const Extrema_ExtFlag F,
290                                                        const Extrema_ExtAlgo A,
291                                                        const Message_ProgressRange& theRange)
292 : myDistRef (0.0),
293   myIsDone (Standard_False),
294   myInnerSol (Standard_False),
295   myEps (Precision::Confusion()),
296   myIsInitS1 (Standard_False),
297   myIsInitS2 (Standard_False),
298   myFlag (F),
299   myAlgo (A)
300 {
301   LoadS1(Shape1);
302   LoadS2(Shape2);
303   Perform(theRange);
304 }
305
306 //=======================================================================
307 //function : BRepExtrema_DistShapeShape
308 //purpose  : 
309 //=======================================================================
310
311 BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape(const TopoDS_Shape& Shape1,
312                                                        const TopoDS_Shape& Shape2,
313                                                        const Standard_Real theDeflection,
314                                                        const Extrema_ExtFlag F,
315                                                        const Extrema_ExtAlgo A,
316                                                        const Message_ProgressRange& theRange)
317 : myDistRef (0.0),
318   myIsDone (Standard_False),
319   myInnerSol (Standard_False),
320   myEps (theDeflection),
321   myIsInitS1 (Standard_False),
322   myIsInitS2 (Standard_False),
323   myFlag (F),
324   myAlgo (A)
325 {
326   LoadS1(Shape1);
327   LoadS2(Shape2);
328   Perform(theRange);
329 }
330
331 //=======================================================================
332 //function : LoadS1
333 //purpose  : 
334 //=======================================================================
335
336 void BRepExtrema_DistShapeShape::LoadS1 (const TopoDS_Shape& Shape1)
337 {
338   myShape1 = Shape1;
339   myIsInitS1 = Standard_False;
340   Decomposition (Shape1, myMapV1, myMapE1, myMapF1);
341 }
342
343 //=======================================================================
344 //function : LoadS2
345 //purpose  : 
346 //=======================================================================
347
348 void BRepExtrema_DistShapeShape::LoadS2 (const TopoDS_Shape& Shape2)
349 {
350   myShape2 = Shape2;
351   myIsInitS2 = Standard_False;
352   Decomposition (Shape2, myMapV2, myMapE2, myMapF2);
353 }
354
355 //=======================================================================
356 //function : SolidTreatment
357 //purpose  : 
358 //=======================================================================
359 Standard_Boolean BRepExtrema_DistShapeShape::SolidTreatment(const TopoDS_Shape& theShape,
360                                                             const TopTools_IndexedMapOfShape& theMap,
361                                                             const Message_ProgressRange& theRange)
362 {
363   BRepClass3d_SolidClassifier aClassifier(theShape);
364   const Standard_Real aTolerance = 0.001;
365   Message_ProgressScope aScope(theRange, NULL, theMap.Extent());
366   for (Standard_Integer i = 1; i < theMap.Extent(); ++i)
367   {
368     aScope.Next();
369     if (!aScope.More())
370     {
371       return Standard_False;
372     }
373     const TopoDS_Vertex& aVertex = TopoDS::Vertex(theMap(i));
374     const gp_Pnt& aPnt = BRep_Tool::Pnt(aVertex);
375     aClassifier.Perform(aPnt, aTolerance);
376     if (aClassifier.State() == TopAbs_IN)
377     {
378       myInnerSol = Standard_True;
379       myDistRef = 0.;
380       myIsDone = Standard_True;
381       BRepExtrema_SolutionElem Sol(0, aPnt, BRepExtrema_IsVertex, aVertex);
382       mySolutionsShape1.Append(Sol);
383       mySolutionsShape2.Append(Sol);
384       break;
385     }
386   }
387   return Standard_True;
388 }
389
390 //=======================================================================
391 //function : Perform
392 //purpose  : 
393 //=======================================================================
394
395 Standard_Boolean BRepExtrema_DistShapeShape::Perform(const Message_ProgressRange& theRange)
396 {
397   myIsDone=Standard_False;
398   myInnerSol=Standard_False;
399   mySolutionsShape1.Clear();
400   mySolutionsShape2.Clear();
401
402   if ( myShape1.IsNull() || myShape2.IsNull() )
403     return Standard_False;
404
405   // Treatment of solids
406   Standard_Boolean anIsSolid1 = (myShape1.ShapeType() == TopAbs_SOLID) ||
407                                 (myShape1.ShapeType() == TopAbs_COMPSOLID);
408   Standard_Boolean anIsSolid2 = (myShape2.ShapeType() == TopAbs_SOLID) ||
409                                 (myShape2.ShapeType() == TopAbs_COMPSOLID);
410   Standard_Integer aRootStepsNum = 9; // By num of DistanceMapMap calls
411   aRootStepsNum = anIsSolid1 ? aRootStepsNum+1 : aRootStepsNum;
412   aRootStepsNum = anIsSolid2 ? aRootStepsNum+1 : aRootStepsNum;
413   Message_ProgressScope aRootScope(theRange, "calculating distance", aRootStepsNum);
414
415   if (anIsSolid1)
416   {
417     if (!SolidTreatment(myShape1, myMapV2, aRootScope.Next()))
418     {
419       return Standard_False;
420     }
421   }
422   
423   if (anIsSolid2 && (!myInnerSol))
424   {
425     if(!SolidTreatment(myShape2, myMapV1, aRootScope.Next()))
426     {
427       return Standard_False;
428     }
429   }
430
431   if (!myInnerSol)
432   {
433     if (!myIsInitS1) // rebuild cached data for 1st shape
434     {
435       myBV1.Clear();
436       myBE1.Clear();
437       myBF1.Clear();
438
439       BoxCalculation (myMapV1, myBV1);
440       BoxCalculation (myMapE1, myBE1);
441       BoxCalculation (myMapF1, myBF1);
442
443       myIsInitS1 = Standard_True;
444     }
445
446     if (!myIsInitS2) // rebuild cached data for 2nd shape
447     {
448       myBV2.Clear();
449       myBE2.Clear();
450       myBF2.Clear();
451
452       BoxCalculation (myMapV2, myBV2);
453       BoxCalculation (myMapE2, myBE2);
454       BoxCalculation (myMapF2, myBF2);
455
456       myIsInitS2 = Standard_True;
457     }
458
459     if (myMapV1.Extent() && myMapV2.Extent())
460     {
461       TopoDS_Vertex V1 = TopoDS::Vertex(myMapV1(1));
462       TopoDS_Vertex V2 = TopoDS::Vertex(myMapV2(1));
463       myDistRef = DistanceInitiale(V1, V2);
464     }
465     else
466       myDistRef= 1.e30; //szv:!!!
467
468     if(!DistanceVertVert(myMapV1, myMapV2, aRootScope.Next()))
469     {
470       return Standard_False;
471     }
472     if(!DistanceMapMap (myMapV1, myMapE2, myBV1, myBE2, aRootScope.Next()))
473     {
474       return Standard_False;
475     }
476     if(!DistanceMapMap (myMapE1, myMapV2, myBE1, myBV2, aRootScope.Next()))
477     {
478       return Standard_False;
479     }
480     if(!DistanceMapMap (myMapV1, myMapF2, myBV1, myBF2, aRootScope.Next()))
481     {
482       return Standard_False;
483     }
484     if(!DistanceMapMap (myMapF1, myMapV2, myBF1, myBV2, aRootScope.Next()))
485     {
486       return Standard_False;
487     }
488     if(!DistanceMapMap (myMapE1, myMapE2, myBE1, myBE2, aRootScope.Next()))
489     {
490       return Standard_False;
491     }
492     if(!DistanceMapMap (myMapE1, myMapF2, myBE1, myBF2, aRootScope.Next()))
493     {
494       return Standard_False;
495     }
496     if(!DistanceMapMap (myMapF1, myMapE2, myBF1, myBE2, aRootScope.Next()))
497     {
498       return Standard_False;
499     }
500
501     if (fabs (myDistRef) > myEps)
502     {
503       if(!DistanceMapMap (myMapF1, myMapF2, myBF1, myBF2, aRootScope.Next()))
504       {
505         return Standard_False;
506       }
507     }
508     
509     //  Modified by Sergey KHROMOV - Tue Mar  6 11:55:03 2001 Begin
510     Standard_Integer i = 1;
511     for (; i <= mySolutionsShape1.Length(); i++)
512       if (mySolutionsShape1.Value(i).Dist() > myDistRef + myEps)
513       {
514         mySolutionsShape1.Remove(i);
515         mySolutionsShape2.Remove(i);
516       }
517     //  Modified by Sergey KHROMOV - Tue Mar  6 11:55:04 2001 End
518     myIsDone = ( mySolutionsShape1.Length() > 0 );
519   }
520
521   return myIsDone;
522 }
523
524 //=======================================================================
525 //function : Value
526 //purpose  : 
527 //=======================================================================
528
529 Standard_Real BRepExtrema_DistShapeShape::Value() const 
530
531   if (!myIsDone)
532     throw StdFail_NotDone("BRepExtrema_DistShapeShape::Value: There's no solution ");
533
534   return myDistRef;
535 }
536
537 //=======================================================================
538 //function : SupportOnShape1
539 //purpose  : 
540 //=======================================================================
541
542 TopoDS_Shape BRepExtrema_DistShapeShape::SupportOnShape1(const Standard_Integer N) const
543
544   if (!myIsDone)
545     throw StdFail_NotDone("BRepExtrema_DistShapeShape::SupportOnShape1: There's no solution ");
546
547   const BRepExtrema_SolutionElem &sol = mySolutionsShape1.Value(N);
548   switch (sol.SupportKind())
549   {
550     case BRepExtrema_IsVertex : return sol.Vertex();
551     case BRepExtrema_IsOnEdge : return sol.Edge();
552     case BRepExtrema_IsInFace : return sol.Face();
553   }
554   return TopoDS_Shape();
555 }
556
557 //=======================================================================
558 //function : SupportOnShape2
559 //purpose  : 
560 //=======================================================================
561
562 TopoDS_Shape BRepExtrema_DistShapeShape::SupportOnShape2(const Standard_Integer N) const 
563
564   if (!myIsDone)
565     throw StdFail_NotDone("BRepExtrema_DistShapeShape::SupportOnShape2: There's no solution ");
566
567   const BRepExtrema_SolutionElem &sol = mySolutionsShape2.Value(N);
568   switch (sol.SupportKind())
569   {
570     case BRepExtrema_IsVertex : return sol.Vertex();
571     case BRepExtrema_IsOnEdge : return sol.Edge();
572     case BRepExtrema_IsInFace : return sol.Face();
573   }
574   return TopoDS_Shape();
575 }
576
577 //=======================================================================
578 //function : ParOnEdgeS1
579 //purpose  : 
580 //=======================================================================
581
582 void BRepExtrema_DistShapeShape::ParOnEdgeS1(const Standard_Integer N, Standard_Real& t) const 
583
584   if (!myIsDone)
585     throw StdFail_NotDone("BRepExtrema_DistShapeShape::ParOnEdgeS1: There's no solution");
586
587   const BRepExtrema_SolutionElem &sol = mySolutionsShape1.Value(N);
588   if (sol.SupportKind() != BRepExtrema_IsOnEdge)
589     throw BRepExtrema_UnCompatibleShape("BRepExtrema_DistShapeShape::ParOnEdgeS1: ParOnEdgeS1 is impossible without EDGE");
590
591   sol.EdgeParameter(t);
592 }
593
594 //=======================================================================
595 //function : ParOnEdgeS2
596 //purpose  : 
597 //=======================================================================
598
599 void BRepExtrema_DistShapeShape::ParOnEdgeS2(const Standard_Integer N,  Standard_Real& t) const 
600
601   if (!myIsDone)
602     throw StdFail_NotDone("BRepExtrema_DistShapeShape::ParOnEdgeS2: There's no solution");
603
604   const BRepExtrema_SolutionElem &sol = mySolutionsShape2.Value(N);
605   if (sol.SupportKind() != BRepExtrema_IsOnEdge)
606     throw BRepExtrema_UnCompatibleShape("BRepExtrema_DistShapeShape::ParOnEdgeS2: ParOnEdgeS2 is impossible without EDGE");
607  
608   sol.EdgeParameter(t);
609 }
610
611 //=======================================================================
612 //function : ParOnFaceS1
613 //purpose  : 
614 //=======================================================================
615
616 void BRepExtrema_DistShapeShape::ParOnFaceS1(const Standard_Integer N,  Standard_Real& u,  Standard_Real& v) const 
617
618   if (!myIsDone)
619     throw StdFail_NotDone("BRepExtrema_DistShapeShape::ParOnFaceS1: There's no solution");
620
621   const BRepExtrema_SolutionElem &sol = mySolutionsShape1.Value(N);
622   if (sol.SupportKind() != BRepExtrema_IsInFace)
623     throw BRepExtrema_UnCompatibleShape("BRepExtrema_DistShapeShape::ParOnFaceS1: ParOnFaceS1 is impossible without FACE");
624   
625   sol.FaceParameter(u, v);
626 }
627
628 //=======================================================================
629 //function : ParOnFaceS2
630 //purpose  : 
631 //=======================================================================
632
633 void BRepExtrema_DistShapeShape::ParOnFaceS2(const Standard_Integer N,  Standard_Real& u, Standard_Real& v) const 
634
635   if (!myIsDone)
636     throw StdFail_NotDone("BRepExtrema_DistShapeShape::ParOnFaceS2: There's no solution");
637
638   const BRepExtrema_SolutionElem &sol = mySolutionsShape2.Value(N);
639   if (sol.SupportKind() != BRepExtrema_IsInFace)
640     throw BRepExtrema_UnCompatibleShape("BRepExtrema_DistShapeShape::ParOnFaceS2:ParOnFaceS2 is impossible without FACE ");
641   
642   sol.FaceParameter(u, v);
643 }
644
645 //=======================================================================
646 //function : Dump
647 //purpose  : 
648 //=======================================================================
649
650 void BRepExtrema_DistShapeShape::Dump(Standard_OStream& o) const 
651 {
652   Standard_Integer i;
653   Standard_Real r1,r2;
654   
655   o<< "the distance  value is :  " << Value()<<std::endl;
656   o<< "the number of solutions is :"<<NbSolution()<<std::endl;
657   o<<std::endl;
658   for (i=1;i<=NbSolution();i++)
659   {
660     o<<"solution number "<<i<<": "<< std::endl;
661     o<<"the type of the solution on the first shape is " <<Standard_Integer( SupportTypeShape1(i)) <<std::endl; 
662     o<<"the type of the solution on the second shape is "<<Standard_Integer( SupportTypeShape2(i))<< std::endl;
663     o<< "the coordinates of  the point on the first shape are: "<<std::endl; 
664     o<<"X=" <<PointOnShape1(i).X()<<" Y=" <<PointOnShape1(i).Y()<<" Z="<<PointOnShape1(i).Z()<<std::endl;
665     o<< "the coordinates of  the point on the second shape are: "<<std::endl; 
666     o<<"X="<< PointOnShape2(i).X()<< " Y="<<PointOnShape2(i).Y()<<" Z="<< PointOnShape2(i).Z()<<std::endl;
667     
668     switch (SupportTypeShape1(i))
669     {
670       case BRepExtrema_IsVertex:
671         break;
672       case BRepExtrema_IsOnEdge:
673         ParOnEdgeS1(i,r1);
674         o << "parameter on the first edge :  t= " << r1 << std::endl;
675         break;
676       case BRepExtrema_IsInFace:
677         ParOnFaceS1(i,r1,r2);
678         o << "parameters on the first face :  u= " << r1 << " v=" <<  r2 << std::endl;
679         break;
680     }
681     switch (SupportTypeShape2(i))
682     {
683       case BRepExtrema_IsVertex:
684         break;
685       case BRepExtrema_IsOnEdge:
686         ParOnEdgeS2(i,r1);
687         o << "parameter on the second edge : t=" << r1 << std::endl;
688         break;
689       case BRepExtrema_IsInFace:
690         ParOnFaceS2(i,r1,r2);
691         o << "parameters on the second face : u= " << r1 << " v=" <<  r2 << std::endl;
692         break;
693     }
694     o<<std::endl;
695   } 
696 }