1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

Integration of OCCT 6.5.0 from SVN

This commit is contained in:
bugmaster
2011-03-16 07:30:28 +00:00
committed by bugmaster
parent 4903637061
commit 7fd59977df
16375 changed files with 3882564 additions and 0 deletions

148
src/Approx/Approx.cdl Executable file
View File

@@ -0,0 +1,148 @@
-- File: Approx.cdl
-- Created: Tue Jan 26 11:16:41 1993
-- Author: Laurent PAINNOT
-- <lpa@sdsun1>
---Copyright: Matra Datavision 1993
package Approx
---Purpose: Tis package provides algorithms approximating a set of
-- points or curves with the possibility of dividing into
-- one or many bezier curves.
-- It also provides an instantiation for approximating
-- a continous function f(t) into one or many curves.
uses AdvApprox,
AppCont,
AppParCurves,
math,
gp,
GeomAbs,
Geom,
Geom2d,
Adaptor3d,
Adaptor2d,
TColStd,
TColGeom,
TColgp,
TCollection,
Standard,
StdFail
is
enumeration ParametrizationType is
ChordLength,
Centripetal,
IsoParametric
end;
enumeration Status is
PointsAdded,
NoPointsAdded,
NoApproximation
end;
deferred generic class TheLineTool; ---Template
---Purpose: This template is different from the one of AppParCurves.
-- In this case, it is possible to insert new points
-- during the approximation with ComputeLine.
---------------------------------------------
---Algorithms for Bezier curves construction:
---------------------------------------------
generic class ComputeLine, MyGradient;
---Purpose: Approximate a MultiLine with a cutting.
generic class ComputeCLine, MyLeastSquare;
---Purpose: Approximate a continous MultiLine with a cutting.
-- The Tool of the line is the tool from AppCont.
generic class ComputeCSurface, MySLeastSquare;
---Purpose: Approximate a continous Surface with or without cutting.
-- The tool is the tool of AppCont.
----------------------------------------------
---Algorithms for BSpline curves construction:
----------------------------------------------
generic class BSplComputeLine, MyBSplGradient, MyGradientbis;
----------------------------------------------
---Algorithms for BSpline Surface construction:
----------------------------------------------
class SweepApproximation;
deferred class SweepFunction;
-----------------------------------------------------------------
--- Transformation of connecting MultiCurves into a MultiBSpCurve
-----------------------------------------------------------------
class MCurvesToBSpCurve;
------------------------------------------------
---Algorithms for PCurve approximation:
------------------------------------------------
class CurveOnSurface;
class Curve3d;
class Curve2d;
------------------------------------------------
---Algorithms for PCurve approximation:
------------------------------------------------
class CurvilinearParameter;
class CurvlinFunc;
--------------------------
--- instantiate classes:
--------------------------
class SequenceOfHArray1OfReal instantiates Sequence from TCollection
(HArray1OfReal from TColStd);
-----------------------------------------------------------------
--- the folowing classes approximate a continous function f(t) in
--- one or many bezier curves.
-----------------------------------------------------------------
class FitAndDivide instantiates ComputeCLine from Approx
(Function from AppCont, FunctionTool from AppCont);
class FitAndDivide2d instantiates ComputeCLine from Approx
(Function2d from AppCont, FunctionTool2d from AppCont);
class SameParameter from Approx ;
---Purpose: this makes a 3D curve from Adaptor3d and
-- a curve on surface to check and build a 2D
-- BSpline curve that has the same parameterisation
-- as the 3D curve.
class Array1OfAdHSurface instantiates Array1 from TCollection
(HSurface from Adaptor3d) ;
class HArray1OfAdHSurface instantiates HArray1 from TCollection
(HSurface from Adaptor3d, Array1OfAdHSurface) ;
class Array1OfGTrsf2d instantiates Array1 from TCollection
(GTrsf2d from gp) ;
class HArray1OfGTrsf2d instantiates HArray1 from TCollection
(GTrsf2d from gp, Array1OfGTrsf2d) ;
-- class ApproxPoints from Approx ;
-- class ApproxPoints from Approx ;
---Purpose:
-- this approximates a series of points
-- Boundary conditions can be given as well
-- a given parameterisation
--
end Approx;

View File

@@ -0,0 +1,310 @@
-- File: Approx_BSplComputeLine.cdl
-- Created: Wed Sep 22 12:36:13 1993
-- Author: Modelistation
-- <model@zerox>
---Copyright: Matra Datavision 1993
generic class BSplComputeLine from Approx
(MultiLine as any;
LineTool as any) --as TheLineTool(MultiLine)
uses ParametrizationType from Approx,
SequenceOfReal from TColStd,
HArray1OfReal from TColStd,
HArray1OfInteger from TColStd,
Array1OfReal from TColStd,
Array1OfInteger from TColStd,
HArray1OfConstraintCouple from AppParCurves,
Constraint from AppParCurves,
MultiBSpCurve from AppParCurves,
MultiCurve from AppParCurves,
Vector from math
private class MyBSplGradient instantiates BSpGradient from AppParCurves
(MultiLine,
LineTool);
private class MyGradientbis instantiates Gradient from AppParCurves
(MultiLine,
LineTool);
is
Create(Line: MultiLine;
degreemin: Integer = 4;
degreemax: Integer = 8;
Tolerance3d: Real = 1.0e-3;
Tolerance2d: Real = 1.0e-6;
NbIterations: Integer = 5;
cutting: Boolean = Standard_True;
parametrization: ParametrizationType from Approx =
Approx_ChordLength;
Squares: Boolean = Standard_False)
---Purpose: The MultiLine <Line> will be approximated until tolerances
-- will be reached.
-- The approximation will be done from degreemin to degreemax
-- with a cutting if the corresponding boolean is True.
-- If <Squares> is True, the computation will be done with
-- no iteration at all.
--
-- The multiplicities of the internal knots is set by
-- default.
returns BSplComputeLine;
Create(Line: MultiLine;
Parameters: Vector from math;
degreemin: Integer = 4;
degreemax: Integer = 8;
Tolerance3d: Real = 1.0e-03;
Tolerance2d: Real = 1.0e-06;
NbIterations: Integer = 5;
cutting: Boolean = Standard_True;
Squares: Boolean = Standard_False)
---Purpose: The MultiLine <Line> will be approximated until tolerances
-- will be reached.
-- The approximation will be done from degreemin to degreemax
-- with a cutting if the corresponding boolean is True.
-- If <Squares> is True, the computation will be done with
-- no iteration at all.
returns BSplComputeLine;
Create(Parameters: Vector from math;
degreemin: Integer = 4;
degreemax: Integer = 8;
Tolerance3d: Real = 1.0e-03;
Tolerance2d: Real = 1.0e-06;
NbIterations: Integer = 5;
cutting: Boolean = Standard_True;
Squares: Boolean = Standard_False)
---Purpose: Initializes the fields of the algorithm.
returns BSplComputeLine;
Create(degreemin: Integer = 4;
degreemax: Integer = 8;
Tolerance3d: Real = 1.0e-03;
Tolerance2d: Real = 1.0e-06;
NbIterations: Integer = 5;
cutting: Boolean = Standard_True;
parametrization: ParametrizationType from Approx =
Approx_ChordLength;
Squares: Boolean = Standard_False)
---Purpose: Initializes the fields of the algorithm.
returns BSplComputeLine;
Interpol(me: in out; Line: MultiLine)
---Purpose: Constructs an interpolation of the MultiLine <Line>
-- The result will be a C2 curve of degree 3.
is static;
Init(me: in out; degreemin: Integer = 4;
degreemax: Integer = 8;
Tolerance3d: Real = 1.0e-03;
Tolerance2d: Real = 1.0e-06;
NbIterations: Integer = 5;
cutting: Boolean = Standard_True;
parametrization: ParametrizationType from Approx =
Approx_ChordLength;
Squares: Boolean = Standard_False)
---Purpose: Initializes the fields of the algorithm.
is static;
Perform(me: in out; Line: MultiLine)
---Purpose: runs the algorithm after having initialized the fields.
is static;
Compute(me: in out; Line: MultiLine; fpt, lpt: Integer;
Para: in out Vector from math; Knots: Array1OfReal;
Mults: in out Array1OfInteger)
---Purpose: is internally used in the algorithm.
returns Boolean
is static private;
ComputeCurve(me: in out; Line: MultiLine; firspt, lastpt: Integer)
---Purpose: is internally used in the algorithm.
returns Boolean
is static private;
Parameters(me; Line: MultiLine; firstP, LastP: Integer;
TheParameters: in out Vector)
---Purpose: computes new parameters between firstP and lastP.
is static private;
SetParameters(me: in out; ThePar: Vector from math)
---Purpose: The approximation will begin with the
-- set of parameters <ThePar>.
is static;
SetKnots(me: in out; Knots: Array1OfReal from TColStd)
---Purpose: The approximation will be done with the
-- set of knots <Knots>. The multiplicities will be set
-- with the degree and the desired continuity.
is static;
SetKnotsAndMultiplicities(me: in out;
Knots: Array1OfReal from TColStd;
Mults: Array1OfInteger from TColStd)
---Purpose: The approximation will be done with the
-- set of knots <Knots> and the multiplicities <Mults>.
is static;
SetDegrees(me: in out; degreemin, degreemax: Integer)
---Purpose: changes the degrees of the approximation.
is static;
SetTolerances(me: in out; Tolerance3d, Tolerance2d: Real)
---Purpose: Changes the tolerances of the approximation.
is static;
SetContinuity(me: in out; C: Integer)
---Purpose: sets the continuity of the spline.
-- if C = 2, the spline will be C2.
is static;
SetConstraints(me: in out; firstC, lastC: Constraint from AppParCurves)
---Purpose: changes the first and the last constraint points.
is static;
IsAllApproximated(me)
---Purpose: returns False if at a moment of the approximation,
-- the status NoApproximation has been sent by the user
-- when more points were needed.
returns Boolean
is static;
IsToleranceReached(me)
---Purpose: returns False if the status NoPointsAdded has been sent.
returns Boolean
is static;
Error(me; tol3d: in out Real; tol2d: in out Real)
---Purpose: returns the tolerances 2d and 3d of the MultiBSpCurve.
is static;
Value(me)
---Purpose: returns the result of the approximation.
---C++: return const&
returns MultiBSpCurve from AppParCurves;
ChangeValue(me: in out)
---Purpose: returns the result of the approximation.
---C++: return &
returns MultiBSpCurve from AppParCurves;
Parameters(me)
---Purpose: returns the new parameters of the approximation
-- corresponding to the points of the MultiBSpCurve.
---C++: return const&
returns Array1OfReal from TColStd
is static;
SearchFirstLambda(me; Line: MultiLine; Para: Vector;
Knots: Array1OfReal from TColStd;
V: Vector; index: Integer)
returns Real
is static private;
SearchLastLambda(me: ; Line: MultiLine; Para: Vector;
Knots: Array1OfReal from TColStd;
V: Vector; index: Integer)
returns Real
is static private;
TangencyVector(me; Line: MultiLine; C: MultiCurve from AppParCurves;
U: Real from Standard; V: in out Vector from math)
is static private;
FirstTangencyVector(me; Line: MultiLine; index: Integer; V: out Vector)
is static private;
LastTangencyVector(me; Line: MultiLine; index: Integer; V: out Vector)
is static private;
FindRealConstraints(me: in out; Line: MultiLine)
is static private;
fields
TheMultiBSpCurve: MultiBSpCurve from AppParCurves;
alldone : Boolean from Standard;
tolreached : Boolean from Standard;
Par : ParametrizationType from Approx;
myParameters : HArray1OfReal from TColStd;
myfirstParam : HArray1OfReal from TColStd;
myknots : HArray1OfReal from TColStd;
mymults : HArray1OfInteger from TColStd;
myhasknots : Boolean from Standard;
myhasmults : Boolean from Standard;
myConstraints : HArray1OfConstraintCouple from AppParCurves;
mydegremin : Integer from Standard;
mydegremax : Integer from Standard;
mytol3d : Real from Standard;
mytol2d : Real from Standard;
currenttol3d : Real from Standard;
currenttol2d : Real from Standard;
mycut : Boolean from Standard;
mysquares : Boolean from Standard;
myitermax : Integer from Standard;
myfirstC : Constraint from AppParCurves;
mylastC : Constraint from AppParCurves;
realfirstC : Constraint from AppParCurves;
reallastC : Constraint from AppParCurves;
mycont : Integer from Standard;
mylambda1 : Real from Standard;
mylambda2 : Real from Standard;
end BSplComputeLine;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,157 @@
-- File: Approx_ComputeCLine.cdl
-- Created: Fri May 14 15:22:38 1993
-- Author: Laurent PAINNOT
-- <lpa@phobox>
---Copyright: Matra Datavision 1993
generic class ComputeCLine from Approx
(MultiLine as any;
LineTool as any) --as TheLineTool from AppCont(MultiLine)
uses ParametrizationType from Approx,
SequenceOfReal from TColStd,
HArray1OfReal from TColStd,
SequenceOfMultiCurve from AppParCurves,
MultiCurve from AppParCurves,
Constraint from AppParCurves,
Vector from math
private class MyLeastSquare instantiates LeastSquare from AppCont
(MultiLine,
LineTool);
is
Create(Line: MultiLine;
degreemin: Integer = 3;
degreemax: Integer = 8;
Tolerance3d: Real = 1.0e-5;
Tolerance2d: Real = 1.0e-5;
cutting: Boolean = Standard_False;
FirstC: Constraint = AppParCurves_TangencyPoint;
LastC: Constraint = AppParCurves_TangencyPoint)
---Purpose: The MultiLine <Line> will be approximated until tolerances
-- will be reached.
-- The approximation will be done from degreemin to degreemax
-- with a cutting if the corresponding boolean is True.
returns ComputeCLine;
Create(degreemin: Integer = 3;
degreemax: Integer = 8;
Tolerance3d: Real = 1.0e-05;
Tolerance2d: Real = 1.0e-05;
cutting: Boolean = Standard_False;
FirstC: Constraint = AppParCurves_TangencyPoint;
LastC: Constraint = AppParCurves_TangencyPoint)
---Purpose: Initializes the fields of the algorithm.
returns ComputeCLine;
Perform(me: in out; Line: MultiLine)
---Purpose: runs the algorithm after having initialized the fields.
is static;
Compute(me: in out; Line: MultiLine; Ufirst, Ulast: Real;
TheTol3d, TheTol2d: in out Real)
---Purpose: is internally used by the algorithms.
returns Boolean
is static private;
SetDegrees(me: in out; degreemin, degreemax: Integer)
---Purpose: changes the degrees of the approximation.
is static;
SetTolerances(me: in out; Tolerance3d, Tolerance2d: Real)
---Purpose: Changes the tolerances of the approximation.
is static;
SetConstraints(me: in out; FirstC, LastC: Constraint)
---Purpose: Changes the constraints of the approximation.
is static;
IsAllApproximated(me)
---Purpose: returns False if at a moment of the approximation,
-- the status NoApproximation has been sent by the user
-- when more points were needed.
returns Boolean
is static;
IsToleranceReached(me)
---Purpose: returns False if the status NoPointsAdded has been sent.
returns Boolean
is static;
Error(me; Index: Integer; tol3d: in out Real; tol2d: in out Real)
---Purpose: returns the tolerances 2d and 3d of the <Index> MultiCurve.
is static;
NbMultiCurves(me)
---Purpose: Returns the number of MultiCurve doing the approximation
-- of the MultiLine.
returns Integer
is static;
Value(me; Index: Integer = 1)
---Purpose: returns the approximation MultiCurve of range <Index>.
returns MultiCurve from AppParCurves;
Parameters(me; Index: Integer; firstp, lastp: in out Real)
---purpose: returns the first and last parameters of the
-- <Index> MultiCurve.
is static;
fields
myMultiCurves: SequenceOfMultiCurve from AppParCurves;
myfirstparam: SequenceOfReal from TColStd;
mylastparam: SequenceOfReal from TColStd;
TheMultiCurve: MultiCurve from AppParCurves;
alldone: Boolean;
tolreached: Boolean;
Tolers3d: SequenceOfReal from TColStd;
Tolers2d: SequenceOfReal from TColStd;
mydegremin: Integer;
mydegremax: Integer;
mytol3d: Real;
mytol2d: Real;
currenttol3d: Real;
currenttol2d: Real;
mycut: Boolean;
myfirstC: Constraint;
mylastC: Constraint;
end ComputeCLine;

View File

@@ -0,0 +1,322 @@
// File Approx_ComputeCLine.gxx
// modified by Edward AGAPOV (eap) Tue Apr 2 2002 (occ265)
// -- stop cutting an interval to approximate if next decisions
// -- get worse on and on
#include <Approx_ParametrizationType.hxx>
#include Approx_MyLeastSquare_hxx
#include <TColStd_Array1OfReal.hxx>
#include <AppParCurves_Constraint.hxx>
#include <Approx_Status.hxx>
//=======================================================================
//function : Approx_ComputeCLine
//purpose : The MultiLine <Line> will be approximated until tolerances
// will be reached.
// The approximation will be done from degreemin to degreemax
// with a cutting if the corresponding boolean is True.
//=======================================================================
Approx_ComputeCLine::Approx_ComputeCLine
(const MultiLine& Line,
const Standard_Integer degreemin,
const Standard_Integer degreemax,
const Standard_Real Tolerance3d,
const Standard_Real Tolerance2d,
const Standard_Boolean cutting,
const AppParCurves_Constraint FirstC,
const AppParCurves_Constraint LastC)
{
mydegremin = degreemin;
mydegremax = degreemax;
mytol3d = Tolerance3d;
mytol2d = Tolerance2d;
mycut = cutting;
myfirstC = FirstC;
mylastC = LastC;
alldone = Standard_False;
Perform(Line);
}
//=======================================================================
//function : Approx_ComputeCLine
//purpose : Initializes the fields of the algorithm.
//=======================================================================
Approx_ComputeCLine::Approx_ComputeCLine
(const Standard_Integer degreemin,
const Standard_Integer degreemax,
const Standard_Real Tolerance3d,
const Standard_Real Tolerance2d,
const Standard_Boolean cutting,
const AppParCurves_Constraint FirstC,
const AppParCurves_Constraint LastC)
{
alldone = Standard_False;
mydegremin = degreemin;
mydegremax = degreemax;
mytol3d = Tolerance3d;
mytol2d = Tolerance2d;
mycut = cutting;
myfirstC = FirstC;
mylastC = LastC;
}
//=======================================================================
//function : Perform
//purpose : runs the algorithm after having initialized the fields.
//=======================================================================
void Approx_ComputeCLine::Perform(const MultiLine& Line)
{
Standard_Real UFirst, ULast;
Standard_Boolean Finish = Standard_False,
begin = Standard_True, Ok = Standard_False;
Standard_Real thetol3d, thetol2d;
UFirst = LineTool::FirstParameter(Line);
ULast = LineTool::LastParameter(Line);
Standard_Real TolU = (ULast-UFirst)*1.e-05;
Standard_Real myfirstU = UFirst;
Standard_Real mylastU = ULast;
if (!mycut) {
alldone = Compute(Line, UFirst, ULast, thetol3d, thetol2d);
if (!alldone) {
tolreached = Standard_False;
myfirstparam.Append(UFirst);
mylastparam.Append(ULast);
myMultiCurves.Append(TheMultiCurve);
Tolers3d.Append(currenttol3d);
Tolers2d.Append(currenttol2d);
}
}
else {
// previous decision to be taken if we get worse with next cut (eap)
AppParCurves_MultiCurve KeptMultiCurve;
Standard_Real KeptUfirst, KeptUlast, KeptT3d, KeptT2d;
Standard_Integer NbWorseDecis = 0, NbAllowedBadDecis = 10;
KeptT3d = RealLast(); KeptT2d = 0;
while (!Finish) {
// Gestion du decoupage de la multiline pour approximer:
if (!begin) {
if (Ok) {
// Calcul de la partie a approximer.
myfirstU = mylastU;
mylastU = ULast;
if (Abs(ULast-myfirstU) <= RealEpsilon()) {
Finish = Standard_True;
alldone = Standard_True;
return;
}
KeptT3d = RealLast(); KeptT2d = 0;
NbWorseDecis = 0;
}
else {
// keep best decison
if ((thetol3d + thetol2d) < (KeptT3d + KeptT2d)) {
KeptMultiCurve = TheMultiCurve;
KeptUfirst = myfirstU;
KeptUlast = mylastU;
KeptT3d = thetol3d;
KeptT2d = thetol2d;
}
// cut an interval
mylastU = (myfirstU + mylastU)/2;
}
}
if (Abs(myfirstU-mylastU) <= TolU) /*break;*/ // pour ne pas planter
NbAllowedBadDecis /= 2; // la station.
// Calcul des parametres sur ce nouvel intervalle.
Ok = Compute(Line, myfirstU, mylastU, thetol3d, thetol2d);
//cout << myfirstU << " - " << mylastU << " tol : " << thetol3d << " " << thetol2d << endl;
// is new decision better?
if ( !Ok && (thetol3d + thetol2d) > (KeptT3d + KeptT2d) )
{
NbWorseDecis++;
if (NbWorseDecis > NbAllowedBadDecis) {
Ok = Standard_True; // stop interval cutting, approx the rest part
mylastU = KeptUlast;
tolreached = Standard_False; // helas
myMultiCurves.Append(KeptMultiCurve);
Tolers3d.Append (KeptT3d);
Tolers2d.Append (KeptT2d);
myfirstparam.Append (KeptUfirst);
mylastparam.Append (KeptUlast);
}
}
begin = Standard_False;
} // while (!Finish)
}
}
//=======================================================================
//function : NbMultiCurves
//purpose : Returns the number of MultiCurve doing the approximation
// of the MultiLine.
//=======================================================================
Standard_Integer Approx_ComputeCLine::NbMultiCurves()const
{
return myMultiCurves.Length();
}
//=======================================================================
//function : Value
//purpose : returns the approximation MultiCurve of range <Index>.
//=======================================================================
AppParCurves_MultiCurve Approx_ComputeCLine::Value(const Standard_Integer Index)
const
{
return myMultiCurves.Value(Index);
}
//=======================================================================
//function : Compute
//purpose : is internally used by the algorithms.
//=======================================================================
Standard_Boolean Approx_ComputeCLine::Compute(const MultiLine& Line,
const Standard_Real Ufirst,
const Standard_Real Ulast,
Standard_Real& TheTol3d,
Standard_Real& TheTol2d)
{
Standard_Integer deg, NbPoints = 24;
Standard_Boolean mydone;
Standard_Real Fv;
for (deg = mydegremin; deg <= mydegremax; deg++) {
AppParCurves_MultiCurve mySCU(deg+1);
Approx_MyLeastSquare LSquare(Line, Ufirst, Ulast, myfirstC, mylastC,
deg, NbPoints);
mydone = LSquare.IsDone();
if (mydone) {
LSquare.Error(Fv, TheTol3d, TheTol2d);
if (TheTol3d <= mytol3d && TheTol2d <= mytol2d) {
mySCU = LSquare.Value();
// Stockage de la multicurve approximee.
tolreached = Standard_True;
myMultiCurves.Append(mySCU);
myfirstparam.Append(Ufirst);
mylastparam.Append(Ulast);
Tolers3d.Append(TheTol3d);
Tolers2d.Append(TheTol2d);
return Standard_True;
}
}
if (deg == mydegremax) {
TheMultiCurve = LSquare.Value();
currenttol3d = TheTol3d;
currenttol2d = TheTol2d;
}
}
return Standard_False;
}
//=======================================================================
//function : Parameters
//purpose : returns the first and last parameters of the
// <Index> MultiCurve.
//=======================================================================
void Approx_ComputeCLine::Parameters(const Standard_Integer Index,
Standard_Real& firstpar,
Standard_Real& lastpar) const
{
firstpar = myfirstparam.Value(Index);
lastpar = mylastparam.Value(Index);
}
//=======================================================================
//function : SetDegrees
//purpose : changes the degrees of the approximation.
//=======================================================================
void Approx_ComputeCLine::SetDegrees(const Standard_Integer degreemin,
const Standard_Integer degreemax)
{
mydegremin = degreemin;
mydegremax = degreemax;
}
//=======================================================================
//function : SetTolerances
//purpose : Changes the tolerances of the approximation.
//=======================================================================
void Approx_ComputeCLine::SetTolerances(const Standard_Real Tolerance3d,
const Standard_Real Tolerance2d)
{
mytol3d = Tolerance3d;
mytol2d = Tolerance2d;
}
//=======================================================================
//function : SetConstraints
//purpose : Changes the constraints of the approximation.
//=======================================================================
void Approx_ComputeCLine::SetConstraints(const AppParCurves_Constraint FirstC,
const AppParCurves_Constraint LastC)
{
myfirstC = FirstC;
mylastC = LastC;
}
//=======================================================================
//function : IsAllApproximated
//purpose : returns False if at a moment of the approximation,
// the status NoApproximation has been sent by the user
// when more points were needed.
//=======================================================================
Standard_Boolean Approx_ComputeCLine::IsAllApproximated()
const {
return alldone;
}
//=======================================================================
//function : IsToleranceReached
//purpose : returns False if the status NoPointsAdded has been sent.
//=======================================================================
Standard_Boolean Approx_ComputeCLine::IsToleranceReached()
const {
return tolreached;
}
//=======================================================================
//function : Error
//purpose : returns the tolerances 2d and 3d of the <Index> MultiCurve.
//=======================================================================
void Approx_ComputeCLine::Error(const Standard_Integer Index,
Standard_Real& tol3d,
Standard_Real& tol2d) const
{
tol3d = Tolers3d.Value(Index);
tol2d = Tolers2d.Value(Index);
}

View File

@@ -0,0 +1,153 @@
-- File: Approx_ComputeCSurface.cdl
-- Created: Thu Sep 9 16:21:47 1993
-- Author: Modelistation
-- <model@zerox>
---Copyright: Matra Datavision 1993
generic class ComputeCSurface from Approx
(Surface as any;
SurfaceTool as any) --as TheLineTool from AppCont(MultiLine)
uses SequenceOfReal from TColStd,
HArray1OfReal from TColStd,
SequenceOfSurface from TColGeom,
BezierSurface from Geom,
Constraint from AppParCurves
private class MySLeastSquare instantiates SurfLeastSquare from AppCont
(Surface,
SurfaceTool);
is
Create(Surf: Surface;
degreemin: Integer = 4;
degreemax: Integer = 8;
Tolerance3d: Real = 1.0e-3;
FirstCons: Constraint = AppParCurves_TangencyPoint;
LastUCons: Constraint = AppParCurves_TangencyPoint;
LastVCons: Constraint = AppParCurves_TangencyPoint;
LastCons: Constraint = AppParCurves_TangencyPoint;
cutting: Boolean = Standard_False)
---Purpose: The Surface <Surface> will be approximated until tolerances
-- will be reached.
-- The approximation will be done from degreemin to degreemax
-- with a cutting if the corresponding boolean is True.
returns ComputeCSurface;
Create(degreemin: Integer = 3;
degreemax: Integer = 8;
Tolerance3d: Real = 1.0e-03;
FirstCons: Constraint = AppParCurves_TangencyPoint;
LastUCons: Constraint = AppParCurves_TangencyPoint;
LastVCons: Constraint = AppParCurves_TangencyPoint;
LastCons: Constraint = AppParCurves_TangencyPoint;
cutting: Boolean = Standard_False)
---Purpose: Initializes the fields of the algorithm.
returns ComputeCSurface;
Perform(me: in out; Surf: Surface)
---Purpose: runs the algorithm after having initialized the fields.
is static;
Compute(me: in out; Surf: Surface; Ufirst, Ulast, Vfirst, Vlast: Real;
TheTol3d: in out Real)
---Purpose: is internally used by the algorithms.
returns Boolean
is static private;
SetDegrees(me: in out; degreemin, degreemax: Integer)
---Purpose: changes the degrees of the approximation.
is static;
SetTolerance(me: in out; Tolerance3d: Real)
---Purpose: Changes the tolerances of the approximation.
is static;
IsAllApproximated(me)
---Purpose: returns False if at a moment of the approximation,
-- NotDone was sent.
returns Boolean
is static;
IsToleranceReached(me)
---Purpose: returns False if the status no cut has been done
-- if necessary.
returns Boolean
is static;
Error(me; Index: Integer)
---Purpose: returns the tolerance of the <Index> approximated Surface.
returns Real
is static;
NbSurfaces(me)
---Purpose: Returns the number of Bezier Surfaces doing the
-- approximation of the Surface.
returns Integer
is static;
Value(me; Index: Integer = 1)
---Purpose: returns the approximation Surface of range <Index>.
returns BezierSurface from Geom;
Parameters(me; Index: Integer; firstU, lastU, firstV, lastV: in out Real)
---purpose: returns the first and last parameters of the
-- <Index> Surface.
is static;
fields
mySurfaces: SequenceOfSurface from TColGeom;
myfirstUparam: SequenceOfReal from TColStd;
mylastUparam: SequenceOfReal from TColStd;
myfirstVparam: SequenceOfReal from TColStd;
mylastVparam: SequenceOfReal from TColStd;
TheSurface: BezierSurface from Geom;
alldone: Boolean;
tolreached: Boolean;
Tolers3d: SequenceOfReal from TColStd;
mydegremin: Integer;
mydegremax: Integer;
mytol3d: Real;
currenttol3d: Real;
mycut: Boolean;
myfirstUCons: Constraint;
mylastUCons: Constraint;
mylastVCons: Constraint;
mylastCons: Constraint;
end ComputeCSurface;

