1 // File: BRepExtrema_DistanceSS.cxx
2 // Created: Mon Apr 22 17:03:37 1996
3 // Author: Maria PUMBORIOS
4 // Author: Herve LOUESSARD
6 // Modified: Sergey ZERCHANINOV
8 #include <BRepExtrema_DistanceSS.hxx>
10 #include <TopTools_IndexedMapOfShape.hxx>
13 #include <gp_Pnt2d.hxx>
14 #include <BRep_Tool.hxx>
15 #include <BRepExtrema_SupportType.hxx>
16 #include <Standard_Real.hxx>
17 #include <BRepExtrema_SolutionElem.hxx>
18 #include <BRepExtrema_SeqOfSolution.hxx>
19 #include <Standard_Boolean.hxx>
20 #include <Standard_Integer.hxx>
21 #include <TopAbs_ShapeEnum.hxx>
23 #include <Bnd_Box.hxx>
24 #include <BRepExtrema_ExtPC.hxx>
25 #include <BRepExtrema_ExtPF.hxx>
26 #include <Extrema_ExtFlag.hxx>
27 #include <BRepExtrema_ExtCC.hxx>
28 #include <BRepExtrema_ExtCF.hxx>
29 #include <BRepExtrema_ExtFF.hxx>
30 #include <BRepClass_FaceClassifier.hxx>
32 #include <Geom_Curve.hxx>
33 #include <GeomAbs_Shape.hxx>
34 #include <GeomAdaptor_Curve.hxx>
35 #include <TColStd_Array1OfReal.hxx>
36 #include <BRepBuilderAPI_MakeVertex.hxx>
37 #include <BRepBuilderAPI_MakeEdge.hxx>
38 #include <BRepBuilderAPI_MakeFace.hxx>
39 #include <Geom_Surface.hxx>
40 #include <GeomAPI_ProjectPointOnSurf.hxx>
41 #include <GeomAPI_ProjectPointOnCurve.hxx>
42 #include <Geom_RectangularTrimmedSurface.hxx>
43 #include <Geom_TrimmedCurve.hxx>
44 #include <BRepBndLib.hxx>
45 #include <BRepTools.hxx>
46 #include <TColgp_Array1OfPnt.hxx>
49 /*********************************************************************************/
51 //------------------------------------------------------------------------------
52 // function: TRI_SOLUTION
53 //------------------------------------------------------------------------------
54 static Standard_Boolean TRI_SOLUTION (const BRepExtrema_SeqOfSolution& SeqSol, const gp_Pnt& Pt)
56 const Standard_Integer Nbsol = SeqSol.Length();
57 for (Standard_Integer i = 1; i <= Nbsol; i++)
59 const Standard_Real dst = SeqSol.Value(i).Point().Distance(Pt);
60 if (dst <= Precision::Confusion()) return Standard_False;
65 //------------------------------------------------------------------------------
66 // function: MIN_SOLUTION
67 //------------------------------------------------------------------------------
68 static void MIN_SOLUTION (const BRepExtrema_SeqOfSolution& SeqSol1,
69 const BRepExtrema_SeqOfSolution& SeqSol2,
70 const Standard_Real DstRef,
71 const Standard_Real Eps,
72 BRepExtrema_SeqOfSolution& seqSol1,
73 BRepExtrema_SeqOfSolution& seqSol2)
75 const Standard_Integer nbSol = SeqSol1.Length();
76 for (Standard_Integer i = 1; i <= nbSol; i++)
78 const Standard_Real dst1 = SeqSol1.Value(i).Dist();
79 if (fabs(dst1 - DstRef) < Eps)
81 seqSol1.Append(SeqSol1.Value(i));
82 seqSol2.Append(SeqSol2.Value(i));
87 //------------------------------------------------------------------------------
88 // function: TRIM_INFINIT_EDGE
89 //------------------------------------------------------------------------------
90 static void TRIM_INFINIT_EDGE(const TopoDS_Edge& S1, const TopoDS_Edge& S2, TopoDS_Edge& aResEdge,
91 Standard_Boolean& bIsTrim1, Standard_Boolean& bIsTrim2)
93 if ( BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2) )
97 Standard_Real aFirst1, aLast1, aFirst2, aLast2;
98 Handle(Geom_Curve) pCurv1 = BRep_Tool::Curve(S1, aFirst1, aLast1);
99 Handle(Geom_Curve) pCurv2 = BRep_Tool::Curve(S2, aFirst2, aLast2);
101 if (Precision::IsInfinite(aFirst1) &&
102 Precision::IsInfinite(aLast1) &&
103 Precision::IsInfinite(aFirst2) &&
104 Precision::IsInfinite(aLast2))
107 Standard_Real Umin, Umax;
108 Standard_Boolean bUmin, bUmax;
109 bUmin = bUmax = Standard_False;
111 Handle(Geom_Curve) pCurv;
112 if ( !pCurv1.IsNull() && (Precision::IsInfinite(aFirst1) || Precision::IsInfinite(aLast1)) )
115 bIsTrim1 = Standard_True;
116 if (!Precision::IsInfinite(aFirst1))
118 bUmin = Standard_True;
121 else if (!Precision::IsInfinite(aLast1))
123 bUmax = Standard_True;
127 else if ( !pCurv2.IsNull() && (Precision::IsInfinite(aFirst2) || Precision::IsInfinite(aLast2)) )
130 bIsTrim2 = Standard_True;
131 if (!Precision::IsInfinite(aFirst2))
133 bUmin = Standard_True;
136 else if (!Precision::IsInfinite(aLast2))
138 bUmax = Standard_True;
142 if (bIsTrim1 || bIsTrim2)
146 BRepBndLib::Add(S2, aEdgeBox);
148 BRepBndLib::Add(S1, aEdgeBox);
149 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
150 aEdgeBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
152 const gp_Pnt aPnt0(Xmin, Ymin, Zmin);
153 const gp_Pnt aPnt1(Xmin, Ymax, Zmin);
154 const gp_Pnt aPnt2(Xmin, Ymax, Zmax);
155 const gp_Pnt aPnt3(Xmin, Ymin, Zmax);
156 const gp_Pnt aPnt4(Xmax, Ymax, Zmin);
157 const gp_Pnt aPnt5(Xmax, Ymax, Zmax);
158 const gp_Pnt aPnt6(Xmax, Ymin, Zmax);
159 const gp_Pnt aPnt7(Xmax, Ymin, Zmin);
161 Standard_Real arrU[8];
162 GeomAPI_ProjectPointOnCurve aProj(aPnt0, pCurv);
163 /*szv:aProj.Perform(aPnt0);*/ arrU[0] = aProj.LowerDistanceParameter();
164 aProj.Perform(aPnt1); arrU[1] = aProj.LowerDistanceParameter();
165 aProj.Perform(aPnt2); arrU[2] = aProj.LowerDistanceParameter();
166 aProj.Perform(aPnt3); arrU[3] = aProj.LowerDistanceParameter();
167 aProj.Perform(aPnt4); arrU[4] = aProj.LowerDistanceParameter();
168 aProj.Perform(aPnt5); arrU[5] = aProj.LowerDistanceParameter();
169 aProj.Perform(aPnt6); arrU[6] = aProj.LowerDistanceParameter();
170 aProj.Perform(aPnt7); arrU[7] = aProj.LowerDistanceParameter();
178 Standard_Integer i = 0;
181 const Standard_Real aU = arrU[i++];
188 Standard_Real tol = Precision::Confusion();
190 tol = BRep_Tool::Tolerance(S1);
192 tol = BRep_Tool::Tolerance(S2);
194 const Standard_Real EpsU = GeomAdaptor_Curve(pCurv).Resolution(3.*tol);
195 if (fabs(Umin - Umax) < EpsU)
201 Handle(Geom_Curve) result = new Geom_TrimmedCurve(pCurv, Umin, Umax);
202 aResEdge = BRepBuilderAPI_MakeEdge(result);
206 //------------------------------------------------------------------------------
207 // function: TRIM_INFINIT_FACE
208 //------------------------------------------------------------------------------
209 static void TRIM_INFINIT_FACE(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
210 TopoDS_Face& aResFace, Standard_Boolean& bIsInfinit)
212 bIsInfinit = Standard_False;
214 TopAbs_ShapeEnum Type1 = S1.ShapeType();
215 TopAbs_ShapeEnum Type2 = S2.ShapeType();
220 if (Type1 == TopAbs_EDGE && Type2 == TopAbs_FACE)
222 aE = TopoDS::Edge(S1);
223 if ( BRep_Tool::Degenerated(aE) )
225 aF = TopoDS::Face(S2);
227 else if (Type2 == TopAbs_EDGE && Type1 == TopAbs_FACE)
229 aE = TopoDS::Edge(S2);
230 if ( BRep_Tool::Degenerated(aE) )
232 aF = TopoDS::Face(S1);
236 bIsInfinit = Standard_False;
241 Handle(Geom_Surface) pSurf = BRep_Tool::Surface(aF);
243 const Standard_Boolean bRestrict = BRep_Tool::NaturalRestriction(aF);
245 Standard_Real U1, V1, U2, V2;
246 Standard_Real Umin, Umax, Vmin, Vmax;
247 Standard_Boolean bUmin, bUmax, bVmin, bVmax;
248 bUmin = bUmax = bVmin = bVmax = Standard_False;
249 Standard_Boolean bIsTrim = Standard_False;
253 pSurf->Bounds(U1, U2, V1, V2);
254 if (Precision::IsInfinite(U1))
255 bIsTrim = Standard_True;
259 bUmin = Standard_True;
262 if (Precision::IsInfinite(U2))
263 bIsTrim = Standard_True;
267 bUmax = Standard_True;
270 if (Precision::IsInfinite(V1))
271 bIsTrim = Standard_True;
275 bVmin = Standard_True;
278 if (Precision::IsInfinite(V2))
279 bIsTrim = Standard_True;
283 bVmax = Standard_True;
288 BRepTools::UVBounds(aF, U1, U2, V1, V2);
289 if (Precision::IsInfinite(U1) &&
290 Precision::IsInfinite(U2) &&
291 Precision::IsInfinite(V1) &&
292 Precision::IsInfinite(V2))
293 bIsTrim = Standard_True;
299 BRepBndLib::Add(aE, aEdgeBox);
301 if(aEdgeBox.IsWhole())
304 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
305 aEdgeBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
307 const gp_Pnt aPnt0(Xmin, Ymin, Zmin);
308 const gp_Pnt aPnt1(Xmin, Ymax, Zmin);
309 const gp_Pnt aPnt2(Xmin, Ymax, Zmax);
310 const gp_Pnt aPnt3(Xmin, Ymin, Zmax);
311 const gp_Pnt aPnt4(Xmax, Ymax, Zmin);
312 const gp_Pnt aPnt5(Xmax, Ymax, Zmax);
313 const gp_Pnt aPnt6(Xmax, Ymin, Zmax);
314 const gp_Pnt aPnt7(Xmax, Ymin, Zmin);
316 Standard_Real arrU[8], arrV[8];
317 GeomAPI_ProjectPointOnSurf aProj(aPnt0, pSurf);
318 /*szv:aProj.Perform(aPnt0);*/ if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[0],arrV[0]);
319 aProj.Perform(aPnt1); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[1],arrV[1]);
320 aProj.Perform(aPnt2); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[2],arrV[2]);
321 aProj.Perform(aPnt3); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[3],arrV[3]);
322 aProj.Perform(aPnt4); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[4],arrV[4]);
323 aProj.Perform(aPnt5); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[5],arrV[5]);
324 aProj.Perform(aPnt6); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[6],arrV[6]);
325 aProj.Perform(aPnt7); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[7],arrV[7]);
336 Standard_Integer i = 0;
339 const Standard_Real aU = arrU[i];
345 const Standard_Real aV = arrV[i];
352 GeomAdaptor_Surface aGAS(pSurf);
353 const Standard_Real tol = BRep_Tool::Tolerance(aF);
355 const Standard_Real EpsU = aGAS.UResolution(3.*tol);
356 if (fabs(Umin - Umax) < EpsU)
362 const Standard_Real EpsV = aGAS.VResolution(3.*tol);
363 if (fabs(Vmin - Vmax) < EpsV)
369 Handle(Geom_Surface) result = new Geom_RectangularTrimmedSurface(pSurf, Umin, Umax, Vmin, Vmax);
370 aResFace = BRepBuilderAPI_MakeFace(result);
372 bIsInfinit = Standard_True;
375 bIsInfinit = Standard_False;
378 //------------------------------------------------------------------------------
379 // static function: PERFORM_C0
380 //------------------------------------------------------------------------------
381 static void PERFORM_C0(const TopoDS_Edge &S1, const TopoDS_Edge &S2,
382 BRepExtrema_SeqOfSolution& SeqSol1,
383 BRepExtrema_SeqOfSolution& SeqSol2,
384 const Standard_Real DstRef,
385 Standard_Real& mDstRef,
386 const Standard_Real Eps)
388 if ( BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2) )
392 for (iE = 0; iE < 2; iE++)
394 TopoDS_Edge E, Eother;
406 Standard_Real aFirst, aLast;
407 Handle(Geom_Curve) pCurv = BRep_Tool::Curve(E, aFirst, aLast);
409 Standard_Real aFOther, aLOther;
410 Handle(Geom_Curve) pCurvOther = BRep_Tool::Curve(Eother, aFOther, aLOther);
412 if (pCurv->Continuity() == GeomAbs_C0)
414 const Standard_Real epsP = Precision::PConfusion();
416 GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
417 const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
419 TColStd_Array1OfReal arrInter(1,1+nbIntervals);
420 aAdaptorCurve.Intervals(arrInter, GeomAbs_C1);
422 GeomAdaptor_Curve aAdaptorCurveOther(pCurvOther, aFOther, aLOther);
423 const Standard_Integer nbIntervalsOther = aAdaptorCurveOther.NbIntervals(GeomAbs_C1);
424 TColStd_Array1OfReal arrInterOther(1,1+nbIntervalsOther);
425 aAdaptorCurveOther.Intervals(arrInterOther, GeomAbs_C1);
427 Standard_Real Udeb,Ufin;
428 BRep_Tool::Range(Eother,Udeb,Ufin);
431 Standard_Integer i, ii;
432 BRepClass_FaceClassifier classifier;
433 for (i = 1; i <= arrInter.Length(); i++)
435 const Standard_Real aParameter = arrInter(i);
436 const gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
437 const TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
439 BRepExtrema_ExtPC Ext(V1,Eother);
440 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
443 // Search minimum distance dstmin
444 Standard_Real Dstmin = Ext.SquareDistance(1);
445 for (ii = 2; ii <= NbExtrema; ii++)
447 const Standard_Real sDst = Ext.SquareDistance(ii);
451 Dstmin = sqrt(Dstmin);
453 if ((Dstmin < DstRef - Eps) || (fabs(Dstmin-DstRef) < Eps))
454 for (ii = 1; ii <= NbExtrema; ii++)
456 if (fabs(Dstmin-sqrt(Ext.SquareDistance(ii)))<Eps)
459 if (TRI_SOLUTION(SeqSol2,Pt))
461 // Check if the parameter does not correspond to a vertex
462 const Standard_Real t = Ext.Parameter(ii);
463 if ((fabs(t-Udeb)>=epsP)&&(fabs(t-Ufin)>epsP))
465 if (mDstRef > Dstmin)
467 const BRepExtrema_SolutionElem Sol1(Dstmin,aPnt,BRepExtrema_IsOnEdge,E,aParameter);
468 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsOnEdge,Eother,t);
469 SeqSol1.Append(iE == 0 ? Sol1 : Sol2);
470 SeqSol2.Append(iE == 0 ? Sol2 : Sol1);
476 for (Standard_Integer i2 = 1; i2<=arrInterOther.Length(); i2++)
478 const Standard_Real aParameterOther = arrInterOther(i2);
479 const gp_Pnt aPntOther = aAdaptorCurveOther.Value(aParameterOther);
480 const Standard_Real Dst = aPnt.Distance(aPntOther);
481 if ((Dst < DstRef - Eps) || (fabs(Dst-DstRef) < Eps))
485 const BRepExtrema_SolutionElem Sol1(Dst,aPnt,BRepExtrema_IsOnEdge,E,aParameter);
486 const BRepExtrema_SolutionElem Sol2(Dst,aPntOther,BRepExtrema_IsOnEdge,Eother,aParameterOther);
487 SeqSol1.Append(iE == 0 ? Sol1 : Sol2);
488 SeqSol2.Append(iE == 0 ? Sol2 : Sol1);
496 /*********************************************************************************/
498 void BRepExtrema_DistanceSS::Perform(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
499 const Bnd_Box& B1, const Bnd_Box& B2)
501 SeqSolShape1.Clear();
502 SeqSolShape2.Clear();
503 myModif=Standard_False;
505 switch (S1.ShapeType())
509 TopoDS_Vertex V1 = TopoDS::Vertex(S1);
510 switch (S2.ShapeType())
514 TopoDS_Vertex V2 = TopoDS::Vertex(S2);
520 TopoDS_Edge E2 = TopoDS::Edge(S2);
521 Perform( V1, E2, B1, B2 );
526 TopoDS_Face F2 = TopoDS::Face(S2);
527 Perform( V1, F2, B1, B2 );
536 TopoDS_Edge E1 = TopoDS::Edge(S1);
537 switch (S2.ShapeType())
541 TopoDS_Vertex V2 = TopoDS::Vertex(S2);
542 Perform( E1, V2, B1, B2 );
547 TopoDS_Edge E2 = TopoDS::Edge(S2);
548 TopoDS_Edge aTrimEdge;
549 Standard_Boolean bIsTrim1 = Standard_False;
550 Standard_Boolean bIsTrim2 = Standard_False;
551 TRIM_INFINIT_EDGE( E1, E2, aTrimEdge, bIsTrim1, bIsTrim2 );
556 Perform( E1, E2, B1, B2 );
561 TopoDS_Face F2 = TopoDS::Face(S2);
562 TopoDS_Face aTrimFace;
563 Standard_Boolean bIsInfinit;
564 TRIM_INFINIT_FACE( E1, F2, aTrimFace, bIsInfinit );
567 Perform( E1, F2, B1, B2 );
576 TopoDS_Face F1 = TopoDS::Face(S1);
577 switch (S2.ShapeType())
581 TopoDS_Vertex V2 = TopoDS::Vertex(S2);
582 Perform( F1, V2, B1, B2 );
587 TopoDS_Edge E2 = TopoDS::Edge(S2);
588 TopoDS_Face aTrimFace;
589 Standard_Boolean bIsInfinit;
590 TRIM_INFINIT_FACE( F1, E2, aTrimFace, bIsInfinit );
593 Perform( F1, E2, B1, B2 );
598 TopoDS_Face F2 = TopoDS::Face(S2);
599 Perform( F1, F2, B1, B2 );
608 /*********************************************************************************/
610 void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Vertex& S2)
612 const gp_Pnt P1 = BRep_Tool::Pnt(S1);
613 const gp_Pnt P2 = BRep_Tool::Pnt(S2);
615 const Standard_Real Dst = P1.Distance(P2);
616 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
620 myModif=Standard_True;
621 const BRepExtrema_SolutionElem Sol1(Dst,P1,BRepExtrema_IsVertex,S1);
622 const BRepExtrema_SolutionElem Sol2(Dst,P2,BRepExtrema_IsVertex,S2);
623 SeqSolShape1.Append(Sol1);
624 SeqSolShape2.Append(Sol2);
628 /*********************************************************************************/
630 void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Edge& S2,
631 const Bnd_Box& B1, const Bnd_Box& B2)
633 if (BRep_Tool::Degenerated(S2))
636 const Standard_Real Dst=B1.Distance(B2);
637 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
639 BRepExtrema_ExtPC Ext(S1,S2);
640 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
643 // Search minimum distance Dstmin
645 Standard_Real Dstmin = Ext.SquareDistance(1);
646 for (i = 2; i <= NbExtrema; i++)
648 const Standard_Real sDst = Ext.SquareDistance(i);
652 Dstmin = sqrt(Dstmin);
653 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
655 Standard_Real Udeb,Ufin;
656 BRep_Tool::Range(S2,Udeb,Ufin);
658 gp_Pnt Pt,P1=BRep_Tool::Pnt(S1);
659 const Standard_Real epsP=Precision::PConfusion();
661 for (i = 1; i <= NbExtrema; i++)
663 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
666 if (TRI_SOLUTION(SeqSolShape2,Pt))
668 // Check if the parameter does not correspond to a vertex
669 const Standard_Real t = Ext.Parameter(i);
670 if ( (fabs(t-Udeb)>=epsP) && (fabs(t-Ufin)>epsP) )
672 if (myDstRef > Dstmin)
674 myModif=Standard_True;
675 const BRepExtrema_SolutionElem Sol1(Dstmin,P1,BRepExtrema_IsVertex,S1);
676 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsOnEdge,S2,t);
677 SeqSolShape1.Append(Sol1);
678 SeqSolShape2.Append(Sol2);
688 void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1,const TopoDS_Vertex& S2,
689 const Bnd_Box& B1,const Bnd_Box& B2)
691 if (BRep_Tool::Degenerated(S1))
694 const Standard_Real Dst=B1.Distance(B2);
695 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
697 BRepExtrema_ExtPC Ext(S2,S1);
698 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
701 // Search minimum distance Dstmin
703 Standard_Real Dstmin = Ext.SquareDistance(1);
704 for (i = 2; i <= NbExtrema; i++)
706 const Standard_Real sDst = Ext.SquareDistance(i);
710 Dstmin = sqrt(Dstmin);
711 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
713 Standard_Real Udeb,Ufin;
714 BRep_Tool::Range(S1,Udeb,Ufin);
716 gp_Pnt Pt,P1=BRep_Tool::Pnt(S2);
717 const Standard_Real epsP=Precision::PConfusion();
719 for (i = 1; i <= NbExtrema; i++)
721 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
724 if (TRI_SOLUTION(SeqSolShape1,Pt))
726 // Check if the parameter does not correspond to a vertex
727 const Standard_Real t = Ext.Parameter(i);
728 if ( (fabs(t-Udeb)>=epsP) && (fabs(t-Ufin)>epsP) )
730 if (myDstRef > Dstmin)
732 myModif=Standard_True;
733 const BRepExtrema_SolutionElem Sol1(Dstmin,P1,BRepExtrema_IsOnEdge,S1,t);
734 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsVertex,S2);
735 SeqSolShape1.Append(Sol1);
736 SeqSolShape2.Append(Sol2);
746 /*********************************************************************************/
748 void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Face& S2,
749 const Bnd_Box& B1, const Bnd_Box& B2)
751 const Standard_Real Dst=B1.Distance(B2);
752 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
754 BRepExtrema_ExtPF Ext(S1,S2,myFlag,myAlgo);
755 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
758 // Search minimum distance Dstmin
760 Standard_Real Dstmin = Ext.SquareDistance(1);
761 for (i = 2; i <= NbExtrema; i++)
763 const Standard_Real sDst = Ext.SquareDistance(i);
767 Dstmin = sqrt(Dstmin);
768 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
771 gp_Pnt Pt,P1=BRep_Tool::Pnt(S1);
772 BRepClass_FaceClassifier classifier;
773 const Standard_Real tol = BRep_Tool::Tolerance(S2);
774 const Standard_Real epsP = Precision::PConfusion();
776 for (i = 1; i <= NbExtrema; i++)
778 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
781 if (TRI_SOLUTION(SeqSolShape2,Pt))
783 // Check if the parameter does not correspond to a vertex
784 Ext.Parameter(i,U,V);
785 const gp_Pnt2d PUV(U,V);
786 classifier.Perform(S2,PUV,tol);
787 if (classifier.State()==TopAbs_IN)
789 if (myDstRef > Dstmin)
791 myModif=Standard_True;
792 const BRepExtrema_SolutionElem Sol1(Dstmin,P1,BRepExtrema_IsVertex,S1);
793 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsInFace,S2,U,V);
794 SeqSolShape1.Append(Sol1);
795 SeqSolShape2.Append(Sol2);
805 void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Vertex& S2,
806 const Bnd_Box& B1, const Bnd_Box& B2)
808 const Standard_Real Dst=B1.Distance(B2);
809 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
811 BRepExtrema_ExtPF Ext(S2,S1,myFlag,myAlgo);
812 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
815 // Search minimum distance Dstmin
817 Standard_Real Dstmin = Ext.SquareDistance(1);
818 for (i = 2; i <= NbExtrema; i++)
820 const Standard_Real sDst = Ext.SquareDistance(i);
824 Dstmin = sqrt(Dstmin);
825 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
828 gp_Pnt Pt,P1=BRep_Tool::Pnt(S2);
829 BRepClass_FaceClassifier classifier;
830 const Standard_Real tol = BRep_Tool::Tolerance(S1);
831 const Standard_Real epsP = Precision::PConfusion();
833 for (i = 1; i <= NbExtrema; i++)
835 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
838 if (TRI_SOLUTION(SeqSolShape1,Pt))
840 // Check if the parameter does not correspond to a vertex
841 Ext.Parameter(i,U,V);
842 const gp_Pnt2d PUV(U,V);
843 classifier.Perform(S1,PUV,tol);
844 if (classifier.State()==TopAbs_IN)
846 if (myDstRef > Dstmin)
848 myModif=Standard_True;
849 const BRepExtrema_SolutionElem Sol1(Dstmin,P1,BRepExtrema_IsInFace,S1,U,V);
850 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsVertex,S2);
851 SeqSolShape1.Append(Sol1);
852 SeqSolShape2.Append(Sol2);
862 /*********************************************************************************/
864 void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Edge& S2,
865 const Bnd_Box& B1, const Bnd_Box& B2)
867 if (BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2))
870 const Standard_Real Dst=B1.Distance(B2);
871 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
873 const Standard_Real DstRef = myDstRef;
875 BRepExtrema_ExtCC Ext(S1,S2);
876 const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
879 // Search minimum distance Dstmin
881 Standard_Real Dstmin = Ext.SquareDistance(1);
882 for (i = 2; i <= NbExtrema; i++)
884 const Standard_Real sDst = Ext.SquareDistance(i);
888 Dstmin = sqrt(Dstmin);
889 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
891 Standard_Real Udeb1,Ufin1,Udeb2,Ufin2;
892 BRep_Tool::Range(S1,Udeb1,Ufin1);
893 BRep_Tool::Range(S2,Udeb2,Ufin2);
896 const Standard_Real epsP=Precision::PConfusion();
898 for (i=1;i<=NbExtrema;i++)
900 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
902 Pt1=Ext.PointOnE1(i);
903 Pt2=Ext.PointOnE2(i);
904 if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
906 // Check if the parameters do not correspond to a vertex
907 const Standard_Real t1 = Ext.ParameterOnE1(i);
908 const Standard_Real t2 = Ext.ParameterOnE2(i);
909 if ((fabs(t1-Udeb1)>=epsP)&&(fabs(t1-Ufin1)>epsP)&&(fabs(t2-Udeb2)>=epsP)&&(fabs(t2-Ufin2)>epsP))
911 if (myDstRef > Dstmin)
913 myModif=Standard_True;
914 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsOnEdge,S1,t1);
915 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsOnEdge,S2,t2);
916 SeqSolShape1.Append(Sol1);
917 SeqSolShape2.Append(Sol2);
925 BRepExtrema_SeqOfSolution SeqSolution1;
926 BRepExtrema_SeqOfSolution SeqSolution2;
928 PERFORM_C0(S1, S2, SeqSolution1, SeqSolution2, DstRef, myDstRef, myEps);
930 BRepExtrema_SeqOfSolution seqSol1;
931 BRepExtrema_SeqOfSolution seqSol2;
933 if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
934 MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
936 if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
938 SeqSolShape1.Append(seqSol1);
939 SeqSolShape2.Append(seqSol2);
940 myModif = Standard_True;
945 /*********************************************************************************/
947 void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Face& S2,
948 const Bnd_Box& B1, const Bnd_Box& B2)
950 if (BRep_Tool::Degenerated(S1))
953 const Standard_Real Dst=B1.Distance(B2);
954 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
956 BRepClass_FaceClassifier classifier;
958 BRepExtrema_ExtCF Ext(S1,S2);
959 const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
962 // Search minimum distance Dstmin
964 Standard_Real Dstmin = Ext.SquareDistance(1);
965 for (i = 2; i <= NbExtrema; i++)
967 const Standard_Real sDst = Ext.SquareDistance(i);
971 Dstmin = sqrt(Dstmin);
972 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
974 Standard_Real Udeb,Ufin,U,V;
975 BRep_Tool::Range(S1,Udeb,Ufin);
976 const Standard_Real tol=BRep_Tool::Tolerance(S2);
979 const Standard_Real epsP=Precision::PConfusion();
981 for (i = 1; i <= NbExtrema; i++)
983 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
985 Pt1=Ext.PointOnEdge(i);
986 Pt2=Ext.PointOnFace(i);
987 if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
989 // Check if the parameter does not correspond to a vertex
990 const Standard_Real t1 = Ext.ParameterOnEdge(i);
991 if ((fabs(t1-Udeb)>=epsP)&&(fabs(t1-Ufin)>epsP))
993 Ext.ParameterOnFace(i,U,V);
994 const gp_Pnt2d PUV(U,V);
995 classifier.Perform(S2,PUV,tol);
996 if (classifier.State()==TopAbs_IN)
998 if (myDstRef > Dstmin)
1000 myModif=Standard_True;
1001 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsOnEdge,S1,t1);
1002 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsInFace,S2,U,V);
1003 SeqSolShape1.Append(Sol1);
1004 SeqSolShape2.Append(Sol2);
1013 Standard_Real aFirst, aLast;
1014 Handle(Geom_Curve) pCurv = BRep_Tool::Curve(S1, aFirst, aLast);
1015 if (pCurv->Continuity() == GeomAbs_C0)
1017 BRepExtrema_SeqOfSolution SeqSolution1;
1018 BRepExtrema_SeqOfSolution SeqSolution2;
1020 GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
1021 const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
1023 TColStd_Array1OfReal arrInter(1,1+nbIntervals);
1024 aAdaptorCurve.Intervals(arrInter, GeomAbs_C1);
1028 const Standard_Real tol = BRep_Tool::Tolerance(S2);
1031 for (i = 1; i <= arrInter.Length(); i++)
1033 const Standard_Real aParameter = arrInter(i);
1034 gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
1035 TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
1037 BRepExtrema_ExtPF ExtPF(V1,S2);
1038 const Standard_Integer NbExtrema = ExtPF.IsDone()? ExtPF.NbExt() : 0;
1039 if ( NbExtrema > 0 )
1041 // Search minimum distance Dstmin
1042 Standard_Integer ii;
1043 Standard_Real Dstmin = ExtPF.SquareDistance(1);
1044 for (ii = 2; ii <= NbExtrema; ii++)
1046 const Standard_Real sDst = ExtPF.SquareDistance(ii);
1050 Dstmin = sqrt(Dstmin);
1052 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1054 for (ii = 1; ii <= NbExtrema; ii++)
1056 if (fabs(Dstmin-sqrt(ExtPF.SquareDistance(ii)))<myEps)
1058 // Check if the parameter does not correspond to a vertex
1059 ExtPF.Parameter(ii,U,V);
1060 const gp_Pnt2d PUV(U,V);
1061 classifier.Perform(S2,PUV,tol);
1062 if (classifier.State()==TopAbs_IN)
1064 if (myDstRef > Dstmin)
1066 myModif=Standard_True;
1067 const BRepExtrema_SolutionElem Sol1(Dstmin,aPnt,BRepExtrema_IsOnEdge,S1,aParameter);
1068 const BRepExtrema_SolutionElem Sol2(Dstmin,ExtPF.Point(ii),BRepExtrema_IsInFace,S2,U,V);
1069 SeqSolution1.Append(Sol1);
1070 SeqSolution2.Append(Sol2);
1078 BRepExtrema_SeqOfSolution seqSol1;
1079 BRepExtrema_SeqOfSolution seqSol2;
1080 Standard_Boolean bIsMini = Standard_False;
1081 if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
1082 MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
1084 if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
1086 SeqSolShape1.Append(seqSol1);
1087 SeqSolShape2.Append(seqSol2);
1093 void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Edge& S2,
1094 const Bnd_Box& B1, const Bnd_Box& B2)
1096 if (BRep_Tool::Degenerated(S2))
1099 const Standard_Real Dst=B1.Distance(B2);
1100 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
1102 BRepClass_FaceClassifier classifier;
1104 BRepExtrema_ExtCF Ext(S2,S1);
1105 const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
1106 if ( NbExtrema > 0 )
1108 // Search minimum distance Dstmin
1110 Standard_Real Dstmin = Ext.SquareDistance(1);
1111 for (i = 2; i <= NbExtrema; i++)
1113 const Standard_Real sDst = Ext.SquareDistance(i);
1117 Dstmin = sqrt(Dstmin);
1118 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1120 Standard_Real Udeb,Ufin,U,V;
1121 BRep_Tool::Range(S2,Udeb,Ufin);
1122 const Standard_Real tol=BRep_Tool::Tolerance(S1);
1125 const Standard_Real epsP=Precision::PConfusion();
1127 for (i = 1; i <= NbExtrema; i++)
1129 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
1131 Pt1=Ext.PointOnEdge(i);
1132 Pt2=Ext.PointOnFace(i);
1133 if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
1135 // Check if the parameter does not correspond to a vertex
1136 const Standard_Real t1 = Ext.ParameterOnEdge(i);
1137 if ((fabs(t1-Udeb)>=epsP)&&(fabs(t1-Ufin)>epsP))
1139 Ext.ParameterOnFace(i,U,V);
1140 const gp_Pnt2d PUV(U,V);
1141 classifier.Perform(S1,PUV,tol);
1142 if (classifier.State()==TopAbs_IN)
1144 if (myDstRef > Dstmin)
1146 myModif=Standard_True;
1147 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt1,BRepExtrema_IsOnEdge,S2,t1);
1148 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt2,BRepExtrema_IsInFace,S1,U,V);
1149 SeqSolShape1.Append(Sol1);
1150 SeqSolShape2.Append(Sol2);
1159 Standard_Real aFirst, aLast;
1160 Handle(Geom_Curve) pCurv = BRep_Tool::Curve(S2, aFirst, aLast);
1161 if (pCurv->Continuity() == GeomAbs_C0)
1163 BRepExtrema_SeqOfSolution SeqSolution1;
1164 BRepExtrema_SeqOfSolution SeqSolution2;
1166 GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
1167 const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
1169 TColStd_Array1OfReal arrInter(1,1+nbIntervals);
1170 aAdaptorCurve.Intervals(arrInter, GeomAbs_C1);
1174 const Standard_Real tol = BRep_Tool::Tolerance(S1);
1177 for (i = 1; i <= arrInter.Length(); i++)
1179 const Standard_Real aParameter = arrInter(i);
1180 gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
1181 TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
1183 BRepExtrema_ExtPF ExtPF(V1,S1);
1184 const Standard_Integer NbExtrema = ExtPF.IsDone()? ExtPF.NbExt() : 0;
1185 if ( NbExtrema > 0 )
1187 // Search minimum distance Dstmin
1188 Standard_Integer ii;
1189 Standard_Real Dstmin = ExtPF.SquareDistance(1);
1190 for (ii = 2; ii <= NbExtrema; ii++)
1192 const Standard_Real sDst = ExtPF.SquareDistance(ii);
1196 Dstmin = sqrt(Dstmin);
1198 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1200 for (ii = 1; ii <= NbExtrema; ii++)
1202 if (fabs(Dstmin-sqrt(ExtPF.SquareDistance(ii)))<myEps)
1204 // Check if the parameter does not correspond to a vertex
1205 ExtPF.Parameter(ii,U,V);
1206 const gp_Pnt2d PUV(U,V);
1207 classifier.Perform(S1,PUV,tol);
1208 if (classifier.State()==TopAbs_IN)
1210 if (myDstRef > Dstmin)
1212 myModif=Standard_True;
1213 const BRepExtrema_SolutionElem Sol2(Dstmin,aPnt,BRepExtrema_IsOnEdge,S2,aParameter);
1214 const BRepExtrema_SolutionElem Sol1(Dstmin,ExtPF.Point(ii),BRepExtrema_IsInFace,S1,U,V);
1215 SeqSolution1.Append(Sol1);
1216 SeqSolution2.Append(Sol2);
1224 BRepExtrema_SeqOfSolution seqSol1;
1225 BRepExtrema_SeqOfSolution seqSol2;
1226 Standard_Boolean bIsMini = Standard_False;
1227 if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
1228 MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
1230 if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
1232 SeqSolShape1.Append(seqSol1);
1233 SeqSolShape2.Append(seqSol2);
1239 /*********************************************************************************/
1241 void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Face& S2,
1242 const Bnd_Box& B1, const Bnd_Box& B2)
1244 const Standard_Real Dst=B1.Distance(B2);
1245 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
1247 BRepExtrema_ExtFF Ext(S1,S2);
1248 const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
1249 if ( NbExtrema > 0 )
1251 // Search minimum distance Dstmin
1253 Standard_Real Dstmin = Ext.SquareDistance(1);
1254 for (i = 2; i <= NbExtrema; i++)
1256 const Standard_Real sDst = Ext.SquareDistance(i);
1260 Dstmin = sqrt(Dstmin);
1261 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1263 const Standard_Real tol1=BRep_Tool::Tolerance(S1);
1264 const Standard_Real tol2=BRep_Tool::Tolerance(S2);
1268 Standard_Real U1,V1,U2,V2;
1269 BRepClass_FaceClassifier classifier;
1270 const Standard_Real epsP=Precision::PConfusion();
1272 for (i = 1; i <= NbExtrema; i++)
1274 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
1276 Pt1=Ext.PointOnFace1(i);
1277 Pt2=Ext.PointOnFace2(i);
1278 if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
1280 // Check if the parameter does not correspond to a vertex
1281 Ext.ParameterOnFace1(i,U1,V1);
1282 PUV.SetCoord(U1,V1);
1283 classifier.Perform(S1,PUV,tol1);
1284 if (classifier.State()==TopAbs_IN)
1286 Ext.ParameterOnFace2(i,U2,V2);
1287 PUV.SetCoord(U2,V2);
1288 classifier.Perform(S2,PUV,tol2);
1289 if (classifier.State()==TopAbs_IN)
1291 if (myDstRef > Dstmin)
1293 myModif=Standard_True;
1294 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsInFace,S1,U1,V1);
1295 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsInFace,S2,U2,V2);
1296 SeqSolShape1.Append(Sol1);
1297 SeqSolShape2.Append(Sol2);
1308 /*********************************************************************************/