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