View File

@@ -0,0 +1,231 @@
#include <Precision.hxx>
#include <TColStd_Array2OfReal.hxx>
Approx_ComputeCSurface::Approx_ComputeCSurface(
const Surface& Surf,
const Standard_Integer degreemin,
const Standard_Integer degreemax,
const Standard_Real Tolerance3d,
const AppParCurves_Constraint FirstCons,
const AppParCurves_Constraint LastUCons,
const AppParCurves_Constraint LastVCons,
const AppParCurves_Constraint LastCons,
const Standard_Boolean cutting)
{
mydegremin = degreemin;
mydegremax = degreemax;
mytol3d = Tolerance3d;
myfirstUCons = FirstCons;
mylastUCons = LastUCons;
mylastVCons = LastVCons;
mylastCons = LastCons;
mycut = cutting;
Perform(Surf);
}
Approx_ComputeCSurface::Approx_ComputeCSurface(
const Standard_Integer degreemin,
const Standard_Integer degreemax,
const Standard_Real Tolerance3d,
const AppParCurves_Constraint FirstCons,
const AppParCurves_Constraint LastUCons,
const AppParCurves_Constraint LastVCons,
const AppParCurves_Constraint LastCons,
const Standard_Boolean cutting)
{
mydegremin = degreemin;
mydegremax = degreemax;
mytol3d = Tolerance3d;
myfirstUCons = FirstCons;
mylastUCons = LastUCons;
mylastVCons = LastVCons;
mylastCons = LastCons;
mycut = cutting;
}
void Approx_ComputeCSurface::Perform(const Surface& Surf)
{
Standard_Real UFirst, ULast, VFirst, VLast;
UFirst = SurfaceTool::FirstUParameter(Surf);
ULast = SurfaceTool::LastUParameter(Surf);
VFirst = SurfaceTool::FirstVParameter(Surf);
VLast = SurfaceTool::LastVParameter(Surf);
Standard_Boolean Finish = Standard_False,
begin = Standard_True, Ok = Standard_False;
Standard_Real thetol3d;
Standard_Real myfirstU = UFirst, mylastU = ULast;
Standard_Real myfirstV = VFirst, mylastV = VLast;
Standard_Integer i;
TColStd_Array2OfReal Error(1, 50, 1, 50); // pour l instant
if (!mycut) {
alldone = Compute(Surf, UFirst, ULast, VFirst, VLast, thetol3d);
if (!alldone) {
tolreached = Standard_False;
mySurfaces.Append(TheSurface);
Tolers3d.Append(thetol3d);
myfirstUparam.Append(UFirst);
mylastUparam.Append(ULast);
myfirstVparam.Append(VFirst);
mylastVparam.Append(VLast);
}
}
else { // gestion du decoupage:
TColStd_SequenceOfReal TheU, TheV;
TheU.Append(UFirst);
TheU.Append(ULast);
TheV.Append(VFirst);
TheV.Append(VLast);
while (!Finish) {
Ok = Compute(Surf, myfirstU, mylastU, myfirstV, mylastV, thetol3d);
if (Ok) {
if (Abs(ULast-mylastU) <= Precision::PConfusion() &&
Abs(VLast-mylastV) <= Precision::PConfusion()) {
Finish = Standard_True;
alldone = Standard_True;
return;
}
myfirstU = mylastU;
mylastU = ULast;
}
else {
// choix du decoupage en u ou en v:
// si debut, en u:
if (begin) {
begin = Standard_False;
mylastU = (myfirstU + mylastU)/2.;
TheU.InsertAfter(1, mylastU);
Error.SetValue(1, 1, currenttol3d);
}
else {
Standard_Real tolu, tolv;
for (i = 1; i <= TheU.Length(); i++) {
}
}
}
}
}
}
Standard_Boolean Approx_ComputeCSurface::Compute(const Surface& Surf,
const Standard_Real Ufirst,
const Standard_Real Ulast,
const Standard_Real Vfirst,
const Standard_Real Vlast,
Standard_Real& TheTol3d)
{
Standard_Integer NbPoints = 12; // 12 * 12 sur la surface.
Standard_Integer degu, degv;
Standard_Real Fv;
for (degu = mydegremin; degu <= mydegremax; degu++) {
for (degv = mydegremin; degv <= mydegremax; degv++) {
Approx_MySLeastSquare LSQ(Surf, Ufirst, Ulast, Vfirst, Vlast,
myfirstUCons, mylastUCons,
mylastVCons, mylastCons,
degu, degv, NbPoints);
LSQ.Error(Fv, TheTol3d);
if (TheTol3d <= mytol3d) {
TheSurface = LSQ.Value();
mySurfaces.Append(TheSurface);
tolreached = Standard_True;
Tolers3d.Append(TheTol3d);
currenttol3d = TheTol3d;
myfirstUparam.Append(Ufirst);
mylastUparam.Append(Ulast);
myfirstVparam.Append(Vfirst);
mylastVparam.Append(Vlast);
return Standard_True;
}
if (degu == mydegremax && degv == mydegremax) {
TheSurface = LSQ.Value();
tolreached = Standard_False;
currenttol3d = TheTol3d;
}
}
}
return Standard_False;
}
Standard_Real Approx_ComputeCSurface::Error(const Standard_Integer Index)const
{
return Tolers3d.Value(Index);
}
Handle(Geom_BezierSurface) Approx_ComputeCSurface::Value(const Standard_Integer Index)const
{
return Handle(Geom_BezierSurface)::DownCast(mySurfaces.Value(Index));
}
Standard_Integer Approx_ComputeCSurface::NbSurfaces() const
{
return mySurfaces.Length();
}
void Approx_ComputeCSurface::Parameters(const Standard_Integer Index,
Standard_Real& firstU,
Standard_Real& lastU,
Standard_Real& firstV,
Standard_Real& lastV)const
{
firstU = myfirstUparam.Value(Index);
lastU = mylastUparam.Value(Index);
firstV = myfirstVparam.Value(Index);
lastV = mylastVparam.Value(Index);
}
Standard_Boolean Approx_ComputeCSurface::IsToleranceReached() const
{
return tolreached;
}
Standard_Boolean Approx_ComputeCSurface::IsAllApproximated() const
{
return alldone;
}
void Approx_ComputeCSurface::SetDegrees(const Standard_Integer degreemin,
const Standard_Integer degreemax)
{
mydegremin = degreemin;
mydegremax = degreemax;
}
void Approx_ComputeCSurface::SetTolerance(const Standard_Real Tolerance3d)
{
mytol3d = Tolerance3d;
}

274
src/Approx/Approx_ComputeLine.cdl Executable file
View File

@@ -0,0 +1,274 @@
-- File: Approx_ComputeLine.cdl
-- Created: Tue Jan 26 11:50:18 1993
-- Author: Laurent PAINNOT
-- <lpa@sdsun1>
---Copyright: Matra Datavision 1993
generic class ComputeLine from Approx
(MultiLine as any;
LineTool as any) --as TheLineTool(MultiLine)
uses ParametrizationType from Approx,
SequenceOfReal from TColStd,
HArray1OfReal from TColStd,
Array1OfReal from TColStd,
SequenceOfMultiCurve from AppParCurves,
HArray1OfMultiCurve from AppParCurves,
HArray1OfConstraintCouple from AppParCurves,
Constraint from AppParCurves,
SequenceOfHArray1OfReal from Approx,
MultiCurve from AppParCurves,
MultiBSpCurve from AppParCurves,
Vector from math
private class MyGradient instantiates Gradient from AppParCurves
(MultiLine,
LineTool);
is
Create(Line: MultiLine;
degreemin: Integer = 4;
degreemax: Integer = 8;
Tolerance3d: Real = 1.0e-3;
Tolerance2d: Real = 1.0e-6;
NbIterations: Integer = 5;
cutting: Boolean = Standard_True;
parametrization: ParametrizationType from Approx =
Approx_ChordLength;
Squares: Boolean = Standard_False)
---Purpose: The MultiLine <Line> will be approximated until tolerances
-- will be reached.
-- The approximation will be done from degreemin to degreemax
-- with a cutting if the corresponding boolean is True.
-- If <Squares> is True, the computation will be done with
-- no iteration at all.
returns ComputeLine;
Create(Line: MultiLine;
Parameters: Vector from math;
degreemin: Integer = 4;
degreemax: Integer = 8;
Tolerance3d: Real = 1.0e-03;
Tolerance2d: Real = 1.0e-06;
NbIterations: Integer = 5;
cutting: Boolean = Standard_True;
Squares: Boolean = Standard_False)
---Purpose: The MultiLine <Line> will be approximated until tolerances
-- will be reached.
-- The approximation will be done from degreemin to degreemax
-- with a cutting if the corresponding boolean is True.
-- If <Squares> is True, the computation will be done with
-- no iteration at all.
returns ComputeLine;
Create(Parameters: Vector from math;
degreemin: Integer = 4;
degreemax: Integer = 8;
Tolerance3d: Real = 1.0e-03;
Tolerance2d: Real = 1.0e-06;
NbIterations: Integer = 5;
cutting: Boolean = Standard_True;
Squares: Boolean = Standard_False)
---Purpose: Initializes the fields of the algorithm.
returns ComputeLine;
Create(degreemin: Integer = 4;
degreemax: Integer = 8;
Tolerance3d: Real = 1.0e-03;
Tolerance2d: Real = 1.0e-06;
NbIterations: Integer = 5;
cutting: Boolean = Standard_True;
parametrization: ParametrizationType from Approx =
Approx_ChordLength;
Squares: Boolean = Standard_False)
---Purpose: Initializes the fields of the algorithm.
returns ComputeLine;
Init(me: in out; degreemin: Integer = 4;
degreemax: Integer = 8;
Tolerance3d: Real = 1.0e-03;
Tolerance2d: Real = 1.0e-06;
NbIterations: Integer = 5;
cutting: Boolean = Standard_True;
parametrization: ParametrizationType from Approx =
Approx_ChordLength;
Squares: Boolean = Standard_False)
---Purpose: Initializes the fields of the algorithm.
is static;
Perform(me: in out; Line: MultiLine)
---Purpose: runs the algorithm after having initialized the fields.
is static;
Compute(me: in out; Line: MultiLine; fpt, lpt: Integer;
Para: in out Vector from math; TheTol3d, TheTol2d: in out Real)
---Purpose: is internally used in the algorithm.
returns Boolean
is static private;
ComputeCurve(me: in out; Line: MultiLine; firspt, lastpt: Integer)
---Purpose: is internally used in the algorithm.
returns Boolean
is static private;
Parameters(me; Line: MultiLine; firstP, LastP: Integer;
TheParameters: in out Vector)
---Purpose: computes new parameters between firstP and lastP.
is static private;
SetDegrees(me: in out; degreemin, degreemax: Integer)
---Purpose: changes the degrees of the approximation.
is static;
SetTolerances(me: in out; Tolerance3d, Tolerance2d: Real)
---Purpose: Changes the tolerances of the approximation.
is static;
SetConstraints(me: in out; firstC, lastC: Constraint from AppParCurves)
---Purpose: changes the first and the last constraint points.
is static;
IsAllApproximated(me)
---Purpose: returns False if at a moment of the approximation,
-- the status NoApproximation has been sent by the user
-- when more points were needed.
returns Boolean
is static;
IsToleranceReached(me)
---Purpose: returns False if the status NoPointsAdded has been sent.
returns Boolean
is static;
Error(me; Index: Integer; tol3d: in out Real; tol2d: in out Real)
---Purpose: returns the tolerances 2d and 3d of the <Index> MultiCurve.
is static;
NbMultiCurves(me)
---Purpose: Returns the number of MultiCurve doing the approximation
-- of the MultiLine.
returns Integer
is static;
Value(me; Index: Integer = 1)
---Purpose: returns the result of the approximation.
---C++: return const&
returns MultiCurve from AppParCurves
is static;
ChangeValue(me: in out; Index: Integer = 1)
---Purpose: returns the result of the approximation.
---C++: return &
returns MultiCurve from AppParCurves
is static;
SplineValue(me: in out)
---Purpose: returns the result of the approximation.
---C++: return const&
returns MultiBSpCurve from AppParCurves
is static;
Parametrization(me; partype : in out ParametrizationType from Approx)
---Purpose: returns the type of parametrization
is static;
Parameters(me; Index: Integer = 1)
---Purpose: returns the new parameters of the approximation
-- corresponding to the points of the multicurve <Index>.
---C++: return const&
returns Array1OfReal from TColStd
is static;
SearchFirstLambda(me; Line: MultiLine; Para: Vector;
V: Vector; index: Integer)
returns Real
is static private;
SearchLastLambda(me: ; Line: MultiLine; Para: Vector;
V: Vector; index: Integer)
returns Real
is static private;
FirstTangencyVector(me; Line: MultiLine; index: Integer; V: in out Vector)
is static private;
LastTangencyVector(me; Line: MultiLine; index: Integer; V: in out Vector)
is static private;
fields
myMultiCurves: SequenceOfMultiCurve from AppParCurves;
TheMultiCurve: MultiCurve from AppParCurves;
myspline : MultiBSpCurve from AppParCurves;
alldone: Boolean from Standard;
tolreached: Boolean from Standard;
Par: ParametrizationType from Approx;
myParameters: HArray1OfReal from TColStd;
myfirstParam: HArray1OfReal from TColStd;
myPar: SequenceOfHArray1OfReal from Approx;
Tolers3d: SequenceOfReal from TColStd;
Tolers2d: SequenceOfReal from TColStd;
myConstraints: HArray1OfConstraintCouple from AppParCurves;
mydegremin: Integer from Standard;
mydegremax: Integer from Standard;
mytol3d: Real from Standard;
mytol2d: Real from Standard;
currenttol3d: Real from Standard;
currenttol2d: Real from Standard;
mycut: Boolean from Standard;
mysquares: Boolean from Standard;
myitermax: Integer from Standard;
myfirstC: Constraint from AppParCurves;
mylastC: Constraint from AppParCurves;
end ComputeLine;

1255
src/Approx/Approx_ComputeLine.gxx Executable file

File diff suppressed because it is too large Load Diff

46
src/Approx/Approx_Curve2d.cdl Executable file
View File

@@ -0,0 +1,46 @@
-- File: Approx_2dCurve.cdl
-- Created: Tue Oct 28 16:28:35 1997
-- Author: Roman BORISOV
-- <rbv@velox.nnov.matra-dtv.fr>
---Copyright: Matra Datavision 1997
class Curve2d from Approx
---Purpose: Makes an approximation for HCurve2d from Adaptor3d
uses
HCurve2d from Adaptor2d,
Shape from GeomAbs,
BSplineCurve from Geom2d
is
Create(C2D : HCurve2d from Adaptor2d;
First,
Last,
TolU, TolV : Real;
Continuity : Shape from GeomAbs;
MaxDegree : Integer ;
MaxSegments : Integer)
returns Curve2d;
IsDone(me) returns Boolean from Standard;
HasResult(me) returns Boolean from Standard;
Curve(me)
returns BSplineCurve from Geom2d;
MaxError2dU(me) returns Real;
MaxError2dV(me) returns Real;
fields
myCurve : BSplineCurve from Geom2d;
myIsDone : Boolean from Standard;
myHasResult : Boolean from Standard;
myMaxError2dU : Real from Standard;
myMaxError2dV : Real from Standard;
end Curve2d;

160
src/Approx/Approx_Curve2d.cxx Executable file
View File

@@ -0,0 +1,160 @@
// File: Approx_Curve2d.cxx
// Created: Tue Oct 28 16:45:57 1997
// Author: Roman BORISOV
// <rbv@velox.nnov.matra-dtv.fr>
#include <Approx_Curve2d.ixx>
#include <AdvApprox_PrefAndRec.hxx>
#include <AdvApprox_ApproxAFunction.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <Precision.hxx>
//=======================================================================
//class : Approx_Curve2d_Eval
//purpose: evaluator class for approximation
//=======================================================================
class Approx_Curve2d_Eval : public AdvApprox_EvaluatorFunction
{
public:
Approx_Curve2d_Eval (const Handle(Adaptor2d_HCurve2d)& theFunc,
Standard_Real First, Standard_Real Last)
: fonct(theFunc) { StartEndSav[0] = First; StartEndSav[1] = Last; }
virtual void Evaluate (Standard_Integer *Dimension,
Standard_Real StartEnd[2],
Standard_Real *Parameter,
Standard_Integer *DerivativeRequest,
Standard_Real *Result, // [Dimension]
Standard_Integer *ErrorCode);
private:
Handle(Adaptor2d_HCurve2d) fonct;
Standard_Real StartEndSav[2];
};
void Approx_Curve2d_Eval::Evaluate (Standard_Integer *Dimension,
Standard_Real StartEnd[2],
Standard_Real *Param, // Parameter at which evaluation
Standard_Integer *Order, // Derivative Request
Standard_Real *Result,// [Dimension]
Standard_Integer *ErrorCode)
{
*ErrorCode = 0;
Standard_Real par = *Param;
// Dimension is incorrect
if (*Dimension!=2) {
*ErrorCode = 1;
}
// Parameter is incorrect
if ( par < StartEnd[0] || par > StartEnd[1] ) {
*ErrorCode = 2;
}
if(StartEnd[0] != StartEndSav[0] || StartEnd[1]!= StartEndSav[1])
{
fonct = fonct->Trim(StartEnd[0],StartEnd[1],Precision::PConfusion());
StartEndSav[0]=StartEnd[0];
StartEndSav[1]=StartEnd[1];
}
gp_Pnt2d pnt;
gp_Vec2d v1, v2;
switch (*Order) {
case 0:
pnt = fonct->Value(par);
Result[0] = pnt.X();
Result[1] = pnt.Y();
break;
case 1:
fonct->D1(par, pnt, v1);
Result[0] = v1.X();
Result[1] = v1.Y();
break;
case 2:
fonct->D2(par, pnt, v1, v2);
Result[0] = v2.X();
Result[1] = v2.Y();
break;
default:
Result[0] = Result[1] = 0.;
*ErrorCode = 3;
break;
}
}
Approx_Curve2d::Approx_Curve2d(const Handle(Adaptor2d_HCurve2d)& C2D,const Standard_Real First,const Standard_Real Last,const Standard_Real TolU,const Standard_Real TolV,const GeomAbs_Shape Continuity,const Standard_Integer MaxDegree,const Standard_Integer MaxSegments)
{
C2D->Trim(First,Last,Precision::PConfusion());
Standard_Integer Num1DSS=2, Num2DSS=0, Num3DSS=0;
Handle(TColStd_HArray1OfReal) TwoDTolNul, ThreeDTolNul;
Handle(TColStd_HArray1OfReal) OneDTol = new TColStd_HArray1OfReal(1,Num1DSS);
OneDTol->ChangeValue(1) = TolU;
OneDTol->ChangeValue(2) = TolV;
Standard_Integer NbInterv_C2 = C2D->NbIntervals(GeomAbs_C2);
TColStd_Array1OfReal CutPnts_C2(1, NbInterv_C2+1);
C2D->Intervals(CutPnts_C2, GeomAbs_C2);
Standard_Integer NbInterv_C3 = C2D->NbIntervals(GeomAbs_C3);
TColStd_Array1OfReal CutPnts_C3(1, NbInterv_C3+1);
C2D->Intervals(CutPnts_C3, GeomAbs_C3);
AdvApprox_PrefAndRec CutTool(CutPnts_C2,CutPnts_C3);
myMaxError2dU = 0;
myMaxError2dV = 0;
Approx_Curve2d_Eval ev (C2D, First, Last);
AdvApprox_ApproxAFunction aApprox (Num1DSS, Num2DSS, Num3DSS,
OneDTol, TwoDTolNul, ThreeDTolNul,
First, Last, Continuity,
MaxDegree, MaxSegments,
ev, CutTool);
myIsDone = aApprox.IsDone();
myHasResult = aApprox.HasResult();
if (myHasResult) {
TColgp_Array1OfPnt2d Poles2d(1,aApprox.NbPoles());
TColStd_Array1OfReal Poles1dU(1,aApprox.NbPoles());
aApprox.Poles1d(1, Poles1dU);
TColStd_Array1OfReal Poles1dV(1,aApprox.NbPoles());
aApprox.Poles1d(2, Poles1dV);
for(Standard_Integer i = 1; i <= aApprox.NbPoles(); i++)
Poles2d.SetValue(i, gp_Pnt2d(Poles1dU.Value(i), Poles1dV.Value(i)));
Handle(TColStd_HArray1OfReal) Knots = aApprox.Knots();
Handle(TColStd_HArray1OfInteger) Mults = aApprox.Multiplicities();
Standard_Integer Degree = aApprox.Degree();
myCurve = new Geom2d_BSplineCurve(Poles2d, Knots->Array1(), Mults->Array1(), Degree);
myMaxError2dU = aApprox.MaxError(1, 1);
myMaxError2dV = aApprox.MaxError(1, 2);
}
}
Standard_Boolean Approx_Curve2d::IsDone() const
{
return myIsDone;
}
Standard_Boolean Approx_Curve2d::HasResult() const
{
return myHasResult;
}
Handle(Geom2d_BSplineCurve) Approx_Curve2d::Curve() const
{
return myCurve;
}
Standard_Real Approx_Curve2d::MaxError2dU() const
{
return myMaxError2dU;
}
Standard_Real Approx_Curve2d::MaxError2dV() const
{
return myMaxError2dV;
}

52
src/Approx/Approx_Curve3d.cdl Executable file
View File

@@ -0,0 +1,52 @@
-- File: Approx_Curve3d.cdl
-- Created: Thu Aug 20 18:31:06 1998
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1998
class Curve3d from Approx
uses
HCurve from Adaptor3d,
BSplineCurve from Geom,
Shape from GeomAbs,
OutOfRange from Standard
raises OutOfRange from Standard,
ConstructionError from Standard
is
Create(Curve: HCurve from Adaptor3d;
Tol3d: Real;
Order: Shape from GeomAbs;
MaxSegments: Integer;
MaxDegree: Integer) returns Curve3d from Approx;
---Purpose: Approximation of a curve with respect of the
-- requiered tolerance Tol3D.
Curve(me) returns BSplineCurve from Geom;
IsDone(me) returns Boolean from Standard;
---Purpose: returns Standard_True if the approximation has
-- been done within requiered tolerance
HasResult(me) returns Boolean;
---Purpose: returns Standard_True if the approximation did come out
-- with a result that is not NECESSARELY within the required
-- tolerance
MaxError(me) returns Real from Standard;
---Purpose: returns the Maximum Error (>0 when an approximation
-- has been done, 0 if no approximation)
Dump(me; o: in out OStream);
---Purpose: Print on the stream o information about the object
fields
myIsDone : Boolean from Standard;
myHasResult : Boolean from Standard;
myBSplCurve : BSplineCurve from Geom;
myMaxError : Real from Standard;
end Curve3d;

166
src/Approx/Approx_Curve3d.cxx Executable file
View File

@@ -0,0 +1,166 @@
// File: Approx_Curve3d.cxx
// Created: Thu Aug 20 18:33:15 1998
// Author: Philippe MANGIN
// <pmn@sgi29>
#include <Approx_Curve3d.ixx>
#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
#include <GeomAdaptor_HCurve.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <AdvApprox_PrefAndRec.hxx>
#include <AdvApprox_ApproxAFunction.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <Precision.hxx>
//=======================================================================
//class : Approx_Curve3d_Eval
//purpose: evaluator class for approximation
//=======================================================================
class Approx_Curve3d_Eval : public AdvApprox_EvaluatorFunction
{
public:
Approx_Curve3d_Eval (const Handle(Adaptor3d_HCurve)& theFunc,
Standard_Real First, Standard_Real Last)
: fonct(theFunc) { StartEndSav[0] = First; StartEndSav[1] = Last; }
virtual void Evaluate (Standard_Integer *Dimension,
Standard_Real StartEnd[2],
Standard_Real *Parameter,
Standard_Integer *DerivativeRequest,
Standard_Real *Result, // [Dimension]
Standard_Integer *ErrorCode);
private:
Handle(Adaptor3d_HCurve) fonct;
Standard_Real StartEndSav[2];
};
void Approx_Curve3d_Eval::Evaluate (Standard_Integer *Dimension,
Standard_Real StartEnd[2],
Standard_Real *Param, // Parameter at which evaluation
Standard_Integer *Order, // Derivative Request
Standard_Real *Result,// [Dimension]
Standard_Integer *ErrorCode)
{
*ErrorCode = 0;
Standard_Real par = *Param;
// Dimension is incorrect
if (*Dimension!=3) {
*ErrorCode = 1;
}
if(StartEnd[0] != StartEndSav[0] || StartEnd[1]!= StartEndSav[1])
{
fonct = fonct->Trim(StartEnd[0],StartEnd[1],Precision::PConfusion());
StartEndSav[0]=StartEnd[0];
StartEndSav[1]=StartEnd[1];
}
gp_Pnt pnt;
gp_Vec v1, v2;
switch (*Order) {
case 0:
pnt = fonct->Value(par);
Result[0] = pnt.X();
Result[1] = pnt.Y();
Result[2] = pnt.Z();
break;
case 1:
fonct->D1(par, pnt, v1);
Result[0] = v1.X();
Result[1] = v1.Y();
Result[2] = v1.Z();
break;
case 2:
fonct->D2(par, pnt, v1, v2);
Result[0] = v2.X();
Result[1] = v2.Y();
Result[2] = v2.Z();
break;
default:
Result[0] = Result[1] = Result[2] = 0.;
*ErrorCode = 3;
break;
}
}
Approx_Curve3d::Approx_Curve3d(const Handle(Adaptor3d_HCurve)& Curve,
const Standard_Real Tol3d,
const GeomAbs_Shape Order,
const Standard_Integer MaxSegments,
const Standard_Integer MaxDegree)
{
// Initialisation of input parameters of AdvApprox
Standard_Integer Num1DSS=0, Num2DSS=0, Num3DSS=1;
Handle(TColStd_HArray1OfReal) OneDTolNul, TwoDTolNul;
Handle(TColStd_HArray1OfReal) ThreeDTol =
new TColStd_HArray1OfReal(1,Num3DSS);
ThreeDTol->Init(Tol3d);
Standard_Real First = Curve->FirstParameter();
Standard_Real Last = Curve->LastParameter();
Standard_Integer NbInterv_C2 = Curve->NbIntervals(GeomAbs_C2);
TColStd_Array1OfReal CutPnts_C2(1, NbInterv_C2+1);
Curve->Intervals(CutPnts_C2,GeomAbs_C2);
Standard_Integer NbInterv_C3 = Curve->NbIntervals(GeomAbs_C3);
TColStd_Array1OfReal CutPnts_C3(1, NbInterv_C3+1);
Curve->Intervals(CutPnts_C3,GeomAbs_C3);
AdvApprox_PrefAndRec CutTool(CutPnts_C2,CutPnts_C3);
myMaxError = 0;
Approx_Curve3d_Eval ev (Curve, First, Last);
AdvApprox_ApproxAFunction aApprox (Num1DSS, Num2DSS, Num3DSS,
OneDTolNul, TwoDTolNul, ThreeDTol,
First, Last, Order,
MaxDegree, MaxSegments,
ev, CutTool);
myIsDone = aApprox.IsDone();
myHasResult = aApprox.HasResult();
if (myHasResult) {
TColgp_Array1OfPnt Poles(1,aApprox.NbPoles());
aApprox.Poles(1,Poles);
Handle(TColStd_HArray1OfReal) Knots = aApprox.Knots();
Handle(TColStd_HArray1OfInteger) Mults = aApprox.Multiplicities();
Standard_Integer Degree = aApprox.Degree();
myBSplCurve = new Geom_BSplineCurve(Poles, Knots->Array1(), Mults->Array1(), Degree);
myMaxError = aApprox.MaxError(3, 1);
}
}
Handle(Geom_BSplineCurve) Approx_Curve3d::Curve() const
{
return myBSplCurve;
}
Standard_Boolean Approx_Curve3d::IsDone() const
{
return myIsDone;
}
Standard_Boolean Approx_Curve3d::HasResult() const
{
return myHasResult;
}
Standard_Real Approx_Curve3d::MaxError() const
{
return myMaxError;
}
void Approx_Curve3d::Dump(Standard_OStream& o) const
{
o << "******* Dump of ApproxCurve *******" << endl;
o << "*******Degree " << Curve()->Degree() << endl;
o << "*******NbSegments " << Curve()->NbKnots() - 1 << endl;
o << "*******Error " << MaxError() << endl;
}

