OCC22322 Improvement extrema Additional integration
[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
7fd59977 167//=======================================================================
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;
bdde5715 215 while ( (nbv1<nbv2) && (!myInnerSol) )
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 }
7fd59977 231 }
232
92d1589b
A
233 const TopAbs_ShapeEnum Type2 = myShape2.ShapeType();
234 if (((Type2==TopAbs_SOLID) || (Type2==TopAbs_COMPSOLID)) && (!myInnerSol))
235 {
7fd59977 236 BRepClass3d_SolidClassifier Classi(myShape2);
92d1589b
A
237 const Standard_Integer nbv1 = myMapV1.Extent();
238 Standard_Integer nbv2 = 0;
bdde5715 239 while ( (nbv2<nbv1) && (!myInnerSol) )
1aeb969a 240 {
7fd59977 241 nbv2++;
92d1589b
A
242 V = TopoDS::Vertex(myMapV1(nbv2));
243 const gp_Pnt &P = BRep_Tool::Pnt(V);
7fd59977 244 Classi.Perform(P,tol);
245 if (Classi.State()==TopAbs_IN) {
246 myInnerSol = Standard_True;
7fd59977 247 myDistRef = 0;
248 myIsDone = Standard_True;
92d1589b
A
249 BRepExtrema_SolutionElem Sol (0,P,BRepExtrema_IsVertex,V);
250 mySolutionsShape1.Append(Sol);
251 mySolutionsShape2.Append(Sol);
7fd59977 252 }
1aeb969a 253 }
7fd59977 254 }
255
92d1589b
A
256 if (!myInnerSol)
257 {
258 BoxCalculation(myMapV1,BV1);
259 BoxCalculation(myMapE1,BE1);
260 BoxCalculation(myMapF1,BF1);
261 BoxCalculation(myMapV2,BV2);
262 BoxCalculation(myMapE2,BE2);
263 BoxCalculation(myMapF2,BF2);
7fd59977 264
92d1589b
A
265 if (myMapV1.Extent() && myMapV2.Extent())
266 {
7fd59977 267 TopoDS_Vertex V1 = TopoDS::Vertex(myMapV1(1));
268 TopoDS_Vertex V2 = TopoDS::Vertex(myMapV2(1));
92d1589b 269 myDistRef = DistanceInitiale(V1, V2);
7fd59977 270 }
271 else
92d1589b
A
272 myDistRef= 1.e30; //szv:!!!
273
274 DistanceMapMap(myMapV1, myMapV2, BV1, BV2);
275 DistanceMapMap(myMapV1, myMapE2, BV1, BE2);
276 DistanceMapMap(myMapE1, myMapV2, BE1, BV2);
277 DistanceMapMap(myMapV1, myMapF2, BV1, BF2);
278 DistanceMapMap(myMapF1, myMapV2, BF1, BV2);
279 DistanceMapMap(myMapE1, myMapE2, BE1, BE2);
280 DistanceMapMap(myMapE1, myMapF2, BE1, BF2);
281 DistanceMapMap(myMapF1, myMapE2, BF1, BE2);
282
7fd59977 283 if( (fabs(myDistRef)) > myEps )
284 DistanceMapMap(myMapF1,myMapF2,BF1,BF2);
285
286 // Modified by Sergey KHROMOV - Tue Mar 6 11:55:03 2001 Begin
92d1589b
A
287 Standard_Integer i = 1;
288 for (; i <= mySolutionsShape1.Length(); i++)
289 if (mySolutionsShape1.Value(i).Dist() > myDistRef + myEps)
290 {
291 mySolutionsShape1.Remove(i);
292 mySolutionsShape2.Remove(i);
7fd59977 293 }
294 // Modified by Sergey KHROMOV - Tue Mar 6 11:55:04 2001 End
92d1589b 295 myIsDone = ( mySolutionsShape1.Length() > 0 );
7fd59977 296 }
297 return myIsDone;
298}
299
7fd59977 300//=======================================================================
301//function : Value
302//purpose :
303//=======================================================================
304
305Standard_Real BRepExtrema_DistShapeShape::Value() const
306{
92d1589b
A
307 if (!myIsDone)
308 StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::Value: There's no solution ");
7fd59977 309
92d1589b 310 return myDistRef;
7fd59977 311}
312
313//=======================================================================
314//function : SupportOnShape1
315//purpose :
316//=======================================================================
317
92d1589b 318TopoDS_Shape BRepExtrema_DistShapeShape::SupportOnShape1(const Standard_Integer N) const
7fd59977 319{
92d1589b
A
320 if (!myIsDone)
321 StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::SupportOnShape1: There's no solution ");
322
323 const BRepExtrema_SolutionElem &sol = mySolutionsShape1.Value(N);
324 switch (sol.SupportKind())
325 {
326 case BRepExtrema_IsVertex : return sol.Vertex();
327 case BRepExtrema_IsOnEdge : return sol.Edge();
328 case BRepExtrema_IsInFace : return sol.Face();
329 }
330 return TopoDS_Shape();
7fd59977 331}
332
333//=======================================================================
334//function : SupportOnShape2
335//purpose :
336//=======================================================================
337
338TopoDS_Shape BRepExtrema_DistShapeShape::SupportOnShape2(const Standard_Integer N) const
339{
92d1589b
A
340 if (!myIsDone)
341 StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::SupportOnShape2: There's no solution ");
342
343 const BRepExtrema_SolutionElem &sol = mySolutionsShape2.Value(N);
344 switch (sol.SupportKind())
345 {
346 case BRepExtrema_IsVertex : return sol.Vertex();
347 case BRepExtrema_IsOnEdge : return sol.Edge();
348 case BRepExtrema_IsInFace : return sol.Face();
349 }
350 return TopoDS_Shape();
7fd59977 351}
352
353//=======================================================================
354//function : ParOnEdgeS1
355//purpose :
356//=======================================================================
357
358void BRepExtrema_DistShapeShape::ParOnEdgeS1(const Standard_Integer N, Standard_Real& t) const
359{
92d1589b
A
360 if (!myIsDone)
361 StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::ParOnEdgeS1: There's no solution");
362
363 const BRepExtrema_SolutionElem &sol = mySolutionsShape1.Value(N);
364 if (sol.SupportKind() != BRepExtrema_IsOnEdge)
365 BRepExtrema_UnCompatibleShape::Raise
366 ("BRepExtrema_DistShapeShape::ParOnEdgeS1: ParOnEdgeS1 is impossible without EDGE");
367
368 sol.EdgeParameter(t);
7fd59977 369}
370
371//=======================================================================
372//function : ParOnEdgeS2
373//purpose :
374//=======================================================================
375
376void BRepExtrema_DistShapeShape::ParOnEdgeS2(const Standard_Integer N, Standard_Real& t) const
377{
92d1589b
A
378 if (!myIsDone)
379 StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::ParOnEdgeS2: There's no solution");
380
381 const BRepExtrema_SolutionElem &sol = mySolutionsShape2.Value(N);
382 if (sol.SupportKind() != BRepExtrema_IsOnEdge)
383 BRepExtrema_UnCompatibleShape::Raise
384 ("BRepExtrema_DistShapeShape::ParOnEdgeS2: ParOnEdgeS2 is impossible without EDGE");
7fd59977 385
92d1589b 386 sol.EdgeParameter(t);
7fd59977 387}
388
389//=======================================================================
390//function : ParOnFaceS1
391//purpose :
392//=======================================================================
393
394void BRepExtrema_DistShapeShape::ParOnFaceS1(const Standard_Integer N, Standard_Real& u, Standard_Real& v) const
395{
92d1589b
A
396 if (!myIsDone)
397 StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::ParOnFaceS1: There's no solution");
398
399 const BRepExtrema_SolutionElem &sol = mySolutionsShape1.Value(N);
400 if (sol.SupportKind() != BRepExtrema_IsInFace)
401 BRepExtrema_UnCompatibleShape::Raise
402 ("BRepExtrema_DistShapeShape::ParOnFaceS1: ParOnFaceS1 is impossible without FACE");
7fd59977 403
92d1589b 404 sol.FaceParameter(u, v);
7fd59977 405}
406
92d1589b
A
407//=======================================================================
408//function : ParOnFaceS2
409//purpose :
410//=======================================================================
411
7fd59977 412void BRepExtrema_DistShapeShape::ParOnFaceS2(const Standard_Integer N, Standard_Real& u, Standard_Real& v) const
413{
92d1589b
A
414 if (!myIsDone)
415 StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::ParOnFaceS2: There's no solution");
7fd59977 416
92d1589b
A
417 const BRepExtrema_SolutionElem &sol = mySolutionsShape2.Value(N);
418 if (sol.SupportKind() != BRepExtrema_IsInFace)
419 BRepExtrema_UnCompatibleShape::Raise
420 ("BRepExtrema_DistShapeShape::ParOnFaceS2:ParOnFaceS2 is impossible without FACE ");
421
422 sol.FaceParameter(u, v);
7fd59977 423}
424
425//=======================================================================
426//function : Dump
427//purpose :
428//=======================================================================
429
430void BRepExtrema_DistShapeShape::Dump(Standard_OStream& o) const
431{
432 Standard_Integer i;
433 Standard_Real r1,r2;
7fd59977 434
435 o<< "the distance value is : " << Value()<<endl;
436 o<< "the number of solutions is :"<<NbSolution()<<endl;
437 o<<endl;
92d1589b
A
438 for (i=1;i<=NbSolution();i++)
439 {
440 o<<"solution number "<<i<<": "<< endl;
7fd59977 441 o<<"the type of the solution on the first shape is " <<Standard_Integer( SupportTypeShape1(i)) <<endl;
442 o<<"the type of the solution on the second shape is "<<Standard_Integer( SupportTypeShape2(i))<< endl;
443 o<< "the coordinates of the point on the first shape are: "<<endl;
444 o<<"X=" <<PointOnShape1(i).X()<<" Y=" <<PointOnShape1(i).Y()<<" Z="<<PointOnShape1(i).Z()<<endl;
445 o<< "the coordinates of the point on the second shape are: "<<endl;
446 o<<"X="<< PointOnShape2(i).X()<< " Y="<<PointOnShape2(i).Y()<<" Z="<< PointOnShape2(i).Z()<<endl;
447
92d1589b
A
448 switch (SupportTypeShape1(i))
449 {
450 case BRepExtrema_IsOnEdge:
451 ParOnEdgeS1(i,r1);
452 o << "parameter on the first edge : t= " << r1 << endl;
453 break;
454 case BRepExtrema_IsInFace:
455 ParOnFaceS1(i,r1,r2);
456 o << "parameters on the first face : u= " << r1 << " v=" << r2 << endl;
457 break;
458 }
459 switch (SupportTypeShape2(i))
460 {
461 case BRepExtrema_IsOnEdge:
462 ParOnEdgeS2(i,r1);
463 o << "parameter on the second edge : t=" << r1 << endl;
464 break;
465 case BRepExtrema_IsInFace:
466 ParOnFaceS2(i,r1,r2);
467 o << "parameters on the second face : u= " << r1 << " v=" << r2 << endl;
468 break;
469 }
7fd59977 470 o<<endl;
471 }
472}