mirror of
https://github.com/Open-Cascade-SAS/OCCT.git
synced 2026-08-09 15:51:29 +08:00
498e7cd173
Refactor the Convert package to eliminate heap-allocated handle-based storage in favor of direct NCollection_Array members, improving performance and simplifying the API. Deprecate single-element accessors (Pole, Knot, etc.) in favor of batch const-reference accessors (Poles, Knots, etc.). Convert_ConicToBSplineCurve: - Replace handle members (poles, weights, knots, mults) with direct NCollection_Array1 fields (myPoles, myWeights, myKnots, myMults). - Replace BuildCosAndSin handle-based parameters with array references. - Add batch accessors: Poles(), Weights(), Knots(), Multiplicities(). - Deprecate single-element accessors: Pole(), Weight(), Knot(), Multiplicity(). - Update all conic subclasses: Circle, Ellipse, Hyperbola, Parabola. Convert_ElementarySurfaceToBSplineSurface: - Replace handle members with direct NCollection_Array fields (myPoles, myWeights, myUKnots, myVKnots, myUMults, myVMults). - Add Finalize() to trim oversized arrays in derived constructors. - Add batch accessors: Poles(), Weights(), UKnots(), VKnots(), UMultiplicities(), VMultiplicities(). - Deprecate single-element accessors: Pole(), Weight(), UKnot(), VKnot(), UMultiplicity(), VMultiplicity(). - Update all surface subclasses: Cone, Cylinder, Sphere, Torus. Convert_CompPolynomialToPoles / Convert_GridPolynomialToPoles: - Replace handle-based output parameters with direct const-reference accessors for Poles, Knots, Multiplicities. - Deprecate old handle-based Poles(), Knots(), Multiplicities() overloads. Convert_CompBezierCurvesToBSplineCurve (2D and 3D): - Extract common logic into Convert_CompBezierCurvesToBSplineCurveBase template header to eliminate code duplication. - Replace handle<HArray1> members with direct NCollection_Array1 storage in the internal sequence, removing unnecessary heap indirection. NCollection_Sequence: - Fix Node constructors to use member initializer lists (copy/move construction) instead of default-construct + assign, which failed for types like NCollection_Array1 where operator= requires matching sizes. Downstream callers migrated: - AdvApprox_ApproxAFunction: use new const-ref Knots()/Multiplicities(). - AppDef_Variational: use new const-ref Knots()/Multiplicities(). - AdvApp2Var_ApproxAFunc2Var, AdvApp2Var_Patch: use new const-ref API. - Geom2dConvert, GeomConvert, GeomConvert_1: use new const-ref API. - GeomFill_PolynomialConvertor, GeomFill_QuasiAngularConvertor: adapted. - Geom_OsculatingSurface: use direct array references instead of handle->Array*() calls. Added GTests for all Convert classes covering conic curves, elementary surfaces, CompBezier, CompPolynomial, and GridPolynomial conversions.
1204 lines
41 KiB
C++
1204 lines
41 KiB
C++
// Created on: 1996-07-03
|
|
// Created by: Joelle CHAUVET
|
|
// Copyright (c) 1996-1999 Matra Datavision
|
|
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
#include <AdvApp2Var_ApproxAFunc2Var.hxx>
|
|
#include <AdvApp2Var_EvaluatorFunc2Var.hxx>
|
|
#include <AdvApp2Var_Criterion.hxx>
|
|
#include <AdvApp2Var_Context.hxx>
|
|
#include <AdvApp2Var_Patch.hxx>
|
|
#include <AdvApp2Var_Network.hxx>
|
|
#include <AdvApp2Var_Node.hxx>
|
|
#include <AdvApp2Var_Iso.hxx>
|
|
#include <NCollection_Sequence.hxx>
|
|
#include <AdvApp2Var_Framework.hxx>
|
|
#include <AdvApprox_Cutting.hxx>
|
|
|
|
#include <Standard_ConstructionError.hxx>
|
|
#include <Standard_OutOfRange.hxx>
|
|
#include <Standard_Integer.hxx>
|
|
#include <NCollection_Array1.hxx>
|
|
#include <NCollection_HArray1.hxx>
|
|
#include <NCollection_Array2.hxx>
|
|
#include <NCollection_HArray2.hxx>
|
|
|
|
#include <gp_XY.hxx>
|
|
#include <gp_Pnt.hxx>
|
|
|
|
#include <Convert_GridPolynomialToPoles.hxx>
|
|
|
|
#include <Geom_BezierSurface.hxx>
|
|
#include <Geom_BSplineSurface.hxx>
|
|
|
|
//=================================================================================================
|
|
|
|
AdvApp2Var_ApproxAFunc2Var::AdvApp2Var_ApproxAFunc2Var(
|
|
const int Num1DSS,
|
|
const int Num2DSS,
|
|
const int Num3DSS,
|
|
const occ::handle<NCollection_HArray1<double>>& OneDTol,
|
|
const occ::handle<NCollection_HArray1<double>>& TwoDTol,
|
|
const occ::handle<NCollection_HArray1<double>>& ThreeDTol,
|
|
const occ::handle<NCollection_HArray2<double>>& OneDTolFr,
|
|
const occ::handle<NCollection_HArray2<double>>& TwoDTolFr,
|
|
const occ::handle<NCollection_HArray2<double>>& ThreeDTolFr,
|
|
const double FirstInU,
|
|
const double LastInU,
|
|
const double FirstInV,
|
|
const double LastInV,
|
|
const GeomAbs_IsoType FavorIso,
|
|
const GeomAbs_Shape ContInU,
|
|
const GeomAbs_Shape ContInV,
|
|
const int PrecisCode,
|
|
const int MaxDegInU,
|
|
const int MaxDegInV,
|
|
const int MaxPatch,
|
|
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(false),
|
|
myHasResult(false),
|
|
myDegreeInU(0),
|
|
myDegreeInV(0),
|
|
myCriterionError(0.0)
|
|
{
|
|
myNumSubSpaces[0] = Num1DSS;
|
|
myNumSubSpaces[1] = Num2DSS;
|
|
myNumSubSpaces[2] = Num3DSS;
|
|
|
|
Init();
|
|
Perform(UChoice, VChoice, Func);
|
|
ConvertBS();
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
AdvApp2Var_ApproxAFunc2Var::AdvApp2Var_ApproxAFunc2Var(
|
|
const int Num1DSS,
|
|
const int Num2DSS,
|
|
const int Num3DSS,
|
|
const occ::handle<NCollection_HArray1<double>>& OneDTol,
|
|
const occ::handle<NCollection_HArray1<double>>& TwoDTol,
|
|
const occ::handle<NCollection_HArray1<double>>& ThreeDTol,
|
|
const occ::handle<NCollection_HArray2<double>>& OneDTolFr,
|
|
const occ::handle<NCollection_HArray2<double>>& TwoDTolFr,
|
|
const occ::handle<NCollection_HArray2<double>>& ThreeDTolFr,
|
|
const double FirstInU,
|
|
const double LastInU,
|
|
const double FirstInV,
|
|
const double LastInV,
|
|
const GeomAbs_IsoType FavorIso,
|
|
const GeomAbs_Shape ContInU,
|
|
const GeomAbs_Shape ContInV,
|
|
const int PrecisCode,
|
|
const int MaxDegInU,
|
|
const int MaxDegInV,
|
|
const int MaxPatch,
|
|
const AdvApp2Var_EvaluatorFunc2Var& Func,
|
|
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(false),
|
|
myHasResult(false),
|
|
myDegreeInU(0),
|
|
myDegreeInV(0),
|
|
myCriterionError(0.0)
|
|
{
|
|
myNumSubSpaces[0] = Num1DSS;
|
|
myNumSubSpaces[1] = Num2DSS;
|
|
myNumSubSpaces[2] = Num3DSS;
|
|
|
|
Init();
|
|
Perform(UChoice, VChoice, Func, Crit);
|
|
ConvertBS();
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : Init
|
|
// purpose : Initialisation of the approximation
|
|
//=======================================================================
|
|
|
|
void AdvApp2Var_ApproxAFunc2Var::Init()
|
|
{
|
|
int ifav, iu = 0, iv = 0, ndu, ndv;
|
|
switch (myFavoriteIso)
|
|
{
|
|
case GeomAbs_IsoU:
|
|
ifav = 1;
|
|
break;
|
|
case GeomAbs_IsoV:
|
|
ifav = 2;
|
|
break;
|
|
default:
|
|
ifav = 2;
|
|
break;
|
|
}
|
|
switch (myContInU)
|
|
{
|
|
case GeomAbs_C0:
|
|
iu = 0;
|
|
break;
|
|
case GeomAbs_C1:
|
|
iu = 1;
|
|
break;
|
|
case GeomAbs_C2:
|
|
iu = 2;
|
|
break;
|
|
default:
|
|
throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : UContinuity Error");
|
|
}
|
|
switch (myContInV)
|
|
{
|
|
case GeomAbs_C0:
|
|
iv = 0;
|
|
break;
|
|
case GeomAbs_C1:
|
|
iv = 1;
|
|
break;
|
|
case GeomAbs_C2:
|
|
iv = 2;
|
|
break;
|
|
default:
|
|
throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : VContinuity Error");
|
|
}
|
|
ndu = std::max(myMaxDegInU + 1, 2 * iu + 2);
|
|
ndv = std::max(myMaxDegInV + 1, 2 * iv + 2);
|
|
if (ndu < 2 * iu + 2)
|
|
throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : UMaxDegree Error");
|
|
if (ndv < 2 * iv + 2)
|
|
throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : VMaxDegree Error");
|
|
myPrecisionCode = std::max(0, std::min(myPrecisionCode, 3));
|
|
AdvApp2Var_Context Conditions(ifav,
|
|
iu,
|
|
iv,
|
|
ndu,
|
|
ndv,
|
|
myPrecisionCode,
|
|
myNumSubSpaces[0],
|
|
myNumSubSpaces[1],
|
|
myNumSubSpaces[2],
|
|
my1DTolerances,
|
|
my2DTolerances,
|
|
my3DTolerances,
|
|
my1DTolOnFront,
|
|
my2DTolOnFront,
|
|
my3DTolOnFront);
|
|
myConditions = Conditions;
|
|
InitGrid(1);
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : InitGrid
|
|
// purpose : Initialisation of the approximation with regular cuttings
|
|
//=======================================================================
|
|
|
|
void AdvApp2Var_ApproxAFunc2Var::InitGrid(const int NbInt)
|
|
{
|
|
int iu = myConditions.UOrder(), iv = myConditions.VOrder(), iint;
|
|
|
|
occ::handle<AdvApp2Var_Patch> M0 =
|
|
new AdvApp2Var_Patch(myFirstParInU, myLastParInU, myFirstParInV, myLastParInV, iu, iv);
|
|
|
|
NCollection_Sequence<occ::handle<AdvApp2Var_Patch>> Net;
|
|
Net.Append(M0);
|
|
|
|
NCollection_Sequence<double> TheU, TheV;
|
|
TheU.Append(myFirstParInU);
|
|
TheV.Append(myFirstParInV);
|
|
TheU.Append(myLastParInU);
|
|
TheV.Append(myLastParInV);
|
|
|
|
AdvApp2Var_Network Result(Net, TheU, TheV);
|
|
|
|
gp_XY UV1(myFirstParInU, myFirstParInV);
|
|
occ::handle<AdvApp2Var_Node> C1 = new AdvApp2Var_Node(UV1, iu, iv);
|
|
gp_XY UV2(myLastParInU, myFirstParInV);
|
|
occ::handle<AdvApp2Var_Node> C2 = new AdvApp2Var_Node(UV2, iu, iv);
|
|
gp_XY UV4(myLastParInU, myLastParInV);
|
|
occ::handle<AdvApp2Var_Node> C4 = new AdvApp2Var_Node(UV4, iu, iv);
|
|
gp_XY UV3(myFirstParInU, myLastParInV);
|
|
occ::handle<AdvApp2Var_Node> C3 = new AdvApp2Var_Node(UV3, iu, iv);
|
|
NCollection_Sequence<occ::handle<AdvApp2Var_Node>> Bag;
|
|
Bag.Append(C1);
|
|
Bag.Append(C2);
|
|
Bag.Append(C3);
|
|
Bag.Append(C4);
|
|
|
|
occ::handle<AdvApp2Var_Iso> V0 = new AdvApp2Var_Iso(GeomAbs_IsoV,
|
|
myFirstParInV,
|
|
myFirstParInU,
|
|
myLastParInU,
|
|
myFirstParInV,
|
|
myLastParInV,
|
|
1,
|
|
iu,
|
|
iv);
|
|
occ::handle<AdvApp2Var_Iso> V1 = new AdvApp2Var_Iso(GeomAbs_IsoV,
|
|
myLastParInV,
|
|
myFirstParInU,
|
|
myLastParInU,
|
|
myFirstParInV,
|
|
myLastParInV,
|
|
2,
|
|
iu,
|
|
iv);
|
|
occ::handle<AdvApp2Var_Iso> U0 = new AdvApp2Var_Iso(GeomAbs_IsoU,
|
|
myFirstParInU,
|
|
myFirstParInU,
|
|
myLastParInU,
|
|
myFirstParInV,
|
|
myLastParInV,
|
|
3,
|
|
iu,
|
|
iv);
|
|
occ::handle<AdvApp2Var_Iso> U1 = new AdvApp2Var_Iso(GeomAbs_IsoU,
|
|
myLastParInU,
|
|
myFirstParInU,
|
|
myLastParInU,
|
|
myFirstParInV,
|
|
myLastParInV,
|
|
4,
|
|
iu,
|
|
iv);
|
|
|
|
NCollection_Sequence<occ::handle<AdvApp2Var_Iso>> BU0, BV0;
|
|
BU0.Append(V0);
|
|
BU0.Append(V1);
|
|
BV0.Append(U0);
|
|
BV0.Append(U1);
|
|
|
|
NCollection_Sequence<NCollection_Sequence<occ::handle<AdvApp2Var_Iso>>> UStrip, VStrip;
|
|
UStrip.Append(BU0);
|
|
VStrip.Append(BV0);
|
|
|
|
AdvApp2Var_Framework Constraints(Bag, UStrip, VStrip);
|
|
|
|
// regular cutting if NbInt>1
|
|
double 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);
|
|
}
|
|
myResult = Result;
|
|
myConstraints = Constraints;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : Perform
|
|
// purpose : Computation of the approximation
|
|
//=======================================================================
|
|
|
|
void AdvApp2Var_ApproxAFunc2Var::Perform(const AdvApprox_Cutting& UChoice,
|
|
const AdvApprox_Cutting& VChoice,
|
|
const AdvApp2Var_EvaluatorFunc2Var& Func)
|
|
{
|
|
ComputePatches(UChoice, VChoice, Func);
|
|
myHasResult = myDone = true;
|
|
Compute3DErrors();
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : Perform
|
|
// purpose : Computation of the approximation
|
|
//=======================================================================
|
|
|
|
void AdvApp2Var_ApproxAFunc2Var::Perform(const AdvApprox_Cutting& UChoice,
|
|
const AdvApprox_Cutting& VChoice,
|
|
const AdvApp2Var_EvaluatorFunc2Var& Func,
|
|
const AdvApp2Var_Criterion& Crit)
|
|
{
|
|
ComputePatches(UChoice, VChoice, Func, Crit);
|
|
myHasResult = myDone = true;
|
|
Compute3DErrors();
|
|
ComputeCritError();
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : ComputePatches
|
|
// purpose : Computation of the polynomial approximations
|
|
//=======================================================================
|
|
|
|
void AdvApp2Var_ApproxAFunc2Var::ComputePatches(const AdvApprox_Cutting& UChoice,
|
|
const AdvApprox_Cutting& VChoice,
|
|
const AdvApp2Var_EvaluatorFunc2Var& Func)
|
|
{
|
|
double Udec, Vdec;
|
|
bool Umore, Vmore;
|
|
int NbPatch, NbU, NbV, NumDec;
|
|
int FirstNA;
|
|
|
|
while (myResult.FirstNotApprox(FirstNA))
|
|
{
|
|
|
|
// complete the set of constraints
|
|
ComputeConstraints(UChoice, VChoice, Func);
|
|
|
|
// discretization of constraints relative to the square
|
|
myResult(FirstNA).Discretise(myConditions, myConstraints, Func);
|
|
if (!myResult(FirstNA).IsDiscretised())
|
|
{
|
|
myHasResult = myDone = false;
|
|
throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : Surface Discretisation Error");
|
|
}
|
|
|
|
// calculate the number and the type of authorized cuts
|
|
// depending on the max number of squares and the validity of next cuts.
|
|
NbU = myResult.NbPatchInU();
|
|
NbV = myResult.NbPatchInV();
|
|
NbPatch = NbU * NbV;
|
|
Umore = UChoice.Value(myResult(FirstNA).U0(), myResult(FirstNA).U1(), Udec);
|
|
Vmore = VChoice.Value(myResult(FirstNA).V0(), myResult(FirstNA).V1(), Vdec);
|
|
|
|
NumDec = 0;
|
|
if (((NbPatch + NbV) <= myMaxPatches) && ((NbPatch + NbU) > myMaxPatches) && (Umore))
|
|
NumDec = 1;
|
|
if (((NbPatch + NbV) > myMaxPatches) && ((NbPatch + NbU) <= myMaxPatches) && (Vmore))
|
|
NumDec = 2;
|
|
if (((NbPatch + NbV) <= myMaxPatches) && ((NbPatch + NbU) <= myMaxPatches))
|
|
{
|
|
if (Umore)
|
|
NumDec = 3;
|
|
if ((NbV > NbU) && Vmore)
|
|
NumDec = 4;
|
|
}
|
|
if ((NbU + 1) * (NbV + 1) <= myMaxPatches)
|
|
{
|
|
if (!Umore && !Vmore)
|
|
NumDec = 0;
|
|
if (Umore && !Vmore)
|
|
NumDec = 3;
|
|
if (!Umore && Vmore)
|
|
NumDec = 4;
|
|
if (Umore && Vmore)
|
|
NumDec = 5;
|
|
}
|
|
|
|
// approximation of the square
|
|
myResult(FirstNA).MakeApprox(myConditions, myConstraints, NumDec);
|
|
|
|
if (!myResult(FirstNA).IsApproximated())
|
|
{
|
|
switch (myResult(FirstNA).CutSense())
|
|
{
|
|
case 0:
|
|
// It is not possible to cut : the result is preserved
|
|
if (myResult(FirstNA).HasResult())
|
|
{
|
|
myResult(FirstNA).OverwriteApprox();
|
|
}
|
|
else
|
|
{
|
|
myHasResult = myDone = false;
|
|
throw Standard_ConstructionError(
|
|
"AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
|
|
}
|
|
break;
|
|
case 1:
|
|
// It is necessary to cut in U
|
|
myResult.UpdateInU(Udec);
|
|
myConstraints.UpdateInU(Udec);
|
|
break;
|
|
case 2:
|
|
// It is necessary to cut in V
|
|
myResult.UpdateInV(Vdec);
|
|
myConstraints.UpdateInV(Vdec);
|
|
break;
|
|
case 3:
|
|
// It is necessary to cut in U and V
|
|
myResult.UpdateInU(Udec);
|
|
myConstraints.UpdateInU(Udec);
|
|
myResult.UpdateInV(Vdec);
|
|
myConstraints.UpdateInV(Vdec);
|
|
break;
|
|
default:
|
|
myHasResult = myDone = false;
|
|
throw Standard_ConstructionError(
|
|
"AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : ComputePatches
|
|
// purpose : Computation of the polynomial approximations
|
|
//=======================================================================
|
|
|
|
void AdvApp2Var_ApproxAFunc2Var::ComputePatches(const AdvApprox_Cutting& UChoice,
|
|
const AdvApprox_Cutting& VChoice,
|
|
const AdvApp2Var_EvaluatorFunc2Var& Func,
|
|
const AdvApp2Var_Criterion& Crit)
|
|
{
|
|
double Udec, Vdec, CritValue, m1 = 0.;
|
|
bool Umore, Vmore, CritAbs = (Crit.Type() == AdvApp2Var_Absolute);
|
|
int NbPatch, NbU, NbV, NbInt, NumDec;
|
|
int FirstNA, decision = 0;
|
|
|
|
while (myResult.FirstNotApprox(FirstNA))
|
|
{
|
|
|
|
// complete the set of constraints
|
|
ComputeConstraints(UChoice, VChoice, Func, Crit);
|
|
if (decision > 0)
|
|
{
|
|
m1 = 0.;
|
|
}
|
|
|
|
// discretize the constraints relative to the square
|
|
myResult(FirstNA).Discretise(myConditions, myConstraints, Func);
|
|
if (!myResult(FirstNA).IsDiscretised())
|
|
{
|
|
myHasResult = myDone = false;
|
|
throw Standard_ConstructionError("AdvApp2Var_ApproxAFunc2Var : Surface Discretisation Error");
|
|
}
|
|
|
|
// calculate the number and type of authorized cuts
|
|
// depending on the max number of squares and the validity of next cuts
|
|
NbU = myResult.NbPatchInU();
|
|
NbV = myResult.NbPatchInV();
|
|
NbPatch = NbU * NbV;
|
|
NbInt = NbU;
|
|
Umore = UChoice.Value(myResult(FirstNA).U0(), myResult(FirstNA).U1(), Udec);
|
|
Vmore = VChoice.Value(myResult(FirstNA).V0(), myResult(FirstNA).V1(), Vdec);
|
|
|
|
NumDec = 0;
|
|
if (((NbPatch + NbV) <= myMaxPatches) && ((NbPatch + NbU) > myMaxPatches) && (Umore))
|
|
NumDec = 1;
|
|
if (((NbPatch + NbV) > myMaxPatches) && ((NbPatch + NbU) <= myMaxPatches) && (Vmore))
|
|
NumDec = 2;
|
|
if (((NbPatch + NbV) <= myMaxPatches) && ((NbPatch + NbU) <= myMaxPatches))
|
|
{
|
|
if (Umore)
|
|
NumDec = 3;
|
|
if ((NbV > NbU) && Vmore)
|
|
NumDec = 4;
|
|
}
|
|
if ((NbU + 1) * (NbV + 1) <= myMaxPatches)
|
|
{
|
|
if (!Umore && !Vmore)
|
|
NumDec = 0;
|
|
if (Umore && !Vmore)
|
|
NumDec = 1;
|
|
if (!Umore && Vmore)
|
|
NumDec = 2;
|
|
if (Umore && Vmore)
|
|
NumDec = 5;
|
|
}
|
|
|
|
// approximation of the square
|
|
if (CritAbs)
|
|
{
|
|
myResult(FirstNA).MakeApprox(myConditions, myConstraints, 0);
|
|
}
|
|
else
|
|
{
|
|
myResult(FirstNA).MakeApprox(myConditions, myConstraints, NumDec);
|
|
}
|
|
if (NumDec >= 3)
|
|
NumDec = NumDec - 2;
|
|
|
|
// evaluation of the criterion on the square
|
|
if (myResult(FirstNA).HasResult())
|
|
{
|
|
Crit.Value(myResult(FirstNA), myConditions);
|
|
CritValue = myResult(FirstNA).CritValue();
|
|
if (m1 < CritValue)
|
|
m1 = CritValue;
|
|
}
|
|
// is it necessary to cut ?
|
|
decision = myResult(FirstNA).CutSense(Crit, NumDec);
|
|
bool Regular = (Crit.Repartition() == AdvApp2Var_Regular);
|
|
// bool Regular = true;
|
|
if (Regular && decision > 0)
|
|
{
|
|
NbInt++;
|
|
InitGrid(NbInt);
|
|
}
|
|
else
|
|
{
|
|
switch (decision)
|
|
{
|
|
case 0:
|
|
// Impossible to cut : the result is preserved
|
|
if (myResult(FirstNA).HasResult())
|
|
{
|
|
myResult(FirstNA).OverwriteApprox();
|
|
}
|
|
else
|
|
{
|
|
myHasResult = myDone = false;
|
|
throw Standard_ConstructionError(
|
|
"AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
|
|
}
|
|
break;
|
|
case 1:
|
|
// It is necessary to cut in U
|
|
myResult.UpdateInU(Udec);
|
|
myConstraints.UpdateInU(Udec);
|
|
break;
|
|
case 2:
|
|
// It is necessary to cut in V
|
|
myResult.UpdateInV(Vdec);
|
|
myConstraints.UpdateInV(Vdec);
|
|
break;
|
|
case 3:
|
|
// It is necessary to cut in U and V
|
|
myResult.UpdateInU(Udec);
|
|
myConstraints.UpdateInU(Udec);
|
|
myResult.UpdateInV(Vdec);
|
|
myConstraints.UpdateInV(Vdec);
|
|
break;
|
|
default:
|
|
myHasResult = myDone = false;
|
|
throw Standard_ConstructionError(
|
|
"AdvApp2Var_ApproxAFunc2Var : Surface Approximation Error");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : ComputeConstraints without Criterion
|
|
// purpose : Approximation of the constraints
|
|
//=======================================================================
|
|
|
|
void AdvApp2Var_ApproxAFunc2Var::ComputeConstraints(const AdvApprox_Cutting& UChoice,
|
|
const AdvApprox_Cutting& VChoice,
|
|
const AdvApp2Var_EvaluatorFunc2Var& Func)
|
|
{
|
|
double dec;
|
|
bool more;
|
|
int ind1, ind2, NbPatch, NbU, NbV;
|
|
int iu = myConditions.UOrder(), iv = myConditions.VOrder();
|
|
AdvApp2Var_Node N1(iu, iv), N2(iu, iv);
|
|
|
|
for (occ::handle<AdvApp2Var_Iso> anIso = myConstraints.FirstNotApprox(ind1, ind2);
|
|
!anIso.IsNull();
|
|
anIso = myConstraints.FirstNotApprox(ind1, ind2))
|
|
{
|
|
// approximation of iso and calculation of constraints at extremities
|
|
const int indN1 = myConstraints.FirstNode(anIso->Type(), ind1, ind2);
|
|
N1 = *myConstraints.Node(indN1);
|
|
const int indN2 = myConstraints.LastNode(anIso->Type(), ind1, ind2);
|
|
N2 = *myConstraints.Node(indN2);
|
|
|
|
// note that old code attempted to make copy of anIso here (but copy was incomplete)
|
|
anIso->MakeApprox(myConditions,
|
|
myFirstParInU,
|
|
myLastParInU,
|
|
myFirstParInV,
|
|
myLastParInV,
|
|
Func,
|
|
N1,
|
|
N2);
|
|
if (anIso->IsApproximated())
|
|
{
|
|
// iso is approached at the required tolerance
|
|
myConstraints.ChangeIso(ind1, ind2, anIso);
|
|
*myConstraints.Node(indN1) = N1;
|
|
*myConstraints.Node(indN2) = N2;
|
|
}
|
|
else
|
|
{
|
|
// Approximation is not satisfactory
|
|
NbU = myResult.NbPatchInU();
|
|
NbV = myResult.NbPatchInV();
|
|
if (anIso->Type() == GeomAbs_IsoV)
|
|
{
|
|
NbPatch = (NbU + 1) * NbV;
|
|
more = UChoice.Value(anIso->T0(), anIso->T1(), dec);
|
|
}
|
|
else
|
|
{
|
|
NbPatch = (NbV + 1) * NbU;
|
|
more = VChoice.Value(anIso->T0(), anIso->T1(), dec);
|
|
}
|
|
|
|
if (NbPatch <= myMaxPatches && more)
|
|
{
|
|
// It is possible to cut iso
|
|
if (anIso->Type() == GeomAbs_IsoV)
|
|
{
|
|
myResult.UpdateInU(dec);
|
|
myConstraints.UpdateInU(dec);
|
|
}
|
|
else
|
|
{
|
|
myResult.UpdateInV(dec);
|
|
myConstraints.UpdateInV(dec);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// It is not possible to cut : the result is preserved
|
|
if (anIso->HasResult())
|
|
{
|
|
anIso->OverwriteApprox();
|
|
myConstraints.ChangeIso(ind1, ind2, anIso);
|
|
*myConstraints.Node(indN1) = N1;
|
|
*myConstraints.Node(indN2) = N2;
|
|
}
|
|
else
|
|
{
|
|
myHasResult = myDone = false;
|
|
throw Standard_ConstructionError(
|
|
"AdvApp2Var_ApproxAFunc2Var : Curve Approximation Error");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : ComputeConstraints with Criterion
|
|
// purpose : Approximation of the constraints
|
|
//=======================================================================
|
|
|
|
void AdvApp2Var_ApproxAFunc2Var::ComputeConstraints(const AdvApprox_Cutting& UChoice,
|
|
const AdvApprox_Cutting& VChoice,
|
|
const AdvApp2Var_EvaluatorFunc2Var& Func,
|
|
const AdvApp2Var_Criterion& Crit)
|
|
{
|
|
double dec;
|
|
bool more, CritRel = (Crit.Type() == AdvApp2Var_Relative);
|
|
int ind1, ind2, NbPatch, NbU, NbV;
|
|
int indN1, indN2;
|
|
int iu = myConditions.UOrder(), iv = myConditions.VOrder();
|
|
AdvApp2Var_Node N1(iu, iv), N2(iu, iv);
|
|
|
|
for (occ::handle<AdvApp2Var_Iso> anIso = myConstraints.FirstNotApprox(ind1, ind2);
|
|
!anIso.IsNull();
|
|
anIso = myConstraints.FirstNotApprox(ind1, ind2))
|
|
{
|
|
// approximation of the iso and calculation of constraints at the extremities
|
|
indN1 = myConstraints.FirstNode(anIso->Type(), ind1, ind2);
|
|
N1 = *myConstraints.Node(indN1);
|
|
indN2 = myConstraints.LastNode(anIso->Type(), ind1, ind2);
|
|
N2 = *myConstraints.Node(indN2);
|
|
|
|
// note that old code attempted to make copy of anIso here (but copy was incomplete)
|
|
anIso->MakeApprox(myConditions,
|
|
myFirstParInU,
|
|
myLastParInU,
|
|
myFirstParInV,
|
|
myLastParInV,
|
|
Func,
|
|
N1,
|
|
N2);
|
|
|
|
if (anIso->IsApproximated())
|
|
{
|
|
// iso is approached at the required tolerance
|
|
myConstraints.ChangeIso(ind1, ind2, anIso);
|
|
*myConstraints.Node(indN1) = N1;
|
|
*myConstraints.Node(indN2) = N2;
|
|
}
|
|
else
|
|
{
|
|
// Approximation is not satisfactory
|
|
NbU = myResult.NbPatchInU();
|
|
NbV = myResult.NbPatchInV();
|
|
if (anIso->Type() == GeomAbs_IsoV)
|
|
{
|
|
NbPatch = (NbU + 1) * NbV;
|
|
more = UChoice.Value(anIso->T0(), anIso->T1(), dec);
|
|
}
|
|
else
|
|
{
|
|
NbPatch = (NbV + 1) * NbU;
|
|
more = VChoice.Value(anIso->T0(), anIso->T1(), dec);
|
|
}
|
|
|
|
// To force Overwrite if the criterion is Absolute
|
|
more = more && (CritRel);
|
|
|
|
if (NbPatch <= myMaxPatches && more)
|
|
{
|
|
// It is possible to cut iso
|
|
if (anIso->Type() == GeomAbs_IsoV)
|
|
{
|
|
myResult.UpdateInU(dec);
|
|
myConstraints.UpdateInU(dec);
|
|
}
|
|
else
|
|
{
|
|
myResult.UpdateInV(dec);
|
|
myConstraints.UpdateInV(dec);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// It is not possible to cut: the result is preserved
|
|
if (anIso->HasResult())
|
|
{
|
|
anIso->OverwriteApprox();
|
|
myConstraints.ChangeIso(ind1, ind2, anIso);
|
|
*myConstraints.Node(indN1) = N1;
|
|
*myConstraints.Node(indN2) = N2;
|
|
}
|
|
else
|
|
{
|
|
myHasResult = myDone = false;
|
|
throw Standard_ConstructionError(
|
|
"AdvApp2Var_ApproxAFunc2Var : Curve Approximation Error");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : Compute3DErrors
|
|
// purpose : Computation of the 3D errors
|
|
//=======================================================================
|
|
|
|
void AdvApp2Var_ApproxAFunc2Var::Compute3DErrors()
|
|
{
|
|
|
|
int iesp, ipat;
|
|
double error_max, error_moy, error_U0, error_V0, error_U1, error_V1;
|
|
double Tol, F1Tol, F2Tol, F3Tol, F4Tol;
|
|
if (myNumSubSpaces[2] > 0)
|
|
{
|
|
my3DMaxError = new (NCollection_HArray1<double>)(1, myNumSubSpaces[2]);
|
|
my3DAverageError = new (NCollection_HArray1<double>)(1, myNumSubSpaces[2]);
|
|
my3DUFrontError = new (NCollection_HArray1<double>)(1, myNumSubSpaces[2]);
|
|
my3DVFrontError = new (NCollection_HArray1<double>)(1, myNumSubSpaces[2]);
|
|
for (iesp = 1; iesp <= myNumSubSpaces[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);
|
|
for (ipat = 1; ipat <= myResult.NbPatch(); ipat++)
|
|
{
|
|
error_max = std::max((myResult(ipat).MaxErrors())->Value(iesp), error_max);
|
|
error_U0 = std::max((myResult(ipat).IsoErrors())->Value(iesp, 3), error_U0);
|
|
error_U1 = std::max((myResult(ipat).IsoErrors())->Value(iesp, 4), error_U1);
|
|
error_V0 = std::max((myResult(ipat).IsoErrors())->Value(iesp, 1), error_V0);
|
|
error_V1 = std::max((myResult(ipat).IsoErrors())->Value(iesp, 2), error_V1);
|
|
error_moy += (myResult(ipat).AverageErrors())->Value(iesp);
|
|
}
|
|
my3DMaxError->SetValue(iesp, error_max);
|
|
my3DUFrontError->SetValue(iesp, std::max(error_U0, error_U1));
|
|
my3DVFrontError->SetValue(iesp, std::max(error_V0, error_V1));
|
|
error_moy /= (double)myResult.NbPatch();
|
|
my3DAverageError->SetValue(iesp, error_moy);
|
|
if (error_max > Tol || error_U0 > F3Tol || error_U1 > F4Tol || error_V0 > F1Tol
|
|
|| error_V1 > F2Tol)
|
|
{
|
|
myDone = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : ComputeCritError
|
|
// purpose : Computation of the max value of the Criterion
|
|
//=======================================================================
|
|
|
|
void AdvApp2Var_ApproxAFunc2Var::ComputeCritError()
|
|
{
|
|
|
|
int iesp, ipat;
|
|
double crit_max;
|
|
if (myNumSubSpaces[2] > 0)
|
|
{
|
|
for (iesp = 1; iesp <= myNumSubSpaces[2]; iesp++)
|
|
{
|
|
crit_max = 0.;
|
|
for (ipat = 1; ipat <= myResult.NbPatch(); ipat++)
|
|
{
|
|
crit_max = std::max((myResult(ipat).CritValue()), crit_max);
|
|
}
|
|
myCriterionError = crit_max;
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : ConvertBS
|
|
// purpose : Conversion of the approximation in BSpline Surface
|
|
//=======================================================================
|
|
|
|
void AdvApp2Var_ApproxAFunc2Var::ConvertBS()
|
|
{
|
|
// Homogeneization of degrees
|
|
int iu = myConditions.UOrder(), iv = myConditions.VOrder();
|
|
int ncfu = myConditions.ULimit(), ncfv = myConditions.VLimit();
|
|
myResult.SameDegree(iu, iv, ncfu, ncfv);
|
|
myDegreeInU = ncfu - 1;
|
|
myDegreeInV = ncfv - 1;
|
|
|
|
// Calculate resulting surfaces
|
|
mySurfaces = new (NCollection_HArray1<occ::handle<Geom_Surface>>)(1, myNumSubSpaces[2]);
|
|
|
|
int j;
|
|
NCollection_Array1<double> UKnots(1, myResult.NbPatchInU() + 1);
|
|
for (j = 1; j <= UKnots.Length(); j++)
|
|
{
|
|
UKnots.SetValue(j, myResult.UParameter(j));
|
|
}
|
|
|
|
NCollection_Array1<double> VKnots(1, myResult.NbPatchInV() + 1);
|
|
for (j = 1; j <= VKnots.Length(); j++)
|
|
{
|
|
VKnots.SetValue(j, myResult.VParameter(j));
|
|
}
|
|
|
|
// Prepare data for conversion grid of polynoms --> poles
|
|
occ::handle<NCollection_HArray1<double>> Uint1 = new (NCollection_HArray1<double>)(1, 2);
|
|
Uint1->SetValue(1, -1);
|
|
Uint1->SetValue(2, 1);
|
|
occ::handle<NCollection_HArray1<double>> Vint1 = new (NCollection_HArray1<double>)(1, 2);
|
|
Vint1->SetValue(1, -1);
|
|
Vint1->SetValue(2, 1);
|
|
|
|
occ::handle<NCollection_HArray1<double>> Uint2 =
|
|
new (NCollection_HArray1<double>)(1, myResult.NbPatchInU() + 1);
|
|
for (j = 1; j <= Uint2->Length(); j++)
|
|
{
|
|
Uint2->SetValue(j, myResult.UParameter(j));
|
|
}
|
|
occ::handle<NCollection_HArray1<double>> Vint2 =
|
|
new (NCollection_HArray1<double>)(1, myResult.NbPatchInV() + 1);
|
|
for (j = 1; j <= Vint2->Length(); j++)
|
|
{
|
|
Vint2->SetValue(j, myResult.VParameter(j));
|
|
}
|
|
|
|
int nmax = myResult.NbPatchInU() * myResult.NbPatchInV(),
|
|
Size_eq = myConditions.ULimit() * myConditions.VLimit() * 3;
|
|
|
|
occ::handle<NCollection_HArray2<int>> NbCoeff = new (NCollection_HArray2<int>)(1, nmax, 1, 2);
|
|
occ::handle<NCollection_HArray1<double>> Poly =
|
|
new (NCollection_HArray1<double>)(1, nmax * Size_eq);
|
|
|
|
int SSP, i;
|
|
for (SSP = 1; SSP <= myNumSubSpaces[2]; SSP++)
|
|
{
|
|
|
|
// Creation of the grid of polynoms
|
|
int n = 0, icf = 1, ieq;
|
|
for (j = 1; j <= myResult.NbPatchInV(); j++)
|
|
{
|
|
for (i = 1; i <= myResult.NbPatchInU(); i++)
|
|
{
|
|
n++;
|
|
NbCoeff->SetValue(n, 1, myResult.Patch(i, j).NbCoeffInU());
|
|
NbCoeff->SetValue(n, 2, myResult.Patch(i, j).NbCoeffInV());
|
|
for (ieq = 1; ieq <= Size_eq; ieq++)
|
|
{
|
|
Poly->SetValue(icf, (myResult.Patch(i, j).Coefficients(SSP, myConditions))->Value(ieq));
|
|
icf++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Conversion into poles
|
|
Convert_GridPolynomialToPoles CvP(myResult.NbPatchInU(),
|
|
myResult.NbPatchInV(),
|
|
iu,
|
|
iv,
|
|
myMaxDegInU,
|
|
myMaxDegInV,
|
|
NbCoeff,
|
|
Poly,
|
|
Uint1,
|
|
Vint1,
|
|
Uint2,
|
|
Vint2);
|
|
if (!CvP.IsDone())
|
|
{
|
|
myDone = false;
|
|
}
|
|
|
|
// Conversion into BSpline
|
|
mySurfaces->ChangeValue(SSP) = new (Geom_BSplineSurface)(CvP.Poles(),
|
|
CvP.UKnots(),
|
|
CvP.VKnots(),
|
|
CvP.UMultiplicities(),
|
|
CvP.VMultiplicities(),
|
|
CvP.UDegree(),
|
|
CvP.VDegree());
|
|
}
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
occ::handle<NCollection_HArray1<double>> AdvApp2Var_ApproxAFunc2Var::MaxError(
|
|
const int Dimension) const
|
|
{
|
|
occ::handle<NCollection_HArray1<double>> EPtr;
|
|
if (Dimension < 1 || Dimension > 3)
|
|
{
|
|
throw Standard_OutOfRange(
|
|
"AdvApp2Var_ApproxAFunc2Var::MaxError : Dimension must be equal to 1,2 or 3 !");
|
|
}
|
|
switch (Dimension)
|
|
{
|
|
case 1:
|
|
EPtr = my1DMaxError;
|
|
break;
|
|
case 2:
|
|
EPtr = my2DMaxError;
|
|
break;
|
|
case 3:
|
|
EPtr = my3DMaxError;
|
|
break;
|
|
}
|
|
return EPtr;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
occ::handle<NCollection_HArray1<double>> AdvApp2Var_ApproxAFunc2Var::AverageError(
|
|
const int Dimension) const
|
|
{
|
|
occ::handle<NCollection_HArray1<double>> EPtr;
|
|
if (Dimension < 1 || Dimension > 3)
|
|
{
|
|
throw Standard_OutOfRange(
|
|
"AdvApp2Var_ApproxAFunc2Var::AverageError : Dimension must be equal to 1,2 or 3 !");
|
|
}
|
|
switch (Dimension)
|
|
{
|
|
case 1:
|
|
EPtr = my1DAverageError;
|
|
break;
|
|
case 2:
|
|
EPtr = my2DAverageError;
|
|
break;
|
|
case 3:
|
|
EPtr = my3DAverageError;
|
|
break;
|
|
}
|
|
return EPtr;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
occ::handle<NCollection_HArray1<double>> AdvApp2Var_ApproxAFunc2Var::UFrontError(
|
|
const int Dimension) const
|
|
{
|
|
occ::handle<NCollection_HArray1<double>> EPtr;
|
|
if (Dimension < 1 || Dimension > 3)
|
|
{
|
|
throw Standard_OutOfRange(
|
|
"AdvApp2Var_ApproxAFunc2Var::UFrontError : Dimension must be equal to 1,2 or 3 !");
|
|
}
|
|
switch (Dimension)
|
|
{
|
|
case 1:
|
|
EPtr = my1DUFrontError;
|
|
break;
|
|
case 2:
|
|
EPtr = my2DUFrontError;
|
|
break;
|
|
case 3:
|
|
EPtr = my3DUFrontError;
|
|
break;
|
|
}
|
|
return EPtr;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
occ::handle<NCollection_HArray1<double>> AdvApp2Var_ApproxAFunc2Var::VFrontError(
|
|
const int Dimension) const
|
|
{
|
|
occ::handle<NCollection_HArray1<double>> EPtr;
|
|
if (Dimension <= 0 || Dimension > 3)
|
|
{
|
|
throw Standard_OutOfRange(
|
|
"AdvApp2Var_ApproxAFunc2Var::VFrontError : Dimension must be equal to 1,2 or 3 !");
|
|
}
|
|
switch (Dimension)
|
|
{
|
|
case 1:
|
|
EPtr = my1DVFrontError;
|
|
break;
|
|
case 2:
|
|
EPtr = my2DVFrontError;
|
|
break;
|
|
case 3:
|
|
EPtr = my3DVFrontError;
|
|
break;
|
|
}
|
|
return EPtr;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
double AdvApp2Var_ApproxAFunc2Var::MaxError(const int Dimension, const int SSPIndex) const
|
|
{
|
|
if (Dimension != 3 || SSPIndex != 1)
|
|
{
|
|
throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::MaxError: ONE Surface 3D only !");
|
|
}
|
|
occ::handle<NCollection_HArray1<double>> EPtr = MaxError(Dimension);
|
|
return EPtr->Value(SSPIndex);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
double AdvApp2Var_ApproxAFunc2Var::AverageError(const int Dimension, const int SSPIndex) const
|
|
{
|
|
if (Dimension != 3 || SSPIndex != 1)
|
|
{
|
|
throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::AverageError : ONE Surface 3D only !");
|
|
}
|
|
occ::handle<NCollection_HArray1<double>> EPtr = AverageError(Dimension);
|
|
return EPtr->Value(SSPIndex);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
double AdvApp2Var_ApproxAFunc2Var::UFrontError(const int Dimension, const int SSPIndex) const
|
|
{
|
|
if (Dimension != 3 || SSPIndex != 1)
|
|
{
|
|
throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::UFrontError : ONE Surface 3D only !");
|
|
}
|
|
occ::handle<NCollection_HArray1<double>> EPtr = UFrontError(Dimension);
|
|
return EPtr->Value(SSPIndex);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
double AdvApp2Var_ApproxAFunc2Var::VFrontError(const int Dimension, const int SSPIndex) const
|
|
{
|
|
if (Dimension != 3 || SSPIndex != 1)
|
|
{
|
|
throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::VFrontError : ONE Surface 3D only !");
|
|
}
|
|
occ::handle<NCollection_HArray1<double>> EPtr = VFrontError(Dimension);
|
|
return EPtr->Value(SSPIndex);
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
double AdvApp2Var_ApproxAFunc2Var::CritError(const int Dimension, const int SSPIndex) const
|
|
{
|
|
if (Dimension != 3 || SSPIndex != 1)
|
|
{
|
|
throw Standard_OutOfRange("AdvApp2Var_ApproxAFunc2Var::CritError: ONE Surface 3D only !");
|
|
}
|
|
return myCriterionError;
|
|
}
|
|
|
|
//=================================================================================================
|
|
|
|
void AdvApp2Var_ApproxAFunc2Var::Dump(Standard_OStream& o) const
|
|
{
|
|
int iesp = 1, NbKU, NbKV, ik;
|
|
o << std::endl;
|
|
if (!myHasResult)
|
|
{
|
|
o << "No result" << std::endl;
|
|
}
|
|
else
|
|
{
|
|
o << "There is a result";
|
|
if (myDone)
|
|
{
|
|
o << " within the requested tolerance " << my3DTolerances->Value(iesp) << std::endl;
|
|
}
|
|
else if (my3DMaxError->Value(iesp) > my3DTolerances->Value(iesp))
|
|
{
|
|
o << " WITHOUT the requested tolerance " << my3DTolerances->Value(iesp) << std::endl;
|
|
}
|
|
else
|
|
{
|
|
o << " WITHOUT the requested continuities " << std::endl;
|
|
}
|
|
o << std::endl;
|
|
o << "Result max error :" << my3DMaxError->Value(iesp) << std::endl;
|
|
o << "Result average error :" << my3DAverageError->Value(iesp) << std::endl;
|
|
o << "Result max error on U frontiers :" << my3DUFrontError->Value(iesp) << std::endl;
|
|
o << "Result max error on V frontiers :" << my3DVFrontError->Value(iesp) << std::endl;
|
|
o << std::endl;
|
|
o << "Degree of Bezier patches in U : " << myDegreeInU << " in V : " << myDegreeInV
|
|
<< std::endl;
|
|
o << std::endl;
|
|
occ::handle<Geom_BSplineSurface> S =
|
|
occ::down_cast<Geom_BSplineSurface>(mySurfaces->Value(iesp));
|
|
o << "Number of poles in U : " << S->NbUPoles() << " in V : " << S->NbVPoles() << std::endl;
|
|
o << std::endl;
|
|
NbKU = S->NbUKnots();
|
|
NbKV = S->NbVKnots();
|
|
o << "Number of knots in U : " << NbKU << std::endl;
|
|
for (ik = 1; ik <= NbKU; ik++)
|
|
{
|
|
o << " " << ik << " : " << S->UKnot(ik) << " mult : " << S->UMultiplicity(ik)
|
|
<< std::endl;
|
|
}
|
|
o << std::endl;
|
|
o << "Number of knots in V : " << NbKV << std::endl;
|
|
for (ik = 1; ik <= NbKV; ik++)
|
|
{
|
|
o << " " << ik << " : " << S->VKnot(ik) << " mult : " << S->VMultiplicity(ik)
|
|
<< std::endl;
|
|
}
|
|
o << std::endl;
|
|
}
|
|
}
|