View File

@@ -0,0 +1,70 @@
-- File: Approx_CurveOnSurface.cdl
-- Created: Tue Sep 30 12:28:05 1997
-- Author: Roman BORISOV
-- <rbv@orthodox.nnov.matra-dtv.fr>
---Copyright: Matra Datavision 1997
class CurveOnSurface from Approx
---Purpose:
---Purpose: Approximation of curve on surface
uses
Surface from Geom,
HCurve2d from Adaptor2d,
HSurface from Adaptor3d,
BSplineCurve from Geom,
BSplineCurve from Geom2d,
Shape from GeomAbs
raises OutOfRange from Standard,
ConstructionError from Standard
is
Create (C2D : HCurve2d from Adaptor2d;
Surf : HSurface from Adaptor3d;
First,
Last,
Tol : Real;
Continuity : Shape from GeomAbs;
MaxDegree : Integer ;
MaxSegments : Integer;
Only3d,
Only2d : Boolean from Standard = Standard_False)
returns CurveOnSurface from Approx
raises ConstructionError;
IsDone(me) returns Boolean from Standard;
HasResult(me) returns Boolean from Standard;
Curve3d(me)
returns BSplineCurve from Geom;
MaxError3d(me) returns Real;
Curve2d(me)
---Purpose:
returns BSplineCurve from Geom2d;
MaxError2dU(me) returns Real;
MaxError2dV(me) returns Real;
---Purpose : returns the maximum errors relativly to the U component or the V component of the
-- 2d Curve
fields
myCurve2d : BSplineCurve from Geom2d;
myCurve3d : BSplineCurve from Geom;
myIsDone : Boolean from Standard;
myHasResult : Boolean from Standard;
myError3d : Real from Standard;
myError2dU : Real from Standard;
myError2dV : Real from Standard;
end CurveOnSurface;

View File

@@ -0,0 +1,428 @@
// File: Approx_CurveOnSurface.cxx
// Created: Mon Oct 6 14:34:17 1997
// Author: Roman BORISOV
// <rbv@velox.nnov.matra-dtv.fr>
#include <Precision.hxx>
#include <Approx_CurveOnSurface.ixx>
#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
#include <GeomAdaptor_HSurface.hxx>
#include <Adaptor3d_CurveOnSurface.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <AdvApprox_ApproxAFunction.hxx>
#include <Adaptor3d_HCurve.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <GeomAdaptor_HCurve.hxx>
#include <Geom2dAdaptor_HCurve.hxx>
#include <Adaptor3d_HCurveOnSurface.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <AdvApprox_PrefAndRec.hxx>
#include <AdvApprox_DichoCutting.hxx>
//=======================================================================
//class : Approx_CurveOnSurface_Eval
//purpose: evaluator class for approximation of both 2d and 3d curves
//=======================================================================
class Approx_CurveOnSurface_Eval : public AdvApprox_EvaluatorFunction
{
public:
Approx_CurveOnSurface_Eval (const Handle(Adaptor3d_HCurve)& theFunc,
const Handle(Adaptor2d_HCurve2d)& theFunc2d,
Standard_Real First, Standard_Real Last)
: fonct(theFunc), fonct2d(theFunc2d)
{ StartEndSav[0] = First; StartEndSav[1] = Last; }
virtual void Evaluate (Standard_Integer *Dimension,
Standard_Real StartEnd[2],
Standard_Real *Parameter,
Standard_Integer *DerivativeRequest,
Standard_Real *Result, // [Dimension]
Standard_Integer *ErrorCode);
private:
Handle(Adaptor3d_HCurve) fonct;
Handle(Adaptor2d_HCurve2d) fonct2d;
Standard_Real StartEndSav[2];
};
void Approx_CurveOnSurface_Eval::Evaluate (Standard_Integer *Dimension,
Standard_Real StartEnd[2],
Standard_Real *Param, // Parameter at which evaluation
Standard_Integer *Order, // Derivative Request
Standard_Real *Result,// [Dimension]
Standard_Integer *ErrorCode)
{
*ErrorCode = 0;
Standard_Real par = *Param;
// Dimension is incorrect
if (*Dimension != 5) {
*ErrorCode = 1;
}
// Parameter is incorrect
if(StartEnd[0] != StartEndSav[0] || StartEnd[1]!= StartEndSav[1])
{
fonct = fonct->Trim(StartEnd[0],StartEnd[1],Precision::PConfusion());
fonct2d = fonct2d->Trim(StartEnd[0],StartEnd[1],
Precision::PConfusion());
StartEndSav[0]=StartEnd[0];
StartEndSav[1]=StartEnd[1];
}
gp_Pnt pnt;
gp_Pnt2d pnt2d;
switch (*Order) {
case 0:
{
fonct2d->D0(par, pnt2d);
fonct->D0(par, pnt);
Result[0] = pnt2d.X();
Result[1] = pnt2d.Y();
Result[2] = pnt.X();
Result[3] = pnt.Y();
Result[4] = pnt.Z();
break;
}
case 1:
{
gp_Vec v1;
gp_Vec2d v21;
fonct2d->D1(par, pnt2d, v21);
fonct->D1(par,pnt, v1);
Result[0] = v21.X();
Result[1] = v21.Y();
Result[2] = v1.X();
Result[3] = v1.Y();
Result[4] = v1.Z();
break;
}
case 2:
{
gp_Vec v1, v2;
gp_Vec2d v21, v22;
fonct2d->D2(par, pnt2d, v21, v22);
fonct->D2(par, pnt, v1, v2);
Result[0] = v22.X();
Result[1] = v22.Y();
Result[2] = v2.X();
Result[3] = v2.Y();
Result[4] = v2.Z();
break;
}
default:
Result[0] = Result[1] = Result[2] = Result[3] = Result[4] = 0.;
*ErrorCode = 3;
break;
}
}
//=======================================================================
//class : Approx_CurveOnSurface_Eval3d
//purpose: evaluator class for approximation of 3d curve
//=======================================================================
class Approx_CurveOnSurface_Eval3d : public AdvApprox_EvaluatorFunction
{
public:
Approx_CurveOnSurface_Eval3d (const Handle(Adaptor3d_HCurve)& theFunc,
Standard_Real First, Standard_Real Last)
: fonct(theFunc) { StartEndSav[0] = First; StartEndSav[1] = Last; }
virtual void Evaluate (Standard_Integer *Dimension,
Standard_Real StartEnd[2],
Standard_Real *Parameter,
Standard_Integer *DerivativeRequest,
Standard_Real *Result, // [Dimension]
Standard_Integer *ErrorCode);
private:
Handle(Adaptor3d_HCurve) fonct;
Standard_Real StartEndSav[2];
};
void Approx_CurveOnSurface_Eval3d::Evaluate (Standard_Integer *Dimension,
Standard_Real StartEnd[2],
Standard_Real *Param, // Parameter at which evaluation
Standard_Integer *Order, // Derivative Request
Standard_Real *Result,// [Dimension]
Standard_Integer *ErrorCode)
{
*ErrorCode = 0;
Standard_Real par = *Param;
// Dimension is incorrect
if (*Dimension != 3) {
*ErrorCode = 1;
}
// Parameter is incorrect
if(StartEnd[0] != StartEndSav[0] || StartEnd[1]!= StartEndSav[1])
{
fonct = fonct->Trim(StartEnd[0],StartEnd[1],Precision::PConfusion());
StartEndSav[0]=StartEnd[0];
StartEndSav[1]=StartEnd[1];
}
gp_Pnt pnt;
switch (*Order) {
case 0:
pnt = fonct->Value(par);
Result[0] = pnt.X();
Result[1] = pnt.Y();
Result[2] = pnt.Z();
break;
case 1:
{
gp_Vec v1;
fonct->D1(par, pnt, v1);
Result[0] = v1.X();
Result[1] = v1.Y();
Result[2] = v1.Z();
break;
}
case 2:
{
gp_Vec v1, v2;
fonct->D2(par, pnt, v1, v2);
Result[0] = v2.X();
Result[1] = v2.Y();
Result[2] = v2.Z();
break;
}
default:
Result[0] = Result[1] = Result[2] = 0.;
*ErrorCode = 3;
break;
}
}
//=======================================================================
//class : Approx_CurveOnSurface_Eval2d
//purpose: evaluator class for approximation of 2d curve
//=======================================================================
class Approx_CurveOnSurface_Eval2d : public AdvApprox_EvaluatorFunction
{
public:
Approx_CurveOnSurface_Eval2d (const Handle(Adaptor2d_HCurve2d)& theFunc2d,
Standard_Real First, Standard_Real Last)
: fonct2d(theFunc2d) { StartEndSav[0] = First; StartEndSav[1] = Last; }
virtual void Evaluate (Standard_Integer *Dimension,
Standard_Real StartEnd[2],
Standard_Real *Parameter,
Standard_Integer *DerivativeRequest,
Standard_Real *Result, // [Dimension]
Standard_Integer *ErrorCode);
private:
Handle(Adaptor2d_HCurve2d) fonct2d;
Standard_Real StartEndSav[2];
};
void Approx_CurveOnSurface_Eval2d::Evaluate (Standard_Integer *Dimension,
Standard_Real StartEnd[2],
Standard_Real *Param, // Parameter at which evaluation
Standard_Integer *Order, // Derivative Request
Standard_Real *Result,// [Dimension]
Standard_Integer *ErrorCode)
{
*ErrorCode = 0;
Standard_Real par = *Param;
// Dimension is incorrect
if (*Dimension != 2) {
*ErrorCode = 1;
}
// Parameter is incorrect
if(StartEnd[0] != StartEndSav[0] || StartEnd[1]!= StartEndSav[1])
{
fonct2d = fonct2d->Trim(StartEnd[0],StartEnd[1],Precision::PConfusion());
StartEndSav[0]=StartEnd[0];
StartEndSav[1]=StartEnd[1];
}
gp_Pnt2d pnt;
switch (*Order) {
case 0:
{
pnt = fonct2d->Value(par);
Result[0] = pnt.X();
Result[1] = pnt.Y();
break;
}
case 1:
{
gp_Vec2d v1;
fonct2d->D1(par, pnt, v1);
Result[0] = v1.X();
Result[1] = v1.Y();
break;
}
case 2:
{
gp_Vec2d v1, v2;
fonct2d->D2(par, pnt, v1, v2);
Result[0] = v2.X();
Result[1] = v2.Y();
break;
}
default:
Result[0] = Result[1] = 0.;
*ErrorCode = 3;
break;
}
}
Approx_CurveOnSurface::Approx_CurveOnSurface(const Handle(Adaptor2d_HCurve2d)& C2D,
const Handle(Adaptor3d_HSurface)& Surf,
const Standard_Real First,
const Standard_Real Last,
const Standard_Real Tol,
const GeomAbs_Shape S,
const Standard_Integer MaxDegree,
const Standard_Integer MaxSegments,
const Standard_Boolean only3d,
const Standard_Boolean only2d)
{
myIsDone = Standard_False;
if(only3d && only2d) Standard_ConstructionError::Raise();
GeomAbs_Shape Order = S;
Handle( Adaptor2d_HCurve2d ) TrimmedC2D = C2D->Trim( First, Last, Precision::PConfusion() );
Adaptor3d_CurveOnSurface COnS( TrimmedC2D, Surf );
Handle(Adaptor3d_HCurveOnSurface) HCOnS = new Adaptor3d_HCurveOnSurface();
HCOnS->Set(COnS);
Standard_Integer Num1DSS = 0, Num2DSS=0, Num3DSS=0;
Handle(TColStd_HArray1OfReal) OneDTol;
Handle(TColStd_HArray1OfReal) TwoDTolNul;
Handle(TColStd_HArray1OfReal) ThreeDTol;
// create evaluators and choose appropriate one
Approx_CurveOnSurface_Eval3d Eval3dCvOnSurf (HCOnS, First, Last);
Approx_CurveOnSurface_Eval2d Eval2dCvOnSurf ( TrimmedC2D, First, Last);
Approx_CurveOnSurface_Eval EvalCvOnSurf (HCOnS, TrimmedC2D, First, Last);
AdvApprox_EvaluatorFunction* EvalPtr;
if ( only3d ) EvalPtr = &Eval3dCvOnSurf;
else if ( only2d ) EvalPtr = &Eval2dCvOnSurf;
else EvalPtr = &EvalCvOnSurf;
// Initialization for 2d approximation
if(!only3d) {
Num1DSS = 2;
OneDTol = new TColStd_HArray1OfReal(1,Num1DSS);
Standard_Real TolU, TolV;
TolU = Surf->UResolution(Tol)/2;
TolV = Surf->VResolution(Tol)/2;
OneDTol->SetValue(1,TolU);
OneDTol->SetValue(2,TolV);
}
if(!only2d) {
Num3DSS=1;
ThreeDTol = new TColStd_HArray1OfReal(1,Num3DSS);
ThreeDTol->Init(Tol/2);
}
myError2dU = 0;
myError2dV = 0;
myError3d = 0;
Standard_Integer NbInterv_C2 = HCOnS->NbIntervals(GeomAbs_C2);
TColStd_Array1OfReal CutPnts_C2(1, NbInterv_C2 + 1);
HCOnS->Intervals(CutPnts_C2, GeomAbs_C2);
Standard_Integer NbInterv_C3 = HCOnS->NbIntervals(GeomAbs_C3);
TColStd_Array1OfReal CutPnts_C3(1, NbInterv_C3 + 1);
HCOnS->Intervals(CutPnts_C3, GeomAbs_C3);
AdvApprox_PrefAndRec CutTool(CutPnts_C2,CutPnts_C3);
AdvApprox_ApproxAFunction aApprox (Num1DSS, Num2DSS, Num3DSS,
OneDTol, TwoDTolNul, ThreeDTol,
First, Last, Order,
MaxDegree, MaxSegments,
*EvalPtr, CutTool);
myIsDone = aApprox.IsDone();
myHasResult = aApprox.HasResult();
if (myHasResult) {
Handle(TColStd_HArray1OfReal) Knots = aApprox.Knots();
Handle(TColStd_HArray1OfInteger) Mults = aApprox.Multiplicities();
Standard_Integer Degree = aApprox.Degree();
if(!only2d)
{
TColgp_Array1OfPnt Poles(1,aApprox.NbPoles());
aApprox.Poles(1,Poles);
myCurve3d = new Geom_BSplineCurve(Poles, Knots->Array1(), Mults->Array1(), Degree);
myError3d = aApprox.MaxError(3, 1);
}
if(!only3d)
{
TColgp_Array1OfPnt2d Poles2d(1,aApprox.NbPoles());
TColStd_Array1OfReal Poles1dU(1,aApprox.NbPoles());
aApprox.Poles1d(1, Poles1dU);
TColStd_Array1OfReal Poles1dV(1,aApprox.NbPoles());
aApprox.Poles1d(2, Poles1dV);
for(Standard_Integer i = 1; i <= aApprox.NbPoles(); i++)
Poles2d.SetValue(i, gp_Pnt2d(Poles1dU.Value(i), Poles1dV.Value(i)));
myCurve2d = new Geom2d_BSplineCurve(Poles2d, Knots->Array1(), Mults->Array1(), Degree);
myError2dU = aApprox.MaxError(1, 1);
myError2dV = aApprox.MaxError(1, 2);
}
}
// }
}
Standard_Boolean Approx_CurveOnSurface::IsDone() const
{
return myIsDone;
}
Standard_Boolean Approx_CurveOnSurface::HasResult() const
{
return myHasResult;
}
Handle(Geom_BSplineCurve) Approx_CurveOnSurface::Curve3d() const
{
return myCurve3d;
}
Handle(Geom2d_BSplineCurve) Approx_CurveOnSurface::Curve2d() const
{
return myCurve2d;
}
Standard_Real Approx_CurveOnSurface::MaxError3d() const
{
return myError3d;
}
Standard_Real Approx_CurveOnSurface::MaxError2dU() const
{
return myError2dU;
}
Standard_Real Approx_CurveOnSurface::MaxError2dV() const
{
return myError2dV;
}

View File

