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
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.
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.
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.
21 // Modified: Mps(10-04-97) portage WNT
23 #include <BRepExtrema_DistShapeShape.hxx>
25 #include <Standard_OStream.hxx>
26 #include <TopTools_IndexedMapOfShape.hxx>
27 #include <BRepBndLib.hxx>
28 #include <Bnd_Box.hxx>
30 #include <BRepExtrema_DistanceSS.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>
44 static void Decomposition(const TopoDS_Shape& S,
45 TopTools_IndexedMapOfShape& MapV,
46 TopTools_IndexedMapOfShape& MapE,
47 TopTools_IndexedMapOfShape& MapF)
52 TopExp::MapShapes(S,TopAbs_VERTEX,MapV);
53 TopExp::MapShapes(S,TopAbs_EDGE,MapE);
54 TopExp::MapShapes(S,TopAbs_FACE,MapF);
57 static void BoxCalculation(const TopTools_IndexedMapOfShape& Map,
60 for (Standard_Integer i = 1; i <= Map.Extent(); i++)
63 BRepBndLib::Add(Map(i), box);
68 inline Standard_Real DistanceInitiale(const TopoDS_Vertex V1,
69 const TopoDS_Vertex V2)
71 return (BRep_Tool::Pnt(V1).Distance(BRep_Tool::Pnt(V2)));
74 //=======================================================================
75 //function : DistanceMapMap
77 //=======================================================================
79 void BRepExtrema_DistShapeShape::DistanceMapMap(const TopTools_IndexedMapOfShape& Map1,
80 const TopTools_IndexedMapOfShape& Map2,
81 const Bnd_SeqOfBox& LBox1,
82 const Bnd_SeqOfBox& LBox2)
84 Standard_Integer i, j;
85 BRepExtrema_SeqOfSolution seq1, seq2;
87 const Standard_Integer n1 = Map1.Extent();
88 const Standard_Integer n2 = Map2.Extent();
89 for (i = 1; i <= n1; i++)
91 const Bnd_Box &box1 = LBox1.Value(i);
92 const TopoDS_Shape &S1 = Map1(i);
93 for (j = 1; j <= n2; j++)
95 const Bnd_Box &box2= LBox2.Value(j);
96 const TopoDS_Shape &S2 = Map2(j);
98 BRepExtrema_DistanceSS dist(S1,S2,box1,box2,myDistRef,myEps);
100 if(dist.DistValue() < (myDistRef-myEps))
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();
110 else if(fabs(dist.DistValue()-myDistRef) < myEps)
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();
124 //=======================================================================
125 //function : BRepExtrema_DistShapeShape
127 //=======================================================================
129 BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape()
131 myIsDone(Standard_False),
132 myInnerSol(Standard_False),
133 myEps(Precision::Confusion()),
134 myFlag(Extrema_ExtFlag_MINMAX),
135 myAlgo(Extrema_ExtAlgo_Grad)
139 //=======================================================================
140 //function : BRepExtrema_DistShapeShape
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)
148 myIsDone(Standard_False),
149 myInnerSol(Standard_False),
150 myEps(Precision::Confusion()),
159 //=======================================================================
160 //function : BRepExtrema_DistShapeShape
162 //=======================================================================
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)
170 myIsDone(Standard_False),
171 myInnerSol(Standard_False),
172 myEps(theDeflection),
181 //=======================================================================
184 //=======================================================================
186 void BRepExtrema_DistShapeShape::LoadS1(const TopoDS_Shape& Shape1)
189 Decomposition(Shape1, myMapV1, myMapE1, myMapF1);
192 //=======================================================================
195 //=======================================================================
197 void BRepExtrema_DistShapeShape::LoadS2(const TopoDS_Shape& Shape2)
200 Decomposition(Shape2, myMapV2, myMapE2, myMapF2);
203 //=======================================================================
206 //=======================================================================
208 Standard_Boolean BRepExtrema_DistShapeShape::Perform()
210 myIsDone=Standard_False;
211 myInnerSol=Standard_False;
212 mySolutionsShape1.Clear();
213 mySolutionsShape2.Clear();
215 if ( myShape1.IsNull() || myShape2.IsNull() )
216 return Standard_False;
219 Bnd_SeqOfBox BV1, BV2, BE1, BE2, BF1, BF2;
220 const Standard_Real tol = 0.001;
222 // Treatment of solids
223 const TopAbs_ShapeEnum Type1 = myShape1.ShapeType();
224 if ((Type1==TopAbs_SOLID) || (Type1 == TopAbs_COMPSOLID))
226 BRepClass3d_SolidClassifier Classi(myShape1);
227 const Standard_Integer nbv2 = myMapV2.Extent();
228 Standard_Integer nbv1 = 0;
229 while ( (nbv1<nbv2) && (!myInnerSol) )
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)
237 myInnerSol = Standard_True;
239 myIsDone = Standard_True;
240 BRepExtrema_SolutionElem Sol(0,P,BRepExtrema_IsVertex,V);
241 mySolutionsShape1.Append(Sol);
242 mySolutionsShape2.Append(Sol);
247 const TopAbs_ShapeEnum Type2 = myShape2.ShapeType();
248 if (((Type2==TopAbs_SOLID) || (Type2==TopAbs_COMPSOLID)) && (!myInnerSol))
250 BRepClass3d_SolidClassifier Classi(myShape2);
251 const Standard_Integer nbv1 = myMapV1.Extent();
252 Standard_Integer nbv2 = 0;
253 while ( (nbv2<nbv1) && (!myInnerSol) )
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;
262 myIsDone = Standard_True;
263 BRepExtrema_SolutionElem Sol (0,P,BRepExtrema_IsVertex,V);
264 mySolutionsShape1.Append(Sol);
265 mySolutionsShape2.Append(Sol);
272 BoxCalculation(myMapV1,BV1);
273 BoxCalculation(myMapE1,BE1);
274 BoxCalculation(myMapF1,BF1);
275 BoxCalculation(myMapV2,BV2);
276 BoxCalculation(myMapE2,BE2);
277 BoxCalculation(myMapF2,BF2);
279 if (myMapV1.Extent() && myMapV2.Extent())
281 TopoDS_Vertex V1 = TopoDS::Vertex(myMapV1(1));
282 TopoDS_Vertex V2 = TopoDS::Vertex(myMapV2(1));
283 myDistRef = DistanceInitiale(V1, V2);
286 myDistRef= 1.e30; //szv:!!!
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);
297 if( (fabs(myDistRef)) > myEps )
298 DistanceMapMap(myMapF1,myMapF2,BF1,BF2);
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)
305 mySolutionsShape1.Remove(i);
306 mySolutionsShape2.Remove(i);
308 // Modified by Sergey KHROMOV - Tue Mar 6 11:55:04 2001 End
309 myIsDone = ( mySolutionsShape1.Length() > 0 );
314 //=======================================================================
317 //=======================================================================
319 Standard_Real BRepExtrema_DistShapeShape::Value() const
322 StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::Value: There's no solution ");
327 //=======================================================================
328 //function : SupportOnShape1
330 //=======================================================================
332 TopoDS_Shape BRepExtrema_DistShapeShape::SupportOnShape1(const Standard_Integer N) const
335 StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::SupportOnShape1: There's no solution ");
337 const BRepExtrema_SolutionElem &sol = mySolutionsShape1.Value(N);
338 switch (sol.SupportKind())
340 case BRepExtrema_IsVertex : return sol.Vertex();
341 case BRepExtrema_IsOnEdge : return sol.Edge();
342 case BRepExtrema_IsInFace : return sol.Face();
344 return TopoDS_Shape();
347 //=======================================================================
348 //function : SupportOnShape2
350 //=======================================================================
352 TopoDS_Shape BRepExtrema_DistShapeShape::SupportOnShape2(const Standard_Integer N) const
355 StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::SupportOnShape2: There's no solution ");
357 const BRepExtrema_SolutionElem &sol = mySolutionsShape2.Value(N);
358 switch (sol.SupportKind())
360 case BRepExtrema_IsVertex : return sol.Vertex();
361 case BRepExtrema_IsOnEdge : return sol.Edge();
362 case BRepExtrema_IsInFace : return sol.Face();
364 return TopoDS_Shape();
367 //=======================================================================
368 //function : ParOnEdgeS1
370 //=======================================================================
372 void BRepExtrema_DistShapeShape::ParOnEdgeS1(const Standard_Integer N, Standard_Real& t) const
375 StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::ParOnEdgeS1: There's no solution");
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");
382 sol.EdgeParameter(t);
385 //=======================================================================
386 //function : ParOnEdgeS2
388 //=======================================================================
390 void BRepExtrema_DistShapeShape::ParOnEdgeS2(const Standard_Integer N, Standard_Real& t) const
393 StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::ParOnEdgeS2: There's no solution");
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");
400 sol.EdgeParameter(t);
403 //=======================================================================
404 //function : ParOnFaceS1
406 //=======================================================================
408 void BRepExtrema_DistShapeShape::ParOnFaceS1(const Standard_Integer N, Standard_Real& u, Standard_Real& v) const
411 StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::ParOnFaceS1: There's no solution");
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");
418 sol.FaceParameter(u, v);
421 //=======================================================================
422 //function : ParOnFaceS2
424 //=======================================================================
426 void BRepExtrema_DistShapeShape::ParOnFaceS2(const Standard_Integer N, Standard_Real& u, Standard_Real& v) const
429 StdFail_NotDone::Raise("BRepExtrema_DistShapeShape::ParOnFaceS2: There's no solution");
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 ");
436 sol.FaceParameter(u, v);
439 //=======================================================================
442 //=======================================================================
444 void BRepExtrema_DistShapeShape::Dump(Standard_OStream& o) const
449 o<< "the distance value is : " << Value()<<endl;
450 o<< "the number of solutions is :"<<NbSolution()<<endl;
452 for (i=1;i<=NbSolution();i++)
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;
462 switch (SupportTypeShape1(i))
464 case BRepExtrema_IsOnEdge:
466 o << "parameter on the first edge : t= " << r1 << endl;
468 case BRepExtrema_IsInFace:
469 ParOnFaceS1(i,r1,r2);
470 o << "parameters on the first face : u= " << r1 << " v=" << r2 << endl;
473 switch (SupportTypeShape2(i))
475 case BRepExtrema_IsOnEdge:
477 o << "parameter on the second edge : t=" << r1 << endl;
479 case BRepExtrema_IsInFace:
480 ParOnFaceS2(i,r1,r2);
481 o << "parameters on the second face : u= " << r1 << " v=" << r2 << endl;