0024171: Eliminate CLang compiler warning -Wreorder
[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   myDistValue(0.),
132   myIsDone(Standard_False),
133   myInnerSol(Standard_False),
134   myEps(Precision::Confusion()),
135   myFlag(Extrema_ExtFlag_MINMAX),
136   myAlgo(Extrema_ExtAlgo_Grad)
137 {
138 }
139
140 //=======================================================================
141 //function : BRepExtrema_DistShapeShape
142 //purpose  : 
143 //=======================================================================
144 BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape(const TopoDS_Shape& Shape1,
145                                                        const TopoDS_Shape& Shape2,
146                                                        const Extrema_ExtFlag F,
147                                                        const Extrema_ExtAlgo A)
148 : myDistRef(0.),
149   myDistValue(0.),
150   myIsDone(Standard_False),
151   myInnerSol(Standard_False),
152   myEps(Precision::Confusion()),
153   myFlag(F),
154   myAlgo(A)
155 {
156   LoadS1(Shape1);
157   LoadS2(Shape2);
158   Perform();
159 }
160
161 //=======================================================================
162 //function : BRepExtrema_DistShapeShape
163 //purpose  : 
164 //=======================================================================
165
166 BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape(const TopoDS_Shape& Shape1,
167                                                        const TopoDS_Shape& Shape2,
168                                                        const Standard_Real theDeflection,
169                                                        const Extrema_ExtFlag F,
170                                                        const Extrema_ExtAlgo A)
171 : myDistRef(0.),
172   myDistValue(0.),
173   myIsDone(Standard_False),
174   myInnerSol(Standard_False),
175   myEps(theDeflection),
176   myFlag(F),
177   myAlgo(A)
178 {
179   LoadS1(Shape1);
180   LoadS2(Shape2);
181   Perform();
182 }
183
184 //=======================================================================
185 //function : LoadS1
186 //purpose  : 
187 //=======================================================================
188
189 void BRepExtrema_DistShapeShape::LoadS1(const TopoDS_Shape& Shape1)
190 {
191   myShape1 = Shape1;
192   Decomposition(Shape1, myMapV1, myMapE1, myMapF1);
193 }
194
195 //=======================================================================
196 //function : LoadS2
197 //purpose  : 
198 //=======================================================================
199
200 void BRepExtrema_DistShapeShape::LoadS2(const TopoDS_Shape& Shape2)
201 {
202   myShape2 = Shape2;
203   Decomposition(Shape2, myMapV2, myMapE2, myMapF2);
204 }
205
206 //=======================================================================
207 //function : Perform
208 //purpose  : 
209 //=======================================================================
210
211 Standard_Boolean BRepExtrema_DistShapeShape::Perform()
212 {
213   myIsDone=Standard_False;
214   myInnerSol=Standard_False;
215   mySolutionsShape1.Clear();
216   mySolutionsShape2.Clear();
217
218   if ( myShape1.IsNull() || myShape2.IsNull() )
219     return Standard_False;
220
221   TopoDS_Vertex V;
222   Bnd_SeqOfBox BV1, BV2, BE1, BE2, BF1, BF2;
223   const Standard_Real tol = 0.001;
224
225   // Treatment of solids
226   const TopAbs_ShapeEnum Type1 = myShape1.ShapeType();
227   if ((Type1==TopAbs_SOLID) || (Type1 == TopAbs_COMPSOLID))
228   {
229     BRepClass3d_SolidClassifier Classi(myShape1);
230     const Standard_Integer nbv2 = myMapV2.Extent();
231     Standard_Integer nbv1 = 0;
232     while ( (nbv1<nbv2) && (!myInnerSol) )
233     {
234       nbv1++;
235       V = TopoDS::Vertex(myMapV2(nbv1));
236       const gp_Pnt &P = BRep_Tool::Pnt(V);
237       Classi.Perform(P,tol);
238       if (Classi.State()==TopAbs_IN)
239       {
240         myInnerSol = Standard_True;
241         myDistRef = 0.;
242         myIsDone = Standard_True; 
243         BRepExtrema_SolutionElem Sol(0,P,BRepExtrema_IsVertex,V);
244         mySolutionsShape1.Append(Sol);
245         mySolutionsShape2.Append(Sol);
246       }  
247     }
248   }
249   
250   const TopAbs_ShapeEnum Type2 = myShape2.ShapeType();
251   if (((Type2==TopAbs_SOLID) || (Type2==TopAbs_COMPSOLID)) && (!myInnerSol))
252   {
253     BRepClass3d_SolidClassifier Classi(myShape2);
254     const Standard_Integer nbv1 = myMapV1.Extent();
255     Standard_Integer nbv2 = 0;
256     while ( (nbv2<nbv1) && (!myInnerSol) )
257     {
258       nbv2++;
259       V = TopoDS::Vertex(myMapV1(nbv2));
260       const gp_Pnt &P = BRep_Tool::Pnt(V);
261       Classi.Perform(P,tol);
262       if (Classi.State()==TopAbs_IN) {
263         myInnerSol = Standard_True;
264         myDistRef = 0;
265         myIsDone = Standard_True; 
266         BRepExtrema_SolutionElem Sol (0,P,BRepExtrema_IsVertex,V);
267         mySolutionsShape1.Append(Sol);
268         mySolutionsShape2.Append(Sol);
269       }
270     }
271   }
272   
273   if (!myInnerSol)
274   {
275     BoxCalculation(myMapV1,BV1);
276     BoxCalculation(myMapE1,BE1);
277     BoxCalculation(myMapF1,BF1);
278     BoxCalculation(myMapV2,BV2);
279     BoxCalculation(myMapE2,BE2);
280     BoxCalculation(myMapF2,BF2);
281     
282     if (myMapV1.Extent() && myMapV2.Extent())
283     {
284       TopoDS_Vertex V1 = TopoDS::Vertex(myMapV1(1));
285       TopoDS_Vertex V2 = TopoDS::Vertex(myMapV2(1));
286       myDistRef = DistanceInitiale(V1, V2);
287     }
288     else
289       myDistRef= 1.e30; //szv:!!!
290
291     DistanceMapMap(myMapV1, myMapV2, BV1, BV2);
292     DistanceMapMap(myMapV1, myMapE2, BV1, BE2);
293     DistanceMapMap(myMapE1, myMapV2, BE1, BV2);
294     DistanceMapMap(myMapV1, myMapF2, BV1, BF2);
295     DistanceMapMap(myMapF1, myMapV2, BF1, BV2);
296     DistanceMapMap(myMapE1, myMapE2, BE1, BE2);
297     DistanceMapMap(myMapE1, myMapF2, BE1, BF2);
298     DistanceMapMap(myMapF1, myMapE2, BF1, BE2);
299
300     if( (fabs(myDistRef)) > myEps )
301       DistanceMapMap(myMapF1,myMapF2,BF1,BF2);
302     
303     //  Modified by Sergey KHROMOV - Tue Mar  6 11:55:03 2001 Begin
304     Standard_Integer i = 1;
305     for (; i <= mySolutionsShape1.Length(); i++)
306       if (mySolutionsShape1.Value(i).Dist() > myDistRef + myEps)
307       {
308         mySolutionsShape1.Remove(i);
309         mySolutionsShape2.Remove(i);
310       }
311     //  Modified by Sergey KHROMOV - Tue Mar  6 11:55:04 2001 End
312     myIsDone = ( mySolutionsShape1.Length() > 0 );
313   }
314   return myIsDone;
315 }
316
317 //=======================================================================
318 //function : Value
319 //purpose  : 
320 //=======================================================================
321
322 Standard_Real BRepExtrema_DistShapeShape::Value() const 
323
324   if (!myIsDone)
325     StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::Value: There's no solution ");
326
327   return myDistRef;
328 }
329
330 //=======================================================================
331 //function : SupportOnShape1
332 //purpose  : 
333 //=======================================================================
334
335 TopoDS_Shape BRepExtrema_DistShapeShape::SupportOnShape1(const Standard_Integer N) const
336
337   if (!myIsDone)
338     StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::SupportOnShape1: There's no solution ");
339
340   const BRepExtrema_SolutionElem &sol = mySolutionsShape1.Value(N);
341   switch (sol.SupportKind())
342   {
343     case BRepExtrema_IsVertex : return sol.Vertex();
344     case BRepExtrema_IsOnEdge : return sol.Edge();
345     case BRepExtrema_IsInFace : return sol.Face();
346   }
347   return TopoDS_Shape();
348 }
349
350 //=======================================================================
351 //function : SupportOnShape2
352 //purpose  : 
353 //=======================================================================
354
355 TopoDS_Shape BRepExtrema_DistShapeShape::SupportOnShape2(const Standard_Integer N) const 
356
357   if (!myIsDone)
358     StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::SupportOnShape2: There's no solution ");
359
360   const BRepExtrema_SolutionElem &sol = mySolutionsShape2.Value(N);
361   switch (sol.SupportKind())
362   {
363     case BRepExtrema_IsVertex : return sol.Vertex();
364     case BRepExtrema_IsOnEdge : return sol.Edge();
365     case BRepExtrema_IsInFace : return sol.Face();
366   }
367   return TopoDS_Shape();
368 }
369
370 //=======================================================================
371 //function : ParOnEdgeS1
372 //purpose  : 
373 //=======================================================================
374
375 void BRepExtrema_DistShapeShape::ParOnEdgeS1(const Standard_Integer N, Standard_Real& t) const 
376
377   if (!myIsDone)
378     StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::ParOnEdgeS1: There's no solution");
379
380   const BRepExtrema_SolutionElem &sol = mySolutionsShape1.Value(N);
381   if (sol.SupportKind() != BRepExtrema_IsOnEdge)
382     BRepExtrema_UnCompatibleShape::Raise
383       ("BRepExtrema_DistShapeShape::ParOnEdgeS1: ParOnEdgeS1 is impossible without EDGE");
384
385   sol.EdgeParameter(t);
386 }
387
388 //=======================================================================
389 //function : ParOnEdgeS2
390 //purpose  : 
391 //=======================================================================
392
393 void BRepExtrema_DistShapeShape::ParOnEdgeS2(const Standard_Integer N,  Standard_Real& t) const 
394
395   if (!myIsDone)
396     StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::ParOnEdgeS2: There's no solution");
397
398   const BRepExtrema_SolutionElem &sol = mySolutionsShape2.Value(N);
399   if (sol.SupportKind() != BRepExtrema_IsOnEdge)
400     BRepExtrema_UnCompatibleShape::Raise
401       ("BRepExtrema_DistShapeShape::ParOnEdgeS2: ParOnEdgeS2 is impossible without EDGE");
402  
403   sol.EdgeParameter(t);
404 }
405
406 //=======================================================================
407 //function : ParOnFaceS1
408 //purpose  : 
409 //=======================================================================
410
411 void BRepExtrema_DistShapeShape::ParOnFaceS1(const Standard_Integer N,  Standard_Real& u,  Standard_Real& v) const 
412
413   if (!myIsDone)
414     StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::ParOnFaceS1: There's no solution");
415
416   const BRepExtrema_SolutionElem &sol = mySolutionsShape1.Value(N);
417   if (sol.SupportKind() != BRepExtrema_IsInFace)
418     BRepExtrema_UnCompatibleShape::Raise
419       ("BRepExtrema_DistShapeShape::ParOnFaceS1: ParOnFaceS1 is impossible without FACE");
420   
421   sol.FaceParameter(u, v);
422 }
423
424 //=======================================================================
425 //function : ParOnFaceS2
426 //purpose  : 
427 //=======================================================================
428
429 void BRepExtrema_DistShapeShape::ParOnFaceS2(const Standard_Integer N,  Standard_Real& u, Standard_Real& v) const 
430
431   if (!myIsDone)
432     StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::ParOnFaceS2: There's no solution");
433
434   const BRepExtrema_SolutionElem &sol = mySolutionsShape2.Value(N);
435   if (sol.SupportKind() != BRepExtrema_IsInFace)
436     BRepExtrema_UnCompatibleShape::Raise
437       ("BRepExtrema_DistShapeShape::ParOnFaceS2:ParOnFaceS2 is impossible without FACE ");
438   
439   sol.FaceParameter(u, v);
440 }
441
442 //=======================================================================
443 //function : Dump
444 //purpose  : 
445 //=======================================================================
446
447 void BRepExtrema_DistShapeShape::Dump(Standard_OStream& o) const 
448 {
449   Standard_Integer i;
450   Standard_Real r1,r2;
451   
452   o<< "the distance  value is :  " << Value()<<endl;
453   o<< "the number of solutions is :"<<NbSolution()<<endl;
454   o<<endl;
455   for (i=1;i<=NbSolution();i++)
456   {
457     o<<"solution number "<<i<<": "<< endl;
458     o<<"the type of the solution on the first shape is " <<Standard_Integer( SupportTypeShape1(i)) <<endl; 
459     o<<"the type of the solution on the second shape is "<<Standard_Integer( SupportTypeShape2(i))<< endl;
460     o<< "the coordinates of  the point on the first shape are: "<<endl; 
461     o<<"X=" <<PointOnShape1(i).X()<<" Y=" <<PointOnShape1(i).Y()<<" Z="<<PointOnShape1(i).Z()<<endl;
462     o<< "the coordinates of  the point on the second shape are: "<<endl; 
463     o<<"X="<< PointOnShape2(i).X()<< " Y="<<PointOnShape2(i).Y()<<" Z="<< PointOnShape2(i).Z()<<endl;
464     
465     switch (SupportTypeShape1(i))
466     {
467       case BRepExtrema_IsOnEdge:
468         ParOnEdgeS1(i,r1);
469         o << "parameter on the first edge :  t= " << r1 << endl;
470         break;
471       case BRepExtrema_IsInFace:
472         ParOnFaceS1(i,r1,r2);
473         o << "parameters on the first face :  u= " << r1 << " v=" <<  r2 << endl;
474         break;
475     }
476     switch (SupportTypeShape2(i))
477     {
478       case BRepExtrema_IsOnEdge:
479         ParOnEdgeS2(i,r1);
480         o << "parameter on the second edge : t=" << r1 << endl;
481         break;
482       case BRepExtrema_IsInFace:
483         ParOnFaceS2(i,r1,r2);
484         o << "parameters on the second face : u= " << r1 << " v=" <<  r2 << endl;
485         break;
486     }
487     o<<endl;
488   } 
489 }