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
8 #include <BRepExtrema_DistShapeShape.ixx>
9 #include <Standard_OStream.hxx>
10 #include <TopTools_IndexedMapOfShape.hxx>
11 #include <BRepBndLib.hxx>
12 #include <Bnd_Box.hxx>
14 #include <TCollection.hxx>
15 #include <Standard_Real.hxx>
16 #include <BRepExtrema_DistanceSS.hxx>
19 #include <TopoDS_Vertex.hxx>
20 #include <TopoDS_Edge.hxx>
21 #include <TopoDS_Face.hxx>
22 #include <TopAbs_ShapeEnum.hxx>
23 #include <Precision.hxx>
24 #include <BRepExtrema_SeqOfSolution.hxx>
25 #include <BRepExtrema_SolutionElem.hxx>
26 #include <Bnd_SeqOfBox.hxx>
27 #include <BRepExtrema_UnCompatibleShape.hxx>
28 #include <BRep_Tool.hxx>
29 #include <BRepClass3d_SolidClassifier.hxx>
31 static void Decomposition(const TopoDS_Shape& S,
32 TopTools_IndexedMapOfShape& MapV,
33 TopTools_IndexedMapOfShape& MapE,
34 TopTools_IndexedMapOfShape& MapF)
39 TopExp::MapShapes(S,TopAbs_VERTEX,MapV);
40 TopExp::MapShapes(S,TopAbs_EDGE,MapE);
41 TopExp::MapShapes(S,TopAbs_FACE,MapF);
44 static void BoxCalculation(const TopTools_IndexedMapOfShape& Map,
47 Standard_Integer i = 0;
48 for(i = 1; i <= Map.Extent(); i++) {
50 BRepBndLib::Add( Map(i), box);
55 static Standard_Real DistanceInitiale(const TopoDS_Vertex V1,
56 const TopoDS_Vertex V2)
59 P1= BRep_Tool::Pnt(V1);
60 P2= BRep_Tool::Pnt(V2);
61 return(P1.Distance(P2));
64 //=======================================================================
65 //function : DistanceMapMap
67 //=======================================================================
69 void BRepExtrema_DistShapeShape::DistanceMapMap(const TopTools_IndexedMapOfShape& Map1,
70 const TopTools_IndexedMapOfShape& Map2,
71 const Bnd_SeqOfBox& LBox1,
72 const Bnd_SeqOfBox& LBox2)
74 Standard_Integer i = 0, j = 0;
77 BRepExtrema_SeqOfSolution seq1, seq2;
79 Standard_Integer n1 = Map1.Extent();
80 Standard_Integer n2 = Map2.Extent();
81 for(i = 1; i <= n1; i++) {
83 S1= TopoDS_Shape (Map1(i));
84 for(j = 1; j <= n2; j++) {
86 S2 = TopoDS_Shape (Map2(j));
87 BRepExtrema_DistanceSS dist(S1,S2,box1,box2,myDistRef,myEps);
89 if(dist.DistValue() < (myDistRef-myEps)) {
90 ListeDeSolutionShape1.Clear();
91 ListeDeSolutionShape2.Clear();
92 seq1= dist.Seq1Value();
93 seq2= dist.Seq2Value();
94 ListeDeSolutionShape1.Append(seq1);
95 ListeDeSolutionShape2.Append(seq2);
96 myDistRef=dist.DistValue();
98 else if(fabs (dist.DistValue()-myDistRef)< myEps ) {
99 seq1= dist.Seq1Value();
100 seq2= dist.Seq2Value();
101 ListeDeSolutionShape1.Append(seq1);
102 ListeDeSolutionShape2.Append(seq2);
103 // Modified by Sergey KHROMOV - Tue Mar 6 12:15:39 2001 Begin
104 if (myDistRef > dist.DistValue())
105 myDistRef=dist.DistValue();
106 // Modified by Sergey KHROMOV - Tue Mar 6 12:15:37 2001 End
112 //=======================================================================
113 //function : BRepExtrema_DistShapeShape
115 //=======================================================================
117 BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape()
119 myEps = Precision::Confusion();
122 //=======================================================================
123 //function : BRepExtrema_DistShapeShape
125 //=======================================================================
126 BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape(const TopoDS_Shape& Shape1,
127 const TopoDS_Shape& Shape2)
129 myEps = Precision::Confusion();
135 //=======================================================================
136 //function : BRepExtrema_DistShapeShape
138 //=======================================================================
140 BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape(const TopoDS_Shape& Shape1,
141 const TopoDS_Shape& Shape2,
142 const Standard_Real theDeflection)
144 myEps = theDeflection;
150 //=======================================================================
151 //function : SetDeflection
153 //=======================================================================
155 void BRepExtrema_DistShapeShape::SetDeflection(const Standard_Real theDeflection)
157 myEps = theDeflection;
160 //=======================================================================
163 //=======================================================================
165 void BRepExtrema_DistShapeShape::LoadS1(const TopoDS_Shape& Shape1)
168 Decomposition(Shape1, myMapV1, myMapE1, myMapF1);
171 //=======================================================================
174 //=======================================================================
176 void BRepExtrema_DistShapeShape::LoadS2(const TopoDS_Shape& Shape2)
179 Decomposition(Shape2, myMapV2, myMapE2, myMapF2);
182 //=======================================================================
185 //=======================================================================
187 Standard_Boolean BRepExtrema_DistShapeShape::Perform()
189 myIsDone=Standard_False;
190 myInnerSol=Standard_False;
191 ListeDeSolutionShape1.Clear();
192 ListeDeSolutionShape2.Clear();
194 if( myShape1.IsNull() || myShape2.IsNull() )
195 return Standard_False;
197 Bnd_SeqOfBox BV1, BV2, BE1, BE2, BF1, BF2;
198 Standard_Real tol = 0.001;
200 Standard_Integer nbv1,nbv2;
202 // traitement des solides
203 TopAbs_ShapeEnum Type1 = myShape1.ShapeType();
204 TopAbs_ShapeEnum Type2 = myShape2.ShapeType();
205 if((Type1==TopAbs_SOLID) || (Type1 == TopAbs_COMPSOLID)) {
206 BRepClass3d_SolidClassifier Classi(myShape1);
207 nbv2=myMapV2.Extent();
209 while ( (nbv1<nbv2) && (! myInnerSol))
212 TopoDS_Vertex V2 = TopoDS::Vertex(myMapV2(nbv1));
213 P=BRep_Tool::Pnt(V2);
214 Classi.Perform(P,tol);
215 if(Classi.State()==TopAbs_IN) {
216 myInnerSol = Standard_True;
219 myIsDone = Standard_True;
220 BRepExtrema_SolutionElem Sol(0,P,BRepExtrema_IsVertex,V2);
221 ListeDeSolutionShape1.Append(Sol);
222 ListeDeSolutionShape2.Append(Sol);
227 if(((Type2==TopAbs_SOLID)||(Type2==TopAbs_COMPSOLID))&&(!myInnerSol)) {
228 BRepClass3d_SolidClassifier Classi(myShape2);
229 nbv1= myMapV1.Extent();
231 while ((nbv2<nbv1) && (! myInnerSol))
234 TopoDS_Vertex V1=TopoDS::Vertex(myMapV1(nbv2));
235 P=BRep_Tool::Pnt(V1);
236 Classi.Perform(P,tol);
237 if (Classi.State()==TopAbs_IN) {
238 myInnerSol = Standard_True;
241 myIsDone = Standard_True;
242 BRepExtrema_SolutionElem Sol (0,P,BRepExtrema_IsVertex,V1);
243 ListeDeSolutionShape1.Append(Sol);
244 ListeDeSolutionShape2.Append(Sol);
250 BoxCalculation( myMapV1,BV1);
251 BoxCalculation( myMapE1,BE1);
252 BoxCalculation( myMapF1,BF1);
253 BoxCalculation( myMapV2,BV2);
254 BoxCalculation( myMapE2,BE2);
255 BoxCalculation( myMapF2,BF2);
257 if (myMapV1.Extent()!=0 && myMapV2.Extent()!=0) {
258 TopoDS_Vertex V1 = TopoDS::Vertex(myMapV1(1));
259 TopoDS_Vertex V2 = TopoDS::Vertex(myMapV2(1));
260 myDistRef = DistanceInitiale(V1, V2);
265 DistanceMapMap( myMapV1, myMapV2, BV1, BV2);
266 DistanceMapMap( myMapV1, myMapE2, BV1, BE2);
267 DistanceMapMap( myMapE1, myMapV2, BE1, BV2);
268 DistanceMapMap( myMapV1, myMapF2, BV1, BF2);
269 DistanceMapMap( myMapF1, myMapV2, BF1, BV2);
270 DistanceMapMap( myMapE1, myMapE2, BE1, BE2);
271 DistanceMapMap( myMapE1, myMapF2, BE1, BF2);
272 DistanceMapMap( myMapF1, myMapE2, BF1, BE2);
274 if( (fabs(myDistRef)) > myEps )
275 DistanceMapMap(myMapF1,myMapF2,BF1,BF2);
277 // Modified by Sergey KHROMOV - Tue Mar 6 11:55:03 2001 Begin
278 Standard_Integer i = 0;
279 for(i = 1; i <= ListeDeSolutionShape1.Length(); i++)
280 if (ListeDeSolutionShape1.Value(i).Dist() > myDistRef + myEps) {
281 ListeDeSolutionShape1.Remove(i);
282 ListeDeSolutionShape2.Remove(i);
284 // Modified by Sergey KHROMOV - Tue Mar 6 11:55:04 2001 End
285 myNbSolution = ListeDeSolutionShape1.Length();
286 if( myNbSolution > 0 )
287 myIsDone = Standard_True;
289 myIsDone = Standard_False;
294 //=======================================================================
297 //=======================================================================
299 Standard_Boolean BRepExtrema_DistShapeShape:: InnerSolution () const
304 //=======================================================================
307 //=======================================================================
309 Standard_Boolean BRepExtrema_DistShapeShape::IsDone() const
314 //=======================================================================
315 //function : NbSolution
317 //=======================================================================
319 Standard_Integer BRepExtrema_DistShapeShape::NbSolution() const
321 if (myIsDone == Standard_False) {
322 StdFail_NotDone::Raise
323 ("BRepExtrema_DistShapeShape::NbSolution: There's no solution ");
325 return (myNbSolution);
328 //=======================================================================
331 //=======================================================================
333 Standard_Real BRepExtrema_DistShapeShape::Value() const
335 if (myIsDone == Standard_False) {
336 StdFail_NotDone::Raise
337 ("BRepExtrema_DistShapeShape::Value: There's no solution ");
342 //=======================================================================
343 //function : PointOnShape1
345 //=======================================================================
347 gp_Pnt BRepExtrema_DistShapeShape::PointOnShape1(const Standard_Integer N) const
349 if (myIsDone == Standard_False)
350 { StdFail_NotDone::Raise
351 ("BRepExtrema_DistShapeShape::PointOnShape1: There's no solution ");
353 if ((N<1)||(N>myNbSolution))
354 { Standard_OutOfRange::Raise
355 ("BRepExtrema_DistShapeShape::PointOnShape1: Nth solution doesn't exist ");
357 return ((ListeDeSolutionShape1.Value(N)).Point());
360 //=======================================================================
361 //function : PointOnShape2
363 //=======================================================================
365 gp_Pnt BRepExtrema_DistShapeShape::PointOnShape2(const Standard_Integer N) const
367 if (myIsDone == Standard_False)
368 { StdFail_NotDone::Raise
369 ("BRepExtrema_DistShapeShape::PointOnShape2: There's no solution ");
371 if ((N<1)||(N>myNbSolution))
372 { Standard_OutOfRange::Raise
373 ("BRepExtrema_DistShapeShape::PointOnShape2: Nth solution doesn't exist ");
375 return ((ListeDeSolutionShape2.Value(N)).Point());
378 //=======================================================================
379 //function : SupportTypeShape1
381 //=======================================================================
383 BRepExtrema_SupportType BRepExtrema_DistShapeShape::SupportTypeShape1(const Standard_Integer N) const
385 if (myIsDone == Standard_False)
386 { StdFail_NotDone::Raise
387 ("BRepExtrema_DistShapeShape::SupportTypeShape1: There's no solution ");
389 if ((N<1)||(N>myNbSolution))
390 { Standard_OutOfRange::Raise
391 ("BRepExtrema_DistShapeShape::SupportTypeShape1: Nth solution doesn't exist ");
393 return ((ListeDeSolutionShape1.Value(N)).SupportKind());
396 //=======================================================================
397 //function : SupportTypeShape2
399 //=======================================================================
401 BRepExtrema_SupportType BRepExtrema_DistShapeShape::SupportTypeShape2(const Standard_Integer N) const
403 if (myIsDone == Standard_False)
404 { StdFail_NotDone::Raise
405 ("BRepExtrema_DistShapeShape::SupportTypeShape2: There's no solution ");
407 if ((N<1)||(N>myNbSolution))
408 { Standard_OutOfRange::Raise
409 ("BRepExtrema_DistShapeShape::SupportTypeShape2: Nth solution doesn't exist ");
411 return ((ListeDeSolutionShape2.Value(N)).SupportKind());
414 //=======================================================================
415 //function : SupportOnShape1
417 //=======================================================================
419 TopoDS_Shape BRepExtrema_DistShapeShape::SupportOnShape1(const Standard_Integer N) const
421 BRepExtrema_SupportType Type;
422 TopoDS_Shape a_shape;
424 if (myIsDone == Standard_False)
425 { StdFail_NotDone::Raise
426 ("BRepExtrema_DistShapeShape::SupportOnShape1: There's no solution ");
428 if ((N<1)||(N>myNbSolution))
429 { Standard_OutOfRange::Raise
430 ("BRepExtrema_DistShapeShape::SupportOnShape1: Nth solution doesn't exist ");
432 Type = ((ListeDeSolutionShape1.Value(N)).SupportKind());
434 { case BRepExtrema_IsVertex : a_shape=ListeDeSolutionShape1.Value(N).Vertex();
436 case BRepExtrema_IsOnEdge : a_shape=ListeDeSolutionShape1.Value(N).Edge();
438 case BRepExtrema_IsInFace : a_shape=ListeDeSolutionShape1.Value(N).Face();
445 //=======================================================================
446 //function : SupportOnShape2
448 //=======================================================================
450 TopoDS_Shape BRepExtrema_DistShapeShape::SupportOnShape2(const Standard_Integer N) const
452 BRepExtrema_SupportType Type;
453 TopoDS_Shape a_shape ;
455 if (myIsDone == Standard_False)
456 { StdFail_NotDone::Raise
457 ("BRepExtrema_DistShapeShape::SupportOnShape2: There's no solution ");
459 if ((N<1)||(N>myNbSolution))
460 { Standard_OutOfRange::Raise
461 ("BRepExtrema_DistShapeShape::SupportOnShape2: Nth solution doesn't exist ");
463 Type = ((ListeDeSolutionShape2.Value(N)).SupportKind());
465 { case BRepExtrema_IsVertex : a_shape=ListeDeSolutionShape2.Value(N).Vertex();
467 case BRepExtrema_IsOnEdge : a_shape=ListeDeSolutionShape2.Value(N).Edge();
469 case BRepExtrema_IsInFace : a_shape=ListeDeSolutionShape2.Value(N).Face();
476 //=======================================================================
477 //function : ParOnEdgeS1
479 //=======================================================================
481 void BRepExtrema_DistShapeShape::ParOnEdgeS1(const Standard_Integer N, Standard_Real& t) const
483 BRepExtrema_SupportType Type;
485 if (myIsDone == Standard_False)
486 { StdFail_NotDone::Raise
487 ("BRepExtrema_DistShapeShape::ParOnEdgeS1: There's no solution ");
489 if ((N<1)||(N>myNbSolution))
490 { Standard_OutOfRange::Raise
491 ("BRepExtrema_DistShapeShape::ParOnEdgeS1: Nth solution doesn't exist ");
494 Type = ((ListeDeSolutionShape1.Value(N)).SupportKind());
495 if (Type != BRepExtrema_IsOnEdge)
496 { BRepExtrema_UnCompatibleShape::Raise
497 ("BRepExtrema_DistShapeShape::ParOnEdgeS1:ParOnEdgeS1 is impossible without EDGE ");
500 (ListeDeSolutionShape1.Value(N)).EdgeParameter(t);
503 //=======================================================================
504 //function : ParOnEdgeS2
506 //=======================================================================
508 void BRepExtrema_DistShapeShape::ParOnEdgeS2(const Standard_Integer N, Standard_Real& t) const
510 BRepExtrema_SupportType Type;
512 if (myIsDone == Standard_False)
513 { StdFail_NotDone::Raise
514 ("BRepExtrema_DistShapeShape::ParOnEdgeS2: There's no solution ");
516 if ((N<1)||(N>myNbSolution))
517 { Standard_OutOfRange::Raise
518 ("BRepExtrema_DistShapeShape::ParOnEdgeS2: Nth solution doesn't exist ");
521 Type = ((ListeDeSolutionShape2.Value(N)).SupportKind());
522 if (Type != BRepExtrema_IsOnEdge)
523 { BRepExtrema_UnCompatibleShape::Raise
524 ("BRepExtrema_DistShapeShape::ParOnEdgeS2:ParOnEdgeS2 is impossible without EDGE ");
527 (ListeDeSolutionShape2.Value(N)).EdgeParameter(t);
530 //=======================================================================
531 //function : ParOnFaceS1
533 //=======================================================================
535 void BRepExtrema_DistShapeShape::ParOnFaceS1(const Standard_Integer N, Standard_Real& u, Standard_Real& v) const
537 BRepExtrema_SupportType Type;
539 if (myIsDone == Standard_False)
540 { StdFail_NotDone::Raise
541 ("BRepExtrema_DistShapeShape::ParOnFaceS1: There's no solution ");
543 if ((N<1)||(N>myNbSolution))
544 { Standard_OutOfRange::Raise
545 ("BRepExtrema_DistShapeShape::ParOnFaceS1: Nth solution doesn't exist ");
548 Type = ((ListeDeSolutionShape1.Value(N)).SupportKind());
549 if (Type != BRepExtrema_IsInFace)
550 { BRepExtrema_UnCompatibleShape::Raise
551 ("BRepExtrema_DistShapeShape::ParOnFaceS1:ParOnFaceS1 is impossible without FACE ");
554 (ListeDeSolutionShape1.Value(N)).FaceParameter(u, v);
557 void BRepExtrema_DistShapeShape::ParOnFaceS2(const Standard_Integer N, Standard_Real& u, Standard_Real& v) const
559 BRepExtrema_SupportType Type;
561 if (myIsDone == Standard_False)
562 { StdFail_NotDone::Raise
563 ("BRepExtrema_DistShapeShape::ParOnFaceS2: There's no solution ");
565 if ((N<1)||(N>myNbSolution))
566 { Standard_OutOfRange::Raise
567 ("BRepExtrema_DistShapeShape::ParOnFaceS2: Nth solution doesn't exist ");
569 Type = ((ListeDeSolutionShape2.Value(N)).SupportKind());
570 if (Type != BRepExtrema_IsInFace)
571 { BRepExtrema_UnCompatibleShape::Raise
572 ("BRepExtrema_DistShapeShape::ParOnFaceS2:ParOnFaceS2 is impossible without FACE ");
575 (ListeDeSolutionShape2.Value(N)).FaceParameter(u, v);
579 //=======================================================================
582 //=======================================================================
584 void BRepExtrema_DistShapeShape::Dump(Standard_OStream& o) const
588 BRepExtrema_SupportType Type1, Type2;
590 o<< "the distance value is : " << Value()<<endl;
591 o<< "the number of solutions is :"<<NbSolution()<<endl;
593 for (i=1;i<=NbSolution();i++) {
594 o<<"solution number "<<i<<": "<< endl;
595 o<<"the type of the solution on the first shape is " <<Standard_Integer( SupportTypeShape1(i)) <<endl;
596 o<<"the type of the solution on the second shape is "<<Standard_Integer( SupportTypeShape2(i))<< endl;
597 o<< "the coordinates of the point on the first shape are: "<<endl;
598 o<<"X=" <<PointOnShape1(i).X()<<" Y=" <<PointOnShape1(i).Y()<<" Z="<<PointOnShape1(i).Z()<<endl;
599 o<< "the coordinates of the point on the second shape are: "<<endl;
600 o<<"X="<< PointOnShape2(i).X()<< " Y="<<PointOnShape2(i).Y()<<" Z="<< PointOnShape2(i).Z()<<endl;
602 Type1=SupportTypeShape1(i);
603 Type2=SupportTypeShape2(i);
604 if (Type1 == BRepExtrema_IsOnEdge)
607 o << "parameter on the first edge : t= " << r1 << endl;
609 if (Type1 == BRepExtrema_IsInFace)
611 ParOnFaceS1(i,r1,r2);
612 o << "parameters on the first face : u= " << r1 << " v=" << r2 << endl;
614 if (Type2 == BRepExtrema_IsOnEdge)
617 o << "parameter on the second edge : t=" << r1 << endl;
619 if (Type2 == BRepExtrema_IsInFace)
621 ParOnFaceS2(i,r1,r2);
622 o << "parameters on the second face : u= " << r1 << " v=" << r2 << endl;