1 // Created on: 1996-04-22
2 // Created by: Herve LOUESSARD
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 // Modified: Sergey ZERCHANINOV
19 #include <BRepExtrema_DistanceSS.hxx>
21 #include <TopTools_IndexedMapOfShape.hxx>
24 #include <gp_Pnt2d.hxx>
25 #include <BRep_Tool.hxx>
26 #include <BRepExtrema_SupportType.hxx>
27 #include <Standard_Real.hxx>
28 #include <BRepExtrema_SolutionElem.hxx>
29 #include <BRepExtrema_SeqOfSolution.hxx>
30 #include <Standard_Boolean.hxx>
31 #include <Standard_Integer.hxx>
32 #include <TopAbs_ShapeEnum.hxx>
34 #include <Bnd_Box.hxx>
35 #include <BRepExtrema_ExtPC.hxx>
36 #include <BRepExtrema_ExtPF.hxx>
37 #include <Extrema_ExtFlag.hxx>
38 #include <BRepExtrema_ExtCC.hxx>
39 #include <BRepExtrema_ExtCF.hxx>
40 #include <BRepExtrema_ExtFF.hxx>
41 #include <BRepClass_FaceClassifier.hxx>
43 #include <Geom_Curve.hxx>
44 #include <GeomAbs_Shape.hxx>
45 #include <GeomAdaptor_Curve.hxx>
46 #include <TColStd_Array1OfReal.hxx>
47 #include <BRepBuilderAPI_MakeVertex.hxx>
48 #include <BRepBuilderAPI_MakeEdge.hxx>
49 #include <BRepBuilderAPI_MakeFace.hxx>
50 #include <Geom_Surface.hxx>
51 #include <GeomAPI_ProjectPointOnSurf.hxx>
52 #include <GeomAPI_ProjectPointOnCurve.hxx>
53 #include <Geom_RectangularTrimmedSurface.hxx>
54 #include <Geom_TrimmedCurve.hxx>
55 #include <BRepBndLib.hxx>
56 #include <BRepTools.hxx>
57 #include <TColgp_Array1OfPnt.hxx>
60 /*********************************************************************************/
62 //------------------------------------------------------------------------------
63 // function: TRI_SOLUTION
64 //------------------------------------------------------------------------------
65 static Standard_Boolean TRI_SOLUTION (const BRepExtrema_SeqOfSolution& SeqSol, const gp_Pnt& Pt)
67 for (BRepExtrema_SeqOfSolution::iterator anIt = SeqSol.begin(); anIt != SeqSol.end(); anIt++)
69 const Standard_Real dst = anIt->Point().Distance(Pt);
70 if (dst <= Precision::Confusion())
72 return Standard_False;
78 //------------------------------------------------------------------------------
79 // function: MIN_SOLUTION
80 //------------------------------------------------------------------------------
81 static void MIN_SOLUTION (const BRepExtrema_SeqOfSolution& SeqSol1,
82 const BRepExtrema_SeqOfSolution& SeqSol2,
83 const Standard_Real DstRef,
84 const Standard_Real Eps,
85 BRepExtrema_SeqOfSolution& seqSol1,
86 BRepExtrema_SeqOfSolution& seqSol2)
88 for (BRepExtrema_SeqOfSolution::iterator anIt1 = SeqSol1.begin(), anIt2 = SeqSol2.begin();
89 anIt1 != SeqSol1.end();
92 const Standard_Real dst1 = anIt1->Dist();
93 if (fabs(dst1 - DstRef) < Eps)
95 seqSol1.Append(*anIt1);
96 seqSol2.Append(*anIt2);
101 //------------------------------------------------------------------------------
102 // function: TRIM_INFINIT_EDGE
103 //------------------------------------------------------------------------------
104 static void TRIM_INFINIT_EDGE(const TopoDS_Edge& S1, const TopoDS_Edge& S2, TopoDS_Edge& aResEdge,
105 Standard_Boolean& bIsTrim1, Standard_Boolean& bIsTrim2)
107 if ( BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2) )
111 Standard_Real aFirst1, aLast1, aFirst2, aLast2;
112 Handle(Geom_Curve) pCurv1 = BRep_Tool::Curve(S1, aFirst1, aLast1);
113 Handle(Geom_Curve) pCurv2 = BRep_Tool::Curve(S2, aFirst2, aLast2);
115 if (Precision::IsInfinite(aFirst1) &&
116 Precision::IsInfinite(aLast1) &&
117 Precision::IsInfinite(aFirst2) &&
118 Precision::IsInfinite(aLast2))
121 Standard_Real Umin = 0., Umax = 0.;
122 Standard_Boolean bUmin, bUmax;
123 bUmin = bUmax = Standard_False;
125 Handle(Geom_Curve) pCurv;
126 if ( !pCurv1.IsNull() && (Precision::IsInfinite(aFirst1) || Precision::IsInfinite(aLast1)) )
129 bIsTrim1 = Standard_True;
130 if (!Precision::IsInfinite(aFirst1))
132 bUmin = Standard_True;
135 else if (!Precision::IsInfinite(aLast1))
137 bUmax = Standard_True;
141 else if ( !pCurv2.IsNull() && (Precision::IsInfinite(aFirst2) || Precision::IsInfinite(aLast2)) )
144 bIsTrim2 = Standard_True;
145 if (!Precision::IsInfinite(aFirst2))
147 bUmin = Standard_True;
150 else if (!Precision::IsInfinite(aLast2))
152 bUmax = Standard_True;
156 if (bIsTrim1 || bIsTrim2)
160 BRepBndLib::Add(S2, aEdgeBox);
162 BRepBndLib::Add(S1, aEdgeBox);
163 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
164 aEdgeBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
166 const gp_Pnt aPnt0(Xmin, Ymin, Zmin);
167 const gp_Pnt aPnt1(Xmin, Ymax, Zmin);
168 const gp_Pnt aPnt2(Xmin, Ymax, Zmax);
169 const gp_Pnt aPnt3(Xmin, Ymin, Zmax);
170 const gp_Pnt aPnt4(Xmax, Ymax, Zmin);
171 const gp_Pnt aPnt5(Xmax, Ymax, Zmax);
172 const gp_Pnt aPnt6(Xmax, Ymin, Zmax);
173 const gp_Pnt aPnt7(Xmax, Ymin, Zmin);
175 Standard_Real arrU[8];
176 GeomAPI_ProjectPointOnCurve aProj(aPnt0, pCurv);
177 /*szv:aProj.Perform(aPnt0);*/ arrU[0] = aProj.LowerDistanceParameter();
178 aProj.Perform(aPnt1); arrU[1] = aProj.LowerDistanceParameter();
179 aProj.Perform(aPnt2); arrU[2] = aProj.LowerDistanceParameter();
180 aProj.Perform(aPnt3); arrU[3] = aProj.LowerDistanceParameter();
181 aProj.Perform(aPnt4); arrU[4] = aProj.LowerDistanceParameter();
182 aProj.Perform(aPnt5); arrU[5] = aProj.LowerDistanceParameter();
183 aProj.Perform(aPnt6); arrU[6] = aProj.LowerDistanceParameter();
184 aProj.Perform(aPnt7); arrU[7] = aProj.LowerDistanceParameter();
192 Standard_Integer i = 0;
195 const Standard_Real aU = arrU[i++];
202 Standard_Real tol = Precision::Confusion();
204 tol = BRep_Tool::Tolerance(S1);
206 tol = BRep_Tool::Tolerance(S2);
208 const Standard_Real EpsU = GeomAdaptor_Curve(pCurv).Resolution(3.*tol);
209 if (fabs(Umin - Umax) < EpsU)
215 Handle(Geom_Curve) result = new Geom_TrimmedCurve(pCurv, Umin, Umax);
216 aResEdge = BRepBuilderAPI_MakeEdge(result);
220 //------------------------------------------------------------------------------
221 // function: TRIM_INFINIT_FACE
222 //------------------------------------------------------------------------------
223 static void TRIM_INFINIT_FACE(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
224 TopoDS_Face& aResFace, Standard_Boolean& bIsInfinit)
226 bIsInfinit = Standard_False;
228 TopAbs_ShapeEnum Type1 = S1.ShapeType();
229 TopAbs_ShapeEnum Type2 = S2.ShapeType();
234 if (Type1 == TopAbs_EDGE && Type2 == TopAbs_FACE)
236 aE = TopoDS::Edge(S1);
237 if ( BRep_Tool::Degenerated(aE) )
239 aF = TopoDS::Face(S2);
241 else if (Type2 == TopAbs_EDGE && Type1 == TopAbs_FACE)
243 aE = TopoDS::Edge(S2);
244 if ( BRep_Tool::Degenerated(aE) )
246 aF = TopoDS::Face(S1);
250 bIsInfinit = Standard_False;
255 Handle(Geom_Surface) pSurf = BRep_Tool::Surface(aF);
257 const Standard_Boolean bRestrict = BRep_Tool::NaturalRestriction(aF);
259 Standard_Real U1, V1, U2, V2;
260 Standard_Real Umin = RealLast(), Umax = RealFirst(), Vmin = RealLast(), Vmax = RealFirst();
261 Standard_Boolean bUmin, bUmax, bVmin, bVmax;
262 bUmin = bUmax = bVmin = bVmax = Standard_False;
263 Standard_Boolean bIsTrim = Standard_False;
267 pSurf->Bounds(U1, U2, V1, V2);
268 if (Precision::IsInfinite(U1))
269 bIsTrim = Standard_True;
273 bUmin = Standard_True;
276 if (Precision::IsInfinite(U2))
277 bIsTrim = Standard_True;
281 bUmax = Standard_True;
284 if (Precision::IsInfinite(V1))
285 bIsTrim = Standard_True;
289 bVmin = Standard_True;
292 if (Precision::IsInfinite(V2))
293 bIsTrim = Standard_True;
297 bVmax = Standard_True;
302 BRepTools::UVBounds(aF, U1, U2, V1, V2);
303 if (Precision::IsInfinite(U1) &&
304 Precision::IsInfinite(U2) &&
305 Precision::IsInfinite(V1) &&
306 Precision::IsInfinite(V2))
307 bIsTrim = Standard_True;
313 BRepBndLib::Add(aE, aEdgeBox);
315 if(aEdgeBox.IsWhole())
318 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
319 aEdgeBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
321 const gp_Pnt aPnt0(Xmin, Ymin, Zmin);
322 const gp_Pnt aPnt1(Xmin, Ymax, Zmin);
323 const gp_Pnt aPnt2(Xmin, Ymax, Zmax);
324 const gp_Pnt aPnt3(Xmin, Ymin, Zmax);
325 const gp_Pnt aPnt4(Xmax, Ymax, Zmin);
326 const gp_Pnt aPnt5(Xmax, Ymax, Zmax);
327 const gp_Pnt aPnt6(Xmax, Ymin, Zmax);
328 const gp_Pnt aPnt7(Xmax, Ymin, Zmin);
330 Standard_Real arrU[8], arrV[8];
331 GeomAPI_ProjectPointOnSurf aProj(aPnt0, pSurf);
332 /*szv:aProj.Perform(aPnt0);*/ if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[0],arrV[0]);
333 aProj.Perform(aPnt1); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[1],arrV[1]);
334 aProj.Perform(aPnt2); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[2],arrV[2]);
335 aProj.Perform(aPnt3); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[3],arrV[3]);
336 aProj.Perform(aPnt4); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[4],arrV[4]);
337 aProj.Perform(aPnt5); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[5],arrV[5]);
338 aProj.Perform(aPnt6); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[6],arrV[6]);
339 aProj.Perform(aPnt7); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[7],arrV[7]);
350 Standard_Integer i = 0;
353 const Standard_Real aU = arrU[i];
359 const Standard_Real aV = arrV[i];
368 GeomAdaptor_Surface aGAS(pSurf);
369 const Standard_Real tol = BRep_Tool::Tolerance(aF);
371 const Standard_Real EpsU = aGAS.UResolution(3.*tol);
372 if (fabs(Umin - Umax) < EpsU)
378 const Standard_Real EpsV = aGAS.VResolution(3.*tol);
379 if (fabs(Vmin - Vmax) < EpsV)
385 Handle(Geom_Surface) result = new Geom_RectangularTrimmedSurface(pSurf, Umin, Umax, Vmin, Vmax);
386 aResFace = BRepBuilderAPI_MakeFace(result, Precision::Confusion());
388 bIsInfinit = Standard_True;
391 bIsInfinit = Standard_False;
394 //------------------------------------------------------------------------------
395 // static function: PERFORM_C0
396 //------------------------------------------------------------------------------
397 static void PERFORM_C0(const TopoDS_Edge &S1, const TopoDS_Edge &S2,
398 BRepExtrema_SeqOfSolution& SeqSol1,
399 BRepExtrema_SeqOfSolution& SeqSol2,
400 const Standard_Real DstRef,
401 Standard_Real& mDstRef,
402 const Standard_Real Eps)
404 if ( BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2) )
408 for (iE = 0; iE < 2; iE++)
410 TopoDS_Edge E, Eother;
422 Standard_Real aFirst, aLast;
423 Handle(Geom_Curve) pCurv = BRep_Tool::Curve(E, aFirst, aLast);
425 Standard_Real aFOther, aLOther;
426 Handle(Geom_Curve) pCurvOther = BRep_Tool::Curve(Eother, aFOther, aLOther);
428 if (pCurv->Continuity() == GeomAbs_C0)
430 const Standard_Real epsP = Precision::PConfusion();
432 GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
433 const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
435 TColStd_Array1OfReal arrInter(1,1+nbIntervals);
436 aAdaptorCurve.Intervals(arrInter, GeomAbs_C1);
438 GeomAdaptor_Curve aAdaptorCurveOther(pCurvOther, aFOther, aLOther);
439 const Standard_Integer nbIntervalsOther = aAdaptorCurveOther.NbIntervals(GeomAbs_C1);
440 TColStd_Array1OfReal arrInterOther(1,1+nbIntervalsOther);
441 aAdaptorCurveOther.Intervals(arrInterOther, GeomAbs_C1);
443 Standard_Real Udeb,Ufin;
444 BRep_Tool::Range(Eother,Udeb,Ufin);
447 Standard_Integer i, ii;
448 BRepClass_FaceClassifier classifier;
449 for (i = 1; i <= arrInter.Length(); i++)
451 const Standard_Real aParameter = arrInter(i);
452 const gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
453 const TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
455 BRepExtrema_ExtPC Ext(V1,Eother);
456 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
459 // Search minimum distance dstmin
460 Standard_Real Dstmin = Ext.SquareDistance(1);
461 for (ii = 2; ii <= NbExtrema; ii++)
463 const Standard_Real sDst = Ext.SquareDistance(ii);
467 Dstmin = sqrt(Dstmin);
469 if ((Dstmin < DstRef - Eps) || (fabs(Dstmin-DstRef) < Eps))
470 for (ii = 1; ii <= NbExtrema; ii++)
472 if (fabs(Dstmin-sqrt(Ext.SquareDistance(ii)))<Eps)
475 if (TRI_SOLUTION(SeqSol2,Pt))
477 // Check if the parameter does not correspond to a vertex
478 const Standard_Real t = Ext.Parameter(ii);
479 if ((fabs(t-Udeb)>=epsP)&&(fabs(t-Ufin)>epsP))
481 if (mDstRef > Dstmin)
483 const BRepExtrema_SolutionElem Sol1(Dstmin,aPnt,BRepExtrema_IsOnEdge,E,aParameter);
484 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsOnEdge,Eother,t);
485 SeqSol1.Append(iE == 0 ? Sol1 : Sol2);
486 SeqSol2.Append(iE == 0 ? Sol2 : Sol1);
492 for (Standard_Integer i2 = 1; i2<=arrInterOther.Length(); i2++)
494 const Standard_Real aParameterOther = arrInterOther(i2);
495 const gp_Pnt aPntOther = aAdaptorCurveOther.Value(aParameterOther);
496 const Standard_Real Dst = aPnt.Distance(aPntOther);
497 if ((Dst < DstRef - Eps) || (fabs(Dst-DstRef) < Eps))
501 const BRepExtrema_SolutionElem Sol1(Dst,aPnt,BRepExtrema_IsOnEdge,E,aParameter);
502 const BRepExtrema_SolutionElem Sol2(Dst,aPntOther,BRepExtrema_IsOnEdge,Eother,aParameterOther);
503 SeqSol1.Append(iE == 0 ? Sol1 : Sol2);
504 SeqSol2.Append(iE == 0 ? Sol2 : Sol1);
512 /*********************************************************************************/
514 void BRepExtrema_DistanceSS::Perform(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
515 const Bnd_Box& B1, const Bnd_Box& B2)
517 SeqSolShape1.Clear();
518 SeqSolShape2.Clear();
519 myModif=Standard_False;
521 switch (S1.ShapeType())
525 TopoDS_Vertex V1 = TopoDS::Vertex(S1);
526 switch (S2.ShapeType())
530 TopoDS_Vertex V2 = TopoDS::Vertex(S2);
536 TopoDS_Edge E2 = TopoDS::Edge(S2);
537 Perform( V1, E2, B1, B2 );
542 TopoDS_Face F2 = TopoDS::Face(S2);
543 Perform( V1, F2, B1, B2 );
554 TopoDS_Edge E1 = TopoDS::Edge(S1);
555 switch (S2.ShapeType())
559 TopoDS_Vertex V2 = TopoDS::Vertex(S2);
560 Perform( E1, V2, B1, B2 );
565 TopoDS_Edge E2 = TopoDS::Edge(S2);
566 TopoDS_Edge aTrimEdge;
567 Standard_Boolean bIsTrim1 = Standard_False;
568 Standard_Boolean bIsTrim2 = Standard_False;
569 TRIM_INFINIT_EDGE( E1, E2, aTrimEdge, bIsTrim1, bIsTrim2 );
574 Perform( E1, E2, B1, B2 );
579 TopoDS_Face F2 = TopoDS::Face(S2);
580 TopoDS_Face aTrimFace;
581 Standard_Boolean bIsInfinit;
582 TRIM_INFINIT_FACE( E1, F2, aTrimFace, bIsInfinit );
585 Perform( E1, F2, B1, B2 );
596 TopoDS_Face F1 = TopoDS::Face(S1);
597 switch (S2.ShapeType())
601 TopoDS_Vertex V2 = TopoDS::Vertex(S2);
602 Perform( F1, V2, B1, B2 );
607 TopoDS_Edge E2 = TopoDS::Edge(S2);
608 TopoDS_Face aTrimFace;
609 Standard_Boolean bIsInfinit;
610 TRIM_INFINIT_FACE( F1, E2, aTrimFace, bIsInfinit );
613 Perform( F1, E2, B1, B2 );
618 TopoDS_Face F2 = TopoDS::Face(S2);
619 Perform( F1, F2, B1, B2 );
632 /*********************************************************************************/
634 void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Vertex& S2)
636 const gp_Pnt P1 = BRep_Tool::Pnt(S1);
637 const gp_Pnt P2 = BRep_Tool::Pnt(S2);
639 const Standard_Real Dst = P1.Distance(P2);
640 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
644 myModif=Standard_True;
645 const BRepExtrema_SolutionElem Sol1(Dst,P1,BRepExtrema_IsVertex,S1);
646 const BRepExtrema_SolutionElem Sol2(Dst,P2,BRepExtrema_IsVertex,S2);
647 SeqSolShape1.Append(Sol1);
648 SeqSolShape2.Append(Sol2);
652 /*********************************************************************************/
654 void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Edge& S2,
655 const Bnd_Box& B1, const Bnd_Box& B2)
657 if (BRep_Tool::Degenerated(S2))
660 const Standard_Real Dst=B1.Distance(B2);
661 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
663 BRepExtrema_ExtPC Ext(S1,S2);
664 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
667 // Search minimum distance Dstmin
669 Standard_Real Dstmin = Ext.SquareDistance(1);
670 for (i = 2; i <= NbExtrema; i++)
672 const Standard_Real sDst = Ext.SquareDistance(i);
676 Dstmin = sqrt(Dstmin);
677 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
679 Standard_Real Udeb,Ufin;
680 BRep_Tool::Range(S2,Udeb,Ufin);
682 gp_Pnt Pt,P1=BRep_Tool::Pnt(S1);
683 const Standard_Real epsP=Precision::PConfusion();
685 for (i = 1; i <= NbExtrema; i++)
687 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
690 if (TRI_SOLUTION(SeqSolShape2,Pt))
692 // Check if the parameter does not correspond to a vertex
693 const Standard_Real t = Ext.Parameter(i);
694 if ( (fabs(t-Udeb)>=epsP) && (fabs(t-Ufin)>epsP) )
696 if (myDstRef > Dstmin)
698 myModif=Standard_True;
699 const BRepExtrema_SolutionElem Sol1(Dstmin,P1,BRepExtrema_IsVertex,S1);
700 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsOnEdge,S2,t);
701 SeqSolShape1.Append(Sol1);
702 SeqSolShape2.Append(Sol2);
712 void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1,const TopoDS_Vertex& S2,
713 const Bnd_Box& B1,const Bnd_Box& B2)
715 if (BRep_Tool::Degenerated(S1))
718 const Standard_Real Dst=B1.Distance(B2);
719 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
721 BRepExtrema_ExtPC Ext(S2,S1);
722 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
725 // Search minimum distance Dstmin
727 Standard_Real Dstmin = Ext.SquareDistance(1);
728 for (i = 2; i <= NbExtrema; i++)
730 const Standard_Real sDst = Ext.SquareDistance(i);
734 Dstmin = sqrt(Dstmin);
735 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
737 Standard_Real Udeb,Ufin;
738 BRep_Tool::Range(S1,Udeb,Ufin);
740 gp_Pnt Pt, P2 = BRep_Tool::Pnt(S2);
741 const Standard_Real epsP=Precision::PConfusion();
743 for (i = 1; i <= NbExtrema; i++)
745 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
748 if (TRI_SOLUTION(SeqSolShape1,Pt))
750 // Check if the parameter does not correspond to a vertex
751 const Standard_Real t = Ext.Parameter(i);
752 if ( (fabs(t-Udeb)>=epsP) && (fabs(t-Ufin)>epsP) )
754 if (myDstRef > Dstmin)
756 myModif=Standard_True;
757 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt,BRepExtrema_IsOnEdge,S1,t);
758 const BRepExtrema_SolutionElem Sol2(Dstmin,P2,BRepExtrema_IsVertex,S2);
759 SeqSolShape1.Append(Sol1);
760 SeqSolShape2.Append(Sol2);
770 /*********************************************************************************/
772 void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Face& S2,
773 const Bnd_Box& B1, const Bnd_Box& B2)
775 const Standard_Real Dst=B1.Distance(B2);
776 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
778 BRepExtrema_ExtPF Ext(S1,S2,myFlag,myAlgo);
779 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
782 // Search minimum distance Dstmin
784 Standard_Real Dstmin = Ext.SquareDistance(1);
785 for (i = 2; i <= NbExtrema; i++)
787 const Standard_Real sDst = Ext.SquareDistance(i);
791 Dstmin = sqrt(Dstmin);
792 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
795 gp_Pnt Pt,P1=BRep_Tool::Pnt(S1);
796 BRepClass_FaceClassifier classifier;
797 const Standard_Real tol = BRep_Tool::Tolerance(S2);
799 for (i = 1; i <= NbExtrema; i++)
801 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
804 if (TRI_SOLUTION(SeqSolShape2,Pt))
806 // Check if the parameter does not correspond to a vertex
807 Ext.Parameter(i,U,V);
808 const gp_Pnt2d PUV(U,V);
809 classifier.Perform(S2,PUV,tol);
810 if (classifier.State()==TopAbs_IN)
812 if (myDstRef > Dstmin)
814 myModif=Standard_True;
815 const BRepExtrema_SolutionElem Sol1(Dstmin,P1,BRepExtrema_IsVertex,S1);
816 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsInFace,S2,U,V);
817 SeqSolShape1.Append(Sol1);
818 SeqSolShape2.Append(Sol2);
828 void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Vertex& S2,
829 const Bnd_Box& B1, const Bnd_Box& B2)
831 const Standard_Real Dst=B1.Distance(B2);
832 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
834 BRepExtrema_ExtPF Ext(S2,S1,myFlag,myAlgo);
835 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
838 // Search minimum distance Dstmin
840 Standard_Real Dstmin = Ext.SquareDistance(1);
841 for (i = 2; i <= NbExtrema; i++)
843 const Standard_Real sDst = Ext.SquareDistance(i);
847 Dstmin = sqrt(Dstmin);
848 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
851 gp_Pnt Pt,P2=BRep_Tool::Pnt(S2);
852 BRepClass_FaceClassifier classifier;
853 const Standard_Real tol = BRep_Tool::Tolerance(S1);
855 for (i = 1; i <= NbExtrema; i++)
857 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
860 if (TRI_SOLUTION(SeqSolShape1,Pt))
862 // Check if the parameter does not correspond to a vertex
863 Ext.Parameter(i,U,V);
864 const gp_Pnt2d PUV(U,V);
865 classifier.Perform(S1,PUV,tol);
866 if (classifier.State()==TopAbs_IN)
868 if (myDstRef > Dstmin)
870 myModif=Standard_True;
871 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt,BRepExtrema_IsInFace,S1,U,V);
872 const BRepExtrema_SolutionElem Sol2(Dstmin,P2,BRepExtrema_IsVertex,S2);
873 SeqSolShape1.Append(Sol1);
874 SeqSolShape2.Append(Sol2);
884 /*********************************************************************************/
886 void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Edge& S2,
887 const Bnd_Box& B1, const Bnd_Box& B2)
889 if (BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2))
892 const Standard_Real Dst=B1.Distance(B2);
893 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
895 const Standard_Real DstRef = myDstRef;
897 BRepExtrema_ExtCC Ext(S1,S2);
898 const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
901 // Search minimum distance Dstmin
903 Standard_Real Dstmin = Ext.SquareDistance(1);
904 for (i = 2; i <= NbExtrema; i++)
906 const Standard_Real sDst = Ext.SquareDistance(i);
910 Dstmin = sqrt(Dstmin);
911 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
913 Standard_Real Udeb1,Ufin1,Udeb2,Ufin2;
914 BRep_Tool::Range(S1,Udeb1,Ufin1);
915 BRep_Tool::Range(S2,Udeb2,Ufin2);
918 const Standard_Real epsP=Precision::PConfusion();
920 for (i=1;i<=NbExtrema;i++)
922 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
924 Pt1=Ext.PointOnE1(i);
925 Pt2=Ext.PointOnE2(i);
926 if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
928 // Check if the parameters do not correspond to a vertex
929 const Standard_Real t1 = Ext.ParameterOnE1(i);
930 const Standard_Real t2 = Ext.ParameterOnE2(i);
931 if ((fabs(t1-Udeb1)>=epsP)&&(fabs(t1-Ufin1)>epsP)&&(fabs(t2-Udeb2)>=epsP)&&(fabs(t2-Ufin2)>epsP))
933 if (myDstRef > Dstmin)
935 myModif=Standard_True;
936 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsOnEdge,S1,t1);
937 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsOnEdge,S2,t2);
938 SeqSolShape1.Append(Sol1);
939 SeqSolShape2.Append(Sol2);
947 BRepExtrema_SeqOfSolution SeqSolution1;
948 BRepExtrema_SeqOfSolution SeqSolution2;
950 PERFORM_C0(S1, S2, SeqSolution1, SeqSolution2, DstRef, myDstRef, myEps);
952 BRepExtrema_SeqOfSolution seqSol1;
953 BRepExtrema_SeqOfSolution seqSol2;
955 if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
956 MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
958 if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
960 SeqSolShape1.Append(seqSol1);
961 SeqSolShape2.Append(seqSol2);
962 myModif = Standard_True;
967 /*********************************************************************************/
969 void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Face& S2,
970 const Bnd_Box& B1, const Bnd_Box& B2)
972 if (BRep_Tool::Degenerated(S1))
975 const Standard_Real Dst=B1.Distance(B2);
976 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
978 BRepClass_FaceClassifier classifier;
980 BRepExtrema_ExtCF Ext(S1,S2);
981 const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
984 // Search minimum distance Dstmin
986 Standard_Real Dstmin = Ext.SquareDistance(1);
987 for (i = 2; i <= NbExtrema; i++)
989 const Standard_Real sDst = Ext.SquareDistance(i);
993 Dstmin = sqrt(Dstmin);
994 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
996 Standard_Real Udeb,Ufin,U,V;
997 BRep_Tool::Range(S1,Udeb,Ufin);
998 const Standard_Real tol=BRep_Tool::Tolerance(S2);
1001 const Standard_Real epsP=Precision::PConfusion();
1003 for (i = 1; i <= NbExtrema; i++)
1005 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
1007 Pt1=Ext.PointOnEdge(i);
1008 Pt2=Ext.PointOnFace(i);
1009 if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
1011 // Check if the parameter does not correspond to a vertex
1012 const Standard_Real t1 = Ext.ParameterOnEdge(i);
1013 if ((fabs(t1-Udeb)>=epsP)&&(fabs(t1-Ufin)>epsP))
1015 Ext.ParameterOnFace(i,U,V);
1016 const gp_Pnt2d PUV(U,V);
1017 classifier.Perform(S2,PUV,tol);
1018 if (classifier.State()==TopAbs_IN)
1020 if (myDstRef > Dstmin)
1022 myModif=Standard_True;
1023 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsOnEdge,S1,t1);
1024 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsInFace,S2,U,V);
1025 SeqSolShape1.Append(Sol1);
1026 SeqSolShape2.Append(Sol2);
1035 Standard_Real aFirst, aLast;
1036 Handle(Geom_Curve) pCurv = BRep_Tool::Curve(S1, aFirst, aLast);
1037 if (pCurv->Continuity() == GeomAbs_C0)
1039 BRepExtrema_SeqOfSolution SeqSolution1;
1040 BRepExtrema_SeqOfSolution SeqSolution2;
1042 GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
1043 const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
1045 TColStd_Array1OfReal arrInter(1,1+nbIntervals);
1046 aAdaptorCurve.Intervals(arrInter, GeomAbs_C1);
1050 const Standard_Real tol = BRep_Tool::Tolerance(S2);
1053 for (i = 1; i <= arrInter.Length(); i++)
1055 const Standard_Real aParameter = arrInter(i);
1056 gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
1057 TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
1059 BRepExtrema_ExtPF ExtPF(V1,S2);
1060 const Standard_Integer NbExtremaPF = ExtPF.IsDone()? ExtPF.NbExt() : 0;
1061 if (NbExtremaPF > 0 )
1063 // Search minimum distance Dstmin
1064 Standard_Integer ii;
1065 Standard_Real Dstmin = ExtPF.SquareDistance(1);
1066 for (ii = 2; ii <= NbExtremaPF; ii++)
1068 const Standard_Real sDst = ExtPF.SquareDistance(ii);
1072 Dstmin = sqrt(Dstmin);
1074 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1076 for (ii = 1; ii <= NbExtremaPF; ii++)
1078 if (fabs(Dstmin-sqrt(ExtPF.SquareDistance(ii)))<myEps)
1080 // Check if the parameter does not correspond to a vertex
1081 ExtPF.Parameter(ii,U,V);
1082 const gp_Pnt2d PUV(U,V);
1083 classifier.Perform(S2,PUV,tol);
1084 if (classifier.State()==TopAbs_IN)
1086 if (myDstRef > Dstmin)
1088 myModif=Standard_True;
1089 const BRepExtrema_SolutionElem Sol1(Dstmin,aPnt,BRepExtrema_IsOnEdge,S1,aParameter);
1090 const BRepExtrema_SolutionElem Sol2(Dstmin,ExtPF.Point(ii),BRepExtrema_IsInFace,S2,U,V);
1091 SeqSolution1.Append(Sol1);
1092 SeqSolution2.Append(Sol2);
1100 BRepExtrema_SeqOfSolution seqSol1;
1101 BRepExtrema_SeqOfSolution seqSol2;
1102 if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
1103 MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
1105 if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
1107 SeqSolShape1.Append(seqSol1);
1108 SeqSolShape2.Append(seqSol2);
1114 void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Edge& S2,
1115 const Bnd_Box& B1, const Bnd_Box& B2)
1117 if (BRep_Tool::Degenerated(S2))
1120 const Standard_Real Dst=B1.Distance(B2);
1121 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
1123 BRepClass_FaceClassifier classifier;
1125 BRepExtrema_ExtCF Ext(S2,S1);
1126 const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
1127 if ( NbExtrema > 0 )
1129 // Search minimum distance Dstmin
1131 Standard_Real Dstmin = Ext.SquareDistance(1);
1132 for (i = 2; i <= NbExtrema; i++)
1134 const Standard_Real sDst = Ext.SquareDistance(i);
1138 Dstmin = sqrt(Dstmin);
1139 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1141 Standard_Real Udeb,Ufin,U,V;
1142 BRep_Tool::Range(S2,Udeb,Ufin);
1143 const Standard_Real tol=BRep_Tool::Tolerance(S1);
1146 const Standard_Real epsP=Precision::PConfusion();
1148 for (i = 1; i <= NbExtrema; i++)
1150 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
1152 Pt1=Ext.PointOnEdge(i);
1153 Pt2=Ext.PointOnFace(i);
1154 if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
1156 // Check if the parameter does not correspond to a vertex
1157 const Standard_Real t1 = Ext.ParameterOnEdge(i);
1158 if ((fabs(t1-Udeb)>=epsP)&&(fabs(t1-Ufin)>epsP))
1160 Ext.ParameterOnFace(i,U,V);
1161 const gp_Pnt2d PUV(U,V);
1162 classifier.Perform(S1,PUV,tol);
1163 if (classifier.State()==TopAbs_IN)
1165 if (myDstRef > Dstmin)
1167 myModif=Standard_True;
1168 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt1,BRepExtrema_IsOnEdge,S2,t1);
1169 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt2,BRepExtrema_IsInFace,S1,U,V);
1170 SeqSolShape1.Append(Sol1);
1171 SeqSolShape2.Append(Sol2);
1180 Standard_Real aFirst, aLast;
1181 Handle(Geom_Curve) pCurv = BRep_Tool::Curve(S2, aFirst, aLast);
1182 if (pCurv->Continuity() == GeomAbs_C0)
1184 BRepExtrema_SeqOfSolution SeqSolution1;
1185 BRepExtrema_SeqOfSolution SeqSolution2;
1187 GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
1188 const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
1190 TColStd_Array1OfReal arrInter(1,1+nbIntervals);
1191 aAdaptorCurve.Intervals(arrInter, GeomAbs_C1);
1195 const Standard_Real tol = BRep_Tool::Tolerance(S1);
1198 for (i = 1; i <= arrInter.Length(); i++)
1200 const Standard_Real aParameter = arrInter(i);
1201 gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
1202 TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
1204 BRepExtrema_ExtPF ExtPF(V1,S1);
1205 const Standard_Integer NbExtremaPF = ExtPF.IsDone()? ExtPF.NbExt() : 0;
1206 if (NbExtremaPF > 0 )
1208 // Search minimum distance Dstmin
1209 Standard_Integer ii;
1210 Standard_Real Dstmin = ExtPF.SquareDistance(1);
1211 for (ii = 2; ii <= NbExtremaPF; ii++)
1213 const Standard_Real sDst = ExtPF.SquareDistance(ii);
1217 Dstmin = sqrt(Dstmin);
1219 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1221 for (ii = 1; ii <= NbExtremaPF; ii++)
1223 if (fabs(Dstmin-sqrt(ExtPF.SquareDistance(ii)))<myEps)
1225 // Check if the parameter does not correspond to a vertex
1226 ExtPF.Parameter(ii,U,V);
1227 const gp_Pnt2d PUV(U,V);
1228 classifier.Perform(S1,PUV,tol);
1229 if (classifier.State()==TopAbs_IN)
1231 if (myDstRef > Dstmin)
1233 myModif=Standard_True;
1234 const BRepExtrema_SolutionElem Sol2(Dstmin,aPnt,BRepExtrema_IsOnEdge,S2,aParameter);
1235 const BRepExtrema_SolutionElem Sol1(Dstmin,ExtPF.Point(ii),BRepExtrema_IsInFace,S1,U,V);
1236 SeqSolution1.Append(Sol1);
1237 SeqSolution2.Append(Sol2);
1245 BRepExtrema_SeqOfSolution seqSol1;
1246 BRepExtrema_SeqOfSolution seqSol2;
1247 if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
1248 MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
1250 if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
1252 SeqSolShape1.Append(seqSol1);
1253 SeqSolShape2.Append(seqSol2);
1259 /*********************************************************************************/
1261 void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Face& S2,
1262 const Bnd_Box& B1, const Bnd_Box& B2)
1264 const Standard_Real Dst=B1.Distance(B2);
1265 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
1267 BRepExtrema_ExtFF Ext(S1,S2);
1268 const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
1269 if ( NbExtrema > 0 )
1271 // Search minimum distance Dstmin
1273 Standard_Real Dstmin = Ext.SquareDistance(1);
1274 for (i = 2; i <= NbExtrema; i++)
1276 const Standard_Real sDst = Ext.SquareDistance(i);
1280 Dstmin = sqrt(Dstmin);
1281 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1283 const Standard_Real tol1=BRep_Tool::Tolerance(S1);
1284 const Standard_Real tol2=BRep_Tool::Tolerance(S2);
1288 Standard_Real U1,V1,U2,V2;
1289 BRepClass_FaceClassifier classifier;
1291 for (i = 1; i <= NbExtrema; i++)
1293 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
1295 Pt1=Ext.PointOnFace1(i);
1296 Pt2=Ext.PointOnFace2(i);
1297 if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
1299 // Check if the parameter does not correspond to a vertex
1300 Ext.ParameterOnFace1(i,U1,V1);
1301 PUV.SetCoord(U1,V1);
1302 classifier.Perform(S1,PUV,tol1);
1303 if (classifier.State()==TopAbs_IN)
1305 Ext.ParameterOnFace2(i,U2,V2);
1306 PUV.SetCoord(U2,V2);
1307 classifier.Perform(S2,PUV,tol2);
1308 if (classifier.State()==TopAbs_IN)
1310 if (myDstRef > Dstmin)
1312 myModif=Standard_True;
1313 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsInFace,S1,U1,V1);
1314 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsInFace,S2,U2,V2);
1315 SeqSolShape1.Append(Sol1);
1316 SeqSolShape2.Append(Sol2);
1327 /*********************************************************************************/