@@ -0,0 +1,115 @@
-- File: Approx_CurvilinearParameter.cdl
-- Created: Fri Aug 22 08:19:47 1997
-- Author: Jeannine PANCIATICI, Sergey SOKOLOV
-- <ssv@nonox.nnov.matra-dtv.fr>
---Copyright: Matra Datavision 1997
class CurvilinearParameter from Approx
---Purpose: Approximation of a Curve to make its parameter be its
-- curvilinear abscissa
-- If the curve is a curve on a surface S, C2D is the corresponding Pcurve,
-- we considere the curve is given by its representation S(C2D(u))
-- If the curve is a curve on 2 surfaces S1 and S2 and C2D1 C2D2 are
-- the two corresponding Pcurve, we considere the curve is given
-- by its representation 1/2(S1(C2D1(u) + S2 (C2D2(u)))
uses
Shape from GeomAbs,
HSurface from Adaptor3d,
HCurve from Adaptor3d,
HCurve2d from Adaptor2d,
BSplineCurve from Geom,
BSplineCurve from Geom2d
raises OutOfRange from Standard,
ConstructionError from Standard
is
Create (C3D : HCurve from Adaptor3d;
Tol : Real;
Order : Shape from GeomAbs;
MaxDegree : Integer;
MaxSegments : Integer)
returns CurvilinearParameter from Approx
---Purpose : case of a free 3D curve
--
raises ConstructionError;
-- If the length of the curve can't be computed or if the length is null
Create (C2D : HCurve2d from Adaptor2d;
Surf : HSurface from Adaptor3d;
Tol : Real;
Order : Shape from GeomAbs;
MaxDegree : Integer;
MaxSegments : Integer)
returns CurvilinearParameter from Approx
---Purpose : case of a curve on one surface
--
raises ConstructionError;
-- If the length of the curve can't be computed or if the length is null
Create (C2D1 : HCurve2d from Adaptor2d;
Surf1 : HSurface from Adaptor3d;
C2D2 : HCurve2d from Adaptor2d;
Surf2 : HSurface from Adaptor3d;
Tol : Real;
Order : Shape from GeomAbs;
MaxDegree : Integer;
MaxSegments : Integer)
returns CurvilinearParameter from Approx
---Purpose : case of a curve on two surfaces
--
raises ConstructionError;
-- If the length of the curve can't be computed or if the length is null
IsDone(me) returns Boolean from Standard;
-- True if the approximation succeeded within the imposed
-- tolerances
HasResult(me) returns Boolean from Standard;
-- True if the approximation did come out with a result that
-- is not NECESSARELY within the required tolerance
Curve3d(me) returns BSplineCurve from Geom;
--- Purpose: returns the Bspline curve corresponding to the reparametrized 3D curve
MaxError3d (me) returns Real;
--- Purpose: returns the maximum error on the reparametrized 3D curve
Curve2d1(me) returns BSplineCurve from Geom2d;
---Purpose: returns the BsplineCurve representing the reparametrized 2D curve on the
-- first surface (case of a curve on one or two surfaces)
MaxError2d1(me) returns Real;
---Purpose: returns the maximum error on the first reparametrized 2D curve
Curve2d2(me) returns BSplineCurve from Geom2d;
---Purpose: returns the BsplineCurve representing the reparametrized 2D curve on the
-- second surface (case of a curve on two surfaces)
MaxError2d2(me) returns Real;
---Purpose: returns the maximum error on the second reparametrized 2D curve
Dump(me; o: in out OStream);
---Purpose: print the maximum errors(s)
ToleranceComputation(myclass; C2D : HCurve2d from Adaptor2d; S : HSurface from Adaptor3d;
MaxNumber : Integer; Tol : Real; TolV, TolW : out Real)
is private;
fields
myCase : Integer from Standard;
myDone : Boolean from Standard;
myHasResult : Boolean from Standard;
myCurve3d : BSplineCurve from Geom;
myMaxError3d : Real from Standard;
myCurve2d1 : BSplineCurve from Geom2d;
myMaxError2d1 : Real from Standard;
myCurve2d2 : BSplineCurve from Geom2d;
myMaxError2d2 : Real from Standard;
end CurvilinearParameter;

View File

@@ -0,0 +1,655 @@
// File: Approx_CurvilinearParameter.cxx
// Created: Fri Aug 22 09:11:03 1997
// Author: Sergey SOKOLOV
// <ssv@nonox.nnov.matra-dtv.fr>
#include <Approx_CurvilinearParameter.ixx>
#include <Adaptor3d_Curve.hxx>
#include <GCPnts_AbscissaPoint.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec.hxx>
#include <gp_Vec2d.hxx>
#include <GeomAbs_Shape.hxx>
#include <AdvApprox_ApproxAFunction.hxx>
#include <Geom_BSplineCurve.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <TColStd_HArray1OfInteger.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <GeomAdaptor_HCurve.hxx>
#include <GeomAdaptor_HSurface.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <AdvApprox_PrefAndRec.hxx>
#include <Adaptor3d_CurveOnSurface.hxx>
#include <Precision.hxx>
#include <Geom2d_BSplineCurve.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <math_Vector.hxx>
#include <CPnts_AbscissaPoint.hxx>
#include <Approx_CurvlinFunc.hxx>
#ifdef DEB
#include <OSD_Timer.hxx>
static OSD_Chronometer chr_total, chr_init, chr_approx;
Standard_Real t_total, t_init, t_approx;
void InitChron(OSD_Chronometer& ch)
{
ch.Reset();
ch.Start();
}
void ResultChron( OSD_Chronometer & ch, Standard_Real & time)
{
Standard_Real tch ;
ch.Stop();
ch.Show(tch);
time=time +tch;
}
Standard_IMPORT Standard_Integer uparam_count;
Standard_IMPORT Standard_Real t_uparam;
#endif
//=======================================================================
//class : Approx_CurvilinearParameter_EvalCurv
//purpose : case of a free 3D curve
//=======================================================================
class Approx_CurvilinearParameter_EvalCurv : public AdvApprox_EvaluatorFunction
{
public:
Approx_CurvilinearParameter_EvalCurv (const Handle(Approx_CurvlinFunc)& theFunc,
Standard_Real First, Standard_Real Last)
: fonct(theFunc) { StartEndSav[0] = First; StartEndSav[1] = Last; }
virtual void Evaluate (Standard_Integer *Dimension,
Standard_Real StartEnd[2],
Standard_Real *Parameter,
Standard_Integer *DerivativeRequest,
Standard_Real *Result, // [Dimension]
Standard_Integer *ErrorCode);
private:
Handle(Approx_CurvlinFunc) fonct;
Standard_Real StartEndSav[2];
};
void Approx_CurvilinearParameter_EvalCurv::Evaluate (Standard_Integer * Dimension,
Standard_Real * StartEnd,
Standard_Real * Param,
Standard_Integer * Order,
Standard_Real * Result,
Standard_Integer * ErrorCode)
{
*ErrorCode = 0;
Standard_Real S = *Param;
TColStd_Array1OfReal Res(0, 2);
Standard_Integer i;
// Dimension is incorrect
if (*Dimension != 3) {
*ErrorCode = 1;
}
// Parameter is incorrect
if ( S < StartEnd[0] || S > StartEnd[1] ) {
*ErrorCode = 2;
}
if(StartEnd[0] != StartEndSav[0] || StartEnd[1]!= StartEndSav[1])
{
fonct->Trim(StartEnd[0],StartEnd[1], Precision::Confusion());
StartEndSav[0]=StartEnd[0];
StartEndSav[1]=StartEnd[1];
}
if(!fonct->EvalCase1(S, *Order, Res)) {
*ErrorCode = 3;
}
for(i = 0; i <= 2; i++)
Result[i] = Res(i);
}
Approx_CurvilinearParameter::Approx_CurvilinearParameter(const Handle(Adaptor3d_HCurve)& C3D,
const Standard_Real Tol,
const GeomAbs_Shape Order,
const Standard_Integer MaxDegree,
const Standard_Integer MaxSegments)
{
#ifdef DEB
t_total = t_init = t_approx = t_uparam = 0;
uparam_count = 0;
InitChron(chr_total);
#endif
myCase = 1;
// Initialisation of input parameters of AdvApprox
Standard_Integer Num1DSS=0, Num2DSS=0, Num3DSS=1;
Handle(TColStd_HArray1OfReal) OneDTolNul, TwoDTolNul;
Handle(TColStd_HArray1OfReal) ThreeDTol = new TColStd_HArray1OfReal(1,Num3DSS);
ThreeDTol->Init(Tol);
#ifdef DEB
InitChron(chr_init);
#endif
Handle(Approx_CurvlinFunc) fonct = new Approx_CurvlinFunc(C3D, Tol/10);
#ifdef DEB
ResultChron(chr_init, t_init);
#endif
Standard_Real FirstS = fonct->FirstParameter();
Standard_Real LastS = fonct->LastParameter();
Standard_Integer NbInterv_C2 = fonct->NbIntervals(GeomAbs_C2);
TColStd_Array1OfReal CutPnts_C2(1, NbInterv_C2+1);
fonct->Intervals(CutPnts_C2,GeomAbs_C2);
Standard_Integer NbInterv_C3 = fonct->NbIntervals(GeomAbs_C3);
TColStd_Array1OfReal CutPnts_C3(1, NbInterv_C3+1);
fonct->Intervals(CutPnts_C3,GeomAbs_C3);
AdvApprox_PrefAndRec CutTool(CutPnts_C2,CutPnts_C3);
#ifdef DEB
InitChron(chr_approx);
#endif
Approx_CurvilinearParameter_EvalCurv evC (fonct, FirstS, LastS);
AdvApprox_ApproxAFunction aApprox (Num1DSS, Num2DSS, Num3DSS,
OneDTolNul, TwoDTolNul, ThreeDTol,
FirstS, LastS, Order,
MaxDegree, MaxSegments,
evC, CutTool);
#ifdef DEB
ResultChron(chr_approx, t_approx);
#endif
myDone = aApprox.IsDone();
myHasResult = aApprox.HasResult();
if (myHasResult) {
TColgp_Array1OfPnt Poles(1,aApprox.NbPoles());
aApprox.Poles(1,Poles);
Handle(TColStd_HArray1OfReal) Knots = aApprox.Knots();
Handle(TColStd_HArray1OfInteger) Mults = aApprox.Multiplicities();
Standard_Integer Degree = aApprox.Degree();
myCurve3d = new Geom_BSplineCurve(Poles, Knots->Array1(), Mults->Array1(), Degree);
}
myMaxError3d = aApprox.MaxError(3,1);
#ifdef DEB
ResultChron(chr_total, t_total);
cout<<" total reparametrization time = "<<t_total<<endl;
cout<<"initialization time = "<<t_init<<endl;
cout<<"approximation time = "<<t_approx<<endl;
cout<<"total time for uparam computation = "<<t_uparam<<endl;
cout<<"number uparam calles = "<<uparam_count<<endl;
#endif
}
//=======================================================================
//class : Approx_CurvilinearParameter_EvalCurvOnSurf
//purpose : case of a curve on one surface
//=======================================================================
class Approx_CurvilinearParameter_EvalCurvOnSurf : public AdvApprox_EvaluatorFunction
{
public:
Approx_CurvilinearParameter_EvalCurvOnSurf (const Handle(Approx_CurvlinFunc)& theFunc,
Standard_Real First, Standard_Real Last)
: fonct(theFunc) { StartEndSav[0] = First; StartEndSav[1] = Last; }
virtual void Evaluate (Standard_Integer *Dimension,
Standard_Real StartEnd[2],
Standard_Real *Parameter,
Standard_Integer *DerivativeRequest,
Standard_Real *Result, // [Dimension]
Standard_Integer *ErrorCode);
private:
Handle(Approx_CurvlinFunc) fonct;
Standard_Real StartEndSav[2];
};
void Approx_CurvilinearParameter_EvalCurvOnSurf::Evaluate (Standard_Integer * Dimension,
Standard_Real * StartEnd,
Standard_Real * Param,
Standard_Integer * Order,
Standard_Real * Result,
Standard_Integer * ErrorCode)
{
*ErrorCode = 0;
Standard_Real S = *Param;
TColStd_Array1OfReal Res(0, 4);
Standard_Integer i;
// Dimension is incorrect
if (*Dimension != 5) {
*ErrorCode = 1;
}
// Parameter is incorrect
if ( S < StartEnd[0] || S > StartEnd[1] ) {
*ErrorCode = 2;
}
if(StartEnd[0] != StartEndSav[0] || StartEnd[1]!= StartEndSav[1])
{
fonct->Trim(StartEnd[0],StartEnd[1], Precision::Confusion());
StartEndSav[0]=StartEnd[0];
StartEndSav[1]=StartEnd[1];
}
if(!fonct->EvalCase2(S, *Order, Res)) {
*ErrorCode = 3;
}
for(i = 0; i <= 4; i++)
Result[i] = Res(i);
}
Approx_CurvilinearParameter::Approx_CurvilinearParameter(const Handle(Adaptor2d_HCurve2d)& C2D,
const Handle(Adaptor3d_HSurface)& Surf,
const Standard_Real Tol,
const GeomAbs_Shape Order,
const Standard_Integer MaxDegree,
const Standard_Integer MaxSegments)
{
#ifdef DEB
t_total = t_init = t_approx = t_uparam = 0;
uparam_count = 0;
InitChron(chr_total);
#endif
myCase = 2;
// Initialisation of input parameters of AdvApprox
Standard_Integer Num1DSS=2, Num2DSS=0, Num3DSS=1, i;
Handle(TColStd_HArray1OfReal) OneDTol = new TColStd_HArray1OfReal(1,Num1DSS);
Standard_Real TolV,TolW;
ToleranceComputation(C2D,Surf,10,Tol,TolV,TolW);
OneDTol->SetValue(1,TolV);
OneDTol->SetValue(2,TolW);
OneDTol->SetValue(1,Tol);
OneDTol->SetValue(2,Tol);
Handle(TColStd_HArray1OfReal) TwoDTolNul;
Handle(TColStd_HArray1OfReal) ThreeDTol = new TColStd_HArray1OfReal(1,Num3DSS);
ThreeDTol->Init(Tol/2.);
#ifdef DEB
InitChron(chr_init);
#endif
Handle(Approx_CurvlinFunc) fonct = new Approx_CurvlinFunc(C2D, Surf, Tol/20);
#ifdef DEB
ResultChron(chr_init, t_init);
#endif
Standard_Real FirstS = fonct->FirstParameter();
Standard_Real LastS = fonct->LastParameter();
Standard_Integer NbInterv_C2 = fonct->NbIntervals(GeomAbs_C2);
TColStd_Array1OfReal CutPnts_C2(1, NbInterv_C2+1);
fonct->Intervals(CutPnts_C2,GeomAbs_C2);
Standard_Integer NbInterv_C3 = fonct->NbIntervals(GeomAbs_C3);
TColStd_Array1OfReal CutPnts_C3(1, NbInterv_C3+1);
fonct->Intervals(CutPnts_C3,GeomAbs_C3);
AdvApprox_PrefAndRec CutTool(CutPnts_C2,CutPnts_C3);
#ifdef DEB
InitChron(chr_approx);
#endif
Approx_CurvilinearParameter_EvalCurvOnSurf evCOnS (fonct, FirstS, LastS);
AdvApprox_ApproxAFunction aApprox (Num1DSS, Num2DSS, Num3DSS,
OneDTol, TwoDTolNul, ThreeDTol,
FirstS, LastS, Order,
MaxDegree, MaxSegments,
evCOnS, CutTool);
#ifdef DEB
ResultChron(chr_approx, t_approx);
#endif
myDone = aApprox.IsDone();
myHasResult = aApprox.HasResult();
if (myHasResult) {
Standard_Integer NbPoles = aApprox.NbPoles();
TColgp_Array1OfPnt Poles (1,NbPoles);
TColgp_Array1OfPnt2d Poles2d(1,NbPoles);
TColStd_Array1OfReal Poles1d(1,NbPoles);
aApprox.Poles(1,Poles);
aApprox.Poles1d(1,Poles1d);
for (i=1; i<=NbPoles; i++)
Poles2d(i).SetX(Poles1d(i));
aApprox.Poles1d(2,Poles1d);
for (i=1; i<=NbPoles; i++)
Poles2d(i).SetY(Poles1d(i));
Handle(TColStd_HArray1OfReal) Knots = aApprox.Knots();
Handle(TColStd_HArray1OfInteger) Mults = aApprox.Multiplicities();
Standard_Integer Degree = aApprox.Degree();
myCurve3d = new Geom_BSplineCurve(Poles, Knots->Array1(), Mults->Array1(), Degree);
myCurve2d1 = new Geom2d_BSplineCurve(Poles2d, Knots->Array1(), Mults->Array1(), Degree);
}
myMaxError2d1 = Max (aApprox.MaxError(1,1),aApprox.MaxError(1,2));
myMaxError3d = aApprox.MaxError(3,1);
#ifdef DEB
ResultChron(chr_total, t_total);
cout<<" total reparametrization time = "<<t_total<<endl;
cout<<"initialization time = "<<t_init<<endl;
cout<<"approximation time = "<<t_approx<<endl;
cout<<"total time for uparam computation = "<<t_uparam<<endl;
cout<<"number uparam calles = "<<uparam_count<<endl;
#endif
}
//=======================================================================
//function : Approx_CurvilinearParameter_EvalCurvOn2Surf
//purpose : case of a curve on two surfaces
//=======================================================================
class Approx_CurvilinearParameter_EvalCurvOn2Surf : public AdvApprox_EvaluatorFunction
{
public:
Approx_CurvilinearParameter_EvalCurvOn2Surf (const Handle(Approx_CurvlinFunc)& theFunc,
Standard_Real First, Standard_Real Last)
: fonct(theFunc) { StartEndSav[0] = First; StartEndSav[1] = Last; }
virtual void Evaluate (Standard_Integer *Dimension,
Standard_Real StartEnd[2],
Standard_Real *Parameter,
Standard_Integer *DerivativeRequest,
Standard_Real *Result, // [Dimension]
Standard_Integer *ErrorCode);
private:
Handle(Approx_CurvlinFunc) fonct;
Standard_Real StartEndSav[2];
};
void Approx_CurvilinearParameter_EvalCurvOn2Surf::Evaluate (Standard_Integer * Dimension,
Standard_Real * StartEnd,
Standard_Real * Param,
Standard_Integer * Order,
Standard_Real * Result,
Standard_Integer * ErrorCode)
{
*ErrorCode = 0;
Standard_Real S = *Param;
TColStd_Array1OfReal Res(0, 6);
Standard_Integer i;
// Dimension is incorrect
if (*Dimension != 7) {
*ErrorCode = 1;
}
// Parameter is incorrect
if ( S < StartEnd[0] || S > StartEnd[1] ) {
*ErrorCode = 2;
}
/* if(StartEnd[0] != StartEndSav[0] || StartEnd[1]!= StartEndSav[1])
{
fonct->Trim(StartEnd[0],StartEnd[1], Precision::Confusion());
StartEndSav[0]=StartEnd[0];
StartEndSav[1]=StartEnd[1];
}
*/
if(!fonct->EvalCase3(S, *Order, Res)) {
*ErrorCode = 3;
}
for(i = 0; i <= 6; i++)
Result[i] = Res(i);
}
Approx_CurvilinearParameter::Approx_CurvilinearParameter(const Handle(Adaptor2d_HCurve2d)& C2D1,
const Handle(Adaptor3d_HSurface)& Surf1,
const Handle(Adaptor2d_HCurve2d)& C2D2,
const Handle(Adaptor3d_HSurface)& Surf2,
const Standard_Real Tol,
const GeomAbs_Shape Order,
const Standard_Integer MaxDegree,
const Standard_Integer MaxSegments)
{
Standard_Integer i;
#ifdef DEB
t_total = t_init = t_approx = t_uparam = 0;
uparam_count = 0;
InitChron(chr_total);
#endif
myCase = 3;
// Initialisation of input parameters of AdvApprox
Standard_Integer Num1DSS=4, Num2DSS=0, Num3DSS=1;
Handle(TColStd_HArray1OfReal) OneDTol = new TColStd_HArray1OfReal(1,Num1DSS);
Standard_Real TolV,TolW;
ToleranceComputation(C2D1,Surf1,10,Tol,TolV,TolW);
OneDTol->SetValue(1,TolV);
OneDTol->SetValue(2,TolW);
ToleranceComputation(C2D2,Surf2,10,Tol,TolV,TolW);
OneDTol->SetValue(3,TolV);
OneDTol->SetValue(4,TolW);
Handle(TColStd_HArray1OfReal) TwoDTolNul;
Handle(TColStd_HArray1OfReal) ThreeDTol = new TColStd_HArray1OfReal(1,Num3DSS);
ThreeDTol->Init(Tol/2);
#ifdef DEB
InitChron(chr_init);
#endif
Handle(Approx_CurvlinFunc) fonct = new Approx_CurvlinFunc(C2D1, C2D2, Surf1, Surf2, Tol/20);
#ifdef DEB
ResultChron(chr_init, t_init);
#endif
Standard_Real FirstS = fonct->FirstParameter();
Standard_Real LastS = fonct->LastParameter();
Standard_Integer NbInterv_C2 = fonct->NbIntervals(GeomAbs_C2);
TColStd_Array1OfReal CutPnts_C2(1, NbInterv_C2+1);
fonct->Intervals(CutPnts_C2,GeomAbs_C2);
Standard_Integer NbInterv_C3 = fonct->NbIntervals(GeomAbs_C3);
TColStd_Array1OfReal CutPnts_C3(1, NbInterv_C3+1);
fonct->Intervals(CutPnts_C3,GeomAbs_C3);
AdvApprox_PrefAndRec CutTool(CutPnts_C2,CutPnts_C3);
#ifdef DEB
InitChron(chr_approx);
#endif
Approx_CurvilinearParameter_EvalCurvOn2Surf evCOn2S (fonct, FirstS, LastS);
AdvApprox_ApproxAFunction aApprox (Num1DSS, Num2DSS, Num3DSS,
OneDTol, TwoDTolNul, ThreeDTol,
FirstS, LastS, Order,
MaxDegree, MaxSegments,
evCOn2S, CutTool);
#ifdef DEB
ResultChron(chr_approx, t_approx);
#endif
myDone = aApprox.IsDone();
myHasResult = aApprox.HasResult();
if (myHasResult) {
Standard_Integer NbPoles = aApprox.NbPoles();
TColgp_Array1OfPnt Poles (1,NbPoles);
TColgp_Array1OfPnt2d Poles2d(1,NbPoles);
TColStd_Array1OfReal Poles1d(1,NbPoles);
aApprox.Poles(1,Poles);
aApprox.Poles1d(1,Poles1d);
for (i=1; i<=NbPoles; i++)
Poles2d(i).SetX(Poles1d(i));
aApprox.Poles1d(2,Poles1d);
for (i=1; i<=NbPoles; i++)
Poles2d(i).SetY(Poles1d(i));
Handle(TColStd_HArray1OfReal) Knots = aApprox.Knots();
Handle(TColStd_HArray1OfInteger) Mults = aApprox.Multiplicities();
Standard_Integer Degree = aApprox.Degree();
myCurve3d = new Geom_BSplineCurve(Poles, Knots->Array1(), Mults->Array1(), Degree);
myCurve2d1 = new Geom2d_BSplineCurve(Poles2d, Knots->Array1(), Mults->Array1(), Degree);
aApprox.Poles1d(3,Poles1d);
for (i=1; i<=NbPoles; i++)
Poles2d(i).SetX(Poles1d(i));
aApprox.Poles1d(4,Poles1d);
for (i=1; i<=NbPoles; i++)
Poles2d(i).SetY(Poles1d(i));
myCurve2d2 = new Geom2d_BSplineCurve(Poles2d, Knots->Array1(), Mults->Array1(), Degree);
}
myMaxError2d1 = Max (aApprox.MaxError(1,1),aApprox.MaxError(1,2));
myMaxError2d2 = Max (aApprox.MaxError(1,3),aApprox.MaxError(1,4));
myMaxError3d = aApprox.MaxError(3,1);
#ifdef DEB
ResultChron(chr_total, t_total);
cout<<" total reparametrization time = "<<t_total<<endl;
cout<<"initialization time = "<<t_init<<endl;
cout<<"approximation time = "<<t_approx<<endl;
cout<<"total time for uparam computation = "<<t_uparam<<endl;
cout<<"number uparam calles = "<<uparam_count<<endl;
#endif
}
//=======================================================================
//function : IsDone
//purpose :
//=======================================================================
Standard_Boolean Approx_CurvilinearParameter::IsDone() const
{
return myDone;
}
//=======================================================================
//function : HasResult
//purpose :
//=======================================================================
Standard_Boolean Approx_CurvilinearParameter::HasResult() const
{
return myHasResult;
}
//=======================================================================
//function : Curve3d
//purpose : returns the Bspline curve corresponding to the reparametrized 3D curve
//=======================================================================
Handle(Geom_BSplineCurve) Approx_CurvilinearParameter::Curve3d() const
{
return myCurve3d;
}
//=======================================================================
//function : MaxError3d
//purpose : returns the maximum error on the reparametrized 3D curve
//=======================================================================
Standard_Real Approx_CurvilinearParameter::MaxError3d() const
{
return myMaxError3d;
}
//=======================================================================
//function : Curve2d1
//purpose : returns the BsplineCurve representing the reparametrized 2D curve on the
// first surface (case of a curve on one or two surfaces)
//=======================================================================
Handle(Geom2d_BSplineCurve) Approx_CurvilinearParameter::Curve2d1() const
{
return myCurve2d1;
}
//=======================================================================
//function : MaxError2d1
//purpose : returns the maximum error on the first reparametrized 2D curve
//=======================================================================
Standard_Real Approx_CurvilinearParameter::MaxError2d1() const
{
return myMaxError2d1;
}
//=======================================================================
//function : Curve2d2
//purpose : returns the BsplineCurve representing the reparametrized 2D curve on the
// second surface (case of a curve on two surfaces)
//=======================================================================
Handle(Geom2d_BSplineCurve) Approx_CurvilinearParameter::Curve2d2() const
{
return myCurve2d2;
}
//=======================================================================
//function : MaxError2d2
//purpose : returns the maximum error on the second reparametrized 2D curve
//=======================================================================
Standard_Real Approx_CurvilinearParameter::MaxError2d2() const
{
return myMaxError2d2;
}
//=======================================================================
//function : Dump
//purpose : print the maximum errors(s)
//=======================================================================
void Approx_CurvilinearParameter::Dump(Standard_OStream& o) const
{
o << "Dump of Approx_CurvilinearParameter" << endl;
if (myCase==2 || myCase==3)
o << "myMaxError2d1 = " << myMaxError2d1 << endl;
if (myCase==3)
o << "myMaxError2d2 = " << myMaxError2d2 << endl;
o << "myMaxError3d = " << myMaxError3d << endl;
}
//=======================================================================
//function : ToleranceComputation
//purpose :
//=======================================================================
void Approx_CurvilinearParameter::ToleranceComputation(const Handle(Adaptor2d_HCurve2d) &C2D,
const Handle(Adaptor3d_HSurface) &S,
const Standard_Integer MaxNumber,
const Standard_Real Tol,
Standard_Real &TolV, Standard_Real &TolW)
{
Standard_Real FirstU = C2D->FirstParameter(),
LastU = C2D->LastParameter();
// Standard_Real parU, Max_dS_dv=1.,Max_dS_dw=1.;
Standard_Real Max_dS_dv=1.,Max_dS_dw=1.;
gp_Pnt P;
gp_Pnt2d pntVW;
gp_Vec dS_dv,dS_dw;
for (Standard_Integer i=1; i<=MaxNumber; i++) {
pntVW = C2D->Value(FirstU + (i-1)*(LastU-FirstU)/(MaxNumber-1));
S->D1(pntVW.X(),pntVW.Y(),P,dS_dv,dS_dw);
Max_dS_dv = Max (Max_dS_dv, dS_dv.Magnitude());
Max_dS_dw = Max (Max_dS_dw, dS_dw.Magnitude());
}
TolV = Tol / (4.*Max_dS_dv);
TolW = Tol / (4.*Max_dS_dw);
#ifdef DEB
cout << "TolV = " << TolV << endl;
cout << "TolW = " << TolW << endl;
#endif
}

149
src/Approx/Approx_CurvlinFunc.cdl Executable file
View File

@@ -0,0 +1,149 @@
-- File: Approx_CurvlinFunc.cdl
-- Created: Tue May 12 12:17:17 1998
-- Author: Roman BORISOV
-- <rbv@sgi38>
---Copyright: Matra Datavision 1998
class CurvlinFunc from Approx inherits TShared from MMgt
---Purpose: defines an abstract curve with
-- curvilinear parametrization
--
--
--
--
uses
HCurve from Adaptor3d,
Curve from Adaptor3d,
HCurve2d from Adaptor2d,
HSurface from Adaptor3d,
Shape from GeomAbs,
Array1OfReal from TColStd,
HArray1OfReal from TColStd,
Pnt from gp,
Vec from gp
raises
OutOfRange from Standard,
DomainError from Standard,
ConstructionError from Standard
is
Create(C: HCurve from Adaptor3d; Tol: Real)
returns mutable CurvlinFunc;
Create(C2D: HCurve2d from Adaptor2d; S: HSurface from Adaptor3d; Tol: Real)
returns mutable CurvlinFunc;
Create(C2D1, C2D2: HCurve2d from Adaptor2d; S1, S2: HSurface from Adaptor3d; Tol: Real)
returns mutable CurvlinFunc;
SetTol(me: mutable; Tol: Real)
---Purpose Update the tolerance to used
is static;
Init(me: mutable)
is private;
Init(me; C: in out Curve from Adaptor3d;
Si: out HArray1OfReal from TColStd;
Ui: out HArray1OfReal from TColStd)
is private;
FirstParameter(me) returns Real;
LastParameter(me) returns Real;
NbIntervals(me; S : Shape from GeomAbs) returns Integer;
---Purpose: Returns the number of intervals for continuity
-- <S>. May be one if Continuity(me) >= <S>
Intervals(me; T : in out Array1OfReal from TColStd;
S : Shape from GeomAbs);
---Purpose: Stores in <T> the parameters bounding the intervals
-- of continuity <S>.
--
-- The array must provide enough room to accomodate
-- for the parameters. i.e. T.Length() > NbIntervals()
Trim(me: mutable; First, Last, Tol: Real from Standard)
raises OutOfRange from Standard;
--- Purpose : if First < 0 or Last > 1
Length(me: mutable)
--- Purpose : Computes length of the curve.
is static;
Length(me; C: in out Curve from Adaptor3d;
FirstU, LasrU: Real) returns Real
--- Purpose : Computes length of the curve segment.
is static;
GetLength(me) returns Real;
GetUParameter(me; C: in out Curve from Adaptor3d; S: Real; NumberOfCurve: Integer) returns Real;
--- Purpose : returns original parameter correponding S. if
-- Case == 1 computation is performed on myC2D1 and mySurf1,
-- otherwise it is done on myC2D2 and mySurf2.
GetSParameter(me; U: Real) returns Real;
--- Purpose : returns original parameter correponding S.
GetSParameter(me; C: in out Curve from Adaptor3d; U, Length: Real) returns Real
--- Purpose : returns curvilinear parameter correponding U.
is private;
EvalCase1(me; S: Real; Order: Integer;
Result: out Array1OfReal from TColStd) -- dim(Result) = 3
returns Boolean from Standard
raises
ConstructionError from Standard;
--- Purpose : if myCase != 1
EvalCase2(me; S: Real; Order: Integer;
Result: out Array1OfReal from TColStd) -- dim(Result) = 5
returns Boolean from Standard
raises
ConstructionError from Standard;
--- Purpose : if myCase != 2
EvalCase3(me: mutable; S: Real; Order: Integer;
Result: out Array1OfReal from TColStd) -- dim(Result) = 7
returns Boolean from Standard
raises
ConstructionError from Standard;
--- Purpose : if myCase != 3
EvalCurOnSur(me; S: Real; Order: Integer;
Result: out Array1OfReal from TColStd;
NumberOfCurve: Integer)
returns Boolean from Standard
is private;
fields
myC3D : HCurve from Adaptor3d;
myC2D1 : HCurve2d from Adaptor2d;
myC2D2 : HCurve2d from Adaptor2d;
mySurf1 : HSurface from Adaptor3d;
mySurf2 : HSurface from Adaptor3d;
myCase : Integer from Standard; -- [1..3]
myFirstS : Real from Standard;
myLastS : Real from Standard;
myFirstU1: Real from Standard;
myLastU1 : Real from Standard;
myFirstU2: Real from Standard;
myLastU2 : Real from Standard;
myLength : Real from Standard;
myLength1: Real from Standard;
myLength2: Real from Standard;
myTolLen : Real from Standard;
myUi_1 : HArray1OfReal from TColStd;
mySi_1 : HArray1OfReal from TColStd;
myUi_2 : HArray1OfReal from TColStd;
mySi_2 : HArray1OfReal from TColStd;
end CurvlinFunc;

678
src/Approx/Approx_CurvlinFunc.cxx Executable file
View File

@@ -0,0 +1,678 @@
// File: Approx_CurvlinFunc.cxx
// Created: Tue May 12 14:03:09 1998
// Author: Roman BORISOV
// <rbv@sgi38>
#include <Approx_CurvlinFunc.ixx>
#include <Adaptor3d_CurveOnSurface.hxx>
#include <Adaptor3d_HCurveOnSurface.hxx>
#include <TColStd_SequenceOfReal.hxx>
#include <GeomLib.hxx>
#include <GCPnts_AbscissaPoint.hxx>
#include <Precision.hxx>
static Standard_Real myPrevS, myPrevU;
#ifdef DEB
#include <OSD_Timer.hxx>
static OSD_Chronometer chr_uparam;
Standard_EXPORT Standard_Integer uparam_count;
Standard_EXPORT Standard_Real t_uparam;
//Standard_IMPORT extern void InitChron(OSD_Chronometer& ch);
Standard_IMPORT void InitChron(OSD_Chronometer& ch);
//Standard_IMPORT extern void ResultChron( OSD_Chronometer & ch, Standard_Real & time);
Standard_IMPORT void ResultChron( OSD_Chronometer & ch, Standard_Real & time);
#endif
static Standard_Real cubic(const Standard_Real X, const Standard_Real *Xi, const Standard_Real *Yi)
{
Standard_Real I1, I2, I3, I21, I22, I31, Result;
I1 = (Yi[0] - Yi[1])/(Xi[0] - Xi[1]);
I2 = (Yi[1] - Yi[2])/(Xi[1] - Xi[2]);
I3 = (Yi[2] - Yi[3])/(Xi[2] - Xi[3]);
I21 = (I1 - I2)/(Xi[0] - Xi[2]);
I22 = (I2 - I3)/(Xi[1] - Xi[3]);
I31 = (I21 - I22)/(Xi[0] - Xi[3]);
Result = Yi[0] + (X - Xi[0])*(I1 + (X - Xi[1])*(I21 + (X - Xi[2])*I31));
return Result;
}
//static void findfourpoints(const Standard_Real S,
static void findfourpoints(const Standard_Real ,
Standard_Integer NInterval,
const Handle(TColStd_HArray1OfReal)& Si,
Handle(TColStd_HArray1OfReal)& Ui,
const Standard_Real prevS,
const Standard_Real prevU, Standard_Real *Xi,
Standard_Real *Yi)
{
Standard_Integer i, j;
Standard_Integer NbInt = Si->Length() - 1;
if (NbInt < 3) Standard_ConstructionError::Raise("Approx_CurvlinFunc::GetUParameter");
if(NInterval < 1) NInterval = 1;
else if(NInterval > NbInt - 2) NInterval = NbInt - 2;
for(i = 0; i < 4; i++) {
Xi[i] = Si->Value(NInterval - 1 + i);
Yi[i] = Ui->Value(NInterval - 1 + i);
}
// try to insert (S, U)
for(i = 0; i < 3; i++) {
if(Xi[i] < prevS && prevS < Xi[i+1]) {
for(j = 0; j < i; j++) {
Xi[j] = Xi[j+1];
Yi[j] = Yi[j+1];
}
Xi[i] = prevS;
Yi[i] = prevU;
break;
}
}
}
/*static Standard_Real curvature(const Standard_Real U, const Adaptor3d_Curve& C)
{
Standard_Real k, tau, mod1, mod2, OMEGA;
gp_Pnt P;
gp_Vec D1, D2, D3;
C.D3(U, P, D1, D2, D3);
mod1 = D1.Magnitude();
mod2 = D1.Crossed(D2).Magnitude();
k = mod2/(mod1*mod1*mod1);
tau = D1.Dot(D2.Crossed(D3));
tau /= mod2*mod2;
OMEGA = Sqrt(k*k + tau*tau);
return OMEGA;
}
*/
Approx_CurvlinFunc::Approx_CurvlinFunc(const Handle(Adaptor3d_HCurve)& C, const Standard_Real Tol) : myC3D(C),
myCase(1),
myFirstS(0),
myLastS(1),
myTolLen(Tol)
{
Init();
}
Approx_CurvlinFunc::Approx_CurvlinFunc(const Handle(Adaptor2d_HCurve2d)& C2D, const Handle(Adaptor3d_HSurface)& S, const Standard_Real Tol) :
myC2D1(C2D),
mySurf1(S),
myCase(2),
myFirstS(0),
myLastS(1),
myTolLen(Tol)
{
Init();
}
Approx_CurvlinFunc::Approx_CurvlinFunc(const Handle(Adaptor2d_HCurve2d)& C2D1, const Handle(Adaptor2d_HCurve2d)& C2D2, const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_HSurface)& S2, const Standard_Real Tol) :
myC2D1(C2D1),
myC2D2(C2D2),
mySurf1(S1),
mySurf2(S2),
myCase(3),
myFirstS(0),
myLastS(1),
myTolLen(Tol)
{
Init();
}
void Approx_CurvlinFunc::Init()
{
Adaptor3d_CurveOnSurface CurOnSur;
switch(myCase) {
case 1:
Init(myC3D->GetCurve(), mySi_1, myUi_1);
myFirstU1 = myC3D->FirstParameter();
myLastU1 = myC3D->LastParameter();
myFirstU2 = myLastU2 = 0;
break;
case 2:
CurOnSur.Load(myC2D1);
CurOnSur.Load(mySurf1);
Init(CurOnSur, mySi_1, myUi_1);
myFirstU1 = CurOnSur.FirstParameter();
myLastU1 = CurOnSur.LastParameter();
myFirstU2 = myLastU2 = 0;
break;
case 3:
CurOnSur.Load(myC2D1);
CurOnSur.Load(mySurf1);
Init(CurOnSur, mySi_1, myUi_1);
myFirstU1 = CurOnSur.FirstParameter();
myLastU1 = CurOnSur.LastParameter();
CurOnSur.Load(myC2D2);
CurOnSur.Load(mySurf2);
Init(CurOnSur, mySi_2, myUi_2);
myFirstU2 = CurOnSur.FirstParameter();
myLastU2 = CurOnSur.LastParameter();
}
Length();
}
//=======================================================================
//function : Init
//purpose : Init the values
//history : 23/10/1998 PMN : Cut at curve's discontinuities
//=======================================================================
void Approx_CurvlinFunc::Init(Adaptor3d_Curve& C, Handle(TColStd_HArray1OfReal)& Si,
Handle(TColStd_HArray1OfReal)& Ui) const
{
Standard_Real Step, FirstU, LastU;
Standard_Integer i, j, k, NbInt, NbIntC3;
FirstU = C.FirstParameter();
LastU = C.LastParameter();
NbInt = 10;
NbIntC3 = C.NbIntervals(GeomAbs_C3);
TColStd_Array1OfReal Disc(1, NbIntC3+1);
if (NbIntC3 >1) {
C.Intervals(Disc, GeomAbs_C3);
}
else {
Disc(1) = FirstU;
Disc(2) = LastU;
}
Ui = new TColStd_HArray1OfReal (0,NbIntC3*NbInt);
Si = new TColStd_HArray1OfReal (0,NbIntC3*NbInt);
Ui->SetValue(0, FirstU);
Si->SetValue(0, 0);
for(j = 1, i=1; j<=NbIntC3; j++) {
Step = (Disc(j+1) - Disc(j))/NbInt;
for(k = 1; k <= NbInt; k++, i++) {
Ui->ChangeValue(i) = Ui->Value(i-1) + Step;
Si->ChangeValue(i) = Si->Value(i-1) + Length(C, Ui->Value(i-1), Ui->Value(i));
}
}
Standard_Real Len = Si->Value(Si->Upper());
for(i = Si->Lower(); i<= Si->Upper(); i++)
Si->ChangeValue(i) /= Len;
myPrevS = myFirstS;
myPrevU = FirstU;
}
void Approx_CurvlinFunc::SetTol(const Standard_Real Tol)
{
myTolLen = Tol;
}
Standard_Real Approx_CurvlinFunc::FirstParameter() const
{
return myFirstS;
}
Standard_Real Approx_CurvlinFunc::LastParameter() const
{
return myLastS;
}
Standard_Integer Approx_CurvlinFunc::NbIntervals(const GeomAbs_Shape S) const
{
Adaptor3d_CurveOnSurface CurOnSur;
switch(myCase) {
case 1:
return myC3D->NbIntervals(S);
case 2:
CurOnSur.Load(myC2D1);
CurOnSur.Load(mySurf1);
return CurOnSur.NbIntervals(S);
case 3:
Standard_Integer NbInt;
CurOnSur.Load(myC2D1);
CurOnSur.Load(mySurf1);
NbInt = CurOnSur.NbIntervals(S);
TColStd_Array1OfReal T1(1, NbInt+1);
CurOnSur.Intervals(T1, S);
CurOnSur.Load(myC2D2);
CurOnSur.Load(mySurf2);
NbInt = CurOnSur.NbIntervals(S);
TColStd_Array1OfReal T2(1, NbInt+1);
CurOnSur.Intervals(T2, S);
TColStd_SequenceOfReal Fusion;
GeomLib::FuseIntervals(T1, T2, Fusion);
return Fusion.Length() - 1;
}
//POP pour WNT
return 1;
}
void Approx_CurvlinFunc::Intervals(TColStd_Array1OfReal& T, const GeomAbs_Shape S) const
{
Adaptor3d_CurveOnSurface CurOnSur;
Standard_Integer i;
switch(myCase) {
case 1:
myC3D->Intervals(T, S);
break;
case 2:
CurOnSur.Load(myC2D1);
CurOnSur.Load(mySurf1);
CurOnSur.Intervals(T, S);
break;
case 3:
Standard_Integer NbInt;
CurOnSur.Load(myC2D1);
CurOnSur.Load(mySurf1);
NbInt = CurOnSur.NbIntervals(S);
TColStd_Array1OfReal T1(1, NbInt+1);
CurOnSur.Intervals(T1, S);
CurOnSur.Load(myC2D2);
CurOnSur.Load(mySurf2);
NbInt = CurOnSur.NbIntervals(S);
TColStd_Array1OfReal T2(1, NbInt+1);
CurOnSur.Intervals(T2, S);
TColStd_SequenceOfReal Fusion;
GeomLib::FuseIntervals(T1, T2, Fusion);
for (i = 1; i <= Fusion.Length(); i++)
T.ChangeValue(i) = Fusion.Value(i);
}
for(i = 1; i <= T.Length(); i++)
T.ChangeValue(i) = GetSParameter(T.Value(i));
}
void Approx_CurvlinFunc::Trim(const Standard_Real First, const Standard_Real Last, const Standard_Real Tol)
{
if (First < 0 || Last >1) Standard_OutOfRange::Raise("Approx_CurvlinFunc::Trim");
if ((Last - First) < Tol) return;
Standard_Real FirstU, LastU;
Adaptor3d_CurveOnSurface CurOnSur;
Handle(Adaptor3d_HCurve) HCurOnSur;
switch(myCase) {
case 1:
myC3D = myC3D->Trim(myFirstU1, myLastU1, Tol);
FirstU = GetUParameter(myC3D->GetCurve(), First, 1);
LastU = GetUParameter(myC3D->GetCurve(), Last, 1);
myC3D = myC3D->Trim(FirstU, LastU, Tol);
break;
case 3:
CurOnSur.Load(myC2D2);
CurOnSur.Load(mySurf2);
HCurOnSur = CurOnSur.Trim(myFirstU2, myLastU2, Tol);
myC2D2 = ((Adaptor3d_CurveOnSurface *)(&(HCurOnSur->Curve())))->GetCurve();
mySurf2 = ((Adaptor3d_CurveOnSurface *)(&(HCurOnSur->Curve())))->GetSurface();
CurOnSur.Load(myC2D2);
CurOnSur.Load(mySurf2);
FirstU = GetUParameter(CurOnSur, First, 1);
LastU = GetUParameter(CurOnSur, Last, 1);
HCurOnSur = CurOnSur.Trim(FirstU, LastU, Tol);
myC2D2 = ((Adaptor3d_CurveOnSurface *)(&(HCurOnSur->Curve())))->GetCurve();
mySurf2 = ((Adaptor3d_CurveOnSurface *)(&(HCurOnSur->Curve())))->GetSurface();
case 2:
CurOnSur.Load(myC2D1);
CurOnSur.Load(mySurf1);
HCurOnSur = CurOnSur.Trim(myFirstU1, myLastU1, Tol);
myC2D1 = ((Adaptor3d_CurveOnSurface *)(&(HCurOnSur->Curve())))->GetCurve();
mySurf1 = ((Adaptor3d_CurveOnSurface *)(&(HCurOnSur->Curve())))->GetSurface();
CurOnSur.Load(myC2D1);
CurOnSur.Load(mySurf1);
FirstU = GetUParameter(CurOnSur, First, 1);
LastU = GetUParameter(CurOnSur, Last, 1);
HCurOnSur = CurOnSur.Trim(FirstU, LastU, Tol);
myC2D1 = ((Adaptor3d_CurveOnSurface *)(&(HCurOnSur->Curve())))->GetCurve();
mySurf1 = ((Adaptor3d_CurveOnSurface *)(&(HCurOnSur->Curve())))->GetSurface();
}
myFirstS = First;
myLastS = Last;
}
void Approx_CurvlinFunc::Length()
{
Adaptor3d_CurveOnSurface CurOnSur;
Standard_Real FirstU, LastU;
switch(myCase){
case 1:
FirstU = myC3D->FirstParameter();
LastU = myC3D->LastParameter();
myLength = Length(myC3D->GetCurve(), FirstU, LastU);
myLength1 = myLength2 = 0;
break;
case 2:
CurOnSur.Load(myC2D1);
CurOnSur.Load(mySurf1);
FirstU = CurOnSur.FirstParameter();
LastU = CurOnSur.LastParameter();
myLength = Length(CurOnSur, FirstU, LastU);
myLength1 = myLength2 = 0;
break;
case 3:
CurOnSur.Load(myC2D1);
CurOnSur.Load(mySurf1);
FirstU = CurOnSur.FirstParameter();
LastU = CurOnSur.LastParameter();
myLength1 = Length(CurOnSur, FirstU, LastU);
CurOnSur.Load(myC2D2);
CurOnSur.Load(mySurf2);
FirstU = CurOnSur.FirstParameter();
LastU = CurOnSur.LastParameter();
myLength2 = Length(CurOnSur, FirstU, LastU);
myLength = (myLength1 + myLength2)/2;
}
}
Standard_Real Approx_CurvlinFunc::Length(Adaptor3d_Curve& C, const Standard_Real FirstU, const Standard_Real LastU) const
{
Standard_Real Length;
Length = GCPnts_AbscissaPoint::Length(C, FirstU, LastU, myTolLen);
return Length;
}
Standard_Real Approx_CurvlinFunc::GetLength() const
{
return myLength;
}
Standard_Real Approx_CurvlinFunc::GetSParameter(const Standard_Real U) const
{
Standard_Real S=0, S1, S2;
Adaptor3d_CurveOnSurface CurOnSur;
switch (myCase) {
case 1:
S = GetSParameter(myC3D->GetCurve(), U, myLength);
break;
case 2:
CurOnSur.Load(myC2D1);
CurOnSur.Load(mySurf1);
S = GetSParameter(CurOnSur, U, myLength);
break;
case 3:
CurOnSur.Load(myC2D1);
CurOnSur.Load(mySurf1);
S1 = GetSParameter(CurOnSur, U, myLength1);
CurOnSur.Load(myC2D2);
CurOnSur.Load(mySurf2);
S2 = GetSParameter(CurOnSur, U, myLength2);
S = (S1 + S2)/2;
}
return S;
}
Standard_Real Approx_CurvlinFunc::GetUParameter(Adaptor3d_Curve& C,
const Standard_Real S,
const Standard_Integer NumberOfCurve) const
{
Standard_Real deltaS, base, U, Length;
Standard_Integer NbInt, NInterval, i;
Handle(TColStd_HArray1OfReal) InitUArray, InitSArray;
#ifdef DEB
InitChron(chr_uparam);
#endif
if(S < 0 || S > 1) Standard_ConstructionError::Raise("Approx_CurvlinFunc::GetUParameter");
if(NumberOfCurve == 1) {
InitUArray = myUi_1;
InitSArray = mySi_1;
if(myCase == 3)
Length = myLength1;
else
Length = myLength;
}
else {
InitUArray = myUi_2;
InitSArray = mySi_2;
Length = myLength2;
}
NbInt = InitUArray->Length() - 1;
if(S == 1) NInterval = NbInt - 1;
else {
for(i = 0; i < NbInt; i++) {
if((InitSArray->Value(i) <= S && S < InitSArray->Value(i+1)))
break;
}
NInterval = i;
}
if(S==InitSArray->Value(NInterval)) {
return InitUArray->Value(NInterval);
}
if(S==InitSArray->Value(NInterval+1)) {
return InitUArray->Value(NInterval+1);
}
base = InitUArray->Value(NInterval);
deltaS = (S - InitSArray->Value(NInterval))*Length;
// to find an initial point
Standard_Real Xi[4], Yi[4], UGuess;
findfourpoints(S, NInterval, InitSArray, InitUArray, myPrevS, myPrevU, Xi, Yi);
UGuess = cubic(S , Xi, Yi);
U = GCPnts_AbscissaPoint(C, deltaS, base, UGuess, myTolLen).Parameter();
myPrevS = S;
myPrevU = U;
#ifdef DEB
ResultChron(chr_uparam, t_uparam);
uparam_count++;
#endif
return U;
}
Standard_Real Approx_CurvlinFunc::GetSParameter(Adaptor3d_Curve& C, const Standard_Real U, const Standard_Real Len) const
{
Standard_Real S, Origin;
Origin = C.FirstParameter();
S = myFirstS + Length(C, Origin, U)/Len;
return S;
}
Standard_Boolean Approx_CurvlinFunc::EvalCase1(const Standard_Real S, const Standard_Integer Order, TColStd_Array1OfReal& Result) const
{
if(myCase != 1) Standard_ConstructionError::Raise("Approx_CurvlinFunc::EvalCase1");
gp_Pnt C;
gp_Vec dC_dU, dC_dS, d2C_dU2, d2C_dS2;
Standard_Real U, Mag, dU_dS, d2U_dS2;
U = GetUParameter(myC3D->GetCurve(), S, 1);
switch(Order) {
case 0:
myC3D->D0(U, C);
Result(0) = C.X();
Result(1) = C.Y();
Result(2) = C.Z();
break;
case 1:
myC3D->D1(U, C, dC_dU);
Mag = dC_dU.Magnitude();
dU_dS = myLength/Mag;
dC_dS = dC_dU*dU_dS;
Result(0) = dC_dS.X();
Result(1) = dC_dS.Y();
Result(2) = dC_dS.Z();
break;
case 2:
myC3D->D2(U, C, dC_dU, d2C_dU2);
Mag = dC_dU.Magnitude();
dU_dS = myLength/Mag;
d2U_dS2 = -myLength*dC_dU.Dot(d2C_dU2)*dU_dS/(Mag*Mag*Mag);
d2C_dS2 = d2C_dU2*dU_dS*dU_dS + dC_dU*d2U_dS2;
Result(0) = d2C_dS2.X();
Result(1) = d2C_dS2.Y();
Result(2) = d2C_dS2.Z();
break;
default: Result(0) = Result(1) = Result(2) = 0;
return Standard_False;
}
return Standard_True;
}
Standard_Boolean Approx_CurvlinFunc::EvalCase2(const Standard_Real S, const Standard_Integer Order, TColStd_Array1OfReal& Result) const
{
if(myCase != 2) Standard_ConstructionError::Raise("Approx_CurvlinFunc::EvalCase2");
Standard_Boolean Done;
Done = EvalCurOnSur(S, Order, Result, 1);
return Done;
}
Standard_Boolean Approx_CurvlinFunc::EvalCase3(const Standard_Real S, const Standard_Integer Order, TColStd_Array1OfReal& Result)
{
if(myCase != 3) Standard_ConstructionError::Raise("Approx_CurvlinFunc::EvalCase3");
TColStd_Array1OfReal tmpRes1(0, 4), tmpRes2(0, 4);
Standard_Boolean Done;
Done = EvalCurOnSur(S, Order, tmpRes1, 1);
Done = EvalCurOnSur(S, Order, tmpRes2, 2) && Done;
Result(0) = tmpRes1(0);
Result(1) = tmpRes1(1);
Result(2) = tmpRes2(0);
Result(3) = tmpRes2(1);
Result(4) = 0.5*(tmpRes1(2) + tmpRes2(2));
Result(5) = 0.5*(tmpRes1(3) + tmpRes2(3));
Result(6) = 0.5*(tmpRes1(4) + tmpRes2(4));
return Done;
}
Standard_Boolean Approx_CurvlinFunc::EvalCurOnSur(const Standard_Real S, const Standard_Integer Order, TColStd_Array1OfReal& Result, const Standard_Integer NumberOfCurve) const
{
Handle(Adaptor2d_HCurve2d) Cur2D;
Handle(Adaptor3d_HSurface) Surf;
Standard_Real U=0, Length=0;
if (NumberOfCurve == 1) {
Cur2D = myC2D1;
Surf = mySurf1;
Adaptor3d_CurveOnSurface CurOnSur(myC2D1, mySurf1);
U = GetUParameter(CurOnSur, S, 1);
if(myCase == 3) Length = myLength1;
else Length = myLength;
}
else if (NumberOfCurve == 2) {
Cur2D = myC2D2;
Surf = mySurf2;
Adaptor3d_CurveOnSurface CurOnSur(myC2D2, mySurf2);
U = GetUParameter(CurOnSur, S, 2);
Length = myLength2;
}
else
Standard_ConstructionError::Raise("Approx_CurvlinFunc::EvalCurOnSur");
Standard_Real Mag, dU_dS, d2U_dS2, dV_dU, dW_dU, dV_dS, dW_dS, d2V_dS2, d2W_dS2, d2V_dU2, d2W_dU2;
gp_Pnt2d C2D;
gp_Pnt C;
gp_Vec2d dC2D_dU, d2C2D_dU2;
gp_Vec dC_dU, d2C_dU2, dC_dS, d2C_dS2, dS_dV, dS_dW, d2S_dV2, d2S_dW2, d2S_dVdW;
switch(Order) {
case 0:
Cur2D->D0(U, C2D);
Surf->D0(C2D.X(), C2D.Y(), C);
Result(0) = C2D.X();
Result(1) = C2D.Y();
Result(2) = C.X();
Result(3) = C.Y();
Result(4) = C.Z();
break;
case 1:
Cur2D->D1(U, C2D, dC2D_dU);
dV_dU = dC2D_dU.X();
dW_dU = dC2D_dU.Y();
Surf->D1(C2D.X(), C2D.Y(), C, dS_dV, dS_dW);
dC_dU = dS_dV*dV_dU + dS_dW*dW_dU;
Mag = dC_dU.Magnitude();
dU_dS = Length/Mag;
dV_dS = dV_dU*dU_dS;
dW_dS = dW_dU*dU_dS;
dC_dS = dC_dU*dU_dS;
Result(0) = dV_dS;
Result(1) = dW_dS;
Result(2) = dC_dS.X();
Result(3) = dC_dS.Y();
Result(4) = dC_dS.Z();
break;
case 2:
Cur2D->D2(U, C2D, dC2D_dU, d2C2D_dU2);
dV_dU = dC2D_dU.X();
dW_dU = dC2D_dU.Y();
d2V_dU2 = d2C2D_dU2.X();
d2W_dU2 = d2C2D_dU2.Y();
Surf->D2(C2D.X(), C2D.Y(), C, dS_dV, dS_dW, d2S_dV2, d2S_dW2, d2S_dVdW);
dC_dU = dS_dV*dV_dU + dS_dW*dW_dU;
d2C_dU2 = (d2S_dV2*dV_dU + d2S_dVdW*dW_dU)*dV_dU + dS_dV*d2V_dU2 +
(d2S_dVdW*dV_dU + d2S_dW2*dW_dU)*dW_dU + dS_dW*d2W_dU2;
Mag = dC_dU.Magnitude();
dU_dS = Length/Mag;
d2U_dS2 = -Length*dC_dU.Dot(d2C_dU2)*dU_dS/(Mag*Mag*Mag);
dV_dS = dV_dU * dU_dS;
dW_dS = dW_dU * dU_dS;
d2V_dS2 = d2V_dU2*dU_dS*dU_dS + dV_dU*d2U_dS2;
d2W_dS2 = d2W_dU2*dU_dS*dU_dS + dW_dU*d2U_dS2;
d2U_dS2 = -dC_dU.Dot(d2C_dU2)*dU_dS/(Mag*Mag);
d2C_dS2 = (d2S_dV2 * dV_dS + d2S_dVdW * dW_dS) * dV_dS + dS_dV * d2V_dS2 +
(d2S_dW2 * dW_dS + d2S_dVdW * dV_dS) * dW_dS + dS_dW * d2W_dS2;
Result(0) = d2V_dS2;
Result(1) = d2W_dS2;
Result(2) = d2C_dS2.X();
Result(3) = d2C_dS2.Y();
Result(4) = d2C_dS2.Z();
break;
default: Result(0) = Result(1) = Result(2) = Result(3) = Result(4) = 0;
return Standard_False;
}
return Standard_True;
}

