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.
22 // Modified: Sergey ZERCHANINOV
24 #include <BRepExtrema_DistanceSS.hxx>
26 #include <TopTools_IndexedMapOfShape.hxx>
29 #include <gp_Pnt2d.hxx>
30 #include <BRep_Tool.hxx>
31 #include <BRepExtrema_SupportType.hxx>
32 #include <Standard_Real.hxx>
33 #include <BRepExtrema_SolutionElem.hxx>
34 #include <BRepExtrema_SeqOfSolution.hxx>
35 #include <Standard_Boolean.hxx>
36 #include <Standard_Integer.hxx>
37 #include <TopAbs_ShapeEnum.hxx>
39 #include <Bnd_Box.hxx>
40 #include <BRepExtrema_ExtPC.hxx>
41 #include <BRepExtrema_ExtPF.hxx>
42 #include <Extrema_ExtFlag.hxx>
43 #include <BRepExtrema_ExtCC.hxx>
44 #include <BRepExtrema_ExtCF.hxx>
45 #include <BRepExtrema_ExtFF.hxx>
46 #include <BRepClass_FaceClassifier.hxx>
48 #include <Geom_Curve.hxx>
49 #include <GeomAbs_Shape.hxx>
50 #include <GeomAdaptor_Curve.hxx>
51 #include <TColStd_Array1OfReal.hxx>
52 #include <BRepBuilderAPI_MakeVertex.hxx>
53 #include <BRepBuilderAPI_MakeEdge.hxx>
54 #include <BRepBuilderAPI_MakeFace.hxx>
55 #include <Geom_Surface.hxx>
56 #include <GeomAPI_ProjectPointOnSurf.hxx>
57 #include <GeomAPI_ProjectPointOnCurve.hxx>
58 #include <Geom_RectangularTrimmedSurface.hxx>
59 #include <Geom_TrimmedCurve.hxx>
60 #include <BRepBndLib.hxx>
61 #include <BRepTools.hxx>
62 #include <TColgp_Array1OfPnt.hxx>
65 /*********************************************************************************/
67 //------------------------------------------------------------------------------
68 // function: TRI_SOLUTION
69 //------------------------------------------------------------------------------
70 static Standard_Boolean TRI_SOLUTION (const BRepExtrema_SeqOfSolution& SeqSol, const gp_Pnt& Pt)
72 const Standard_Integer Nbsol = SeqSol.Length();
73 for (Standard_Integer i = 1; i <= Nbsol; i++)
75 const Standard_Real dst = SeqSol.Value(i).Point().Distance(Pt);
76 if (dst <= Precision::Confusion()) return Standard_False;
81 //------------------------------------------------------------------------------
82 // function: MIN_SOLUTION
83 //------------------------------------------------------------------------------
84 static void MIN_SOLUTION (const BRepExtrema_SeqOfSolution& SeqSol1,
85 const BRepExtrema_SeqOfSolution& SeqSol2,
86 const Standard_Real DstRef,
87 const Standard_Real Eps,
88 BRepExtrema_SeqOfSolution& seqSol1,
89 BRepExtrema_SeqOfSolution& seqSol2)
91 const Standard_Integer nbSol = SeqSol1.Length();
92 for (Standard_Integer i = 1; i <= nbSol; i++)
94 const Standard_Real dst1 = SeqSol1.Value(i).Dist();
95 if (fabs(dst1 - DstRef) < Eps)
97 seqSol1.Append(SeqSol1.Value(i));
98 seqSol2.Append(SeqSol2.Value(i));
103 //------------------------------------------------------------------------------
104 // function: TRIM_INFINIT_EDGE
105 //------------------------------------------------------------------------------
106 static void TRIM_INFINIT_EDGE(const TopoDS_Edge& S1, const TopoDS_Edge& S2, TopoDS_Edge& aResEdge,
107 Standard_Boolean& bIsTrim1, Standard_Boolean& bIsTrim2)
109 if ( BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2) )
113 Standard_Real aFirst1, aLast1, aFirst2, aLast2;
114 Handle(Geom_Curve) pCurv1 = BRep_Tool::Curve(S1, aFirst1, aLast1);
115 Handle(Geom_Curve) pCurv2 = BRep_Tool::Curve(S2, aFirst2, aLast2);
117 if (Precision::IsInfinite(aFirst1) &&
118 Precision::IsInfinite(aLast1) &&
119 Precision::IsInfinite(aFirst2) &&
120 Precision::IsInfinite(aLast2))
123 Standard_Real Umin, Umax;
124 Standard_Boolean bUmin, bUmax;
125 bUmin = bUmax = Standard_False;
127 Handle(Geom_Curve) pCurv;
128 if ( !pCurv1.IsNull() && (Precision::IsInfinite(aFirst1) || Precision::IsInfinite(aLast1)) )
131 bIsTrim1 = Standard_True;
132 if (!Precision::IsInfinite(aFirst1))
134 bUmin = Standard_True;
137 else if (!Precision::IsInfinite(aLast1))
139 bUmax = Standard_True;
143 else if ( !pCurv2.IsNull() && (Precision::IsInfinite(aFirst2) || Precision::IsInfinite(aLast2)) )
146 bIsTrim2 = Standard_True;
147 if (!Precision::IsInfinite(aFirst2))
149 bUmin = Standard_True;
152 else if (!Precision::IsInfinite(aLast2))
154 bUmax = Standard_True;
158 if (bIsTrim1 || bIsTrim2)
162 BRepBndLib::Add(S2, aEdgeBox);
164 BRepBndLib::Add(S1, aEdgeBox);
165 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
166 aEdgeBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
168 const gp_Pnt aPnt0(Xmin, Ymin, Zmin);
169 const gp_Pnt aPnt1(Xmin, Ymax, Zmin);
170 const gp_Pnt aPnt2(Xmin, Ymax, Zmax);
171 const gp_Pnt aPnt3(Xmin, Ymin, Zmax);
172 const gp_Pnt aPnt4(Xmax, Ymax, Zmin);
173 const gp_Pnt aPnt5(Xmax, Ymax, Zmax);
174 const gp_Pnt aPnt6(Xmax, Ymin, Zmax);
175 const gp_Pnt aPnt7(Xmax, Ymin, Zmin);
177 Standard_Real arrU[8];
178 GeomAPI_ProjectPointOnCurve aProj(aPnt0, pCurv);
179 /*szv:aProj.Perform(aPnt0);*/ arrU[0] = aProj.LowerDistanceParameter();
180 aProj.Perform(aPnt1); arrU[1] = aProj.LowerDistanceParameter();
181 aProj.Perform(aPnt2); arrU[2] = aProj.LowerDistanceParameter();
182 aProj.Perform(aPnt3); arrU[3] = aProj.LowerDistanceParameter();
183 aProj.Perform(aPnt4); arrU[4] = aProj.LowerDistanceParameter();
184 aProj.Perform(aPnt5); arrU[5] = aProj.LowerDistanceParameter();
185 aProj.Perform(aPnt6); arrU[6] = aProj.LowerDistanceParameter();
186 aProj.Perform(aPnt7); arrU[7] = aProj.LowerDistanceParameter();
194 Standard_Integer i = 0;
197 const Standard_Real aU = arrU[i++];
204 Standard_Real tol = Precision::Confusion();
206 tol = BRep_Tool::Tolerance(S1);
208 tol = BRep_Tool::Tolerance(S2);
210 const Standard_Real EpsU = GeomAdaptor_Curve(pCurv).Resolution(3.*tol);
211 if (fabs(Umin - Umax) < EpsU)
217 Handle(Geom_Curve) result = new Geom_TrimmedCurve(pCurv, Umin, Umax);
218 aResEdge = BRepBuilderAPI_MakeEdge(result);
222 //------------------------------------------------------------------------------
223 // function: TRIM_INFINIT_FACE
224 //------------------------------------------------------------------------------
225 static void TRIM_INFINIT_FACE(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
226 TopoDS_Face& aResFace, Standard_Boolean& bIsInfinit)
228 bIsInfinit = Standard_False;
230 TopAbs_ShapeEnum Type1 = S1.ShapeType();
231 TopAbs_ShapeEnum Type2 = S2.ShapeType();
236 if (Type1 == TopAbs_EDGE && Type2 == TopAbs_FACE)
238 aE = TopoDS::Edge(S1);
239 if ( BRep_Tool::Degenerated(aE) )
241 aF = TopoDS::Face(S2);
243 else if (Type2 == TopAbs_EDGE && Type1 == TopAbs_FACE)
245 aE = TopoDS::Edge(S2);
246 if ( BRep_Tool::Degenerated(aE) )
248 aF = TopoDS::Face(S1);
252 bIsInfinit = Standard_False;
257 Handle(Geom_Surface) pSurf = BRep_Tool::Surface(aF);
259 const Standard_Boolean bRestrict = BRep_Tool::NaturalRestriction(aF);
261 Standard_Real U1, V1, U2, V2;
262 Standard_Real Umin, Umax, Vmin, Vmax;
263 Standard_Boolean bUmin, bUmax, bVmin, bVmax;
264 bUmin = bUmax = bVmin = bVmax = Standard_False;
265 Standard_Boolean bIsTrim = Standard_False;
269 pSurf->Bounds(U1, U2, V1, V2);
270 if (Precision::IsInfinite(U1))
271 bIsTrim = Standard_True;
275 bUmin = Standard_True;
278 if (Precision::IsInfinite(U2))
279 bIsTrim = Standard_True;
283 bUmax = Standard_True;
286 if (Precision::IsInfinite(V1))
287 bIsTrim = Standard_True;
291 bVmin = Standard_True;
294 if (Precision::IsInfinite(V2))
295 bIsTrim = Standard_True;
299 bVmax = Standard_True;
304 BRepTools::UVBounds(aF, U1, U2, V1, V2);
305 if (Precision::IsInfinite(U1) &&
306 Precision::IsInfinite(U2) &&
307 Precision::IsInfinite(V1) &&
308 Precision::IsInfinite(V2))
309 bIsTrim = Standard_True;
315 BRepBndLib::Add(aE, aEdgeBox);
317 if(aEdgeBox.IsWhole())
320 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
321 aEdgeBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
323 const gp_Pnt aPnt0(Xmin, Ymin, Zmin);
324 const gp_Pnt aPnt1(Xmin, Ymax, Zmin);
325 const gp_Pnt aPnt2(Xmin, Ymax, Zmax);
326 const gp_Pnt aPnt3(Xmin, Ymin, Zmax);
327 const gp_Pnt aPnt4(Xmax, Ymax, Zmin);
328 const gp_Pnt aPnt5(Xmax, Ymax, Zmax);
329 const gp_Pnt aPnt6(Xmax, Ymin, Zmax);
330 const gp_Pnt aPnt7(Xmax, Ymin, Zmin);
332 Standard_Real arrU[8], arrV[8];
333 GeomAPI_ProjectPointOnSurf aProj(aPnt0, pSurf);
334 /*szv:aProj.Perform(aPnt0);*/ if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[0],arrV[0]);
335 aProj.Perform(aPnt1); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[1],arrV[1]);
336 aProj.Perform(aPnt2); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[2],arrV[2]);
337 aProj.Perform(aPnt3); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[3],arrV[3]);
338 aProj.Perform(aPnt4); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[4],arrV[4]);
339 aProj.Perform(aPnt5); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[5],arrV[5]);
340 aProj.Perform(aPnt6); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[6],arrV[6]);
341 aProj.Perform(aPnt7); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[7],arrV[7]);
352 Standard_Integer i = 0;
355 const Standard_Real aU = arrU[i];
361 const Standard_Real aV = arrV[i];
370 GeomAdaptor_Surface aGAS(pSurf);
371 const Standard_Real tol = BRep_Tool::Tolerance(aF);
373 const Standard_Real EpsU = aGAS.UResolution(3.*tol);
374 if (fabs(Umin - Umax) < EpsU)
380 const Standard_Real EpsV = aGAS.VResolution(3.*tol);
381 if (fabs(Vmin - Vmax) < EpsV)
387 Handle(Geom_Surface) result = new Geom_RectangularTrimmedSurface(pSurf, Umin, Umax, Vmin, Vmax);
388 aResFace = BRepBuilderAPI_MakeFace(result, Precision::Confusion());
390 bIsInfinit = Standard_True;
393 bIsInfinit = Standard_False;
396 //------------------------------------------------------------------------------
397 // static function: PERFORM_C0
398 //------------------------------------------------------------------------------
399 static void PERFORM_C0(const TopoDS_Edge &S1, const TopoDS_Edge &S2,
400 BRepExtrema_SeqOfSolution& SeqSol1,
401 BRepExtrema_SeqOfSolution& SeqSol2,
402 const Standard_Real DstRef,
403 Standard_Real& mDstRef,
404 const Standard_Real Eps)
406 if ( BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2) )
410 for (iE = 0; iE < 2; iE++)
412 TopoDS_Edge E, Eother;
424 Standard_Real aFirst, aLast;
425 Handle(Geom_Curve) pCurv = BRep_Tool::Curve(E, aFirst, aLast);
427 Standard_Real aFOther, aLOther;
428 Handle(Geom_Curve) pCurvOther = BRep_Tool::Curve(Eother, aFOther, aLOther);
430 if (pCurv->Continuity() == GeomAbs_C0)
432 const Standard_Real epsP = Precision::PConfusion();
434 GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
435 const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
437 TColStd_Array1OfReal arrInter(1,1+nbIntervals);
438 aAdaptorCurve.Intervals(arrInter, GeomAbs_C1);
440 GeomAdaptor_Curve aAdaptorCurveOther(pCurvOther, aFOther, aLOther);
441 const Standard_Integer nbIntervalsOther = aAdaptorCurveOther.NbIntervals(GeomAbs_C1);
442 TColStd_Array1OfReal arrInterOther(1,1+nbIntervalsOther);
443 aAdaptorCurveOther.Intervals(arrInterOther, GeomAbs_C1);
445 Standard_Real Udeb,Ufin;
446 BRep_Tool::Range(Eother,Udeb,Ufin);
449 Standard_Integer i, ii;
450 BRepClass_FaceClassifier classifier;
451 for (i = 1; i <= arrInter.Length(); i++)
453 const Standard_Real aParameter = arrInter(i);
454 const gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
455 const TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
457 BRepExtrema_ExtPC Ext(V1,Eother);
458 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
461 // Search minimum distance dstmin
462 Standard_Real Dstmin = Ext.SquareDistance(1);
463 for (ii = 2; ii <= NbExtrema; ii++)
465 const Standard_Real sDst = Ext.SquareDistance(ii);
469 Dstmin = sqrt(Dstmin);
471 if ((Dstmin < DstRef - Eps) || (fabs(Dstmin-DstRef) < Eps))
472 for (ii = 1; ii <= NbExtrema; ii++)
474 if (fabs(Dstmin-sqrt(Ext.SquareDistance(ii)))<Eps)
477 if (TRI_SOLUTION(SeqSol2,Pt))
479 // Check if the parameter does not correspond to a vertex
480 const Standard_Real t = Ext.Parameter(ii);
481 if ((fabs(t-Udeb)>=epsP)&&(fabs(t-Ufin)>epsP))
483 if (mDstRef > Dstmin)
485 const BRepExtrema_SolutionElem Sol1(Dstmin,aPnt,BRepExtrema_IsOnEdge,E,aParameter);
486 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsOnEdge,Eother,t);
487 SeqSol1.Append(iE == 0 ? Sol1 : Sol2);
488 SeqSol2.Append(iE == 0 ? Sol2 : Sol1);
494 for (Standard_Integer i2 = 1; i2<=arrInterOther.Length(); i2++)
496 const Standard_Real aParameterOther = arrInterOther(i2);
497 const gp_Pnt aPntOther = aAdaptorCurveOther.Value(aParameterOther);
498 const Standard_Real Dst = aPnt.Distance(aPntOther);
499 if ((Dst < DstRef - Eps) || (fabs(Dst-DstRef) < Eps))
503 const BRepExtrema_SolutionElem Sol1(Dst,aPnt,BRepExtrema_IsOnEdge,E,aParameter);
504 const BRepExtrema_SolutionElem Sol2(Dst,aPntOther,BRepExtrema_IsOnEdge,Eother,aParameterOther);
505 SeqSol1.Append(iE == 0 ? Sol1 : Sol2);
506 SeqSol2.Append(iE == 0 ? Sol2 : Sol1);
514 /*********************************************************************************/
516 void BRepExtrema_DistanceSS::Perform(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
517 const Bnd_Box& B1, const Bnd_Box& B2)
519 SeqSolShape1.Clear();
520 SeqSolShape2.Clear();
521 myModif=Standard_False;
523 switch (S1.ShapeType())
527 TopoDS_Vertex V1 = TopoDS::Vertex(S1);
528 switch (S2.ShapeType())
532 TopoDS_Vertex V2 = TopoDS::Vertex(S2);
538 TopoDS_Edge E2 = TopoDS::Edge(S2);
539 Perform( V1, E2, B1, B2 );
544 TopoDS_Face F2 = TopoDS::Face(S2);
545 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 );
594 TopoDS_Face F1 = TopoDS::Face(S1);
595 switch (S2.ShapeType())
599 TopoDS_Vertex V2 = TopoDS::Vertex(S2);
600 Perform( F1, V2, B1, B2 );
605 TopoDS_Edge E2 = TopoDS::Edge(S2);
606 TopoDS_Face aTrimFace;
607 Standard_Boolean bIsInfinit;
608 TRIM_INFINIT_FACE( F1, E2, aTrimFace, bIsInfinit );
611 Perform( F1, E2, B1, B2 );
616 TopoDS_Face F2 = TopoDS::Face(S2);
617 Perform( F1, F2, B1, B2 );
626 /*********************************************************************************/
628 void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Vertex& S2)
630 const gp_Pnt P1 = BRep_Tool::Pnt(S1);
631 const gp_Pnt P2 = BRep_Tool::Pnt(S2);
633 const Standard_Real Dst = P1.Distance(P2);
634 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
638 myModif=Standard_True;
639 const BRepExtrema_SolutionElem Sol1(Dst,P1,BRepExtrema_IsVertex,S1);
640 const BRepExtrema_SolutionElem Sol2(Dst,P2,BRepExtrema_IsVertex,S2);
641 SeqSolShape1.Append(Sol1);
642 SeqSolShape2.Append(Sol2);
646 /*********************************************************************************/
648 void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Edge& S2,
649 const Bnd_Box& B1, const Bnd_Box& B2)
651 if (BRep_Tool::Degenerated(S2))
654 const Standard_Real Dst=B1.Distance(B2);
655 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
657 BRepExtrema_ExtPC Ext(S1,S2);
658 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
661 // Search minimum distance Dstmin
663 Standard_Real Dstmin = Ext.SquareDistance(1);
664 for (i = 2; i <= NbExtrema; i++)
666 const Standard_Real sDst = Ext.SquareDistance(i);
670 Dstmin = sqrt(Dstmin);
671 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
673 Standard_Real Udeb,Ufin;
674 BRep_Tool::Range(S2,Udeb,Ufin);
676 gp_Pnt Pt,P1=BRep_Tool::Pnt(S1);
677 const Standard_Real epsP=Precision::PConfusion();
679 for (i = 1; i <= NbExtrema; i++)
681 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
684 if (TRI_SOLUTION(SeqSolShape2,Pt))
686 // Check if the parameter does not correspond to a vertex
687 const Standard_Real t = Ext.Parameter(i);
688 if ( (fabs(t-Udeb)>=epsP) && (fabs(t-Ufin)>epsP) )
690 if (myDstRef > Dstmin)
692 myModif=Standard_True;
693 const BRepExtrema_SolutionElem Sol1(Dstmin,P1,BRepExtrema_IsVertex,S1);
694 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsOnEdge,S2,t);
695 SeqSolShape1.Append(Sol1);
696 SeqSolShape2.Append(Sol2);
706 void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1,const TopoDS_Vertex& S2,
707 const Bnd_Box& B1,const Bnd_Box& B2)
709 if (BRep_Tool::Degenerated(S1))
712 const Standard_Real Dst=B1.Distance(B2);
713 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
715 BRepExtrema_ExtPC Ext(S2,S1);
716 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
719 // Search minimum distance Dstmin
721 Standard_Real Dstmin = Ext.SquareDistance(1);
722 for (i = 2; i <= NbExtrema; i++)
724 const Standard_Real sDst = Ext.SquareDistance(i);
728 Dstmin = sqrt(Dstmin);
729 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
731 Standard_Real Udeb,Ufin;
732 BRep_Tool::Range(S1,Udeb,Ufin);
734 gp_Pnt Pt, P2 = BRep_Tool::Pnt(S2);
735 const Standard_Real epsP=Precision::PConfusion();
737 for (i = 1; i <= NbExtrema; i++)
739 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
742 if (TRI_SOLUTION(SeqSolShape1,Pt))
744 // Check if the parameter does not correspond to a vertex
745 const Standard_Real t = Ext.Parameter(i);
746 if ( (fabs(t-Udeb)>=epsP) && (fabs(t-Ufin)>epsP) )
748 if (myDstRef > Dstmin)
750 myModif=Standard_True;
751 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt,BRepExtrema_IsOnEdge,S1,t);
752 const BRepExtrema_SolutionElem Sol2(Dstmin,P2,BRepExtrema_IsVertex,S2);
753 SeqSolShape1.Append(Sol1);
754 SeqSolShape2.Append(Sol2);
764 /*********************************************************************************/
766 void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Face& S2,
767 const Bnd_Box& B1, const Bnd_Box& B2)
769 const Standard_Real Dst=B1.Distance(B2);
770 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
772 BRepExtrema_ExtPF Ext(S1,S2,myFlag,myAlgo);
773 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
776 // Search minimum distance Dstmin
778 Standard_Real Dstmin = Ext.SquareDistance(1);
779 for (i = 2; i <= NbExtrema; i++)
781 const Standard_Real sDst = Ext.SquareDistance(i);
785 Dstmin = sqrt(Dstmin);
786 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
789 gp_Pnt Pt,P1=BRep_Tool::Pnt(S1);
790 BRepClass_FaceClassifier classifier;
791 const Standard_Real tol = BRep_Tool::Tolerance(S2);
793 for (i = 1; i <= NbExtrema; i++)
795 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
798 if (TRI_SOLUTION(SeqSolShape2,Pt))
800 // Check if the parameter does not correspond to a vertex
801 Ext.Parameter(i,U,V);
802 const gp_Pnt2d PUV(U,V);
803 classifier.Perform(S2,PUV,tol);
804 if (classifier.State()==TopAbs_IN)
806 if (myDstRef > Dstmin)
808 myModif=Standard_True;
809 const BRepExtrema_SolutionElem Sol1(Dstmin,P1,BRepExtrema_IsVertex,S1);
810 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsInFace,S2,U,V);
811 SeqSolShape1.Append(Sol1);
812 SeqSolShape2.Append(Sol2);
822 void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Vertex& S2,
823 const Bnd_Box& B1, const Bnd_Box& B2)
825 const Standard_Real Dst=B1.Distance(B2);
826 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
828 BRepExtrema_ExtPF Ext(S2,S1,myFlag,myAlgo);
829 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
832 // Search minimum distance Dstmin
834 Standard_Real Dstmin = Ext.SquareDistance(1);
835 for (i = 2; i <= NbExtrema; i++)
837 const Standard_Real sDst = Ext.SquareDistance(i);
841 Dstmin = sqrt(Dstmin);
842 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
845 gp_Pnt Pt,P2=BRep_Tool::Pnt(S2);
846 BRepClass_FaceClassifier classifier;
847 const Standard_Real tol = BRep_Tool::Tolerance(S1);
849 for (i = 1; i <= NbExtrema; i++)
851 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
854 if (TRI_SOLUTION(SeqSolShape1,Pt))
856 // Check if the parameter does not correspond to a vertex
857 Ext.Parameter(i,U,V);
858 const gp_Pnt2d PUV(U,V);
859 classifier.Perform(S1,PUV,tol);
860 if (classifier.State()==TopAbs_IN)
862 if (myDstRef > Dstmin)
864 myModif=Standard_True;
865 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt,BRepExtrema_IsInFace,S1,U,V);
866 const BRepExtrema_SolutionElem Sol2(Dstmin,P2,BRepExtrema_IsVertex,S2);
867 SeqSolShape1.Append(Sol1);
868 SeqSolShape2.Append(Sol2);
878 /*********************************************************************************/
880 void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Edge& S2,
881 const Bnd_Box& B1, const Bnd_Box& B2)
883 if (BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2))
886 const Standard_Real Dst=B1.Distance(B2);
887 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
889 const Standard_Real DstRef = myDstRef;
891 BRepExtrema_ExtCC Ext(S1,S2);
892 const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
895 // Search minimum distance Dstmin
897 Standard_Real Dstmin = Ext.SquareDistance(1);
898 for (i = 2; i <= NbExtrema; i++)
900 const Standard_Real sDst = Ext.SquareDistance(i);
904 Dstmin = sqrt(Dstmin);
905 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
907 Standard_Real Udeb1,Ufin1,Udeb2,Ufin2;
908 BRep_Tool::Range(S1,Udeb1,Ufin1);
909 BRep_Tool::Range(S2,Udeb2,Ufin2);
912 const Standard_Real epsP=Precision::PConfusion();
914 for (i=1;i<=NbExtrema;i++)
916 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
918 Pt1=Ext.PointOnE1(i);
919 Pt2=Ext.PointOnE2(i);
920 if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
922 // Check if the parameters do not correspond to a vertex
923 const Standard_Real t1 = Ext.ParameterOnE1(i);
924 const Standard_Real t2 = Ext.ParameterOnE2(i);
925 if ((fabs(t1-Udeb1)>=epsP)&&(fabs(t1-Ufin1)>epsP)&&(fabs(t2-Udeb2)>=epsP)&&(fabs(t2-Ufin2)>epsP))
927 if (myDstRef > Dstmin)
929 myModif=Standard_True;
930 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsOnEdge,S1,t1);
931 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsOnEdge,S2,t2);
932 SeqSolShape1.Append(Sol1);
933 SeqSolShape2.Append(Sol2);
941 BRepExtrema_SeqOfSolution SeqSolution1;
942 BRepExtrema_SeqOfSolution SeqSolution2;
944 PERFORM_C0(S1, S2, SeqSolution1, SeqSolution2, DstRef, myDstRef, myEps);
946 BRepExtrema_SeqOfSolution seqSol1;
947 BRepExtrema_SeqOfSolution seqSol2;
949 if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
950 MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
952 if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
954 SeqSolShape1.Append(seqSol1);
955 SeqSolShape2.Append(seqSol2);
956 myModif = Standard_True;
961 /*********************************************************************************/
963 void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Face& S2,
964 const Bnd_Box& B1, const Bnd_Box& B2)
966 if (BRep_Tool::Degenerated(S1))
969 const Standard_Real Dst=B1.Distance(B2);
970 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
972 BRepClass_FaceClassifier classifier;
974 BRepExtrema_ExtCF Ext(S1,S2);
975 const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
978 // Search minimum distance Dstmin
980 Standard_Real Dstmin = Ext.SquareDistance(1);
981 for (i = 2; i <= NbExtrema; i++)
983 const Standard_Real sDst = Ext.SquareDistance(i);
987 Dstmin = sqrt(Dstmin);
988 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
990 Standard_Real Udeb,Ufin,U,V;
991 BRep_Tool::Range(S1,Udeb,Ufin);
992 const Standard_Real tol=BRep_Tool::Tolerance(S2);
995 const Standard_Real epsP=Precision::PConfusion();
997 for (i = 1; i <= NbExtrema; i++)
999 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
1001 Pt1=Ext.PointOnEdge(i);
1002 Pt2=Ext.PointOnFace(i);
1003 if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
1005 // Check if the parameter does not correspond to a vertex
1006 const Standard_Real t1 = Ext.ParameterOnEdge(i);
1007 if ((fabs(t1-Udeb)>=epsP)&&(fabs(t1-Ufin)>epsP))
1009 Ext.ParameterOnFace(i,U,V);
1010 const gp_Pnt2d PUV(U,V);
1011 classifier.Perform(S2,PUV,tol);
1012 if (classifier.State()==TopAbs_IN)
1014 if (myDstRef > Dstmin)
1016 myModif=Standard_True;
1017 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsOnEdge,S1,t1);
1018 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsInFace,S2,U,V);
1019 SeqSolShape1.Append(Sol1);
1020 SeqSolShape2.Append(Sol2);
1029 Standard_Real aFirst, aLast;
1030 Handle(Geom_Curve) pCurv = BRep_Tool::Curve(S1, aFirst, aLast);
1031 if (pCurv->Continuity() == GeomAbs_C0)
1033 BRepExtrema_SeqOfSolution SeqSolution1;
1034 BRepExtrema_SeqOfSolution SeqSolution2;
1036 GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
1037 const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
1039 TColStd_Array1OfReal arrInter(1,1+nbIntervals);
1040 aAdaptorCurve.Intervals(arrInter, GeomAbs_C1);
1044 const Standard_Real tol = BRep_Tool::Tolerance(S2);
1047 for (i = 1; i <= arrInter.Length(); i++)
1049 const Standard_Real aParameter = arrInter(i);
1050 gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
1051 TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
1053 BRepExtrema_ExtPF ExtPF(V1,S2);
1054 const Standard_Integer NbExtrema = ExtPF.IsDone()? ExtPF.NbExt() : 0;
1055 if ( NbExtrema > 0 )
1057 // Search minimum distance Dstmin
1058 Standard_Integer ii;
1059 Standard_Real Dstmin = ExtPF.SquareDistance(1);
1060 for (ii = 2; ii <= NbExtrema; ii++)
1062 const Standard_Real sDst = ExtPF.SquareDistance(ii);
1066 Dstmin = sqrt(Dstmin);
1068 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1070 for (ii = 1; ii <= NbExtrema; ii++)
1072 if (fabs(Dstmin-sqrt(ExtPF.SquareDistance(ii)))<myEps)
1074 // Check if the parameter does not correspond to a vertex
1075 ExtPF.Parameter(ii,U,V);
1076 const gp_Pnt2d PUV(U,V);
1077 classifier.Perform(S2,PUV,tol);
1078 if (classifier.State()==TopAbs_IN)
1080 if (myDstRef > Dstmin)
1082 myModif=Standard_True;
1083 const BRepExtrema_SolutionElem Sol1(Dstmin,aPnt,BRepExtrema_IsOnEdge,S1,aParameter);
1084 const BRepExtrema_SolutionElem Sol2(Dstmin,ExtPF.Point(ii),BRepExtrema_IsInFace,S2,U,V);
1085 SeqSolution1.Append(Sol1);
1086 SeqSolution2.Append(Sol2);
1094 BRepExtrema_SeqOfSolution seqSol1;
1095 BRepExtrema_SeqOfSolution seqSol2;
1096 if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
1097 MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
1099 if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
1101 SeqSolShape1.Append(seqSol1);
1102 SeqSolShape2.Append(seqSol2);
1108 void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Edge& S2,
1109 const Bnd_Box& B1, const Bnd_Box& B2)
1111 if (BRep_Tool::Degenerated(S2))
1114 const Standard_Real Dst=B1.Distance(B2);
1115 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
1117 BRepClass_FaceClassifier classifier;
1119 BRepExtrema_ExtCF Ext(S2,S1);
1120 const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
1121 if ( NbExtrema > 0 )
1123 // Search minimum distance Dstmin
1125 Standard_Real Dstmin = Ext.SquareDistance(1);
1126 for (i = 2; i <= NbExtrema; i++)
1128 const Standard_Real sDst = Ext.SquareDistance(i);
1132 Dstmin = sqrt(Dstmin);
1133 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1135 Standard_Real Udeb,Ufin,U,V;
1136 BRep_Tool::Range(S2,Udeb,Ufin);
1137 const Standard_Real tol=BRep_Tool::Tolerance(S1);
1140 const Standard_Real epsP=Precision::PConfusion();
1142 for (i = 1; i <= NbExtrema; i++)
1144 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
1146 Pt1=Ext.PointOnEdge(i);
1147 Pt2=Ext.PointOnFace(i);
1148 if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
1150 // Check if the parameter does not correspond to a vertex
1151 const Standard_Real t1 = Ext.ParameterOnEdge(i);
1152 if ((fabs(t1-Udeb)>=epsP)&&(fabs(t1-Ufin)>epsP))
1154 Ext.ParameterOnFace(i,U,V);
1155 const gp_Pnt2d PUV(U,V);
1156 classifier.Perform(S1,PUV,tol);
1157 if (classifier.State()==TopAbs_IN)
1159 if (myDstRef > Dstmin)
1161 myModif=Standard_True;
1162 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt1,BRepExtrema_IsOnEdge,S2,t1);
1163 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt2,BRepExtrema_IsInFace,S1,U,V);
1164 SeqSolShape1.Append(Sol1);
1165 SeqSolShape2.Append(Sol2);
1174 Standard_Real aFirst, aLast;
1175 Handle(Geom_Curve) pCurv = BRep_Tool::Curve(S2, aFirst, aLast);
1176 if (pCurv->Continuity() == GeomAbs_C0)
1178 BRepExtrema_SeqOfSolution SeqSolution1;
1179 BRepExtrema_SeqOfSolution SeqSolution2;
1181 GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
1182 const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
1184 TColStd_Array1OfReal arrInter(1,1+nbIntervals);
1185 aAdaptorCurve.Intervals(arrInter, GeomAbs_C1);
1189 const Standard_Real tol = BRep_Tool::Tolerance(S1);
1192 for (i = 1; i <= arrInter.Length(); i++)
1194 const Standard_Real aParameter = arrInter(i);
1195 gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
1196 TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
1198 BRepExtrema_ExtPF ExtPF(V1,S1);
1199 const Standard_Integer NbExtrema = ExtPF.IsDone()? ExtPF.NbExt() : 0;
1200 if ( NbExtrema > 0 )
1202 // Search minimum distance Dstmin
1203 Standard_Integer ii;
1204 Standard_Real Dstmin = ExtPF.SquareDistance(1);
1205 for (ii = 2; ii <= NbExtrema; ii++)
1207 const Standard_Real sDst = ExtPF.SquareDistance(ii);
1211 Dstmin = sqrt(Dstmin);
1213 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1215 for (ii = 1; ii <= NbExtrema; ii++)
1217 if (fabs(Dstmin-sqrt(ExtPF.SquareDistance(ii)))<myEps)
1219 // Check if the parameter does not correspond to a vertex
1220 ExtPF.Parameter(ii,U,V);
1221 const gp_Pnt2d PUV(U,V);
1222 classifier.Perform(S1,PUV,tol);
1223 if (classifier.State()==TopAbs_IN)
1225 if (myDstRef > Dstmin)
1227 myModif=Standard_True;
1228 const BRepExtrema_SolutionElem Sol2(Dstmin,aPnt,BRepExtrema_IsOnEdge,S2,aParameter);
1229 const BRepExtrema_SolutionElem Sol1(Dstmin,ExtPF.Point(ii),BRepExtrema_IsInFace,S1,U,V);
1230 SeqSolution1.Append(Sol1);
1231 SeqSolution2.Append(Sol2);
1239 BRepExtrema_SeqOfSolution seqSol1;
1240 BRepExtrema_SeqOfSolution seqSol2;
1241 if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
1242 MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
1244 if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
1246 SeqSolShape1.Append(seqSol1);
1247 SeqSolShape2.Append(seqSol2);
1253 /*********************************************************************************/
1255 void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Face& S2,
1256 const Bnd_Box& B1, const Bnd_Box& B2)
1258 const Standard_Real Dst=B1.Distance(B2);
1259 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
1261 BRepExtrema_ExtFF Ext(S1,S2);
1262 const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
1263 if ( NbExtrema > 0 )
1265 // Search minimum distance Dstmin
1267 Standard_Real Dstmin = Ext.SquareDistance(1);
1268 for (i = 2; i <= NbExtrema; i++)
1270 const Standard_Real sDst = Ext.SquareDistance(i);
1274 Dstmin = sqrt(Dstmin);
1275 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1277 const Standard_Real tol1=BRep_Tool::Tolerance(S1);
1278 const Standard_Real tol2=BRep_Tool::Tolerance(S2);
1282 Standard_Real U1,V1,U2,V2;
1283 BRepClass_FaceClassifier classifier;
1285 for (i = 1; i <= NbExtrema; i++)
1287 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
1289 Pt1=Ext.PointOnFace1(i);
1290 Pt2=Ext.PointOnFace2(i);
1291 if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
1293 // Check if the parameter does not correspond to a vertex
1294 Ext.ParameterOnFace1(i,U1,V1);
1295 PUV.SetCoord(U1,V1);
1296 classifier.Perform(S1,PUV,tol1);
1297 if (classifier.State()==TopAbs_IN)
1299 Ext.ParameterOnFace2(i,U2,V2);
1300 PUV.SetCoord(U2,V2);
1301 classifier.Perform(S2,PUV,tol2);
1302 if (classifier.State()==TopAbs_IN)
1304 if (myDstRef > Dstmin)
1306 myModif=Standard_True;
1307 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsInFace,S1,U1,V1);
1308 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsInFace,S2,U2,V2);
1309 SeqSolShape1.Append(Sol1);
1310 SeqSolShape2.Append(Sol2);
1321 /*********************************************************************************/