0024180: Eliminate CLang / GCC compiler warning -Wswitch
[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-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21 // Modified: Mps(10-04-97) portage WNT
22
23 #include <BRepExtrema_DistShapeShape.hxx>
24
25 #include <Standard_OStream.hxx>
26 #include <TopTools_IndexedMapOfShape.hxx>
27 #include <BRepBndLib.hxx>
28 #include <Bnd_Box.hxx>
29 #include <TopExp.hxx>
30 #include <BRepExtrema_DistanceSS.hxx>
31 #include <TopoDS.hxx>
32 #include <TopAbs.hxx>
33 #include <TopoDS_Vertex.hxx>
34 #include <TopoDS_Edge.hxx>
35 #include <TopoDS_Face.hxx>
36 #include <TopAbs_ShapeEnum.hxx>
37 #include <Precision.hxx>
38 #include <Bnd_SeqOfBox.hxx>
39 #include <BRepExtrema_UnCompatibleShape.hxx>
40 #include <BRep_Tool.hxx>
41 #include <BRepClass3d_SolidClassifier.hxx>
42 #include <StdFail_NotDone.hxx>
43
44 static void Decomposition(const TopoDS_Shape&         S,
45                           TopTools_IndexedMapOfShape& MapV,
46                           TopTools_IndexedMapOfShape& MapE,
47                           TopTools_IndexedMapOfShape& MapF)
48 {
49   MapV.Clear();
50   MapE.Clear();
51   MapF.Clear();
52   TopExp::MapShapes(S,TopAbs_VERTEX,MapV);
53   TopExp::MapShapes(S,TopAbs_EDGE,MapE);
54   TopExp::MapShapes(S,TopAbs_FACE,MapF);
55 }
56
57 static void BoxCalculation(const TopTools_IndexedMapOfShape& Map,
58                            Bnd_SeqOfBox&                     SBox)
59
60   for (Standard_Integer i = 1; i <= Map.Extent(); i++)
61   {
62     Bnd_Box box;
63     BRepBndLib::Add(Map(i), box);
64     SBox.Append(box);
65   }
66 }
67
68 inline Standard_Real DistanceInitiale(const TopoDS_Vertex V1,
69                                       const TopoDS_Vertex V2)
70 {
71   return (BRep_Tool::Pnt(V1).Distance(BRep_Tool::Pnt(V2)));
72
73
74 //=======================================================================
75 //function : DistanceMapMap
76 //purpose  : 
77 //=======================================================================
78
79 void BRepExtrema_DistShapeShape::DistanceMapMap(const TopTools_IndexedMapOfShape& Map1,
80                                                 const TopTools_IndexedMapOfShape& Map2,
81                                                 const Bnd_SeqOfBox&               LBox1,
82                                                 const Bnd_SeqOfBox&               LBox2)
83 {
84   Standard_Integer i, j;
85   BRepExtrema_SeqOfSolution seq1, seq2;
86
87   const Standard_Integer n1 = Map1.Extent();
88   const Standard_Integer n2 = Map2.Extent();
89   for (i = 1; i <= n1; i++)
90   {
91     const Bnd_Box &box1 = LBox1.Value(i);
92     const TopoDS_Shape &S1 = Map1(i);
93     for (j = 1; j <= n2; j++)
94     {
95       const Bnd_Box &box2= LBox2.Value(j);
96       const TopoDS_Shape &S2 = Map2(j);
97
98       BRepExtrema_DistanceSS  dist(S1,S2,box1,box2,myDistRef,myEps);
99       if (dist.IsDone()) {
100         if(dist.DistValue() < (myDistRef-myEps))
101         {
102           mySolutionsShape1.Clear();
103           mySolutionsShape2.Clear();
104           seq1= dist.Seq1Value();
105           seq2= dist.Seq2Value();
106           mySolutionsShape1.Append(seq1);
107           mySolutionsShape2.Append(seq2);
108           myDistRef=dist.DistValue();
109         }
110         else if(fabs(dist.DistValue()-myDistRef) < myEps)
111         {
112           seq1= dist.Seq1Value();
113           seq2= dist.Seq2Value();
114           mySolutionsShape1.Append(seq1);
115           mySolutionsShape2.Append(seq2);
116           if (myDistRef > dist.DistValue())
117             myDistRef=dist.DistValue();
118         }
119       }
120     }
121   }
122 }
123
124 //=======================================================================
125 //function : BRepExtrema_DistShapeShape
126 //purpose  : 
127 //=======================================================================
128
129 BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape()
130 : myDistRef(0.),
131   myIsDone(Standard_False),
132   myInnerSol(Standard_False),
133   myEps(Precision::Confusion()),
134   myFlag(Extrema_ExtFlag_MINMAX),
135   myAlgo(Extrema_ExtAlgo_Grad)
136 {
137 }
138
139 //=======================================================================
140 //function : BRepExtrema_DistShapeShape
141 //purpose  : 
142 //=======================================================================
143 BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape(const TopoDS_Shape& Shape1,
144                                                        const TopoDS_Shape& Shape2,
145                                                        const Extrema_ExtFlag F,
146                                                        const Extrema_ExtAlgo A)
147 : myDistRef(0.),
148   myIsDone(Standard_False),
149   myInnerSol(Standard_False),
150   myEps(Precision::Confusion()),
151   myFlag(F),
152   myAlgo(A)
153 {
154   LoadS1(Shape1);
155   LoadS2(Shape2);
156   Perform();
157 }
158
159 //=======================================================================
160 //function : BRepExtrema_DistShapeShape
161 //purpose  : 
162 //=======================================================================
163
164 BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape(const TopoDS_Shape& Shape1,
165                                                        const TopoDS_Shape& Shape2,
166                                                        const Standard_Real theDeflection,
167                                                        const Extrema_ExtFlag F,
168                                                        const Extrema_ExtAlgo A)
169 : myDistRef(0.),
170   myIsDone(Standard_False),
171   myInnerSol(Standard_False),
172   myEps(theDeflection),
173   myFlag(F),
174   myAlgo(A)
175 {
176   LoadS1(Shape1);
177   LoadS2(Shape2);
178   Perform();
179 }
180
181 //=======================================================================
182 //function : LoadS1
183 //purpose  : 
184 //=======================================================================
185
186 void BRepExtrema_DistShapeShape::LoadS1(const TopoDS_Shape& Shape1)
187 {
188   myShape1 = Shape1;
189   Decomposition(Shape1, myMapV1, myMapE1, myMapF1);
190 }
191
192 //=======================================================================
193 //function : LoadS2
194 //purpose  : 
195 //=======================================================================
196
197 void BRepExtrema_DistShapeShape::LoadS2(const TopoDS_Shape& Shape2)
198 {
199   myShape2 = Shape2;
200   Decomposition(Shape2, myMapV2, myMapE2, myMapF2);
201 }
202
203 //=======================================================================
204 //function : Perform
205 //purpose  : 
206 //=======================================================================
207
208 Standard_Boolean BRepExtrema_DistShapeShape::Perform()
209 {
210   myIsDone=Standard_False;
211   myInnerSol=Standard_False;
212   mySolutionsShape1.Clear();
213   mySolutionsShape2.Clear();
214
215   if ( myShape1.IsNull() || myShape2.IsNull() )
216     return Standard_False;
217
218   TopoDS_Vertex V;
219   Bnd_SeqOfBox BV1, BV2, BE1, BE2, BF1, BF2;
220   const Standard_Real tol = 0.001;
221
222   // Treatment of solids
223   const TopAbs_ShapeEnum Type1 = myShape1.ShapeType();
224   if ((Type1==TopAbs_SOLID) || (Type1 == TopAbs_COMPSOLID))
225   {
226     BRepClass3d_SolidClassifier Classi(myShape1);
227     const Standard_Integer nbv2 = myMapV2.Extent();
228     Standard_Integer nbv1 = 0;
229     while ( (nbv1<nbv2) && (!myInnerSol) )
230     {
231       nbv1++;
232       V = TopoDS::Vertex(myMapV2(nbv1));
233       const gp_Pnt &P = BRep_Tool::Pnt(V);
234       Classi.Perform(P,tol);
235       if (Classi.State()==TopAbs_IN)
236       {
237         myInnerSol = Standard_True;
238         myDistRef = 0.;
239         myIsDone = Standard_True; 
240         BRepExtrema_SolutionElem Sol(0,P,BRepExtrema_IsVertex,V);
241         mySolutionsShape1.Append(Sol);
242         mySolutionsShape2.Append(Sol);
243       }  
244     }
245   }
246   
247   const TopAbs_ShapeEnum Type2 = myShape2.ShapeType();
248   if (((Type2==TopAbs_SOLID) || (Type2==TopAbs_COMPSOLID)) && (!myInnerSol))
249   {
250     BRepClass3d_SolidClassifier Classi(myShape2);
251     const Standard_Integer nbv1 = myMapV1.Extent();
252     Standard_Integer nbv2 = 0;
253     while ( (nbv2<nbv1) && (!myInnerSol) )
254     {
255       nbv2++;
256       V = TopoDS::Vertex(myMapV1(nbv2));
257       const gp_Pnt &P = BRep_Tool::Pnt(V);
258       Classi.Perform(P,tol);
259       if (Classi.State()==TopAbs_IN) {
260         myInnerSol = Standard_True;
261         myDistRef = 0;
262         myIsDone = Standard_True; 
263         BRepExtrema_SolutionElem Sol (0,P,BRepExtrema_IsVertex,V);
264         mySolutionsShape1.Append(Sol);
265         mySolutionsShape2.Append(Sol);
266       }
267     }
268   }
269   
270   if (!myInnerSol)
271   {
272     BoxCalculation(myMapV1,BV1);
273     BoxCalculation(myMapE1,BE1);
274     BoxCalculation(myMapF1,BF1);
275     BoxCalculation(myMapV2,BV2);
276     BoxCalculation(myMapE2,BE2);
277     BoxCalculation(myMapF2,BF2);
278     
279     if (myMapV1.Extent() && myMapV2.Extent())
280     {
281       TopoDS_Vertex V1 = TopoDS::Vertex(myMapV1(1));
282       TopoDS_Vertex V2 = TopoDS::Vertex(myMapV2(1));
283       myDistRef = DistanceInitiale(V1, V2);
284     }
285     else
286       myDistRef= 1.e30; //szv:!!!
287
288     DistanceMapMap(myMapV1, myMapV2, BV1, BV2);
289     DistanceMapMap(myMapV1, myMapE2, BV1, BE2);
290     DistanceMapMap(myMapE1, myMapV2, BE1, BV2);
291     DistanceMapMap(myMapV1, myMapF2, BV1, BF2);
292     DistanceMapMap(myMapF1, myMapV2, BF1, BV2);
293     DistanceMapMap(myMapE1, myMapE2, BE1, BE2);
294     DistanceMapMap(myMapE1, myMapF2, BE1, BF2);
295     DistanceMapMap(myMapF1, myMapE2, BF1, BE2);
296
297     if( (fabs(myDistRef)) > myEps )
298       DistanceMapMap(myMapF1,myMapF2,BF1,BF2);
299     
300     //  Modified by Sergey KHROMOV - Tue Mar  6 11:55:03 2001 Begin
301     Standard_Integer i = 1;
302     for (; i <= mySolutionsShape1.Length(); i++)
303       if (mySolutionsShape1.Value(i).Dist() > myDistRef + myEps)
304       {
305         mySolutionsShape1.Remove(i);
306         mySolutionsShape2.Remove(i);
307       }
308     //  Modified by Sergey KHROMOV - Tue Mar  6 11:55:04 2001 End
309     myIsDone = ( mySolutionsShape1.Length() > 0 );
310   }
311   return myIsDone;
312 }
313
314 //=======================================================================
315 //function : Value
316 //purpose  : 
317 //=======================================================================
318
319 Standard_Real BRepExtrema_DistShapeShape::Value() const 
320
321   if (!myIsDone)
322     StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::Value: There's no solution ");
323
324   return myDistRef;
325 }
326
327 //=======================================================================
328 //function : SupportOnShape1
329 //purpose  : 
330 //=======================================================================
331
332 TopoDS_Shape BRepExtrema_DistShapeShape::SupportOnShape1(const Standard_Integer N) const
333
334   if (!myIsDone)
335     StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::SupportOnShape1: There's no solution ");
336
337   const BRepExtrema_SolutionElem &sol = mySolutionsShape1.Value(N);
338   switch (sol.SupportKind())
339   {
340     case BRepExtrema_IsVertex : return sol.Vertex();
341     case BRepExtrema_IsOnEdge : return sol.Edge();
342     case BRepExtrema_IsInFace : return sol.Face();
343   }
344   return TopoDS_Shape();
345 }
346
347 //=======================================================================
348 //function : SupportOnShape2
349 //purpose  : 
350 //=======================================================================
351
352 TopoDS_Shape BRepExtrema_DistShapeShape::SupportOnShape2(const Standard_Integer N) const 
353
354   if (!myIsDone)
355     StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::SupportOnShape2: There's no solution ");
356
357   const BRepExtrema_SolutionElem &sol = mySolutionsShape2.Value(N);
358   switch (sol.SupportKind())
359   {
360     case BRepExtrema_IsVertex : return sol.Vertex();
361     case BRepExtrema_IsOnEdge : return sol.Edge();
362     case BRepExtrema_IsInFace : return sol.Face();
363   }
364   return TopoDS_Shape();
365 }
366
367 //=======================================================================
368 //function : ParOnEdgeS1
369 //purpose  : 
370 //=======================================================================
371
372 void BRepExtrema_DistShapeShape::ParOnEdgeS1(const Standard_Integer N, Standard_Real& t) const 
373
374   if (!myIsDone)
375     StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::ParOnEdgeS1: There's no solution");
376
377   const BRepExtrema_SolutionElem &sol = mySolutionsShape1.Value(N);
378   if (sol.SupportKind() != BRepExtrema_IsOnEdge)
379     BRepExtrema_UnCompatibleShape::Raise
380       ("BRepExtrema_DistShapeShape::ParOnEdgeS1: ParOnEdgeS1 is impossible without EDGE");
381
382   sol.EdgeParameter(t);
383 }
384
385 //=======================================================================
386 //function : ParOnEdgeS2
387 //purpose  : 
388 //=======================================================================
389
390 void BRepExtrema_DistShapeShape::ParOnEdgeS2(const Standard_Integer N,  Standard_Real& t) const 
391
392   if (!myIsDone)
393     StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::ParOnEdgeS2: There's no solution");
394
395   const BRepExtrema_SolutionElem &sol = mySolutionsShape2.Value(N);
396   if (sol.SupportKind() != BRepExtrema_IsOnEdge)
397     BRepExtrema_UnCompatibleShape::Raise
398       ("BRepExtrema_DistShapeShape::ParOnEdgeS2: ParOnEdgeS2 is impossible without EDGE");
399  
400   sol.EdgeParameter(t);
401 }
402
403 //=======================================================================
404 //function : ParOnFaceS1
405 //purpose  : 
406 //=======================================================================
407
408 void BRepExtrema_DistShapeShape::ParOnFaceS1(const Standard_Integer N,  Standard_Real& u,  Standard_Real& v) const 
409
410   if (!myIsDone)
411     StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::ParOnFaceS1: There's no solution");
412
413   const BRepExtrema_SolutionElem &sol = mySolutionsShape1.Value(N);
414   if (sol.SupportKind() != BRepExtrema_IsInFace)
415     BRepExtrema_UnCompatibleShape::Raise
416       ("BRepExtrema_DistShapeShape::ParOnFaceS1: ParOnFaceS1 is impossible without FACE");
417   
418   sol.FaceParameter(u, v);
419 }
420
421 //=======================================================================
422 //function : ParOnFaceS2
423 //purpose  : 
424 //=======================================================================
425
426 void BRepExtrema_DistShapeShape::ParOnFaceS2(const Standard_Integer N,  Standard_Real& u, Standard_Real& v) const 
427
428   if (!myIsDone)
429     StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::ParOnFaceS2: There's no solution");
430
431   const BRepExtrema_SolutionElem &sol = mySolutionsShape2.Value(N);
432   if (sol.SupportKind() != BRepExtrema_IsInFace)
433     BRepExtrema_UnCompatibleShape::Raise
434       ("BRepExtrema_DistShapeShape::ParOnFaceS2:ParOnFaceS2 is impossible without FACE ");
435   
436   sol.FaceParameter(u, v);
437 }
438
439 //=======================================================================
440 //function : Dump
441 //purpose  : 
442 //=======================================================================
443
444 void BRepExtrema_DistShapeShape::Dump(Standard_OStream& o) const 
445 {
446   Standard_Integer i;
447   Standard_Real r1,r2;
448   
449   o<< "the distance  value is :  " << Value()<<endl;
450   o<< "the number of solutions is :"<<NbSolution()<<endl;
451   o<<endl;
452   for (i=1;i<=NbSolution();i++)
453   {
454     o<<"solution number "<<i<<": "<< endl;
455     o<<"the type of the solution on the first shape is " <<Standard_Integer( SupportTypeShape1(i)) <<endl; 
456     o<<"the type of the solution on the second shape is "<<Standard_Integer( SupportTypeShape2(i))<< endl;
457     o<< "the coordinates of  the point on the first shape are: "<<endl; 
458     o<<"X=" <<PointOnShape1(i).X()<<" Y=" <<PointOnShape1(i).Y()<<" Z="<<PointOnShape1(i).Z()<<endl;
459     o<< "the coordinates of  the point on the second shape are: "<<endl; 
460     o<<"X="<< PointOnShape2(i).X()<< " Y="<<PointOnShape2(i).Y()<<" Z="<< PointOnShape2(i).Z()<<endl;
461     
462     switch (SupportTypeShape1(i))
463     {
464       case BRepExtrema_IsVertex:
465         break;
466       case BRepExtrema_IsOnEdge:
467         ParOnEdgeS1(i,r1);
468         o << "parameter on the first edge :  t= " << r1 << endl;
469         break;
470       case BRepExtrema_IsInFace:
471         ParOnFaceS1(i,r1,r2);
472         o << "parameters on the first face :  u= " << r1 << " v=" <<  r2 << endl;
473         break;
474     }
475     switch (SupportTypeShape2(i))
476     {
477       case BRepExtrema_IsVertex:
478         break;
479       case BRepExtrema_IsOnEdge:
480         ParOnEdgeS2(i,r1);
481         o << "parameter on the second edge : t=" << r1 << endl;
482         break;
483       case BRepExtrema_IsInFace:
484         ParOnFaceS2(i,r1,r2);
485         o << "parameters on the second face : u= " << r1 << " v=" <<  r2 << endl;
486         break;
487     }
488     o<<endl;
489   } 
490 }