View File

@@ -0,0 +1,60 @@
-- File: Approx_MCurvesToBSpCurve.cdl
-- Created: Mon Feb 21 10:27:51 1994
-- Author: Laurent PAINNOT
-- <lpa@zerox>
---Copyright: Matra Datavision 1994
class MCurvesToBSpCurve from Approx
uses MultiBSpCurve from AppParCurves,
MultiCurve from AppParCurves,
SequenceOfMultiCurve from AppParCurves
is
Create returns MCurvesToBSpCurve;
Reset(me: in out)
--- Clear the internal Sequence Of MultiCurve
is static;
Append(me: in out; MC: MultiCurve from AppParCurves)
is static;
Perform(me: in out)
is static;
Perform(me: in out; TheSeq: SequenceOfMultiCurve from AppParCurves)
is static;
Value(me)
---Purpose: return the composite MultiCurves as a MultiBSpCurve.
---C++: return const&
returns MultiBSpCurve
is static;
ChangeValue(me: in out)
---Purpose: return the composite MultiCurves as a MultiBSpCurve.
---C++: return const&
returns MultiBSpCurve
is static;
fields
mySpline: MultiBSpCurve from AppParCurves;
myDone : Boolean from Standard;
myCurves: SequenceOfMultiCurve from AppParCurves;
end MCurvesToBSpCurve;

View File

@@ -0,0 +1,236 @@
#include <Approx_MCurvesToBSpCurve.ixx>
#include <Convert_CompBezierCurvesToBSplineCurve.hxx>
#include <Convert_CompBezierCurves2dToBSplineCurve2d.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <AppParCurves_MultiCurve.hxx>
#include <AppParCurves_MultiPoint.hxx>
#include <AppParCurves_Array1OfMultiPoint.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <BSplCLib.hxx>
#include <PLib.hxx>
#ifdef DEB
static void DEBUG(const AppParCurves_MultiCurve& MC) {
Standard_Integer i, j;
Standard_Integer nbcu = MC.NbCurves();
Standard_Integer nbpoles = MC.NbPoles();
TColgp_Array1OfPnt Poles(1, nbpoles);
TColgp_Array1OfPnt2d Poles2d(1, nbpoles);
for (i = 1; i <= nbcu; i++) {
cout << " Curve No. " << i << endl;
if (MC.Dimension(i) == 3) {
MC.Curve(i, Poles);
for (j = 1; j <= nbpoles; j++) {
cout<< " Pole = " << Poles(j).X() <<" "<<Poles(j).Y()<<" "<<Poles(j).Z()<< endl;
}
}
else {
MC.Curve(i, Poles2d);
for (j = 1; j <= nbpoles; j++) {
cout<< " Pole = " << Poles2d(j).X() <<" "<<Poles2d(j).Y()<< endl;
}
}
}
}
#endif
Approx_MCurvesToBSpCurve::Approx_MCurvesToBSpCurve()
{
myDone = Standard_False;
}
void Approx_MCurvesToBSpCurve::Reset()
{
myDone = Standard_False;
myCurves.Clear();
}
void Approx_MCurvesToBSpCurve::Append(const AppParCurves_MultiCurve& MC)
{
myCurves.Append(MC);
}
void Approx_MCurvesToBSpCurve::Perform()
{
Perform(myCurves);
}
void Approx_MCurvesToBSpCurve::Perform
(const AppParCurves_SequenceOfMultiCurve& TheSeq)
{
Standard_Integer i, j, deg=0;
Standard_Integer nbcu = TheSeq.Length();
AppParCurves_MultiCurve CU;
Standard_Integer nbpolesspl=0, nbknots=0;
#ifdef DEB
Standard_Boolean debug = Standard_False;
#endif
if (nbcu == 1) {
CU = TheSeq.Value(1);
deg = CU.Degree();
TColStd_Array1OfReal Knots(1, 2);
TColStd_Array1OfInteger Mults(1, 2);
Knots(1) = 0.0;
Knots(2) = 1.0;
Mults(1) = Mults(2) = deg+1;
mySpline = AppParCurves_MultiBSpCurve (CU, Knots, Mults);
}
else {
AppParCurves_MultiPoint P = TheSeq.Value(nbcu).Value(1);
Standard_Integer nb3d = P.NbPoints();
Standard_Integer nb2d = P.NbPoints2d();
Convert_CompBezierCurvesToBSplineCurve conv;
Convert_CompBezierCurves2dToBSplineCurve2d conv2d;
if (nb3d != 0) {
for (i = 1; i <= nbcu; i++) {
CU = TheSeq.Value(i);
TColgp_Array1OfPnt ThePoles3d(1, CU.NbPoles());
CU.Curve(1, ThePoles3d);
conv.AddCurve(ThePoles3d);
}
conv.Perform();
}
else if (nb2d != 0) {
for (i = 1; i <= nbcu; i++) {
CU = TheSeq.Value(i);
TColgp_Array1OfPnt2d ThePoles2d(1, CU.NbPoles());
CU.Curve(1+nb3d, ThePoles2d);
conv2d.AddCurve(ThePoles2d);
}
conv2d.Perform();
}
// Recuperation:
if (nb3d != 0) {
nbpolesspl = conv.NbPoles();
nbknots = conv.NbKnots();
}
else if (nb2d != 0) {
nbpolesspl = conv2d.NbPoles();
nbknots = conv2d.NbKnots();
}
AppParCurves_Array1OfMultiPoint tabMU(1, nbpolesspl);
TColgp_Array1OfPnt PolesSpl(1, nbpolesspl);
TColgp_Array1OfPnt2d PolesSpl2d(1, nbpolesspl);
TColStd_Array1OfInteger TheMults(1, nbknots);
TColStd_Array1OfReal TheKnots(1, nbknots);
if (nb3d != 0) {
conv.KnotsAndMults(TheKnots, TheMults);
conv.Poles(PolesSpl);
deg = conv.Degree();
}
else if (nb2d != 0) {
conv2d.KnotsAndMults(TheKnots, TheMults);
conv2d.Poles(PolesSpl2d);
deg = conv2d.Degree();
}
for (j = 1; j <= nbpolesspl; j++) {
AppParCurves_MultiPoint MP(nb3d, nb2d);
if (nb3d!=0) {
MP.SetPoint(1, PolesSpl(j));
}
else if (nb2d!=0) {
MP.SetPoint2d(1+nb3d, PolesSpl2d(j));
}
tabMU.SetValue(j, MP);
}
Standard_Integer kpol = 1, kpoles3d=1, kpoles2d=1;
Standard_Integer mydegre, k;
Standard_Integer first, last, Inc, thefirst;
if (nb3d != 0) thefirst = 1;
else thefirst = 2;
for (i = 1; i <= nbcu; i++) {
CU = TheSeq.Value(i);
mydegre = CU.Degree();
if (TheMults(i+1) == deg) last = deg+1; // Continuite C0
else last = deg; // Continuite C1
if (i==nbcu) {last = deg+1;}
first = 1;
if (i==1) first = 1;
else if ((TheMults(i)== deg-1) || (TheMults(i)==deg)) first = 2;
for (j = 2; j <= nb3d; j++) {
kpol = kpoles3d;
TColgp_Array1OfPnt ThePoles(1, CU.NbPoles());
CU.Curve(j, ThePoles);
Inc = deg-mydegre;
TColgp_Array1OfPnt Points(1, deg+1);
if (Inc > 0) {
BSplCLib::IncreaseDegree(deg, ThePoles, PLib::NoWeights(),
Points, PLib::NoWeights());
}
else {
Points = ThePoles;
}
for (k = first; k <= last; k++) {
tabMU.ChangeValue(kpol++).SetPoint(j, Points(k));
}
}
kpoles3d = kpol;
for (j = thefirst; j <= nb2d; j++) {
kpol = kpoles2d;
TColgp_Array1OfPnt2d ThePoles2d(1, CU.NbPoles());
CU.Curve(j+nb3d, ThePoles2d);
Inc = deg-mydegre;
TColgp_Array1OfPnt2d Points2d(1, deg+1);
if (Inc > 0) {
BSplCLib::IncreaseDegree(deg, ThePoles2d, PLib::NoWeights(),
Points2d, PLib::NoWeights());
}
else {
Points2d = ThePoles2d;
}
for (k = first; k <= last; k++) {
tabMU.ChangeValue(kpol++).SetPoint2d(j+nb3d, Points2d(k));
}
}
kpoles2d = kpol;
}
mySpline = AppParCurves_MultiBSpCurve(tabMU, TheKnots, TheMults);
}
#ifdef DEB
if(debug) DEBUG(mySpline);
#endif
myDone = Standard_True;
}
const AppParCurves_MultiBSpCurve& Approx_MCurvesToBSpCurve::Value() const
{
return mySpline;
}
const AppParCurves_MultiBSpCurve& Approx_MCurvesToBSpCurve::ChangeValue()
{
return mySpline;
}

View File

