diff --git a/src/ModelingAlgorithms/TKGeomAlgo/GeomFill/GeomFill_ConstrainedFilling.cxx b/src/ModelingAlgorithms/TKGeomAlgo/GeomFill/GeomFill_ConstrainedFilling.cxx index 1ce159def4..149cdaf548 100644 --- a/src/ModelingAlgorithms/TKGeomAlgo/GeomFill/GeomFill_ConstrainedFilling.cxx +++ b/src/ModelingAlgorithms/TKGeomAlgo/GeomFill/GeomFill_ConstrainedFilling.cxx @@ -1651,12 +1651,20 @@ void GeomFill_ConstrainedFilling::CheckResult(const Standard_Integer I) { pbound[k] = bou->Value(ww); if (!donor) - surf->D0(uu, vv, pres[k]); + { + if (auto aResult = surf->D0(uu, vv)) + pres[k] = *aResult; + } else { vbound[k] = bou->Norm(ww); gp_Vec V1, V2; - surf->D1(uu, vv, pres[k], V1, V2); + if (auto aResult = surf->D1(uu, vv)) + { + pres[k] = aResult->theValue; + V1 = aResult->theD1U; + V2 = aResult->theD1V; + } vres[k] = V1.Crossed(V2); if (vres[k].Magnitude() > 1.e-15 && vbound[k].Magnitude() > 1.e-15) { diff --git a/src/ModelingAlgorithms/TKGeomAlgo/GeomFill/GeomFill_Darboux.cxx b/src/ModelingAlgorithms/TKGeomAlgo/GeomFill/GeomFill_Darboux.cxx index da900ddc7f..c5d59b7ec3 100644 --- a/src/ModelingAlgorithms/TKGeomAlgo/GeomFill/GeomFill_Darboux.cxx +++ b/src/ModelingAlgorithms/TKGeomAlgo/GeomFill/GeomFill_Darboux.cxx @@ -60,13 +60,14 @@ static gp_Vec DDeriv(const gp_Vec& F, const gp_Vec& DF, const gp_Vec& D2F) //======================================================================= // function : NormalD0 // purpose : computes Normal to Surface +// @return Standard_True if calculation is successful, Standard_False otherwise //======================================================================= -static void NormalD0(const Standard_Real U, - const Standard_Real V, - const Handle(Adaptor3d_Surface)& Surf, - gp_Dir& Normal, - Standard_Integer& OrderU, - Standard_Integer& OrderV) +static Standard_Boolean NormalD0(const Standard_Real U, + const Standard_Real V, + const Handle(Adaptor3d_Surface)& Surf, + gp_Dir& Normal, + Standard_Integer& OrderU, + Standard_Integer& OrderV) { // gp_Vec D1U,D1V,D2U,D2V,DUV; gp_Vec D1U, D1V; @@ -75,7 +76,7 @@ static void NormalD0(const Standard_Real U, OrderU = OrderV = 0; #ifdef CHECK if (Cont == GeomAbs_C0) - throw Geom_UndefinedValue(); + return Standard_False; #endif gp_Pnt P; Surf->D1(U, V, P, D1U, D1V); @@ -87,7 +88,7 @@ static void NormalD0(const Standard_Real U, { if (Cont == GeomAbs_C0 || Cont == GeomAbs_C1) { - throw Geom_UndefinedValue(); + return Standard_False; } Standard_Integer MaxOrder = 3; TColgp_Array2OfVec DerNUV(0, MaxOrder, 0, MaxOrder); @@ -140,21 +141,23 @@ static void NormalD0(const Standard_Real U, << DerSurf(i, j).Y() << "," << DerSurf(i, j).Z() << std::endl; } #endif - throw Geom_UndefinedValue(); + return Standard_False; } } + return Standard_True; } //======================================================================= // function : NormalD1 // purpose : computes Normal to Surface and its first derivative +// @return Standard_True if calculation is successful, Standard_False otherwise //======================================================================= -static void NormalD1(const Standard_Real U, - const Standard_Real V, - const Handle(Adaptor3d_Surface)& Surf, - gp_Dir& Normal, - gp_Vec& D1UNormal, - gp_Vec& D1VNormal) +static Standard_Boolean NormalD1(const Standard_Real U, + const Standard_Real V, + const Handle(Adaptor3d_Surface)& Surf, + gp_Dir& Normal, + gp_Vec& D1UNormal, + gp_Vec& D1VNormal) { #ifdef CHECK GeomAbs_Shape Cont = (Surf->Surface().UContinuity() < Surf->Surface().VContinuity()) @@ -220,25 +223,27 @@ static void NormalD1(const Standard_Real U, OrderU, OrderV); if (NStatus != CSLib_Defined) - throw Geom_UndefinedValue(); + return Standard_False; D1UNormal = CSLib::DNNormal(1, 0, DerNUV, OrderU, OrderV); D1VNormal = CSLib::DNNormal(0, 1, DerNUV, OrderU, OrderV); + return Standard_True; } //======================================================================= // function : NormalD2 // purpose : computes Normal to Surface and its first and second derivatives +// @return Standard_True if calculation is successful, Standard_False otherwise //======================================================================= -static void NormalD2(const Standard_Real U, - const Standard_Real V, - const Handle(Adaptor3d_Surface)& Surf, - gp_Dir& Normal, - gp_Vec& D1UNormal, - gp_Vec& D1VNormal, - gp_Vec& D2UNormal, - gp_Vec& D2VNormal, - gp_Vec& D2UVNormal) +static Standard_Boolean NormalD2(const Standard_Real U, + const Standard_Real V, + const Handle(Adaptor3d_Surface)& Surf, + gp_Dir& Normal, + gp_Vec& D1UNormal, + gp_Vec& D1VNormal, + gp_Vec& D2UNormal, + gp_Vec& D2VNormal, + gp_Vec& D2UVNormal) { #ifdef CHECK GeomAbs_Shape Cont = (Surf->Surface().UContinuity() < Surf->Surface().VContinuity()) @@ -309,13 +314,14 @@ static void NormalD2(const Standard_Real U, OrderU, OrderV); if (NStatus != CSLib_Defined) - throw Geom_UndefinedValue(); + return Standard_False; D1UNormal = CSLib::DNNormal(1, 0, DerNUV, OrderU, OrderV); D1VNormal = CSLib::DNNormal(0, 1, DerNUV, OrderU, OrderV); D2UNormal = CSLib::DNNormal(2, 0, DerNUV, OrderU, OrderV); D2VNormal = CSLib::DNNormal(0, 2, DerNUV, OrderU, OrderV); D2UVNormal = CSLib::DNNormal(1, 1, DerNUV, OrderU, OrderV); + return Standard_True; } GeomFill_Darboux::GeomFill_Darboux() {} @@ -346,7 +352,8 @@ Standard_Boolean GeomFill_Darboux::D0(const Standard_Real Param, // Normal = dS_du.Crossed(dS_dv).Normalized(); gp_Dir NormalDir; - NormalD0(C2d.X(), C2d.Y(), mySupport, NormalDir, OrderU, OrderV); + if (!NormalD0(C2d.X(), C2d.Y(), mySupport, NormalDir, OrderU, OrderV)) + return Standard_False; BiNormal.SetXYZ(NormalDir.XYZ()); mySupport->D1(C2d.X(), C2d.Y(), S, dS_du, dS_dv); @@ -393,7 +400,8 @@ Standard_Boolean GeomFill_Darboux::D1(const Standard_Real Param, gp_Dir NormalDir; gp_Vec D1UNormal, D1VNormal; - NormalD1(C2d.X(), C2d.Y(), mySupport, NormalDir, D1UNormal, D1VNormal); + if (!NormalD1(C2d.X(), C2d.Y(), mySupport, NormalDir, D1UNormal, D1VNormal)) + return Standard_False; BiNormal.SetXYZ(NormalDir.XYZ()); DBiNormal = D1UNormal * D2d.X() + D1VNormal * D2d.Y(); @@ -459,15 +467,16 @@ Standard_Boolean GeomFill_Darboux::D2(const Standard_Real Param, gp_Dir NormalDir; gp_Vec D1UNormal, D1VNormal, D2UNormal, D2VNormal, D2UVNormal; - NormalD2(C2d.X(), - C2d.Y(), - mySupport, - NormalDir, - D1UNormal, - D1VNormal, - D2UNormal, - D2VNormal, - D2UVNormal); + if (!NormalD2(C2d.X(), + C2d.Y(), + mySupport, + NormalDir, + D1UNormal, + D1VNormal, + D2UNormal, + D2VNormal, + D2UVNormal)) + return Standard_False; BiNormal.SetXYZ(NormalDir.XYZ()); DBiNormal = D1UNormal * D2d.X() + D1VNormal * D2d.Y(); D2BiNormal = D1UNormal * D2_2d.X() + D1VNormal * D2_2d.Y() + D2UNormal * D2d.X() * D2d.X() @@ -499,24 +508,33 @@ void GeomFill_Darboux::GetAverageLaw(gp_Vec& ATangent, gp_Vec& ANormal, gp_Vec& ATangent = gp_Vec(0, 0, 0); ANormal = gp_Vec(0, 0, 0); ABiNormal = gp_Vec(0, 0, 0); - Standard_Real Step = (myTrimmed->LastParameter() - myTrimmed->FirstParameter()) / Num; - Standard_Real Param; + Standard_Real Step = (myTrimmed->LastParameter() - myTrimmed->FirstParameter()) / Num; + Standard_Real Param; + Standard_Integer aSuccessCount = 0; for (Standard_Integer i = 0; i <= Num; i++) { Param = myTrimmed->FirstParameter() + i * Step; if (Param > myTrimmed->LastParameter()) Param = myTrimmed->LastParameter(); - D0(Param, T, N, BN); - ATangent += T; - ANormal += N; - ABiNormal += BN; + if (D0(Param, T, N, BN)) + { + ATangent += T; + ANormal += N; + ABiNormal += BN; + aSuccessCount++; + } + // Skip samples where calculation failed } - ATangent /= Num + 1; - ANormal /= Num + 1; - ATangent.Normalize(); - ABiNormal = ATangent.Crossed(ANormal).Normalized(); - ANormal = ABiNormal.Crossed(ATangent); + if (aSuccessCount > 0) + { + ATangent /= aSuccessCount; + ANormal /= aSuccessCount; + + ATangent.Normalize(); + ABiNormal = ATangent.Crossed(ANormal).Normalized(); + ANormal = ABiNormal.Crossed(ATangent); + } } Standard_Boolean GeomFill_Darboux::IsConstant() const diff --git a/src/ModelingAlgorithms/TKGeomAlgo/GeomFill/GeomFill_FunctionGuide.cxx b/src/ModelingAlgorithms/TKGeomAlgo/GeomFill/GeomFill_FunctionGuide.cxx index 2cb5bd5798..c5a23a4aaf 100644 --- a/src/ModelingAlgorithms/TKGeomAlgo/GeomFill/GeomFill_FunctionGuide.cxx +++ b/src/ModelingAlgorithms/TKGeomAlgo/GeomFill/GeomFill_FunctionGuide.cxx @@ -141,7 +141,8 @@ Standard_Boolean GeomFill_FunctionGuide::Value(const math_Vector& X, math_Vector gp_Pnt P, P1; TheGuide->D0(X(1), P); - TheSurface->D0(X(2), X(3), P1); + if (auto aResult = TheSurface->D0(X(2), X(3))) + P1 = *aResult; F(1) = P.Coord(1) - P1.Coord(1); F(2) = P.Coord(2) - P1.Coord(2); @@ -160,7 +161,12 @@ Standard_Boolean GeomFill_FunctionGuide::Derivatives(const math_Vector& X, math_ gp_Vec DP, DP1U, DP1V; TheGuide->D1(X(1), P, DP); - TheSurface->D1(X(2), X(3), P1, DP1U, DP1V); + if (auto aResult = TheSurface->D1(X(2), X(3))) + { + P1 = aResult->theValue; + DP1U = aResult->theD1U; + DP1V = aResult->theD1V; + } Standard_Integer i; for (i = 1; i <= 3; i++) @@ -185,7 +191,12 @@ Standard_Boolean GeomFill_FunctionGuide::Values(const math_Vector& X, gp_Vec DP, DP1U, DP1V; TheGuide->D1(X(1), P, DP); // derivee de la generatrice - TheSurface->D1(X(2), X(3), P1, DP1U, DP1V); // derivee de la new surface + if (auto aResult = TheSurface->D1(X(2), X(3))) + { + P1 = aResult->theValue; + DP1U = aResult->theD1U; + DP1V = aResult->theD1V; + } // derivee de la new surface Standard_Integer i; for (i = 1; i <= 3; i++) @@ -311,8 +322,18 @@ void GeomFill_FunctionGuide::DSDT(const Standard_Real U, TheCurve->D1(R(1), P1, DP1); // guide TheCurve->D1(X0(1), P2, DP2); - TheSurface->D1(R(2), R(3), P1, DP1U, DP1V); // surface - TheSurface->D1(X0(2), X0(3), P2, DP2U, DP2V); //derivee de la new surface + if (auto aResult = TheSurface->D1(R(2), R(3))) + { + P1 = aResult->theValue; + DP1U = aResult->theD1U; + DP1V = aResult->theD1V; + } // surface + if (auto aResult = TheSurface->D1(X0(2), X0(3))) + { + P2 = aResult->theValue; + DP2U = aResult->theD1U; + DP2V = aResult->theD1V; + } //derivee de la new surface Standard_Real h = Param0 - Param; @@ -341,7 +362,15 @@ void GeomFill_FunctionGuide::DSDT(const Standard_Real U, gp_Vec D2PU, D2PV, D2PUV; TheCurve->D2(X(1), P1, DP, D2P); - TheSurface->D2(X(2), X(3), P, DPU, DPV, D2PU, D2PV, D2PUV); + if (auto aResult = TheSurface->D2(X(2), X(3))) + { + P = aResult->theValue; + DPU = aResult->theD1U; + DPV = aResult->theD1V; + D2PU = aResult->theD2U; + D2PV = aResult->theD2V; + D2PUV = aResult->theD2UV; + } T.Init(0.); // tenseur diff --git a/src/ModelingAlgorithms/TKGeomAlgo/GeomPlate/GeomPlate_BuildPlateSurface.cxx b/src/ModelingAlgorithms/TKGeomAlgo/GeomPlate/GeomPlate_BuildPlateSurface.cxx index 9c5a67385f..a876a21997 100644 --- a/src/ModelingAlgorithms/TKGeomAlgo/GeomPlate/GeomPlate_BuildPlateSurface.cxx +++ b/src/ModelingAlgorithms/TKGeomAlgo/GeomPlate/GeomPlate_BuildPlateSurface.cxx @@ -763,7 +763,8 @@ void GeomPlate_BuildPlateSurface::EcartContraintesMil(const Standard_Integer else P2d = ProjectPoint(Pi); } - myGeomPlateSurface->D0(P2d.Coord(1), P2d.Coord(2), Pf); + if (auto aResult = myGeomPlateSurface->D0(P2d.Coord(1), P2d.Coord(2))) + Pf = *aResult; an->Init(0); courb->Init(0); d->ChangeValue(i) = Pf.Distance(Pi); @@ -783,7 +784,12 @@ void GeomPlate_BuildPlateSurface::EcartContraintesMil(const Standard_Integer else P2d = ProjectPoint(Pi); } - myGeomPlateSurface->D1(P2d.Coord(1), P2d.Coord(2), Pf, v1f, v2f); + if (auto aResult = myGeomPlateSurface->D1(P2d.Coord(1), P2d.Coord(2))) + { + Pf = aResult->theValue; + v1f = aResult->theD1U; + v2f = aResult->theD1V; + } d->ChangeValue(i) = Pf.Distance(Pi); v3i = v1i ^ v2i; v3f = v1f ^ v2f; @@ -2146,7 +2152,8 @@ void GeomPlate_BuildPlateSurface::Discretise( AC2d.D0(Inter, P2d); LinCont->D0(Inter, P3d); - mySurfInit->D0(P2d.Coord(1), P2d.Coord(2), PP); + if (auto aResult = mySurfInit->D0(P2d.Coord(1), P2d.Coord(2))) + PP = *aResult; Pdif.SetCoord(-PP.Coord(1) + P3d.Coord(1), -PP.Coord(2) + P3d.Coord(2), -PP.Coord(3) + P3d.Coord(3)); @@ -2187,7 +2194,8 @@ void GeomPlate_BuildPlateSurface::Discretise( AC2d.D0(Inter, P2d); LinCont->D0(Inter, P3d); - mySurfInit->D0(P2d.Coord(1), P2d.Coord(2), PP); + if (auto aResult = mySurfInit->D0(P2d.Coord(1), P2d.Coord(2))) + PP = *aResult; Pdif.SetCoord(-PP.Coord(1) + P3d.Coord(1), -PP.Coord(2) + P3d.Coord(2), -PP.Coord(3) + P3d.Coord(3)); @@ -2288,7 +2296,8 @@ void GeomPlate_BuildPlateSurface::LoadCurve(const Standard_Integer NbBoucle, else P2d = ProjectPoint(P3d); } - mySurfInit->D0(P2d.Coord(1), P2d.Coord(2), PP); + if (auto aResult = mySurfInit->D0(P2d.Coord(1), P2d.Coord(2))) + PP = *aResult; Pdif.SetCoord(-PP.Coord(1) + P3d.Coord(1), -PP.Coord(2) + P3d.Coord(2), -PP.Coord(3) + P3d.Coord(3)); @@ -2300,7 +2309,12 @@ void GeomPlate_BuildPlateSurface::LoadCurve(const Standard_Integer NbBoucle, { // ==1 gp_Vec V1, V2, V3, V4; CC->D1(myPlateCont->Value(i).Value(j), PP, V1, V2); - mySurfInit->D1(P2d.Coord(1), P2d.Coord(2), PP, V3, V4); + if (auto aResult = mySurfInit->D1(P2d.Coord(1), P2d.Coord(2))) + { + PP = aResult->theValue; + V3 = aResult->theD1U; + V4 = aResult->theD1V; + } Plate_D1 D1final(V1.XYZ(), V2.XYZ()); Plate_D1 D1init(V3.XYZ(), V4.XYZ()); @@ -2339,7 +2353,15 @@ void GeomPlate_BuildPlateSurface::LoadCurve(const Standard_Integer NbBoucle, { gp_Vec V1, V2, V3, V4, V5, V6, V7, V8, V9, V10; CC->D2(myPlateCont->Value(i).Value(j), PP, V1, V2, V5, V6, V7); - mySurfInit->D2(P2d.Coord(1), P2d.Coord(2), PP, V3, V4, V8, V9, V10); + if (auto aResult = mySurfInit->D2(P2d.Coord(1), P2d.Coord(2))) + { + PP = aResult->theValue; + V3 = aResult->theD1U; + V4 = aResult->theD1V; + V8 = aResult->theD2U; + V9 = aResult->theD2V; + V10 = aResult->theD2UV; + } Plate_D1 D1final(V1.XYZ(), V2.XYZ()); Plate_D1 D1init(V3.XYZ(), V4.XYZ()); @@ -2379,7 +2401,8 @@ void GeomPlate_BuildPlateSurface::LoadPoint(const Standard_Integer, const Standa { myPntCont->Value(i)->D0(P3d); P2d = myPntCont->Value(i)->Pnt2dOnSurf(); - mySurfInit->D0(P2d.Coord(1), P2d.Coord(2), PP); + if (auto aResult = mySurfInit->D0(P2d.Coord(1), P2d.Coord(2))) + PP = *aResult; Pdif.SetCoord(-PP.Coord(1) + P3d.Coord(1), -PP.Coord(2) + P3d.Coord(2), -PP.Coord(3) + P3d.Coord(3)); @@ -2390,7 +2413,12 @@ void GeomPlate_BuildPlateSurface::LoadPoint(const Standard_Integer, const Standa { // ==1 gp_Vec V1, V2, V3, V4; myPntCont->Value(i)->D1(PP, V1, V2); - mySurfInit->D1(P2d.Coord(1), P2d.Coord(2), PP, V3, V4); + if (auto aResult = mySurfInit->D1(P2d.Coord(1), P2d.Coord(2))) + { + PP = aResult->theValue; + V3 = aResult->theD1U; + V4 = aResult->theD1V; + } Plate_D1 D1final(V1.XYZ(), V2.XYZ()); Plate_D1 D1init(V3.XYZ(), V4.XYZ()); if (!myFree) @@ -2410,7 +2438,15 @@ void GeomPlate_BuildPlateSurface::LoadPoint(const Standard_Integer, const Standa gp_Vec V1, V2, V3, V4, V5, V6, V7, V8, V9, V10; myPntCont->Value(i)->D2(PP, V1, V2, V5, V6, V7); // gp_Vec Tv2 = V1^V2; - mySurfInit->D2(P2d.Coord(1), P2d.Coord(2), PP, V3, V4, V8, V9, V10); + if (auto aResult = mySurfInit->D2(P2d.Coord(1), P2d.Coord(2))) + { + PP = aResult->theValue; + V3 = aResult->theD1U; + V4 = aResult->theD1V; + V8 = aResult->theD2U; + V9 = aResult->theD2V; + V10 = aResult->theD2UV; + } Plate_D1 D1final(V1.XYZ(), V2.XYZ()); Plate_D1 D1init(V3.XYZ(), V4.XYZ()); Plate_D2 D2final(V5.XYZ(), V6.XYZ(), V7.XYZ()); @@ -2600,13 +2636,19 @@ void GeomPlate_BuildPlateSurface::VerifPoints(Standard_Real& Dist, case 0: P2d = PntCont->Pnt2dOnSurf(); PntCont->D0(Pi); - myGeomPlateSurface->D0(P2d.Coord(1), P2d.Coord(2), Pf); + if (auto aResult = myGeomPlateSurface->D0(P2d.Coord(1), P2d.Coord(2))) + Pf = *aResult; Dist = Pf.Distance(Pi); break; case 1: PntCont->D1(Pi, v1i, v2i); P2d = PntCont->Pnt2dOnSurf(); - myGeomPlateSurface->D1(P2d.Coord(1), P2d.Coord(2), Pf, v1f, v2f); + if (auto aResult = myGeomPlateSurface->D1(P2d.Coord(1), P2d.Coord(2))) + { + Pf = aResult->theValue; + v1f = aResult->theD1U; + v2f = aResult->theD1V; + } Dist = Pf.Distance(Pi); v3i = v1i ^ v2i; v3f = v1f ^ v2f; diff --git a/src/ModelingAlgorithms/TKGeomAlgo/GeomPlate/GeomPlate_MakeApprox.cxx b/src/ModelingAlgorithms/TKGeomAlgo/GeomPlate/GeomPlate_MakeApprox.cxx index 587cfcf39b..34685c36ad 100644 --- a/src/ModelingAlgorithms/TKGeomAlgo/GeomPlate/GeomPlate_MakeApprox.cxx +++ b/src/ModelingAlgorithms/TKGeomAlgo/GeomPlate/GeomPlate_MakeApprox.cxx @@ -364,17 +364,25 @@ GeomPlate_MakeApprox::GeomPlate_MakeApprox(const Handle(GeomPlate_Surface)& Surf if (CritOrder == 0) { // a l'ordre 0 - myPlate->D0(P2d.X(), P2d.Y(), PP); - gp_XYZ P3d(PP.X(), PP.Y(), PP.Z()); - Seq3d.Append(P3d); + if (auto aResult = myPlate->D0(P2d.X(), P2d.Y())) + { + PP = *aResult; + gp_XYZ P3d(PP.X(), PP.Y(), PP.Z()); + Seq3d.Append(P3d); + } } else { // a l'ordre 1 - myPlate->D1(P2d.X(), P2d.Y(), PP, v1h, v2h); - v3h = v1h ^ v2h; - gp_XYZ P3d(v3h.X(), v3h.Y(), v3h.Z()); - Seq3d.Append(P3d); + if (auto aResult = myPlate->D1(P2d.X(), P2d.Y())) + { + PP = aResult->theValue; + v1h = aResult->theD1U; + v2h = aResult->theD1V; + v3h = v1h ^ v2h; + gp_XYZ P3d(v3h.X(), v3h.Y(), v3h.Z()); + Seq3d.Append(P3d); + } } } } diff --git a/src/ModelingAlgorithms/TKGeomAlgo/GeomPlate/GeomPlate_PointConstraint.cxx b/src/ModelingAlgorithms/TKGeomAlgo/GeomPlate/GeomPlate_PointConstraint.cxx index 2b6114dcd2..ff94158dad 100644 --- a/src/ModelingAlgorithms/TKGeomAlgo/GeomPlate/GeomPlate_PointConstraint.cxx +++ b/src/ModelingAlgorithms/TKGeomAlgo/GeomPlate/GeomPlate_PointConstraint.cxx @@ -66,7 +66,15 @@ GeomPlate_PointConstraint::GeomPlate_PointConstraint(const Standard_Real hasPnt2dOnSurf(Standard_False) { - Surf->D2(myU, myV, myPoint, myD11, myD12, myD21, myD22, myD23); + if (auto aResult = Surf->D2(myU, myV)) + { + myPoint = aResult->theValue; + myD11 = aResult->theD1U; + myD12 = aResult->theD1V; + myD21 = aResult->theD2U; + myD22 = aResult->theD2V; + myD23 = aResult->theD2UV; + } myLProp.SetSurface(Surf); } diff --git a/src/ModelingAlgorithms/TKGeomAlgo/GeomPlate/GeomPlate_Surface.cxx b/src/ModelingAlgorithms/TKGeomAlgo/GeomPlate/GeomPlate_Surface.cxx index bcbab6bfe5..c9462c6320 100644 --- a/src/ModelingAlgorithms/TKGeomAlgo/GeomPlate/GeomPlate_Surface.cxx +++ b/src/ModelingAlgorithms/TKGeomAlgo/GeomPlate/GeomPlate_Surface.cxx @@ -194,100 +194,92 @@ Standard_Boolean GeomPlate_Surface::IsCNv(const Standard_Integer) const //================================================================================================= -void GeomPlate_Surface::D0(const Standard_Real U, const Standard_Real V, gp_Pnt& P) const +std::optional GeomPlate_Surface::D0(const Standard_Real U, const Standard_Real V) const { - gp_XY P1(U, V); - gp_Pnt P2; - mySurfinit->D0(U, V, P2); - gp_XYZ P3; //=mySurfinter.Evaluate(P1); - P3 = mySurfinter.Evaluate(P1); - for (Standard_Integer i = 1; i <= 3; i++) + gp_XY P1(U, V); + if (auto aInitResult = mySurfinit->D0(U, V)) { - P.SetCoord(i, P3.Coord(i) + P2.Coord(i)); + gp_XYZ P3 = mySurfinter.Evaluate(P1); + gp_Pnt P; + for (Standard_Integer i = 1; i <= 3; i++) + { + P.SetCoord(i, P3.Coord(i) + aInitResult->Coord(i)); + } + return P; } + return std::nullopt; } //================================================================================================= -void GeomPlate_Surface::D1(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V) const +std::optional GeomPlate_Surface::D1(const Standard_Real U, + const Standard_Real V) const { - gp_XY P1(U, V); - gp_Pnt P2; - D0(U, V, P); - gp_Vec V1U, V1V; - mySurfinit->D1(U, V, P2, V1U, V1V); - gp_XYZ V2U = mySurfinter.EvaluateDerivative(P1, 1, 0); - gp_XYZ V2V = mySurfinter.EvaluateDerivative(P1, 0, 1); - for (Standard_Integer i = 1; i <= 3; i++) + gp_XY P1(U, V); + if (auto aD0Result = D0(U, V)) { - D1U.SetCoord(i, V1U.Coord(i) + V2U.Coord(i)); - D1V.SetCoord(i, V1V.Coord(i) + V2V.Coord(i)); + if (auto aInitResult = mySurfinit->D1(U, V)) + { + GeomEvaluator_Surface::D1Result aResult; + aResult.theValue = *aD0Result; + gp_XYZ V2U = mySurfinter.EvaluateDerivative(P1, 1, 0); + gp_XYZ V2V = mySurfinter.EvaluateDerivative(P1, 0, 1); + for (Standard_Integer i = 1; i <= 3; i++) + { + aResult.theD1U.SetCoord(i, aInitResult->theD1U.Coord(i) + V2U.Coord(i)); + aResult.theD1V.SetCoord(i, aInitResult->theD1V.Coord(i) + V2V.Coord(i)); + } + return aResult; + } } + return std::nullopt; } //================================================================================================= -void GeomPlate_Surface::D2(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV) const +std::optional GeomPlate_Surface::D2(const Standard_Real U, + const Standard_Real V) const { - gp_XY P1(U, V); - gp_Pnt P2; - - gp_Vec V1U, V1V, V1UV, vv, v; - D1(U, V, P, D1U, D1V); - mySurfinit->D2(U, V, P2, vv, v, V1U, V1V, V1UV); - gp_XYZ V2U = mySurfinter.EvaluateDerivative(P1, 2, 0); - gp_XYZ V2V = mySurfinter.EvaluateDerivative(P1, 0, 2); - gp_XYZ V2UV = mySurfinter.EvaluateDerivative(P1, 1, 1); - for (Standard_Integer i = 1; i <= 3; i++) + gp_XY P1(U, V); + if (auto aD1Result = D1(U, V)) { - D2U.SetCoord(i, V1U.Coord(i) + V2U.Coord(i)); - D2V.SetCoord(i, V1V.Coord(i) + V2V.Coord(i)); - D2UV.SetCoord(i, V1UV.Coord(i) + V2UV.Coord(i)); + if (auto aInitResult = mySurfinit->D2(U, V)) + { + GeomEvaluator_Surface::D2Result aResult; + aResult.theValue = aD1Result->theValue; + aResult.theD1U = aD1Result->theD1U; + aResult.theD1V = aD1Result->theD1V; + gp_XYZ V2U = mySurfinter.EvaluateDerivative(P1, 2, 0); + gp_XYZ V2V = mySurfinter.EvaluateDerivative(P1, 0, 2); + gp_XYZ V2UV = mySurfinter.EvaluateDerivative(P1, 1, 1); + for (Standard_Integer i = 1; i <= 3; i++) + { + aResult.theD2U.SetCoord(i, aInitResult->theD2U.Coord(i) + V2U.Coord(i)); + aResult.theD2V.SetCoord(i, aInitResult->theD2V.Coord(i) + V2V.Coord(i)); + aResult.theD2UV.SetCoord(i, aInitResult->theD2UV.Coord(i) + V2UV.Coord(i)); + } + return aResult; + } } + return std::nullopt; } //================================================================================================= -// void GeomPlate_Surface::D3(const Standard_Real U, const Standard_Real V, gp_Pnt& P, gp_Vec& D1U, -// gp_Vec& D1V, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV, gp_Vec& D3U, gp_Vec& D3V, gp_Vec& D3UUV, -// gp_Vec& D3UVV) const -void GeomPlate_Surface::D3(const Standard_Real, - const Standard_Real, - gp_Pnt&, - gp_Vec&, - gp_Vec&, - gp_Vec&, - gp_Vec&, - gp_Vec&, - gp_Vec&, - gp_Vec&, - gp_Vec&, - gp_Vec&) const +std::optional GeomPlate_Surface::D3(const Standard_Real, + const Standard_Real) const { - throw Standard_Failure("D3"); + return std::nullopt; } //================================================================================================= -// gp_Vec GeomPlate_Surface::DN(const Standard_Real U, const Standard_Real V, const Standard_Integer -// Nu, const Standard_Integer Nv) const -gp_Vec GeomPlate_Surface::DN(const Standard_Real, - const Standard_Real, - const Standard_Integer, - const Standard_Integer) const +std::optional GeomPlate_Surface::DN(const Standard_Real, + const Standard_Real, + const Standard_Integer, + const Standard_Integer) const { - throw Standard_Failure("DN"); + return std::nullopt; } //================================================================================================= diff --git a/src/ModelingAlgorithms/TKGeomAlgo/GeomPlate/GeomPlate_Surface.hxx b/src/ModelingAlgorithms/TKGeomAlgo/GeomPlate/GeomPlate_Surface.hxx index aa97182e63..9c44c1a5e6 100644 --- a/src/ModelingAlgorithms/TKGeomAlgo/GeomPlate/GeomPlate_Surface.hxx +++ b/src/ModelingAlgorithms/TKGeomAlgo/GeomPlate/GeomPlate_Surface.hxx @@ -23,6 +23,7 @@ #include #include #include +#include #include #include class gp_Trsf; @@ -204,46 +205,26 @@ public: //! //! Raised only for an "OffsetSurface" if it is not possible to //! compute the current point. - Standard_EXPORT void D0(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P) const Standard_OVERRIDE; + Standard_EXPORT std::optional D0(const Standard_Real U, + const Standard_Real V) const override; //! Computes the point P and the first derivatives in the //! directions U and V at this point. //! Raised if the continuity of the surface is not C1. - Standard_EXPORT void D1(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V) const Standard_OVERRIDE; + Standard_EXPORT std::optional D1(const Standard_Real U, + const Standard_Real V) const override; //! Computes the point P, the first and the second derivatives in //! the directions U and V at this point. //! Raised if the continuity of the surface is not C2. - Standard_EXPORT void D2(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV) const Standard_OVERRIDE; + Standard_EXPORT std::optional D2(const Standard_Real U, + const Standard_Real V) const override; //! Computes the point P, the first,the second and the third //! derivatives in the directions U and V at this point. //! Raised if the continuity of the surface is not C2. - Standard_EXPORT void D3(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV, - gp_Vec& D3U, - gp_Vec& D3V, - gp_Vec& D3UUV, - gp_Vec& D3UVV) const Standard_OVERRIDE; + Standard_EXPORT std::optional D3(const Standard_Real U, + const Standard_Real V) const override; //! ---Purpose ; //! Computes the derivative of order Nu in the direction U and Nv @@ -252,10 +233,10 @@ public: //! Raised if the continuity of the surface is not CNu in the U //! direction or not CNv in the V direction. //! Raised if Nu + Nv < 1 or Nu < 0 or Nv < 0. - Standard_EXPORT gp_Vec DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const Standard_OVERRIDE; + Standard_EXPORT std::optional DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const override; Standard_EXPORT Handle(Geom_Geometry) Copy() const Standard_OVERRIDE; diff --git a/src/ModelingAlgorithms/TKGeomAlgo/NLPlate/NLPlate_NLPlate.cxx b/src/ModelingAlgorithms/TKGeomAlgo/NLPlate/NLPlate_NLPlate.cxx index 222a65ffef..369deff7f5 100644 --- a/src/ModelingAlgorithms/TKGeomAlgo/NLPlate/NLPlate_NLPlate.cxx +++ b/src/ModelingAlgorithms/TKGeomAlgo/NLPlate/NLPlate_NLPlate.cxx @@ -159,9 +159,15 @@ gp_XYZ NLPlate_NLPlate::EvaluateDerivative(const gp_XY& point2d, { gp_XYZ Value(0., 0., 0.); if ((iu == 0) && (iv == 0)) - Value = myInitialSurface->Value(point2d.X(), point2d.Y()).XYZ(); + { + if (auto aResult = myInitialSurface->D0(point2d.X(), point2d.Y())) + Value = aResult->XYZ(); + } else - Value = myInitialSurface->DN(point2d.X(), point2d.Y(), iu, iv).XYZ(); + { + if (auto aResult = myInitialSurface->DN(point2d.X(), point2d.Y(), iu, iv)) + Value = aResult->XYZ(); + } for (NLPlate_ListIteratorOfStackOfPlate SI(mySOP); SI.More(); SI.Next()) { diff --git a/src/ModelingAlgorithms/TKShHealing/ShapeCustom/ShapeCustom_Surface.cxx b/src/ModelingAlgorithms/TKShHealing/ShapeCustom/ShapeCustom_Surface.cxx index 2b23d96e83..c79b395fd0 100644 --- a/src/ModelingAlgorithms/TKShHealing/ShapeCustom/ShapeCustom_Surface.cxx +++ b/src/ModelingAlgorithms/TKShHealing/ShapeCustom/ShapeCustom_Surface.cxx @@ -337,7 +337,12 @@ Handle(Geom_Surface) ShapeCustom_Surface::ConvertToAnalytical(const Standard_Rea Handle(Geom_ToroidalSurface) anObject = new Geom_ToroidalSurface(aAx3, RR1, RR2); if (j == 2) anObject->UReverse(); - anObject->D1(0., 0., resPnt, resD1U, resD1V); + if (auto aResult = anObject->D1(0., 0.)) + { + resPnt = aResult->theValue; + resD1U = aResult->theD1U; + resD1V = aResult->theD1V; + } #ifdef OCCT_DEBUG if (resD1U.Dot(origD1U) < 0 && j != 2) std::cout << " Tore a inverser !" << std::endl; diff --git a/src/ModelingAlgorithms/TKShHealing/ShapeCustom/ShapeCustom_SweptToElementary.cxx b/src/ModelingAlgorithms/TKShHealing/ShapeCustom/ShapeCustom_SweptToElementary.cxx index 926cf44fbd..06d4dc1dfa 100644 --- a/src/ModelingAlgorithms/TKShHealing/ShapeCustom/ShapeCustom_SweptToElementary.cxx +++ b/src/ModelingAlgorithms/TKShHealing/ShapeCustom/ShapeCustom_SweptToElementary.cxx @@ -244,7 +244,8 @@ Standard_Boolean ShapeCustom_SweptToElementary::NewCurve2d(const TopoDS_Edge& Standard_Real U1, U2, V1, V2; SR->Bounds(U1, U2, V1, V2); gp_Pnt P0; - SR->D0(U1, V1, P0); + if (auto aResult = SR->D0(U1, V1)) + P0 = *aResult; Handle(ShapeAnalysis_Surface) sas = new ShapeAnalysis_Surface(NS); gp_Pnt2d p2d = sas->ValueOfUV(P0, Precision::Confusion()); gp_Vec2d shift(p2d.X() - U1, p2d.Y() - V1); @@ -260,10 +261,12 @@ Standard_Boolean ShapeCustom_SweptToElementary::NewCurve2d(const TopoDS_Edge& Handle(Geom_SphericalSurface) SPH = Handle(Geom_SphericalSurface)::DownCast(NS); Standard_Real US1, US2, VS1, VS2; SPH->Bounds(US1, US2, VS1, VS2); - SPH->D0(US1, VS1, PS); + if (auto aResult = SPH->D0(US1, VS1)) + PS = *aResult; Standard_Real UR1, UR2, VR1, VR2; SR->Bounds(UR1, UR2, VR1, VR2); - SR->D0(UR1, VR1, PR); + if (auto aResult = SR->D0(UR1, VR1)) + PR = *aResult; gp_Pnt P0 = SPH->Location(); gp_Vec VS(P0, PS); gp_Vec VR(P0, PR); diff --git a/src/ModelingAlgorithms/TKShHealing/ShapeExtend/ShapeExtend_CompositeSurface.cxx b/src/ModelingAlgorithms/TKShHealing/ShapeExtend/ShapeExtend_CompositeSurface.cxx index 753bf35e33..82df3c974b 100644 --- a/src/ModelingAlgorithms/TKShHealing/ShapeExtend/ShapeExtend_CompositeSurface.cxx +++ b/src/ModelingAlgorithms/TKShHealing/ShapeExtend/ShapeExtend_CompositeSurface.cxx @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -506,72 +507,53 @@ Standard_Boolean ShapeExtend_CompositeSurface::IsVClosed() const //================================================================================================= -void ShapeExtend_CompositeSurface::D0(const Standard_Real U, const Standard_Real V, gp_Pnt& P) const +std::optional ShapeExtend_CompositeSurface::D0(const Standard_Real U, const Standard_Real V) const { Standard_Integer i = LocateUParameter(U); Standard_Integer j = LocateVParameter(V); gp_Pnt2d uv = GlobalToLocal(i, j, gp_Pnt2d(U, V)); - myPatches->Value(i, j)->D0(uv.X(), uv.Y(), P); + return myPatches->Value(i, j)->D0(uv.X(), uv.Y()); } //================================================================================================= -void ShapeExtend_CompositeSurface::D1(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V) const +std::optional ShapeExtend_CompositeSurface::D1(const Standard_Real U, + const Standard_Real V) const { Standard_Integer i = LocateUParameter(U); Standard_Integer j = LocateVParameter(V); gp_Pnt2d uv = GlobalToLocal(i, j, gp_Pnt2d(U, V)); - myPatches->Value(i, j)->D1(uv.X(), uv.Y(), P, D1U, D1V); + return myPatches->Value(i, j)->D1(uv.X(), uv.Y()); } //================================================================================================= -void ShapeExtend_CompositeSurface::D2(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV) const +std::optional ShapeExtend_CompositeSurface::D2(const Standard_Real U, + const Standard_Real V) const { Standard_Integer i = LocateUParameter(U); Standard_Integer j = LocateVParameter(V); gp_Pnt2d uv = GlobalToLocal(i, j, gp_Pnt2d(U, V)); - myPatches->Value(i, j)->D2(uv.X(), uv.Y(), P, D1U, D1V, D2U, D2V, D2UV); + return myPatches->Value(i, j)->D2(uv.X(), uv.Y()); } //================================================================================================= -void ShapeExtend_CompositeSurface::D3(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV, - gp_Vec& D3U, - gp_Vec& D3V, - gp_Vec& D3UUV, - gp_Vec& D3UVV) const +std::optional ShapeExtend_CompositeSurface::D3(const Standard_Real U, + const Standard_Real V) const { Standard_Integer i = LocateUParameter(U); Standard_Integer j = LocateVParameter(V); gp_Pnt2d uv = GlobalToLocal(i, j, gp_Pnt2d(U, V)); - myPatches->Value(i, j)->D3(uv.X(), uv.Y(), P, D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV); + return myPatches->Value(i, j)->D3(uv.X(), uv.Y()); } //================================================================================================= -gp_Vec ShapeExtend_CompositeSurface::DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const +std::optional ShapeExtend_CompositeSurface::DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const { Standard_Integer i = LocateUParameter(U); Standard_Integer j = LocateVParameter(V); diff --git a/src/ModelingAlgorithms/TKShHealing/ShapeExtend/ShapeExtend_CompositeSurface.hxx b/src/ModelingAlgorithms/TKShHealing/ShapeExtend/ShapeExtend_CompositeSurface.hxx index 064bff9e0f..599b2b5dea 100644 --- a/src/ModelingAlgorithms/TKShHealing/ShapeExtend/ShapeExtend_CompositeSurface.hxx +++ b/src/ModelingAlgorithms/TKShHealing/ShapeExtend/ShapeExtend_CompositeSurface.hxx @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -287,50 +288,30 @@ public: Standard_EXPORT virtual Standard_Boolean IsCNv(const Standard_Integer N) const Standard_OVERRIDE; //! Computes the point of parameter U,V on the grid. - Standard_EXPORT virtual void D0(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P) const Standard_OVERRIDE; + Standard_EXPORT virtual std::optional D0(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; //! Computes the point P and the first derivatives in the //! directions U and V at this point. - Standard_EXPORT virtual void D1(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V) const Standard_OVERRIDE; + Standard_EXPORT virtual std::optional D1(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; //! Computes the point P, the first and the second derivatives in //! the directions U and V at this point. - Standard_EXPORT virtual void D2(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV) const Standard_OVERRIDE; + Standard_EXPORT virtual std::optional D2(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; //! Computes the point P, the first,the second and the third //! derivatives in the directions U and V at this point. - Standard_EXPORT virtual void D3(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV, - gp_Vec& D3U, - gp_Vec& D3V, - gp_Vec& D3UUV, - gp_Vec& D3UVV) const Standard_OVERRIDE; + Standard_EXPORT virtual std::optional D3(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; //! Computes the derivative of order Nu in the direction U and Nv //! in the direction V at the point P(U, V). - Standard_EXPORT virtual gp_Vec DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const Standard_OVERRIDE; + Standard_EXPORT virtual std::optional DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const Standard_OVERRIDE; //! Computes the point of parameter pnt on the grid. Standard_EXPORT gp_Pnt Value(const gp_Pnt2d& pnt) const; diff --git a/src/ModelingData/TKG3d/Geom/Geom_BSplineSurface.hxx b/src/ModelingData/TKG3d/Geom/Geom_BSplineSurface.hxx index d4e7933d5e..aaa2561cb0 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_BSplineSurface.hxx +++ b/src/ModelingData/TKG3d/Geom/Geom_BSplineSurface.hxx @@ -1106,40 +1106,20 @@ public: //! value and derivatives computation Standard_EXPORT const TColStd_Array2OfReal* Weights() const; - Standard_EXPORT void D0(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P) const Standard_OVERRIDE; + Standard_EXPORT std::optional D0(const Standard_Real U, + const Standard_Real V) const override; //! Raised if the continuity of the surface is not C1. - Standard_EXPORT void D1(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V) const Standard_OVERRIDE; + Standard_EXPORT std::optional D1(const Standard_Real U, + const Standard_Real V) const override; //! Raised if the continuity of the surface is not C2. - Standard_EXPORT void D2(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV) const Standard_OVERRIDE; + Standard_EXPORT std::optional D2(const Standard_Real U, + const Standard_Real V) const override; //! Raised if the continuity of the surface is not C3. - Standard_EXPORT void D3(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV, - gp_Vec& D3U, - gp_Vec& D3V, - gp_Vec& D3UUV, - gp_Vec& D3UVV) const Standard_OVERRIDE; + Standard_EXPORT std::optional D3(const Standard_Real U, + const Standard_Real V) const override; //! Nu is the order of derivation in the U parametric direction and //! Nv is the order of derivation in the V parametric direction. @@ -1162,10 +1142,10 @@ public: //! the evaluations are the same as if we consider the whole //! definition of the surface. Of course the evaluations are //! different outside this parametric domain. - Standard_EXPORT gp_Vec DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const Standard_OVERRIDE; + Standard_EXPORT std::optional DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const override; //! Raised if FromUK1 = ToUK2 or FromVK1 = ToVK2. Standard_EXPORT void LocalD0(const Standard_Real U, diff --git a/src/ModelingData/TKG3d/Geom/Geom_BSplineSurface_1.cxx b/src/ModelingData/TKG3d/Geom/Geom_BSplineSurface_1.cxx index ce348a53a3..1c7e3aa9d6 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_BSplineSurface_1.cxx +++ b/src/ModelingData/TKG3d/Geom/Geom_BSplineSurface_1.cxx @@ -113,12 +113,13 @@ Standard_Boolean Geom_BSplineSurface::IsCNv(const Standard_Integer N) const //================================================================================================= -void Geom_BSplineSurface::D0(const Standard_Real U, const Standard_Real V, gp_Pnt& P) const +std::optional Geom_BSplineSurface::D0(const Standard_Real U, const Standard_Real V) const { Standard_Real aNewU = U; Standard_Real aNewV = V; PeriodicNormalization(aNewU, aNewV); + gp_Pnt P; BSplSLib::D0(aNewU, aNewV, 0, @@ -136,15 +137,13 @@ void Geom_BSplineSurface::D0(const Standard_Real U, const Standard_Real V, gp_Pn uperiodic, vperiodic, P); + return P; } //================================================================================================= -void Geom_BSplineSurface::D1(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V) const +std::optional Geom_BSplineSurface::D1(const Standard_Real U, + const Standard_Real V) const { Standard_Real aNewU = U; Standard_Real aNewV = V; @@ -158,6 +157,7 @@ void Geom_BSplineSurface::D1(const Standard_Real U, BSplCLib::LocateParameter(vdeg, vknots->Array1(), &vmults->Array1(), V, vperiodic, vindex, aNewV); vindex = BSplCLib::FlatIndex(vdeg, vindex, vmults->Array1(), vperiodic); + GeomEvaluator_Surface::D1Result aResult; BSplSLib::D1(aNewU, aNewV, uindex, @@ -174,21 +174,16 @@ void Geom_BSplineSurface::D1(const Standard_Real U, vrational, uperiodic, vperiodic, - P, - D1U, - D1V); + aResult.theValue, + aResult.theD1U, + aResult.theD1V); + return aResult; } //================================================================================================= -void Geom_BSplineSurface::D2(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV) const +std::optional Geom_BSplineSurface::D2(const Standard_Real U, + const Standard_Real V) const { Standard_Real aNewU = U; Standard_Real aNewV = V; @@ -202,6 +197,7 @@ void Geom_BSplineSurface::D2(const Standard_Real U, BSplCLib::LocateParameter(vdeg, vknots->Array1(), &vmults->Array1(), V, vperiodic, vindex, aNewV); vindex = BSplCLib::FlatIndex(vdeg, vindex, vmults->Array1(), vperiodic); + GeomEvaluator_Surface::D2Result aResult; BSplSLib::D2(aNewU, aNewV, uindex, @@ -218,33 +214,37 @@ void Geom_BSplineSurface::D2(const Standard_Real U, vrational, uperiodic, vperiodic, - P, - D1U, - D1V, - D2U, - D2V, - D2UV); + aResult.theValue, + aResult.theD1U, + aResult.theD1V, + aResult.theD2U, + aResult.theD2V, + aResult.theD2UV); + return aResult; } //================================================================================================= -void Geom_BSplineSurface::D3(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV, - gp_Vec& D3U, - gp_Vec& D3V, - gp_Vec& D3UUV, - gp_Vec& D3UVV) const +std::optional Geom_BSplineSurface::D3(const Standard_Real U, + const Standard_Real V) const { - BSplSLib::D3(U, - V, - 0, - 0, + Standard_Real aNewU = U; + Standard_Real aNewV = V; + PeriodicNormalization(aNewU, aNewV); + + Standard_Integer uindex = 0, vindex = 0; + + BSplCLib::LocateParameter(udeg, uknots->Array1(), &umults->Array1(), U, uperiodic, uindex, aNewU); + uindex = BSplCLib::FlatIndex(udeg, uindex, umults->Array1(), uperiodic); + + BSplCLib::LocateParameter(vdeg, vknots->Array1(), &vmults->Array1(), V, vperiodic, vindex, aNewV); + vindex = BSplCLib::FlatIndex(vdeg, vindex, vmults->Array1(), vperiodic); + + GeomEvaluator_Surface::D3Result aResult; + BSplSLib::D3(aNewU, + aNewV, + uindex, + vindex, POLES, &WEIGHTS, UFKNOTS, @@ -257,32 +257,50 @@ void Geom_BSplineSurface::D3(const Standard_Real U, vrational, uperiodic, vperiodic, - P, - D1U, - D1V, - D2U, - D2V, - D2UV, - D3U, - D3V, - D3UUV, - D3UVV); + aResult.theValue, + aResult.theD1U, + aResult.theD1V, + aResult.theD2U, + aResult.theD2V, + aResult.theD2UV, + aResult.theD3U, + aResult.theD3V, + aResult.theD3UUV, + aResult.theD3UVV); + return aResult; } //================================================================================================= -gp_Vec Geom_BSplineSurface::DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const +std::optional Geom_BSplineSurface::DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const { + if (Nu + Nv < 1 || Nu < 0 || Nv < 0) + { + return std::nullopt; + } + + Standard_Real aNewU = U; + Standard_Real aNewV = V; + PeriodicNormalization(aNewU, aNewV); + + Standard_Integer uindex = 0, vindex = 0; + + BSplCLib::LocateParameter(udeg, uknots->Array1(), &umults->Array1(), U, uperiodic, uindex, aNewU); + uindex = BSplCLib::FlatIndex(udeg, uindex, umults->Array1(), uperiodic); + + BSplCLib::LocateParameter(vdeg, vknots->Array1(), &vmults->Array1(), V, vperiodic, vindex, aNewV); + vindex = BSplCLib::FlatIndex(vdeg, vindex, vmults->Array1(), vperiodic); + gp_Vec Vn; - BSplSLib::DN(U, - V, + BSplSLib::DN(aNewU, + aNewV, Nu, Nv, - 0, - 0, + uindex, + vindex, POLES, &WEIGHTS, UFKNOTS, @@ -1727,7 +1745,7 @@ void Geom_BSplineSurface::MovePoint(const Standard_Real U, TColgp_Array2OfPnt npoles(1, poles->UpperRow(), 1, poles->UpperCol()); gp_Pnt P0; - D0(U, V, P0); + Geom_Surface::D0(U, V, P0); // Use base class wrapper (name hiding in derived class) gp_Vec Displ(P0, P); Standard_Boolean rational = (urational || vrational); BSplSLib::MovePoint(U, diff --git a/src/ModelingData/TKG3d/Geom/Geom_BezierSurface.cxx b/src/ModelingData/TKG3d/Geom/Geom_BezierSurface.cxx index 077461d3b6..3f52f906cc 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_BezierSurface.cxx +++ b/src/ModelingData/TKG3d/Geom/Geom_BezierSurface.cxx @@ -1389,8 +1389,9 @@ GeomAbs_Shape Geom_BezierSurface::Continuity() const //================================================================================================= -void Geom_BezierSurface::D0(const Standard_Real U, const Standard_Real V, gp_Pnt& P) const +std::optional Geom_BezierSurface::D0(const Standard_Real U, const Standard_Real V) const { + gp_Pnt P; Standard_Real array_u[2] = {0.0, 1.0}; Standard_Real array_v[2] = {0.0, 1.0}; Standard_Integer mult_u[2] = {UDegree() + 1, UDegree() + 1}; @@ -1440,24 +1441,23 @@ void Geom_BezierSurface::D0(const Standard_Real U, const Standard_Real V, gp_Pnt Standard_False, P); } + return P; } //================================================================================================= -void Geom_BezierSurface::D1(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V) const +std::optional Geom_BezierSurface::D1(const Standard_Real U, + const Standard_Real V) const { - Standard_Real array_u[2] = {0.0, 1.0}; - Standard_Real array_v[2] = {0.0, 1.0}; - Standard_Integer mult_u[2] = {UDegree() + 1, UDegree() + 1}; - Standard_Integer mult_v[2] = {VDegree() + 1, VDegree() + 1}; - TColStd_Array1OfReal biduknots(array_u[0], 1, 2); - TColStd_Array1OfInteger bidumults(mult_u[0], 1, 2); - TColStd_Array1OfReal bidvknots(array_v[0], 1, 2); - TColStd_Array1OfInteger bidvmults(mult_v[0], 1, 2); + GeomEvaluator_Surface::D1Result aResult; + Standard_Real array_u[2] = {0.0, 1.0}; + Standard_Real array_v[2] = {0.0, 1.0}; + Standard_Integer mult_u[2] = {UDegree() + 1, UDegree() + 1}; + Standard_Integer mult_v[2] = {VDegree() + 1, VDegree() + 1}; + TColStd_Array1OfReal biduknots(array_u[0], 1, 2); + TColStd_Array1OfInteger bidumults(mult_u[0], 1, 2); + TColStd_Array1OfReal bidvknots(array_v[0], 1, 2); + TColStd_Array1OfInteger bidvmults(mult_v[0], 1, 2); if (urational || vrational) { BSplSLib::D1(U, @@ -1476,9 +1476,9 @@ void Geom_BezierSurface::D1(const Standard_Real U, vrational, Standard_False, Standard_False, - P, - D1U, - D1V); + aResult.theValue, + aResult.theD1U, + aResult.theD1V); } else { @@ -1498,34 +1498,29 @@ void Geom_BezierSurface::D1(const Standard_Real U, vrational, Standard_False, Standard_False, - P, - D1U, - D1V); + aResult.theValue, + aResult.theD1U, + aResult.theD1V); } + return aResult; } //================================================================================================= -void Geom_BezierSurface::D2(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV) const +std::optional Geom_BezierSurface::D2(const Standard_Real U, + const Standard_Real V) const { - Standard_Real array_u[2] = {0.0, 1.0}; - Standard_Real array_v[2] = {0.0, 1.0}; - Standard_Integer mult_u[2] = {UDegree() + 1, UDegree() + 1}; - Standard_Integer mult_v[2] = {VDegree() + 1, VDegree() + 1}; - TColStd_Array1OfReal biduknots(array_u[0], 1, 2); - TColStd_Array1OfInteger bidumults(mult_u[0], 1, 2); - TColStd_Array1OfReal bidvknots(array_v[0], 1, 2); - TColStd_Array1OfInteger bidvmults(mult_v[0], 1, 2); + GeomEvaluator_Surface::D2Result aResult; + Standard_Real array_u[2] = {0.0, 1.0}; + Standard_Real array_v[2] = {0.0, 1.0}; + Standard_Integer mult_u[2] = {UDegree() + 1, UDegree() + 1}; + Standard_Integer mult_v[2] = {VDegree() + 1, VDegree() + 1}; + TColStd_Array1OfReal biduknots(array_u[0], 1, 2); + TColStd_Array1OfInteger bidumults(mult_u[0], 1, 2); + TColStd_Array1OfReal bidvknots(array_v[0], 1, 2); + TColStd_Array1OfInteger bidvmults(mult_v[0], 1, 2); if (urational || vrational) { - //-- ATTENTION a l'ORDRE d'appel ds BSPLSLIB BSplSLib::D2(U, V, 1, @@ -1542,16 +1537,15 @@ void Geom_BezierSurface::D2(const Standard_Real U, vrational, Standard_False, Standard_False, - P, - D1U, - D1V, - D2U, - D2V, - D2UV); + aResult.theValue, + aResult.theD1U, + aResult.theD1V, + aResult.theD2U, + aResult.theD2V, + aResult.theD2UV); } else { - //-- ATTENTION a l'ORDRE d'appel ds BSPLSLIB BSplSLib::D2(U, V, 1, @@ -1568,46 +1562,36 @@ void Geom_BezierSurface::D2(const Standard_Real U, vrational, Standard_False, Standard_False, - P, - D1U, - D1V, - D2U, - D2V, - D2UV); + aResult.theValue, + aResult.theD1U, + aResult.theD1V, + aResult.theD2U, + aResult.theD2V, + aResult.theD2UV); } + return aResult; } //================================================================================================= -void Geom_BezierSurface::D3(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV, - gp_Vec& D3U, - gp_Vec& D3V, - gp_Vec& D3UUV, - gp_Vec& D3UVV) const +std::optional Geom_BezierSurface::D3(const Standard_Real U, + const Standard_Real V) const { - TColStd_Array1OfReal biduknots(1, 2); - biduknots(1) = 0.; - biduknots(2) = 1.; - TColStd_Array1OfInteger bidumults(1, 2); - bidumults.Init(UDegree() + 1); - TColStd_Array1OfReal bidvknots(1, 2); - bidvknots(1) = 0.; - bidvknots(2) = 1.; - TColStd_Array1OfInteger bidvmults(1, 2); - bidvmults.Init(VDegree() + 1); + GeomEvaluator_Surface::D3Result aResult; + Standard_Real array_u[2] = {0.0, 1.0}; + Standard_Real array_v[2] = {0.0, 1.0}; + Standard_Integer mult_u[2] = {UDegree() + 1, UDegree() + 1}; + Standard_Integer mult_v[2] = {VDegree() + 1, VDegree() + 1}; + TColStd_Array1OfReal biduknots(array_u[0], 1, 2); + TColStd_Array1OfInteger bidumults(mult_u[0], 1, 2); + TColStd_Array1OfReal bidvknots(array_v[0], 1, 2); + TColStd_Array1OfInteger bidvmults(mult_v[0], 1, 2); if (urational || vrational) { BSplSLib::D3(U, V, - 0, - 0, + 1, + 1, poles->Array2(), &weights->Array2(), biduknots, @@ -1618,25 +1602,25 @@ void Geom_BezierSurface::D3(const Standard_Real U, VDegree(), urational, vrational, - 0, - 0, - P, - D1U, - D1V, - D2U, - D2V, - D2UV, - D3U, - D3V, - D3UUV, - D3UVV); + Standard_False, + Standard_False, + aResult.theValue, + aResult.theD1U, + aResult.theD1V, + aResult.theD2U, + aResult.theD2V, + aResult.theD2UV, + aResult.theD3U, + aResult.theD3V, + aResult.theD3UUV, + aResult.theD3UVV); } else { BSplSLib::D3(U, V, - 0, - 0, + 1, + 1, poles->Array2(), BSplSLib::NoWeights(), biduknots, @@ -1647,48 +1631,46 @@ void Geom_BezierSurface::D3(const Standard_Real U, VDegree(), urational, vrational, - 0, - 0, - P, - D1U, - D1V, - D2U, - D2V, - D2UV, - D3U, - D3V, - D3UUV, - D3UVV); - } -} - -//================================================================================================= - -gp_Vec Geom_BezierSurface::DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const -{ - Standard_RangeError_Raise_if(Nu + Nv < 1 || Nv < 0 || Nu < 0, " "); - gp_Vec Derivative; - TColStd_Array1OfReal biduknots(1, 2); - biduknots(1) = 0.; - biduknots(2) = 1.; - TColStd_Array1OfInteger bidumults(1, 2); - bidumults.Init(UDegree() + 1); - TColStd_Array1OfReal bidvknots(1, 2); - bidvknots(1) = 0.; - bidvknots(2) = 1.; - TColStd_Array1OfInteger bidvmults(1, 2); - bidvmults.Init(VDegree() + 1); + Standard_False, + Standard_False, + aResult.theValue, + aResult.theD1U, + aResult.theD1V, + aResult.theD2U, + aResult.theD2V, + aResult.theD2UV, + aResult.theD3U, + aResult.theD3V, + aResult.theD3UUV, + aResult.theD3UVV); + } + return aResult; +} + +//================================================================================================= + +std::optional Geom_BezierSurface::DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const +{ + gp_Vec aResult; + Standard_Real array_u[2] = {0.0, 1.0}; + Standard_Real array_v[2] = {0.0, 1.0}; + Standard_Integer mult_u[2] = {UDegree() + 1, UDegree() + 1}; + Standard_Integer mult_v[2] = {VDegree() + 1, VDegree() + 1}; + TColStd_Array1OfReal biduknots(array_u[0], 1, 2); + TColStd_Array1OfInteger bidumults(mult_u[0], 1, 2); + TColStd_Array1OfReal bidvknots(array_v[0], 1, 2); + TColStd_Array1OfInteger bidvmults(mult_v[0], 1, 2); if (urational || vrational) { BSplSLib::DN(U, V, Nu, Nv, - 0, - 0, + 1, + 1, poles->Array2(), &weights->Array2(), biduknots, @@ -1699,9 +1681,9 @@ gp_Vec Geom_BezierSurface::DN(const Standard_Real U, VDegree(), urational, vrational, - 0, - 0, - Derivative); + Standard_False, + Standard_False, + aResult); } else { @@ -1709,8 +1691,8 @@ gp_Vec Geom_BezierSurface::DN(const Standard_Real U, V, Nu, Nv, - 0, - 0, + 1, + 1, poles->Array2(), BSplSLib::NoWeights(), biduknots, @@ -1721,11 +1703,11 @@ gp_Vec Geom_BezierSurface::DN(const Standard_Real U, VDegree(), urational, vrational, - 0, - 0, - Derivative); + Standard_False, + Standard_False, + aResult); } - return Derivative; + return aResult; } //================================================================================================= diff --git a/src/ModelingData/TKG3d/Geom/Geom_BezierSurface.hxx b/src/ModelingData/TKG3d/Geom/Geom_BezierSurface.hxx index 8e14758d11..e4ad54a0fb 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_BezierSurface.hxx +++ b/src/ModelingData/TKG3d/Geom/Geom_BezierSurface.hxx @@ -447,24 +447,14 @@ public: //! continuity is infinite. Standard_EXPORT GeomAbs_Shape Continuity() const Standard_OVERRIDE; - Standard_EXPORT void D0(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P) const Standard_OVERRIDE; - - Standard_EXPORT void D1(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V) const Standard_OVERRIDE; - - Standard_EXPORT void D2(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV) const Standard_OVERRIDE; + Standard_EXPORT std::optional D0(const Standard_Real U, + const Standard_Real V) const override; + + Standard_EXPORT std::optional D1(const Standard_Real U, + const Standard_Real V) const override; + + Standard_EXPORT std::optional D2(const Standard_Real U, + const Standard_Real V) const override; //! Computes P, the point of parameters (U, V) of this Bezier surface, and //! - one or more of the following sets of vectors: @@ -474,18 +464,8 @@ public: //! - D3U, D3V, D3UUV and D3UVV, the third //! derivative vectors at this point. //! Note: The parameters U and V can be outside the bounds of the surface. - Standard_EXPORT void D3(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV, - gp_Vec& D3U, - gp_Vec& D3V, - gp_Vec& D3UUV, - gp_Vec& D3UVV) const Standard_OVERRIDE; + Standard_EXPORT std::optional D3(const Standard_Real U, + const Standard_Real V) const override; //! Computes the derivative of order Nu in the u //! parametric direction, and Nv in the v parametric @@ -494,10 +474,10 @@ public: //! Exceptions //! Standard_RangeError if: //! - Nu + Nv is less than 1, or Nu or Nv is negative. - Standard_EXPORT gp_Vec DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const Standard_OVERRIDE; + Standard_EXPORT std::optional DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const override; //! Returns the number of poles in the U direction. Standard_EXPORT Standard_Integer NbUPoles() const; diff --git a/src/ModelingData/TKG3d/Geom/Geom_ConicalSurface.cxx b/src/ModelingData/TKG3d/Geom/Geom_ConicalSurface.cxx index 6ec6cc6283..b1ba5939ad 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_ConicalSurface.cxx +++ b/src/ModelingData/TKG3d/Geom/Geom_ConicalSurface.cxx @@ -258,63 +258,76 @@ void Geom_ConicalSurface::Coefficients(Standard_Real& A1, //================================================================================================= -void Geom_ConicalSurface::D0(const Standard_Real U, const Standard_Real V, Pnt& P) const +std::optional Geom_ConicalSurface::D0(const Standard_Real U, const Standard_Real V) const { - - P = ElSLib::ConeValue(U, V, pos, radius, semiAngle); + return ElSLib::ConeValue(U, V, pos, radius, semiAngle); } //================================================================================================= -void Geom_ConicalSurface::D1(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V) const +std::optional Geom_ConicalSurface::D1(const Standard_Real U, + const Standard_Real V) const { - ElSLib::ConeD1(U, V, pos, radius, semiAngle, P, D1U, D1V); + GeomEvaluator_Surface::D1Result aResult; + ElSLib::ConeD1(U, V, pos, radius, semiAngle, aResult.theValue, aResult.theD1U, aResult.theD1V); + return aResult; } //================================================================================================= -void Geom_ConicalSurface::D2(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V, - Vec& D2U, - Vec& D2V, - Vec& D2UV) const +std::optional Geom_ConicalSurface::D2(const Standard_Real U, + const Standard_Real V) const { - ElSLib::ConeD2(U, V, pos, radius, semiAngle, P, D1U, D1V, D2U, D2V, D2UV); + GeomEvaluator_Surface::D2Result aResult; + ElSLib::ConeD2(U, + V, + pos, + radius, + semiAngle, + aResult.theValue, + aResult.theD1U, + aResult.theD1V, + aResult.theD2U, + aResult.theD2V, + aResult.theD2UV); + return aResult; } //================================================================================================= -void Geom_ConicalSurface::D3(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V, - Vec& D2U, - Vec& D2V, - Vec& D2UV, - Vec& D3U, - Vec& D3V, - Vec& D3UUV, - Vec& D3UVV) const +std::optional Geom_ConicalSurface::D3(const Standard_Real U, + const Standard_Real V) const { - ElSLib::ConeD3(U, V, pos, radius, semiAngle, P, D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV); + GeomEvaluator_Surface::D3Result aResult; + ElSLib::ConeD3(U, + V, + pos, + radius, + semiAngle, + aResult.theValue, + aResult.theD1U, + aResult.theD1V, + aResult.theD2U, + aResult.theD2V, + aResult.theD2UV, + aResult.theD3U, + aResult.theD3V, + aResult.theD3UUV, + aResult.theD3UVV); + return aResult; } //================================================================================================= -Vec Geom_ConicalSurface::DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const +std::optional Geom_ConicalSurface::DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const { - Standard_RangeError_Raise_if(Nu + Nv < 1 || Nu < 0 || Nv < 0, " "); + if (Nu + Nv < 1 || Nu < 0 || Nv < 0) + { + return std::nullopt; + } if (Nv > 1) { return Vec(0.0, 0.0, 0.0); diff --git a/src/ModelingData/TKG3d/Geom/Geom_ConicalSurface.hxx b/src/ModelingData/TKG3d/Geom/Geom_ConicalSurface.hxx index d30e7f9ad5..35570cc095 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_ConicalSurface.hxx +++ b/src/ModelingData/TKG3d/Geom/Geom_ConicalSurface.hxx @@ -245,60 +245,31 @@ public: Standard_EXPORT Handle(Geom_Curve) VIso(const Standard_Real V) const Standard_OVERRIDE; //! Computes the point P (U, V) on the surface. - //! @code - //! P (U, V) = Loc + - //! (RefRadius + V * sin (Semi-Angle)) * (cos (U) * XDir + sin (U) * YDir) + - //! V * cos (Semi-Angle) * ZDir - //! @endcode - //! where Loc is the origin of the placement plane (XAxis, YAxis) - //! XDir is the direction of the XAxis and YDir the direction of the YAxis. - Standard_EXPORT void D0(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P) const Standard_OVERRIDE; + //! @return Point value if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D0(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; //! Computes the current point and the first derivatives in the directions U and V. - Standard_EXPORT void D1(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V) const Standard_OVERRIDE; + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D1(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; //! Computes the current point, the first and the second derivatives in the directions U and V. - Standard_EXPORT void D2(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV) const Standard_OVERRIDE; - - //! Computes the current point, the first,the second and the third - //! derivatives in the directions U and V. - Standard_EXPORT void D3(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV, - gp_Vec& D3U, - gp_Vec& D3V, - gp_Vec& D3UUV, - gp_Vec& D3UVV) const Standard_OVERRIDE; - - //! Computes the derivative of order Nu in the u - //! parametric direction, and Nv in the v parametric - //! direction at the point of parameters (U, V) of this cone. - //! Exceptions - //! Standard_RangeError if: - //! - Nu + Nv is less than 1, - //! - Nu or Nv is negative. - Standard_EXPORT gp_Vec DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const Standard_OVERRIDE; + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D2(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; + + //! Computes the current point, the first, second and third derivatives in the directions U and V. + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D3(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; + + //! Computes the derivative of order Nu in the u parametric direction, and Nv in the v parametric direction. + //! @return Derivative vector if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const Standard_OVERRIDE; //! Applies the transformation T to this cone. Standard_EXPORT void Transform(const gp_Trsf& T) Standard_OVERRIDE; diff --git a/src/ModelingData/TKG3d/Geom/Geom_CylindricalSurface.cxx b/src/ModelingData/TKG3d/Geom/Geom_CylindricalSurface.cxx index ae241b6c84..524897a689 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_CylindricalSurface.cxx +++ b/src/ModelingData/TKG3d/Geom/Geom_CylindricalSurface.cxx @@ -212,62 +212,76 @@ gp_Cylinder Geom_CylindricalSurface::Cylinder() const //================================================================================================= -void Geom_CylindricalSurface::D0(const Standard_Real U, const Standard_Real V, Pnt& P) const +std::optional Geom_CylindricalSurface::D0(const Standard_Real U, const Standard_Real V) const { + gp_Pnt P; ElSLib::CylinderD0(U, V, pos, radius, P); + return P; } //================================================================================================= -void Geom_CylindricalSurface::D1(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V) const +std::optional Geom_CylindricalSurface::D1(const Standard_Real U, + const Standard_Real V) const { - ElSLib::CylinderD1(U, V, pos, radius, P, D1U, D1V); + GeomEvaluator_Surface::D1Result aResult; + ElSLib::CylinderD1(U, V, pos, radius, aResult.theValue, aResult.theD1U, aResult.theD1V); + return aResult; } //================================================================================================= -void Geom_CylindricalSurface::D2(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V, - Vec& D2U, - Vec& D2V, - Vec& D2UV) const +std::optional Geom_CylindricalSurface::D2(const Standard_Real U, + const Standard_Real V) const { - ElSLib::CylinderD2(U, V, pos, radius, P, D1U, D1V, D2U, D2V, D2UV); + GeomEvaluator_Surface::D2Result aResult; + ElSLib::CylinderD2(U, + V, + pos, + radius, + aResult.theValue, + aResult.theD1U, + aResult.theD1V, + aResult.theD2U, + aResult.theD2V, + aResult.theD2UV); + return aResult; } //================================================================================================= -void Geom_CylindricalSurface::D3(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V, - Vec& D2U, - Vec& D2V, - Vec& D2UV, - Vec& D3U, - Vec& D3V, - Vec& D3UUV, - Vec& D3UVV) const +std::optional Geom_CylindricalSurface::D3(const Standard_Real U, + const Standard_Real V) const { - ElSLib::CylinderD3(U, V, pos, radius, P, D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV); + GeomEvaluator_Surface::D3Result aResult; + ElSLib::CylinderD3(U, + V, + pos, + radius, + aResult.theValue, + aResult.theD1U, + aResult.theD1V, + aResult.theD2U, + aResult.theD2V, + aResult.theD2UV, + aResult.theD3U, + aResult.theD3V, + aResult.theD3UUV, + aResult.theD3UVV); + return aResult; } //================================================================================================= -Vec Geom_CylindricalSurface::DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const +std::optional Geom_CylindricalSurface::DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const { - Standard_RangeError_Raise_if(Nu + Nv < 1 || Nu < 0 || Nv < 0, " "); + if (Nu + Nv < 1 || Nu < 0 || Nv < 0) + { + return std::nullopt; + } if (Nv > 1) { diff --git a/src/ModelingData/TKG3d/Geom/Geom_CylindricalSurface.hxx b/src/ModelingData/TKG3d/Geom/Geom_CylindricalSurface.hxx index c26a1191e5..ce38827d3a 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_CylindricalSurface.hxx +++ b/src/ModelingData/TKG3d/Geom/Geom_CylindricalSurface.hxx @@ -188,57 +188,32 @@ public: //! The center of the circle is on the symmetry axis. Standard_EXPORT Handle(Geom_Curve) VIso(const Standard_Real V) const Standard_OVERRIDE; - //! Computes the point P (U, V) on the surface. - //! P (U, V) = Loc + Radius * (cos (U) * XDir + sin (U) * YDir) + - //! V * ZDir - //! where Loc is the origin of the placement plane (XAxis, YAxis) - //! XDir is the direction of the XAxis and YDir the direction of - //! the YAxis. - Standard_EXPORT void D0(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P) const Standard_OVERRIDE; - - //! Computes the current point and the first derivatives in the - //! directions U and V. - Standard_EXPORT void D1(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V) const Standard_OVERRIDE; - - //! Computes the current point, the first and the second derivatives - //! in the directions U and V. - Standard_EXPORT void D2(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV) const Standard_OVERRIDE; - - //! Computes the current point, the first, the second and the - //! third derivatives in the directions U and V. - Standard_EXPORT void D3(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV, - gp_Vec& D3U, - gp_Vec& D3V, - gp_Vec& D3UUV, - gp_Vec& D3UVV) const Standard_OVERRIDE; - - //! Computes the derivative of order Nu in the direction u and Nv - //! in the direction v. - //! Raised if Nu + Nv < 1 or Nu < 0 or Nv < 0. - Standard_EXPORT gp_Vec DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const Standard_OVERRIDE; + //! Computes the point P (U, V) on the surface. + //! @return Point value if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D0(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; + + //! Computes the current point and the first derivatives in the directions U and V. + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D1(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; + + //! Computes the current point, the first and the second derivatives in the directions U and V. + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D2(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; + + //! Computes the current point, the first, second and third derivatives in the directions U and V. + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D3(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; + + //! Computes the derivative of order Nu in the direction u and Nv in the direction v. + //! @return Derivative vector if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const Standard_OVERRIDE; //! Applies the transformation T to this cylinder. Standard_EXPORT void Transform(const gp_Trsf& T) Standard_OVERRIDE; diff --git a/src/ModelingData/TKG3d/Geom/Geom_OffsetSurface.cxx b/src/ModelingData/TKG3d/Geom/Geom_OffsetSurface.cxx index 873d34c384..54af2e87bc 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_OffsetSurface.cxx +++ b/src/ModelingData/TKG3d/Geom/Geom_OffsetSurface.cxx @@ -314,106 +314,104 @@ GeomAbs_Shape Geom_OffsetSurface::Continuity() const //================================================================================================= -void Geom_OffsetSurface::D0(const Standard_Real U, const Standard_Real V, gp_Pnt& P) const +std::optional Geom_OffsetSurface::D0(const Standard_Real U, const Standard_Real V) const { -#ifdef CHECK - if (myBasisSurfContinuity == GeomAbs_C0) - throw Geom_UndefinedValue(); -#endif if (equivSurf.IsNull()) - myEvaluator->D0(U, V, P); + { + return myEvaluator->D0(U, V); + } else - equivSurf->D0(U, V, P); + { + return equivSurf->D0(U, V); + } } //================================================================================================= -void Geom_OffsetSurface::D1(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V) const +std::optional Geom_OffsetSurface::D1(const Standard_Real U, + const Standard_Real V) const { #ifdef CHECK if (myBasisSurfContinuity == GeomAbs_C0 || myBasisSurfContinuity == GeomAbs_C1) - throw Geom_UndefinedDerivative(); + return std::nullopt; #endif if (equivSurf.IsNull()) - myEvaluator->D1(U, V, P, D1U, D1V); + { + return myEvaluator->D1(U, V); + } else - equivSurf->D1(U, V, P, D1U, D1V); + { + return equivSurf->D1(U, V); + } } //================================================================================================= -void Geom_OffsetSurface::D2(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV) const +std::optional Geom_OffsetSurface::D2(const Standard_Real U, + const Standard_Real V) const { #ifdef CHECK if (myBasisSurfContinuity == GeomAbs_C0 || myBasisSurfContinuity == GeomAbs_C1 || myBasisSurfContinuity == GeomAbs_C2) - throw Geom_UndefinedDerivative(); + return std::nullopt; #endif if (equivSurf.IsNull()) - myEvaluator->D2(U, V, P, D1U, D1V, D2U, D2V, D2UV); + { + return myEvaluator->D2(U, V); + } else - equivSurf->D2(U, V, P, D1U, D1V, D2U, D2V, D2UV); + { + return equivSurf->D2(U, V); + } } //================================================================================================= -void Geom_OffsetSurface::D3(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV, - gp_Vec& D3U, - gp_Vec& D3V, - gp_Vec& D3UUV, - gp_Vec& D3UVV) const +std::optional Geom_OffsetSurface::D3(const Standard_Real U, + const Standard_Real V) const { #ifdef CHECK if (!(basisSurf->IsCNu(4) && basisSurf->IsCNv(4))) { - throw Geom_UndefinedDerivative(); + return std::nullopt; } #endif if (equivSurf.IsNull()) - myEvaluator->D3(U, V, P, D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV); + { + return myEvaluator->D3(U, V); + } else - equivSurf->D3(U, V, P, D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV); + { + return equivSurf->D3(U, V); + } } //================================================================================================= -gp_Vec Geom_OffsetSurface::DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const +std::optional Geom_OffsetSurface::DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const { - Standard_RangeError_Raise_if(Nu < 0 || Nv < 0 || Nu + Nv < 1, " "); + if (Nu < 0 || Nv < 0 || Nu + Nv < 1) + { + return std::nullopt; + } #ifdef CHECK if (!(basisSurf->IsCNu(Nu) && basisSurf->IsCNv(Nv))) { - throw Geom_UndefinedDerivative(); + return std::nullopt; } #endif - gp_Vec D(0, 0, 0); if (equivSurf.IsNull()) - D = myEvaluator->DN(U, V, Nu, Nv); + { + return myEvaluator->DN(U, V, Nu, Nv); + } else - D = equivSurf->DN(U, V, Nu, Nv); - return D; + { + return equivSurf->DN(U, V, Nu, Nv); + } } ////************************************************* diff --git a/src/ModelingData/TKG3d/Geom/Geom_OffsetSurface.hxx b/src/ModelingData/TKG3d/Geom/Geom_OffsetSurface.hxx index ac5060b58f..52ca8f0b34 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_OffsetSurface.hxx +++ b/src/ModelingData/TKG3d/Geom/Geom_OffsetSurface.hxx @@ -252,42 +252,25 @@ public: //! of derivation the exception UndefinedValue is raised. //! //! Raised if the continuity of the basis surface is not C1. - //! Raised if the order of derivation required to compute the - //! normal direction is greater than the second order. - Standard_EXPORT void D0(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P) const Standard_OVERRIDE; - - //! Raised if the continuity of the basis surface is not C2. - Standard_EXPORT void D1(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V) const Standard_OVERRIDE; - - //! Raised if the continuity of the basis surface is not C3. - Standard_EXPORT void D2(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV) const Standard_OVERRIDE; - - //! Raised if the continuity of the basis surface is not C4. - Standard_EXPORT void D3(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV, - gp_Vec& D3U, - gp_Vec& D3V, - gp_Vec& D3UUV, - gp_Vec& D3UVV) const Standard_OVERRIDE; + //! Computes the point of parameter U,V on the surface. + //! @return Point value if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D0(const Standard_Real U, + const Standard_Real V) const override; + + //! Computes the point P and the first derivatives in the directions U and V at this point. + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D1(const Standard_Real U, + const Standard_Real V) const override; + + //! Computes the point P, the first and the second derivatives in the directions U and V at this point. + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D2(const Standard_Real U, + const Standard_Real V) const override; + + //! Computes the point P, the first,the second and the third derivatives in the directions U and V at this point. + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D3(const Standard_Real U, + const Standard_Real V) const override; //! Computes the derivative of order Nu in the direction u and Nv in the direction v. //! @@ -301,13 +284,12 @@ public: //! The computation of the value and derivatives on the basis //! surface are used to evaluate the offset surface. //! - //! Warnings: - //! The exception UndefinedValue or UndefinedDerivative is - //! raised if it is not possible to compute a unique offset direction. - Standard_EXPORT gp_Vec DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const Standard_OVERRIDE; + //! Computes the derivative of order Nu in the direction u and Nv in the direction v. + //! @return Derivative vector if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const override; //! Applies the transformation T to this offset surface. //! Note: the basis surface is also modified. diff --git a/src/ModelingData/TKG3d/Geom/Geom_Plane.cxx b/src/ModelingData/TKG3d/Geom/Geom_Plane.cxx index a17734eaab..b339c89e98 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_Plane.cxx +++ b/src/ModelingData/TKG3d/Geom/Geom_Plane.cxx @@ -204,72 +204,62 @@ void Geom_Plane::Coefficients(Standard_Real& A, //================================================================================================= -void Geom_Plane::D0(const Standard_Real U, const Standard_Real V, Pnt& P) const +std::optional Geom_Plane::D0(const Standard_Real U, const Standard_Real V) const { - - P = ElSLib::PlaneValue(U, V, pos); + return ElSLib::PlaneValue(U, V, pos); } //================================================================================================= -void Geom_Plane::D1(const Standard_Real U, const Standard_Real V, Pnt& P, Vec& D1U, Vec& D1V) const +std::optional Geom_Plane::D1(const Standard_Real U, + const Standard_Real V) const { - - ElSLib::PlaneD1(U, V, pos, P, D1U, D1V); + GeomEvaluator_Surface::D1Result aResult; + ElSLib::PlaneD1(U, V, pos, aResult.theValue, aResult.theD1U, aResult.theD1V); + return aResult; } //================================================================================================= -void Geom_Plane::D2(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V, - Vec& D2U, - Vec& D2V, - Vec& D2UV) const +std::optional Geom_Plane::D2(const Standard_Real U, + const Standard_Real V) const { - - ElSLib::PlaneD1(U, V, pos, P, D1U, D1V); - D2U.SetCoord(0.0, 0.0, 0.0); - D2V.SetCoord(0.0, 0.0, 0.0); - D2UV.SetCoord(0.0, 0.0, 0.0); + GeomEvaluator_Surface::D2Result aResult; + ElSLib::PlaneD1(U, V, pos, aResult.theValue, aResult.theD1U, aResult.theD1V); + aResult.theD2U.SetCoord(0.0, 0.0, 0.0); + aResult.theD2V.SetCoord(0.0, 0.0, 0.0); + aResult.theD2UV.SetCoord(0.0, 0.0, 0.0); + return aResult; } //================================================================================================= -void Geom_Plane::D3(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V, - Vec& D2U, - Vec& D2V, - Vec& D2UV, - Vec& D3U, - Vec& D3V, - Vec& D3UUV, - Vec& D3UVV) const +std::optional Geom_Plane::D3(const Standard_Real U, + const Standard_Real V) const { - ElSLib::PlaneD1(U, V, pos, P, D1U, D1V); - D2U.SetCoord(0.0, 0.0, 0.0); - D2V.SetCoord(0.0, 0.0, 0.0); - D2UV.SetCoord(0.0, 0.0, 0.0); - D3U.SetCoord(0.0, 0.0, 0.0); - D3V.SetCoord(0.0, 0.0, 0.0); - D3UUV.SetCoord(0.0, 0.0, 0.0); - D3UVV.SetCoord(0.0, 0.0, 0.0); + GeomEvaluator_Surface::D3Result aResult; + ElSLib::PlaneD1(U, V, pos, aResult.theValue, aResult.theD1U, aResult.theD1V); + aResult.theD2U.SetCoord(0.0, 0.0, 0.0); + aResult.theD2V.SetCoord(0.0, 0.0, 0.0); + aResult.theD2UV.SetCoord(0.0, 0.0, 0.0); + aResult.theD3U.SetCoord(0.0, 0.0, 0.0); + aResult.theD3V.SetCoord(0.0, 0.0, 0.0); + aResult.theD3UUV.SetCoord(0.0, 0.0, 0.0); + aResult.theD3UVV.SetCoord(0.0, 0.0, 0.0); + return aResult; } //================================================================================================= -Vec Geom_Plane::DN(const Standard_Real, - const Standard_Real, - const Standard_Integer Nu, - const Standard_Integer Nv) const +std::optional Geom_Plane::DN(const Standard_Real, + const Standard_Real, + const Standard_Integer Nu, + const Standard_Integer Nv) const { - - Standard_RangeError_Raise_if(Nu < 0 || Nv < 0 || Nu + Nv < 1, " "); + if (Nu < 0 || Nv < 0 || Nu + Nv < 1) + { + return std::nullopt; + } if (Nu == 0 && Nv == 1) { return Vec(pos.YDirection()); diff --git a/src/ModelingData/TKG3d/Geom/Geom_Plane.hxx b/src/ModelingData/TKG3d/Geom/Geom_Plane.hxx index 96d90fc5dd..241e90ab8f 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_Plane.hxx +++ b/src/ModelingData/TKG3d/Geom/Geom_Plane.hxx @@ -191,55 +191,31 @@ public: Standard_EXPORT Handle(Geom_Curve) VIso(const Standard_Real V) const Standard_OVERRIDE; //! Computes the point P (U, V) on . - //! @code - //! P = O + U * XDir + V * YDir. - //! @endcode - //! where O is the "Location" point of the plane, XDir the - //! "XDirection" and YDir the "YDirection" of the plane's local coordinate system. - Standard_EXPORT void D0(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P) const Standard_OVERRIDE; + //! @return Point value if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D0(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; //! Computes the current point and the first derivatives in the directions U and V. - Standard_EXPORT void D1(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V) const Standard_OVERRIDE; - - //! Computes the current point, the first and the second - //! derivatives in the directions U and V. - Standard_EXPORT void D2(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV) const Standard_OVERRIDE; - - //! Computes the current point, the first,the second and the - //! third derivatives in the directions U and V. - Standard_EXPORT void D3(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV, - gp_Vec& D3U, - gp_Vec& D3V, - gp_Vec& D3UUV, - gp_Vec& D3UVV) const Standard_OVERRIDE; - - //! Computes the derivative of order Nu in the direction u - //! and Nv in the direction v. - //! Raised if Nu + Nv < 1 or Nu < 0 or Nv < 0. - Standard_EXPORT gp_Vec DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const Standard_OVERRIDE; + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D1(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; + + //! Computes the current point, the first and the second derivatives in the directions U and V. + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D2(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; + + //! Computes the current point, the first, second and third derivatives in the directions U and V. + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D3(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; + + //! Computes the derivative of order Nu in the direction u and Nv in the direction v. + //! @return Derivative vector if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const Standard_OVERRIDE; //! Applies the transformation T to this plane. Standard_EXPORT void Transform(const gp_Trsf& T) Standard_OVERRIDE; diff --git a/src/ModelingData/TKG3d/Geom/Geom_RectangularTrimmedSurface.cxx b/src/ModelingData/TKG3d/Geom/Geom_RectangularTrimmedSurface.cxx index ec2e907d01..1e2dd2635d 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_RectangularTrimmedSurface.cxx +++ b/src/ModelingData/TKG3d/Geom/Geom_RectangularTrimmedSurface.cxx @@ -368,66 +368,46 @@ GeomAbs_Shape Geom_RectangularTrimmedSurface::Continuity() const //================================================================================================= -void Geom_RectangularTrimmedSurface::D0(const Standard_Real U, const Standard_Real V, Pnt& P) const +std::optional Geom_RectangularTrimmedSurface::D0(const Standard_Real U, + const Standard_Real V) const { - - basisSurf->D0(U, V, P); + return basisSurf->D0(U, V); } //================================================================================================= -void Geom_RectangularTrimmedSurface::D1(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V) const +std::optional Geom_RectangularTrimmedSurface::D1( + const Standard_Real U, + const Standard_Real V) const { - - basisSurf->D1(U, V, P, D1U, D1V); + return basisSurf->D1(U, V); } //================================================================================================= -void Geom_RectangularTrimmedSurface::D2(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V, - Vec& D2U, - Vec& D2V, - Vec& D2UV) const +std::optional Geom_RectangularTrimmedSurface::D2( + const Standard_Real U, + const Standard_Real V) const { - - basisSurf->D2(U, V, P, D1U, D1V, D2U, D2V, D2UV); + return basisSurf->D2(U, V); } //================================================================================================= -void Geom_RectangularTrimmedSurface::D3(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V, - Vec& D2U, - Vec& D2V, - Vec& D2UV, - Vec& D3U, - Vec& D3V, - Vec& D3UUV, - Vec& D3UVV) const +std::optional Geom_RectangularTrimmedSurface::D3( + const Standard_Real U, + const Standard_Real V) const { - - basisSurf->D3(U, V, P, D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV); + return basisSurf->D3(U, V); } //================================================================================================= -Vec Geom_RectangularTrimmedSurface::DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const +std::optional Geom_RectangularTrimmedSurface::DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const { - return basisSurf->DN(U, V, Nu, Nv); } diff --git a/src/ModelingData/TKG3d/Geom/Geom_RectangularTrimmedSurface.hxx b/src/ModelingData/TKG3d/Geom/Geom_RectangularTrimmedSurface.hxx index dc0df9e518..e913574dab 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_RectangularTrimmedSurface.hxx +++ b/src/ModelingData/TKG3d/Geom/Geom_RectangularTrimmedSurface.hxx @@ -237,49 +237,34 @@ public: Standard_EXPORT Handle(Geom_Curve) VIso(const Standard_Real V) const Standard_OVERRIDE; //! Can be raised if the basis surface is an OffsetSurface. - Standard_EXPORT void D0(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P) const Standard_OVERRIDE; + //! Computes the point of parameter U,V on the surface. + //! @return Point value if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D0(const Standard_Real U, + const Standard_Real V) const override; //! The returned derivatives have the same orientation as the //! derivatives of the basis surface even if the trimmed surface //! has not the same parametric orientation. //! Warning! UndefinedDerivative raised if the continuity of the surface is not C1. - Standard_EXPORT void D1(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V) const Standard_OVERRIDE; + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D1(const Standard_Real U, + const Standard_Real V) const override; //! The returned derivatives have the same orientation as the //! derivatives of the basis surface even if the trimmed surface //! has not the same parametric orientation. //! Warning! UndefinedDerivative raised if the continuity of the surface is not C2. - Standard_EXPORT void D2(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV) const Standard_OVERRIDE; + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D2(const Standard_Real U, + const Standard_Real V) const override; //! The returned derivatives have the same orientation as the //! derivatives of the basis surface even if the trimmed surface //! has not the same parametric orientation. //! Warning UndefinedDerivative raised if the continuity of the surface is not C3. - Standard_EXPORT void D3(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV, - gp_Vec& D3U, - gp_Vec& D3V, - gp_Vec& D3UUV, - gp_Vec& D3UVV) const Standard_OVERRIDE; + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D3(const Standard_Real U, + const Standard_Real V) const override; //! The returned derivative has the same orientation as the //! derivative of the basis surface even if the trimmed surface @@ -287,10 +272,11 @@ public: //! Warning! UndefinedDerivative raised if the continuity of the surface is not CNu in the U //! parametric direction and CNv in the V parametric direction. //! RangeError Raised if Nu + Nv < 1 or Nu < 0 or Nv < 0. - Standard_EXPORT gp_Vec DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const Standard_OVERRIDE; + //! @return Derivative vector if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const override; //! Applies the transformation T to this patch. //! Warning diff --git a/src/ModelingData/TKG3d/Geom/Geom_SphericalSurface.cxx b/src/ModelingData/TKG3d/Geom/Geom_SphericalSurface.cxx index 2fd6abb221..f71139ba1a 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_SphericalSurface.cxx +++ b/src/ModelingData/TKG3d/Geom/Geom_SphericalSurface.cxx @@ -210,63 +210,67 @@ void Geom_SphericalSurface::Coefficients(Standard_Real& A1, //================================================================================================= -void Geom_SphericalSurface::D0(const Standard_Real U, const Standard_Real V, Pnt& P) const +std::optional Geom_SphericalSurface::D0(const Standard_Real U, const Standard_Real V) const { + gp_Pnt P; ElSLib::SphereD0(U, V, pos, radius, P); + return P; } //================================================================================================= -void Geom_SphericalSurface::D1(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V) const +std::optional Geom_SphericalSurface::D1(const Standard_Real U, + const Standard_Real V) const { - ElSLib::SphereD1(U, V, pos, radius, P, D1U, D1V); + GeomEvaluator_Surface::D1Result aResult; + ElSLib::SphereD1(U, V, pos, radius, aResult.theValue, aResult.theD1U, aResult.theD1V); + return aResult; } //================================================================================================= -void Geom_SphericalSurface::D2(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V, - Vec& D2U, - Vec& D2V, - Vec& D2UV) const +std::optional Geom_SphericalSurface::D2(const Standard_Real U, + const Standard_Real V) const { - ElSLib::SphereD2(U, V, pos, radius, P, D1U, D1V, D2U, D2V, D2UV); + GeomEvaluator_Surface::D2Result aResult; + ElSLib::SphereD2(U, V, pos, radius, aResult.theValue, aResult.theD1U, aResult.theD1V, aResult.theD2U, aResult.theD2V, aResult.theD2UV); + return aResult; } //================================================================================================= -void Geom_SphericalSurface::D3(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V, - Vec& D2U, - Vec& D2V, - Vec& D2UV, - Vec& D3U, - Vec& D3V, - Vec& D3UUV, - Vec& D3UVV) const +std::optional Geom_SphericalSurface::D3(const Standard_Real U, + const Standard_Real V) const { - ElSLib::SphereD3(U, V, pos, radius, P, D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV); + GeomEvaluator_Surface::D3Result aResult; + ElSLib::SphereD3(U, + V, + pos, + radius, + aResult.theValue, + aResult.theD1U, + aResult.theD1V, + aResult.theD2U, + aResult.theD2V, + aResult.theD2UV, + aResult.theD3U, + aResult.theD3V, + aResult.theD3UUV, + aResult.theD3UVV); + return aResult; } //================================================================================================= -Vec Geom_SphericalSurface::DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const +std::optional Geom_SphericalSurface::DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const { - - Standard_RangeError_Raise_if(Nu + Nv < 1 || Nu < 0 || Nv < 0, " "); + if (Nu + Nv < 1 || Nu < 0 || Nv < 0) + { + return std::nullopt; + } return ElSLib::SphereDN(U, V, pos, radius, Nu, Nv); } diff --git a/src/ModelingData/TKG3d/Geom/Geom_SphericalSurface.hxx b/src/ModelingData/TKG3d/Geom/Geom_SphericalSurface.hxx index f2360e1df4..b5bd132ad3 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_SphericalSurface.hxx +++ b/src/ModelingData/TKG3d/Geom/Geom_SphericalSurface.hxx @@ -188,57 +188,32 @@ public: //! Warnings : The radius of this circle can be zero. Standard_EXPORT Handle(Geom_Curve) VIso(const Standard_Real V) const Standard_OVERRIDE; - //! Computes the point P (U, V) on the surface. - //! P (U, V) = Loc + Radius * Sin (V) * Zdir + - //! Radius * Cos (V) * (cos (U) * XDir + sin (U) * YDir) - //! where Loc is the origin of the placement plane (XAxis, YAxis) - //! XDir is the direction of the XAxis and YDir the direction of - //! the YAxis and ZDir the direction of the ZAxis. - Standard_EXPORT void D0(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P) const Standard_OVERRIDE; - - //! Computes the current point and the first derivatives in the - //! directions U and V. - Standard_EXPORT void D1(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V) const Standard_OVERRIDE; - - //! Computes the current point, the first and the second derivatives - //! in the directions U and V. - Standard_EXPORT void D2(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV) const Standard_OVERRIDE; - - //! Computes the current point, the first,the second and the third - //! derivatives in the directions U and V. - Standard_EXPORT void D3(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV, - gp_Vec& D3U, - gp_Vec& D3V, - gp_Vec& D3UUV, - gp_Vec& D3UVV) const Standard_OVERRIDE; - - //! Computes the derivative of order Nu in the direction u - //! and Nv in the direction v. - //! Raised if Nu + Nv < 1 or Nu < 0 or Nv < 0. - Standard_EXPORT gp_Vec DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const Standard_OVERRIDE; + //! Computes the point P (U, V) on the surface. + //! @return Point value if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D0(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; + + //! Computes the current point and the first derivatives in the directions U and V. + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D1(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; + + //! Computes the current point, the first and the second derivatives in the directions U and V. + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D2(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; + + //! Computes the current point, the first, second and third derivatives in the directions U and V. + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D3(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; + + //! Computes the derivative of order Nu in the direction u and Nv in the direction v. + //! @return Derivative vector if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const Standard_OVERRIDE; //! Applies the transformation T to this sphere. Standard_EXPORT void Transform(const gp_Trsf& T) Standard_OVERRIDE; diff --git a/src/ModelingData/TKG3d/Geom/Geom_Surface.cxx b/src/ModelingData/TKG3d/Geom/Geom_Surface.cxx index c5c1224a0d..0611440ee5 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_Surface.cxx +++ b/src/ModelingData/TKG3d/Geom/Geom_Surface.cxx @@ -82,6 +82,100 @@ Standard_Real Geom_Surface::VPeriod() const //================================================================================================= +void Geom_Surface::D0(const Standard_Real U, const Standard_Real V, gp_Pnt& P) const +{ + if (auto aResult = D0(U, V)) + { + P = *aResult; + } + else + { + throw Geom_UndefinedValue("Geom_Surface::D0 - computation failed"); + } +} + +//================================================================================================= + +void Geom_Surface::D1(const Standard_Real U, + const Standard_Real V, + gp_Pnt& P, + gp_Vec& D1U, + gp_Vec& D1V) const +{ + if (auto aResult = D1(U, V)) + { + P = aResult->theValue; + D1U = aResult->theD1U; + D1V = aResult->theD1V; + } + else + { + throw Geom_UndefinedValue("Geom_Surface::D1 - computation failed"); + } +} + +//================================================================================================= + +void Geom_Surface::D2(const Standard_Real U, + const Standard_Real V, + gp_Pnt& P, + gp_Vec& D1U, + gp_Vec& D1V, + gp_Vec& D2U, + gp_Vec& D2V, + gp_Vec& D2UV) const +{ + if (auto aResult = D2(U, V)) + { + P = aResult->theValue; + D1U = aResult->theD1U; + D1V = aResult->theD1V; + D2U = aResult->theD2U; + D2V = aResult->theD2V; + D2UV = aResult->theD2UV; + } + else + { + throw Geom_UndefinedValue("Geom_Surface::D2 - computation failed"); + } +} + +//================================================================================================= + +void Geom_Surface::D3(const Standard_Real U, + const Standard_Real V, + gp_Pnt& P, + gp_Vec& D1U, + gp_Vec& D1V, + gp_Vec& D2U, + gp_Vec& D2V, + gp_Vec& D2UV, + gp_Vec& D3U, + gp_Vec& D3V, + gp_Vec& D3UUV, + gp_Vec& D3UVV) const +{ + if (auto aResult = D3(U, V)) + { + P = aResult->theValue; + D1U = aResult->theD1U; + D1V = aResult->theD1V; + D2U = aResult->theD2U; + D2V = aResult->theD2V; + D2UV = aResult->theD2UV; + D3U = aResult->theD3U; + D3V = aResult->theD3V; + D3UUV = aResult->theD3UUV; + D3UVV = aResult->theD3UVV; + } + else + { + throw Geom_UndefinedValue("Geom_Surface::D3 - computation failed"); + } +} + +//================================================================================================= + gp_Pnt Geom_Surface::Value(const Standard_Real U, const Standard_Real V) const { gp_Pnt P; diff --git a/src/ModelingData/TKG3d/Geom/Geom_Surface.hxx b/src/ModelingData/TKG3d/Geom/Geom_Surface.hxx index 00c11243d9..db95c243ca 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_Surface.hxx +++ b/src/ModelingData/TKG3d/Geom/Geom_Surface.hxx @@ -18,6 +18,8 @@ #define _Geom_Surface_HeaderFile #include +#include +#include class gp_Trsf; class gp_GTrsf2d; @@ -214,60 +216,92 @@ public: Standard_EXPORT virtual Standard_Boolean IsCNv(const Standard_Integer N) const = 0; //! Computes the point of parameter U,V on the surface. - //! - //! Raised only for an "OffsetSurface" if it is not possible to - //! compute the current point. - Standard_EXPORT virtual void D0(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P) const = 0; + //! @return Point value if calculation succeeds, std::nullopt otherwise + Standard_EXPORT virtual std::optional D0(const Standard_Real U, + const Standard_Real V) const = 0; + + //! @deprecated Use D0() returning std::optional instead + //! Computes the point of parameter U,V on the surface. + //! Raised only for an "OffsetSurface" if it is not possible to compute the current point. + Standard_DEPRECATED("Use D0() returning std::optional instead") + Standard_EXPORT void D0(const Standard_Real U, + const Standard_Real V, + gp_Pnt& P) const; //! Computes the point P and the first derivatives in the directions U and V at this point. //! Raised if the continuity of the surface is not C1. //! //! Tip: use GeomLib::NormEstim() to calculate surface normal at specified (U, V) point. - Standard_EXPORT virtual void D1(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V) const = 0; + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT virtual std::optional D1(const Standard_Real U, + const Standard_Real V) const = 0; + + //! @deprecated Use D1() returning std::optional instead + //! Computes the point P and the first derivatives in the directions U and V at this point. + //! Raised if the continuity of the surface is not C1. + Standard_DEPRECATED("Use D1() returning std::optional instead") + Standard_EXPORT void D1(const Standard_Real U, + const Standard_Real V, + gp_Pnt& P, + gp_Vec& D1U, + gp_Vec& D1V) const; //! Computes the point P, the first and the second derivatives in //! the directions U and V at this point. //! Raised if the continuity of the surface is not C2. - Standard_EXPORT virtual void D2(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV) const = 0; + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT virtual std::optional D2(const Standard_Real U, + const Standard_Real V) const = 0; + + //! @deprecated Use D2() returning std::optional instead + //! Computes the point P, the first and the second derivatives in + //! the directions U and V at this point. + //! Raised if the continuity of the surface is not C2. + Standard_DEPRECATED("Use D2() returning std::optional instead") + Standard_EXPORT void D2(const Standard_Real U, + const Standard_Real V, + gp_Pnt& P, + gp_Vec& D1U, + gp_Vec& D1V, + gp_Vec& D2U, + gp_Vec& D2V, + gp_Vec& D2UV) const; + + //! Computes the point P, the first,the second and the third + //! derivatives in the directions U and V at this point. + //! Raised if the continuity of the surface is not C2. + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT virtual std::optional D3(const Standard_Real U, + const Standard_Real V) const = 0; + //! @deprecated Use D3() returning std::optional instead //! Computes the point P, the first,the second and the third //! derivatives in the directions U and V at this point. //! Raised if the continuity of the surface is not C2. - Standard_EXPORT virtual void D3(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV, - gp_Vec& D3U, - gp_Vec& D3V, - gp_Vec& D3UUV, - gp_Vec& D3UVV) const = 0; + Standard_DEPRECATED("Use D3() returning std::optional instead") + Standard_EXPORT void D3(const Standard_Real U, + const Standard_Real V, + gp_Pnt& P, + gp_Vec& D1U, + gp_Vec& D1V, + gp_Vec& D2U, + gp_Vec& D2V, + gp_Vec& D2UV, + gp_Vec& D3U, + gp_Vec& D3V, + gp_Vec& D3UUV, + gp_Vec& D3UVV) const; //! Computes the derivative of order Nu in the direction U and Nv in the direction V at the point //! P(U, V). //! //! Raised if the continuity of the surface is not CNu in the U direction or not CNv in the V //! direction. Raised if Nu + Nv < 1 or Nu < 0 or Nv < 0. - Standard_EXPORT virtual gp_Vec DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const = 0; + //! @return Derivative vector if calculation succeeds, std::nullopt otherwise + Standard_EXPORT virtual std::optional DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const = 0; //! Computes the point of parameter (U, V) on the surface. //! diff --git a/src/ModelingData/TKG3d/Geom/Geom_SurfaceOfLinearExtrusion.cxx b/src/ModelingData/TKG3d/Geom/Geom_SurfaceOfLinearExtrusion.cxx index e37a19ff36..a2a4d469f2 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_SurfaceOfLinearExtrusion.cxx +++ b/src/ModelingData/TKG3d/Geom/Geom_SurfaceOfLinearExtrusion.cxx @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -142,60 +143,41 @@ void Geom_SurfaceOfLinearExtrusion::Bounds(Standard_Real& U1, //================================================================================================= -void Geom_SurfaceOfLinearExtrusion::D0(const Standard_Real U, const Standard_Real V, Pnt& P) const +std::optional Geom_SurfaceOfLinearExtrusion::D0(const Standard_Real U, const Standard_Real V) const { - myEvaluator->D0(U, V, P); + return myEvaluator->D0(U, V); } //================================================================================================= -void Geom_SurfaceOfLinearExtrusion::D1(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V) const +std::optional Geom_SurfaceOfLinearExtrusion::D1(const Standard_Real U, + const Standard_Real V) const { - myEvaluator->D1(U, V, P, D1U, D1V); + return myEvaluator->D1(U, V); } //================================================================================================= -void Geom_SurfaceOfLinearExtrusion::D2(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V, - Vec& D2U, - Vec& D2V, - Vec& D2UV) const +std::optional Geom_SurfaceOfLinearExtrusion::D2(const Standard_Real U, + const Standard_Real V) const { - myEvaluator->D2(U, V, P, D1U, D1V, D2U, D2V, D2UV); + return myEvaluator->D2(U, V); } //================================================================================================= -void Geom_SurfaceOfLinearExtrusion::D3(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V, - Vec& D2U, - Vec& D2V, - Vec& D2UV, - Vec& D3U, - Vec& D3V, - Vec& D3UUV, - Vec& D3UVV) const +std::optional Geom_SurfaceOfLinearExtrusion::D3(const Standard_Real U, + const Standard_Real V) const { - myEvaluator->D3(U, V, P, D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV); + return myEvaluator->D3(U, V); } //================================================================================================= -Vec Geom_SurfaceOfLinearExtrusion::DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const +std::optional Geom_SurfaceOfLinearExtrusion::DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const { return myEvaluator->DN(U, V, Nu, Nv); } diff --git a/src/ModelingData/TKG3d/Geom/Geom_SurfaceOfLinearExtrusion.hxx b/src/ModelingData/TKG3d/Geom/Geom_SurfaceOfLinearExtrusion.hxx index 2dd005bd3f..8a8086eac2 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_SurfaceOfLinearExtrusion.hxx +++ b/src/ModelingData/TKG3d/Geom/Geom_SurfaceOfLinearExtrusion.hxx @@ -167,62 +167,41 @@ public: //! extrusion, with the magnitude V. Standard_EXPORT Handle(Geom_Curve) VIso(const Standard_Real V) const Standard_OVERRIDE; - //! Computes the point P (U, V) on the surface. + //! Computes the point P (U, V) on the surface. //! The parameter U is the parameter on the extruded curve. //! The parametrization V is a linear parametrization, and //! the direction of parametrization is the direction of //! extrusion. If the point is on the extruded curve, V = 0.0 - Standard_EXPORT void D0(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P) const Standard_OVERRIDE; + //! @return Point value if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D0(const Standard_Real U, + const Standard_Real V) const override; - //! Computes the current point and the first derivatives in the - //! directions U and V. + //! Computes the point P and the first derivatives in the directions U and V at this point. //! Raises UndefinedDerivative if the continuity of the surface is not C1. - Standard_EXPORT void D1(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V) const Standard_OVERRIDE; - - //! --- Purpose ; - //! Computes the current point, the first and the second derivatives - //! in the directions U and V. + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D1(const Standard_Real U, + const Standard_Real V) const override; + + //! Computes the point P, the first and the second derivatives in the directions U and V at this point. //! Raises UndefinedDerivative if the continuity of the surface is not C2. - Standard_EXPORT void D2(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV) const Standard_OVERRIDE; - - //! Computes the current point, the first,the second and the third - //! derivatives in the directions U and V. + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D2(const Standard_Real U, + const Standard_Real V) const override; + + //! Computes the point P, the first,the second and the third derivatives in the directions U and V at this point. //! Raises UndefinedDerivative if the continuity of the surface is not C3. - Standard_EXPORT void D3(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV, - gp_Vec& D3U, - gp_Vec& D3V, - gp_Vec& D3UUV, - gp_Vec& D3UVV) const Standard_OVERRIDE; - - //! Computes the derivative of order Nu in the direction u - //! and Nv in the direction v. - //! Raises UndefinedDerivative if the continuity of the surface is not CNu in the u - //! direction and CNv in the v direction. + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D3(const Standard_Real U, + const Standard_Real V) const override; + + //! Computes the derivative of order Nu in the direction U and Nv in the direction V at the point P(U, V). + //! Raises UndefinedDerivative if the continuity of the surface is not CNu in the u direction and CNv in the v direction. //! Raises RangeError if Nu + Nv < 1 or Nu < 0 or Nv < 0. - Standard_EXPORT gp_Vec DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const Standard_OVERRIDE; + //! @return Derivative vector if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const override; //! Applies the transformation T to this surface of linear extrusion. Standard_EXPORT void Transform(const gp_Trsf& T) Standard_OVERRIDE; diff --git a/src/ModelingData/TKG3d/Geom/Geom_SurfaceOfRevolution.cxx b/src/ModelingData/TKG3d/Geom/Geom_SurfaceOfRevolution.cxx index 02b09a0832..0698eb4d98 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_SurfaceOfRevolution.cxx +++ b/src/ModelingData/TKG3d/Geom/Geom_SurfaceOfRevolution.cxx @@ -229,60 +229,41 @@ void Geom_SurfaceOfRevolution::Bounds(Standard_Real& U1, //================================================================================================= -void Geom_SurfaceOfRevolution::D0(const Standard_Real U, const Standard_Real V, Pnt& P) const +std::optional Geom_SurfaceOfRevolution::D0(const Standard_Real U, const Standard_Real V) const { - myEvaluator->D0(U, V, P); + return myEvaluator->D0(U, V); } //================================================================================================= -void Geom_SurfaceOfRevolution::D1(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V) const +std::optional Geom_SurfaceOfRevolution::D1(const Standard_Real U, + const Standard_Real V) const { - myEvaluator->D1(U, V, P, D1U, D1V); + return myEvaluator->D1(U, V); } //================================================================================================= -void Geom_SurfaceOfRevolution::D2(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V, - Vec& D2U, - Vec& D2V, - Vec& D2UV) const +std::optional Geom_SurfaceOfRevolution::D2(const Standard_Real U, + const Standard_Real V) const { - myEvaluator->D2(U, V, P, D1U, D1V, D2U, D2V, D2UV); + return myEvaluator->D2(U, V); } //================================================================================================= -void Geom_SurfaceOfRevolution::D3(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V, - Vec& D2U, - Vec& D2V, - Vec& D2UV, - Vec& D3U, - Vec& D3V, - Vec& D3UUV, - Vec& D3UVV) const +std::optional Geom_SurfaceOfRevolution::D3(const Standard_Real U, + const Standard_Real V) const { - myEvaluator->D3(U, V, P, D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV); + return myEvaluator->D3(U, V); } //================================================================================================= -Vec Geom_SurfaceOfRevolution::DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const +std::optional Geom_SurfaceOfRevolution::DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const { return myEvaluator->DN(U, V, Nu, Nv); } diff --git a/src/ModelingData/TKG3d/Geom/Geom_SurfaceOfRevolution.hxx b/src/ModelingData/TKG3d/Geom/Geom_SurfaceOfRevolution.hxx index ed89142a69..79dd39a50f 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_SurfaceOfRevolution.hxx +++ b/src/ModelingData/TKG3d/Geom/Geom_SurfaceOfRevolution.hxx @@ -253,68 +253,40 @@ public: //! meridian through an angle U about the axis of revolution. Standard_EXPORT Handle(Geom_Curve) VIso(const Standard_Real V) const Standard_OVERRIDE; - //! Computes the point P (U, V) on the surface. + //! Computes the point of parameter U,V on the surface. //! U is the angle of the rotation around the revolution axis. //! The direction of this axis gives the sense of rotation. //! V is the parameter of the revolved curve. - Standard_EXPORT void D0(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P) const Standard_OVERRIDE; + //! @return Point value if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D0(const Standard_Real U, + const Standard_Real V) const override; - //! Computes the current point and the first derivatives - //! in the directions U and V. + //! Computes the point P and the first derivatives in the directions U and V at this point. //! Raised if the continuity of the surface is not C1. - Standard_EXPORT void D1(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V) const Standard_OVERRIDE; - - //! Computes the current point, the first and the second derivatives - //! in the directions U and V. + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D1(const Standard_Real U, + const Standard_Real V) const override; + + //! Computes the point P, the first and the second derivatives in the directions U and V at this point. //! Raised if the continuity of the surface is not C2. - Standard_EXPORT void D2(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV) const Standard_OVERRIDE; - - //! Computes the current point, the first,the second and the third - //! derivatives in the directions U and V. + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D2(const Standard_Real U, + const Standard_Real V) const override; + + //! Computes the point P, the first,the second and the third derivatives in the directions U and V at this point. //! Raised if the continuity of the surface is not C3. - Standard_EXPORT void D3(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV, - gp_Vec& D3U, - gp_Vec& D3V, - gp_Vec& D3UUV, - gp_Vec& D3UVV) const Standard_OVERRIDE; - - //! Computes the derivative of order Nu in the direction u and - //! Nv in the direction v. - //! - //! Raised if the continuity of the surface is not CNu in the u - //! direction and CNv in the v direction. + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D3(const Standard_Real U, + const Standard_Real V) const override; + + //! Computes the derivative of order Nu in the direction U and Nv in the direction V at the point P(U, V). + //! Raised if the continuity of the surface is not CNu in the u direction and CNv in the v direction. //! Raised if Nu + Nv < 1 or Nu < 0 or Nv < 0. - //! The following functions evaluates the local derivatives - //! on surface. Useful to manage discontinuities on the surface. - //! if Side = 1 -> P = S( U+,V ) - //! if Side = -1 -> P = S( U-,V ) - //! else P is betveen discontinuities - //! can be evaluated using methods of - //! global evaluations P = S( U ,V ) - Standard_EXPORT gp_Vec DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const Standard_OVERRIDE; + //! @return Derivative vector if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const override; //! Applies the transformation T to this surface of revolution. Standard_EXPORT void Transform(const gp_Trsf& T) Standard_OVERRIDE; diff --git a/src/ModelingData/TKG3d/Geom/Geom_ToroidalSurface.cxx b/src/ModelingData/TKG3d/Geom/Geom_ToroidalSurface.cxx index d1816be7a9..23da10caca 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_ToroidalSurface.cxx +++ b/src/ModelingData/TKG3d/Geom/Geom_ToroidalSurface.cxx @@ -214,79 +214,68 @@ void Geom_ToroidalSurface::Coefficients(Array1OfReal& Coef) const //================================================================================================= -void Geom_ToroidalSurface::D0(const Standard_Real U, const Standard_Real V, Pnt& P) const +std::optional Geom_ToroidalSurface::D0(const Standard_Real U, const Standard_Real V) const { - + gp_Pnt P; ElSLib::TorusD0(U, V, pos, majorRadius, minorRadius, P); + return P; } //================================================================================================= -void Geom_ToroidalSurface::D1(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V) const +std::optional Geom_ToroidalSurface::D1(const Standard_Real U, + const Standard_Real V) const { - ElSLib::TorusD1(U, V, pos, majorRadius, minorRadius, P, D1U, D1V); + GeomEvaluator_Surface::D1Result aResult; + ElSLib::TorusD1(U, V, pos, majorRadius, minorRadius, aResult.theValue, aResult.theD1U, aResult.theD1V); + return aResult; } //================================================================================================= -void Geom_ToroidalSurface::D2(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V, - Vec& D2U, - Vec& D2V, - Vec& D2UV) const +std::optional Geom_ToroidalSurface::D2(const Standard_Real U, + const Standard_Real V) const { - ElSLib::TorusD2(U, V, pos, majorRadius, minorRadius, P, D1U, D1V, D2U, D2V, D2UV); + GeomEvaluator_Surface::D2Result aResult; + ElSLib::TorusD2(U, V, pos, majorRadius, minorRadius, aResult.theValue, aResult.theD1U, aResult.theD1V, aResult.theD2U, aResult.theD2V, aResult.theD2UV); + return aResult; } //================================================================================================= -void Geom_ToroidalSurface::D3(const Standard_Real U, - const Standard_Real V, - Pnt& P, - Vec& D1U, - Vec& D1V, - Vec& D2U, - Vec& D2V, - Vec& D2UV, - Vec& D3U, - Vec& D3V, - Vec& D3UUV, - Vec& D3UVV) const +std::optional Geom_ToroidalSurface::D3(const Standard_Real U, + const Standard_Real V) const { - + GeomEvaluator_Surface::D3Result aResult; ElSLib::TorusD3(U, V, pos, majorRadius, minorRadius, - P, - D1U, - D1V, - D2U, - D2V, - D2UV, - D3U, - D3V, - D3UUV, - D3UVV); + aResult.theValue, + aResult.theD1U, + aResult.theD1V, + aResult.theD2U, + aResult.theD2V, + aResult.theD2UV, + aResult.theD3U, + aResult.theD3V, + aResult.theD3UUV, + aResult.theD3UVV); + return aResult; } //================================================================================================= -Vec Geom_ToroidalSurface::DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const +std::optional Geom_ToroidalSurface::DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const { - - Standard_RangeError_Raise_if(Nu + Nv < 1 || Nu < 0 || Nv < 0, " "); + if (Nu + Nv < 1 || Nu < 0 || Nv < 0) + { + return std::nullopt; + } return ElSLib::TorusDN(U, V, pos, majorRadius, minorRadius, Nu, Nv); } diff --git a/src/ModelingData/TKG3d/Geom/Geom_ToroidalSurface.hxx b/src/ModelingData/TKG3d/Geom/Geom_ToroidalSurface.hxx index 7c8e0ccd28..4eb7f1c943 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_ToroidalSurface.hxx +++ b/src/ModelingData/TKG3d/Geom/Geom_ToroidalSurface.hxx @@ -208,51 +208,33 @@ public: //! where Loc is the origin of the placement plane (XAxis, YAxis) //! XDir is the direction of the XAxis and YDir the direction of //! the YAxis and ZDir the direction of the ZAxis. - Standard_EXPORT void D0(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P) const Standard_OVERRIDE; - - //! Computes the current point and the first derivatives in - //! the directions U and V. - Standard_EXPORT void D1(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V) const Standard_OVERRIDE; - - //! Computes the current point, the first and the second derivatives - //! in the directions U and V. - Standard_EXPORT void D2(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV) const Standard_OVERRIDE; - - //! Computes the current point, the first,the second and the - //! third derivatives in the directions U and V. - Standard_EXPORT void D3(const Standard_Real U, - const Standard_Real V, - gp_Pnt& P, - gp_Vec& D1U, - gp_Vec& D1V, - gp_Vec& D2U, - gp_Vec& D2V, - gp_Vec& D2UV, - gp_Vec& D3U, - gp_Vec& D3V, - gp_Vec& D3UUV, - gp_Vec& D3UVV) const Standard_OVERRIDE; - - //! Computes the derivative of order Nu in the direction u and - //! Nv in the direction v. - //! Raised if Nu + Nv < 1 or Nu < 0 or Nv < 0. - Standard_EXPORT gp_Vec DN(const Standard_Real U, - const Standard_Real V, - const Standard_Integer Nu, - const Standard_Integer Nv) const Standard_OVERRIDE; + + //! Computes the point P (U, V) on the surface. + //! @return Point value if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D0(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; + + //! Computes the current point and the first derivatives in the directions U and V. + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D1(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; + + //! Computes the current point, the first and the second derivatives in the directions U and V. + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D2(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; + + //! Computes the current point, the first, second and third derivatives in the directions U and V. + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D3(const Standard_Real U, + const Standard_Real V) const Standard_OVERRIDE; + + //! Computes the derivative of order Nu in the direction u and Nv in the direction v. + //! @return Derivative vector if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional DN(const Standard_Real U, + const Standard_Real V, + const Standard_Integer Nu, + const Standard_Integer Nv) const Standard_OVERRIDE; //! Applies the transformation T to this torus. Standard_EXPORT void Transform(const gp_Trsf& T) Standard_OVERRIDE; diff --git a/src/ModelingData/TKG3d/Geom/Geom_UndefinedValue.hxx b/src/ModelingData/TKG3d/Geom/Geom_UndefinedValue.hxx index 4477c94d0a..f8e9a908b6 100644 --- a/src/ModelingData/TKG3d/Geom/Geom_UndefinedValue.hxx +++ b/src/ModelingData/TKG3d/Geom/Geom_UndefinedValue.hxx @@ -22,10 +22,14 @@ #include #include -class Geom_UndefinedValue; +//! @deprecated This exception class is deprecated and should not be used in new code. +//! Use boolean return values or output parameters to signal errors instead. +class Standard_DEPRECATED("Use boolean return values or output parameters instead of throwing exceptions") + Geom_UndefinedValue; DEFINE_STANDARD_HANDLE(Geom_UndefinedValue, Standard_DomainError) #if !defined No_Exception && !defined No_Geom_UndefinedValue + //! @deprecated This macro is deprecated. Use boolean return values instead. #define Geom_UndefinedValue_Raise_if(CONDITION, MESSAGE) \ if (CONDITION) \ throw Geom_UndefinedValue(MESSAGE); diff --git a/src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_Surface.cxx b/src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_Surface.cxx index 7dba6c900b..796fb49c83 100644 --- a/src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_Surface.cxx +++ b/src/ModelingData/TKG3d/GeomAdaptor/GeomAdaptor_Surface.cxx @@ -748,7 +748,10 @@ void GeomAdaptor_Surface::D0(const Standard_Real U, const Standard_Real V, gp_Pn case GeomAbs_SurfaceOfRevolution: Standard_NoSuchObject_Raise_if(myNestedEvaluator.IsNull(), "GeomAdaptor_Surface::D0: evaluator is not initialized"); - myNestedEvaluator->D0(U, V, P); + if (auto aResult = myNestedEvaluator->D0(U, V)) + P = *aResult; + else + throw Standard_Failure("myNestedEvaluator->D0 failed"); break; default: @@ -808,7 +811,14 @@ void GeomAdaptor_Surface::D1(const Standard_Real U, case GeomAbs_OffsetSurface: Standard_NoSuchObject_Raise_if(myNestedEvaluator.IsNull(), "GeomAdaptor_Surface::D1: evaluator is not initialized"); - myNestedEvaluator->D1(u, v, P, D1U, D1V); + if (auto aResult = myNestedEvaluator->D1(u, v)) + { + P = aResult->theValue; + D1U = aResult->theD1U; + D1V = aResult->theD1V; + } + else + throw Standard_Failure("myNestedEvaluator->D1 failed"); break; default: @@ -871,7 +881,17 @@ void GeomAdaptor_Surface::D2(const Standard_Real U, case GeomAbs_OffsetSurface: Standard_NoSuchObject_Raise_if(myNestedEvaluator.IsNull(), "GeomAdaptor_Surface::D2: evaluator is not initialized"); - myNestedEvaluator->D2(u, v, P, D1U, D1V, D2U, D2V, D2UV); + if (auto aResult = myNestedEvaluator->D2(u, v)) + { + P = aResult->theValue; + D1U = aResult->theD1U; + D1V = aResult->theD1V; + D2U = aResult->theD2U; + D2V = aResult->theD2V; + D2UV = aResult->theD2UV; + } + else + throw Standard_Failure("myNestedEvaluator->D2 failed"); break; default: { @@ -923,7 +943,21 @@ void GeomAdaptor_Surface::D3(const Standard_Real U, { case GeomAbs_BSplineSurface: { if ((USide == 0) && (VSide == 0)) - myBSplineSurface->D3(u, v, P, D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV); + if (auto aResult = myBSplineSurface->D3(u, v)) + { + P = aResult->theValue; + D1U = aResult->theD1U; + D1V = aResult->theD1V; + D2U = aResult->theD2U; + D2V = aResult->theD2V; + D2UV = aResult->theD2UV; + D3U = aResult->theD3U; + D3V = aResult->theD3V; + D3UUV = aResult->theD3UUV; + D3UVV = aResult->theD3UVV; + } + else + throw Standard_Failure("myBSplineSurface->D3 failed"); else { if (IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide)) @@ -944,7 +978,21 @@ void GeomAdaptor_Surface::D3(const Standard_Real U, D3UUV, D3UVV); else - myBSplineSurface->D3(u, v, P, D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV); + if (auto aResult = myBSplineSurface->D3(u, v)) + { + P = aResult->theValue; + D1U = aResult->theD1U; + D1V = aResult->theD1V; + D2U = aResult->theD2U; + D2V = aResult->theD2V; + D2UV = aResult->theD2UV; + D3U = aResult->theD3U; + D3V = aResult->theD3V; + D3UUV = aResult->theD3UUV; + D3UVV = aResult->theD3UVV; + } + else + throw Standard_Failure("myBSplineSurface->D3 failed"); } break; } @@ -954,7 +1002,21 @@ void GeomAdaptor_Surface::D3(const Standard_Real U, case GeomAbs_OffsetSurface: Standard_NoSuchObject_Raise_if(myNestedEvaluator.IsNull(), "GeomAdaptor_Surface::D3: evaluator is not initialized"); - myNestedEvaluator->D3(u, v, P, D1U, D1V, D2U, D2V, D2UV, D3U, D3V, D3UUV, D3UVV); + if (auto aResult = myNestedEvaluator->D3(u, v)) + { + P = aResult->theValue; + D1U = aResult->theD1U; + D1V = aResult->theD1V; + D2U = aResult->theD2U; + D2V = aResult->theD2V; + D2UV = aResult->theD2UV; + D3U = aResult->theD3U; + D3V = aResult->theD3V; + D3UUV = aResult->theD3UUV; + D3UVV = aResult->theD3UVV; + } + else + throw Standard_Failure("myNestedEvaluator->D3 failed"); break; default: { @@ -998,13 +1060,19 @@ gp_Vec GeomAdaptor_Surface::DN(const Standard_Real U, { case GeomAbs_BSplineSurface: { if ((USide == 0) && (VSide == 0)) - return myBSplineSurface->DN(u, v, Nu, Nv); + if (auto aResult = myBSplineSurface->DN(u, v, Nu, Nv)) + return *aResult; + else + throw Standard_Failure("myBSplineSurface->DN failed"); else { if (IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide)) return myBSplineSurface->LocalDN(u, v, Ideb, Ifin, IVdeb, IVfin, Nu, Nv); else - return myBSplineSurface->DN(u, v, Nu, Nv); + if (auto aResult = myBSplineSurface->DN(u, v, Nu, Nv)) + return *aResult; + else + throw Standard_Failure("myBSplineSurface->DN failed"); } } @@ -1013,7 +1081,10 @@ gp_Vec GeomAdaptor_Surface::DN(const Standard_Real U, case GeomAbs_OffsetSurface: Standard_NoSuchObject_Raise_if(myNestedEvaluator.IsNull(), "GeomAdaptor_Surface::DN: evaluator is not initialized"); - return myNestedEvaluator->DN(u, v, Nu, Nv); + if (auto aResult = myNestedEvaluator->DN(u, v, Nu, Nv)) + return *aResult; + else + throw Standard_Failure("myNestedEvaluator->DN failed"); case GeomAbs_Plane: case GeomAbs_Cylinder: @@ -1026,7 +1097,10 @@ gp_Vec GeomAdaptor_Surface::DN(const Standard_Real U, break; } - return mySurface->DN(u, v, Nu, Nv); + if (auto aResult = mySurface->DN(u, v, Nu, Nv)) + return *aResult; + else + throw Standard_Failure("mySurface->DN failed"); } //================================================================================================= diff --git a/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_OffsetSurface.cxx b/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_OffsetSurface.cxx index 0e5e7f56b1..49006335a2 100644 --- a/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_OffsetSurface.cxx +++ b/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_OffsetSurface.cxx @@ -32,6 +32,23 @@ namespace // tolerance for considering derivative to be null const Standard_Real the_D1MagTol = 1.e-9; +// Helper function to unwrap DN() results that may be std::optional or gp_Vec +template +gp_Vec unwrapDN(const T& theResult) +{ + if constexpr (std::is_same_v>) + { + if (theResult) + return *theResult; + else + throw Standard_Failure("DN computation failed"); + } + else + { + return theResult; + } +} + // If calculation of normal fails, try shifting the point towards the center // of the parametric space of the surface, in the hope that derivatives // are better defined there. @@ -128,12 +145,29 @@ static void derivatives(Standard_Integer theMaxOrder, switch (theMinOrder) { case 1: - theL->D1(theU, theV, P, DL1U, DL1V); + if (auto aD1 = theL->D1(theU, theV)) + { + P = aD1->theValue; + DL1U = aD1->theD1U; + DL1V = aD1->theD1V; + } + else + throw Standard_Failure("theL->D1 failed"); DerSurfL.SetValue(1, 0, DL1U); DerSurfL.SetValue(0, 1, DL1V); break; case 2: - theL->D2(theU, theV, P, DL1U, DL1V, DL2U, DL2V, DL2UV); + if (auto aD2 = theL->D2(theU, theV)) + { + P = aD2->theValue; + DL1U = aD2->theD1U; + DL1V = aD2->theD1V; + DL2U = aD2->theD2U; + DL2V = aD2->theD2V; + DL2UV = aD2->theD2UV; + } + else + throw Standard_Failure("theL->D2 failed"); DerSurfL.SetValue(1, 0, DL1U); DerSurfL.SetValue(0, 1, DL1V); DerSurfL.SetValue(1, 1, DL2UV); @@ -141,7 +175,21 @@ static void derivatives(Standard_Integer theMaxOrder, DerSurfL.SetValue(0, 2, DL2V); break; case 3: - theL->D3(theU, theV, P, DL1U, DL1V, DL2U, DL2V, DL2UV, DL3U, DL3V, DL3UUV, DL3UVV); + if (auto aD3 = theL->D3(theU, theV)) + { + P = aD3->theValue; + DL1U = aD3->theD1U; + DL1V = aD3->theD1V; + DL2U = aD3->theD2U; + DL2V = aD3->theD2V; + DL2UV = aD3->theD2UV; + DL3U = aD3->theD3U; + DL3V = aD3->theD3V; + DL3UUV = aD3->theD3UUV; + DL3UVV = aD3->theD3UVV; + } + else + throw Standard_Failure("theL->D3 failed"); DerSurfL.SetValue(1, 0, DL1U); DerSurfL.SetValue(0, 1, DL1V); DerSurfL.SetValue(1, 1, DL2UV); @@ -162,12 +210,12 @@ static void derivatives(Standard_Integer theMaxOrder, for (j = i; j <= theMaxOrder + theNV + 1; j++) if (i + j > theMinOrder) { - DerSurfL.SetValue(i, j, theL->DN(theU, theV, i, j)); - theDerSurf.SetValue(i, j, theBasisSurf->DN(theU, theV, i, j)); + DerSurfL.SetValue(i, j, unwrapDN(theL->DN(theU, theV, i, j))); + theDerSurf.SetValue(i, j, unwrapDN(theBasisSurf->DN(theU, theV, i, j))); if (i != j && j <= theNU + 1) { - theDerSurf.SetValue(j, i, theBasisSurf->DN(theU, theV, j, i)); - DerSurfL.SetValue(j, i, theL->DN(theU, theV, j, i)); + theDerSurf.SetValue(j, i, unwrapDN(theBasisSurf->DN(theU, theV, j, i))); + DerSurfL.SetValue(j, i, unwrapDN(theL->DN(theU, theV, j, i))); } } } @@ -177,12 +225,12 @@ static void derivatives(Standard_Integer theMaxOrder, for (i = j; i <= theMaxOrder + theNU + 1; i++) if (i + j > theMinOrder) { - DerSurfL.SetValue(i, j, theL->DN(theU, theV, i, j)); - theDerSurf.SetValue(i, j, theBasisSurf->DN(theU, theV, i, j)); + DerSurfL.SetValue(i, j, unwrapDN(theL->DN(theU, theV, i, j))); + theDerSurf.SetValue(i, j, unwrapDN(theBasisSurf->DN(theU, theV, i, j))); if (i != j && i <= theNV + 1) { - theDerSurf.SetValue(j, i, theBasisSurf->DN(theU, theV, j, i)); - DerSurfL.SetValue(j, i, theL->DN(theU, theV, j, i)); + theDerSurf.SetValue(j, i, unwrapDN(theBasisSurf->DN(theU, theV, j, i))); + DerSurfL.SetValue(j, i, unwrapDN(theL->DN(theU, theV, j, i))); } } } @@ -203,10 +251,10 @@ static void derivatives(Standard_Integer theMaxOrder, { if (i + j > theMinOrder) { - theDerSurf.SetValue(i, j, theBasisSurf->DN(theU, theV, i, j)); + theDerSurf.SetValue(i, j, unwrapDN(theBasisSurf->DN(theU, theV, i, j))); if (i != j && j <= theDerSurf.UpperRow() && i <= theDerSurf.UpperCol()) { - theDerSurf.SetValue(j, i, theBasisSurf->DN(theU, theV, j, i)); + theDerSurf.SetValue(j, i, unwrapDN(theBasisSurf->DN(theU, theV, j, i))); } } } @@ -262,170 +310,154 @@ GeomEvaluator_OffsetSurface::GeomEvaluator_OffsetSurface( { } -void GeomEvaluator_OffsetSurface::D0(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue) const +std::optional GeomEvaluator_OffsetSurface::D0(const Standard_Real theU, + const Standard_Real theV) const { Standard_Real aU = theU, aV = theV; for (;;) { + gp_Pnt aValue; gp_Vec aD1U, aD1V; - BaseD1(aU, aV, theValue, aD1U, aD1V); + BaseD1(aU, aV, aValue, aD1U, aD1V); CheckInfinite(aD1U, aD1V); - try + if (auto aResult = CalculateD0(aU, aV, aValue, aD1U, aD1V)) { - CalculateD0(aU, aV, theValue, aD1U, aD1V); - break; + return aResult; } - catch (Geom_UndefinedValue&) + else { // if failed at parametric boundary, try taking derivative at shifted point if (!shiftPoint(theU, theV, aU, aV, myBaseSurf, myBaseAdaptor, aD1U, aD1V)) { - throw; + return std::nullopt; } } } } -void GeomEvaluator_OffsetSurface::D1(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V) const +std::optional GeomEvaluator_OffsetSurface::D1( + const Standard_Real theU, + const Standard_Real theV) const { Standard_Real aU = theU, aV = theV; for (;;) { - gp_Vec aD2U, aD2V, aD2UV; - BaseD2(aU, aV, theValue, theD1U, theD1V, aD2U, aD2V, aD2UV); + gp_Pnt aValue; + gp_Vec aD1U, aD1V, aD2U, aD2V, aD2UV; + BaseD2(aU, aV, aValue, aD1U, aD1V, aD2U, aD2V, aD2UV); - CheckInfinite(theD1U, theD1V); + CheckInfinite(aD1U, aD1V); - try + if (auto aResult = CalculateD1(aU, aV, aValue, aD1U, aD1V, aD2U, aD2V, aD2UV)) { - CalculateD1(aU, aV, theValue, theD1U, theD1V, aD2U, aD2V, aD2UV); - break; + return aResult; } - catch (Geom_UndefinedValue&) + else { // if failed at parametric boundary, try taking derivative at shifted point - if (!shiftPoint(theU, theV, aU, aV, myBaseSurf, myBaseAdaptor, theD1U, theD1V)) + if (!shiftPoint(theU, theV, aU, aV, myBaseSurf, myBaseAdaptor, aD1U, aD1V)) { - throw; + return std::nullopt; } } } } -void GeomEvaluator_OffsetSurface::D2(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V, - gp_Vec& theD2U, - gp_Vec& theD2V, - gp_Vec& theD2UV) const +std::optional GeomEvaluator_OffsetSurface::D2( + const Standard_Real theU, + const Standard_Real theV) const { Standard_Real aU = theU, aV = theV; for (;;) { - gp_Vec aD3U, aD3V, aD3UUV, aD3UVV; - BaseD3(aU, aV, theValue, theD1U, theD1V, theD2U, theD2V, theD2UV, aD3U, aD3V, aD3UUV, aD3UVV); + gp_Pnt aValue; + gp_Vec aD1U, aD1V, aD2U, aD2V, aD2UV, aD3U, aD3V, aD3UUV, aD3UVV; + BaseD3(aU, aV, aValue, aD1U, aD1V, aD2U, aD2V, aD2UV, aD3U, aD3V, aD3UUV, aD3UVV); - CheckInfinite(theD1U, theD1V); + CheckInfinite(aD1U, aD1V); - try + if (auto aResult = CalculateD2(aU, + aV, + aValue, + aD1U, + aD1V, + aD2U, + aD2V, + aD2UV, + aD3U, + aD3V, + aD3UUV, + aD3UVV)) { - CalculateD2(aU, - aV, - theValue, - theD1U, - theD1V, - theD2U, - theD2V, - theD2UV, - aD3U, - aD3V, - aD3UUV, - aD3UVV); - break; + return aResult; } - catch (Geom_UndefinedValue&) + else { // if failed at parametric boundary, try taking derivative at shifted point - if (!shiftPoint(theU, theV, aU, aV, myBaseSurf, myBaseAdaptor, theD1U, theD1V)) + if (!shiftPoint(theU, theV, aU, aV, myBaseSurf, myBaseAdaptor, aD1U, aD1V)) { - throw; + return std::nullopt; } } } } -void GeomEvaluator_OffsetSurface::D3(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V, - gp_Vec& theD2U, - gp_Vec& theD2V, - gp_Vec& theD2UV, - gp_Vec& theD3U, - gp_Vec& theD3V, - gp_Vec& theD3UUV, - gp_Vec& theD3UVV) const +std::optional GeomEvaluator_OffsetSurface::D3( + const Standard_Real theU, + const Standard_Real theV) const { Standard_Real aU = theU, aV = theV; for (;;) { + gp_Pnt aValue; + gp_Vec aD1U, aD1V, aD2U, aD2V, aD2UV, aD3U, aD3V, aD3UUV, aD3UVV; BaseD3(aU, aV, - theValue, - theD1U, - theD1V, - theD2U, - theD2V, - theD2UV, - theD3U, - theD3V, - theD3UUV, - theD3UVV); - - CheckInfinite(theD1U, theD1V); - - try + aValue, + aD1U, + aD1V, + aD2U, + aD2V, + aD2UV, + aD3U, + aD3V, + aD3UUV, + aD3UVV); + + CheckInfinite(aD1U, aD1V); + + if (auto aResult = CalculateD3(aU, + aV, + aValue, + aD1U, + aD1V, + aD2U, + aD2V, + aD2UV, + aD3U, + aD3V, + aD3UUV, + aD3UVV)) { - CalculateD3(aU, - aV, - theValue, - theD1U, - theD1V, - theD2U, - theD2V, - theD2UV, - theD3U, - theD3V, - theD3UUV, - theD3UVV); - break; + return aResult; } - catch (Geom_UndefinedValue&) + else { // if failed at parametric boundary, try taking derivative at shifted point - if (!shiftPoint(theU, theV, aU, aV, myBaseSurf, myBaseAdaptor, theD1U, theD1V)) + if (!shiftPoint(theU, theV, aU, aV, myBaseSurf, myBaseAdaptor, aD1U, aD1V)) { - throw; + return std::nullopt; } } } } -gp_Vec GeomEvaluator_OffsetSurface::DN(const Standard_Real theU, - const Standard_Real theV, - const Standard_Integer theDerU, - const Standard_Integer theDerV) const +std::optional GeomEvaluator_OffsetSurface::DN(const Standard_Real theU, + const Standard_Real theV, + const Standard_Integer theDerU, + const Standard_Integer theDerV) const { Standard_RangeError_Raise_if(theDerU < 0, "GeomEvaluator_OffsetSurface::DN(): theDerU < 0"); Standard_RangeError_Raise_if(theDerV < 0, "GeomEvaluator_OffsetSurface::DN(): theDerV < 0"); @@ -441,16 +473,16 @@ gp_Vec GeomEvaluator_OffsetSurface::DN(const Standard_Real theU, CheckInfinite(aD1U, aD1V); - try + if (auto aResult = CalculateDN(aU, aV, theDerU, theDerV, aD1U, aD1V)) { - return CalculateDN(aU, aV, theDerU, theDerV, aD1U, aD1V); + return aResult; } - catch (Geom_UndefinedValue&) + else { // if failed at parametric boundary, try taking derivative at shifted point if (!shiftPoint(theU, theV, aU, aV, myBaseSurf, myBaseAdaptor, aD1U, aD1V)) { - throw; + return std::nullopt; } } } @@ -552,12 +584,14 @@ void GeomEvaluator_OffsetSurface::BaseD3(const Standard_Real theU, theD3UVV); } -void GeomEvaluator_OffsetSurface::CalculateD0(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - const gp_Vec& theD1U, - const gp_Vec& theD1V) const +std::optional GeomEvaluator_OffsetSurface::CalculateD0(const Standard_Real theU, + const Standard_Real theV, + const gp_Pnt& theBaseValue, + const gp_Vec& theD1U, + const gp_Vec& theD1V) const { + gp_Pnt aValue = theBaseValue; + // Normalize derivatives before normal calculation because it gives more stable result. // There will be normalized only derivatives greater than 1.0 to avoid differences in last // significant digit @@ -575,7 +609,7 @@ void GeomEvaluator_OffsetSurface::CalculateD0(const Standard_Real theU, { // Non singular case. Simple computations. aNorm.Normalize(); - theValue.SetXYZ(theValue.XYZ() + myOffset * aNorm.XYZ()); + aValue.SetXYZ(aValue.XYZ() + myOffset * aNorm.XYZ()); } else { @@ -630,22 +664,28 @@ void GeomEvaluator_OffsetSurface::CalculateD0(const Standard_Real theU, } if (NStatus != CSLib_Defined) - throw Geom_UndefinedValue( - "GeomEvaluator_OffsetSurface::CalculateD0(): Unable to calculate normal"); + return std::nullopt; - theValue.SetXYZ(theValue.XYZ() + myOffset * aSign * Normal.XYZ()); + aValue.SetXYZ(aValue.XYZ() + myOffset * aSign * Normal.XYZ()); } + return aValue; } -void GeomEvaluator_OffsetSurface::CalculateD1(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V, - const gp_Vec& theD2U, - const gp_Vec& theD2V, - const gp_Vec& theD2UV) const +std::optional GeomEvaluator_OffsetSurface::CalculateD1( + const Standard_Real theU, + const Standard_Real theV, + const gp_Pnt& theBaseValue, + const gp_Vec& theBaseD1U, + const gp_Vec& theBaseD1V, + const gp_Vec& theD2U, + const gp_Vec& theD2V, + const gp_Vec& theD2UV) const { + GeomEvaluator_Surface::D1Result aResult; + aResult.theValue = theBaseValue; + aResult.theD1U = theBaseD1U; + aResult.theD1V = theBaseD1V; + // Check offset side. Handle(Geom_BSplineSurface) L; Standard_Boolean isOpposite = Standard_False; @@ -655,8 +695,8 @@ void GeomEvaluator_OffsetSurface::CalculateD1(const Standard_Real theU, // Normalize derivatives before normal calculation because it gives more stable result. // There will be normalized only derivatives greater than 1.0 to avoid differences in last // significant digit - gp_Vec aD1U(theD1U); - gp_Vec aD1V(theD1V); + gp_Vec aD1U(theBaseD1U); + gp_Vec aD1V(theBaseD1V); Standard_Real aD1UNorm2 = aD1U.SquareMagnitude(); Standard_Real aD1VNorm2 = aD1V.SquareMagnitude(); if (aD1UNorm2 > 1.0) @@ -686,36 +726,36 @@ void GeomEvaluator_OffsetSurface::CalculateD1(const Standard_Real theU, // AlongU or AlongV leads to more complex D1 computation // Try to compute D0 and D1 much simpler aNorm.Normalize(); - theValue.SetXYZ(theValue.XYZ() + myOffset * aSign * aNorm.XYZ()); + aResult.theValue.SetXYZ(aResult.theValue.XYZ() + myOffset * aSign * aNorm.XYZ()); gp_Vec aN0(aNorm.XYZ()), aN1U, aN1V; - Standard_Real aScale = (theD1U ^ theD1V).Dot(aN0); - aN1U.SetX(theD2U.Y() * theD1V.Z() + theD1U.Y() * theD2UV.Z() - theD2U.Z() * theD1V.Y() - - theD1U.Z() * theD2UV.Y()); - aN1U.SetY((theD2U.X() * theD1V.Z() + theD1U.X() * theD2UV.Z() - theD2U.Z() * theD1V.X() - - theD1U.Z() * theD2UV.X()) + Standard_Real aScale = (theBaseD1U ^ theBaseD1V).Dot(aN0); + aN1U.SetX(theD2U.Y() * theBaseD1V.Z() + theBaseD1U.Y() * theD2UV.Z() + - theD2U.Z() * theBaseD1V.Y() - theBaseD1U.Z() * theD2UV.Y()); + aN1U.SetY((theD2U.X() * theBaseD1V.Z() + theBaseD1U.X() * theD2UV.Z() + - theD2U.Z() * theBaseD1V.X() - theBaseD1U.Z() * theD2UV.X()) * -1.0); - aN1U.SetZ(theD2U.X() * theD1V.Y() + theD1U.X() * theD2UV.Y() - theD2U.Y() * theD1V.X() - - theD1U.Y() * theD2UV.X()); + aN1U.SetZ(theD2U.X() * theBaseD1V.Y() + theBaseD1U.X() * theD2UV.Y() + - theD2U.Y() * theBaseD1V.X() - theBaseD1U.Y() * theD2UV.X()); Standard_Real aScaleU = aN1U.Dot(aN0); aN1U.Subtract(aScaleU * aN0); aN1U /= aScale; - aN1V.SetX(theD2UV.Y() * theD1V.Z() + theD2V.Z() * theD1U.Y() - theD2UV.Z() * theD1V.Y() - - theD2V.Y() * theD1U.Z()); - aN1V.SetY((theD2UV.X() * theD1V.Z() + theD2V.Z() * theD1U.X() - theD2UV.Z() * theD1V.X() - - theD2V.X() * theD1U.Z()) + aN1V.SetX(theD2UV.Y() * theBaseD1V.Z() + theD2V.Z() * theBaseD1U.Y() + - theD2UV.Z() * theBaseD1V.Y() - theD2V.Y() * theBaseD1U.Z()); + aN1V.SetY((theD2UV.X() * theBaseD1V.Z() + theD2V.Z() * theBaseD1U.X() + - theD2UV.Z() * theBaseD1V.X() - theD2V.X() * theBaseD1U.Z()) * -1.0); - aN1V.SetZ(theD2UV.X() * theD1V.Y() + theD2V.Y() * theD1U.X() - theD2UV.Y() * theD1V.X() - - theD2V.X() * theD1U.Y()); + aN1V.SetZ(theD2UV.X() * theBaseD1V.Y() + theD2V.Y() * theBaseD1U.X() + - theD2UV.Y() * theBaseD1V.X() - theD2V.X() * theBaseD1U.Y()); Standard_Real aScaleV = aN1V.Dot(aN0); aN1V.Subtract(aScaleV * aN0); aN1V /= aScale; - theD1U += myOffset * aSign * aN1U; - theD1V += myOffset * aSign * aN1V; + aResult.theD1U += myOffset * aSign * aN1U; + aResult.theD1V += myOffset * aSign * aN1V; - return; + return aResult; } Standard_Integer OrderU, OrderV; @@ -724,8 +764,8 @@ void GeomEvaluator_OffsetSurface::CalculateD1(const Standard_Real theU, Standard_Real Umin = 0, Umax = 0, Vmin = 0, Vmax = 0; Bounds(Umin, Umax, Vmin, Vmax); - DerSurf.SetValue(1, 0, theD1U); - DerSurf.SetValue(0, 1, theD1V); + DerSurf.SetValue(1, 0, theBaseD1U); + DerSurf.SetValue(0, 1, theBaseD1V); DerSurf.SetValue(1, 1, theD2UV); DerSurf.SetValue(2, 0, theD2U); DerSurf.SetValue(0, 2, theD2V); @@ -751,8 +791,8 @@ void GeomEvaluator_OffsetSurface::CalculateD1(const Standard_Real theU, OrderV); if (NStatus == CSLib_InfinityOfSolutions) { - gp_Vec aNewDU = theD1U; - gp_Vec aNewDV = theD1V; + gp_Vec aNewDU = theBaseD1U; + gp_Vec aNewDV = theBaseD1V; // Replace zero derivative and try to calculate normal if (ReplaceDerivative(theU, theV, aNewDU, aNewDV, the_D1MagTol * the_D1MagTol)) { @@ -790,31 +830,35 @@ void GeomEvaluator_OffsetSurface::CalculateD1(const Standard_Real theU, } if (NStatus != CSLib_Defined) - throw Geom_UndefinedValue( - "GeomEvaluator_OffsetSurface::CalculateD1(): Unable to calculate normal"); + return std::nullopt; - theValue.SetXYZ(theValue.XYZ() + myOffset * aSign * Normal.XYZ()); + aResult.theValue.SetXYZ(aResult.theValue.XYZ() + myOffset * aSign * Normal.XYZ()); - theD1U = DerSurf(1, 0) + myOffset * aSign * CSLib::DNNormal(1, 0, DerNUV, OrderU, OrderV); - theD1V = DerSurf(0, 1) + myOffset * aSign * CSLib::DNNormal(0, 1, DerNUV, OrderU, OrderV); + aResult.theD1U = DerSurf(1, 0) + myOffset * aSign * CSLib::DNNormal(1, 0, DerNUV, OrderU, OrderV); + aResult.theD1V = DerSurf(0, 1) + myOffset * aSign * CSLib::DNNormal(0, 1, DerNUV, OrderU, OrderV); + return aResult; } -void GeomEvaluator_OffsetSurface::CalculateD2(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V, - gp_Vec& theD2U, - gp_Vec& theD2V, - gp_Vec& theD2UV, - const gp_Vec& theD3U, - const gp_Vec& theD3V, - const gp_Vec& theD3UUV, - const gp_Vec& theD3UVV) const +std::optional GeomEvaluator_OffsetSurface::CalculateD2( + const Standard_Real theU, + const Standard_Real theV, + const gp_Pnt& theBaseValue, + const gp_Vec& theBaseD1U, + const gp_Vec& theBaseD1V, + const gp_Vec& theBaseD2U, + const gp_Vec& theBaseD2V, + const gp_Vec& theBaseD2UV, + const gp_Vec& theD3U, + const gp_Vec& theD3V, + const gp_Vec& theD3UUV, + const gp_Vec& theD3UVV) const { + GeomEvaluator_Surface::D2Result aResult; + aResult.theValue = theBaseValue; + gp_Dir Normal; CSLib_NormalStatus NStatus; - CSLib::Normal(theD1U, theD1V, the_D1MagTol, NStatus, Normal); + CSLib::Normal(theBaseD1U, theBaseD1V, the_D1MagTol, NStatus, Normal); const Standard_Integer MaxOrder = (NStatus == CSLib_Defined) ? 0 : 3; Standard_Integer OrderU, OrderV; @@ -824,11 +868,11 @@ void GeomEvaluator_OffsetSurface::CalculateD2(const Standard_Real theU, Standard_Real Umin = 0, Umax = 0, Vmin = 0, Vmax = 0; Bounds(Umin, Umax, Vmin, Vmax); - DerSurf.SetValue(1, 0, theD1U); - DerSurf.SetValue(0, 1, theD1V); - DerSurf.SetValue(1, 1, theD2UV); - DerSurf.SetValue(2, 0, theD2U); - DerSurf.SetValue(0, 2, theD2V); + DerSurf.SetValue(1, 0, theBaseD1U); + DerSurf.SetValue(0, 1, theBaseD1V); + DerSurf.SetValue(1, 1, theBaseD2UV); + DerSurf.SetValue(2, 0, theBaseD2U); + DerSurf.SetValue(0, 2, theBaseD2V); DerSurf.SetValue(3, 0, theD3U); DerSurf.SetValue(2, 1, theD3UUV); DerSurf.SetValue(1, 2, theD3UVV); @@ -865,48 +909,52 @@ void GeomEvaluator_OffsetSurface::CalculateD2(const Standard_Real theU, OrderU, OrderV); if (NStatus != CSLib_Defined) - throw Geom_UndefinedValue( - "GeomEvaluator_OffsetSurface::CalculateD2(): Unable to calculate normal"); + return std::nullopt; - theValue.SetXYZ(theValue.XYZ() + myOffset * aSign * Normal.XYZ()); + aResult.theValue.SetXYZ(aResult.theValue.XYZ() + myOffset * aSign * Normal.XYZ()); - theD1U = DerSurf(1, 0) + myOffset * aSign * CSLib::DNNormal(1, 0, DerNUV, OrderU, OrderV); - theD1V = DerSurf(0, 1) + myOffset * aSign * CSLib::DNNormal(0, 1, DerNUV, OrderU, OrderV); + aResult.theD1U = DerSurf(1, 0) + myOffset * aSign * CSLib::DNNormal(1, 0, DerNUV, OrderU, OrderV); + aResult.theD1V = DerSurf(0, 1) + myOffset * aSign * CSLib::DNNormal(0, 1, DerNUV, OrderU, OrderV); if (!myBaseSurf.IsNull()) { - theD2U = myBaseSurf->DN(theU, theV, 2, 0); - theD2V = myBaseSurf->DN(theU, theV, 0, 2); - theD2UV = myBaseSurf->DN(theU, theV, 1, 1); + aResult.theD2U = unwrapDN(myBaseSurf->DN(theU, theV, 2, 0)); + aResult.theD2V = unwrapDN(myBaseSurf->DN(theU, theV, 0, 2)); + aResult.theD2UV = unwrapDN(myBaseSurf->DN(theU, theV, 1, 1)); } else { - theD2U = myBaseAdaptor->DN(theU, theV, 2, 0); - theD2V = myBaseAdaptor->DN(theU, theV, 0, 2); - theD2UV = myBaseAdaptor->DN(theU, theV, 1, 1); + aResult.theD2U = myBaseAdaptor->DN(theU, theV, 2, 0); + aResult.theD2V = myBaseAdaptor->DN(theU, theV, 0, 2); + aResult.theD2UV = myBaseAdaptor->DN(theU, theV, 1, 1); } - theD2U += aSign * myOffset * CSLib::DNNormal(2, 0, DerNUV, OrderU, OrderV); - theD2V += aSign * myOffset * CSLib::DNNormal(0, 2, DerNUV, OrderU, OrderV); - theD2UV += aSign * myOffset * CSLib::DNNormal(1, 1, DerNUV, OrderU, OrderV); + aResult.theD2U += aSign * myOffset * CSLib::DNNormal(2, 0, DerNUV, OrderU, OrderV); + aResult.theD2V += aSign * myOffset * CSLib::DNNormal(0, 2, DerNUV, OrderU, OrderV); + aResult.theD2UV += aSign * myOffset * CSLib::DNNormal(1, 1, DerNUV, OrderU, OrderV); + return aResult; } -void GeomEvaluator_OffsetSurface::CalculateD3(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V, - gp_Vec& theD2U, - gp_Vec& theD2V, - gp_Vec& theD2UV, - gp_Vec& theD3U, - gp_Vec& theD3V, - gp_Vec& theD3UUV, - gp_Vec& theD3UVV) const +std::optional GeomEvaluator_OffsetSurface::CalculateD3( + const Standard_Real theU, + const Standard_Real theV, + const gp_Pnt& theBaseValue, + const gp_Vec& theBaseD1U, + const gp_Vec& theBaseD1V, + const gp_Vec& theBaseD2U, + const gp_Vec& theBaseD2V, + const gp_Vec& theBaseD2UV, + const gp_Vec& theBaseD3U, + const gp_Vec& theBaseD3V, + const gp_Vec& theBaseD3UUV, + const gp_Vec& theBaseD3UVV) const { + GeomEvaluator_Surface::D3Result aResult; + aResult.theValue = theBaseValue; + gp_Dir Normal; CSLib_NormalStatus NStatus; - CSLib::Normal(theD1U, theD1V, the_D1MagTol, NStatus, Normal); + CSLib::Normal(theBaseD1U, theBaseD1V, the_D1MagTol, NStatus, Normal); const Standard_Integer MaxOrder = (NStatus == CSLib_Defined) ? 0 : 3; Standard_Integer OrderU, OrderV; TColgp_Array2OfVec DerNUV(0, MaxOrder + 3, 0, MaxOrder + 3); @@ -914,15 +962,15 @@ void GeomEvaluator_OffsetSurface::CalculateD3(const Standard_Real theU, Standard_Real Umin = 0, Umax = 0, Vmin = 0, Vmax = 0; Bounds(Umin, Umax, Vmin, Vmax); - DerSurf.SetValue(1, 0, theD1U); - DerSurf.SetValue(0, 1, theD1V); - DerSurf.SetValue(1, 1, theD2UV); - DerSurf.SetValue(2, 0, theD2U); - DerSurf.SetValue(0, 2, theD2V); - DerSurf.SetValue(3, 0, theD3U); - DerSurf.SetValue(2, 1, theD3UUV); - DerSurf.SetValue(1, 2, theD3UVV); - DerSurf.SetValue(0, 3, theD3V); + DerSurf.SetValue(1, 0, theBaseD1U); + DerSurf.SetValue(0, 1, theBaseD1V); + DerSurf.SetValue(1, 1, theBaseD2UV); + DerSurf.SetValue(2, 0, theBaseD2U); + DerSurf.SetValue(0, 2, theBaseD2V); + DerSurf.SetValue(3, 0, theBaseD3U); + DerSurf.SetValue(2, 1, theBaseD3UUV); + DerSurf.SetValue(1, 2, theBaseD3UVV); + DerSurf.SetValue(0, 3, theBaseD3V); //********************* Handle(Geom_BSplineSurface) L; @@ -955,50 +1003,51 @@ void GeomEvaluator_OffsetSurface::CalculateD3(const Standard_Real theU, OrderU, OrderV); if (NStatus != CSLib_Defined) - throw Geom_UndefinedValue( - "GeomEvaluator_OffsetSurface::CalculateD3(): Unable to calculate normal"); + return std::nullopt; - theValue.SetXYZ(theValue.XYZ() + myOffset * aSign * Normal.XYZ()); + aResult.theValue.SetXYZ(aResult.theValue.XYZ() + myOffset * aSign * Normal.XYZ()); - theD1U = DerSurf(1, 0) + myOffset * aSign * CSLib::DNNormal(1, 0, DerNUV, OrderU, OrderV); - theD1V = DerSurf(0, 1) + myOffset * aSign * CSLib::DNNormal(0, 1, DerNUV, OrderU, OrderV); + aResult.theD1U = DerSurf(1, 0) + myOffset * aSign * CSLib::DNNormal(1, 0, DerNUV, OrderU, OrderV); + aResult.theD1V = DerSurf(0, 1) + myOffset * aSign * CSLib::DNNormal(0, 1, DerNUV, OrderU, OrderV); if (!myBaseSurf.IsNull()) { - theD2U = myBaseSurf->DN(theU, theV, 2, 0); - theD2V = myBaseSurf->DN(theU, theV, 0, 2); - theD2UV = myBaseSurf->DN(theU, theV, 1, 1); - theD3U = myBaseSurf->DN(theU, theV, 3, 0); - theD3V = myBaseSurf->DN(theU, theV, 0, 3); - theD3UUV = myBaseSurf->DN(theU, theV, 2, 1); - theD3UVV = myBaseSurf->DN(theU, theV, 1, 2); + aResult.theD2U = unwrapDN(myBaseSurf->DN(theU, theV, 2, 0)); + aResult.theD2V = unwrapDN(myBaseSurf->DN(theU, theV, 0, 2)); + aResult.theD2UV = unwrapDN(myBaseSurf->DN(theU, theV, 1, 1)); + aResult.theD3U = unwrapDN(myBaseSurf->DN(theU, theV, 3, 0)); + aResult.theD3V = unwrapDN(myBaseSurf->DN(theU, theV, 0, 3)); + aResult.theD3UUV = unwrapDN(myBaseSurf->DN(theU, theV, 2, 1)); + aResult.theD3UVV = unwrapDN(myBaseSurf->DN(theU, theV, 1, 2)); } else { - theD2U = myBaseAdaptor->DN(theU, theV, 2, 0); - theD2V = myBaseAdaptor->DN(theU, theV, 0, 2); - theD2UV = myBaseAdaptor->DN(theU, theV, 1, 1); - theD3U = myBaseAdaptor->DN(theU, theV, 3, 0); - theD3V = myBaseAdaptor->DN(theU, theV, 0, 3); - theD3UUV = myBaseAdaptor->DN(theU, theV, 2, 1); - theD3UVV = myBaseAdaptor->DN(theU, theV, 1, 2); + aResult.theD2U = myBaseAdaptor->DN(theU, theV, 2, 0); + aResult.theD2V = myBaseAdaptor->DN(theU, theV, 0, 2); + aResult.theD2UV = myBaseAdaptor->DN(theU, theV, 1, 1); + aResult.theD3U = myBaseAdaptor->DN(theU, theV, 3, 0); + aResult.theD3V = myBaseAdaptor->DN(theU, theV, 0, 3); + aResult.theD3UUV = myBaseAdaptor->DN(theU, theV, 2, 1); + aResult.theD3UVV = myBaseAdaptor->DN(theU, theV, 1, 2); } - theD2U += aSign * myOffset * CSLib::DNNormal(2, 0, DerNUV, OrderU, OrderV); - theD2V += aSign * myOffset * CSLib::DNNormal(0, 2, DerNUV, OrderU, OrderV); - theD2UV += aSign * myOffset * CSLib::DNNormal(1, 1, DerNUV, OrderU, OrderV); - theD3U += aSign * myOffset * CSLib::DNNormal(3, 0, DerNUV, OrderU, OrderV); - theD3V += aSign * myOffset * CSLib::DNNormal(0, 3, DerNUV, OrderU, OrderV); - theD3UUV += aSign * myOffset * CSLib::DNNormal(2, 1, DerNUV, OrderU, OrderV); - theD3UVV += aSign * myOffset * CSLib::DNNormal(1, 2, DerNUV, OrderU, OrderV); + aResult.theD2U += aSign * myOffset * CSLib::DNNormal(2, 0, DerNUV, OrderU, OrderV); + aResult.theD2V += aSign * myOffset * CSLib::DNNormal(0, 2, DerNUV, OrderU, OrderV); + aResult.theD2UV += aSign * myOffset * CSLib::DNNormal(1, 1, DerNUV, OrderU, OrderV); + aResult.theD3U += aSign * myOffset * CSLib::DNNormal(3, 0, DerNUV, OrderU, OrderV); + aResult.theD3V += aSign * myOffset * CSLib::DNNormal(0, 3, DerNUV, OrderU, OrderV); + aResult.theD3UUV += aSign * myOffset * CSLib::DNNormal(2, 1, DerNUV, OrderU, OrderV); + aResult.theD3UVV += aSign * myOffset * CSLib::DNNormal(1, 2, DerNUV, OrderU, OrderV); + return aResult; } -gp_Vec GeomEvaluator_OffsetSurface::CalculateDN(const Standard_Real theU, - const Standard_Real theV, - const Standard_Integer theNu, - const Standard_Integer theNv, - const gp_Vec& theD1U, - const gp_Vec& theD1V) const +std::optional GeomEvaluator_OffsetSurface::CalculateDN( + const Standard_Real theU, + const Standard_Real theV, + const Standard_Integer theNu, + const Standard_Integer theNv, + const gp_Vec& theD1U, + const gp_Vec& theD1V) const { gp_Dir Normal; CSLib_NormalStatus NStatus; @@ -1068,17 +1117,16 @@ gp_Vec GeomEvaluator_OffsetSurface::CalculateDN(const Standard_Real theU, OrderU, OrderV); if (NStatus != CSLib_Defined) - throw Geom_UndefinedValue( - "GeomEvaluator_OffsetSurface::CalculateDN(): Unable to calculate normal"); + return std::nullopt; - gp_Vec D; + gp_Vec aResult; if (!myBaseSurf.IsNull()) - D = myBaseSurf->DN(theU, theV, theNu, theNv); + aResult = unwrapDN(myBaseSurf->DN(theU, theV, theNu, theNv)); else - D = myBaseAdaptor->DN(theU, theV, theNu, theNv); + aResult = myBaseAdaptor->DN(theU, theV, theNu, theNv); - D += aSign * myOffset * CSLib::DNNormal(theNu, theNv, DerNUV, OrderU, OrderV); - return D; + aResult += aSign * myOffset * CSLib::DNNormal(theNu, theNv, DerNUV, OrderU, OrderV); + return aResult; } void GeomEvaluator_OffsetSurface::Bounds(Standard_Real& theUMin, diff --git a/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_OffsetSurface.hxx b/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_OffsetSurface.hxx index 0bce0b3793..8e78e35e42 100644 --- a/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_OffsetSurface.hxx +++ b/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_OffsetSurface.hxx @@ -39,44 +39,29 @@ public: void SetOffsetValue(Standard_Real theOffset) { myOffset = theOffset; } //! Value of surface - Standard_EXPORT void D0(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue) const Standard_OVERRIDE; + //! @return Point value if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D0(const Standard_Real theU, + const Standard_Real theV) const Standard_OVERRIDE; //! Value and first derivatives of surface - Standard_EXPORT void D1(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V) const Standard_OVERRIDE; + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D1(const Standard_Real theU, + const Standard_Real theV) const Standard_OVERRIDE; //! Value, first and second derivatives of surface - Standard_EXPORT void D2(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V, - gp_Vec& theD2U, - gp_Vec& theD2V, - gp_Vec& theD2UV) const Standard_OVERRIDE; + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D2(const Standard_Real theU, + const Standard_Real theV) const Standard_OVERRIDE; //! Value, first, second and third derivatives of surface - Standard_EXPORT void D3(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V, - gp_Vec& theD2U, - gp_Vec& theD2V, - gp_Vec& theD2UV, - gp_Vec& theD3U, - gp_Vec& theD3V, - gp_Vec& theD3UUV, - gp_Vec& theD3UVV) const Standard_OVERRIDE; + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D3(const Standard_Real theU, + const Standard_Real theV) const Standard_OVERRIDE; //! Calculates N-th derivatives of surface, where N = theDerU + theDerV. //! //! Raises if N < 1 or theDerU < 0 or theDerV < 0 - Standard_EXPORT gp_Vec DN(const Standard_Real theU, - const Standard_Real theV, - const Standard_Integer theDerU, - const Standard_Integer theDerV) const Standard_OVERRIDE; + //! @return Derivative vector if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional DN(const Standard_Real theU, + const Standard_Real theV, + const Standard_Integer theDerU, + const Standard_Integer theDerV) const Standard_OVERRIDE; Standard_EXPORT Handle(GeomEvaluator_Surface) ShallowCopy() const Standard_OVERRIDE; @@ -90,53 +75,58 @@ private: Standard_Real& theVMax) const; //! Recalculate D1 values of base surface into D0 value of offset surface - void CalculateD0(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - const gp_Vec& theD1U, - const gp_Vec& theD1V) const; + //! @return Point value if calculation succeeds, std::nullopt otherwise + std::optional CalculateD0(const Standard_Real theU, + const Standard_Real theV, + const gp_Pnt& theBaseValue, + const gp_Vec& theD1U, + const gp_Vec& theD1V) const; //! Recalculate D2 values of base surface into D1 values of offset surface - void CalculateD1(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V, - const gp_Vec& theD2U, - const gp_Vec& theD2V, - const gp_Vec& theD2UV) const; + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + std::optional CalculateD1(const Standard_Real theU, + const Standard_Real theV, + const gp_Pnt& theBaseValue, + const gp_Vec& theBaseD1U, + const gp_Vec& theBaseD1V, + const gp_Vec& theD2U, + const gp_Vec& theD2V, + const gp_Vec& theD2UV) const; //! Recalculate D3 values of base surface into D2 values of offset surface - void CalculateD2(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V, - gp_Vec& theD2U, - gp_Vec& theD2V, - gp_Vec& theD2UV, - const gp_Vec& theD3U, - const gp_Vec& theD3V, - const gp_Vec& theD3UUV, - const gp_Vec& theD3UVV) const; - //! Recalculate D3 values of base surface into D3 values of offset surface - void CalculateD3(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V, - gp_Vec& theD2U, - gp_Vec& theD2V, - gp_Vec& theD2UV, - gp_Vec& theD3U, - gp_Vec& theD3V, - gp_Vec& theD3UUV, - gp_Vec& theD3UVV) const; + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + std::optional CalculateD2(const Standard_Real theU, + const Standard_Real theV, + const gp_Pnt& theBaseValue, + const gp_Vec& theBaseD1U, + const gp_Vec& theBaseD1V, + const gp_Vec& theBaseD2U, + const gp_Vec& theBaseD2V, + const gp_Vec& theBaseD2UV, + const gp_Vec& theD3U, + const gp_Vec& theD3V, + const gp_Vec& theD3UUV, + const gp_Vec& theD3UVV) const; + //! Recalculate base surface values into D3 values of offset surface + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + std::optional CalculateD3(const Standard_Real theU, + const Standard_Real theV, + const gp_Pnt& theBaseValue, + const gp_Vec& theBaseD1U, + const gp_Vec& theBaseD1V, + const gp_Vec& theBaseD2U, + const gp_Vec& theBaseD2V, + const gp_Vec& theBaseD2UV, + const gp_Vec& theBaseD3U, + const gp_Vec& theBaseD3V, + const gp_Vec& theBaseD3UUV, + const gp_Vec& theBaseD3UVV) const; //! Calculate DN of offset surface based on derivatives of base surface - gp_Vec CalculateDN(const Standard_Real theU, - const Standard_Real theV, - const Standard_Integer theNu, - const Standard_Integer theNv, - const gp_Vec& theD1U, - const gp_Vec& theD1V) const; + //! @return Derivative vector if calculation succeeds, std::nullopt otherwise + std::optional CalculateDN(const Standard_Real theU, + const Standard_Real theV, + const Standard_Integer theNu, + const Standard_Integer theNv, + const gp_Vec& theD1U, + const gp_Vec& theD1V) const; //! Calculate value of base surface/adaptor void BaseD0(const Standard_Real theU, const Standard_Real theV, gp_Pnt& theValue) const; diff --git a/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_Surface.hxx b/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_Surface.hxx index 50d4c2eb9a..642906742e 100644 --- a/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_Surface.hxx +++ b/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_Surface.hxx @@ -17,54 +17,76 @@ #include #include - -class gp_Pnt; -class gp_Vec; +#include +#include +#include //! Interface for calculation of values and derivatives for different kinds of surfaces. //! Works both with adaptors and surfaces. +//! All methods return std::optional to properly handle calculation failures. class GeomEvaluator_Surface : public Standard_Transient { public: + //! Result structure for D1 evaluation - point and first derivatives + struct D1Result + { + gp_Pnt theValue; + gp_Vec theD1U; + gp_Vec theD1V; + }; + + //! Result structure for D2 evaluation - point, first and second derivatives + struct D2Result + { + gp_Pnt theValue; + gp_Vec theD1U; + gp_Vec theD1V; + gp_Vec theD2U; + gp_Vec theD2V; + gp_Vec theD2UV; + }; + + //! Result structure for D3 evaluation - point, first, second and third derivatives + struct D3Result + { + gp_Pnt theValue; + gp_Vec theD1U; + gp_Vec theD1V; + gp_Vec theD2U; + gp_Vec theD2V; + gp_Vec theD2UV; + gp_Vec theD3U; + gp_Vec theD3V; + gp_Vec theD3UUV; + gp_Vec theD3UVV; + }; + GeomEvaluator_Surface() {} //! Value of surface - virtual void D0(const Standard_Real theU, const Standard_Real theV, gp_Pnt& theValue) const = 0; + //! @return Point value if calculation succeeds, std::nullopt otherwise + virtual std::optional D0(const Standard_Real theU, const Standard_Real theV) const = 0; + //! Value and first derivatives of surface - virtual void D1(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V) const = 0; + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + virtual std::optional D1(const Standard_Real theU, const Standard_Real theV) const = 0; + //! Value, first and second derivatives of surface - virtual void D2(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V, - gp_Vec& theD2U, - gp_Vec& theD2V, - gp_Vec& theD2UV) const = 0; + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + virtual std::optional D2(const Standard_Real theU, const Standard_Real theV) const = 0; + //! Value, first, second and third derivatives of surface - virtual void D3(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V, - gp_Vec& theD2U, - gp_Vec& theD2V, - gp_Vec& theD2UV, - gp_Vec& theD3U, - gp_Vec& theD3V, - gp_Vec& theD3UUV, - gp_Vec& theD3UVV) const = 0; + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + virtual std::optional D3(const Standard_Real theU, const Standard_Real theV) const = 0; + //! Calculates N-th derivatives of surface, where N = theDerU + theDerV. //! //! Raises if N < 1 or theDerU < 0 or theDerV < 0 - virtual gp_Vec DN(const Standard_Real theU, - const Standard_Real theV, - const Standard_Integer theDerU, - const Standard_Integer theDerV) const = 0; + //! @return Derivative vector if calculation succeeds, std::nullopt otherwise + virtual std::optional DN(const Standard_Real theU, + const Standard_Real theV, + const Standard_Integer theDerU, + const Standard_Integer theDerV) const = 0; virtual Handle(GeomEvaluator_Surface) ShallowCopy() const = 0; diff --git a/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfExtrusion.cxx b/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfExtrusion.cxx index fa51c2b89d..7e526a0179 100644 --- a/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfExtrusion.cxx +++ b/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfExtrusion.cxx @@ -36,86 +36,77 @@ GeomEvaluator_SurfaceOfExtrusion::GeomEvaluator_SurfaceOfExtrusion( { } -void GeomEvaluator_SurfaceOfExtrusion::D0(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue) const +std::optional GeomEvaluator_SurfaceOfExtrusion::D0(const Standard_Real theU, + const Standard_Real theV) const { + gp_Pnt aValue; if (!myBaseAdaptor.IsNull()) - myBaseAdaptor->D0(theU, theValue); + myBaseAdaptor->D0(theU, aValue); else - myBaseCurve->D0(theU, theValue); + myBaseCurve->D0(theU, aValue); - Shift(theV, theValue); + Shift(theV, aValue); + return aValue; } -void GeomEvaluator_SurfaceOfExtrusion::D1(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V) const +std::optional GeomEvaluator_SurfaceOfExtrusion::D1( + const Standard_Real theU, + const Standard_Real theV) const { + GeomEvaluator_Surface::D1Result aResult; if (!myBaseAdaptor.IsNull()) - myBaseAdaptor->D1(theU, theValue, theD1U); + myBaseAdaptor->D1(theU, aResult.theValue, aResult.theD1U); else - myBaseCurve->D1(theU, theValue, theD1U); + myBaseCurve->D1(theU, aResult.theValue, aResult.theD1U); - theD1V = myDirection; - Shift(theV, theValue); + aResult.theD1V = myDirection; + Shift(theV, aResult.theValue); + return aResult; } -void GeomEvaluator_SurfaceOfExtrusion::D2(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V, - gp_Vec& theD2U, - gp_Vec& theD2V, - gp_Vec& theD2UV) const +std::optional GeomEvaluator_SurfaceOfExtrusion::D2( + const Standard_Real theU, + const Standard_Real theV) const { + GeomEvaluator_Surface::D2Result aResult; if (!myBaseAdaptor.IsNull()) - myBaseAdaptor->D2(theU, theValue, theD1U, theD2U); + myBaseAdaptor->D2(theU, aResult.theValue, aResult.theD1U, aResult.theD2U); else - myBaseCurve->D2(theU, theValue, theD1U, theD2U); + myBaseCurve->D2(theU, aResult.theValue, aResult.theD1U, aResult.theD2U); - theD1V = myDirection; - theD2V.SetCoord(0.0, 0.0, 0.0); - theD2UV.SetCoord(0.0, 0.0, 0.0); + aResult.theD1V = myDirection; + aResult.theD2V.SetCoord(0.0, 0.0, 0.0); + aResult.theD2UV.SetCoord(0.0, 0.0, 0.0); - Shift(theV, theValue); + Shift(theV, aResult.theValue); + return aResult; } -void GeomEvaluator_SurfaceOfExtrusion::D3(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V, - gp_Vec& theD2U, - gp_Vec& theD2V, - gp_Vec& theD2UV, - gp_Vec& theD3U, - gp_Vec& theD3V, - gp_Vec& theD3UUV, - gp_Vec& theD3UVV) const +std::optional GeomEvaluator_SurfaceOfExtrusion::D3( + const Standard_Real theU, + const Standard_Real theV) const { + GeomEvaluator_Surface::D3Result aResult; if (!myBaseAdaptor.IsNull()) - myBaseAdaptor->D3(theU, theValue, theD1U, theD2U, theD3U); + myBaseAdaptor->D3(theU, aResult.theValue, aResult.theD1U, aResult.theD2U, aResult.theD3U); else - myBaseCurve->D3(theU, theValue, theD1U, theD2U, theD3U); + myBaseCurve->D3(theU, aResult.theValue, aResult.theD1U, aResult.theD2U, aResult.theD3U); - theD1V = myDirection; - theD2V.SetCoord(0.0, 0.0, 0.0); - theD2UV.SetCoord(0.0, 0.0, 0.0); - theD3V.SetCoord(0.0, 0.0, 0.0); - theD3UUV.SetCoord(0.0, 0.0, 0.0); - theD3UVV.SetCoord(0.0, 0.0, 0.0); + aResult.theD1V = myDirection; + aResult.theD2V.SetCoord(0.0, 0.0, 0.0); + aResult.theD2UV.SetCoord(0.0, 0.0, 0.0); + aResult.theD3V.SetCoord(0.0, 0.0, 0.0); + aResult.theD3UUV.SetCoord(0.0, 0.0, 0.0); + aResult.theD3UVV.SetCoord(0.0, 0.0, 0.0); - Shift(theV, theValue); + Shift(theV, aResult.theValue); + return aResult; } -gp_Vec GeomEvaluator_SurfaceOfExtrusion::DN(const Standard_Real theU, - const Standard_Real, - const Standard_Integer theDerU, - const Standard_Integer theDerV) const +std::optional GeomEvaluator_SurfaceOfExtrusion::DN(const Standard_Real theU, + const Standard_Real, + const Standard_Integer theDerU, + const Standard_Integer theDerV) const { Standard_RangeError_Raise_if(theDerU < 0, "GeomEvaluator_SurfaceOfExtrusion::DN(): theDerU < 0"); Standard_RangeError_Raise_if(theDerV < 0, "GeomEvaluator_SurfaceOfExtrusion::DN(): theDerV < 0"); diff --git a/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfExtrusion.hxx b/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfExtrusion.hxx index 3cf45007b0..0eb49c2339 100644 --- a/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfExtrusion.hxx +++ b/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfExtrusion.hxx @@ -35,44 +35,29 @@ public: void SetDirection(const gp_Dir& theDirection) { myDirection = theDirection; } //! Value of surface - Standard_EXPORT void D0(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue) const Standard_OVERRIDE; + //! @return Point value if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D0(const Standard_Real theU, + const Standard_Real theV) const Standard_OVERRIDE; //! Value and first derivatives of surface - Standard_EXPORT void D1(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V) const Standard_OVERRIDE; + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D1(const Standard_Real theU, + const Standard_Real theV) const Standard_OVERRIDE; //! Value, first and second derivatives of surface - Standard_EXPORT void D2(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V, - gp_Vec& theD2U, - gp_Vec& theD2V, - gp_Vec& theD2UV) const Standard_OVERRIDE; + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D2(const Standard_Real theU, + const Standard_Real theV) const Standard_OVERRIDE; //! Value, first, second and third derivatives of surface - Standard_EXPORT void D3(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V, - gp_Vec& theD2U, - gp_Vec& theD2V, - gp_Vec& theD2UV, - gp_Vec& theD3U, - gp_Vec& theD3V, - gp_Vec& theD3UUV, - gp_Vec& theD3UVV) const Standard_OVERRIDE; + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D3(const Standard_Real theU, + const Standard_Real theV) const Standard_OVERRIDE; //! Calculates N-th derivatives of surface, where N = theDerU + theDerV. //! //! Raises if N < 1 or theDerU < 0 or theDerV < 0 - Standard_EXPORT gp_Vec DN(const Standard_Real theU, - const Standard_Real theV, - const Standard_Integer theDerU, - const Standard_Integer theDerV) const Standard_OVERRIDE; + //! @return Derivative vector if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional DN(const Standard_Real theU, + const Standard_Real theV, + const Standard_Integer theDerU, + const Standard_Integer theDerV) const Standard_OVERRIDE; Standard_EXPORT Handle(GeomEvaluator_Surface) ShallowCopy() const Standard_OVERRIDE; diff --git a/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfRevolution.cxx b/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfRevolution.cxx index 1b42d347f8..e247b6d2bf 100644 --- a/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfRevolution.cxx +++ b/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfRevolution.cxx @@ -40,131 +40,122 @@ GeomEvaluator_SurfaceOfRevolution::GeomEvaluator_SurfaceOfRevolution( { } -void GeomEvaluator_SurfaceOfRevolution::D0(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue) const +std::optional GeomEvaluator_SurfaceOfRevolution::D0(const Standard_Real theU, + const Standard_Real theV) const { + gp_Pnt aValue; if (!myBaseAdaptor.IsNull()) - myBaseAdaptor->D0(theV, theValue); + myBaseAdaptor->D0(theV, aValue); else - myBaseCurve->D0(theV, theValue); + myBaseCurve->D0(theV, aValue); gp_Trsf aRotation; aRotation.SetRotation(myRotAxis, theU); - theValue.Transform(aRotation); + aValue.Transform(aRotation); + return aValue; } -void GeomEvaluator_SurfaceOfRevolution::D1(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V) const +std::optional GeomEvaluator_SurfaceOfRevolution::D1( + const Standard_Real theU, + const Standard_Real theV) const { + GeomEvaluator_Surface::D1Result aResult; if (!myBaseAdaptor.IsNull()) - myBaseAdaptor->D1(theV, theValue, theD1V); + myBaseAdaptor->D1(theV, aResult.theValue, aResult.theD1V); else - myBaseCurve->D1(theV, theValue, theD1V); + myBaseCurve->D1(theV, aResult.theValue, aResult.theD1V); // vector from center of rotation to the point on rotated curve - gp_XYZ aCQ = theValue.XYZ() - myRotAxis.Location().XYZ(); - theD1U = gp_Vec(myRotAxis.Direction().XYZ().Crossed(aCQ)); + gp_XYZ aCQ = aResult.theValue.XYZ() - myRotAxis.Location().XYZ(); + aResult.theD1U = gp_Vec(myRotAxis.Direction().XYZ().Crossed(aCQ)); // If the point is placed on the axis of revolution then derivatives on U are undefined. // Manually set them to zero. - if (theD1U.SquareMagnitude() < Precision::SquareConfusion()) - theD1U.SetCoord(0.0, 0.0, 0.0); + if (aResult.theD1U.SquareMagnitude() < Precision::SquareConfusion()) + aResult.theD1U.SetCoord(0.0, 0.0, 0.0); gp_Trsf aRotation; aRotation.SetRotation(myRotAxis, theU); - theValue.Transform(aRotation); - theD1U.Transform(aRotation); - theD1V.Transform(aRotation); + aResult.theValue.Transform(aRotation); + aResult.theD1U.Transform(aRotation); + aResult.theD1V.Transform(aRotation); + return aResult; } -void GeomEvaluator_SurfaceOfRevolution::D2(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V, - gp_Vec& theD2U, - gp_Vec& theD2V, - gp_Vec& theD2UV) const +std::optional GeomEvaluator_SurfaceOfRevolution::D2( + const Standard_Real theU, + const Standard_Real theV) const { + GeomEvaluator_Surface::D2Result aResult; if (!myBaseAdaptor.IsNull()) - myBaseAdaptor->D2(theV, theValue, theD1V, theD2V); + myBaseAdaptor->D2(theV, aResult.theValue, aResult.theD1V, aResult.theD2V); else - myBaseCurve->D2(theV, theValue, theD1V, theD2V); + myBaseCurve->D2(theV, aResult.theValue, aResult.theD1V, aResult.theD2V); // vector from center of rotation to the point on rotated curve - gp_XYZ aCQ = theValue.XYZ() - myRotAxis.Location().XYZ(); + gp_XYZ aCQ = aResult.theValue.XYZ() - myRotAxis.Location().XYZ(); const gp_XYZ& aDir = myRotAxis.Direction().XYZ(); - theD1U = gp_Vec(aDir.Crossed(aCQ)); + aResult.theD1U = gp_Vec(aDir.Crossed(aCQ)); // If the point is placed on the axis of revolution then derivatives on U are undefined. // Manually set them to zero. - if (theD1U.SquareMagnitude() < Precision::SquareConfusion()) - theD1U.SetCoord(0.0, 0.0, 0.0); - theD2U = gp_Vec(aDir.Dot(aCQ) * aDir - aCQ); - theD2UV = gp_Vec(aDir.Crossed(theD1V.XYZ())); + if (aResult.theD1U.SquareMagnitude() < Precision::SquareConfusion()) + aResult.theD1U.SetCoord(0.0, 0.0, 0.0); + aResult.theD2U = gp_Vec(aDir.Dot(aCQ) * aDir - aCQ); + aResult.theD2UV = gp_Vec(aDir.Crossed(aResult.theD1V.XYZ())); gp_Trsf aRotation; aRotation.SetRotation(myRotAxis, theU); - theValue.Transform(aRotation); - theD1U.Transform(aRotation); - theD1V.Transform(aRotation); - theD2U.Transform(aRotation); - theD2V.Transform(aRotation); - theD2UV.Transform(aRotation); + aResult.theValue.Transform(aRotation); + aResult.theD1U.Transform(aRotation); + aResult.theD1V.Transform(aRotation); + aResult.theD2U.Transform(aRotation); + aResult.theD2V.Transform(aRotation); + aResult.theD2UV.Transform(aRotation); + return aResult; } -void GeomEvaluator_SurfaceOfRevolution::D3(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V, - gp_Vec& theD2U, - gp_Vec& theD2V, - gp_Vec& theD2UV, - gp_Vec& theD3U, - gp_Vec& theD3V, - gp_Vec& theD3UUV, - gp_Vec& theD3UVV) const +std::optional GeomEvaluator_SurfaceOfRevolution::D3( + const Standard_Real theU, + const Standard_Real theV) const { + GeomEvaluator_Surface::D3Result aResult; if (!myBaseAdaptor.IsNull()) - myBaseAdaptor->D3(theV, theValue, theD1V, theD2V, theD3V); + myBaseAdaptor->D3(theV, aResult.theValue, aResult.theD1V, aResult.theD2V, aResult.theD3V); else - myBaseCurve->D3(theV, theValue, theD1V, theD2V, theD3V); + myBaseCurve->D3(theV, aResult.theValue, aResult.theD1V, aResult.theD2V, aResult.theD3V); // vector from center of rotation to the point on rotated curve - gp_XYZ aCQ = theValue.XYZ() - myRotAxis.Location().XYZ(); + gp_XYZ aCQ = aResult.theValue.XYZ() - myRotAxis.Location().XYZ(); const gp_XYZ& aDir = myRotAxis.Direction().XYZ(); - theD1U = gp_Vec(aDir.Crossed(aCQ)); + aResult.theD1U = gp_Vec(aDir.Crossed(aCQ)); // If the point is placed on the axis of revolution then derivatives on U are undefined. // Manually set them to zero. - if (theD1U.SquareMagnitude() < Precision::SquareConfusion()) - theD1U.SetCoord(0.0, 0.0, 0.0); - theD2U = gp_Vec(aDir.Dot(aCQ) * aDir - aCQ); - theD2UV = gp_Vec(aDir.Crossed(theD1V.XYZ())); - theD3U = -theD1U; - theD3UUV = gp_Vec(aDir.Dot(theD1V.XYZ()) * aDir - theD1V.XYZ()); - theD3UVV = gp_Vec(aDir.Crossed(theD2V.XYZ())); + if (aResult.theD1U.SquareMagnitude() < Precision::SquareConfusion()) + aResult.theD1U.SetCoord(0.0, 0.0, 0.0); + aResult.theD2U = gp_Vec(aDir.Dot(aCQ) * aDir - aCQ); + aResult.theD2UV = gp_Vec(aDir.Crossed(aResult.theD1V.XYZ())); + aResult.theD3U = -aResult.theD1U; + aResult.theD3UUV = gp_Vec(aDir.Dot(aResult.theD1V.XYZ()) * aDir - aResult.theD1V.XYZ()); + aResult.theD3UVV = gp_Vec(aDir.Crossed(aResult.theD2V.XYZ())); gp_Trsf aRotation; aRotation.SetRotation(myRotAxis, theU); - theValue.Transform(aRotation); - theD1U.Transform(aRotation); - theD1V.Transform(aRotation); - theD2U.Transform(aRotation); - theD2V.Transform(aRotation); - theD2UV.Transform(aRotation); - theD3U.Transform(aRotation); - theD3V.Transform(aRotation); - theD3UUV.Transform(aRotation); - theD3UVV.Transform(aRotation); + aResult.theValue.Transform(aRotation); + aResult.theD1U.Transform(aRotation); + aResult.theD1V.Transform(aRotation); + aResult.theD2U.Transform(aRotation); + aResult.theD2V.Transform(aRotation); + aResult.theD2UV.Transform(aRotation); + aResult.theD3U.Transform(aRotation); + aResult.theD3V.Transform(aRotation); + aResult.theD3UUV.Transform(aRotation); + aResult.theD3UVV.Transform(aRotation); + return aResult; } -gp_Vec GeomEvaluator_SurfaceOfRevolution::DN(const Standard_Real theU, - const Standard_Real theV, - const Standard_Integer theDerU, - const Standard_Integer theDerV) const +std::optional GeomEvaluator_SurfaceOfRevolution::DN(const Standard_Real theU, + const Standard_Real theV, + const Standard_Integer theDerU, + const Standard_Integer theDerV) const { Standard_RangeError_Raise_if(theDerU < 0, "GeomEvaluator_SurfaceOfRevolution::DN(): theDerU < 0"); Standard_RangeError_Raise_if(theDerV < 0, "GeomEvaluator_SurfaceOfRevolution::DN(): theDerV < 0"); diff --git a/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfRevolution.hxx b/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfRevolution.hxx index 1d2b58831a..0c15c8185b 100644 --- a/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfRevolution.hxx +++ b/src/ModelingData/TKG3d/GeomEvaluator/GeomEvaluator_SurfaceOfRevolution.hxx @@ -45,44 +45,29 @@ public: void SetAxis(const gp_Ax1& theAxis) { myRotAxis = theAxis; } //! Value of surface - Standard_EXPORT void D0(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue) const Standard_OVERRIDE; + //! @return Point value if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D0(const Standard_Real theU, + const Standard_Real theV) const Standard_OVERRIDE; //! Value and first derivatives of surface - Standard_EXPORT void D1(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V) const Standard_OVERRIDE; + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D1(const Standard_Real theU, + const Standard_Real theV) const Standard_OVERRIDE; //! Value, first and second derivatives of surface - Standard_EXPORT void D2(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V, - gp_Vec& theD2U, - gp_Vec& theD2V, - gp_Vec& theD2UV) const Standard_OVERRIDE; + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D2(const Standard_Real theU, + const Standard_Real theV) const Standard_OVERRIDE; //! Value, first, second and third derivatives of surface - Standard_EXPORT void D3(const Standard_Real theU, - const Standard_Real theV, - gp_Pnt& theValue, - gp_Vec& theD1U, - gp_Vec& theD1V, - gp_Vec& theD2U, - gp_Vec& theD2V, - gp_Vec& theD2UV, - gp_Vec& theD3U, - gp_Vec& theD3V, - gp_Vec& theD3UUV, - gp_Vec& theD3UVV) const Standard_OVERRIDE; + //! @return Result structure with point and derivatives if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional D3(const Standard_Real theU, + const Standard_Real theV) const Standard_OVERRIDE; //! Calculates N-th derivatives of surface, where N = theDerU + theDerV. //! //! Raises if N < 1 or theDerU < 0 or theDerV < 0 - Standard_EXPORT gp_Vec DN(const Standard_Real theU, - const Standard_Real theV, - const Standard_Integer theDerU, - const Standard_Integer theDerV) const Standard_OVERRIDE; + //! @return Derivative vector if calculation succeeds, std::nullopt otherwise + Standard_EXPORT std::optional DN(const Standard_Real theU, + const Standard_Real theV, + const Standard_Integer theDerU, + const Standard_Integer theDerV) const Standard_OVERRIDE; Standard_EXPORT Handle(GeomEvaluator_Surface) ShallowCopy() const Standard_OVERRIDE; diff --git a/src/ModelingData/TKG3d/GeomLProp/GeomLProp_SurfaceTool.cxx b/src/ModelingData/TKG3d/GeomLProp/GeomLProp_SurfaceTool.cxx index 37e39c6a53..ad04078258 100644 --- a/src/ModelingData/TKG3d/GeomLProp/GeomLProp_SurfaceTool.cxx +++ b/src/ModelingData/TKG3d/GeomLProp/GeomLProp_SurfaceTool.cxx @@ -19,6 +19,7 @@ #include #include #include +#include void GeomLProp_SurfaceTool::Value(const Handle(Geom_Surface)& S, const Standard_Real U, @@ -59,7 +60,10 @@ gp_Vec GeomLProp_SurfaceTool::DN(const Handle(Geom_Surface)& S, const Standard_Integer IU, const Standard_Integer IV) { - return S->DN(U, V, IU, IV); + if (auto aResult = S->DN(U, V, IU, IV)) + return *aResult; + else + throw Standard_Failure("GeomLProp_SurfaceTool::DN - computation failed"); } Standard_Integer GeomLProp_SurfaceTool::Continuity(const Handle(Geom_Surface)& S)