diff --git a/src/Extrema/Extrema_ExtCS.cxx b/src/Extrema/Extrema_ExtCS.cxx index 1b4e6c6cd8..a1c4d7544c 100644 --- a/src/Extrema/Extrema_ExtCS.cxx +++ b/src/Extrema/Extrema_ExtCS.cxx @@ -38,6 +38,7 @@ #include #include #include +#include Extrema_ExtCS::Extrema_ExtCS() { @@ -218,6 +219,11 @@ void Extrema_ExtCS::Perform(const Adaptor3d_Curve& C, myExtElCS.Perform(C.Circle(), myS->Cylinder()); break; } + else if(myStype == GeomAbs_Plane) + { + myExtElCS.Perform(C.Circle(), myS->Plane()); + break; + } } case GeomAbs_Hyperbola: { @@ -351,6 +357,30 @@ void Extrema_ExtCS::Perform(const Adaptor3d_Curve& C, PS.Parameter(U, V); AddSolution(C, Ucurve, U, V, PC.Value(), PS.Value(), myExtElCS.SquareDistance(i)); } + if(mySqDist.Length() == 0 && NbExt > 0) + { + //Analytical extremas seem to be out of curve/surface boundaries. + //For plane it is possible to add extremity points of curve + if(myStype == GeomAbs_Plane) + { + gp_Pln aPln = myS->Plane(); + gp_Pnt PC, PP; + if(!Precision::IsInfinite(myucinf)) + { + PC = C.Value(myucinf); + ElSLib::PlaneParameters(aPln.Position(), PC, U, V); + PP = ElSLib::PlaneValue(U, V, aPln.Position()); + AddSolution(C, myucinf, U, V, PC, PP, PC.SquareDistance(PP)); + } + if(!Precision::IsInfinite(myucsup)) + { + PC = C.Value(myucsup); + ElSLib::PlaneParameters(aPln.Position(), PC, U, V); + PP = ElSLib::PlaneValue(U, V, aPln.Position()); + AddSolution(C, myucsup, U, V, PC, PP, PC.SquareDistance(PP)); + } + } + } } } diff --git a/src/Extrema/Extrema_ExtElCS.cxx b/src/Extrema/Extrema_ExtElCS.cxx index 96384d0cb3..e0bcd739d5 100644 --- a/src/Extrema/Extrema_ExtElCS.cxx +++ b/src/Extrema/Extrema_ExtElCS.cxx @@ -311,13 +311,90 @@ Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C, -//void Extrema_ExtElCS::Perform(const gp_Circ& C, -// const gp_Pln& S) -void Extrema_ExtElCS::Perform(const gp_Circ& , - const gp_Pln& ) +void Extrema_ExtElCS::Perform(const gp_Circ& C, + const gp_Pln& S) { - Standard_NotImplemented::Raise(); + myDone = Standard_True; + myIsPar = Standard_False; + gp_Ax2 Pos = C.Position(); + gp_Dir NCirc = Pos.Direction(); + gp_Dir NPln = S.Axis().Direction(); + + if (NCirc.IsParallel(NPln, Precision::Angular())) { + + mySqDist = new TColStd_HArray1OfReal(1, 1); + mySqDist->SetValue(1, S.SquareDistance(C.Location())); + myIsPar = Standard_True; + + } + else { + + gp_Dir ExtLine = NCirc ^ NPln; + ExtLine = ExtLine ^ NCirc; + // + gp_Dir XDir = Pos.XDirection(); + Standard_Real T[2]; + T[0] = XDir.AngleWithRef(ExtLine, NCirc); + if(T[0] < 0.) + { + //Put in period + T[0] += M_PI; + } + T[1] = T[0] + M_PI; + // + myNbExt = 2; + //Check intersection + IntAna_IntConicQuad anInter(C, S, + Precision::Angular(), + Precision::Confusion()); + if(anInter.IsDone()) + { + if(anInter.NbPoints() > 1) + { + myNbExt += anInter.NbPoints(); + } + } + + myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt); + mySqDist = new TColStd_HArray1OfReal(1, myNbExt); + myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt); + + Standard_Integer i; + gp_Pnt PC, PP; + Standard_Real U, V; + Extrema_POnCurv POnC; + Extrema_POnSurf POnS; + for(i = 0; i < 2; ++i) + { + PC = ElCLib::CircleValue(T[i], C.Position(), C.Radius()); + POnC.SetValues(T[i], PC); + myPoint1->SetValue(i+1, POnC); + ElSLib::PlaneParameters(S.Position(), PC, U, V); + PP = ElSLib::PlaneValue(U, V, S.Position()); + POnS.SetParameters(U, V, PP); + myPoint2->SetValue(i+1, POnS); + mySqDist->SetValue(i+1, PC.SquareDistance(PP)); + } + // + if(myNbExt > 2) + { + //Add intersection points + for(i = 1; i <= anInter.NbPoints(); ++i) + { + Standard_Real t = anInter.ParamOnConic(i); + PC = ElCLib::CircleValue(t, C.Position(), C.Radius()); + POnC.SetValues(t, PC); + myPoint1->SetValue(i+2, POnC); + ElSLib::PlaneParameters(S.Position(), PC, U, V); + PP = ElSLib::PlaneValue(U, V, S.Position()); + POnS.SetParameters(U, V, PP); + myPoint2->SetValue(i+2, POnS); + mySqDist->SetValue(i+2, PC.SquareDistance(PP)); + } + } + } + // } diff --git a/tests/bugs/moddata_3/bug26038_1 b/tests/bugs/moddata_3/bug26038_1 new file mode 100755 index 0000000000..44e2bcb7d1 --- /dev/null +++ b/tests/bugs/moddata_3/bug26038_1 @@ -0,0 +1,39 @@ +puts "=========" +puts "CR26038" +puts "=========" +puts "" +############################### +## Wrong result done by extrema for the circle and plane +############################### + +restore [locate_data_file bug26038_f.brep] f +restore [locate_data_file bug26038_e.brep] e + +mksurface s f +mkcurve c e + +extrema c s +regexp {The length ext_1 is +([-0-9.+eE]+)} [length ext_1] full ext_1_length +set good_length 1.0e-7 +set tol_abs 1.0e-6 +set tol_rel 1.0e-6 +checkreal "length of ext_1" ${ext_1_length} ${good_length} ${tol_abs} ${tol_rel} + +trim ct c 3.0050016686511065 3.2781836385284797 +extrema ct s +regexp {The length ext_1 is +([-0-9.+eE]+)} [length ext_1] full ext_1_length +set good_length 1.0e-7 +set tol_abs 1.0e-6 +set tol_rel 1.0e-6 +checkreal "length of ext_1" ${ext_1_length} ${good_length} ${tol_abs} ${tol_rel} + +dlog reset +dlog on +xdistcs c s 3.140212946671221 3.142972360508366 10 +set Log [dlog get] + +set List [split ${Log} {TD= \t\n}] +set Tolerance 1.0e-6 +set D_good 0. +set Limit_Tol 1.0e-6 +checkList ${List} ${Tolerance} ${D_good} ${Limit_Tol} diff --git a/tests/bugs/moddata_3/bug26038_2 b/tests/bugs/moddata_3/bug26038_2 new file mode 100755 index 0000000000..f39adbff8a --- /dev/null +++ b/tests/bugs/moddata_3/bug26038_2 @@ -0,0 +1,31 @@ +puts "=========" +puts "CR26038" +puts "=========" +puts "" +############################### +## Wrong result done by extrema for the circle and plane +############################### + +restore [locate_data_file bug26038_f1.brep] f +restore [locate_data_file bug26038_e1.brep] e + +mksurface s f +mkcurve c e + +extrema c s +regexp {The length ext_1 is +([-0-9.+eE]+)} [length ext_1] full ext_1_length +set good_length 1.0e-7 +set tol_abs 1.0e-6 +set tol_rel 1.0e-6 +checkreal "length of ext_1" ${ext_1_length} ${good_length} ${tol_abs} ${tol_rel} + +dlog reset +dlog on +xdistcs c s 1.57079 1.5708 10 +set Log [dlog get] + +set List [split ${Log} {TD= \t\n}] +set Tolerance 1.0e-6 +set D_good 0. +set Limit_Tol 1.0e-6 +checkList ${List} ${Tolerance} ${D_good} ${Limit_Tol}