@@ -0,0 +1,105 @@
-- File: Approx_SameParameter.cdl
-- Created: Fri Jun 2 17:16:15 1995
-- Author: Xavier BENVENISTE
-- <xab@nonox>
---Copyright: Matra Datavision 1995
class SameParameter from Approx
---Purpose: Approximation of a PCurve on a surface to make its
-- parameter be the same that the parameter of a given 3d
-- reference curve.
uses
HSurface from Adaptor3d,
HCurve from Adaptor3d,
HCurve2d from Adaptor2d,
Surface from Geom,
Curve from Geom,
Curve from Geom2d,
BSplineCurve from Geom2d
raises OutOfRange from Standard,
ConstructionError from Standard
is
Create (C3D : Curve from Geom;
C2D : Curve from Geom2d;
S : Surface from Geom;
Tol : Real)
returns SameParameter from Approx
---Purpose:
-- Warning: the C3D and C2D must have the same parametric domain.
--
raises ConstructionError;
Create (C3D : HCurve from Adaptor3d;
C2D : Curve from Geom2d;
S : HSurface from Adaptor3d;
Tol : Real)
returns SameParameter from Approx
---Purpose:
--Warning: the C3D and C2D must have the same parametric domain.
raises ConstructionError;
Create (C3D : HCurve from Adaptor3d;
C2D : HCurve2d from Adaptor2d;
S : HSurface from Adaptor3d;
Tol : Real)
returns SameParameter from Approx
---Purpose:
-- Warning: the C3D and C2D must have the same parametric domain.
--
raises ConstructionError;
Build (me : in out;
Tol : Real from Standard)
---Purpose: Compute the Pcurve (internal use only).
is static private;
IsDone(me) returns Boolean from Standard;
---C++: inline
TolReached(me) returns Real from Standard;
---C++: inline
IsSameParameter(me)
---C++: inline
---Purpose: Tells whether the original data had already the same
-- parameter up to the tolerance : in that case nothing
-- is done.
returns Boolean from Standard;
Curve2d(me)
---C++: inline
---Purpose: Returns the 2D curve that has the same parameter as
-- the 3D curve once evaluated on the surface up to the
-- specified tolerance
returns BSplineCurve from Geom2d;
fields
mySameParameter : Boolean from Standard;
myDone : Boolean from Standard;
myTolReached : Real from Standard;
myCurve2d : BSplineCurve from Geom2d;
myHCurve2d : HCurve2d from Adaptor2d;
myC3d : HCurve from Adaptor3d;
mySurf : HSurface from Adaptor3d;
end SameParameter;

View File

@@ -0,0 +1,814 @@
// File: Approx_SameParameter.cxx
// Created: Tue Jun 6 09:51:17 1995
// Author: Xavier BENVENISTE
// <xab@nonox>
// Modified by skv - Wed Jun 2 11:49:59 2004 OCC5898
#include <Approx_SameParameter.ixx>
#include <TColStd_Array1OfReal.hxx>
#include <BSplCLib.hxx>
#include <Adaptor3d_CurveOnSurface.hxx>
#include <Geom2dAdaptor_Curve.hxx>
#include <Geom2dAdaptor_HCurve.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GeomAdaptor_HCurve.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <GeomAdaptor_HSurface.hxx>
//#include <GCPnts_UniformDeflection.hxx>
#include <GCPnts_QuasiUniformDeflection.hxx>
#include <Extrema_LocateExtPC.hxx>
#include <AdvApprox_ApproxAFunction.hxx>
#include <GeomLib_MakeCurvefromApprox.hxx>
#include <Precision.hxx>
#define MAX_ARRAY_SIZE 1000 // IFV, Jan 2000
#ifdef DEB
#ifdef DRAW
#include <DrawTrSurf.hxx>
#endif
#include <Geom2d_BSplineCurve.hxx>
#include <stdio.h>
static Standard_Boolean Voir = Standard_False;
static Standard_Boolean AffichFw = Standard_False;
static Standard_Integer NbCurve = 0;
#endif
//
// sert a tester si Extrema raconte pas des betises
//
static void ProjectPointOnCurve(const Standard_Real InitValue,
const gp_Pnt APoint,
const Standard_Real Tolerance,
const Standard_Integer NumIteration,
const Adaptor3d_Curve& Curve,
Standard_Boolean& Status,
Standard_Real& Result)
{
Standard_Integer num_iter = 0,
not_done = 1,
ii ;
gp_Pnt a_point ;
gp_Vec vector,
d1,
d2 ;
Standard_Real func,
func_derivative,
param = InitValue ;
Status = Standard_False ;
Standard_Real Toler = 1.0e-12;
do {
num_iter += 1 ;
Curve.D2(param,
a_point,
d1,
d2) ;
for (ii = 1 ; ii <= 3 ; ii++) {
vector.SetCoord(ii, APoint.Coord(ii) - a_point.Coord(ii)) ;
}
func = vector.Dot(d1) ;
func_derivative = vector.Dot(d2) ;
func_derivative -= d1.Dot(d1) ;
if ( Abs(func) < Tolerance * d1.Magnitude()) {
not_done = 0 ;
Status = Standard_True ;
}
else
{ // fixing a bug PRO18577 : avoid divizion by zero
if( Abs(func_derivative) > Toler ) {
param -= func / func_derivative ;
}
param = Max(param,Curve.FirstParameter()) ;
param = Min(param,Curve.LastParameter()) ;
Status = Standard_True ;
}
}
while (not_done && num_iter <= NumIteration) ;
Result = param ;
}
//=======================================================================
//class : Approx_SameParameter_Evaluator
//purpose :
//=======================================================================
class Approx_SameParameter_Evaluator : public AdvApprox_EvaluatorFunction
{
public:
Approx_SameParameter_Evaluator (const TColStd_Array1OfReal& theFlatKnots,
const TColStd_Array1OfReal& thePoles,
const Handle(Adaptor2d_HCurve2d)& theHCurve2d)
: FlatKnots(theFlatKnots), Poles(thePoles), HCurve2d(theHCurve2d) {}
virtual void Evaluate (Standard_Integer *Dimension,
Standard_Real StartEnd[2],
Standard_Real *Parameter,
Standard_Integer *DerivativeRequest,
Standard_Real *Result, // [Dimension]
Standard_Integer *ErrorCode);
private:
const TColStd_Array1OfReal& FlatKnots;
const TColStd_Array1OfReal& Poles;
Handle(Adaptor2d_HCurve2d) HCurve2d;
};
void Approx_SameParameter_Evaluator::Evaluate (Standard_Integer *,/*Dimension*/
Standard_Real /*StartEnd*/[2],
Standard_Real *Parameter,
Standard_Integer *DerivativeRequest,
Standard_Real *Result,
Standard_Integer *ReturnCode)
{
gp_Pnt2d Point ;
gp_Vec2d Vector ;
Standard_Integer extrap_mode[2] ;
extrap_mode[0] = extrap_mode[1] = 3;
Standard_Real eval_result[2] ;
Standard_Real *PolesArray =
(Standard_Real *) &Poles(Poles.Lower()) ;
//
// evaluate the 1D bspline that represents the change in parameterization
//
BSplCLib::Eval(*Parameter,
Standard_False,
*DerivativeRequest,
extrap_mode[0],
3,
FlatKnots,
1,
PolesArray[0],
eval_result[0]) ;
if (*DerivativeRequest == 0){
HCurve2d->D0(eval_result[0],Point);
Point.Coord(Result[0],Result[1]);
}
else if (*DerivativeRequest == 1){
HCurve2d->D1(eval_result[0], Point, Vector);
Vector.Multiply(eval_result[1]);
Vector.Coord(Result[0],Result[1]);
}
ReturnCode[0] = 0 ;
}
static Standard_Real ComputeTolReached(const Handle(Adaptor3d_HCurve)& c3d,
const Adaptor3d_CurveOnSurface& cons,
const Standard_Integer nbp)
{
Standard_Real d2 = 0.;
Standard_Integer nn = nbp;
Standard_Real unsurnn = 1./nn;
Standard_Real first = c3d->FirstParameter();
Standard_Real last = c3d->LastParameter();
for(Standard_Integer i = 0; i <= nn; i++){
Standard_Real t = unsurnn*i;
Standard_Real u = first*(1.-t) + last*t;
gp_Pnt Pc3d = c3d->Value(u);
gp_Pnt Pcons = cons.Value(u);
if (Precision::IsInfinite(Pcons.X()) ||
Precision::IsInfinite(Pcons.Y()) ||
Precision::IsInfinite(Pcons.Z())) {
d2=Precision::Infinite();
break;
}
Standard_Real temp = Pc3d.SquareDistance(Pcons);
if(temp > d2) d2 = temp;
}
d2 = 1.5*sqrt(d2);
if(d2<1.e-7) d2 = 1.e-7;
return d2;
}
static Standard_Boolean Check(const TColStd_Array1OfReal& FlatKnots,
const TColStd_Array1OfReal& Poles,
const Standard_Integer nbp,
const TColStd_Array1OfReal& pc3d,
// const TColStd_Array1OfReal& pcons,
const TColStd_Array1OfReal& ,
const Handle(Adaptor3d_HCurve)& c3d,
const Adaptor3d_CurveOnSurface& cons,
Standard_Real& tol,
const Standard_Real oldtol)
{
Standard_Real d = tol;
Standard_Integer extrap_mode[2] ;
extrap_mode[0] = extrap_mode[1] = 3;
Standard_Integer i;
#ifdef DEB
if (Voir) {
cout<<endl;
cout<<"Controle du changement de variable : "<<endl;
cout<<"baillement mesure par projection : "<<d<<endl;
cout<<"Nombre de points : "<<nbp<<endl;
}
#endif
#if 0
Standard_Real glis = 0., dglis = 0.;
for(i = 1; i <= nbp; i++){
Standard_Real tc3d = pc3d(i);
gp_Pnt Pc3d = c3d->Value(tc3d);
Standard_Real tcons;
BSplCLib::Eval(tc3d,Standard_False,0,extrap_mode[0],
3,FlatKnots,1, (Standard_Real&)Poles(1),tcons);
gp_Pnt Pcons = cons.Value(tcons);
Standard_Real temp = Pc3d.SquareDistance(Pcons);
if(temp >= dglis) dglis = temp;
temp = Abs(tcons-pcons(i));
if(temp >= glis) glis = temp;
}
dglis = sqrt(dglis);
#ifdef DEB
if ( Voir) {
cout<<"glissement de parametre aux points imposes : "<<glis<<endl;
cout<<"distance de glissement aux points imposes : "<<dglis<<endl;
}
#endif
dglis = 0.;
for(i = 1; i < nbp; i++){
Standard_Real tc3d = 0.5*(pc3d(i)+pc3d(i+1));
gp_Pnt Pc3d = c3d->Value(tc3d);
Standard_Real tcons;
BSplCLib::Eval(tc3d,Standard_False,0,extrap_mode[0],
3,FlatKnots,1, (Standard_Real&)Poles(1),tcons);
gp_Pnt Pcons = cons.Value(tcons);
Standard_Real temp = Pc3d.SquareDistance(Pcons);
if(temp >= dglis) dglis = temp;
}
dglis = sqrt(dglis);
#ifdef DEB
if (Voir)
cout<<"distance de glissement en milieu d intervals : "<<dglis<<endl;
#endif
#endif
Standard_Real d2 = 0.;
Standard_Integer nn = 2*nbp;
Standard_Real unsurnn = 1./nn;
// Modified by skv - Wed Jun 2 11:49:59 2004 OCC5898 Begin
// Correction of the interval of valid values. This condition has no sensible
// grounds. But it is better then the old one (which is commented out) because
// it fixes the bug OCC5898. To develop more or less sensible criterion it is
// necessary to deeply investigate this problem which is not possible in frames
// of debugging.
// Standard_Real firstborne= 2*pc3d(1)-pc3d(nbp);
// Standard_Real lastborne= 2*pc3d(nbp)-pc3d(1);
Standard_Real firstborne= 3.*pc3d(1) - 2.*pc3d(nbp);
Standard_Real lastborne = 3.*pc3d(nbp) - 2.*pc3d(1);
// Modified by skv - Wed Jun 2 11:50:03 2004 OCC5898 End
for(i = 0; i <= nn; i++){
Standard_Real t = unsurnn*i;
Standard_Real tc3d = pc3d(1)*(1.-t) + pc3d(nbp)*t;
gp_Pnt Pc3d = c3d->Value(tc3d);
Standard_Real tcons;
BSplCLib::Eval(tc3d,Standard_False,0,extrap_mode[0],
3,FlatKnots,1, (Standard_Real&)Poles(1),tcons);
if (tcons < firstborne || tcons > lastborne) {
tol=Precision::Infinite();
return Standard_False;
}
gp_Pnt Pcons = cons.Value(tcons);
Standard_Real temp = Pc3d.SquareDistance(Pcons);
if(temp > d2) d2 = temp;
}
tol = sqrt(d2);
#ifdef DEB
if (Voir)
cout<<"distance max sur "<<nn<<" points : "<<tol<<endl<<endl;
#endif
return ((tol <= d) || (tol > 0.8 * oldtol));
}
//=======================================================================
//function : Approx_SameParameter
//purpose :
//=======================================================================
Approx_SameParameter::Approx_SameParameter(const Handle(Geom_Curve)& C3D,
const Handle(Geom2d_Curve)& C2D,
const Handle(Geom_Surface)& S,
const Standard_Real Tol):
mySameParameter(Standard_True), myDone(Standard_False)
{
myHCurve2d = new Geom2dAdaptor_HCurve(C2D);
myC3d = new GeomAdaptor_HCurve(C3D);
mySurf = new GeomAdaptor_HSurface(S);
Build(Tol);
}
//=======================================================================
//function : Approx_SameParameter
//purpose :
//=======================================================================
Approx_SameParameter::Approx_SameParameter(const Handle(Adaptor3d_HCurve)& C3D,
const Handle(Geom2d_Curve)& C2D,
const Handle(Adaptor3d_HSurface)& S,
const Standard_Real Tol):
mySameParameter(Standard_True), myDone(Standard_False)
{
myC3d = C3D;
mySurf = S;
myHCurve2d = new Geom2dAdaptor_HCurve(C2D);
Build(Tol);
}
//=======================================================================
//function : Approx_SameParameter
//purpose :
//=======================================================================
Approx_SameParameter::Approx_SameParameter(const Handle(Adaptor3d_HCurve)& C3D,
const Handle(Adaptor2d_HCurve2d)& C2D,
const Handle(Adaptor3d_HSurface)& S,
const Standard_Real Tol):
mySameParameter(Standard_True), myDone(Standard_False)
{
myC3d = C3D;
mySurf = S;
myHCurve2d = C2D;
Build(Tol);
}
//=======================================================================
//function : Build
//purpose :
//=======================================================================
void Approx_SameParameter::Build(const Standard_Real Tolerance)
{
Standard_Integer ii ;
Adaptor3d_CurveOnSurface CurveOnSurface(myHCurve2d,mySurf);
Standard_Real fcons = CurveOnSurface.FirstParameter();
Standard_Real lcons = CurveOnSurface.LastParameter();
Standard_Real fc3d = myC3d->FirstParameter();
Standard_Real lc3d = myC3d->LastParameter();
GeomAbs_Shape Continuity = myHCurve2d->Continuity();
if(Continuity > GeomAbs_C1) Continuity = GeomAbs_C1;
//On controle les tangentes aux extremites pour savoir si le
//reparametrage est possible et on calcule les tangentes aux
//extremites de la fonction de changement de variable.
Standard_Real tangent[2];
gp_Pnt Pcons,Pc3d;
gp_Vec Vcons,Vc3d;
Standard_Real Tol = Tolerance;
Standard_Real Tol2 = Tol * Tol;
Standard_Real Tolp = myC3d->Resolution(Tol), deltamin = 50*Tolp;
Standard_Real besttol2 = Tol2;
Standard_Boolean extrok = 0;
extrok = 1;
CurveOnSurface.D1(fcons,Pcons,Vcons);
myC3d->D1(fc3d,Pc3d,Vc3d);
Standard_Real dist2 = Pcons.SquareDistance(Pc3d);
Standard_Real dmax2 = dist2;
Standard_Real magVcons = Vcons.Magnitude();
if (magVcons > 1.e-12){
tangent[0] = Vc3d.Magnitude() / magVcons;
}
else extrok = 0;
CurveOnSurface.D1(lcons,Pcons,Vcons);
myC3d->D1(lc3d,Pc3d,Vc3d);
dist2 = Pcons.SquareDistance(Pc3d);
if(dist2 > dmax2) dmax2 = dist2;
magVcons = Vcons.Magnitude();
if (magVcons > 1.e-12){
tangent[1] = Vc3d.Magnitude() / magVcons;
}
else extrok = 0;
if(dmax2 > besttol2) besttol2 = dmax2;
//On prend un multiple de l echantillon du CheckShape,
//au moins les points de controle seront bons. No comment!!!
Standard_Integer NCONTROL = 22;
#ifdef DEB
Standard_Integer nbcoups = 0;
#endif
Standard_Boolean interpolok = 0;
Standard_Real tolsov = 1.e200;
//On prend des parametres a pas constant sur la curve on surface
//et sur la courbe 3d.
Standard_Real deltacons = lcons - fcons;
deltacons /= (NCONTROL);
Standard_Real deltac3d = lc3d - fc3d;
deltac3d /= (NCONTROL);
Standard_Real wcons = fcons;
Standard_Real wc3d = fc3d;
Standard_Real qpcons[MAX_ARRAY_SIZE], qnewpcons[MAX_ARRAY_SIZE],
qpc3d[MAX_ARRAY_SIZE], qnewpc3d[MAX_ARRAY_SIZE];
Standard_Real * pcons = qpcons; Standard_Real * newpcons = qnewpcons;
Standard_Real * pc3d = qpc3d; Standard_Real * newpc3d = qnewpc3d;
for ( ii = 0 ; ii < NCONTROL; ii++) {
pcons[ii] = wcons;
pc3d[ii] = wc3d;
wcons += deltacons;
wc3d += deltac3d;
}
pcons[NCONTROL] = lcons;
pc3d[NCONTROL] = lc3d;
Standard_Integer New_NCONTROL = NCONTROL;
if(Continuity < GeomAbs_C1) {
Standard_Integer NbInt = myHCurve2d->NbIntervals(GeomAbs_C1) + 1;
TColStd_Array1OfReal Param_de_decoupeC1 (1, NbInt);
myHCurve2d->Intervals(Param_de_decoupeC1, GeomAbs_C1);
TColStd_SequenceOfReal new_par;
Standard_Integer inter = 1;
ii =1;
new_par.Append(fcons);
while(Param_de_decoupeC1(inter) <= fcons + deltamin) inter++;
while(Param_de_decoupeC1(NbInt) >= lcons - deltamin) NbInt--;
while(inter <= NbInt || ii < NCONTROL) {
if(Param_de_decoupeC1(inter) < pcons[ii]) {
new_par.Append(Param_de_decoupeC1(inter));
if((pcons[ii] - Param_de_decoupeC1(inter)) <= deltamin) {
ii++;
if(ii > NCONTROL) {ii = NCONTROL;}
}
inter++;
}
else {
if((Param_de_decoupeC1(inter) - pcons[ii]) > deltamin) {
new_par.Append(pcons[ii]);
}
ii++;
}
}
new_par.Append(lcons);
New_NCONTROL = new_par.Length() - 1;
//simple protection if New_NCONTROL > allocated elements in array
if (New_NCONTROL > MAX_ARRAY_SIZE) {
mySameParameter = Standard_False;
return;
}
for(ii = 1; ii <= New_NCONTROL; ii++){
pcons[ii] = pc3d[ii] = new_par.Value(ii + 1);
}
pc3d[New_NCONTROL] = lc3d;
}
Extrema_LocateExtPC Projector;
Projector.Initialize(myC3d->Curve(),fc3d,lc3d,Tol);
Standard_Integer count = 1;
Standard_Real previousp = fc3d, initp=0, curp;//, deltamin = 50*Tolp;
Standard_Real bornesup = lc3d - deltamin;
Standard_Boolean projok = 0,
use_parameter ;
for (ii = 1; ii < New_NCONTROL; ii++){
CurveOnSurface.D0(pcons[ii],Pcons);
myC3d->D0(pc3d[ii],Pc3d);
dist2 = Pcons.SquareDistance(Pc3d);
use_parameter = (dist2 <= Tol2 && (pc3d[ii] > pc3d[count-1] + deltamin)) ;
if(use_parameter) {
if(dist2 > dmax2) dmax2 = dist2;
initp = previousp = pc3d[count] = pc3d[ii];
pcons[count] = pcons[ii];
count++;
}
else {
if(!projok) initp = pc3d[ii];
projok = mySameParameter = Standard_False;
Projector.Perform(Pcons, initp);
if (Projector.IsDone()) {
curp = Projector.Point().Parameter();
Standard_Real dist_2 = Projector.SquareDistance();
if(dist_2 > besttol2) besttol2 = dist_2;
projok = 1;
}
else {
ProjectPointOnCurve(initp,Pcons,Tol,30,myC3d->Curve(),projok,curp);
}
if(projok){
if(curp > previousp + deltamin && curp < bornesup){
initp = previousp = pc3d[count] = curp;
pcons[count] = pcons[ii];
count++;
}
}
else {
#ifdef DEB
// JAG
cout << "Projection not done" << endl;
#endif
}
}
}
if(mySameParameter){
myTolReached = 1.5*sqrt(dmax2);
return;
}
if(!extrok) { // Si pas deja SameP et tgte aux fraise, on abandonne.
mySameParameter = Standard_False;
#ifdef DEB
cout<<"SameParameter probleme : tangente nulle aux extremites"<<endl;
#endif
return;
}
pcons[count] = lcons;
pc3d[count] = lc3d;
#ifdef DEB
if (AffichFw) {
char Name[17];
Name[0]='\0';
TColgp_Array1OfPnt2d DEBP2d (0,count);
TColStd_Array1OfInteger DEBMults(0,count);
DEBMults.Init(1); DEBMults(0) = 2; DEBMults(count) = 2;
TColStd_Array1OfReal DEBKnots(0,count);
for (Standard_Integer DEBi = 0; DEBi <= count; DEBi++) {
DEBKnots(DEBi) = DEBi;
DEBP2d (DEBi) = gp_Pnt2d(pc3d[DEBi],pcons[DEBi]);
}
Handle(Geom2d_BSplineCurve) DEBBS =
new Geom2d_BSplineCurve(DEBP2d,DEBKnots,DEBMults,1);
sprintf(Name,"DEBC2d_%d",++NbCurve);
#ifdef DRAW
DrawTrSurf::Set(Name,DEBBS);
#endif
}
#endif
while(!interpolok){
// Les tableaux et leurs bornes pour l interpolation.
Standard_Integer num_knots = count + 7;
Standard_Integer num_poles = count + 3;
TColStd_Array1OfReal Paramc3d(*pc3d,1,count+1);
TColStd_Array1OfReal Paramcons(*pcons,1,count+1);
TColStd_Array1OfInteger ContactOrder(1,num_poles) ;
TColStd_Array1OfReal Poles(1,num_poles) ;
TColStd_Array1OfReal InterpolationParameters(1,num_poles) ;
TColStd_Array1OfReal FlatKnots(1,num_knots) ;
// On remplit les tableaux en faisant attention aux valeurs des bouts.
ContactOrder.Init(0);
ContactOrder(2) = ContactOrder(num_poles - 1) = 1;
FlatKnots(1) = FlatKnots(2) = FlatKnots(3) = FlatKnots(4) = fc3d;
FlatKnots(num_poles + 1) = FlatKnots(num_poles + 2) =
FlatKnots(num_poles + 3) = FlatKnots(num_poles + 4) = lc3d;
Poles(1) = fcons; Poles(num_poles) = lcons;
Poles(2) = tangent[0]; Poles(num_poles - 1) = tangent[1];
InterpolationParameters(1) = InterpolationParameters(2) = fc3d;
InterpolationParameters(num_poles - 1) = InterpolationParameters(num_poles) = lc3d;
for (ii = 3; ii <= num_poles - 2; ii++) {
Poles(ii) = Paramcons(ii - 1);
InterpolationParameters(ii) = FlatKnots(ii+2) = Paramc3d(ii - 1);
}
Standard_Integer inversion_problem;
BSplCLib::Interpolate(3,FlatKnots,InterpolationParameters,ContactOrder,
1,Poles(1),inversion_problem);
if(inversion_problem) {
Standard_ConstructionError::Raise();
}
//-------------------------------------------
#ifdef DEB
if (AffichFw) {
nbcoups ++;
char Name[17];
Name[0] = '\0';
Standard_Integer nnn = 100;
TColgp_Array1OfPnt2d DEBP2d (0,nnn);
TColStd_Array1OfInteger DEBMults(0,nnn);
DEBMults.Init(1); DEBMults(0) = 2; DEBMults(nnn) = 2;
TColStd_Array1OfReal DEBKnots(0,nnn);
Standard_Real du = (lc3d - fc3d) / nnn;
Standard_Real u3d = fc3d;
Standard_Integer extrap_mode[2] ;
extrap_mode[0] = extrap_mode[1] = 3;
Standard_Real eval_result[2] ;
Standard_Integer DerivativeRequest = 0;
Standard_Real *PolesArray =
(Standard_Real *) &Poles(Poles.Lower()) ;
for (Standard_Integer DEBi = 0; DEBi <= nnn; DEBi++) {
DEBKnots(DEBi) = DEBi;
BSplCLib::Eval(u3d,
Standard_False,
DerivativeRequest,
extrap_mode[0],
3,
FlatKnots,
1,
PolesArray[0],
eval_result[0]) ;
DEBP2d (DEBi) = gp_Pnt2d(u3d,eval_result[0]);
u3d += du;
}
Handle(Geom2d_BSplineCurve) DEBBS =
new Geom2d_BSplineCurve(DEBP2d,DEBKnots,DEBMults,1);
sprintf(Name,"DEBC2d_%d_%d",NbCurve,nbcoups );
#ifdef DRAW
DrawTrSurf::Set(Name,DEBBS);
#endif
}
#endif
//-------------------------------------------
//-------------------------------------------
// Test if par2d(par3d) is monotonous function or not ----- IFV, Jan 2000
// and try to insert new point to improve BSpline interpolation
Standard_Integer extrap_mode[2] ;
extrap_mode[0] = extrap_mode[1] = 3;
Standard_Real eval_result[2] ;
Standard_Integer DerivativeRequest = 0;
Standard_Real *PolesArray =
(Standard_Real *) &Poles(Poles.Lower()) ;
Standard_Integer newcount = 0;
for (ii = 0; ii < count; ii++) {
newpcons[newcount] = pcons[ii];
newpc3d[newcount] = pc3d[ii];
newcount++;
if(count - ii + newcount == MAX_ARRAY_SIZE) continue;
BSplCLib::Eval(.5*(pc3d[ii]+pc3d[ii+1]), Standard_False, DerivativeRequest,
extrap_mode[0], 3, FlatKnots, 1, PolesArray[0], eval_result[0]);
if(eval_result[0] < pcons[ii] || eval_result[0] > pcons[ii+1]) {
Standard_Real ucons = 0.5*(pcons[ii]+pcons[ii+1]);
Standard_Real uc3d = 0.5*(pc3d[ii]+pc3d[ii+1]);
CurveOnSurface.D0(ucons,Pcons);
Projector.Perform(Pcons, uc3d);
if (Projector.IsDone()) {
curp = Projector.Point().Parameter();
Standard_Real dist_2 = Projector.SquareDistance();
if(dist_2 > besttol2) besttol2 = dist_2;
projok = 1;
}
else {
ProjectPointOnCurve(uc3d,Pcons,Tol,30,myC3d->Curve(),projok,curp);
}
if(projok){
if(curp > pc3d[ii] + deltamin && curp < pc3d[ii+1] - deltamin){
newpc3d[newcount] = curp;
newpcons[newcount] = ucons;
newcount ++;
}
}
else {
#ifdef DEB
// JAG
cout << "Projection not done" << endl;
#endif
}
}
}
newpc3d[newcount] = pc3d[count];
newpcons[newcount] = pcons[count];
Standard_Real * temp;
temp = pc3d;
pc3d = newpc3d;
newpc3d = temp;
temp = pcons;
pcons = newpcons;
newpcons = temp;
if((count != newcount) && newcount < MAX_ARRAY_SIZE) { count = newcount; continue;}
count = newcount;
Standard_Real algtol = sqrt(besttol2);
interpolok = Check (FlatKnots, Poles, count+1, Paramc3d, Paramcons,
myC3d, CurveOnSurface, algtol, tolsov);
if (Precision::IsInfinite(algtol)) {
mySameParameter = Standard_False;
#ifdef DEB
cout<<"SameParameter probleme : fonction d'interpolation du parametrage aux fraises !!"<<endl;
#endif
return;
}
tolsov = algtol;
interpolok = (interpolok || count >= MAX_ARRAY_SIZE);
if(interpolok) {
Standard_Real besttol = sqrt(besttol2);
#ifdef DEB
if (Voir) {
if(algtol > besttol){
cout<<"SameParameter : Tol non atteinte avant approx"<<endl;
}
}
#endif
Handle(TColStd_HArray1OfReal) tol1d,tol2d,tol3d;
tol1d = new TColStd_HArray1OfReal(1,2) ;
tol1d->SetValue(1, mySurf->UResolution(besttol));
tol1d->SetValue(2, mySurf->VResolution(besttol));
Approx_SameParameter_Evaluator ev (FlatKnots, Poles, myHCurve2d);
AdvApprox_ApproxAFunction anApproximator(2,0,0,tol1d,tol2d,tol3d,fc3d,lc3d,
Continuity,11,40,ev);
if (anApproximator.IsDone() || anApproximator.HasResult()) {
GeomLib_MakeCurvefromApprox aCurveBuilder(anApproximator) ;
myCurve2d = aCurveBuilder.Curve2dFromTwo1d(1,2) ;
myHCurve2d = new Geom2dAdaptor_HCurve(myCurve2d);
CurveOnSurface.Load(myHCurve2d);
myTolReached = ComputeTolReached(myC3d,CurveOnSurface,NCONTROL);
myDone = Standard_True;
}
}
else {
#ifdef DEB
if (Voir)
cout<<"SameParameter : Pas assez de points, on enrichit"<<endl;
#endif
Standard_Integer newcount = 0;
for(Standard_Integer n = 0; n < count; n++){
newpc3d[newcount] = pc3d[n];
newpcons[newcount] = pcons[n];
newcount ++;
if(count - n + newcount == MAX_ARRAY_SIZE) continue;
Standard_Real ucons = 0.5*(pcons[n]+pcons[n+1]);
Standard_Real uc3d = 0.5*(pc3d[n]+pc3d[n+1]);
CurveOnSurface.D0(ucons,Pcons);
Projector.Perform(Pcons, uc3d);
if (Projector.IsDone()) {
curp = Projector.Point().Parameter();
Standard_Real dist_2 = Projector.SquareDistance();
if(dist_2 > besttol2) besttol2 = dist_2;
projok = 1;
}
else {
ProjectPointOnCurve(uc3d,Pcons,Tol,30,myC3d->Curve(),projok,curp);
}
if(projok){
if(curp > pc3d[n] + deltamin && curp < pc3d[n+1] - deltamin){
newpc3d[newcount] = curp;
newpcons[newcount] = ucons;
newcount ++;
}
}
else {
#ifdef DEB
// JAG
cout << "Projection not done" << endl;
#endif
}
}
newpc3d[newcount] = pc3d[count];
newpcons[newcount] = pcons[count];
Standard_Real * tempx;
tempx = pc3d;
pc3d = newpc3d;
newpc3d = tempx;
tempx = pcons;
pcons = newpcons;
newpcons = tempx;
count = newcount;
}
}
}

