From 1be4eb79ac470fff9e33c89717e06f73bc115939 Mon Sep 17 00:00:00 2001 From: razmyslovich Date: Fri, 20 Jan 2017 12:59:06 +0100 Subject: [PATCH] 0027903: Patch AdvApp2Var_ApproxAFunc2Var and GeomPlate_MakeApprox to handle the non-uniform approximation parameters: degree, continuity, number of patches --- src/AdvApp2Var/AdvApp2Var_ApproxAFunc2Var.cxx | 373 +++++++++++------ src/AdvApp2Var/AdvApp2Var_ApproxAFunc2Var.hxx | 125 +++++- src/AdvApp2Var/AdvApp2Var_ApproxAFunc2Var.lxx | 5 - src/GeomPlate/GeomPlate_MakeApprox.cxx | 387 ++++++++++-------- src/GeomPlate/GeomPlate_MakeApprox.hxx | 42 +- src/QABugs/QABugs_20.cxx | 184 ++++++++- tests/bugs/modalg_6/bug27903 | 26 ++ 7 files changed, 809 insertions(+), 333 deletions(-) create mode 100644 tests/bugs/modalg_6/bug27903 diff --git a/src/AdvApp2Var/AdvApp2Var_ApproxAFunc2Var.cxx b/src/AdvApp2Var/AdvApp2Var_ApproxAFunc2Var.cxx index 92423d9447..370d7b0707 100644 --- a/src/AdvApp2Var/AdvApp2Var_ApproxAFunc2Var.cxx +++ b/src/AdvApp2Var/AdvApp2Var_ApproxAFunc2Var.cxx @@ -43,6 +43,44 @@ #include #include +AdvApp2Var_ApproxAFunc2Var::AdvApp2Var_ApproxAFunc2Var +( + const Parameters & parameters, + const AdvApp2Var_EvaluatorFunc2Var& Func, + AdvApprox_Cutting& UChoice, + AdvApprox_Cutting& VChoice +): + myParameters (parameters), + myDone (Standard_False), + myHasResult (Standard_False), + myDegreeInU (0), + myDegreeInV (0), + myCriterionError(0.0) +{ + Init(); + Perform(UChoice, VChoice, Func); + ConvertBS(); +} + +AdvApp2Var_ApproxAFunc2Var::AdvApp2Var_ApproxAFunc2Var +( + const Parameters & parameters, + const AdvApp2Var_EvaluatorFunc2Var& Func, + const AdvApp2Var_Criterion& Crit, + AdvApprox_Cutting& UChoice, + AdvApprox_Cutting& VChoice +): + myParameters (parameters), + myDone (Standard_False), + myHasResult (Standard_False), + myDegreeInU (0), + myDegreeInV (0), + myCriterionError(0.0) +{ + Init(); + Perform(UChoice, VChoice, Func, Crit); + ConvertBS(); +} //======================================================================= //function : AdvApp2Var_ApproxAFunc2Var @@ -73,32 +111,41 @@ AdvApp2Var_ApproxAFunc2Var::AdvApp2Var_ApproxAFunc2Var( const AdvApp2Var_EvaluatorFunc2Var& Func, AdvApprox_Cutting& UChoice, AdvApprox_Cutting& VChoice) -: my1DTolerances (OneDTol), - my2DTolerances (TwoDTol), - my3DTolerances (ThreeDTol), - my1DTolOnFront (OneDTolFr), - my2DTolOnFront (TwoDTolFr), - my3DTolOnFront (ThreeDTolFr), - myFirstParInU (FirstInU), - myLastParInU (LastInU), - myFirstParInV (FirstInV), - myLastParInV (LastInV), - myFavoriteIso (FavorIso), - myContInU (ContInU), - myContInV (ContInV), - myPrecisionCode (PrecisCode), - myMaxDegInU (MaxDegInU), - myMaxDegInV (MaxDegInV), - myMaxPatches (MaxPatch), - myDone (Standard_False), +: myDone (Standard_False), myHasResult (Standard_False), myDegreeInU (0), myDegreeInV (0), myCriterionError(0.0) { - myNumSubSpaces[0] = Num1DSS; - myNumSubSpaces[1] = Num2DSS; - myNumSubSpaces[2] = Num3DSS; + myParameters.NumberSubSpaces[0] = Num1DSS; + myParameters.NumberSubSpaces[1] = Num2DSS; + myParameters.NumberSubSpaces[2] = Num3DSS; + + myParameters.Tolerances1D = OneDTol; + myParameters.Tolerances2D = TwoDTol; + myParameters.Tolerances3D = ThreeDTol; + + myParameters.TolerancesOnFrontier1D = OneDTolFr; + myParameters.TolerancesOnFrontier2D = TwoDTolFr; + myParameters.TolerancesOnFrontier3D = ThreeDTolFr; + + myParameters.FirstParamU = FirstInU; + myParameters.FirstParamV = FirstInV; + myParameters.LastParamU = LastInU; + myParameters.LastParamV = LastInV; + + myParameters.FavouriteIso = FavorIso; + + myParameters.ContinuityU = ContInU; + myParameters.ContinuityV = ContInV; + + myParameters.PrecisionCode = PrecisCode; + myParameters.DegreeU = MaxDegInU; + myParameters.DegreeV = MaxDegInV; + + myParameters.MaxPatchesU = myParameters.MaxPatchesV = IntegerLast(); + + myParameters.TotalPatches = MaxPatch; Init(); Perform(UChoice, VChoice, Func); @@ -135,32 +182,41 @@ AdvApp2Var_ApproxAFunc2Var::AdvApp2Var_ApproxAFunc2Var( const AdvApp2Var_Criterion& Crit, AdvApprox_Cutting& UChoice, AdvApprox_Cutting& VChoice) -: my1DTolerances (OneDTol), - my2DTolerances (TwoDTol), - my3DTolerances (ThreeDTol), - my1DTolOnFront (OneDTolFr), - my2DTolOnFront (TwoDTolFr), - my3DTolOnFront (ThreeDTolFr), - myFirstParInU (FirstInU), - myLastParInU (LastInU), - myFirstParInV (FirstInV), - myLastParInV (LastInV), - myFavoriteIso (FavorIso), - myContInU (ContInU), - myContInV (ContInV), - myPrecisionCode (PrecisCode), - myMaxDegInU (MaxDegInU), - myMaxDegInV (MaxDegInV), - myMaxPatches (MaxPatch), - myDone (Standard_False), +: myDone (Standard_False), myHasResult (Standard_False), myDegreeInU (0), myDegreeInV (0), myCriterionError(0.0) { - myNumSubSpaces[0] = Num1DSS; - myNumSubSpaces[1] = Num2DSS; - myNumSubSpaces[2] = Num3DSS; + myParameters.NumberSubSpaces[0] = Num1DSS; + myParameters.NumberSubSpaces[1] = Num2DSS; + myParameters.NumberSubSpaces[2] = Num3DSS; + + myParameters.Tolerances1D = OneDTol; + myParameters.Tolerances2D = TwoDTol; + myParameters.Tolerances3D = ThreeDTol; + + myParameters.TolerancesOnFrontier1D = OneDTolFr; + myParameters.TolerancesOnFrontier2D = TwoDTolFr; + myParameters.TolerancesOnFrontier3D = ThreeDTolFr; + + myParameters.FirstParamU = FirstInU; + myParameters.FirstParamV = FirstInV; + myParameters.LastParamU = LastInU; + myParameters.LastParamV = LastInV; + + myParameters.FavouriteIso = FavorIso; + + myParameters.ContinuityU = ContInU; + myParameters.ContinuityV = ContInV; + + myParameters.PrecisionCode = PrecisCode; + myParameters.DegreeU = MaxDegInU; + myParameters.DegreeV = MaxDegInV; + + myParameters.MaxPatchesU = myParameters.MaxPatchesV = IntegerLast(); + + myParameters.TotalPatches = MaxPatch; Init(); Perform(UChoice, VChoice, Func, Crit); @@ -175,7 +231,7 @@ AdvApp2Var_ApproxAFunc2Var::AdvApp2Var_ApproxAFunc2Var( void AdvApp2Var_ApproxAFunc2Var::Init() { Standard_Integer ifav,iu=0,iv=0,ndu,ndv; - switch (myFavoriteIso) { + switch (myParameters.FavouriteIso) { case GeomAbs_IsoU : ifav = 1; break; @@ -186,7 +242,7 @@ void AdvApp2Var_ApproxAFunc2Var::Init() ifav = 2; break; } - switch (myContInU) { + switch (myParameters.ContinuityU) { case GeomAbs_C0 : iu = 0; break; @@ -199,7 +255,7 @@ void AdvApp2Var_ApproxAFunc2Var::Init() default : Standard_ConstructionError::Raise("AdvApp2Var_ApproxAFunc2Var : UContinuity Error"); } - switch (myContInV) { + switch (myParameters.ContinuityV) { case GeomAbs_C0 : iv = 0; break; @@ -212,26 +268,27 @@ void AdvApp2Var_ApproxAFunc2Var::Init() default : Standard_ConstructionError::Raise("AdvApp2Var_ApproxAFunc2Var : VContinuity Error"); } - ndu = Max(myMaxDegInU+1,2*iu+2); - ndv = Max(myMaxDegInV+1,2*iv+2); + ndu = Max(myParameters.DegreeU+1,2*iu+2); + ndv = Max(myParameters.DegreeV+1,2*iv+2); if (ndu<2*iu+2) Standard_ConstructionError::Raise("AdvApp2Var_ApproxAFunc2Var : UMaxDegree Error"); if (ndv<2*iv+2) Standard_ConstructionError::Raise("AdvApp2Var_ApproxAFunc2Var : VMaxDegree Error"); - myPrecisionCode = Max(0,Min(myPrecisionCode,3)); + myParameters.PrecisionCode = Max(0,Min(myParameters.PrecisionCode,3)); AdvApp2Var_Context Conditions(ifav,iu,iv,ndu,ndv, - myPrecisionCode, - myNumSubSpaces[0], - myNumSubSpaces[1], - myNumSubSpaces[2], - my1DTolerances, - my2DTolerances, - my3DTolerances, - my1DTolOnFront, - my2DTolOnFront, - my3DTolOnFront); + myParameters.PrecisionCode, + myParameters.NumberSubSpaces[0], + myParameters.NumberSubSpaces[1], + myParameters.NumberSubSpaces[2], + myParameters.Tolerances1D, + myParameters.Tolerances2D, + myParameters.Tolerances3D, + myParameters.TolerancesOnFrontier1D, + myParameters.TolerancesOnFrontier2D, + myParameters.TolerancesOnFrontier3D + ); myConditions = Conditions; - InitGrid(1); + InitGrid(1, 1); } @@ -240,50 +297,50 @@ void AdvApp2Var_ApproxAFunc2Var::Init() //purpose : Initialisation of the approximation with regular cuttings //======================================================================= -void AdvApp2Var_ApproxAFunc2Var::InitGrid(const Standard_Integer NbInt) +void AdvApp2Var_ApproxAFunc2Var::InitGrid(const Standard_Integer sizeU, const Standard_Integer sizeV) { - Standard_Integer iu=myConditions.UOrder(),iv=myConditions.VOrder(),iint; + Standard_Integer iu=myConditions.UOrder(),iv=myConditions.VOrder(); - AdvApp2Var_Patch M0(myFirstParInU,myLastParInU,myFirstParInV,myLastParInV,iu,iv); + AdvApp2Var_Patch M0(myParameters.FirstParamU, myParameters.LastParamU, myParameters.FirstParamV, myParameters.LastParamV,iu,iv); AdvApp2Var_SequenceOfPatch Net; Net.Append(M0); TColStd_SequenceOfReal TheU,TheV; - TheU.Append(myFirstParInU); - TheV.Append(myFirstParInV); - TheU.Append(myLastParInU); - TheV.Append(myLastParInV); + TheU.Append(myParameters.FirstParamU); + TheV.Append(myParameters.FirstParamV); + TheU.Append(myParameters.LastParamU); + TheV.Append(myParameters.LastParamV); AdvApp2Var_Network Result(Net,TheU,TheV); + gp_XY UV1 (myParameters.FirstParamU, myParameters.FirstParamV); + AdvApp2Var_Node C1 (UV1, iu, iv); + gp_XY UV2 (myParameters.LastParamU, myParameters.FirstParamV); + AdvApp2Var_Node C2 (UV2, iu, iv); + gp_XY UV3 (myParameters.FirstParamU, myParameters.LastParamV); + AdvApp2Var_Node C3 (UV3, iu, iv); + gp_XY UV4 (myParameters.LastParamU, myParameters.LastParamV); + AdvApp2Var_Node C4 (UV4, iu, iv); - gp_XY UV1(myFirstParInU,myFirstParInV); - AdvApp2Var_Node C1(UV1,iu,iv); - gp_XY UV2(myLastParInU,myFirstParInV); - AdvApp2Var_Node C2(UV2,iu,iv); - gp_XY UV4(myLastParInU,myLastParInV); - AdvApp2Var_Node C4(UV4,iu,iv); - gp_XY UV3(myFirstParInU,myLastParInV); - AdvApp2Var_Node C3(UV3,iu,iv); AdvApp2Var_SequenceOfNode Bag; Bag.Append(C1); Bag.Append(C2); Bag.Append(C3); Bag.Append(C4); - AdvApp2Var_Iso V0(GeomAbs_IsoV,myFirstParInV, - myFirstParInU,myLastParInU,myFirstParInV,myLastParInV, - 1,iu,iv); - AdvApp2Var_Iso V1(GeomAbs_IsoV,myLastParInV, - myFirstParInU,myLastParInU,myFirstParInV,myLastParInV, - 2,iu,iv); - AdvApp2Var_Iso U0(GeomAbs_IsoU,myFirstParInU, - myFirstParInU,myLastParInU,myFirstParInV,myLastParInV, - 3,iu,iv); - AdvApp2Var_Iso U1(GeomAbs_IsoU,myLastParInU, - myFirstParInU,myLastParInU,myFirstParInV,myLastParInV, - 4,iu,iv); + AdvApp2Var_Iso V0(GeomAbs_IsoV,myParameters.FirstParamV, + myParameters.FirstParamU,myParameters.LastParamU,myParameters.FirstParamV,myParameters.LastParamV, + 1,iu,iv); + AdvApp2Var_Iso V1(GeomAbs_IsoV,myParameters.LastParamV, + myParameters.FirstParamU,myParameters.LastParamU,myParameters.FirstParamV,myParameters.LastParamV, + 2,iu,iv); + AdvApp2Var_Iso U0(GeomAbs_IsoU,myParameters.FirstParamU, + myParameters.FirstParamU,myParameters.LastParamU,myParameters.FirstParamV,myParameters.LastParamV, + 3,iu,iv); + AdvApp2Var_Iso U1(GeomAbs_IsoU,myParameters.LastParamU, + myParameters.FirstParamU,myParameters.LastParamU,myParameters.FirstParamV,myParameters.LastParamV, + 4,iu,iv); AdvApp2Var_Strip BU0,BV0; BU0.Append(V0); @@ -295,16 +352,24 @@ void AdvApp2Var_ApproxAFunc2Var::InitGrid(const Standard_Integer NbInt) UStrip.Append(BU0); VStrip.Append(BV0); - AdvApp2Var_Framework Constraints(Bag,UStrip,VStrip); + AdvApp2Var_Framework Constraints(Bag, UStrip, VStrip); -// regular cutting if NbInt>1 - Standard_Real deltu = (myLastParInU-myFirstParInU)/NbInt, - deltv = (myLastParInV-myFirstParInV)/NbInt; - for (iint=1;iint<=NbInt-1;iint++) { - Result.UpdateInU(myFirstParInU+iint*deltu); - Constraints.UpdateInU(myFirstParInU+iint*deltu); - Result.UpdateInV(myFirstParInV+iint*deltv); - Constraints.UpdateInV(myFirstParInV+iint*deltv); + { + Standard_Real deltaU = (myParameters.LastParamU - myParameters.FirstParamU)/sizeU; + for (Standard_Integer i = 1; i < sizeU; ++i) + { + Result.UpdateInU(myParameters.FirstParamU + i * deltaU); + Constraints.UpdateInU(myParameters.FirstParamU + i * deltaU); + } + } + + { + Standard_Real deltaV = (myParameters.LastParamV - myParameters.FirstParamV)/sizeV; + for (Standard_Integer i = 1; i < sizeV; ++i) + { + Result.UpdateInV(myParameters.FirstParamV + i * deltaV); + Constraints.UpdateInV(myParameters.FirstParamV + i * deltaV); + } } myResult = Result; myConstraints = Constraints; @@ -375,16 +440,25 @@ void AdvApp2Var_ApproxAFunc2Var::ComputePatches(const AdvApprox_Cutting& UChoice Umore = UChoice.Value(myResult(FirstNA).U0(), myResult(FirstNA).U1(),Udec); Vmore = VChoice.Value(myResult(FirstNA).V0(), myResult(FirstNA).V1(),Vdec); + if (NbU >= myParameters.MaxPatchesU) + { + Umore = Standard_False; + } + if (NbV >= myParameters.MaxPatchesV) + { + Vmore = Standard_False; + } + NumDec = 0; - if ( ((NbPatch+NbV)<=myMaxPatches) && ((NbPatch+NbU)>myMaxPatches) + if ( ((NbPatch+NbV)<=myParameters.TotalPatches) && ((NbPatch+NbU)>myParameters.TotalPatches) && (Umore) ) NumDec = 1; - if ( ((NbPatch+NbV)>myMaxPatches) && ((NbPatch+NbU)<=myMaxPatches) + if ( ((NbPatch+NbV)>myParameters.TotalPatches) && ((NbPatch+NbU)<=myParameters.TotalPatches) && (Vmore) ) NumDec = 2; - if ( ((NbPatch+NbV)<=myMaxPatches) && ((NbPatch+NbU)<=myMaxPatches) ) { + if ( ((NbPatch+NbV)<=myParameters.TotalPatches) && ((NbPatch+NbU)<=myParameters.TotalPatches) ) { if ( Umore ) NumDec = 3; if ( (NbV>NbU) && Vmore ) NumDec = 4; } - if ( (NbU+1)*(NbV+1)<=myMaxPatches ) { + if ( (NbU+1)*(NbV+1)<=myParameters.TotalPatches ) { if ( !Umore && !Vmore ) NumDec=0; if ( Umore && !Vmore ) NumDec=3; if ( !Umore && Vmore ) NumDec=4; @@ -472,17 +546,24 @@ void AdvApp2Var_ApproxAFunc2Var::ComputePatches(const AdvApprox_Cutting& UChoice NbInt = NbU; Umore = UChoice.Value(myResult(FirstNA).U0(), myResult(FirstNA).U1(),Udec); Vmore = VChoice.Value(myResult(FirstNA).V0(), myResult(FirstNA).V1(),Vdec); - + if (NbU >= myParameters.MaxPatchesU) + { + Umore = Standard_False; + } + if (NbV >= myParameters.MaxPatchesV) + { + Vmore = Standard_False; + } NumDec = 0; - if ( ((NbPatch+NbV)<=myMaxPatches) && ((NbPatch+NbU)>myMaxPatches) + if ( ((NbPatch+NbV)<=myParameters.TotalPatches) && ((NbPatch+NbU)>myParameters.TotalPatches) && (Umore) ) NumDec = 1; - if ( ((NbPatch+NbV)>myMaxPatches) && ((NbPatch+NbU)<=myMaxPatches) + if ( ((NbPatch+NbV)>myParameters.TotalPatches) && ((NbPatch+NbU)<=myParameters.TotalPatches) && (Vmore) ) NumDec = 2; - if ( ((NbPatch+NbV)<=myMaxPatches) && ((NbPatch+NbU)<=myMaxPatches) ) { + if ( ((NbPatch+NbV)<=myParameters.TotalPatches) && ((NbPatch+NbU)<=myParameters.TotalPatches) ) { if ( Umore ) NumDec = 3; if ( (NbV>NbU) && Vmore ) NumDec = 4; } - if ( (NbU+1)*(NbV+1)<=myMaxPatches ) { + if ( (NbU+1)*(NbV+1)<=myParameters.TotalPatches ) { if ( !Umore && !Vmore ) NumDec=0; if ( Umore && !Vmore ) NumDec=1; if ( !Umore && Vmore ) NumDec=2; @@ -509,8 +590,19 @@ void AdvApp2Var_ApproxAFunc2Var::ComputePatches(const AdvApprox_Cutting& UChoice Standard_Boolean Regular = (Crit.Repartition() == AdvApp2Var_Regular); // Standard_Boolean Regular = Standard_True; if (Regular && decision>0) { - NbInt++; - InitGrid(NbInt); + switch (decision) + { + case 1: ++NbU; break; + case 2: ++NbV; break; + case 3: ++NbU; ++NbV; break; + default: + { + myHasResult = myDone = Standard_False; + Standard_ConstructionError::Raise ("AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error"); + } + } + + InitGrid(NbU, NbV); } else { switch (decision) { @@ -577,8 +669,8 @@ void AdvApp2Var_ApproxAFunc2Var::ComputeConstraints(const AdvApprox_Cutting& UCh N2 = myConstraints.Node(indN2); Is.MakeApprox(myConditions, - myFirstParInU, myLastParInU, - myFirstParInV, myLastParInV, + myParameters.FirstParamU, myParameters.LastParamU, + myParameters.FirstParamV, myParameters.LastParamV, Func, N1 , N2); if (Is.IsApproximated()) { @@ -595,13 +687,15 @@ void AdvApp2Var_ApproxAFunc2Var::ComputeConstraints(const AdvApprox_Cutting& UCh if (Is.Type()==GeomAbs_IsoV) { NbPatch = (NbU+1)*NbV; more = UChoice.Value(Is.T0(),Is.T1(),dec); + more = more && (NbU < myParameters.MaxPatchesU); } else { NbPatch = (NbV+1)*NbU; more = VChoice.Value(Is.T0(),Is.T1(),dec); + more = more && (NbU < myParameters.MaxPatchesV); } - if (NbPatch<=myMaxPatches && more) { + if (NbPatch<=myParameters.TotalPatches && more) { // It is possible to cut iso if (Is.Type()==GeomAbs_IsoV) { myResult.UpdateInU(dec); @@ -659,8 +753,8 @@ void AdvApp2Var_ApproxAFunc2Var::ComputeConstraints(const AdvApprox_Cutting& UCh N2 = myConstraints.Node(indN2); Is.MakeApprox(myConditions, - myFirstParInU, myLastParInU, - myFirstParInV, myLastParInV, + myParameters.FirstParamU, myParameters.LastParamU, + myParameters.FirstParamV, myParameters.LastParamV, Func, N1 , N2); if (Is.IsApproximated()) { @@ -677,16 +771,18 @@ void AdvApp2Var_ApproxAFunc2Var::ComputeConstraints(const AdvApprox_Cutting& UCh if (Is.Type()==GeomAbs_IsoV) { NbPatch = (NbU+1)*NbV; more = UChoice.Value(Is.T0(),Is.T1(),dec); + more = more && (NbU < myParameters.MaxPatchesU); } else { NbPatch = (NbV+1)*NbU; more = VChoice.Value(Is.T0(),Is.T1(),dec); + more = more && (NbU < myParameters.MaxPatchesU); } // To force Overwrite if the criterion is Absolute more = more && (CritRel); - if (NbPatch<=myMaxPatches && more) { + if (NbPatch<=myParameters.TotalPatches && more) { // It is possible to cut iso if (Is.Type()==GeomAbs_IsoV) { myResult.UpdateInU(dec); @@ -727,23 +823,23 @@ void AdvApp2Var_ApproxAFunc2Var::Compute3DErrors() Standard_Integer iesp,ipat; Standard_Real error_max,error_moy,error_U0,error_V0,error_U1,error_V1; Standard_Real Tol,F1Tol,F2Tol,F3Tol,F4Tol; - if ( myNumSubSpaces[2] > 0 ) { - my3DMaxError = new (TColStd_HArray1OfReal) (1,myNumSubSpaces[2]); - my3DAverageError = new (TColStd_HArray1OfReal) (1,myNumSubSpaces[2]); - my3DUFrontError = new (TColStd_HArray1OfReal) (1,myNumSubSpaces[2]); - my3DVFrontError = new (TColStd_HArray1OfReal) (1,myNumSubSpaces[2]); - for (iesp=1;iesp<=myNumSubSpaces[2];iesp++) { + if ( myParameters.NumberSubSpaces[2] > 0 ) { + my3DMaxError = new (TColStd_HArray1OfReal) (1,myParameters.NumberSubSpaces[2]); + my3DAverageError = new (TColStd_HArray1OfReal) (1,myParameters.NumberSubSpaces[2]); + my3DUFrontError = new (TColStd_HArray1OfReal) (1,myParameters.NumberSubSpaces[2]); + my3DVFrontError = new (TColStd_HArray1OfReal) (1,myParameters.NumberSubSpaces[2]); + for (iesp=1;iesp<=myParameters.NumberSubSpaces[2];iesp++) { error_max = 0; error_moy = 0.; error_U0 = 0.; error_V0 = 0.; error_U1 = 0.; error_V1 = 0.; - Tol = my3DTolerances->Value(iesp); - F1Tol = my3DTolOnFront->Value(iesp,1); - F2Tol = my3DTolOnFront->Value(iesp,2); - F3Tol = my3DTolOnFront->Value(iesp,3); - F4Tol = my3DTolOnFront->Value(iesp,4); + Tol = myParameters.Tolerances3D->Value(iesp); + F1Tol = myParameters.TolerancesOnFrontier3D->Value(iesp,1); + F2Tol = myParameters.TolerancesOnFrontier3D->Value(iesp,2); + F3Tol = myParameters.TolerancesOnFrontier3D->Value(iesp,3); + F4Tol = myParameters.TolerancesOnFrontier3D->Value(iesp,4); for (ipat=1;ipat<=myResult.NbPatch();ipat++) { error_max = Max((myResult(ipat).MaxErrors())->Value(iesp),error_max); error_U0 = Max((myResult(ipat).IsoErrors())->Value(iesp,3),error_U0); @@ -777,8 +873,8 @@ void AdvApp2Var_ApproxAFunc2Var::ComputeCritError() Standard_Integer iesp,ipat; Standard_Real crit_max; - if ( myNumSubSpaces[2] > 0 ) { - for (iesp=1;iesp<=myNumSubSpaces[2];iesp++) { + if ( myParameters.NumberSubSpaces[2] > 0 ) { + for (iesp=1;iesp<=myParameters.NumberSubSpaces[2];iesp++) { crit_max = 0.; for (ipat=1;ipat<=myResult.NbPatch();ipat++) { crit_max = Max((myResult(ipat).CritValue()),crit_max); @@ -803,7 +899,7 @@ void AdvApp2Var_ApproxAFunc2Var::ConvertBS() myDegreeInV = ncfv - 1; // Calculate resulting surfaces - mySurfaces = new ( TColGeom_HArray1OfSurface) (1, myNumSubSpaces[2]); + mySurfaces = new ( TColGeom_HArray1OfSurface) (1, myParameters.NumberSubSpaces[2]); Standard_Integer j; TColStd_Array1OfReal UKnots (1, myResult.NbPatchInU()+1); @@ -838,7 +934,7 @@ void AdvApp2Var_ApproxAFunc2Var::ConvertBS() new (TColStd_HArray1OfReal) (1, nmax * Size_eq); Standard_Integer SSP, i; - for (SSP=1; SSP <= myNumSubSpaces[2]; SSP++) { + for (SSP=1; SSP <= myParameters.NumberSubSpaces[2]; SSP++) { // Creation of the grid of polynoms Standard_Integer n=0,icf=1,ieq; @@ -857,7 +953,7 @@ void AdvApp2Var_ApproxAFunc2Var::ConvertBS() // Conversion into poles Convert_GridPolynomialToPoles CvP (myResult.NbPatchInU(),myResult.NbPatchInV(), - iu,iv,myMaxDegInU,myMaxDegInV,NbCoeff, + iu,iv,myParameters.DegreeU,myParameters.DegreeV,NbCoeff, Poly,Uint1,Vint1,Uint2,Vint2); if ( !CvP.IsDone() ) { myDone = Standard_False; } @@ -870,6 +966,21 @@ void AdvApp2Var_ApproxAFunc2Var::ConvertBS() } } +//======================================================================= +//function : NumSubSpaces +//purpose : +//======================================================================= + +Standard_Integer +AdvApp2Var_ApproxAFunc2Var::NumSubSpaces(const Standard_Integer Dimension) const +{ + if (Dimension < 1 || Dimension > 3) + { + Standard_OutOfRange::Raise ("AdvApp2Var_ApproxAFunc2Var::MaxError : Dimension must be equal to 1,2 or 3 !"); + } + return myParameters.NumberSubSpaces[Dimension-1]; +} + //======================================================================= //function : MaxError //purpose : @@ -1076,10 +1187,10 @@ void AdvApp2Var_ApproxAFunc2Var::Dump(Standard_OStream& o) const else { o<<"There is a result"; if (myDone) { - o<<" within the requested tolerance "<Value(iesp)<Value(iesp)<Value(iesp)>my3DTolerances->Value(iesp)) { - o<<" WITHOUT the requested tolerance "<Value(iesp)<Value(iesp)>myParameters.Tolerances3D->Value(iesp)) { + o<<" WITHOUT the requested tolerance "<Value(iesp)<RealBounds(U0, U1, V0, V1); - U0 = EnlargeCoeff * U0; - U1 = EnlargeCoeff * U1; - V0 = EnlargeCoeff * V0; - V1 = EnlargeCoeff * V1; - - Standard_Integer nb1 = 0, nb2 = 0, nb3 = 1; - Handle(TColStd_HArray1OfReal) nul1 = - new TColStd_HArray1OfReal(1,1); - nul1->Init(0.); - Handle(TColStd_HArray2OfReal) nul2 = - new TColStd_HArray2OfReal(1,1,1,4); - nul2->Init(0.); - Handle(TColStd_HArray1OfReal) eps3D = - new TColStd_HArray1OfReal(1,1); - eps3D->Init(Tol3d); - Handle(TColStd_HArray2OfReal) epsfr = - new TColStd_HArray2OfReal(1,1,1,4); - epsfr->Init(Tol3d); - GeomAbs_IsoType myType = GeomAbs_IsoV; - Standard_Integer myPrec = 0; + Parameters parameters; - AdvApprox_DichoCutting myDec; + parameters.Tolerance3D = Tol3d; + parameters.ContinuityU = parameters.ContinuityV = Continuity; + parameters.DegreeU = parameters.DegreeV = dgmax; + parameters.MaxPatchesU = parameters.MaxPatchesV = IntegerLast(); + parameters.TotalPatches = Nbmax; -//POP pour WNT - GeomPlate_MakeApprox_Eval ev (myPlate); - AdvApp2Var_ApproxAFunc2Var AppPlate(nb1, nb2, nb3, - nul1,nul1,eps3D, - nul2,nul2,epsfr, - U0,U1,V0,V1, - myType, - Continuity, Continuity, - myPrec, - dgmax,dgmax,Nbmax,ev, -// dgmax,dgmax,Nbmax,myPlateSurfEval, - PlateCrit,myDec,myDec); - mySurface = AppPlate.Surface(1); - myAppError = AppPlate.MaxError(3,1); - myCritError = AppPlate.CritError(3,1); -#ifdef OCCT_DEBUG - cout<<"Approximation results"<=0) { - -// contraintes 2d d'ordre 0 - myPlate->Constraints(Seq2d); - -// contraintes 3d correspondantes sur plate - Standard_Integer i,nbp=Seq2d.Length(); - for(i=1;i<=nbp;i++){ - gp_XY P2d=Seq2d.Value(i); - gp_Pnt PP; - gp_Vec v1h,v2h,v3h; - 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); - } - 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); - } - } + Parameters parameters; + + parameters.Tolerance3D = Tol3d; + parameters.ContinuityU = parameters.ContinuityV = Continuity; + parameters.DegreeU = parameters.DegreeV = dgmax; + parameters.MaxPatchesU = parameters.MaxPatchesV = IntegerLast(); + parameters.TotalPatches = Nbmax; + + Perform(parameters, CritOrder, dmax, EnlargeCoeff); +} + +//======================================================================= +//function : Perform +//purpose : +//======================================================================= +void GeomPlate_MakeApprox::Perform +( + const Parameters & parameters, + const Standard_Integer CritOrder, + const Standard_Real dmax, + const Standard_Real EnlargeCoeff +) +{ + if (myPlate.IsNull() || CritOrder > 1) + { + return; } - Standard_Real U0=0., U1=0., V0=0., V1=0.; - myPlate->RealBounds(U0, U1, V0, V1); - U0 = EnlargeCoeff * U0; - U1 = EnlargeCoeff * U1; - V0 = EnlargeCoeff * V0; - V1 = EnlargeCoeff * V1; + AdvApp2Var_Criterion * criterion = nullptr; + + if (CritOrder >= 0) + { + TColgp_SequenceOfXY Seq2d; + TColgp_SequenceOfXYZ Seq3d; + + { + // contraintes 2d d'ordre 0 + myPlate->Constraints(Seq2d); + + // contraintes 3d correspondantes sur plate + for(Standard_Integer i = 1; i <= Seq2d.Length(); ++i) + { + gp_XY P2d=Seq2d.Value(i); + gp_Pnt PP; + gp_Vec v1h,v2h,v3h; + 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); + } + 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); + } + } + } - Standard_Real seuil = Tol3d; - if (CritOrder==0&&Tol3d<10*dmax) { - seuil=10*dmax; + Standard_Real seuil = parameters.Tolerance3D; + if (parameters.Tolerance3D < 10 * dmax) + { + seuil = 10 * dmax; #ifdef OCCT_DEBUG - cout<<"Seuil G0 choisi trop faible par rapport au contour. On prend "<Init(0.); - Handle(TColStd_HArray2OfReal) nul2 = - new TColStd_HArray2OfReal(1,1,1,4); - nul2->Init(0.); - Handle(TColStd_HArray1OfReal) eps3D = - new TColStd_HArray1OfReal(1,1); - eps3D->Init(Tol3d); - Handle(TColStd_HArray2OfReal) epsfr = - new TColStd_HArray2OfReal(1,1,1,4); - epsfr->Init(Tol3d); - - GeomAbs_IsoType myType = GeomAbs_IsoV; - Standard_Integer myPrec = 0; + + AdvApp2Var_ApproxAFunc2Var::Parameters approxParameters; + + approxParameters.NumberSubSpaces[0] = 0; + approxParameters.NumberSubSpaces[1] = 0; + approxParameters.NumberSubSpaces[2] = 1; + + { + Standard_Real U0=0., U1=0., V0=0., V1=0.; + myPlate->RealBounds(U0, U1, V0, V1); + + approxParameters.FirstParamU = EnlargeCoeff * U0; + approxParameters.LastParamU = EnlargeCoeff * U1; + approxParameters.FirstParamV = EnlargeCoeff * V0; + approxParameters.LastParamV = EnlargeCoeff * V1; + } + + { + Handle(TColStd_HArray1OfReal) nul1 = new TColStd_HArray1OfReal(1,1); + nul1->Init(0.); + Handle(TColStd_HArray2OfReal) nul2 = new TColStd_HArray2OfReal(1,1,1,4); + nul2->Init(0.); + Handle(TColStd_HArray1OfReal) eps3D = new TColStd_HArray1OfReal(1,1); + eps3D->Init(parameters.Tolerance3D); + Handle(TColStd_HArray2OfReal) epsfr = new TColStd_HArray2OfReal(1,1,1,4); + epsfr->Init(parameters.Tolerance3D); + + approxParameters.Tolerances1D = nul1; + approxParameters.Tolerances2D = nul1; + approxParameters.Tolerances3D = eps3D; + + approxParameters.TolerancesOnFrontier1D = nul2; + approxParameters.TolerancesOnFrontier2D = nul2; + approxParameters.TolerancesOnFrontier3D = epsfr; + } + + approxParameters.FavouriteIso = GeomAbs_IsoV; + + approxParameters.ContinuityU = parameters.ContinuityU; + approxParameters.ContinuityV = parameters.ContinuityV; + + approxParameters.PrecisionCode = 0; + + approxParameters.DegreeU = parameters.DegreeU; + approxParameters.DegreeV = parameters.DegreeV; + + approxParameters.MaxPatchesU = parameters.MaxPatchesU; + approxParameters.MaxPatchesV = parameters.MaxPatchesV; + + approxParameters.TotalPatches = parameters.TotalPatches; AdvApprox_DichoCutting myDec; + GeomPlate_MakeApprox_Eval ev (myPlate); + + if (nullptr == criterion) + { + approxParameters.PrecisionCode = 1; + + AdvApp2Var_ApproxAFunc2Var AppPlate + ( + approxParameters, + ev, + myDec, myDec + ); - if (CritOrder==-1) { - myPrec = 1; -// POP pour NT - GeomPlate_MakeApprox_Eval ev (myPlate); - AdvApp2Var_ApproxAFunc2Var AppPlate(nb1, nb2, nb3, - nul1,nul1,eps3D, - nul2,nul2,epsfr, - U0,U1,V0,V1, - myType, - Continuity, Continuity, - myPrec, - dgmax,dgmax,Nbmax,ev, - myDec,myDec); mySurface = AppPlate.Surface(1); myAppError = AppPlate.MaxError(3,1); myCritError = 0.; -#ifdef OCCT_DEBUG - cout<<"Approximation results"< +#include +#include +#include +#include +#include +#include +#include +static Standard_Integer OCC27903(Draw_Interpretor& theDI, + Standard_Integer n, + const char ** a) +{ + /* + This test code is a copy-paste of the gplate code, but with the added arguments for the degree, continuity and segments count + */ + if ( n < 13 ) + { + theDI << "Not enough arguments\n"; + return 1; + } + + Standard_Integer NbCurFront = Draw::Atoi(a[9]); + Standard_Integer NbPointConstraint = Draw::Atoi(a[10]); + + GeomPlate_BuildPlateSurface Henri(3, 15, 2); + + Standard_Integer Indice=11; + + { + TopoDS_Shape aLocalFace (DBRep::Get(a[Indice++],TopAbs_FACE)); + TopoDS_Face SI = TopoDS::Face(aLocalFace); + if(SI.IsNull()) + { + theDI << "Wrong arguments\n"; + return 1; + } + + { + Handle(BRepAdaptor_HSurface) HSI = new BRepAdaptor_HSurface(); + HSI->ChangeSurface().Initialize(SI); + Henri.LoadInitSurface( BRep_Tool::Surface(HSI->ChangeSurface().Face())); + } + } + + for (Standard_Integer i=1; i<=NbCurFront ; i++) + { + TopoDS_Shape aLocalShape(DBRep::Get(a[Indice++],TopAbs_EDGE)); + TopoDS_Edge E = TopoDS::Edge(aLocalShape); + + if(E.IsNull()) + { + theDI << "Wrong arguments\n"; + return 1; + } + + Standard_Integer Conti=Draw::Atoi(a[Indice++]); + if (Conti==0 || Conti==-1) + { + Handle(BRepAdaptor_HCurve) C = new BRepAdaptor_HCurve(); + C->ChangeCurve().Initialize(E); + const Handle(Adaptor3d_HCurve)& aC = C; // to avoid ambiguity + Handle(GeomPlate_CurveConstraint) Cont= new BRepFill_CurveConstraint(aC,Conti); + Henri.Add(Cont); + } + else + { + TopoDS_Shape aLocalFace = DBRep::Get(a[Indice++],TopAbs_FACE); + TopoDS_Face F = TopoDS::Face(aLocalFace); + + if(F.IsNull()) + { + theDI << "Wrong arguments\n"; + return 1; + } + Handle(BRepAdaptor_HSurface) S = new BRepAdaptor_HSurface(); + S->ChangeSurface().Initialize(F); + Handle(BRepAdaptor_HCurve2d) C = new BRepAdaptor_HCurve2d(); + C->ChangeCurve2d().Initialize(E,F); + Adaptor3d_CurveOnSurface ConS(C,S); + + Handle (Adaptor3d_HCurveOnSurface) HConS = new Adaptor3d_HCurveOnSurface(ConS); + Handle(GeomPlate_CurveConstraint) Cont= new BRepFill_CurveConstraint(HConS,Conti); + Henri.Add(Cont); + } + } + + for (Standard_Integer i=1; i<=NbPointConstraint ; i++) + { + gp_Pnt P1; + + if (DrawTrSurf::GetPoint(a[Indice], P1) ) + { + Handle(GeomPlate_PointConstraint) PCont = new GeomPlate_PointConstraint(P1,0); + Henri.Add(PCont); + Indice++; + } + else + { + Standard_Real u=Draw::Atof(a[Indice++]), + v=Draw::Atof(a[Indice++]); + + Standard_Integer Conti=Draw::Atoi(a[Indice++]); + TopoDS_Shape aLocalFace = DBRep::Get(a[Indice++],TopAbs_FACE); + TopoDS_Face F = TopoDS::Face(aLocalFace); + + if(F.IsNull()) + { + theDI << "Wrong arguments\n"; + return 1; + } + + Handle(BRepAdaptor_HSurface) HF = new BRepAdaptor_HSurface(); + HF->ChangeSurface().Initialize(F); + Handle(GeomPlate_PointConstraint) PCont= new GeomPlate_PointConstraint(u,v,BRep_Tool::Surface(HF->ChangeSurface().Face()),Conti,0.001,0.001,0.001); + Henri.Add(PCont); + } + } + + Henri.Perform(); + + Handle(GeomPlate_Surface) gpPlate = Henri.Surface(); + TColgp_SequenceOfXY S2d; + TColgp_SequenceOfXYZ S3d; + S2d.Clear(); + S3d.Clear(); + Henri.Disc2dContour(4,S2d); + Henri.Disc3dContour(4,0,S3d); + Standard_Real seuil = Max(0.0001, 10 * Henri.G0Error()); + GeomPlate_PlateG0Criterion critere (S2d, S3d, seuil); + + Standard_Integer nbcarreau=9; + Standard_Integer degmax=8; + + GeomPlate_MakeApprox::Parameters params; + Standard_Integer continuity = Draw::Atoi(a[4]); + switch (continuity) + { + case 0: params.ContinuityU = GeomAbs_C0; break; + case 1: params.ContinuityU = GeomAbs_C1; break; + case 2: params.ContinuityU = GeomAbs_C2; break; + case 3: params.ContinuityU = GeomAbs_C3; break; + default: params.ContinuityU = GeomAbs_CN; break; + } + continuity = Draw::Atoi(a[5]); + switch (continuity) + { + case 0: params.ContinuityV = GeomAbs_C0; break; + case 1: params.ContinuityV = GeomAbs_C1; break; + case 2: params.ContinuityV = GeomAbs_C2; break; + case 3: params.ContinuityV = GeomAbs_C3; break; + default: params.ContinuityV = GeomAbs_CN; break; + } + + params.DegreeU = Draw::Atoi(a[2]); + params.DegreeV = Draw::Atoi(a[3]); + + params.MaxPatchesU = Draw::Atoi(a[6]); + params.MaxPatchesV = Draw::Atoi(a[7]); + + params.TotalPatches = Draw::Atoi(a[8]); + + params.Tolerance3D = 0.0001; + + GeomPlate_MakeApprox approx (gpPlate, critere, params); + Handle (Geom_BSplineSurface) bspline (approx.Surface()); + + if (bspline.IsNull()) + { + theDI << "GeomPlate_MakeApprox is not done.\n"; + } + + { + Standard_Real Umin, Umax, Vmin, Vmax; + Henri.Surface()->Bounds( Umin, Umax, Vmin, Vmax); + BRepBuilderAPI_MakeFace MF(bspline, Umin, Umax, Vmin, Vmax, Precision::Confusion()); + DBRep::Set(a[1], MF.Face()); + } + + return 0; +} + #include namespace { @@ -2202,7 +2383,8 @@ void QABugs::Commands_20(Draw_Interpretor& theCommands) { theCommands.Add("OCC26270", "OCC26270 shape result", __FILE__, OCC26270, group); theCommands.Add ("OCC27552", "OCC27552", __FILE__, OCC27552, group); theCommands.Add("OCC27875", "OCC27875 curve", __FILE__, OCC27875, group); + theCommands.Add("OCC27903", "OCC27903 result degmaxU degmaxV contU contV segmaxU segmaxV totalsegmax nbrcurfront nbrpntconst SurfInit [edge 0] [edge tang (1:G1;2:G2) surf]... [point] [u v tang (1:G1;2:G2) surf] ...", __FILE__, OCC27903, group); theCommands.Add("OCC28217", "OCC28217", __FILE__, OCC28217, group); - + return; } diff --git a/tests/bugs/modalg_6/bug27903 b/tests/bugs/modalg_6/bug27903 new file mode 100644 index 0000000000..438faa574f --- /dev/null +++ b/tests/bugs/modalg_6/bug27903 @@ -0,0 +1,26 @@ +pload QAcommands + +puts "============" +puts "OCC27903" +puts "============" +puts "" +###################################################### +# Enhanced approximation algorithm +###################################################### + +plane p +trim p p -1 3 -1 3 +mkface p p + +beziercurve c1 3 0 0 0 1 0 1 2 0 0 +mkedge e1 c1 +tcopy e1 e2 +tcopy e1 e3 + +ttranslate e2 0 2 0 +trotate e3 0 0 0 0 0 1 90 +tcopy e3 e4 +ttranslate e4 2 0 0 +# create the surface +OCC27903 r1 5 5 0 2 100 100 5000 4 0 p e1 0 e2 0 e3 0 e4 0 +checkshape r1 -- 2.39.5