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 const Standard_Integer Nbsol = SeqSol.Length();
68 for (Standard_Integer i = 1; i <= Nbsol; i++)
70 const Standard_Real dst = SeqSol.Value(i).Point().Distance(Pt);
71 if (dst <= Precision::Confusion()) return Standard_False;
76 //------------------------------------------------------------------------------
77 // function: MIN_SOLUTION
78 //------------------------------------------------------------------------------
79 static void MIN_SOLUTION (const BRepExtrema_SeqOfSolution& SeqSol1,
80 const BRepExtrema_SeqOfSolution& SeqSol2,
81 const Standard_Real DstRef,
82 const Standard_Real Eps,
83 BRepExtrema_SeqOfSolution& seqSol1,
84 BRepExtrema_SeqOfSolution& seqSol2)
86 const Standard_Integer nbSol = SeqSol1.Length();
87 for (Standard_Integer i = 1; i <= nbSol; i++)
89 const Standard_Real dst1 = SeqSol1.Value(i).Dist();
90 if (fabs(dst1 - DstRef) < Eps)
92 seqSol1.Append(SeqSol1.Value(i));
93 seqSol2.Append(SeqSol2.Value(i));
98 //------------------------------------------------------------------------------
99 // function: TRIM_INFINIT_EDGE
100 //------------------------------------------------------------------------------
101 static void TRIM_INFINIT_EDGE(const TopoDS_Edge& S1, const TopoDS_Edge& S2, TopoDS_Edge& aResEdge,
102 Standard_Boolean& bIsTrim1, Standard_Boolean& bIsTrim2)
104 if ( BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2) )
108 Standard_Real aFirst1, aLast1, aFirst2, aLast2;
109 Handle(Geom_Curve) pCurv1 = BRep_Tool::Curve(S1, aFirst1, aLast1);
110 Handle(Geom_Curve) pCurv2 = BRep_Tool::Curve(S2, aFirst2, aLast2);
112 if (Precision::IsInfinite(aFirst1) &&
113 Precision::IsInfinite(aLast1) &&
114 Precision::IsInfinite(aFirst2) &&
115 Precision::IsInfinite(aLast2))
118 Standard_Real Umin = 0., Umax = 0.;
119 Standard_Boolean bUmin, bUmax;
120 bUmin = bUmax = Standard_False;
122 Handle(Geom_Curve) pCurv;
123 if ( !pCurv1.IsNull() && (Precision::IsInfinite(aFirst1) || Precision::IsInfinite(aLast1)) )
126 bIsTrim1 = Standard_True;
127 if (!Precision::IsInfinite(aFirst1))
129 bUmin = Standard_True;
132 else if (!Precision::IsInfinite(aLast1))
134 bUmax = Standard_True;
138 else if ( !pCurv2.IsNull() && (Precision::IsInfinite(aFirst2) || Precision::IsInfinite(aLast2)) )
141 bIsTrim2 = Standard_True;
142 if (!Precision::IsInfinite(aFirst2))
144 bUmin = Standard_True;
147 else if (!Precision::IsInfinite(aLast2))
149 bUmax = Standard_True;
153 if (bIsTrim1 || bIsTrim2)
157 BRepBndLib::Add(S2, aEdgeBox);
159 BRepBndLib::Add(S1, aEdgeBox);
160 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
161 aEdgeBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
163 const gp_Pnt aPnt0(Xmin, Ymin, Zmin);
164 const gp_Pnt aPnt1(Xmin, Ymax, Zmin);
165 const gp_Pnt aPnt2(Xmin, Ymax, Zmax);
166 const gp_Pnt aPnt3(Xmin, Ymin, Zmax);
167 const gp_Pnt aPnt4(Xmax, Ymax, Zmin);
168 const gp_Pnt aPnt5(Xmax, Ymax, Zmax);
169 const gp_Pnt aPnt6(Xmax, Ymin, Zmax);
170 const gp_Pnt aPnt7(Xmax, Ymin, Zmin);
172 Standard_Real arrU[8];
173 GeomAPI_ProjectPointOnCurve aProj(aPnt0, pCurv);
174 /*szv:aProj.Perform(aPnt0);*/ arrU[0] = aProj.LowerDistanceParameter();
175 aProj.Perform(aPnt1); arrU[1] = aProj.LowerDistanceParameter();
176 aProj.Perform(aPnt2); arrU[2] = aProj.LowerDistanceParameter();
177 aProj.Perform(aPnt3); arrU[3] = aProj.LowerDistanceParameter();
178 aProj.Perform(aPnt4); arrU[4] = aProj.LowerDistanceParameter();
179 aProj.Perform(aPnt5); arrU[5] = aProj.LowerDistanceParameter();
180 aProj.Perform(aPnt6); arrU[6] = aProj.LowerDistanceParameter();
181 aProj.Perform(aPnt7); arrU[7] = aProj.LowerDistanceParameter();
189 Standard_Integer i = 0;
192 const Standard_Real aU = arrU[i++];
199 Standard_Real tol = Precision::Confusion();
201 tol = BRep_Tool::Tolerance(S1);
203 tol = BRep_Tool::Tolerance(S2);
205 const Standard_Real EpsU = GeomAdaptor_Curve(pCurv).Resolution(3.*tol);
206 if (fabs(Umin - Umax) < EpsU)
212 Handle(Geom_Curve) result = new Geom_TrimmedCurve(pCurv, Umin, Umax);
213 aResEdge = BRepBuilderAPI_MakeEdge(result);
217 //------------------------------------------------------------------------------
218 // function: TRIM_INFINIT_FACE
219 //------------------------------------------------------------------------------
220 static void TRIM_INFINIT_FACE(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
221 TopoDS_Face& aResFace, Standard_Boolean& bIsInfinit)
223 bIsInfinit = Standard_False;
225 TopAbs_ShapeEnum Type1 = S1.ShapeType();
226 TopAbs_ShapeEnum Type2 = S2.ShapeType();
231 if (Type1 == TopAbs_EDGE && Type2 == TopAbs_FACE)
233 aE = TopoDS::Edge(S1);
234 if ( BRep_Tool::Degenerated(aE) )
236 aF = TopoDS::Face(S2);
238 else if (Type2 == TopAbs_EDGE && Type1 == TopAbs_FACE)
240 aE = TopoDS::Edge(S2);
241 if ( BRep_Tool::Degenerated(aE) )
243 aF = TopoDS::Face(S1);
247 bIsInfinit = Standard_False;
252 Handle(Geom_Surface) pSurf = BRep_Tool::Surface(aF);
254 const Standard_Boolean bRestrict = BRep_Tool::NaturalRestriction(aF);
256 Standard_Real U1, V1, U2, V2;
257 Standard_Real Umin = RealLast(), Umax = RealFirst(), Vmin = RealLast(), Vmax = RealFirst();
258 Standard_Boolean bUmin, bUmax, bVmin, bVmax;
259 bUmin = bUmax = bVmin = bVmax = Standard_False;
260 Standard_Boolean bIsTrim = Standard_False;
264 pSurf->Bounds(U1, U2, V1, V2);
265 if (Precision::IsInfinite(U1))
266 bIsTrim = Standard_True;
270 bUmin = Standard_True;
273 if (Precision::IsInfinite(U2))
274 bIsTrim = Standard_True;
278 bUmax = Standard_True;
281 if (Precision::IsInfinite(V1))
282 bIsTrim = Standard_True;
286 bVmin = Standard_True;
289 if (Precision::IsInfinite(V2))
290 bIsTrim = Standard_True;
294 bVmax = Standard_True;
299 BRepTools::UVBounds(aF, U1, U2, V1, V2);
300 if (Precision::IsInfinite(U1) &&
301 Precision::IsInfinite(U2) &&
302 Precision::IsInfinite(V1) &&
303 Precision::IsInfinite(V2))
304 bIsTrim = Standard_True;
310 BRepBndLib::Add(aE, aEdgeBox);
312 if(aEdgeBox.IsWhole())
315 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
316 aEdgeBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
318 const gp_Pnt aPnt0(Xmin, Ymin, Zmin);
319 const gp_Pnt aPnt1(Xmin, Ymax, Zmin);
320 const gp_Pnt aPnt2(Xmin, Ymax, Zmax);
321 const gp_Pnt aPnt3(Xmin, Ymin, Zmax);
322 const gp_Pnt aPnt4(Xmax, Ymax, Zmin);
323 const gp_Pnt aPnt5(Xmax, Ymax, Zmax);
324 const gp_Pnt aPnt6(Xmax, Ymin, Zmax);
325 const gp_Pnt aPnt7(Xmax, Ymin, Zmin);
327 Standard_Real arrU[8], arrV[8];
328 GeomAPI_ProjectPointOnSurf aProj(aPnt0, pSurf);
329 /*szv:aProj.Perform(aPnt0);*/ if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[0],arrV[0]);
330 aProj.Perform(aPnt1); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[1],arrV[1]);
331 aProj.Perform(aPnt2); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[2],arrV[2]);
332 aProj.Perform(aPnt3); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[3],arrV[3]);
333 aProj.Perform(aPnt4); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[4],arrV[4]);
334 aProj.Perform(aPnt5); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[5],arrV[5]);
335 aProj.Perform(aPnt6); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[6],arrV[6]);
336 aProj.Perform(aPnt7); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[7],arrV[7]);
347 Standard_Integer i = 0;
350 const Standard_Real aU = arrU[i];
356 const Standard_Real aV = arrV[i];
365 GeomAdaptor_Surface aGAS(pSurf);
366 const Standard_Real tol = BRep_Tool::Tolerance(aF);
368 const Standard_Real EpsU = aGAS.UResolution(3.*tol);
369 if (fabs(Umin - Umax) < EpsU)
375 const Standard_Real EpsV = aGAS.VResolution(3.*tol);
376 if (fabs(Vmin - Vmax) < EpsV)
382 Handle(Geom_Surface) result = new Geom_RectangularTrimmedSurface(pSurf, Umin, Umax, Vmin, Vmax);
383 aResFace = BRepBuilderAPI_MakeFace(result, Precision::Confusion());
385 bIsInfinit = Standard_True;
388 bIsInfinit = Standard_False;
391 //------------------------------------------------------------------------------
392 // static function: PERFORM_C0
393 //------------------------------------------------------------------------------
394 static void PERFORM_C0(const TopoDS_Edge &S1, const TopoDS_Edge &S2,
395 BRepExtrema_SeqOfSolution& SeqSol1,
396 BRepExtrema_SeqOfSolution& SeqSol2,
397 const Standard_Real DstRef,
398 Standard_Real& mDstRef,
399 const Standard_Real Eps)
401 if ( BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2) )
405 for (iE = 0; iE < 2; iE++)
407 TopoDS_Edge E, Eother;
419 Standard_Real aFirst, aLast;
420 Handle(Geom_Curve) pCurv = BRep_Tool::Curve(E, aFirst, aLast);
422 Standard_Real aFOther, aLOther;
423 Handle(Geom_Curve) pCurvOther = BRep_Tool::Curve(Eother, aFOther, aLOther);
425 if (pCurv->Continuity() == GeomAbs_C0)
427 const Standard_Real epsP = Precision::PConfusion();
429 GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
430 const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
432 TColStd_Array1OfReal arrInter(1,1+nbIntervals);
433 aAdaptorCurve.Intervals(arrInter, GeomAbs_C1);
435 GeomAdaptor_Curve aAdaptorCurveOther(pCurvOther, aFOther, aLOther);
436 const Standard_Integer nbIntervalsOther = aAdaptorCurveOther.NbIntervals(GeomAbs_C1);
437 TColStd_Array1OfReal arrInterOther(1,1+nbIntervalsOther);
438 aAdaptorCurveOther.Intervals(arrInterOther, GeomAbs_C1);
440 Standard_Real Udeb,Ufin;
441 BRep_Tool::Range(Eother,Udeb,Ufin);
444 Standard_Integer i, ii;
445 BRepClass_FaceClassifier classifier;
446 for (i = 1; i <= arrInter.Length(); i++)
448 const Standard_Real aParameter = arrInter(i);
449 const gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
450 const TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
452 BRepExtrema_ExtPC Ext(V1,Eother);
453 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
456 // Search minimum distance dstmin
457 Standard_Real Dstmin = Ext.SquareDistance(1);
458 for (ii = 2; ii <= NbExtrema; ii++)
460 const Standard_Real sDst = Ext.SquareDistance(ii);
464 Dstmin = sqrt(Dstmin);
466 if ((Dstmin < DstRef - Eps) || (fabs(Dstmin-DstRef) < Eps))
467 for (ii = 1; ii <= NbExtrema; ii++)
469 if (fabs(Dstmin-sqrt(Ext.SquareDistance(ii)))<Eps)
472 if (TRI_SOLUTION(SeqSol2,Pt))
474 // Check if the parameter does not correspond to a vertex
475 const Standard_Real t = Ext.Parameter(ii);
476 if ((fabs(t-Udeb)>=epsP)&&(fabs(t-Ufin)>epsP))
478 if (mDstRef > Dstmin)
480 const BRepExtrema_SolutionElem Sol1(Dstmin,aPnt,BRepExtrema_IsOnEdge,E,aParameter);
481 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsOnEdge,Eother,t);
482 SeqSol1.Append(iE == 0 ? Sol1 : Sol2);
483 SeqSol2.Append(iE == 0 ? Sol2 : Sol1);
489 for (Standard_Integer i2 = 1; i2<=arrInterOther.Length(); i2++)
491 const Standard_Real aParameterOther = arrInterOther(i2);
492 const gp_Pnt aPntOther = aAdaptorCurveOther.Value(aParameterOther);
493 const Standard_Real Dst = aPnt.Distance(aPntOther);
494 if ((Dst < DstRef - Eps) || (fabs(Dst-DstRef) < Eps))
498 const BRepExtrema_SolutionElem Sol1(Dst,aPnt,BRepExtrema_IsOnEdge,E,aParameter);
499 const BRepExtrema_SolutionElem Sol2(Dst,aPntOther,BRepExtrema_IsOnEdge,Eother,aParameterOther);
500 SeqSol1.Append(iE == 0 ? Sol1 : Sol2);
501 SeqSol2.Append(iE == 0 ? Sol2 : Sol1);
509 /*********************************************************************************/
511 void BRepExtrema_DistanceSS::Perform(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
512 const Bnd_Box& B1, const Bnd_Box& B2)
514 SeqSolShape1.Clear();
515 SeqSolShape2.Clear();
516 myModif=Standard_False;
518 switch (S1.ShapeType())
522 TopoDS_Vertex V1 = TopoDS::Vertex(S1);
523 switch (S2.ShapeType())
527 TopoDS_Vertex V2 = TopoDS::Vertex(S2);
533 TopoDS_Edge E2 = TopoDS::Edge(S2);
534 Perform( V1, E2, B1, B2 );
539 TopoDS_Face F2 = TopoDS::Face(S2);
540 Perform( V1, F2, B1, B2 );
551 TopoDS_Edge E1 = TopoDS::Edge(S1);
552 switch (S2.ShapeType())
556 TopoDS_Vertex V2 = TopoDS::Vertex(S2);
557 Perform( E1, V2, B1, B2 );
562 TopoDS_Edge E2 = TopoDS::Edge(S2);
563 TopoDS_Edge aTrimEdge;
564 Standard_Boolean bIsTrim1 = Standard_False;
565 Standard_Boolean bIsTrim2 = Standard_False;
566 TRIM_INFINIT_EDGE( E1, E2, aTrimEdge, bIsTrim1, bIsTrim2 );
571 Perform( E1, E2, B1, B2 );
576 TopoDS_Face F2 = TopoDS::Face(S2);
577 TopoDS_Face aTrimFace;
578 Standard_Boolean bIsInfinit;
579 TRIM_INFINIT_FACE( E1, F2, aTrimFace, bIsInfinit );
582 Perform( E1, F2, B1, B2 );
593 TopoDS_Face F1 = TopoDS::Face(S1);
594 switch (S2.ShapeType())
598 TopoDS_Vertex V2 = TopoDS::Vertex(S2);
599 Perform( F1, V2, B1, B2 );
604 TopoDS_Edge E2 = TopoDS::Edge(S2);
605 TopoDS_Face aTrimFace;
606 Standard_Boolean bIsInfinit;
607 TRIM_INFINIT_FACE( F1, E2, aTrimFace, bIsInfinit );
610 Perform( F1, E2, B1, B2 );
615 TopoDS_Face F2 = TopoDS::Face(S2);
616 Perform( F1, F2, B1, B2 );
629 /*********************************************************************************/
631 void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Vertex& S2)
633 const gp_Pnt P1 = BRep_Tool::Pnt(S1);
634 const gp_Pnt P2 = BRep_Tool::Pnt(S2);
636 const Standard_Real Dst = P1.Distance(P2);
637 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
641 myModif=Standard_True;
642 const BRepExtrema_SolutionElem Sol1(Dst,P1,BRepExtrema_IsVertex,S1);
643 const BRepExtrema_SolutionElem Sol2(Dst,P2,BRepExtrema_IsVertex,S2);
644 SeqSolShape1.Append(Sol1);
645 SeqSolShape2.Append(Sol2);
649 /*********************************************************************************/
651 void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Edge& S2,
652 const Bnd_Box& B1, const Bnd_Box& B2)
654 if (BRep_Tool::Degenerated(S2))
657 const Standard_Real Dst=B1.Distance(B2);
658 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
660 BRepExtrema_ExtPC Ext(S1,S2);
661 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
664 // Search minimum distance Dstmin
666 Standard_Real Dstmin = Ext.SquareDistance(1);
667 for (i = 2; i <= NbExtrema; i++)
669 const Standard_Real sDst = Ext.SquareDistance(i);
673 Dstmin = sqrt(Dstmin);
674 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
676 Standard_Real Udeb,Ufin;
677 BRep_Tool::Range(S2,Udeb,Ufin);
679 gp_Pnt Pt,P1=BRep_Tool::Pnt(S1);
680 const Standard_Real epsP=Precision::PConfusion();
682 for (i = 1; i <= NbExtrema; i++)
684 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
687 if (TRI_SOLUTION(SeqSolShape2,Pt))
689 // Check if the parameter does not correspond to a vertex
690 const Standard_Real t = Ext.Parameter(i);
691 if ( (fabs(t-Udeb)>=epsP) && (fabs(t-Ufin)>epsP) )
693 if (myDstRef > Dstmin)
695 myModif=Standard_True;
696 const BRepExtrema_SolutionElem Sol1(Dstmin,P1,BRepExtrema_IsVertex,S1);
697 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsOnEdge,S2,t);
698 SeqSolShape1.Append(Sol1);
699 SeqSolShape2.Append(Sol2);
709 void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1,const TopoDS_Vertex& S2,
710 const Bnd_Box& B1,const Bnd_Box& B2)
712 if (BRep_Tool::Degenerated(S1))
715 const Standard_Real Dst=B1.Distance(B2);
716 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
718 BRepExtrema_ExtPC Ext(S2,S1);
719 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
722 // Search minimum distance Dstmin
724 Standard_Real Dstmin = Ext.SquareDistance(1);
725 for (i = 2; i <= NbExtrema; i++)
727 const Standard_Real sDst = Ext.SquareDistance(i);
731 Dstmin = sqrt(Dstmin);
732 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
734 Standard_Real Udeb,Ufin;
735 BRep_Tool::Range(S1,Udeb,Ufin);
737 gp_Pnt Pt, P2 = BRep_Tool::Pnt(S2);
738 const Standard_Real epsP=Precision::PConfusion();
740 for (i = 1; i <= NbExtrema; i++)
742 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
745 if (TRI_SOLUTION(SeqSolShape1,Pt))
747 // Check if the parameter does not correspond to a vertex
748 const Standard_Real t = Ext.Parameter(i);
749 if ( (fabs(t-Udeb)>=epsP) && (fabs(t-Ufin)>epsP) )
751 if (myDstRef > Dstmin)
753 myModif=Standard_True;
754 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt,BRepExtrema_IsOnEdge,S1,t);
755 const BRepExtrema_SolutionElem Sol2(Dstmin,P2,BRepExtrema_IsVertex,S2);
756 SeqSolShape1.Append(Sol1);
757 SeqSolShape2.Append(Sol2);
767 /*********************************************************************************/
769 void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Face& S2,
770 const Bnd_Box& B1, const Bnd_Box& B2)
772 const Standard_Real Dst=B1.Distance(B2);
773 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
775 BRepExtrema_ExtPF Ext(S1,S2,myFlag,myAlgo);
776 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
779 // Search minimum distance Dstmin
781 Standard_Real Dstmin = Ext.SquareDistance(1);
782 for (i = 2; i <= NbExtrema; i++)
784 const Standard_Real sDst = Ext.SquareDistance(i);
788 Dstmin = sqrt(Dstmin);
789 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
792 gp_Pnt Pt,P1=BRep_Tool::Pnt(S1);
793 BRepClass_FaceClassifier classifier;
794 const Standard_Real tol = BRep_Tool::Tolerance(S2);
796 for (i = 1; i <= NbExtrema; i++)
798 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
801 if (TRI_SOLUTION(SeqSolShape2,Pt))
803 // Check if the parameter does not correspond to a vertex
804 Ext.Parameter(i,U,V);
805 const gp_Pnt2d PUV(U,V);
806 classifier.Perform(S2,PUV,tol);
807 if (classifier.State()==TopAbs_IN)
809 if (myDstRef > Dstmin)
811 myModif=Standard_True;
812 const BRepExtrema_SolutionElem Sol1(Dstmin,P1,BRepExtrema_IsVertex,S1);
813 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsInFace,S2,U,V);
814 SeqSolShape1.Append(Sol1);
815 SeqSolShape2.Append(Sol2);
825 void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Vertex& S2,
826 const Bnd_Box& B1, const Bnd_Box& B2)
828 const Standard_Real Dst=B1.Distance(B2);
829 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
831 BRepExtrema_ExtPF Ext(S2,S1,myFlag,myAlgo);
832 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
835 // Search minimum distance Dstmin
837 Standard_Real Dstmin = Ext.SquareDistance(1);
838 for (i = 2; i <= NbExtrema; i++)
840 const Standard_Real sDst = Ext.SquareDistance(i);
844 Dstmin = sqrt(Dstmin);
845 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
848 gp_Pnt Pt,P2=BRep_Tool::Pnt(S2);
849 BRepClass_FaceClassifier classifier;
850 const Standard_Real tol = BRep_Tool::Tolerance(S1);
852 for (i = 1; i <= NbExtrema; i++)
854 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
857 if (TRI_SOLUTION(SeqSolShape1,Pt))
859 // Check if the parameter does not correspond to a vertex
860 Ext.Parameter(i,U,V);
861 const gp_Pnt2d PUV(U,V);
862 classifier.Perform(S1,PUV,tol);
863 if (classifier.State()==TopAbs_IN)
865 if (myDstRef > Dstmin)
867 myModif=Standard_True;
868 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt,BRepExtrema_IsInFace,S1,U,V);
869 const BRepExtrema_SolutionElem Sol2(Dstmin,P2,BRepExtrema_IsVertex,S2);
870 SeqSolShape1.Append(Sol1);
871 SeqSolShape2.Append(Sol2);
881 /*********************************************************************************/
883 void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Edge& S2,
884 const Bnd_Box& B1, const Bnd_Box& B2)
886 if (BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2))
889 const Standard_Real Dst=B1.Distance(B2);
890 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
892 const Standard_Real DstRef = myDstRef;
894 BRepExtrema_ExtCC Ext(S1,S2);
895 const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
898 // Search minimum distance Dstmin
900 Standard_Real Dstmin = Ext.SquareDistance(1);
901 for (i = 2; i <= NbExtrema; i++)
903 const Standard_Real sDst = Ext.SquareDistance(i);
907 Dstmin = sqrt(Dstmin);
908 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
910 Standard_Real Udeb1,Ufin1,Udeb2,Ufin2;
911 BRep_Tool::Range(S1,Udeb1,Ufin1);
912 BRep_Tool::Range(S2,Udeb2,Ufin2);
915 const Standard_Real epsP=Precision::PConfusion();
917 for (i=1;i<=NbExtrema;i++)
919 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
921 Pt1=Ext.PointOnE1(i);
922 Pt2=Ext.PointOnE2(i);
923 if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
925 // Check if the parameters do not correspond to a vertex
926 const Standard_Real t1 = Ext.ParameterOnE1(i);
927 const Standard_Real t2 = Ext.ParameterOnE2(i);
928 if ((fabs(t1-Udeb1)>=epsP)&&(fabs(t1-Ufin1)>epsP)&&(fabs(t2-Udeb2)>=epsP)&&(fabs(t2-Ufin2)>epsP))
930 if (myDstRef > Dstmin)
932 myModif=Standard_True;
933 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsOnEdge,S1,t1);
934 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsOnEdge,S2,t2);
935 SeqSolShape1.Append(Sol1);
936 SeqSolShape2.Append(Sol2);
944 BRepExtrema_SeqOfSolution SeqSolution1;
945 BRepExtrema_SeqOfSolution SeqSolution2;
947 PERFORM_C0(S1, S2, SeqSolution1, SeqSolution2, DstRef, myDstRef, myEps);
949 BRepExtrema_SeqOfSolution seqSol1;
950 BRepExtrema_SeqOfSolution seqSol2;
952 if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
953 MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
955 if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
957 SeqSolShape1.Append(seqSol1);
958 SeqSolShape2.Append(seqSol2);
959 myModif = Standard_True;
964 /*********************************************************************************/
966 void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Face& S2,
967 const Bnd_Box& B1, const Bnd_Box& B2)
969 if (BRep_Tool::Degenerated(S1))
972 const Standard_Real Dst=B1.Distance(B2);
973 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
975 BRepClass_FaceClassifier classifier;
977 BRepExtrema_ExtCF Ext(S1,S2);
978 const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
981 // Search minimum distance Dstmin
983 Standard_Real Dstmin = Ext.SquareDistance(1);
984 for (i = 2; i <= NbExtrema; i++)
986 const Standard_Real sDst = Ext.SquareDistance(i);
990 Dstmin = sqrt(Dstmin);
991 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
993 Standard_Real Udeb,Ufin,U,V;
994 BRep_Tool::Range(S1,Udeb,Ufin);
995 const Standard_Real tol=BRep_Tool::Tolerance(S2);
998 const Standard_Real epsP=Precision::PConfusion();
1000 for (i = 1; i <= NbExtrema; i++)
1002 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
1004 Pt1=Ext.PointOnEdge(i);
1005 Pt2=Ext.PointOnFace(i);
1006 if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
1008 // Check if the parameter does not correspond to a vertex
1009 const Standard_Real t1 = Ext.ParameterOnEdge(i);
1010 if ((fabs(t1-Udeb)>=epsP)&&(fabs(t1-Ufin)>epsP))
1012 Ext.ParameterOnFace(i,U,V);
1013 const gp_Pnt2d PUV(U,V);
1014 classifier.Perform(S2,PUV,tol);
1015 if (classifier.State()==TopAbs_IN)
1017 if (myDstRef > Dstmin)
1019 myModif=Standard_True;
1020 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsOnEdge,S1,t1);
1021 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsInFace,S2,U,V);
1022 SeqSolShape1.Append(Sol1);
1023 SeqSolShape2.Append(Sol2);
1032 Standard_Real aFirst, aLast;
1033 Handle(Geom_Curve) pCurv = BRep_Tool::Curve(S1, aFirst, aLast);
1034 if (pCurv->Continuity() == GeomAbs_C0)
1036 BRepExtrema_SeqOfSolution SeqSolution1;
1037 BRepExtrema_SeqOfSolution SeqSolution2;
1039 GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
1040 const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
1042 TColStd_Array1OfReal arrInter(1,1+nbIntervals);
1043 aAdaptorCurve.Intervals(arrInter, GeomAbs_C1);
1047 const Standard_Real tol = BRep_Tool::Tolerance(S2);
1050 for (i = 1; i <= arrInter.Length(); i++)
1052 const Standard_Real aParameter = arrInter(i);
1053 gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
1054 TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
1056 BRepExtrema_ExtPF ExtPF(V1,S2);
1057 const Standard_Integer NbExtremaPF = ExtPF.IsDone()? ExtPF.NbExt() : 0;
1058 if (NbExtremaPF > 0 )
1060 // Search minimum distance Dstmin
1061 Standard_Integer ii;
1062 Standard_Real Dstmin = ExtPF.SquareDistance(1);
1063 for (ii = 2; ii <= NbExtremaPF; ii++)
1065 const Standard_Real sDst = ExtPF.SquareDistance(ii);
1069 Dstmin = sqrt(Dstmin);
1071 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1073 for (ii = 1; ii <= NbExtremaPF; ii++)
1075 if (fabs(Dstmin-sqrt(ExtPF.SquareDistance(ii)))<myEps)
1077 // Check if the parameter does not correspond to a vertex
1078 ExtPF.Parameter(ii,U,V);
1079 const gp_Pnt2d PUV(U,V);
1080 classifier.Perform(S2,PUV,tol);
1081 if (classifier.State()==TopAbs_IN)
1083 if (myDstRef > Dstmin)
1085 myModif=Standard_True;
1086 const BRepExtrema_SolutionElem Sol1(Dstmin,aPnt,BRepExtrema_IsOnEdge,S1,aParameter);
1087 const BRepExtrema_SolutionElem Sol2(Dstmin,ExtPF.Point(ii),BRepExtrema_IsInFace,S2,U,V);
1088 SeqSolution1.Append(Sol1);
1089 SeqSolution2.Append(Sol2);
1097 BRepExtrema_SeqOfSolution seqSol1;
1098 BRepExtrema_SeqOfSolution seqSol2;
1099 if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
1100 MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
1102 if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
1104 SeqSolShape1.Append(seqSol1);
1105 SeqSolShape2.Append(seqSol2);
1111 void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Edge& S2,
1112 const Bnd_Box& B1, const Bnd_Box& B2)
1114 if (BRep_Tool::Degenerated(S2))
1117 const Standard_Real Dst=B1.Distance(B2);
1118 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
1120 BRepClass_FaceClassifier classifier;
1122 BRepExtrema_ExtCF Ext(S2,S1);
1123 const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
1124 if ( NbExtrema > 0 )
1126 // Search minimum distance Dstmin
1128 Standard_Real Dstmin = Ext.SquareDistance(1);
1129 for (i = 2; i <= NbExtrema; i++)
1131 const Standard_Real sDst = Ext.SquareDistance(i);
1135 Dstmin = sqrt(Dstmin);
1136 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1138 Standard_Real Udeb,Ufin,U,V;
1139 BRep_Tool::Range(S2,Udeb,Ufin);
1140 const Standard_Real tol=BRep_Tool::Tolerance(S1);
1143 const Standard_Real epsP=Precision::PConfusion();
1145 for (i = 1; i <= NbExtrema; i++)
1147 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
1149 Pt1=Ext.PointOnEdge(i);
1150 Pt2=Ext.PointOnFace(i);
1151 if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
1153 // Check if the parameter does not correspond to a vertex
1154 const Standard_Real t1 = Ext.ParameterOnEdge(i);
1155 if ((fabs(t1-Udeb)>=epsP)&&(fabs(t1-Ufin)>epsP))
1157 Ext.ParameterOnFace(i,U,V);
1158 const gp_Pnt2d PUV(U,V);
1159 classifier.Perform(S1,PUV,tol);
1160 if (classifier.State()==TopAbs_IN)
1162 if (myDstRef > Dstmin)
1164 myModif=Standard_True;
1165 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt1,BRepExtrema_IsOnEdge,S2,t1);
1166 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt2,BRepExtrema_IsInFace,S1,U,V);
1167 SeqSolShape1.Append(Sol1);
1168 SeqSolShape2.Append(Sol2);
1177 Standard_Real aFirst, aLast;
1178 Handle(Geom_Curve) pCurv = BRep_Tool::Curve(S2, aFirst, aLast);
1179 if (pCurv->Continuity() == GeomAbs_C0)
1181 BRepExtrema_SeqOfSolution SeqSolution1;
1182 BRepExtrema_SeqOfSolution SeqSolution2;
1184 GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
1185 const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
1187 TColStd_Array1OfReal arrInter(1,1+nbIntervals);
1188 aAdaptorCurve.Intervals(arrInter, GeomAbs_C1);
1192 const Standard_Real tol = BRep_Tool::Tolerance(S1);
1195 for (i = 1; i <= arrInter.Length(); i++)
1197 const Standard_Real aParameter = arrInter(i);
1198 gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
1199 TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
1201 BRepExtrema_ExtPF ExtPF(V1,S1);
1202 const Standard_Integer NbExtremaPF = ExtPF.IsDone()? ExtPF.NbExt() : 0;
1203 if (NbExtremaPF > 0 )
1205 // Search minimum distance Dstmin
1206 Standard_Integer ii;
1207 Standard_Real Dstmin = ExtPF.SquareDistance(1);
1208 for (ii = 2; ii <= NbExtremaPF; ii++)
1210 const Standard_Real sDst = ExtPF.SquareDistance(ii);
1214 Dstmin = sqrt(Dstmin);
1216 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1218 for (ii = 1; ii <= NbExtremaPF; ii++)
1220 if (fabs(Dstmin-sqrt(ExtPF.SquareDistance(ii)))<myEps)
1222 // Check if the parameter does not correspond to a vertex
1223 ExtPF.Parameter(ii,U,V);
1224 const gp_Pnt2d PUV(U,V);
1225 classifier.Perform(S1,PUV,tol);
1226 if (classifier.State()==TopAbs_IN)
1228 if (myDstRef > Dstmin)
1230 myModif=Standard_True;
1231 const BRepExtrema_SolutionElem Sol2(Dstmin,aPnt,BRepExtrema_IsOnEdge,S2,aParameter);
1232 const BRepExtrema_SolutionElem Sol1(Dstmin,ExtPF.Point(ii),BRepExtrema_IsInFace,S1,U,V);
1233 SeqSolution1.Append(Sol1);
1234 SeqSolution2.Append(Sol2);
1242 BRepExtrema_SeqOfSolution seqSol1;
1243 BRepExtrema_SeqOfSolution seqSol2;
1244 if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
1245 MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
1247 if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
1249 SeqSolShape1.Append(seqSol1);
1250 SeqSolShape2.Append(seqSol2);
1256 /*********************************************************************************/
1258 void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Face& S2,
1259 const Bnd_Box& B1, const Bnd_Box& B2)
1261 const Standard_Real Dst=B1.Distance(B2);
1262 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
1264 BRepExtrema_ExtFF Ext(S1,S2);
1265 const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
1266 if ( NbExtrema > 0 )
1268 // Search minimum distance Dstmin
1270 Standard_Real Dstmin = Ext.SquareDistance(1);
1271 for (i = 2; i <= NbExtrema; i++)
1273 const Standard_Real sDst = Ext.SquareDistance(i);
1277 Dstmin = sqrt(Dstmin);
1278 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1280 const Standard_Real tol1=BRep_Tool::Tolerance(S1);
1281 const Standard_Real tol2=BRep_Tool::Tolerance(S2);
1285 Standard_Real U1,V1,U2,V2;
1286 BRepClass_FaceClassifier classifier;
1288 for (i = 1; i <= NbExtrema; i++)
1290 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
1292 Pt1=Ext.PointOnFace1(i);
1293 Pt2=Ext.PointOnFace2(i);
1294 if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
1296 // Check if the parameter does not correspond to a vertex
1297 Ext.ParameterOnFace1(i,U1,V1);
1298 PUV.SetCoord(U1,V1);
1299 classifier.Perform(S1,PUV,tol1);
1300 if (classifier.State()==TopAbs_IN)
1302 Ext.ParameterOnFace2(i,U2,V2);
1303 PUV.SetCoord(U2,V2);
1304 classifier.Perform(S2,PUV,tol2);
1305 if (classifier.State()==TopAbs_IN)
1307 if (myDstRef > Dstmin)
1309 myModif=Standard_True;
1310 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsInFace,S1,U1,V1);
1311 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsInFace,S2,U2,V2);
1312 SeqSolShape1.Append(Sol1);
1313 SeqSolShape2.Append(Sol2);
1324 /*********************************************************************************/