View File

@@ -0,0 +1,32 @@
// File: Approx_SameParameter.lxx
// Created: Tue Jun 6 16:38:05 1995
// Author: Modelistation
// <model@fuegox>
//=======================================================================
//function : IsDone
//purpose :
//=======================================================================
inline Standard_Boolean Approx_SameParameter::IsDone() const
{ return myDone ; }
//=======================================================================
//function : TolReached
//purpose :
//=======================================================================
inline Standard_Real Approx_SameParameter::TolReached() const
{ return myTolReached; }
//=======================================================================
//function : IsSameParameter
//purpose :
//=======================================================================
inline Standard_Boolean Approx_SameParameter::IsSameParameter() const
{ return mySameParameter ; }
//=======================================================================
//function : Curve2d
//purpose :
//=======================================================================
inline Handle(Geom2d_BSplineCurve) Approx_SameParameter::Curve2d() const
{ return myCurve2d ; }

View File

@@ -0,0 +1,364 @@
-- File: Approx_SweepApproximation.cdl
-- Created: Tue Jun 24 17:24:35 1997
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1997
class SweepApproximation from Approx
---Purpose: Approximation of an Surface S(u,v)
-- (and eventually associate 2d Curves) defined
-- by section's law.
--
-- This surface is defined by a function F(u, v)
-- where Ft(u) = F(u, t) is a bspline curve.
-- To use this algorithme, you have to implement Ft(u)
-- as a derivative class of Approx_SweepFunction.
-- This algorithm can be used by blending, sweeping...
uses Array2OfReal from TColStd,
HArray2OfReal from TColStd,
Array1OfReal from TColStd,
HArray1OfReal from TColStd,
Array1OfInteger from TColStd,
HArray1OfInteger from TColStd,
Vec from gp,
Array1OfPnt2d from TColgp,
HArray1OfPnt2d from TColgp,
HArray1OfPnt from TColgp,
HArray1OfVec2d from TColgp,
HArray1OfVec from TColgp,
Array2OfPnt from TColgp,
HArray2OfPnt from TColgp,
HArray1OfGTrsf2d from Approx,
SequenceOfArray1OfPnt2d from TColgp,
Shape from GeomAbs,
EvaluatorFunction from AdvApprox,
Cutting from AdvApprox,
SweepFunction from Approx
raises NotDone from StdFail,
DomainError,
OutOfRange
is
Create(Func : SweepFunction from Approx)
returns SweepApproximation from Approx;
Perform(me : in out;
First, Last : Real;
Tol3d, BoundTol, Tol2d, TolAngular : Real;
Continuity : Shape = GeomAbs_C0;
Degmax : Integer = 11;
Segmax : Integer = 50)
---Purpose: Perform the Approximation
-- [First, Last] : Approx_SweepApproximation.cdl
-- Tol3d : Tolerance to surface approximation
-- Tol2d : Tolerance used to perform curve approximation
-- Normaly the 2d curve are approximated with a
-- tolerance given by the resolution on support surfaces,
-- but if this tolerance is too large Tol2d is used.
-- TolAngular : Tolerance (in radian) to control the angle
-- beetween tangents on the section law and
-- tangent of iso-v on approximed surface
-- Continuity : The continuity in v waiting on the surface
-- Degmax : The maximum degree in v requiered on the surface
-- Segmax : The maximum number of span in v requiered on
-- the surface
-- Warning : The continuity ci can be obtained only if Ft is Ci
raises DomainError from Standard;
-- if <Continuity> not in {C0, C1, C2}
-- if <Degmax> < 2 or degmax > Geom_BSplineSurface::MaxDegree()
-- if <Segmax> < 1
-- if one tolerance is <= 0
Approximation(me : in out;
OneDTol, TwoDTol, ThreeDTol : HArray1OfReal;
BounTol : Real;
First, Last : Real;
Continuity : Shape;
Degmax, Segmax : Integer;
TheApproxFunction : EvaluatorFunction from AdvApprox;
TheCuttingTool : Cutting from AdvApprox)
is private;
Eval(me : in out;
Parameter : Real;
DerivativeRequest : Integer;
First, Last : Real;
Result : in out Real)
---Purpose : The EvaluatorFunction from AdvApprox;
returns Integer from Standard;
D0(me : in out;
Param: Real;
First, Last : Real;
Result:in out Real)
returns Boolean is private;
D1(me : in out;
Param: Real;
First, Last : Real;
Result:in out Real)
returns Boolean is private;
D2(me : in out;
Param: Real;
First, Last : Real;
Result:in out Real)
returns Boolean is private;
IsDone(me)
---Purpose : returns if we have an result
returns Boolean from Standard
---C++: inline
is static;
SurfShape(me; UDegree,VDegree : out Integer from Standard;
NbUPoles,NbVPoles: out Integer from Standard;
NbUKnots,NbVKnots: out Integer from Standard)
raises NotDone from StdFail
is static;
Surface(me; TPoles : out Array2OfPnt from TColgp;
TWeights : out Array2OfReal from TColStd;
TUKnots,TVKnots : out Array1OfReal from TColStd;
TUMults,TVMults : out Array1OfInteger from TColStd)
raises NotDone from StdFail
is static;
UDegree(me)
returns Integer from Standard
---C++: inline
raises NotDone from StdFail
is static;
VDegree(me)
returns Integer from Standard
---C++: inline
raises NotDone from StdFail
is static;
SurfPoles(me)
returns Array2OfPnt from TColgp
---C++: inline
---C++: return const&
raises NotDone from StdFail
is static;
SurfWeights(me)
returns Array2OfReal from TColStd
---C++: inline
---C++: return const&
raises NotDone from StdFail
is static;
SurfUKnots(me)
returns Array1OfReal from TColStd
---C++: inline
---C++: return const&
raises NotDone from StdFail
is static;
SurfVKnots(me)
returns Array1OfReal from TColStd
---C++: inline
---C++: return const&
raises NotDone from StdFail
is static;
SurfUMults(me)
returns Array1OfInteger from TColStd
---C++: inline
---C++: return const&
raises NotDone from StdFail
is static;
SurfVMults(me)
returns Array1OfInteger from TColStd
---C++: inline
---C++: return const&
raises NotDone from StdFail
is static;
MaxErrorOnSurf (me)
---Purpose: returns the maximum error in the suface approximation.
returns Real;
AverageErrorOnSurf(me)
---Purpose: returns the average error in the suface approximation.
returns Real;
NbCurves2d(me)
returns Integer from Standard
---C++: inline
raises NotDone from StdFail
is static;
Curves2dShape(me; Degree,NbPoles,NbKnots: out Integer from Standard)
raises NotDone from StdFail,
DomainError from Standard
is static;
Curve2d(me; Index: Integer from Standard;
TPoles : out Array1OfPnt2d from TColgp;
TKnots : out Array1OfReal from TColStd;
TMults : out Array1OfInteger from TColStd)
raises NotDone from StdFail,
OutOfRange from Standard,
DomainError from Standard
is static;
Curves2dDegree(me)
returns Integer from Standard
---C++: inline
raises NotDone from StdFail,
DomainError from Standard
is static;
Curve2dPoles(me; Index: Integer from Standard)
returns Array1OfPnt2d from TColgp
---C++: inline
---C++: return const&
raises NotDone from StdFail,
OutOfRange from Standard,
DomainError from Standard
is static;
Curves2dKnots(me)
returns Array1OfReal from TColStd
---C++: inline
---C++: return const&
raises NotDone from StdFail,
DomainError from Standard
is static;
Curves2dMults(me)
returns Array1OfInteger from TColStd
---C++: inline
---C++: return const&
raises NotDone from StdFail,
DomainError from Standard
is static;
Max2dError (me; Index : Integer)
---Purpose: returns the maximum error of the <Index>
-- 2d curve approximation.
returns Real;
Average2dError(me; Index : Integer )
---Purpose: returns the average error of the <Index>
-- 2d curve approximation.
returns Real;
TolCurveOnSurf(me; Index : Integer from Standard)
---Purpose: returns the maximum 3d error of the <Index>
-- 2d curve approximation on the Surface.
returns Real from Standard
raises NotDone from StdFail
is static;
Dump(me; o: in out OStream);
---Purpose: display information on approximation.
fields
myFunc : SweepFunction from Approx;
done : Boolean from Standard;
Num1DSS : Integer from Standard;
Num2DSS : Integer from Standard;
Num3DSS : Integer from Standard;
udeg : Integer from Standard;
vdeg : Integer from Standard;
deg2d : Integer from Standard;
tabPoles : HArray2OfPnt from TColgp;
tabWeights: HArray2OfReal from TColStd;
tabUKnots : HArray1OfReal from TColStd;
tabVKnots : HArray1OfReal from TColStd;
tab2dKnots: HArray1OfReal from TColStd;
tabUMults : HArray1OfInteger from TColStd;
tabVMults : HArray1OfInteger from TColStd;
tab2dMults: HArray1OfInteger from TColStd;
seqPoles2d: SequenceOfArray1OfPnt2d from TColgp;
MError1d : HArray1OfReal from TColStd;
tab2dError: HArray1OfReal from TColStd;
MError3d : HArray1OfReal from TColStd;
AError1d : HArray1OfReal from TColStd;
Ave2dError: HArray1OfReal from TColStd;
AError3d : HArray1OfReal from TColStd;
AAffin : HArray1OfGTrsf2d from Approx;
COnSurfErr: HArray1OfReal from TColStd;
Translation : Vec from gp;
--
-- To Accelerate Evaluation :
--
myPoles : HArray1OfPnt;
myPoles2d : HArray1OfPnt2d;
myWeigths : HArray1OfReal;
myDPoles : HArray1OfVec;
myD2Poles : HArray1OfVec;
myDPoles2d : HArray1OfVec2d;
myD2Poles2d: HArray1OfVec2d;
myDWeigths : HArray1OfReal;
myD2Weigths: HArray1OfReal;
myOrder : Integer;
myParam : Real;
first, last: Real;
end SweepApproximation;

View File

@@ -0,0 +1,739 @@
// File: Approx_SweepApproximation.cxx
// Created: Wed Jun 25 17:01:37 1997
// Author: Philippe MANGIN
// <pmn@sgi29>
#include <Approx_SweepApproximation.ixx>
#include <gp_XYZ.hxx>
#include <BSplCLib.hxx>
#include <AdvApprox_ApproxAFunction.hxx>
#include <AdvApprox_DichoCutting.hxx>
#include <AdvApprox_PrefAndRec.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <TColgp_Array1OfVec.hxx>
#include <TColgp_Array1OfVec2d.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <StdFail_NotDone.hxx>
//=======================================================================
//class : Approx_SweepApproximation_Eval
//purpose: evaluator class for approximation
//=======================================================================
class Approx_SweepApproximation_Eval : public AdvApprox_EvaluatorFunction
{
public:
Approx_SweepApproximation_Eval (Approx_SweepApproximation& theTool)
: Tool(theTool) {}
virtual void Evaluate (Standard_Integer *Dimension,
Standard_Real StartEnd[2],
Standard_Real *Parameter,
Standard_Integer *DerivativeRequest,
Standard_Real *Result, // [Dimension]
Standard_Integer *ErrorCode);
private:
Approx_SweepApproximation &Tool;
};
void Approx_SweepApproximation_Eval::Evaluate (Standard_Integer *,/*Dimension*/
Standard_Real StartEnd[2],
Standard_Real *Parameter,
Standard_Integer *DerivativeRequest,
Standard_Real *Result,// [Dimension]
Standard_Integer *ErrorCode)
{
*ErrorCode = Tool.Eval (*Parameter, *DerivativeRequest,
StartEnd[0], StartEnd[1], Result[0]);
}
Approx_SweepApproximation::
Approx_SweepApproximation(const Handle(Approx_SweepFunction)& Func)
{
myFunc = Func;
// Init des variables de controles
myParam = 0;
myOrder = -1;
first = 1.e100; last = -1.e100;
done = Standard_False;
}
void Approx_SweepApproximation::Perform(const Standard_Real First,
const Standard_Real Last,
const Standard_Real Tol3d,
const Standard_Real BoundTol,
const Standard_Real Tol2d,
const Standard_Real TolAngular,
const GeomAbs_Shape Continuity,
const Standard_Integer Degmax,
const Standard_Integer Segmax)
{
Standard_Integer NbPolSect, NbKnotSect, ii;
Standard_Real Tol, Tol3dMin = Tol3d, The3D2DTol=0 ;
GeomAbs_Shape continuity = Continuity;
// (1) Caracteristiques d'une section
myFunc->SectionShape(NbPolSect, NbKnotSect, udeg);
Num2DSS = myFunc->Nb2dCurves();
tabUKnots = new (TColStd_HArray1OfReal) (1, NbKnotSect);
tabUMults = new (TColStd_HArray1OfInteger) (1, NbKnotSect);
myFunc->Knots(tabUKnots->ChangeArray1());
myFunc->Mults(tabUMults->ChangeArray1());
// (2) Decompositition en sous espaces
Handle(TColStd_HArray1OfReal) OneDTol, TwoDTol, ThreeDTol;
Num3DSS = NbPolSect;
// (2.1) Tolerance 3d et 1d
OneDTol = new (TColStd_HArray1OfReal) (1, Num3DSS);
ThreeDTol = new (TColStd_HArray1OfReal) (1, Num3DSS);
myFunc->GetTolerance(BoundTol, Tol3d, TolAngular,
ThreeDTol->ChangeArray1());
for (ii=1; ii<=Num3DSS; ii++)
if (ThreeDTol->Value(ii) < Tol3dMin) Tol3dMin = ThreeDTol->Value(ii);
if (myFunc->IsRational()) {
Standard_Real Size;
Num1DSS = NbPolSect;
TColStd_Array1OfReal Wmin(1, Num1DSS);
myFunc->GetMinimalWeight(Wmin);
Size = myFunc->MaximalSection();
Translation.SetXYZ
(myFunc->BarycentreOfSurf().XYZ());
for (ii=1; ii<=Num3DSS; ii++) {
Tol = ThreeDTol->Value(ii)/2; //Afin de respecter l'erreur sur le resultat final.
OneDTol->SetValue(ii, Tol * Wmin(ii) / Size);
Tol *= Wmin(ii); //Facteur de projection
ThreeDTol->SetValue(ii, Max(Tol, 1.e-20) );
}
}
else { Num1DSS = 0; }
// (2.2) Tolerance et Transformation 2d.
if (Num2DSS == 0) {TwoDTol.Nullify();}
else {
// pour le 2d on definit une affinite a partir des resolutions, afin
// d'avoir une tolerance d'approximation homogene (u/v et 2d/3d)
Standard_Real res, tolu, tolv;
TwoDTol = new (TColStd_HArray1OfReal) (1, Num2DSS);
AAffin = new (Approx_HArray1OfGTrsf2d) (1, Num2DSS);
The3D2DTol= 0.9*BoundTol; // 10% de securite
for (ii=1; ii<=Num2DSS; ii++) {
myFunc->Resolution(ii, The3D2DTol, tolu, tolv);
if ( tolu> tolv ) {
res = tolv;
AAffin->ChangeValue(ii).SetValue(1,1, tolv/tolu);
}
else {
res = tolu;
AAffin->ChangeValue(ii).SetValue(2,2, tolu/tolv);
}
TwoDTol->SetValue(ii, Min( Tol2d, res));
}
}
// (3) Approximation
// Init
myPoles = new (TColgp_HArray1OfPnt)(1, Num3DSS);
myDPoles = new (TColgp_HArray1OfVec)(1, Num3DSS);
myD2Poles = new (TColgp_HArray1OfVec)(1, Num3DSS);
myWeigths = new (TColStd_HArray1OfReal)(1, Num3DSS);
myDWeigths = new (TColStd_HArray1OfReal)(1, Num3DSS);
myD2Weigths = new (TColStd_HArray1OfReal)(1, Num3DSS);
if (Num2DSS>0) {
myPoles2d = new (TColgp_HArray1OfPnt2d)(1, Num2DSS);
myDPoles2d = new (TColgp_HArray1OfVec2d)(1, Num2DSS);
myD2Poles2d = new (TColgp_HArray1OfVec2d)(1, Num2DSS);
COnSurfErr = new (TColStd_HArray1OfReal)(1, Num2DSS);
}
// Controle que myFunc->D2 est implemente
if (continuity >= GeomAbs_C2) {
Standard_Boolean B;
B = myFunc->D2(First, First, Last,
myPoles->ChangeArray1(), myDPoles->ChangeArray1(),
myD2Poles->ChangeArray1(),
myPoles2d->ChangeArray1(), myDPoles2d->ChangeArray1(),
myD2Poles2d->ChangeArray1(),
myWeigths->ChangeArray1(), myDWeigths->ChangeArray1(),
myD2Weigths->ChangeArray1());
if (!B) continuity = GeomAbs_C1;
}
// Controle que myFunc->D1 est implemente
if (continuity == GeomAbs_C1) {
Standard_Boolean B;
B = myFunc->D1(First, First, Last,
myPoles->ChangeArray1(), myDPoles->ChangeArray1(),
myPoles2d->ChangeArray1(), myDPoles2d->ChangeArray1(),
myWeigths->ChangeArray1(), myDWeigths->ChangeArray1());
if (!B) continuity = GeomAbs_C0;
}
//Pour que F soit au moins 20 fois plus precise que son approx
myFunc->SetTolerance(Tol3dMin/20, Tol2d/20);
Standard_Integer NbIntervalC2 = myFunc->NbIntervals(GeomAbs_C2);
Standard_Integer NbIntervalC3 = myFunc->NbIntervals(GeomAbs_C3);
if (NbIntervalC3 > 1) {
// (3.1) Approximation avec decoupe preferentiel
TColStd_Array1OfReal Param_de_decoupeC2 (1, NbIntervalC2+1);
myFunc->Intervals(Param_de_decoupeC2, GeomAbs_C2);
TColStd_Array1OfReal Param_de_decoupeC3 (1, NbIntervalC3+1);
myFunc->Intervals(Param_de_decoupeC3, GeomAbs_C3);
AdvApprox_PrefAndRec Preferentiel(Param_de_decoupeC2,
Param_de_decoupeC3);
Approx_SweepApproximation_Eval ev (*this);
Approximation(OneDTol, TwoDTol, ThreeDTol,
The3D2DTol,
First, Last,
continuity,
Degmax, Segmax,
ev,
Preferentiel);
}
else {
// (3.2) Approximation sans decoupe preferentiel
AdvApprox_DichoCutting Dichotomie;
Approx_SweepApproximation_Eval ev (*this);
Approximation(OneDTol, TwoDTol, ThreeDTol,
The3D2DTol,
First, Last,
continuity,
Degmax, Segmax,
ev,
Dichotomie);
}
}
//========================================================================
//function : Approximation
//purpose : Appel F(t) et stocke les resultats
//========================================================================
void Approx_SweepApproximation::
Approximation(const Handle(TColStd_HArray1OfReal)& OneDTol,
const Handle(TColStd_HArray1OfReal)& TwoDTol,
const Handle(TColStd_HArray1OfReal)& ThreeDTol,
const Standard_Real BoundTol,
const Standard_Real First,const Standard_Real Last,
const GeomAbs_Shape Continuity,const Standard_Integer Degmax,
const Standard_Integer Segmax,
const AdvApprox_EvaluatorFunction& TheApproxFunction,
const AdvApprox_Cutting& TheCuttingTool)
{
AdvApprox_ApproxAFunction Approx(Num1DSS,
Num2DSS,
Num3DSS,
OneDTol,
TwoDTol,
ThreeDTol,
First,
Last,
Continuity,
Degmax,
Segmax,
TheApproxFunction,
TheCuttingTool);
done = Approx.HasResult();
if (done) {
// --> Remplissage des Champs de la surface ----
Standard_Integer ii, jj;
vdeg = Approx.Degree();
// Malheureusement Adv_Approx stock la transpose de
// ce que l'on souhaite, donc l'ecriture
// tabPoles = Approx.Poles() donnerait un resultat errone
// Il n'y a plus qu'a allouer et recopier termes a termes...
tabPoles = new (TColgp_HArray2OfPnt)
(1, Num3DSS, 1, Approx.NbPoles());
tabWeights = new (TColStd_HArray2OfReal)
(1, Num3DSS, 1, Approx.NbPoles());
if (Num1DSS == Num3DSS) {
Standard_Real wpoid;
gp_Pnt P;
for (ii=1; ii <=Num3DSS; ii++) {
for (jj=1; jj <=Approx.NbPoles() ; jj++) {
P = Approx.Poles()->Value(jj,ii);
wpoid = Approx.Poles1d()->Value(jj,ii);
P.ChangeCoord() /= wpoid; // Il faut diviser les poles par les poids
P.Translate(Translation);
tabPoles->SetValue (ii, jj, P);
tabWeights->SetValue(ii, jj, wpoid );
}
}
}
else {
tabWeights->Init(1);
for (ii=1; ii <=Num3DSS; ii++) {
for (jj=1; jj <=Approx.NbPoles() ; jj++) {
tabPoles->SetValue (ii, jj, Approx.Poles ()->Value(jj,ii) );
}
}
}
// ici cela va mieux
tabVKnots = Approx.Knots();
tabVMults = Approx.Multiplicities();
// --> Remplissage des courbes 2d ----------
if (Num2DSS>0) {
gp_GTrsf2d TrsfInv;
deg2d = vdeg;
tab2dKnots = Approx.Knots();
tab2dMults = Approx.Multiplicities();
for (ii=1; ii<=Num2DSS; ii++) {
TrsfInv = AAffin->Value(ii).Inverted();
Handle(TColgp_HArray1OfPnt2d) P2d =
new (TColgp_HArray1OfPnt2d) (1, Approx.NbPoles());
Approx.Poles2d( ii, P2d->ChangeArray1() );
// On n'oublie pas d'appliquer l'homothetie inverse.
for (jj=1; jj<=Approx.NbPoles(); jj++) {
TrsfInv.Transforms(P2d->ChangeValue(jj).ChangeCoord());
}
seqPoles2d.Append(P2d);
}
}
// ---> Remplissage des erreurs
MError3d = new (TColStd_HArray1OfReal) (1,Num3DSS);
AError3d = new (TColStd_HArray1OfReal) (1,Num3DSS);
for (ii=1; ii<=Num3DSS; ii++) {
MError3d->SetValue(ii, Approx.MaxError(3, ii));
AError3d->SetValue(ii, Approx.AverageError(3, ii));
}
if (myFunc->IsRational()) {
MError1d = new (TColStd_HArray1OfReal) (1,Num3DSS);
AError1d = new (TColStd_HArray1OfReal) (1,Num3DSS);
for (ii=1; ii<=Num1DSS; ii++) {
MError1d->SetValue(ii, Approx.MaxError(1, ii));
AError1d->SetValue(ii, Approx.AverageError(1, ii));
}
}
if (Num2DSS>0) {
tab2dError = new (TColStd_HArray1OfReal) (1,Num2DSS);
Ave2dError = new (TColStd_HArray1OfReal) (1,Num2DSS);
for (ii=1; ii<=Num2DSS; ii++) {
tab2dError->SetValue(ii, Approx.MaxError(2, ii));
Ave2dError->SetValue(ii, Approx.AverageError(2, ii));
COnSurfErr->SetValue(ii,
(tab2dError->Value(ii)/TwoDTol->Value(ii))*BoundTol);
}
}
}
}
Standard_Integer Approx_SweepApproximation::Eval(const Standard_Real Parameter,
const Standard_Integer DerivativeRequest,
const Standard_Real First,
const Standard_Real Last,
Standard_Real& Result)
{
Standard_Integer ier=0;
switch (DerivativeRequest) {
case 0 :
ier = ( ! D0(Parameter, First, Last, Result));
break;
case 1 :
ier = ( ! D1(Parameter, First, Last, Result));
break;
case 2 :
ier = ( ! D2(Parameter, First, Last,Result));
break;
default :
ier = 2;
}
return ier;
}
Standard_Boolean Approx_SweepApproximation::D0(const Standard_Real Param,
const Standard_Real First,
const Standard_Real Last,
Standard_Real& Result)
{
Standard_Integer index, ii;
Standard_Boolean Ok=Standard_True;
Standard_Real * LocalResult = &Result;
// Gestion des Bornes
if ((first!=First) || (Last!=last)) {
myFunc->SetInterval(First, Last);
}
if (! ( (Param==myParam) && (myOrder>=0)
&& (first==First) && (Last==last)) ) {
// Positionement dans le cas ou l'on ne repete pas
// la derniere operation
Ok = myFunc->D0(Param, First, Last,
myPoles->ChangeArray1(),
myPoles2d->ChangeArray1(),
myWeigths->ChangeArray1());
// On multiplie les poles3d par les poids apres tranlations.
for (ii=1; ii<=Num1DSS; ii++) {
myPoles->ChangeValue(ii).ChangeCoord()
-= Translation.XYZ();
myPoles->ChangeValue(ii).ChangeCoord()
*= myWeigths->Value(ii);
}
// On applique la transformation aux poles 2d.
for (ii=1; ii<=Num2DSS; ii++) {
AAffin->Value(ii).Transforms(myPoles2d->ChangeValue(ii).ChangeCoord());
}
// Mise a jour des variable de controles et retour
first = First;
last = Last;
myOrder = 0;
myParam = Param;
}
// Extraction des resultats
index = 0;
for (ii=1; ii<=Num1DSS; ii++) {
LocalResult[index] = myWeigths->Value(ii);
index++;
}
for (ii=1; ii<=Num2DSS; ii++) {
LocalResult[index] = myPoles2d->Value(ii).X();
LocalResult[index+1] = myPoles2d->Value(ii).Y();
index += 2;
}
for (ii=1; ii<=Num3DSS; ii++, index+=3) {
LocalResult[index] = myPoles->Value(ii).X();
LocalResult[index+1] = myPoles->Value(ii).Y();
LocalResult[index+2] = myPoles->Value(ii).Z();
}
return Ok;
}
Standard_Boolean Approx_SweepApproximation::D1(const Standard_Real Param,
const Standard_Real First,
const Standard_Real Last,
Standard_Real& Result)
{
gp_XY Vcoord;
gp_Vec Vaux;
Standard_Integer index, ii;
Standard_Boolean Ok=Standard_True;
Standard_Real * LocalResult = &Result;
if ((first!=First) || (Last!=last)) {
myFunc->SetInterval(First, Last);
}
if (! ( (Param==myParam) && (myOrder>=1)
&& (first==First) && (Last==last)) ){
// Positionement
Ok = myFunc->D1(Param, First, Last,
myPoles->ChangeArray1(),
myDPoles->ChangeArray1(),
myPoles2d->ChangeArray1(),
myDPoles2d->ChangeArray1(),
myWeigths->ChangeArray1(),
myDWeigths->ChangeArray1());
// On tient compte de la multiplication des poles3d par les poids.
// et de la translation.
for ( ii=1; ii<=Num1DSS; ii++) {
//Translation sur la section
myPoles->ChangeValue(ii).ChangeCoord()
-= Translation.XYZ();
// Homothetie sur tout
myDPoles->ChangeValue(ii) *= myWeigths->Value(ii);
Vaux.SetXYZ( myPoles->Value(ii).Coord());
myDPoles->ChangeValue(ii) += myDWeigths->Value(ii)*Vaux;
myPoles->ChangeValue(ii).ChangeCoord()
*= myWeigths->Value(ii); // Pour le cache
}
// On applique les transformation 2d aux vecteurs idoines
for (ii=1; ii<=Num2DSS; ii++) {
Vcoord = myDPoles2d->Value(ii).XY();
AAffin->Value(ii).Transforms(Vcoord);
myDPoles2d->ChangeValue(ii).SetXY(Vcoord);
AAffin->Value(ii).Transforms(myPoles2d->ChangeValue(ii).ChangeCoord());
}
// Mise a jour des variable de controles et retour
first = First;
last = Last;
myOrder = 1;
myParam = Param;
}
// Extraction des resultats
index = 0;
for (ii=1; ii<=Num1DSS; ii++) {
LocalResult[index] = myDWeigths->Value(ii);
index++;
}
for (ii=1; ii<=Num2DSS; ii++) {
LocalResult[index] = myDPoles2d->Value(ii).X();
LocalResult[index+1] = myDPoles2d->Value(ii).Y();
index += 2;
}
for (ii=1; ii<=Num3DSS; ii++, index+=3) {
LocalResult[index] = myDPoles->Value(ii).X();
LocalResult[index+1] = myDPoles->Value(ii).Y();
LocalResult[index+2] = myDPoles->Value(ii).Z();
}
return Ok;
}
Standard_Boolean Approx_SweepApproximation::D2(const Standard_Real Param,
const Standard_Real First,
const Standard_Real Last,
Standard_Real& Result)
{
gp_XY Vcoord;
gp_Vec Vaux;
Standard_Integer index, ii;
Standard_Boolean Ok=Standard_True;
Standard_Real * LocalResult = &Result;
// Gestion des Bornes
if ((first!=First) || (Last!=last)) {
myFunc->SetInterval(First, Last);
}
if (! ( (Param==myParam) && (myOrder>=2)
&& (first==First) && (Last==last)) ) {
// Positionement dans le cas ou l'on ne repete pas
// la derniere operation
Ok = myFunc->D2(Param, First, Last,
myPoles->ChangeArray1(),
myDPoles->ChangeArray1(),
myD2Poles->ChangeArray1(),
myPoles2d->ChangeArray1(),
myDPoles2d->ChangeArray1(),
myD2Poles2d->ChangeArray1(),
myWeigths->ChangeArray1(),
myDWeigths->ChangeArray1(),
myD2Weigths->ChangeArray1());
// On multiplie les poles3d par les poids apres tranlations.
for (ii=1; ii<=Num1DSS; ii++) {
// D'abord on translate
myPoles->ChangeValue(ii).ChangeCoord()
-= Translation.XYZ();
//On calcul la derive seconde
myD2Poles->ChangeValue(ii) *= myWeigths->Value(ii);
Vaux.SetXYZ( myDPoles->Value(ii).XYZ());
myD2Poles->ChangeValue(ii) += (2*myDWeigths->Value(ii))*Vaux;
Vaux.SetXYZ( myPoles->Value(ii).Coord());
myD2Poles->ChangeValue(ii) += myD2Weigths->Value(ii)*Vaux;
//Puis le reste pour le cache
myDPoles->ChangeValue(ii) *= myWeigths->Value(ii);
Vaux.SetXYZ( myPoles->Value(ii).Coord());
myDPoles->ChangeValue(ii) += myDWeigths->Value(ii)*Vaux;
myPoles->ChangeValue(ii).ChangeCoord()
*= myWeigths->Value(ii);
}
// On applique la transformation aux poles 2d.
for (ii=1; ii<=Num2DSS; ii++) {
Vcoord = myD2Poles2d->Value(ii).XY();
AAffin->Value(ii).Transforms(Vcoord);
myD2Poles2d->ChangeValue(ii).SetXY(Vcoord);
Vcoord = myDPoles2d->Value(ii).XY();
AAffin->Value(ii).Transforms(Vcoord);
myDPoles2d->ChangeValue(ii).SetXY(Vcoord);
AAffin->Value(ii).Transforms(myPoles2d->ChangeValue(ii).ChangeCoord());
}
// Mise a jour des variable de controles et retour
first = First;
last = Last;
myOrder = 2;
myParam = Param;
}
// Extraction des resultats
index = 0;
for (ii=1; ii<=Num1DSS; ii++) {
LocalResult[index] = myD2Weigths->Value(ii);
index++;
}
for (ii=1; ii<=Num2DSS; ii++) {
LocalResult[index] = myD2Poles2d->Value(ii).X();
LocalResult[index+1] = myD2Poles2d->Value(ii).Y();
index += 2;
}
for (ii=1; ii<=Num3DSS; ii++, index+=3) {
LocalResult[index] = myD2Poles->Value(ii).X();
LocalResult[index+1] = myD2Poles->Value(ii).Y();
LocalResult[index+2] = myD2Poles->Value(ii).Z();
}
return Ok;
}
void Approx_SweepApproximation::
SurfShape(Standard_Integer& UDegree,
Standard_Integer& VDegree,Standard_Integer& NbUPoles,
Standard_Integer& NbVPoles,
Standard_Integer& NbUKnots,
Standard_Integer& NbVKnots) const
{
if (!done) {StdFail_NotDone::Raise("Approx_SweepApproximation");}
UDegree = udeg;
VDegree = vdeg;
NbUPoles = tabPoles->ColLength();
NbVPoles = tabPoles->RowLength();
NbUKnots = tabUKnots->Length();
NbVKnots = tabVKnots->Length();
}
void Approx_SweepApproximation::
Surface(TColgp_Array2OfPnt& TPoles,
TColStd_Array2OfReal& TWeights,
TColStd_Array1OfReal& TUKnots,
TColStd_Array1OfReal& TVKnots,
TColStd_Array1OfInteger& TUMults,
TColStd_Array1OfInteger& TVMults) const
{
if (!done) {StdFail_NotDone::Raise("Approx_SweepApproximation");}
TPoles = tabPoles->Array2();
TWeights = tabWeights->Array2();
TUKnots = tabUKnots->Array1();
TUMults = tabUMults->Array1();
TVKnots = tabVKnots->Array1();
TVMults = tabVMults->Array1();
}
Standard_Real Approx_SweepApproximation::MaxErrorOnSurf() const
{
Standard_Integer ii;
Standard_Real MaxError = 0, err;
if (!done) {StdFail_NotDone::Raise("Approx_SweepApproximation");}
if (myFunc->IsRational()) {
TColStd_Array1OfReal Wmin(1, Num1DSS);
myFunc->GetMinimalWeight(Wmin);
Standard_Real Size = myFunc->MaximalSection();
for (ii=1; ii<=Num3DSS; ii++) {
err = (Size*MError1d->Value(ii) + MError3d->Value(ii)) / Wmin(ii);
if (err>MaxError) MaxError = err;
}
}
else {
for (ii=1; ii<=Num3DSS; ii++) {
err = MError3d->Value(ii);
if (err>MaxError) MaxError = err;
}
}
return MaxError;
}
Standard_Real Approx_SweepApproximation::AverageErrorOnSurf() const
{
Standard_Integer ii;
Standard_Real MoyError = 0, err;
if (!done) {StdFail_NotDone::Raise("Approx_SweepApproximation");}
if (myFunc->IsRational()) {
TColStd_Array1OfReal Wmin(1, Num1DSS);
myFunc->GetMinimalWeight(Wmin);
Standard_Real Size = myFunc->MaximalSection();
for (ii=1; ii<=Num3DSS; ii++) {
err = (Size*AError1d->Value(ii) + AError3d->Value(ii)) / Wmin(ii);
MoyError += err;
}
}
else {
for (ii=1; ii<=Num3DSS; ii++) {
err = AError3d->Value(ii);
MoyError += err;
}
}
return MoyError/Num3DSS;
}
void Approx_SweepApproximation::Curves2dShape(Standard_Integer& Degree,
Standard_Integer& NbPoles,
Standard_Integer& NbKnots) const
{
if (!done) {StdFail_NotDone::Raise("Approx_SweepApproximation");}
if (seqPoles2d.Length() == 0) {Standard_DomainError::Raise("Approx_SweepApproximation");}
Degree = deg2d;
NbPoles = seqPoles2d(1)->Length();
NbKnots = tab2dKnots->Length();
}
void Approx_SweepApproximation::Curve2d(const Standard_Integer Index,
TColgp_Array1OfPnt2d& TPoles,
TColStd_Array1OfReal& TKnots,
TColStd_Array1OfInteger& TMults) const
{
if (!done) {StdFail_NotDone::Raise("Approx_SweepApproximation");}
if (seqPoles2d.Length() == 0) {Standard_DomainError::Raise("Approx_SweepApproximation");}
TPoles = seqPoles2d(Index)->Array1();
TKnots = tab2dKnots->Array1();
TMults = tab2dMults->Array1();
}
Standard_Real Approx_SweepApproximation::Max2dError(const Standard_Integer Index) const
{
if (!done) {StdFail_NotDone::Raise("Approx_SweepApproximation");}
return tab2dError->Value(Index);
}
Standard_Real Approx_SweepApproximation::Average2dError(const Standard_Integer Index) const
{
if (!done) {StdFail_NotDone::Raise("Approx_SweepApproximation");}
return Ave2dError->Value(Index);
}
Standard_Real Approx_SweepApproximation::TolCurveOnSurf(const Standard_Integer Index) const
{
if (!done) {StdFail_NotDone::Raise("Approx_SweepApproximation");}
return COnSurfErr->Value(Index);
}
void Approx_SweepApproximation::Dump(Standard_OStream& o) const
{
o << "Dump of SweepApproximation" << endl;
if (done) {
o << "Error 3d = " << MaxErrorOnSurf() << endl;
if (Num2DSS>0) {
o << "Error 2d = ";
for (Standard_Integer ii=1; ii<=Num2DSS; ii++)
{ o << Max2dError(ii);
if (ii < Num2DSS) o << " , " << endl;
}
cout << endl;
}
o << tabVKnots->Length()-1 <<" Segment(s) of degree " << vdeg << endl;
}
else cout << " Not Done " << endl;
}

View File

@@ -0,0 +1,117 @@
// File: Approx_SweepApproximation.lxx
// Created: Thu Jun 26 15:33:33 1997
// Author: Philippe MANGIN
// <pmn@sgi29>
#include <StdFail_NotDone.hxx>
#include <TColgp_HArray2OfPnt.hxx>
#include <TColgp_HArray1OfPnt2d.hxx>
#include <TColStd_HArray2OfReal.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <TColStd_HArray1OfInteger.hxx>
inline Standard_Boolean Approx_SweepApproximation::IsDone() const
{
return done;
}
inline Standard_Integer Approx_SweepApproximation::UDegree() const
{
if (!done) {StdFail_NotDone::Raise(" Approx_SweepApproximation");}
return udeg;
}
inline Standard_Integer Approx_SweepApproximation::VDegree() const
{
if (!done) {StdFail_NotDone::Raise(" Approx_SweepApproximation");}
return vdeg;
}
inline const TColgp_Array2OfPnt& Approx_SweepApproximation::SurfPoles() const
{
if (!done) {StdFail_NotDone::Raise(" Approx_SweepApproximation");}
return tabPoles->Array2();
}
inline const TColStd_Array2OfReal& Approx_SweepApproximation::SurfWeights() const
{
if (!done) {StdFail_NotDone::Raise(" Approx_SweepApproximation");}
return tabWeights->Array2();
}
inline const TColStd_Array1OfReal& Approx_SweepApproximation::SurfUKnots() const
{
if (!done) {StdFail_NotDone::Raise(" Approx_SweepApproximation");}
return tabUKnots->Array1();
}
inline const TColStd_Array1OfReal& Approx_SweepApproximation::SurfVKnots() const
{
if (!done) {StdFail_NotDone::Raise(" Approx_SweepApproximation");}
return tabVKnots->Array1();
}
inline const TColStd_Array1OfInteger& Approx_SweepApproximation::SurfUMults() const
{
if (!done) {StdFail_NotDone::Raise(" Approx_SweepApproximation");}
return tabUMults->Array1();
}
inline const TColStd_Array1OfInteger& Approx_SweepApproximation::SurfVMults() const
{
if (!done) {StdFail_NotDone::Raise(" Approx_SweepApproximation");}
return tabVMults->Array1();
}
inline Standard_Integer Approx_SweepApproximation::NbCurves2d() const
{
if (!done) {StdFail_NotDone::Raise(" Approx_SweepApproximation");}
return Num2DSS;
}
inline Standard_Integer Approx_SweepApproximation::Curves2dDegree() const
{
if (!done) {StdFail_NotDone::Raise(" Approx_SweepApproximation");}
if (seqPoles2d.Length() == 0) {Standard_DomainError::Raise();}
return deg2d;
}
inline const TColgp_Array1OfPnt2d& Approx_SweepApproximation::Curve2dPoles(const Standard_Integer Index) const
{
if (!done) {StdFail_NotDone::Raise(" Approx_SweepApproximation");}
if (seqPoles2d.Length() == 0) {Standard_DomainError::Raise();}
return seqPoles2d(Index)->Array1();
}
inline const TColStd_Array1OfReal& Approx_SweepApproximation::Curves2dKnots() const
{
if (!done) {StdFail_NotDone::Raise(" Approx_SweepApproximation");}
if (seqPoles2d.Length() == 0) {Standard_DomainError::Raise();}
return tab2dKnots->Array1();
}
inline const TColStd_Array1OfInteger& Approx_SweepApproximation::Curves2dMults() const
{
if (!done) {StdFail_NotDone::Raise(" Approx_SweepApproximation");}
if (seqPoles2d.Length() == 0) {Standard_DomainError::Raise();}
return tab2dMults->Array1();
}
/*
inline void Approx_SweepApproximation::TolReached(Standard_Real& Tol3d,Standard_Real& Tol2d) const
{
}*/

View File

@@ -0,0 +1,194 @@
-- File: Approx_SweepFunction.cdl
-- Created: Wed Jun 25 10:40:14 1997
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1997
deferred class SweepFunction from Approx inherits TShared from MMgt
---Purpose: defined the function used by SweepApproximation to
-- perform sweeping application.
uses
Shape from GeomAbs,
Pnt from gp,
Array1OfPnt from TColgp,
Array1OfPnt2d from TColgp,
Array1OfVec from TColgp,
Array1OfVec2d from TColgp,
Array1OfInteger from TColStd,
Array1OfReal from TColStd
raises NotImplemented ,
OutOfRange from Standard
is
--
--========== To compute Sections and derivatives Sections
--
D0(me : mutable;
Param: Real;
First, Last : Real;
Poles : out Array1OfPnt from TColgp;
Poles2d : out Array1OfPnt2d from TColgp;
Weigths : out Array1OfReal from TColStd)
---Purpose: compute the section for v = param
returns Boolean is deferred;
D1(me : mutable;
Param: Real;
First, Last : Real;
Poles : out Array1OfPnt from TColgp;
DPoles : out Array1OfVec from TColgp;
Poles2d : out Array1OfPnt2d from TColgp;
DPoles2d : out Array1OfVec2d from TColgp;
Weigths : out Array1OfReal from TColStd;
DWeigths : out Array1OfReal from TColStd)
---Purpose: compute the first derivative in v direction of the
-- section for v = param
-- Warning : It used only for C1 or C2 aproximation
returns Boolean
raises NotImplemented
is virtual;
D2(me : mutable;
Param: Real;
First, Last : Real;
Poles : out Array1OfPnt from TColgp;
DPoles : out Array1OfVec from TColgp;
D2Poles : out Array1OfVec from TColgp;
Poles2d : out Array1OfPnt2d from TColgp;
DPoles2d : out Array1OfVec2d from TColgp;
D2Poles2d : out Array1OfVec2d from TColgp;
Weigths : out Array1OfReal from TColStd;
DWeigths : out Array1OfReal from TColStd;
D2Weigths : out Array1OfReal from TColStd)
---Purpose: compute the second derivative in v direction of the
-- section for v = param
-- Warning : It used only for C2 aproximation
returns Boolean
raises NotImplemented
is virtual;
--
-- =================== General Information On The Function ===================
--
Nb2dCurves(me)
---Purpose: get the number of 2d curves to approximate.
returns Integer is deferred;
SectionShape(me; NbPoles : out Integer from Standard;
NbKnots : out Integer from Standard;
Degree : out Integer from Standard)
---Purpose: get the format of an section
is deferred;
Knots(me; TKnots: out Array1OfReal from TColStd)
---Purpose: get the Knots of the section
is deferred;
Mults(me; TMults: out Array1OfInteger from TColStd)
---Purpose: get the Multplicities of the section
is deferred;
IsRational(me)
---Purpose: Returns if the sections are rationnal or not
returns Boolean is deferred;
--
-- =================== Management of continuity ===================
--
NbIntervals(me; S : Shape from GeomAbs)
---Purpose: Returns the number of intervals for continuity
-- <S>.
-- May be one if Continuity(me) >= <S>
returns Integer is deferred;
Intervals(me; T : in out Array1OfReal from TColStd;
S : Shape from GeomAbs)
---Purpose: Stores in <T> the parameters bounding the intervals
-- of continuity <S>.
--
-- The array must provide enough room to accomodate
-- for the parameters. i.e. T.Length() > NbIntervals()
raises
OutOfRange from Standard
is deferred;
SetInterval(me: mutable; First, Last: Real from Standard)
---Purpose: Sets the bounds of the parametric interval on
-- the fonction
-- This determines the derivatives in these values if the
-- function is not Cn.
is deferred;
-- ===================== To help computation of Tolerance ======
-- Evaluation of error, in 2d space, or on rational function, is
-- difficult. The following methods can help the approximation to
-- make good evaluation and use good tolerances.
--
-- It is not necessary for the following informations to be very
-- precise. A fast evaluation is sufficient.
Resolution(me;
Index : Integer from Standard;
Tol : Real from Standard;
TolU, TolV : out Real from Standard)
---Purpose: Returns the resolutions in the sub-space 2d <Index>
-- This information is usfull to find an good tolerance in
-- 2d approximation.
---Warning: Used only if Nb2dCurve > 0
raises NotImplemented
is virtual;
GetTolerance(me;
BoundTol, SurfTol, AngleTol : Real;
Tol3d : out Array1OfReal)
---Purpose: Returns the tolerance to reach in approximation
-- to satisfy.
-- BoundTol error at the Boundary
-- AngleTol tangent error at the Boundary (in radian)
-- SurfTol error inside the surface.
is deferred;
SetTolerance(me : mutable; Tol3d, Tol2d : Real)
---Purpose: Is usefull, if (me) have to run numerical
-- algorithm to perform D0, D1 or D2
is deferred;
BarycentreOfSurf(me)
---Purpose: Get the barycentre of Surface.
-- An very poor estimation is sufficent.
-- This information is usefull to perform well
-- conditioned rational approximation.
-- Warning: Used only if <me> IsRational
returns Pnt from gp
raises NotImplemented
is virtual;
MaximalSection(me) returns Real
---Purpose: Returns the length of the greater section. This
-- information is usefull to G1's control.
-- Warning: With an little value, approximation can be slower.
raises NotImplemented
is virtual;
GetMinimalWeight(me; Weigths : out Array1OfReal from TColStd)
---Purpose: Compute the minimal value of weight for each poles
-- in all sections.
-- This information is usefull to control error
-- in rational approximation.
-- Warning: Used only if <me> IsRational
raises NotImplemented
is virtual;
end SweepFunction;

View File

@@ -0,0 +1,45 @@
// File: Approx_SweepFunction.cxx
// Created: Wed Jun 25 16:54:26 1997
// Author: Philippe MANGIN
// <pmn@sgi29>
#include <Approx_SweepFunction.ixx>
// Standard_Boolean Approx_SweepFunction::D1(const Standard_Real Param,const Standard_Real First,const Standard_Real Last,TColgp_Array1OfPnt& Poles,TColgp_Array1OfVec& DPoles,TColgp_Array1OfPnt2d& Poles2d,TColgp_Array1OfVec2d& DPoles2d,TColStd_Array1OfReal& Weigths,TColStd_Array1OfReal& DWeigths)
Standard_Boolean Approx_SweepFunction::D1(const Standard_Real ,const Standard_Real ,const Standard_Real ,TColgp_Array1OfPnt& ,TColgp_Array1OfVec& ,TColgp_Array1OfPnt2d& ,TColgp_Array1OfVec2d& ,TColStd_Array1OfReal& ,TColStd_Array1OfReal& )
{
Standard_NotImplemented::Raise("Approx_SweepFunction::D1");
return Standard_False;
}
// Standard_Boolean Approx_SweepFunction::D2(const Standard_Real Param,const Standard_Real First,const Standard_Real Last,TColgp_Array1OfPnt& Poles,TColgp_Array1OfVec& DPoles,TColgp_Array1OfVec& D2Poles,TColgp_Array1OfPnt2d& Poles2d,TColgp_Array1OfVec2d& DPoles2d,TColgp_Array1OfVec2d& D2Poles2d,TColStd_Array1OfReal& Weigths,TColStd_Array1OfReal& DWeigths,TColStd_Array1OfReal& D2Weigths)
Standard_Boolean Approx_SweepFunction::D2(const Standard_Real ,const Standard_Real ,const Standard_Real ,TColgp_Array1OfPnt& ,TColgp_Array1OfVec& ,TColgp_Array1OfVec& ,TColgp_Array1OfPnt2d& ,TColgp_Array1OfVec2d& ,TColgp_Array1OfVec2d& ,TColStd_Array1OfReal& ,TColStd_Array1OfReal& ,TColStd_Array1OfReal& )
{
Standard_NotImplemented::Raise("Approx_SweepFunction::D2");
return Standard_False;
}
// void Approx_SweepFunction::Resolution(const Standard_Integer Index,const Standard_Real Tol,Standard_Real& TolU,Standard_Real& TolV) const
void Approx_SweepFunction::Resolution(const Standard_Integer ,const Standard_Real ,Standard_Real& ,Standard_Real& ) const
{
Standard_NotImplemented::Raise("Approx_SweepFunction::Resolution");
}
gp_Pnt Approx_SweepFunction::BarycentreOfSurf() const
{
Standard_NotImplemented::Raise("Approx_SweepFunction::BarycentreOfSurf");
return gp_Pnt(0.,0.,0.);
}
Standard_Real Approx_SweepFunction::MaximalSection() const
{
Standard_NotImplemented::Raise("Approx_SweepFunction::MaximalSection()");
return 0;
}
// void Approx_SweepFunction::GetMinimalWeight(TColStd_Array1OfReal& Weigths) const
void Approx_SweepFunction::GetMinimalWeight(TColStd_Array1OfReal& ) const
{
Standard_NotImplemented::Raise("Approx_SweepFunction::GetMinimalWeight");
}

View File

@@ -0,0 +1,97 @@
-- File: Approx_TheLineTool.cdl
-- Created: Tue Jan 26 14:46:32 1993
-- Author: Laurent PAINNOT
-- <lpa@sdsun1>
---Copyright: Matra Datavision 1993
deferred generic class TheLineTool from Approx (MLine as any;
MPoint as any)
---Purpose: Template which defines all the services relative to
-- a MultiLine for approximation algorithms.
uses Status from Approx,
Pnt from gp,
Pnt2d from gp,
Vec from gp,
Vec2d from gp,
Array1OfPnt from TColgp,
Array1OfPnt2d from TColgp,
Array1OfVec from TColgp,
Array1OfVec2d from TColgp
is
FirstPoint(myclass; ML: MLine) returns Integer;
---Purpose: Returns the first index of multipoints of the MLine.
LastPoint(myclass; ML: MLine) returns Integer;
---Purpose: Returns the last index of multipoints of the MLine.
NbP2d(myclass; ML: MLine) returns Integer;
---Purpose: Returns the number of 2d points of a MLine.
NbP3d(myclass; ML: MLine) returns Integer;
---Purpose: Returns the number of 3d points of a MLine.
Value(myclass; ML: MLine; MPointIndex: Integer; tabPt: out Array1OfPnt);
---Purpose: returns the 3d points of the multipoint <MPointIndex>
-- when only 3d points exist.
Value(myclass; ML: MLine; MPointIndex: Integer;
tabPt2d: out Array1OfPnt2d);
---Purpose: returns the 2d points of the multipoint <MPointIndex>
-- when only 2d points exist.
Value(myclass; ML: MLine; MPointIndex: Integer;
tabPt: out Array1OfPnt; tabPt2d: out Array1OfPnt2d);
---Purpose: returns the 3d and 2d points of the multipoint
-- <MPointIndex>.
Tangency(myclass; ML: MLine; MPointIndex: Integer; tabV: out Array1OfVec)
returns Boolean;
---Purpose: returns the 3d derivative values of the multipoint
-- <MPointIndex> when only 3d points exist.
Tangency(myclass; ML: MLine; MPointIndex: Integer;
tabV2d: out Array1OfVec2d)
returns Boolean;
---Purpose: returns the 2d derivative values of the multipoint
-- <MPointIndex> only when 2d points exist.
Tangency(myclass; ML: MLine; MPointIndex: Integer;
tabV: out Array1OfVec; tabV2d: out Array1OfVec2d)
returns Boolean;
---Purpose: returns the 3d and 2d derivative values of the multipoint
-- <MPointIndex>.
WhatStatus(myclass; ML: MLine; I1, I2: Integer)
returns Status from Approx;
---Purpose: . if Status = PointsAdded, a new MLine is created between
-- the two MPoints <I1> and <I2> of ML by MakeMLBetween.
-- . if Status = NoPointsAdded, no MLine will be created.
-- The algorithm will return the best approximation done.
-- . if Status = NoApproximation, nothing will be
-- done between <I1> and <I2>.
MakeMLBetween(myclass; ML: MLine; I1, I2: Integer;
NbPMin: Integer)
returns MLine;
---Purpose: Is called if WhatStatus returned "PointsAdded".
end TheLineTool;

View File