1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-04 13:13:25 +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

2
src/GeomConvert/FILES Executable file
View File

@@ -0,0 +1,2 @@
GeomConvert_1.cxx

428
src/GeomConvert/GeomConvert.cdl Executable file
View File

@@ -0,0 +1,428 @@
-- File: GeomConvert.cdl
-- Created: Thu Oct 3 14:34:29 1991
-- Author: JeanClaude VAUTHIER
-- ---Copyright: Matra Datavision 1991, 1992
-- Modified : 07/10/97 : JPI/RBV/SMN : traitement des courbes offset
-- et surfaces offset par approximation
package GeomConvert
--- Purpose : The GeomConvert package provides some global functions as follows
-- - converting classical Geom curves into BSpline curves,
-- - segmenting BSpline curves, particularly at knots
-- values: this function may be used in conjunction with the
-- GeomConvert_BSplineCurveKnotSplitting
-- class to segment a BSpline curve into arcs which
-- comply with required continuity levels,
-- - converting classical Geom surfaces into BSpline surfaces, and
-- - segmenting BSpline surfaces, particularly at
-- knots values: this function may be used in conjunction with the
-- GeomConvert_BSplineSurfaceKnotSplitting
-- class to segment a BSpline surface into patches
-- which comply with required continuity levels.
-- All geometric entities used in this package are bounded.
--
-- References :
-- . Generating the Bezier Points of B-spline curves and surfaces
-- (Wolfgang Bohm) CAGD volume 13 number 6 november 1981
-- . On NURBS: A Survey (Leslie Piegl) IEEE Computer Graphics and
-- Application January 1991
-- . Curve and surface construction using rational B-splines
-- (Leslie Piegl and Wayne Tiller) CAD Volume 19 number 9 november
-- 1987
-- . A survey of curve and surface methods in CAGD (Wolfgang BOHM)
-- CAGD 1 1984
uses Standard,
TColStd,
TColGeom,
TColgp,
GeomAbs,
gp,
Geom,
Geom2d,
Convert,
AdvApp2Var
is
class BSplineCurveKnotSplitting;
--- Purpose : This algorithm searches the knot values corresponding to the
-- splitting of a given B-spline curve into several arcs with
-- the same continuity. The continuity order is given at the
-- construction time. It is possible to compute the curve arcs
-- corresponding to this splitting with the method of package
-- SplitBSplineCurve.
class BSplineSurfaceKnotSplitting;
--- Purpose :
-- This algorithm searches the knot values corresponding to the
-- splitting of a given B-spline surface into several patches with
-- the same continuity. The continuity order is given at the
-- construction time. It is possible to compute the surface patches
-- corresponding to the splitting with the method of package
-- SplitBSplineSurface.
class BSplineCurveToBezierCurve;
--- Purpose :
-- This algorithm converts a B-spline curve from the package Geom
-- into several Bezier curves.
class CompCurveToBSplineCurve;
--- Purpose :
-- This algorithm converts and concat sevral curve in a
-- B-spline curve.
class BSplineSurfaceToBezierSurface;
--- Purpose :
-- This algorithm converts a B-spline surface from the package Geom
-- into several Bezier surfaces.
class CompBezierSurfacesToBSplineSurface;
---Purpose: Convert a grid of Bezier Surfaces
-- that are have continuity CM to an
-- Bspline Surface that has continuity CM
class ApproxSurface;
---Purpose: Convert a surface from Geom by an approximation method
--
class ApproxCurve;
---Purpose: Convert a curve from Geom by an approximation method
--
SplitBSplineCurve (C : BSplineCurve from Geom;
FromK1, ToK2 : Integer;
SameOrientation : Boolean = Standard_True)
returns mutable BSplineCurve from Geom
--- Purpose :
-- This method computes the arc of B-spline curve between the two
-- knots FromK1 and ToK2. If C is periodic the arc has the same
-- orientation as C if SameOrientation = Standard_True.
-- If C is not periodic SameOrientation is not used for the
-- computation and C is oriented from the knot fromK1 to the knot toK2.
-- We just keep the local definition of C between the knots
-- FromK1 and ToK2. The returned B-spline curve has its first
-- and last knots with a multiplicity equal to degree + 1, where
-- degree is the polynomial degree of C.
-- The indexes of the knots FromK1 and ToK2 doesn't include the
-- repetition of multiple knots in their definition.
raises DomainError from Standard;
--- Purpose : Raised if FromK1 = ToK2
-- Raised if FromK1 or ToK2 are out of the bounds
-- [FirstUKnotIndex, LastUKnotIndex]
SplitBSplineCurve (C : BSplineCurve from Geom;
FromU1, ToU2 : Real;
ParametricTolerance : Real;
SameOrientation : Boolean = Standard_True)
returns mutable BSplineCurve from Geom
--- Purpose :
-- This function computes the segment of B-spline curve between the
-- parametric values FromU1, ToU2.
-- If C is periodic the arc has the same orientation as C if
-- SameOrientation = True.
-- If C is not periodic SameOrientation is not used for the
-- computation and C is oriented fromU1 toU2.
-- If U1 and U2 and two parametric values we consider that
-- U1 = U2 if Abs (U1 - U2) <= ParametricTolerance and
-- ParametricTolerance must be greater or equal to Resolution
-- from package gp.
raises DomainError from Standard;
--- Purpose :
-- Raised if FromU1 or ToU2 are out of the parametric bounds of the
-- curve (The tolerance criterion is ParametricTolerance).
-- Raised if Abs (FromU1 - ToU2) <= ParametricTolerance
-- Raised if ParametricTolerance < Resolution from gp.
SplitBSplineSurface (S : BSplineSurface from Geom;
FromUK1, ToUK2, FromVK1, ToVK2 : Integer;
SameUOrientation : Boolean = Standard_True;
SameVOrientation : Boolean = Standard_True)
returns mutable BSplineSurface from Geom
--- Purpose :
-- Computes the B-spline surface patche between the knots values
-- FromUK1, ToUK2, FromVK1, ToVK2.
-- If S is periodic in one direction the patche has the same
-- orientation as S in this direction if the flag is true in this
-- direction (SameUOrientation, SameVOrientation).
-- If S is not periodic SameUOrientation and SameVOrientation are not
-- used for the computation and S is oriented FromUK1 ToUK2 and
-- FromVK1 ToVK2.
raises DomainError from Standard;
--- Purpose : Raised if
-- FromUK1 = ToUK2 or FromVK1 = ToVK2
-- FromUK1 or ToUK2 are out of the bounds
-- [FirstUKnotIndex, LastUKnotIndex]
-- FromVK1 or ToVK2 are out of the bounds
-- [FirstVKnotIndex, LastVKnotIndex]
SplitBSplineSurface (S : BSplineSurface from Geom;
FromK1, ToK2 : Integer;
USplit : Boolean;
SameOrientation : Boolean = Standard_True)
returns mutable BSplineSurface from Geom
--- Purpose :
-- This method splits a B-spline surface patche between the
-- knots values FromK1, ToK2 in one direction.
-- If USplit = True then the splitting direction is the U parametric
-- direction else it is the V parametric direction.
-- If S is periodic in the considered direction the patche has the
-- same orientation as S in this direction if SameOrientation is True
-- If S is not periodic in this direction SameOrientation is not used
-- for the computation and S is oriented FromK1 ToK2.
raises DomainError from Standard;
--- Purpose : Raised if FromK1 = ToK2 or if
-- FromK1 or ToK2 are out of the bounds
-- [FirstUKnotIndex, LastUKnotIndex] in the
-- considered parametric direction.
SplitBSplineSurface (S : BSplineSurface from Geom;
FromU1, ToU2, FromV1, ToV2 : Real;
ParametricTolerance : Real;
SameUOrientation : Boolean = Standard_True;
SameVOrientation : Boolean = Standard_True)
returns mutable BSplineSurface from Geom
--- Purpose :
-- This method computes the B-spline surface patche between the
-- parametric values FromU1, ToU2, FromV1, ToV2.
-- If S is periodic in one direction the patche has the same
-- orientation as S in this direction if the flag is True in this
-- direction (SameUOrientation, SameVOrientation).
-- If S is not periodic SameUOrientation and SameVOrientation are not
-- used for the computation and S is oriented FromU1 ToU2 and
-- FromV1 ToV2.
-- If U1 and U2 and two parametric values we consider that U1 = U2 if
-- Abs (U1 - U2) <= ParametricTolerance and ParametricTolerance must
-- be greater or equal to Resolution from package gp.
raises DomainError from Standard;
--- Purpose :
-- Raised if FromU1 or ToU2 or FromV1 or ToU2 are out of the
-- parametric bounds of the surface (the tolerance criterion is
-- ParametricTolerance).
-- Raised if Abs (FromU1 - ToU2) <= ParametricTolerance or
-- Abs (FromV1 - ToV2) <= ParametricTolerance.
-- Raised if ParametricTolerance < Resolution.
SplitBSplineSurface (S : BSplineSurface from Geom;
FromParam1, ToParam2 : Real;
USplit : Boolean;
ParametricTolerance : Real;
SameOrientation : Boolean = Standard_True)
returns mutable BSplineSurface from Geom
--- Purpose :
-- This method splits the B-spline surface S in one direction
-- between the parametric values FromParam1, ToParam2.
-- If USplit = True then the Splitting direction is the U parametric
-- direction else it is the V parametric direction.
-- If S is periodic in the considered direction the patche has
-- the same orientation as S in this direction if SameOrientation
-- is true.
-- If S is not periodic in the considered direction SameOrientation
-- is not used for the computation and S is oriented FromParam1
-- ToParam2.
-- If U1 and U2 and two parametric values we consider that U1 = U2
-- if Abs (U1 - U2) <= ParametricTolerance and ParametricTolerance
-- must be greater or equal to Resolution from package gp.
raises DomainError from Standard;
--- Purpose :
-- Raises if FromParam1 or ToParam2 are out of the parametric bounds
-- of the surface in the considered direction.
-- Raises if Abs (FromParam1 - ToParam2) <= ParametricTolerance.
CurveToBSplineCurve (C : Curve from Geom ;
Parameterisation : ParameterisationType from Convert
= Convert_TgtThetaOver2)
returns mutable BSplineCurve from Geom
--- Purpose : This function converts a non infinite curve from
-- Geom into a B-spline curve. C must be an ellipse or a
-- circle or a trimmed conic or a trimmed line or a Bezier
-- curve or a trimmed Bezier curve or a BSpline curve or a
-- trimmed BSpline curve or an OffsetCurve. The returned B-spline is
-- not periodic except if C is a Circle or an Ellipse. If
-- the Parameterisation is QuasiAngular than the returned
-- curve is NOT periodic in case a periodic Geom_Circle or
-- Geom_Ellipse. For TgtThetaOver2_1 and TgtThetaOver2_2 the
-- method raises an exception in case of a periodic
-- Geom_Circle or a Geom_Ellipse ParameterisationType applies
-- only if the curve is a Circle or an ellipse :
-- TgtThetaOver2, -- TgtThetaOver2_1, -- TgtThetaOver2_2, --
-- TgtThetaOver2_3, -- TgtThetaOver2_4,
--
-- Purpose: this is the classical rational parameterisation
-- 2
-- 1 - t
-- cos(theta) = ------
-- 2
-- 1 + t
--
-- 2t
-- sin(theta) = ------
-- 2
-- 1 + t
--
-- t = tan (theta/2)
--
-- with TgtThetaOver2 the routine will compute the number of spans
-- using the rule num_spans = [ (ULast - UFirst) / 1.2 ] + 1
-- with TgtThetaOver2_N, N spans will be forced: an error will
-- be raized if (ULast - UFirst) >= PI and N = 1,
-- ULast - UFirst >= 2 PI and N = 2
--
-- QuasiAngular,
-- here t is a rational function that approximates
-- theta ----> tan(theta/2).
-- Neverthless the composing with above function yields exact
-- functions whose square sum up to 1
-- RationalC1 ;
-- t is replaced by a polynomial function of u so as to grant
-- C1 contiuity across knots.
-- Exceptions
-- Standard_DomainError:
-- - if the curve C is infinite, or
-- - if C is a (complete) circle or ellipse, and Parameterisation is equal to
-- Convert_TgtThetaOver2_1 or Convert_TgtThetaOver2_2.
-- Standard_ConstructionError:
-- - if C is a (complete) circle or ellipse, and if Parameterisation is not equal to
-- Convert_TgtThetaOver2, Convert_RationalC1,
-- Convert_QuasiAngular (the curve is converted
-- in these three cases) or to Convert_TgtThetaOver2_1 or
-- Convert_TgtThetaOver2_2 (another exception is raised in these two cases).
-- - if C is a trimmed circle or ellipse, if Parameterisation is equal to
-- Convert_TgtThetaOver2_1 and if U2 - U1 > 0.9999 * Pi, where U1 and U2 are
-- respectively the first and the last parameters of the
-- trimmed curve (this method of parameterization
-- cannot be used to convert a half-circle or a half-ellipse, for example), or
-- - if C is a trimmed circle or ellipse, if
-- Parameterisation is equal to Convert_TgtThetaOver2_2 and U2 - U1 >
-- 1.9999 * Pi where U1 and U2 are
-- respectively the first and the last parameters of the
-- trimmed curve (this method of parameterization
-- cannot be used to convert a quasi-complete circle or ellipse).
raises DomainError,
ConstructionError;
SurfaceToBSplineSurface (S : Surface from Geom)
returns mutable BSplineSurface from Geom
--- Purpose :
-- This algorithm converts a non infinite surface from Geom
-- into a B-spline surface.
-- S must be a trimmed plane or a trimmed cylinder or a trimmed cone
-- or a trimmed sphere or a trimmed torus or a sphere or a torus or
-- a Bezier surface of a trimmed Bezier surface or a trimmed swept
-- surface with a corresponding basis curve which can be turned into
-- a B-spline curve (see the method CurveToBSplineCurve).
-- Raises DomainError if the type of the surface is not previously defined.
raises DomainError;
ConcatG1(ArrayOfCurves : in out Array1OfBSplineCurve from TColGeom;
ArrayOfToler : in Array1OfReal from TColStd;
ArrayOfConcatenated : out HArray1OfBSplineCurve from TColGeom;
ClosedG1Flag : in Boolean from Standard ;
ClosedTolerance : in Real from Standard) ;
--- Purpose : This Method concatenates G1 the ArrayOfCurves as far
-- as it is possible.
-- ArrayOfCurves[0..N-1]
-- ArrayOfToler contains the biggest tolerance of the two
-- points shared by two consecutives curves.
-- Its dimension: [0..N-2]
-- ClosedG1 indicates if the ArrayOfCurves is closed.
-- In this case ClosedG1 contains the biggest tolerance
-- of the two points which are at the closure.
-- Otherwise its value is 0.0
ConcatC1(ArrayOfCurves : in out Array1OfBSplineCurve from TColGeom;
ArrayOfToler : in Array1OfReal from TColStd;
ArrayOfIndices : out HArray1OfInteger from TColStd;
ArrayOfConcatenated : out HArray1OfBSplineCurve from TColGeom;
ClosedG1Flag : in Boolean from Standard ;
ClosedTolerance : in Real from Standard) ;
--- Purpose : This Method concatenates C1 the ArrayOfCurves as far
-- as it is possible.
-- ArrayOfCurves[0..N-1]
-- ArrayOfToler contains the biggest tolerance of the two
-- points shared by two consecutives curves.
-- Its dimension: [0..N-2]
-- ClosedG1 indicates if the ArrayOfCurves is closed.
-- In this case ClosedG1 contains the biggest tolerance
-- of the two points which are at the closure.
-- Otherwise its value is 0.0
ConcatC1(ArrayOfCurves : in out Array1OfBSplineCurve from TColGeom;
ArrayOfToler : in Array1OfReal from TColStd;
ArrayOfIndices : out HArray1OfInteger from TColStd;
ArrayOfConcatenated : out HArray1OfBSplineCurve from TColGeom;
ClosedG1Flag : in Boolean from Standard ;
ClosedTolerance : in Real from Standard ;
AngularTolerance : in Real from Standard) ;
--- Purpose : This Method concatenates C1 the ArrayOfCurves as far
-- as it is possible.
-- ArrayOfCurves[0..N-1]
-- ArrayOfToler contains the biggest tolerance of the two
-- points shared by two consecutives curves.
-- Its dimension: [0..N-2]
-- ClosedG1 indicates if the ArrayOfCurves is closed.
-- In this case ClosedG1 contains the biggest tolerance
-- of the two points which are at the closure.
-- Otherwise its value is 0.0
--
C0BSplineToC1BSplineCurve(BS : in out BSplineCurve from Geom;
tolerance : in Real from Standard;
AngularTolerance: in Real = 1.0e-7);
---Purpose : This Method reduces as far as it is possible the
-- multiplicities of the knots of the BSpline BS.(keeping the
-- geometry). It returns a new BSpline which could still be C0.
-- tolerance is a geometrical tolerance.
-- The Angular toleranceis in radians and mesures the angle of
-- the tangents on the left and on the right to decide if the
-- curve is G1 or not at a given point
C0BSplineToArrayOfC1BSplineCurve(BS : in BSplineCurve from Geom;
tabBS : out HArray1OfBSplineCurve from TColGeom;
tolerance : in Real from Standard);
--- Purpose : This Method reduces as far as it is possible the
-- multiplicities of the knots of the BSpline BS.(keeping the geometry).
-- It returns an array of BSpline C1. tolerance is a geometrical tolerance.
C0BSplineToArrayOfC1BSplineCurve(BS : in BSplineCurve from Geom;
tabBS : out HArray1OfBSplineCurve from TColGeom;
AngularTolerance : in Real from Standard ;
tolerance : in Real from Standard);
--- Purpose :This Method reduces as far as it is possible the
-- multiplicities of the knots of the BSpline BS.(keeping the
-- geometry). It returns an array of BSpline C1. tolerance is a
-- geometrical tolerance : it allows for the maximum deformation
-- The Angular tolerance is in radians and mesures the angle of
-- the tangents on the left and on the right to decide if the curve
-- is C1 or not at a given point
end GeomConvert;

1327
src/GeomConvert/GeomConvert.cxx Executable file

File diff suppressed because it is too large Load Diff

872
src/GeomConvert/GeomConvert_1.cxx Executable file
View File

@@ -0,0 +1,872 @@
//File GeomConvert_1.cxx
//Jean-Claude Vauthier Novembre 1991
//Passage sur C1 Aout 1992 et ajout transformation Bezier->BSpline
//Modif JCV correction bug le 02/08/1993
#include <GeomConvert.ixx>
#include <BSplCLib.hxx>
#include <Standard_DomainError.hxx>
#include <Standard_NotImplemented.hxx>
#include <Convert_ElementarySurfaceToBSplineSurface.hxx>
#include <Convert_ConeToBSplineSurface.hxx>
#include <Convert_CylinderToBSplineSurface.hxx>
#include <Convert_SphereToBSplineSurface.hxx>
#include <Convert_TorusToBSplineSurface.hxx>
#include <GeomConvert_ApproxSurface.hxx>
#include <Geom_OffsetSurface.hxx>
#include <Geom_Surface.hxx>
#include <Geom_Plane.hxx>
#include <Geom_CylindricalSurface.hxx>
#include <Geom_ConicalSurface.hxx>
#include <Geom_SphericalSurface.hxx>
#include <Geom_ToroidalSurface.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <Geom_SurfaceOfRevolution.hxx>
#include <Geom_SurfaceOfLinearExtrusion.hxx>
#include <Geom_BSplineSurface.hxx>
#include <Geom_BezierSurface.hxx>
#include <Geom_Geometry.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <TColgp_Array2OfPnt.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_Array2OfReal.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <TColStd_Array2OfInteger.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <TColStd_HArray1OfInteger.hxx>
#include <Precision.hxx>
#include <gp_Vec.hxx>
#include <gp_Sphere.hxx>
#include <gp_Cylinder.hxx>
#include <gp_Cone.hxx>
#include <gp_Torus.hxx>
#include <gp_Pln.hxx>
#include <gp_Trsf.hxx>
#include <gp_GTrsf.hxx>
typedef Geom_Surface Surface;
typedef Geom_BSplineSurface BSplineSurface;
typedef Handle(Geom_Curve) Handle(Curve);
typedef Handle(Geom_BSplineCurve) Handle(BSplineCurve);
typedef Handle(Geom_BezierSurface) Handle(BezierSurface);
typedef Handle(Geom_Geometry) Handle(Geometry);
typedef Handle(Geom_Surface) Handle(Surface);
typedef Handle(Geom_Plane) Handle(Plane);
typedef Handle(Geom_CylindricalSurface) Handle(CylindricalSurface);
typedef Handle(Geom_ConicalSurface) Handle(ConicalSurface);
typedef Handle(Geom_SphericalSurface) Handle(SphericalSurface);
typedef Handle(Geom_ToroidalSurface) Handle(ToroidalSurface);
typedef Handle(Geom_BSplineSurface) Handle(BSplineSurface);
typedef Handle(Geom_SurfaceOfRevolution) Handle(SurfaceOfRevolution);
typedef Handle(Geom_SurfaceOfLinearExtrusion) Handle(SurfaceOfLinearExtrusion);
typedef Handle(Geom_RectangularTrimmedSurface)
Handle(RectangularTrimmedSurface);
typedef TColStd_Array1OfReal Array1OfReal;
typedef TColStd_Array2OfReal Array2OfReal;
typedef TColStd_Array1OfInteger Array1OfInteger;
typedef TColStd_Array2OfInteger Array2OfInteger;
typedef TColgp_Array2OfPnt Array2OfPnt;
typedef TColgp_Array1OfPnt Array1OfPnt;
typedef gp_Pnt Pnt;
//=======================================================================
//function : BSplineSurfaceBuilder
//purpose :
//=======================================================================
Handle(BSplineSurface) BSplineSurfaceBuilder
(const Convert_ElementarySurfaceToBSplineSurface& Convert)
{
Handle(BSplineSurface) TheSurface;
Standard_Integer UDegree = Convert.UDegree ();
Standard_Integer VDegree = Convert.VDegree ();
Standard_Integer NbUPoles = Convert.NbUPoles();
Standard_Integer NbVPoles = Convert.NbVPoles();
Standard_Integer NbUKnots = Convert.NbUKnots();
Standard_Integer NbVKnots = Convert.NbVKnots();
Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
Array1OfReal UKnots (1, NbUKnots);
Array1OfReal VKnots (1, NbVKnots);
Array1OfInteger UMults (1, NbUKnots);
Array1OfInteger VMults (1, NbVKnots);
Standard_Integer i, j;
for (j = 1; j <= NbVPoles; j++) {
for (i = 1; i <= NbUPoles; i++) {
Poles (i, j) = Convert.Pole (i, j);
Weights (i, j) = Convert.Weight (i, j);
}
}
for (i = 1; i <= NbUKnots; i++) {
UKnots (i) = Convert.UKnot (i);
UMults (i) = Convert.UMultiplicity (i);
}
for (i = 1; i <= NbVKnots; i++) {
VKnots (i) = Convert.VKnot (i);
VMults (i) = Convert.VMultiplicity (i);
}
TheSurface = new BSplineSurface (Poles, Weights, UKnots, VKnots,
UMults, VMults, UDegree, VDegree,
Convert.IsUPeriodic(),
Convert.IsVPeriodic());
return TheSurface;
}
//=======================================================================
//function : SplitBSplineSurface
//purpose :
//=======================================================================
Handle(BSplineSurface) GeomConvert::SplitBSplineSurface
(const Handle(BSplineSurface)& S,
const Standard_Integer FromUK1,
const Standard_Integer ToUK2,
const Standard_Integer FromVK1,
const Standard_Integer ToVK2,
const Standard_Boolean SameUOrientation,
const Standard_Boolean SameVOrientation )
{
Standard_Integer FirstU = S->FirstUKnotIndex ();
Standard_Integer FirstV = S->FirstVKnotIndex ();
Standard_Integer LastU = S->LastUKnotIndex ();
Standard_Integer LastV = S->LastVKnotIndex ();
if (FromUK1 == ToUK2 || FromVK1 == ToVK2) Standard_DomainError::Raise();
Standard_Integer FirstUK = Min (FromUK1, ToUK2);
Standard_Integer LastUK = Max (FromUK1, ToUK2);
Standard_Integer FirstVK = Min (FromVK1, ToVK2);
Standard_Integer LastVK = Max (FromVK1, ToVK2);
if (FirstUK < FirstU || LastUK > LastU ||
FirstVK < FirstV || LastVK > LastV) { Standard_DomainError::Raise(); }
Handle(BSplineSurface) S1= Handle(BSplineSurface)::DownCast(S->Copy());
S1->Segment(S1->UKnot(FirstUK),S1->UKnot(LastUK),
S1->VKnot(FirstVK),S1->VKnot(LastVK));
if (S->IsUPeriodic()) {
if (!SameUOrientation) S1->UReverse();
}
else {
if (FromUK1 > ToUK2) S1->UReverse();
}
if (S->IsVPeriodic()) {
if (!SameVOrientation) S1->VReverse();
}
else {
if (FromVK1 > ToVK2) S1->VReverse();
}
return S1;
}
//=======================================================================
//function : SplitBSplineSurface
//purpose :
//=======================================================================
Handle(BSplineSurface) GeomConvert::SplitBSplineSurface
(const Handle(BSplineSurface)& S,
const Standard_Integer FromK1,
const Standard_Integer ToK2,
const Standard_Boolean USplit,
const Standard_Boolean SameOrientation )
{
if (FromK1 == ToK2) Standard_DomainError::Raise();
Handle(BSplineSurface) S1 = Handle(BSplineSurface)::DownCast(S->Copy());
if (USplit) {
Standard_Integer FirstU = S->FirstUKnotIndex ();
Standard_Integer LastU = S->LastUKnotIndex ();
Standard_Integer FirstUK = Min (FromK1, ToK2);
Standard_Integer LastUK = Max (FromK1, ToK2);
if (FirstUK < FirstU || LastUK > LastU) Standard_DomainError::Raise();
S1->Segment( S1->UKnot(FirstUK),
S1->UKnot(LastUK),
S1->VKnot(S1->FirstVKnotIndex()),
S1->VKnot(S1->LastVKnotIndex()));
if (S->IsUPeriodic()) {
if (!SameOrientation) S1->UReverse();
}
else {
if (FromK1 > ToK2) S1->UReverse();
}
}
else {
Standard_Integer FirstV = S->FirstVKnotIndex ();
Standard_Integer LastV = S->LastVKnotIndex ();
Standard_Integer FirstVK = Min (FromK1, ToK2);
Standard_Integer LastVK = Max (FromK1, ToK2);
if (FirstVK < FirstV || LastVK > LastV) Standard_DomainError::Raise();
S1->Segment( S1->UKnot(S1->FirstUKnotIndex()),
S1->UKnot(S1->LastUKnotIndex()),
S1->VKnot(FirstVK),
S1->VKnot(LastVK));
if (S->IsVPeriodic()) {
if (!SameOrientation) S1->VReverse();
}
else {
if (FromK1 > ToK2) S1->VReverse();
}
}
return S1;
}
//=======================================================================
//function : SplitBSplineSurface
//purpose :
//=======================================================================
Handle(BSplineSurface) GeomConvert::SplitBSplineSurface
(const Handle(BSplineSurface)& S,
const Standard_Real FromU1,
const Standard_Real ToU2,
const Standard_Real FromV1,
const Standard_Real ToV2,
// const Standard_Real ParametricTolerance,
const Standard_Real ,
const Standard_Boolean SameUOrientation,
const Standard_Boolean SameVOrientation )
{
Standard_Real FirstU = Min( FromU1, ToU2);
Standard_Real LastU = Max( FromU1, ToU2);
Standard_Real FirstV = Min( FromV1, ToV2);
Standard_Real LastV = Max( FromV1, ToV2);
Handle (Geom_BSplineSurface) NewSurface
= Handle(Geom_BSplineSurface)::DownCast(S->Copy());
NewSurface->Segment(FirstU, LastU, FirstV, LastV);
if (S->IsUPeriodic()) {
if (!SameUOrientation) NewSurface->UReverse();
}
else {
if (FromU1 > ToU2) NewSurface->UReverse();
}
if (S->IsVPeriodic()) {
if (!SameVOrientation) NewSurface->VReverse();
}
else {
if (FromV1 > ToV2) NewSurface->VReverse();
}
return NewSurface;
}
//=======================================================================
//function : SplitBSplineSurface
//purpose :
//=======================================================================
Handle(BSplineSurface) GeomConvert::SplitBSplineSurface
(const Handle(BSplineSurface)& S,
const Standard_Real FromParam1,
const Standard_Real ToParam2,
const Standard_Boolean USplit,
const Standard_Real ParametricTolerance,
const Standard_Boolean SameOrientation )
{
if (Abs (FromParam1 - ToParam2) <= Abs(ParametricTolerance)) {
Standard_DomainError::Raise();
}
Handle(BSplineSurface) NewSurface
= Handle(Geom_BSplineSurface)::DownCast(S->Copy());
if (USplit) {
Standard_Real FirstU = Min( FromParam1, ToParam2);
Standard_Real LastU = Max( FromParam1, ToParam2);
Standard_Real FirstV = S->VKnot(S->FirstVKnotIndex());
Standard_Real LastV = S->VKnot(S->LastVKnotIndex());
NewSurface->Segment(FirstU, LastU, FirstV, LastV);
if (S->IsUPeriodic()) {
if (!SameOrientation) NewSurface->UReverse();
}
else {
if (FromParam1 > ToParam2) NewSurface->UReverse();
}
}
else {
Standard_Real FirstU = S->UKnot(S->FirstUKnotIndex());
Standard_Real LastU = S->UKnot(S->LastUKnotIndex());
Standard_Real FirstV = Min( FromParam1, ToParam2);
Standard_Real LastV = Max( FromParam1, ToParam2);
NewSurface->Segment(FirstU, LastU, FirstV, LastV);
if (S->IsUPeriodic()) {
if (!SameOrientation) NewSurface->UReverse();
}
else {
if (FromParam1 > ToParam2) NewSurface->UReverse();
}
}
return NewSurface;
}
//=======================================================================
//function : SurfaceToBSplineSurface
//purpose :
//=======================================================================
Handle(Geom_BSplineSurface) GeomConvert::SurfaceToBSplineSurface
(const Handle(Surface)& Sr)
{
Standard_Real U1, U2, V1, V2;
Sr->Bounds (U1, U2, V1, V2);
Standard_Real UFirst = Min (U1, U2);
Standard_Real ULast = Max (U1, U2);
Standard_Real VFirst = Min (V1, V2);
Standard_Real VLast = Max (V1, V2);
//If the surface Sr is infinite stop the computation
if (Precision::IsNegativeInfinite(UFirst) ||
Precision::IsPositiveInfinite(ULast) ||
Precision::IsNegativeInfinite(VFirst) ||
Precision::IsPositiveInfinite(VLast) ) {
Standard_DomainError::Raise("");
}
Handle(Geom_BSplineSurface) TheSurface;
Handle(Surface) S;
Handle(Geom_OffsetSurface) OffsetSur;
if (Sr->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
OffsetSur = *((Handle(Geom_OffsetSurface)*)& Sr);
S = OffsetSur->Surface();
if (!S.IsNull()) { // Convert the equivalent surface.
return SurfaceToBSplineSurface(S);
}
}
S = Sr;
if (S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
Handle(Geom_RectangularTrimmedSurface) Strim =
Handle(Geom_RectangularTrimmedSurface)::DownCast(S);
Handle(Geom_Surface) Surf = Strim->BasisSurface();
UFirst = U1; ULast = U2; VFirst = V1; VLast = V2;
if (Surf->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
Handle(Geom_OffsetSurface) OffsetSur =
Handle(Geom_OffsetSurface)::DownCast(Surf);
S = OffsetSur->Surface();
if (!S.IsNull()) {
Surf = S;
}
else S = Surf;
}
if (Surf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
Handle(Geom_RectangularTrimmedSurface) Strim = new
(Geom_RectangularTrimmedSurface) (Surf,
UFirst, ULast,
VFirst, VLast);
return SurfaceToBSplineSurface(Strim);
}
if (Surf->IsKind(STANDARD_TYPE(Geom_Plane))) {
TColgp_Array2OfPnt Poles (1, 2, 1, 2);
Poles (1, 1) = Strim->Value (U1, V1);
Poles (1, 2) = Strim->Value (U1, V2);
Poles (2, 1) = Strim->Value (U2, V1);
Poles (2, 2) = Strim->Value (U2, V2);
TColStd_Array1OfReal UKnots (1, 2);
TColStd_Array1OfReal VKnots (1, 2);
TColStd_Array1OfInteger UMults (1, 2);
TColStd_Array1OfInteger VMults (1, 2);
UKnots (1) = U1;
UKnots (2) = U2;
VKnots (1) = V1;
VKnots (2) = V2;
UMults (1) = 2;
UMults (2) = 2;
VMults (1) = 2;
VMults (2) = 2;
Standard_Integer UDegree = 1;
Standard_Integer VDegree = 1;
TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots, UMults,
VMults, UDegree, VDegree);
}
else if (Surf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
Handle(Geom_CylindricalSurface) TheElSurf=
Handle(Geom_CylindricalSurface)::DownCast(Surf);
gp_Cylinder Cyl = TheElSurf->Cylinder();
if (Strim->IsUClosed()) {
Convert_CylinderToBSplineSurface Convert (Cyl, VFirst, VLast);
TheSurface = BSplineSurfaceBuilder (Convert);
}
else {
Convert_CylinderToBSplineSurface
Conv (Cyl, UFirst, ULast, VFirst, VLast);
TheSurface = BSplineSurfaceBuilder (Conv);
}
}
else if (Surf->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) {
Handle(Geom_ConicalSurface) TheElSurf =
Handle(Geom_ConicalSurface)::DownCast(Surf);
gp_Cone Co = TheElSurf->Cone();
if (Strim->IsUClosed()) {
Convert_ConeToBSplineSurface Convert (Co, VFirst, VLast);
TheSurface = BSplineSurfaceBuilder (Convert);
}
else {
Convert_ConeToBSplineSurface
Convert (Co, UFirst, ULast, VFirst, VLast);
TheSurface = BSplineSurfaceBuilder (Convert);
}
}
else if (Surf->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
Handle(Geom_SphericalSurface) TheElSurf =
Handle(Geom_SphericalSurface)::DownCast(Surf);
gp_Sphere Sph = TheElSurf->Sphere();
//OCC217
if (Strim->IsUClosed()) {
//if (Strim->IsVClosed()) {
//Convert_SphereToBSplineSurface Convert (Sph, UFirst, ULast);
Convert_SphereToBSplineSurface Convert (Sph, VFirst, VLast, Standard_False);
TheSurface = BSplineSurfaceBuilder (Convert);
}
else {
Convert_SphereToBSplineSurface
Convert (Sph, UFirst, ULast, VFirst, VLast);
TheSurface = BSplineSurfaceBuilder (Convert);
}
}
else if (Surf->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
Handle(Geom_ToroidalSurface) TheElSurf =
Handle(Geom_ToroidalSurface)::DownCast(Surf);
gp_Torus Tr = TheElSurf->Torus();
if (Strim->IsUClosed()) {
Convert_TorusToBSplineSurface Convert (Tr, VFirst, VLast,
Standard_False);
TheSurface = BSplineSurfaceBuilder (Convert);
}
else if (Strim->IsVClosed()) {
Convert_TorusToBSplineSurface Convert (Tr, UFirst, ULast);
TheSurface = BSplineSurfaceBuilder (Convert);
}
else {
Convert_TorusToBSplineSurface
Convert (Tr, UFirst, ULast, VFirst, VLast);
TheSurface = BSplineSurfaceBuilder (Convert);
}
}
else if (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
Handle(Geom_SurfaceOfRevolution) Revol =
Handle(Geom_SurfaceOfRevolution)::DownCast(Surf);
Handle(Geom_Curve) Meridian = Revol->BasisCurve();
Handle(Geom_BSplineCurve) C;
if (Strim->IsVClosed()) {
C = GeomConvert::CurveToBSplineCurve (Meridian);
}
else {
Handle(Geom_TrimmedCurve) CT =
new Geom_TrimmedCurve( Meridian, VFirst, VLast);
C = GeomConvert::CurveToBSplineCurve (CT);
}
Standard_Integer NbUPoles, NbUKnots;
Standard_Integer NbVPoles, NbVKnots;
Standard_Boolean periodic = Standard_False;
// Poles of meridian = Vpoles
NbVPoles = C->NbPoles();
TColgp_Array1OfPnt Poles(1, NbVPoles);
C->Poles(Poles);
TColStd_Array1OfReal Weights( 1, NbVPoles);
Weights.Init(1.);
if ( C->IsRational()) C->Weights(Weights);
Standard_Integer nbUSpans;
Standard_Real AlfaU;
if (Strim->IsUPeriodic()) {
NbUKnots = 4;
nbUSpans = 3;
AlfaU = PI / 3.;
NbUPoles = 6;
periodic = Standard_True;
}
else {
// Nombre de spans : ouverture maximale = 150 degres ( = PI / 1.2 rds)
nbUSpans =
(Standard_Integer)IntegerPart( 1.2 * (ULast - UFirst) / PI) + 1;
AlfaU = (ULast - UFirst) / ( nbUSpans * 2);
NbUPoles = 2 * nbUSpans + 1;
NbUKnots = nbUSpans + 1;
}
// Compute Knots and Mults
TColStd_Array1OfReal UKnots(1, NbUKnots);
TColStd_Array1OfInteger UMults( 1, NbUKnots);
Standard_Integer i,j;
for ( i = 1; i <= NbUKnots; i++) {
UKnots(i) = UFirst + (i-1) * 2 * AlfaU;
UMults(i) = 2;
}
if (!periodic) {
UMults(1)++; UMults(NbUKnots)++;
}
NbVKnots = C->NbKnots();
TColStd_Array1OfReal VKnots(1, NbVKnots);
TColStd_Array1OfInteger VMults(1, NbVKnots);
C->Knots(VKnots);
C->Multiplicities(VMults);
// Compute the poles.
TColgp_Array2OfPnt NewPoles ( 1, NbUPoles, 1, NbVPoles);
TColStd_Array2OfReal NewWeights( 1, NbUPoles, 1, NbVPoles);
gp_Trsf Trsf;
for ( i = 1; i<= NbUPoles; i+=2) {
Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
for ( j = 1; j <= NbVPoles; j++) {
NewPoles(i,j) = Poles(j).Transformed(Trsf);
NewWeights(i,j) = Weights(j);
}
}
gp_GTrsf Aff;
Aff.SetAffinity( Revol->Axis(), 1/Cos(AlfaU));
gp_XYZ coord;
for ( j= 1; j<= NbVPoles; j++) {
coord = Poles(j).XYZ();
Aff.Transforms(coord);
Poles(j).SetXYZ(coord);
}
for ( i = 2; i<= NbUPoles; i+=2) {
Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
for ( j = 1; j <= NbVPoles; j++) {
NewPoles(i,j) = Poles(j).Transformed(Trsf);
NewWeights(i,j) = Weights(j) * Cos(AlfaU);
}
}
TheSurface = new Geom_BSplineSurface(NewPoles, NewWeights,
UKnots, VKnots,
UMults, VMults,
2 , C->Degree(),
periodic, C->IsPeriodic());
}
else if (Surf->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
Handle(Geom_SurfaceOfLinearExtrusion) Extru =
Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(Surf);
Handle(Geom_Curve) Meridian = Extru->BasisCurve();
Handle(Geom_BSplineCurve) C;
if (Strim->IsUClosed()) {
C = GeomConvert::CurveToBSplineCurve (Meridian);
}
else {
Handle(Geom_TrimmedCurve) CT =
new Geom_TrimmedCurve( Meridian, UFirst, ULast);
C = GeomConvert::CurveToBSplineCurve (CT);
}
TColgp_Array2OfPnt Poles ( 1, C->NbPoles(), 1, 2);
TColStd_Array2OfReal Weights( 1, C->NbPoles(), 1, 2);
TColStd_Array1OfReal UKnots ( 1, C->NbKnots());
C->Knots(UKnots);
TColStd_Array1OfInteger UMults ( 1, C->NbKnots());
C->Multiplicities(UMults);
TColStd_Array1OfReal VKnots ( 1, 2);
VKnots(1) = VFirst;
VKnots(2) = VLast;
TColStd_Array1OfInteger VMults ( 1, 2);
VMults.Init(2);
gp_Vec D( Extru->Direction());
gp_Vec DV1 = VFirst * D;
gp_Vec DV2 = VLast * D;
for (Standard_Integer i = 1; i <= C->NbPoles(); i++) {
Poles(i,1) = C->Pole(i).Translated(DV1);
Poles(i,2) = C->Pole(i).Translated(DV2);
Weights(i,1) = Weights(i,2) = C->Weight(i);
}
TheSurface = new Geom_BSplineSurface(Poles, Weights, UKnots, VKnots,
UMults, VMults,
C->Degree(), 1,
C->IsPeriodic(), Standard_False);
}
else if (Surf->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
Handle(Geom_BezierSurface) SBez =
Handle(Geom_BezierSurface)::DownCast(Surf->Copy());
SBez->Segment (U1, U2, V1, V2);
Standard_Integer NbUPoles = SBez->NbUPoles();
Standard_Integer NbVPoles = SBez->NbVPoles();
Standard_Integer UDegree = SBez->UDegree();
Standard_Integer VDegree = SBez->VDegree();
TColgp_Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
TColStd_Array1OfReal UKnots (1, 2);
TColStd_Array1OfInteger UMults (1, 2);
TColStd_Array1OfReal VKnots (1, 2);
TColStd_Array1OfInteger VMults (1, 2);
UKnots (1) = 0.0;
UKnots (2) = 1.0;
UMults (1) = UDegree + 1;
UMults (2) = UDegree + 1;
VKnots (1) = 0.0;
VKnots (2) = 1.0;
VMults (1) = VDegree + 1;
VMults (2) = VDegree + 1;
SBez->Poles (Poles);
if (SBez->IsURational() || SBez->IsVRational()) {
TColStd_Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
SBez->Weights (Weights);
TheSurface = new Geom_BSplineSurface (Poles, Weights, UKnots, VKnots,
UMults, VMults,
UDegree, VDegree);
}
else {
TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots,
UMults, VMults,
UDegree, VDegree);
}
}
else if (Surf->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
Handle(Geom_BSplineSurface) BS =
Handle(Geom_BSplineSurface)::DownCast(Surf->Copy());
Standard_Real umin, umax, vmin, vmax;
BS->Bounds(umin, umax, vmin, vmax);
if (!BS->IsUPeriodic()) {
if (U1 < umin)
U1 = umin;
if (U2 > umax)
U2 = umax;
}
if (!BS->IsVPeriodic()) {
if (V1 < vmin)
V1 = vmin;
if (V2 > vmax)
V2 = vmax;
}
BS->Segment (U1, U2, V1, V2);
TheSurface = BS;
}
else {
Standard_Real Tol3d=1.e-4;
Standard_Integer MaxDegree =14, MaxSeg;
GeomAbs_Shape cont;
GeomAdaptor_Surface AS(Sr);
if (AS.NbUIntervals(GeomAbs_C2) > 1 || AS.NbVIntervals(GeomAbs_C2) > 1 )
cont=GeomAbs_C1;
else
cont=GeomAbs_C2;
MaxSeg = 4*(AS.NbUIntervals(GeomAbs_CN)+1)*(AS.NbVIntervals(GeomAbs_CN)+1);
GeomConvert_ApproxSurface BSpS(Sr, Tol3d, cont, cont,
MaxDegree, MaxDegree, MaxSeg, 1);
TheSurface = BSpS.Surface();
}
} // Fin du cas Rectangular::TrimmedSurface
else {
if (S->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
Handle(Geom_SphericalSurface) TheElSurf =
Handle(Geom_SphericalSurface)::DownCast(S);
gp_Sphere Sph = TheElSurf->Sphere();
Convert_SphereToBSplineSurface Convert(Sph);
TheSurface = BSplineSurfaceBuilder(Convert);
}
else if (S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
Handle(Geom_ToroidalSurface) TheElSurf =
Handle(Geom_ToroidalSurface)::DownCast(S);
gp_Torus Tr = TheElSurf->Torus();
Convert_TorusToBSplineSurface Convert(Tr);
TheSurface = BSplineSurfaceBuilder(Convert);
}
else if (S->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
Handle(Geom_SurfaceOfRevolution) Revol =
Handle(Geom_SurfaceOfRevolution)::DownCast(S);
Handle(Geom_Curve) Meridian = Revol->BasisCurve();
Handle(Geom_BSplineCurve) C
= GeomConvert::CurveToBSplineCurve (Meridian);
Standard_Integer NbUPoles, NbUKnots;
Standard_Integer NbVPoles, NbVKnots;
Standard_Boolean periodic = Standard_True;
// Poles of meridian = Vpoles
NbVPoles = C->NbPoles();
TColgp_Array1OfPnt Poles(1, NbVPoles);
C->Poles(Poles);
TColStd_Array1OfReal Weights( 1, NbVPoles);
Weights.Init(1.);
if ( C->IsRational()) C->Weights(Weights);
Standard_Integer nbUSpans;
Standard_Real AlfaU;
NbUKnots = 4;
nbUSpans = 3;
AlfaU = PI / 3.;
NbUPoles = 6;
// Compute Knots and Mults
TColStd_Array1OfReal UKnots(1, NbUKnots);
TColStd_Array1OfInteger UMults( 1, NbUKnots);
Standard_Integer i,j;
for ( i = 1; i <= NbUKnots; i++) {
UKnots(i) = UFirst + (i-1) * 2 * AlfaU;
UMults(i) = 2;
}
NbVKnots = C->NbKnots();
TColStd_Array1OfReal VKnots(1, NbVKnots);
TColStd_Array1OfInteger VMults(1, NbVKnots);
C->Knots(VKnots);
C->Multiplicities(VMults);
// Compute the poles.
TColgp_Array2OfPnt NewPoles ( 1, NbUPoles, 1, NbVPoles);
TColStd_Array2OfReal NewWeights( 1, NbUPoles, 1, NbVPoles);
gp_Trsf Trsf;
for ( i = 1; i<= NbUPoles; i+=2) {
Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
for ( j = 1; j <= NbVPoles; j++) {
NewPoles(i,j) = Poles(j).Transformed(Trsf);
NewWeights(i,j) = Weights(j);
}
}
gp_GTrsf Aff;
Aff.SetAffinity( Revol->Axis(), 1/Cos(AlfaU));
gp_XYZ coord;
for ( j= 1; j<= NbVPoles; j++) {
coord = Poles(j).XYZ();
Aff.Transforms(coord);
Poles(j).SetXYZ(coord);
}
for ( i = 2; i<= NbUPoles; i+=2) {
Trsf.SetRotation( Revol->Axis(), UFirst + (i-1)*AlfaU);
for ( j = 1; j <= NbVPoles; j++) {
NewPoles(i,j) = Poles(j).Transformed(Trsf);
NewWeights(i,j) = Weights(j) * Cos(AlfaU);
}
}
TheSurface = new Geom_BSplineSurface(NewPoles, NewWeights,
UKnots, VKnots,
UMults, VMults,
2 , C->Degree(),
periodic, C->IsPeriodic());
}
else if (S->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
Handle(Geom_BezierSurface) SBez =
Handle(Geom_BezierSurface)::DownCast(S);
Standard_Integer NbUPoles = SBez->NbUPoles();
Standard_Integer NbVPoles = SBez->NbVPoles();
Standard_Integer UDegree = SBez->UDegree();
Standard_Integer VDegree = SBez->VDegree();
TColgp_Array2OfPnt Poles (1, NbUPoles, 1, NbVPoles);
TColStd_Array1OfReal UKnots(1, 2);
TColStd_Array1OfInteger UMults(1, 2);
TColStd_Array1OfReal VKnots(1, 2);
TColStd_Array1OfInteger VMults(1, 2);
UKnots (1) = 0.0;
UKnots (2) = 1.0;
UMults (1) = UDegree + 1;
UMults (2) = UDegree + 1;
VKnots (1) = 0.0;
VKnots (2) = 1.0;
VMults (1) = VDegree + 1;
VMults (2) = VDegree + 1;
SBez->Poles (Poles);
if (SBez->IsURational() || SBez->IsVRational()) {
TColStd_Array2OfReal Weights (1, NbUPoles, 1, NbVPoles);
SBez->Weights (Weights);
TheSurface = new Geom_BSplineSurface (Poles, Weights, UKnots, VKnots,
UMults, VMults,
UDegree, VDegree);
}
else {
TheSurface = new Geom_BSplineSurface (Poles, UKnots, VKnots,
UMults, VMults,
UDegree, VDegree);
}
}
else if (S->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
TheSurface = Handle(Geom_BSplineSurface)::DownCast(S->Copy()); //Just a copy
}
else { // In other cases => Approx
Standard_Real Tol3d=1.e-4;
Standard_Integer MaxDegree =14, MaxSeg;
GeomAbs_Shape cont;
GeomAdaptor_Surface AS(Sr);
if (AS.NbUIntervals(GeomAbs_C2) > 1 || AS.NbVIntervals(GeomAbs_C2) > 1 )
cont=GeomAbs_C1;
else
cont=GeomAbs_C2;
MaxSeg = 4*(AS.NbUIntervals(GeomAbs_CN)+1)*(AS.NbVIntervals(GeomAbs_CN)+1);
GeomConvert_ApproxSurface BSpS(Sr,Tol3d,cont,cont,
MaxDegree,MaxDegree,MaxSeg,1);
TheSurface = BSpS.Surface();
}
} // Fin du cas direct
return TheSurface;
}

View File

@@ -0,0 +1,64 @@
-- File: GeomConvert_ApproxCurve.cdl
-- Created: Thu Sep 11 15:08:38 1997
-- Author: Roman BORISOV
-- <rbv@toctox.nnov.matra-dtv.fr>
---Copyright: Matra Datavision 1997
class ApproxCurve from GeomConvert
---Purpose: A framework to convert a 3D curve to a 3D BSpline.
-- This is done by approximation to a BSpline curve within a given tolerance.
uses
Curve from Geom,
BSplineCurve from Geom,
Shape from GeomAbs,
OutOfRange from Standard
raises OutOfRange from Standard,
ConstructionError from Standard
is
Create (Curve: Curve from Geom;
Tol3d: Real;
Order: Shape from GeomAbs;
MaxSegments: Integer;
MaxDegree: Integer) returns ApproxCurve;
---Purpose: Constructs a curve approximation framework defined by -
-- - the conic Curve,
-- - the tolerance value Tol3d,
-- - the degree of continuity Order,
-- - the maximum number of segments
-- MaxSegments allowed in the resulting BSpline curve, and
-- - the highest degree MaxDeg which the
-- polynomial defining the BSpline curve may have.
Curve(me) returns BSplineCurve from Geom;
--- Purpose: Returns the BSpline curve resulting from the approximation algorithm.
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 greatest distance between a point on the
-- source conic and the BSpline curve resulting from the
-- approximation. (>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
myCurve : Curve from Geom;
myIsDone : Boolean from Standard;
myHasResult : Boolean from Standard;
myBSplCurve : BSplineCurve from Geom;
myMaxError : Real from Standard;
end ApproxCurve;

View File

@@ -0,0 +1,164 @@
// File: GeomConvertMy_ApproxCurve.cxx
// Created: Thu Sep 11 15:50:30 1997
// Author: Roman BORISOV
// <rbv@toctox.nnov.matra-dtv.fr>
#include <GeomConvert_ApproxCurve.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 : GeomConvert_ApproxCurve_Eval
//purpose: evaluator class for approximation
//=======================================================================
class GeomConvert_ApproxCurve_Eval : public AdvApprox_EvaluatorFunction
{
public:
GeomConvert_ApproxCurve_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 GeomConvert_ApproxCurve_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;
}
}
GeomConvert_ApproxCurve::GeomConvert_ApproxCurve(const Handle(Geom_Curve)& Curve,const Standard_Real Tol3d,const GeomAbs_Shape Order,const Standard_Integer MaxSegments,const Standard_Integer MaxDegree)
{
Handle(GeomAdaptor_HCurve) HCurve = new GeomAdaptor_HCurve (Curve);
// 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 = HCurve->NbIntervals(GeomAbs_C2);
TColStd_Array1OfReal CutPnts_C2(1, NbInterv_C2+1);
HCurve->Intervals(CutPnts_C2,GeomAbs_C2);
Standard_Integer NbInterv_C3 = HCurve->NbIntervals(GeomAbs_C3);
TColStd_Array1OfReal CutPnts_C3(1, NbInterv_C3+1);
HCurve->Intervals(CutPnts_C3,GeomAbs_C3);
AdvApprox_PrefAndRec CutTool(CutPnts_C2,CutPnts_C3);
myMaxError = 0;
GeomConvert_ApproxCurve_Eval ev (HCurve, 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) GeomConvert_ApproxCurve::Curve() const
{
return myBSplCurve;
}
Standard_Boolean GeomConvert_ApproxCurve::IsDone() const
{
return myIsDone;
}
Standard_Boolean GeomConvert_ApproxCurve::HasResult() const
{
return myHasResult;
}
Standard_Real GeomConvert_ApproxCurve::MaxError() const
{
return myMaxError;
}
void GeomConvert_ApproxCurve::Dump(Standard_OStream& o) const
{
o << "******* Dump of ApproxCurve *******" << endl;
o << "*******Error " << MaxError() << endl;
}

View File

@@ -0,0 +1,78 @@
-- File: GeomConvert_ApproxSurface.cdl
-- Created: Tue Aug 26 10:44:03 1997
-- Author: Stepan MISHIN
-- <smn@toctox.nnov.matra-dtv.fr>
---Copyright: Matra Datavision 1997
class ApproxSurface from GeomConvert
---Purpose: A framework to convert a surface to a BSpline
-- surface. This is done by approximation to a BSpline
-- surface within a given tolerance.
uses
Pnt from gp,
Surface from Geom,
OffsetSurface from Geom,
BSplineSurface from Geom,
Shape from GeomAbs,
ApproxAFunc2Var from AdvApp2Var,
OutOfRange from Standard
raises OutOfRange from Standard
is
Create(Surf: Surface from Geom;
Tol3d: Real;
UContinuity : Shape from GeomAbs;
VContinuity : Shape from GeomAbs;
MaxDegU : Integer;
MaxDegV : Integer;
MaxSegments: Integer;
PrecisCode : Integer) returns ApproxSurface ;
---Purpose: Constructs a surface approximation framework defined by
-- - the conic Surf
-- - the tolerance value Tol3d
-- - the degree of continuity UContinuity, VContinuity
-- in the directions of the U and V parameters
-- - the highest degree MaxDegU, MaxDegV which
-- the polynomial defining the BSpline curve may
-- have in the directions of the U and V parameters
-- - the maximum number of segments MaxSegments
-- allowed in the resulting BSpline curve
-- - the index of precision PrecisCode.
Surface(me) returns BSplineSurface from Geom;
---Purpose: Returns the BSpline surface resulting from the approximation algorithm.
IsDone(me) returns Boolean from Standard;
--- Purpose: Returns Standard_True if the approximation has be done
HasResult(me) returns Boolean;
--- Purpose: Returns true if the approximation did come out with a result that
-- is not NECESSARILY within the required tolerance or a result
-- that is not recognized with the wished continuities.
MaxError(me) returns Real from Standard;
--- Purpose: Returns the greatest distance between a point on the
-- source conic surface and the BSpline surface
-- resulting from the approximation (>0 when an approximation
-- has been done, 0 if no approximation )
Dump(me ; o : in out OStream);
---Purpose: Prints on the stream o informations on the current state of the object.
fields
mySurf : Surface from Geom;
myIsDone : Boolean from Standard;
myHasResult: Boolean from Standard;
myBSplSurf : BSplineSurface from Geom;
myMaxError : Real from Standard;
end;

View File

@@ -0,0 +1,384 @@
#include <GeomConvert_ApproxSurface.ixx>
#include <GeomAdaptor_HSurface.hxx>
#include <Precision.hxx>
#include <AdvApp2Var_ApproxAFunc2Var.hxx>
#include <Standard_Real.hxx>
#include <TColStd_HArray2OfReal.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <AdvApprox_PrefAndRec.hxx>
static Handle(Adaptor3d_HSurface) fonct;
extern "C" void mySurfEval1(Standard_Integer * Dimension,
// Dimension
Standard_Real * UStartEnd,
// StartEnd[2] in U
Standard_Real * VStartEnd,
// StartEnd[2] in V
Standard_Integer * FavorIso,
// Choice of constante, 1 for U, 2 for V
Standard_Real * ConstParam,
// Value of constant parameter
Standard_Integer * NbParams,
// Number of parameters N
Standard_Real * Parameters,
// Values of parameters,
Standard_Integer * UOrder,
// Derivative Request in U
Standard_Integer * VOrder,
// Derivative Request in V
Standard_Real * Result,
// Result[Dimension,N]
Standard_Integer * ErrorCode)
// Error Code
{
*ErrorCode = 0;
// Standard_Integer idim;
Standard_Integer jpar;
Standard_Real Upar,Vpar;
// Dimension incorrecte
if (*Dimension!=3) {
*ErrorCode = 1;
}
// Parametres incorrects
/* if (*FavorIso==1) {
Upar = *ConstParam;
if (( Upar < UStartEnd[0] ) || ( Upar > UStartEnd[1] )) {
*ErrorCode = 2;
}
for (jpar=1;jpar<=*NbParams;jpar++) {
Vpar = Parameters[jpar-1];
if (( Vpar < VStartEnd[0] ) || ( Vpar > VStartEnd[1] )) {
*ErrorCode = 2;
}
}
}
else {
Vpar = *ConstParam;
if (( Vpar < VStartEnd[0] ) || ( Vpar > VStartEnd[1] )) {
*ErrorCode = 2;
}
for (jpar=1;jpar<=*NbParams;jpar++) {
Upar = Parameters[jpar-1];
if (( Upar < UStartEnd[0] ) || ( Upar > UStartEnd[1] )) {
*ErrorCode = 2;
}
}
}*/
// Initialisation
fonct = fonct->UTrim(UStartEnd[0], UStartEnd[1], Precision::PConfusion());
fonct = fonct->VTrim(VStartEnd[0], VStartEnd[1], Precision::PConfusion());
/*
for (idim=1;idim<=*Dimension;idim++) {
for (jpar=1;jpar<=*NbParams;jpar++) {
Result[idim-1+(jpar-1)*(*Dimension)] = 0.;
}
}*/
Standard_Integer Order = *UOrder + *VOrder;
gp_Pnt pnt;
gp_Vec vect, v1, v2, v3, v4, v5, v6, v7, v8, v9;
if (*FavorIso==1) {
Upar = *ConstParam;
switch (Order) {
case 0 :
for (jpar=1;jpar<=*NbParams;jpar++) {
Vpar = Parameters[jpar-1];
pnt = fonct->Value(Upar,Vpar);
Result[(jpar-1)*(*Dimension)] = pnt.X();
Result[1+(jpar-1)*(*Dimension)] = pnt.Y();
Result[2+(jpar-1)*(*Dimension)] = pnt.Z();
}
break;
case 1 :
for (jpar=1;jpar<=*NbParams;jpar++) {
Vpar = Parameters[jpar-1];
fonct->D1(Upar, Vpar, pnt, v1, v2);
if (*UOrder==1) {
Result[(jpar-1)*(*Dimension)] = v1.X();
Result[1+(jpar-1)*(*Dimension)] = v1.Y();
Result[2+(jpar-1)*(*Dimension)] = v1.Z();
}
else {
Result[(jpar-1)*(*Dimension)] = v2.X();
Result[1+(jpar-1)*(*Dimension)] = v2.Y();
Result[2+(jpar-1)*(*Dimension)] = v2.Z();
}
}
break;
case 2 :
for (jpar=1;jpar<=*NbParams;jpar++) {
Vpar = Parameters[jpar-1];
fonct->D2(Upar, Vpar, pnt, v1, v2, v3, v4, v5);
if (*UOrder==2) {
Result[(jpar-1)*(*Dimension)] = v3.X();
Result[1+(jpar-1)*(*Dimension)] = v3.Y();
Result[2+(jpar-1)*(*Dimension)] = v3.Z();
}
else if (*UOrder==1) {
Result[(jpar-1)*(*Dimension)] = v5.X();
Result[1+(jpar-1)*(*Dimension)] = v5.Y();
Result[2+(jpar-1)*(*Dimension)] = v5.Z();
}
else if (*UOrder==0) {
Result[(jpar-1)*(*Dimension)] = v4.X();
Result[1+(jpar-1)*(*Dimension)] = v4.Y();
Result[2+(jpar-1)*(*Dimension)] = v4.Z();
}
}
break;
case 3 :
for (jpar=1;jpar<=*NbParams;jpar++) {
Vpar = Parameters[jpar-1];
fonct->D3(Upar, Vpar, pnt, v1, v2, v3, v4, v5, v6, v7, v8, v9);
if (*UOrder==2) {
Result[(jpar-1)*(*Dimension)] = v8.X();
Result[1+(jpar-1)*(*Dimension)] = v8.Y();
Result[2+(jpar-1)*(*Dimension)] = v8.Z();
}
else if (*UOrder==1) {
Result[(jpar-1)*(*Dimension)] = v9.X();
Result[1+(jpar-1)*(*Dimension)] = v9.Y();
Result[2+(jpar-1)*(*Dimension)] = v9.Z();
}
}
break;
case 4 :
for (jpar=1;jpar<=*NbParams;jpar++) {
Vpar = Parameters[jpar-1];
vect = fonct->DN(Upar, Vpar, *UOrder, *VOrder);
Result[(jpar-1)*(*Dimension)] = vect.X();
Result[1+(jpar-1)*(*Dimension)] = vect.Y();
Result[2+(jpar-1)*(*Dimension)] = vect.Z();
}
break;
}
}
else {
Vpar = *ConstParam;
switch (Order) {
case 0 :
for (jpar=1;jpar<=*NbParams;jpar++) {
Upar = Parameters[jpar-1];
pnt = fonct->Value(Upar,Vpar);
Result[(jpar-1)*(*Dimension)] = pnt.X();
Result[1+(jpar-1)*(*Dimension)] = pnt.Y();
Result[2+(jpar-1)*(*Dimension)] = pnt.Z();
}
break;
case 1 :
for (jpar=1;jpar<=*NbParams;jpar++) {
Upar = Parameters[jpar-1];
fonct->D1(Upar, Vpar, pnt, v1, v2);
if (*UOrder==1) {
Result[(jpar-1)*(*Dimension)] = v1.X();
Result[1+(jpar-1)*(*Dimension)] = v1.Y();
Result[2+(jpar-1)*(*Dimension)] = v1.Z();
}
else {
Result[(jpar-1)*(*Dimension)] = v2.X();
Result[1+(jpar-1)*(*Dimension)] = v2.Y();
Result[2+(jpar-1)*(*Dimension)] = v2.Z();
}
}
break;
case 2 :
for (jpar=1;jpar<=*NbParams;jpar++) {
Upar = Parameters[jpar-1];
fonct->D2(Upar, Vpar, pnt, v1, v2, v3, v4, v5);
if (*UOrder==2) {
Result[(jpar-1)*(*Dimension)] = v3.X();
Result[1+(jpar-1)*(*Dimension)] = v3.Y();
Result[2+(jpar-1)*(*Dimension)] = v3.Z();
}
else if (*UOrder==1) {
Result[(jpar-1)*(*Dimension)] = v5.X();
Result[1+(jpar-1)*(*Dimension)] = v5.Y();
Result[2+(jpar-1)*(*Dimension)] = v5.Z();
}
else if (*UOrder==0) {
Result[(jpar-1)*(*Dimension)] = v4.X();
Result[1+(jpar-1)*(*Dimension)] = v4.Y();
Result[2+(jpar-1)*(*Dimension)] = v4.Z();
}
}
break;
case 3 :
for (jpar=1;jpar<=*NbParams;jpar++) {
Upar = Parameters[jpar-1];
fonct->D3(Upar, Vpar, pnt, v1, v2, v3, v4, v5, v6, v7, v8, v9);
if (*UOrder==2) {
Result[(jpar-1)*(*Dimension)] = v8.X();
Result[1+(jpar-1)*(*Dimension)] = v8.Y();
Result[2+(jpar-1)*(*Dimension)] = v8.Z();
}
else if (*UOrder==1) {
Result[(jpar-1)*(*Dimension)] = v9.X();
Result[1+(jpar-1)*(*Dimension)] = v9.Y();
Result[2+(jpar-1)*(*Dimension)] = v9.Z();
}
}
break;
case 4 :
for (jpar=1;jpar<=*NbParams;jpar++) {
Upar = Parameters[jpar-1];
vect = fonct->DN(Upar, Vpar, *UOrder, *VOrder);
Result[(jpar-1)*(*Dimension)] = vect.X();
Result[1+(jpar-1)*(*Dimension)] = vect.Y();
Result[2+(jpar-1)*(*Dimension)] = vect.Z();
}
break;
}
}
}
//=======================================================================
//function : GeomConvert_ApproxSurface
//purpose :
//=======================================================================
GeomConvert_ApproxSurface::GeomConvert_ApproxSurface(const Handle(Geom_Surface)& Surf,
const Standard_Real Tol3d,
const GeomAbs_Shape UContinuity,
const GeomAbs_Shape VContinuity,
const Standard_Integer MaxDegU,
const Standard_Integer MaxDegV,
const Standard_Integer MaxSegments,
const Standard_Integer PrecisCode)
{
Standard_Real U0, U1, V0, V1;
fonct = new (GeomAdaptor_HSurface)(Surf); // Initialisation de la surface algorithmique
Surf->Bounds(U0, U1, V0, V1);
// " Init des nombres de sous-espaces et des tolerances"
Standard_Integer nb1 = 0, nb2 = 0, nb3 = 1;
Handle(TColStd_HArray1OfReal) nul1 =
new TColStd_HArray1OfReal(1,1);
nul1->SetValue(1,0.);
Handle(TColStd_HArray2OfReal) nul2 =
new TColStd_HArray2OfReal(1,1,1,4);
nul2->SetValue(1,1,0.);
nul2->SetValue(1,2,0.);
nul2->SetValue(1,3,0.);
nul2->SetValue(1,4,0.);
Handle(TColStd_HArray1OfReal) eps3D =
new TColStd_HArray1OfReal(1,1);
eps3D->SetValue(1,Tol3d);
Handle(TColStd_HArray2OfReal) epsfr =
new TColStd_HArray2OfReal(1,1,1,4);
epsfr->SetValue(1,1,Tol3d);
epsfr->SetValue(1,2,Tol3d);
epsfr->SetValue(1,3,Tol3d);
epsfr->SetValue(1,4,Tol3d);
// " Init du type d'iso"
GeomAbs_IsoType IsoType = GeomAbs_IsoV;
Standard_Integer NbDec;
NbDec = fonct->NbUIntervals(GeomAbs_C2);
TColStd_Array1OfReal UDec_C2(1, NbDec+1);
fonct->UIntervals(UDec_C2, GeomAbs_C2);
NbDec = fonct->NbVIntervals(GeomAbs_C2);
TColStd_Array1OfReal VDec_C2(1, NbDec+1);
fonct->VIntervals(VDec_C2, GeomAbs_C2);
NbDec = fonct->NbUIntervals(GeomAbs_C3);
TColStd_Array1OfReal UDec_C3(1, NbDec+1);
fonct->UIntervals(UDec_C3, GeomAbs_C3);
NbDec = fonct->NbVIntervals(GeomAbs_C3);
TColStd_Array1OfReal VDec_C3(1, NbDec+1);
fonct->VIntervals(VDec_C3, GeomAbs_C3);
// Approximation avec decoupe preferentiel
// aux lieux de discontinuitees C2
AdvApprox_PrefAndRec pUDec(UDec_C2,UDec_C3);
AdvApprox_PrefAndRec pVDec(VDec_C2,VDec_C3);
//POP pour WNT
AdvApp2Var_EvaluatorFunc2Var ev = mySurfEval1;
AdvApp2Var_ApproxAFunc2Var approx(nb1, nb2, nb3,
nul1,nul1,eps3D,
nul2,nul2,epsfr,
U0,U1,V0,V1,
IsoType,UContinuity,VContinuity,PrecisCode,
// MaxDegU,MaxDegV,MaxSegments,mySurfEval1,
MaxDegU,MaxDegV,MaxSegments,ev,
pUDec,pVDec);
myMaxError = approx.MaxError(3,1);
myBSplSurf = approx.Surface(1);
myIsDone = approx.IsDone();
myHasResult = approx.HasResult();
}
//=======================================================================
//function : Surface
//purpose :
//=======================================================================
Handle(Geom_BSplineSurface) GeomConvert_ApproxSurface::Surface() const
{
return myBSplSurf;
}
//=======================================================================
//function : IsDone
//purpose :
//=======================================================================
Standard_Boolean GeomConvert_ApproxSurface::IsDone() const
{
return myIsDone;
}
//=======================================================================
//function : HasResult
//purpose :
//=======================================================================
Standard_Boolean GeomConvert_ApproxSurface::HasResult() const
{
return myHasResult;
}
//=======================================================================
//function : MaxError
//purpose :
//=======================================================================
Standard_Real GeomConvert_ApproxSurface::MaxError() const
{
return myMaxError;
}
//=======================================================================
//function : Dump
//purpose :
//=======================================================================
void GeomConvert_ApproxSurface::Dump(Standard_OStream& o) const
{
o<<endl;
if (!myHasResult) { o<<"No result"<<endl; }
else {
o<<"Result max error :"<< myMaxError <<endl;
}
o<<endl;
}

View File

@@ -0,0 +1,117 @@
-- File: BSplineCurveKnotSplitting.cdl
-- Created: Thu Oct 3 15:54:16 1991
---Copyright: Matra Datavision 1991, 1992
class BSplineCurveKnotSplitting from GeomConvert
--- Purpose : An algorithm to determine points at which a BSpline
-- curve should be split in order to obtain arcs of the same continuity.
-- If you require curves with a minimum continuity for
-- your computation, it is useful to know the points
-- between which an arc has a continuity of a given
-- order. For a BSpline curve, the discontinuities are
-- localized at the knot values. Between two knot values
-- the BSpline is infinitely and continuously
-- differentiable. At a given knot, the continuity is equal
-- to: Degree - Mult, where Degree is the
-- degree of the BSpline curve and Mult is the multiplicity of the knot.
-- It is possible to compute the arcs which correspond to
-- this splitting using the global function
-- SplitBSplineCurve provided by the package GeomConvert.
-- A BSplineCurveKnotSplitting object provides a framework for:
-- - defining the curve to be analyzed and the
-- required degree of continuity,
-- - implementing the computation algorithm, and
-- - consulting the results.
uses Array1OfInteger from TColStd,
HArray1OfInteger from TColStd,
BSplineCurve from Geom
raises DimensionError from Standard,
RangeError from Standard
is
Create (BasisCurve : BSplineCurve from Geom; ContinuityRange : Integer)
returns BSplineCurveKnotSplitting
--- Purpose : Determines points at which the BSpline curve
-- BasisCurve should be split in order to obtain arcs
-- with a degree of continuity equal to ContinuityRange.
-- These points are knot values of BasisCurve. They
-- are identified by indices in the knots table of BasisCurve.
-- Use the available interrogation functions to access
-- computed values, followed by the global function
-- SplitBSplineCurve (provided by the package GeomConvert) to split the curve.
-- Exceptions
-- Standard_RangeError if ContinuityRange is less than zero.
raises RangeError;
NbSplits (me) returns Integer is static;
--- Purpose :Returns the number of points at which the analyzed
-- BSpline curve should be split, in order to obtain arcs
-- with the continuity required by this framework.
-- All these points correspond to knot values. Note that
-- the first and last points of the curve, which bound the
-- first and last arcs, are counted among these splitting points.
Splitting (me; SplitValues : in out Array1OfInteger)
--- Purpose : Loads the SplitValues table with the split knots
-- values computed in this framework. Each value in the
-- table is an index in the knots table of the BSpline
-- curve analyzed by this algorithm.
-- The values in SplitValues are given in ascending
-- order and comprise the indices of the knots which
-- give the first and last points of the curve. Use two
-- consecutive values from the table as arguments of the
-- global function SplitBSplineCurve (provided by the
-- package GeomConvert) to split the curve.
-- Exceptions
-- Standard_DimensionError if the array SplitValues
-- was not created with the following bounds:
-- - 1, and
-- - the number of split points computed in this
-- framework (as given by the function NbSplits).
raises DimensionError
is static;
SplitValue (me; Index : Integer) returns Integer
--- Purpose : Returns the split knot of index Index to the split knots
-- table computed in this framework. The returned value
-- is an index in the knots table of the BSpline curve
-- analyzed by this algorithm.
-- Notes:
-- - If Index is equal to 1, the corresponding knot
-- gives the first point of the curve.
-- - If Index is equal to the number of split knots
-- computed in this framework, the corresponding
-- point is the last point of the curve.
-- Exceptions
-- Standard_RangeError if Index is less than 1 or
-- greater than the number of split knots computed in this framework.
raises RangeError
is static;
fields
splitIndexes : HArray1OfInteger;
end BSplineCurveKnotSplitting;

View File

@@ -0,0 +1,105 @@
//File GeomConvert_BSplineCurveKnotSplitting.cxx
//Jean-Claude Vauthier 27 November 1991
//Passage sur C1 Aout 1992
#include <GeomConvert_BSplineCurveKnotSplitting.ixx>
#include <Standard_RangeError.hxx>
#include <BSplCLib.hxx>
typedef Handle(Geom_BSplineCurve) Handle(BSplineCurve);
typedef TColStd_Array1OfInteger Array1OfInteger;
typedef TColStd_HArray1OfInteger HArray1OfInteger;
GeomConvert_BSplineCurveKnotSplitting::GeomConvert_BSplineCurveKnotSplitting (
const Handle(BSplineCurve)& BasisCurve,
const Standard_Integer ContinuityRange
) {
if (ContinuityRange < 0) Standard_RangeError::Raise();
Standard_Integer FirstIndex = BasisCurve->FirstUKnotIndex();
Standard_Integer LastIndex = BasisCurve->LastUKnotIndex();
Standard_Integer Degree = BasisCurve->Degree();
if (ContinuityRange == 0) {
splitIndexes = new HArray1OfInteger (1, 2);
splitIndexes->SetValue (1, FirstIndex);
splitIndexes->SetValue (2, LastIndex);
}
else {
Standard_Integer NbKnots = BasisCurve->NbKnots();
Array1OfInteger Mults (1, NbKnots);
BasisCurve->Multiplicities (Mults);
Standard_Integer Mmax = BSplCLib::MaxKnotMult (Mults, FirstIndex, LastIndex);
if (Degree - Mmax >= ContinuityRange) {
splitIndexes = new HArray1OfInteger (1, 2);
splitIndexes->SetValue (1, FirstIndex);
splitIndexes->SetValue (2, LastIndex);
}
else {
Array1OfInteger Split (1, LastIndex - FirstIndex + 1);
Standard_Integer NbSplit = 1;
Standard_Integer Index = FirstIndex;
Split (NbSplit) = Index;
Index++;
NbSplit++;
while (Index < LastIndex) {
if (Degree - Mults (Index) < ContinuityRange) {
Split (NbSplit) = Index;
NbSplit++;
}
Index++;
}
Split (NbSplit) = Index;
splitIndexes = new HArray1OfInteger (1, NbSplit);
for (Standard_Integer i = 1; i <= NbSplit; i++) {
splitIndexes->SetValue (i, Split (i));
}
}
}
}
Standard_Integer GeomConvert_BSplineCurveKnotSplitting::NbSplits () const {
return splitIndexes->Length();
}
Standard_Integer GeomConvert_BSplineCurveKnotSplitting::SplitValue (
const Standard_Integer Index
) const {
Standard_RangeError_Raise_if (
Index < 1 || Index > splitIndexes->Length(), " ");
return splitIndexes->Value (Index);
}
void GeomConvert_BSplineCurveKnotSplitting::Splitting (
Array1OfInteger& SplitValues
) const {
for (Standard_Integer i = 1; i <= splitIndexes->Length(); i++){
SplitValues (i) = splitIndexes->Value (i);
}
}

View File

@@ -0,0 +1,109 @@
-- File: GeomConvert_BSplineCurveToBezierCurve.cdl
-- Created: Tue Mar 12 17:13:53 1996
-- Author: Bruno DUMORTIER
-- <dub@fuegox>
---Copyright: Matra Datavision 1996
class BSplineCurveToBezierCurve from GeomConvert
--- Purpose :An algorithm to convert a BSpline curve into a series
-- of adjacent Bezier curves.
-- A BSplineCurveToBezierCurve object provides a framework for:
-- - defining the BSpline curve to be converted
-- - implementing the construction algorithm, and
-- - consulting the results.
-- References :
-- Generating the Bezier points of B-spline curves and surfaces
-- (Wolfgang Bohm) CAD volume 13 number 6 november 1981
uses
Array1OfReal from TColStd,
Array1OfBezierCurve from TColGeom,
BezierCurve from Geom,
BSplineCurve from Geom
raises
DimensionError from Standard,
DomainError from Standard,
OutOfRange from Standard
is
Create (BasisCurve : BSplineCurve) returns BSplineCurveToBezierCurve;
--- Purpose : Computes all the data needed to convert the
-- BSpline curve BasisCurve into a series of adjacent Bezier arcs.
Create (BasisCurve : BSplineCurve;
U1, U2 : Real;
ParametricTolerance : Real)
returns BSplineCurveToBezierCurve
--- Purpose : Computes all the data needed to convert
-- the portion of the BSpline curve BasisCurve
-- limited by the two parameter values U1 and U2 into a series of adjacent Bezier arcs.
-- The result consists of a series of BasisCurve arcs
-- limited by points corresponding to knot values of the curve.
-- Use the available interrogation functions to ascertain
-- the number of computed Bezier arcs, and then to
-- construct each individual Bezier curve (or all Bezier curves).
-- Note: ParametricTolerance is not used.
-- Raises DomainError if U1 or U2 are out of the parametric bounds of the basis
-- curve [FirstParameter, LastParameter]. The Tolerance criterion
-- is ParametricTolerance.
-- Raised if Abs (U2 - U1) <= ParametricTolerance.
raises DomainError;
Arc (me : in out; Index : Integer) returns mutable BezierCurve
--- Purpose : Constructs and returns the Bezier curve of index
-- Index to the table of adjacent Bezier arcs
-- computed by this algorithm.
-- This Bezier curve has the same orientation as the
-- BSpline curve analyzed in this framework.
-- Exceptions
-- Standard_OutOfRange if Index is less than 1 or
-- greater than the number of adjacent Bezier arcs
-- computed by this algorithm.
raises OutOfRange
is static;
Arcs (me : in out; Curves : in out Array1OfBezierCurve)
--- Purpose : Constructs all the Bezier curves whose data is
-- computed by this algorithm and loads these curves into the Curves table.
-- The Bezier curves have the same orientation as the
-- BSpline curve analyzed in this framework.
-- Exceptions
-- Standard_DimensionError if the Curves array was
-- not created with the following bounds:
-- - 1 , and
-- - the number of adjacent Bezier arcs computed by
-- this algorithm (as given by the function NbArcs).
raises DimensionError
is static;
Knots(me; TKnots : out Array1OfReal from TColStd)
---Purpose: This methode returns the bspline's knots associated to
-- the converted arcs
raises DimensionError
--- Purpose : Raised if the length of Curves is not equal to
-- NbArcs + 1.
is static;
NbArcs (me) returns Integer is static;
--- Purpose :
-- Returns the number of BezierCurve arcs.
-- If at the creation time you have decomposed the basis curve
-- between the parametric values UFirst, ULast the number of
-- BezierCurve arcs depends on the number of knots included inside
-- the interval [UFirst, ULast].
-- If you have decomposed the whole basis B-spline curve the number
-- of BezierCurve arcs NbArcs is equal to the number of knots less
-- one.
fields
myCurve : BSplineCurve from Geom;
end BSplineCurveToBezierCurve;

View File

@@ -0,0 +1,138 @@
// File: GeomConvert_BSplineCurveToBezierCurve.cxx
// Created: Tue Mar 12 17:14:53 1996
// Author: Bruno DUMORTIER
// <dub@fuegox>
#include <GeomConvert_BSplineCurveToBezierCurve.ixx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColStd_Array1OfReal.hxx>
//=======================================================================
//function : GeomConvert_BSplineCurveToBezierCurve
//purpose :
//=======================================================================
GeomConvert_BSplineCurveToBezierCurve::GeomConvert_BSplineCurveToBezierCurve (const Handle(Geom_BSplineCurve)& BasisCurve)
{
myCurve = Handle(Geom_BSplineCurve)::DownCast(BasisCurve->Copy());
Standard_Real Uf = myCurve->FirstParameter();
Standard_Real Ul = myCurve->LastParameter();
myCurve->Segment(Uf,Ul);
myCurve->IncreaseMultiplicity(myCurve->FirstUKnotIndex(),
myCurve->LastUKnotIndex(),
myCurve->Degree());
}
//=======================================================================
//function : GeomConvert_BSplineCurveToBezierCurve
//purpose :
// 01/12/1997 PMN: On elimine d'eventuelles micro-courbe PRO11516
//=======================================================================Real I
GeomConvert_BSplineCurveToBezierCurve::GeomConvert_BSplineCurveToBezierCurve
(const Handle(Geom_BSplineCurve)& BasisCurve,
const Standard_Real U1,
const Standard_Real U2,
const Standard_Real ParametricTolerance)
{
if (U2 - U1 < ParametricTolerance)
Standard_DomainError::Raise("GeomConvert_BSplineCurveToBezierSurface");
Standard_Real Uf = U1, Ul = U2;
Standard_Real PTol = ParametricTolerance/2 ;
Standard_Integer I1, I2;
myCurve = Handle(Geom_BSplineCurve)::DownCast(BasisCurve->Copy());
myCurve->LocateU(U1, PTol, I1, I2);
if (I1==I2) { // On est sur le noeud
if ( myCurve->Knot(I1) > U1) Uf = myCurve->Knot(I1);
}
myCurve->LocateU(U2, PTol, I1, I2);
if (I1==I2) { // On est sur le noeud
if ( myCurve->Knot(I1) < U2) Ul = myCurve->Knot(I1);
}
myCurve->Segment(Uf,Ul);
myCurve->IncreaseMultiplicity(myCurve->FirstUKnotIndex(),
myCurve->LastUKnotIndex(),
myCurve->Degree());
}
//=======================================================================
//function : Arc
//purpose :
//=======================================================================
Handle(Geom_BezierCurve) GeomConvert_BSplineCurveToBezierCurve::Arc
(const Standard_Integer Index)
{
if ( Index < 1 || Index > myCurve->NbKnots()-1) {
Standard_OutOfRange::Raise("GeomConvert_BSplineCurveToBezierCurve");
}
Standard_Integer Deg = myCurve->Degree();
TColgp_Array1OfPnt Poles(1,Deg+1);
Handle(Geom_BezierCurve) C;
if ( myCurve->IsRational()) {
TColStd_Array1OfReal Weights(1,Deg+1);
for ( Standard_Integer i = 1; i <= Deg+1; i++) {
Poles(i) = myCurve->Pole(i+Deg*(Index-1));
Weights(i) = myCurve->Weight(i+Deg*(Index-1));
}
C = new Geom_BezierCurve(Poles,Weights);
}
else {
for ( Standard_Integer i = 1; i <= Deg+1; i++) {
Poles(i) = myCurve->Pole(i+Deg*(Index-1));
}
C = new Geom_BezierCurve(Poles);
}
return C;
}
//=======================================================================
//function : Arcs
//purpose :
//=======================================================================
void GeomConvert_BSplineCurveToBezierCurve::Arcs
(TColGeom_Array1OfBezierCurve& Curves)
{
Standard_Integer n = NbArcs();
for ( Standard_Integer i = 1; i <= n; i++) {
Curves(i) = Arc(i);
}
}
//=======================================================================
//function : Knots
//purpose :
//=======================================================================
void GeomConvert_BSplineCurveToBezierCurve::Knots
(TColStd_Array1OfReal& TKnots) const
{
Standard_Integer ii, kk;
for (ii = 1, kk = TKnots.Lower();
ii <=myCurve->NbKnots(); ii++, kk++)
TKnots(kk) = myCurve->Knot(ii);
}
//=======================================================================
//function : NbArcs
//purpose :
//=======================================================================
Standard_Integer GeomConvert_BSplineCurveToBezierCurve::NbArcs() const
{
return (myCurve->NbKnots()-1);
}

View File

@@ -0,0 +1,157 @@
-- File: BSplineSurfaceKnotSplitting.cdl
-- Created: Fri Oct 4 08:44:03 1991
---Copyright: Matra Datavision 1991, 1992
class BSplineSurfaceKnotSplitting from GeomConvert
--- Purpose : An algorithm to determine isoparametric curves along
-- which a BSpline surface should be split in order to
-- obtain patches of the same continuity.
-- For a B-spline surface the discontinuities are localised at
-- the knot values. Between two knots values the B-spline is
-- infinitely continuously differentiable. For each parametric
-- direction at a knot of range index the continuity in this
-- direction is equal to : Degree - Mult (Index) where Degree
-- is the degree of the basis B-spline functions and Mult the
-- multiplicity of the knot of range Index in the given direction.
-- If for your computation you need to have B-spline surface with a
-- minima of continuity it can be interesting to know between which
-- knot values, a B-spline patch, has a continuity of given order.
-- This algorithm computes the indexes of the knots where you should
-- split the surface, to obtain patches with a constant continuity
-- given at the construction time. If you just want to compute the
-- local derivatives on the surface you don't need to create the
-- BSpline patches, you can use the functions LocalD1, LocalD2,
-- LocalD3, LocalDN of the class BSplineSurface from package Geom.
uses BSplineSurface from Geom,
Array1OfInteger from TColStd,
HArray1OfInteger from TColStd
raises DimensionError from Standard,
RangeError from Standard
is
Create (BasisSurface : BSplineSurface;
UContinuityRange, VContinuityRange : Integer)
returns BSplineSurfaceKnotSplitting;
--- Purpose : Determines the u- and v-isoparametric curves
-- along which the BSpline surface BasisSurface
-- should be split in order to obtain patches with a
-- degree of continuity equal to UContinuityRange in
-- the u parametric direction, and to
-- VContinuityRange in the v parametric direction.
-- These isoparametric curves are defined by
-- parameters, which are BasisSurface knot values in
-- the u or v parametric direction. They are identified
-- by indices in the BasisSurface knots table in the
-- corresponding parametric direction.
-- Use the available interrogation functions to access
-- computed values, followed by the global function
-- SplitBSplineSurface (provided by the package
-- GeomConvert) to split the surface.
-- Exceptions
-- Standard_RangeError if UContinuityRange or
-- VContinuityRange is less than zero.
NbUSplits (me) returns Integer is static;
--- Purpose : Returns the number of u-isoparametric curves
-- along which the analysed BSpline surface should be
-- split in order to obtain patches with the continuity
-- required by this framework.
-- The parameters which define these curves are knot
-- values in the corresponding parametric direction.
-- Note that the four curves which bound the surface are
-- counted among these splitting curves.
NbVSplits (me) returns Integer is static;
--- Purpose : Returns the number of v-isoparametric curves
-- along which the analysed BSpline surface should be
-- split in order to obtain patches with the continuity
-- required by this framework.
-- The parameters which define these curves are knot
-- values in the corresponding parametric direction.
-- Note that the four curves which bound the surface are
-- counted among these splitting curves.
Splitting (me; USplit, VSplit : in out Array1OfInteger)
--- Purpose: Loads the USplit and VSplit tables with the split
-- knots values computed in this framework. Each value
-- in these tables is an index in the knots table
-- corresponding to the u or v parametric direction of
-- the BSpline surface analysed by this algorithm.
-- The USplit and VSplit values are given in ascending
-- order and comprise the indices of the knots which
-- give the first and last isoparametric curves of the
-- surface in the corresponding parametric direction.
-- Use two consecutive values from the USplit table and
-- two consecutive values from the VSplit table as
-- arguments of the global function
-- SplitBSplineSurface (provided by the package
-- GeomConvert) to split the surface.
-- Exceptions
-- Standard_DimensionError if:
-- - the array USplit was not created with the following bounds:
-- - 1 , and
-- - the number of split knots in the u parametric
-- direction computed in this framework (as given
-- by the function NbUSplits); or
-- - the array VSplit was not created with the following bounds:
-- - 1 , and
-- - the number of split knots in the v parametric
-- direction computed in this framework (as given
-- by the function NbVSplits).
raises DimensionError
is static;
USplitValue (me; UIndex : Integer) returns Integer
--- Purpose : Returns the split knot of index UIndex
-- to the split knots table for the u parametric direction
-- computed in this framework. The returned value is
-- an index in the knots table relative to the u
-- parametric direction of the BSpline surface analysed by this algorithm.
-- Note: If UIndex is equal to 1, or to the number of split knots for the u
-- parametric direction computed in
-- this framework, the corresponding knot gives the
-- parameter of one of the bounding curves of the surface.
-- Exceptions
-- Standard_RangeError if UIndex is less than 1 or greater than the number
-- of split knots for the u parametric direction computed in this framework.
raises RangeError
is static;
VSplitValue (me; VIndex : Integer) returns Integer
--- Purpose : Returns the split knot of index VIndex
-- to the split knots table for the v parametric direction
-- computed in this framework. The returned value is
-- an index in the knots table relative to the v
-- parametric direction of the BSpline surface analysed by this algorithm.
-- Note: If UIndex is equal to 1, or to the number of split knots for the v
-- parametric direction computed in
-- this framework, the corresponding knot gives the
-- parameter of one of the bounding curves of the surface.
-- Exceptions
-- Standard_RangeError if VIndex is less than 1 or greater than the number
-- of split knots for the v parametric direction computed in this framework.
raises RangeError
is static;
fields
usplitIndexes : HArray1OfInteger;
vsplitIndexes : HArray1OfInteger;
end BSplineSurfaceKnotSplitting;

View File

@@ -0,0 +1,169 @@
//File GeomConvert_BSplineSurfaceKnotSplitting.cxx
//Jean-Claude Vauthier 28 Novembre 1991
//Passage sur C1 Aout 1992
#include <GeomConvert_BSplineSurfaceKnotSplitting.ixx>
#include <Standard_RangeError.hxx>
#include <BSplCLib.hxx>
typedef Handle(Geom_BSplineSurface) Handle(BSplineSurface);
typedef TColStd_Array1OfInteger Array1OfInteger;
typedef TColStd_HArray1OfInteger HArray1OfInteger;
GeomConvert_BSplineSurfaceKnotSplitting::
GeomConvert_BSplineSurfaceKnotSplitting (
const Handle(BSplineSurface)& BasisSurface,
const Standard_Integer UContinuityRange,
const Standard_Integer VContinuityRange
) {
if (UContinuityRange < 0 || VContinuityRange < 0) {
Standard_RangeError::Raise();
}
Standard_Integer FirstUIndex = BasisSurface->FirstUKnotIndex ();
Standard_Integer LastUIndex = BasisSurface->LastUKnotIndex ();
Standard_Integer FirstVIndex = BasisSurface->FirstVKnotIndex ();
Standard_Integer LastVIndex = BasisSurface->LastVKnotIndex ();
Standard_Integer UDegree = BasisSurface->UDegree ();
Standard_Integer VDegree = BasisSurface->VDegree ();
Standard_Integer i;
if (UContinuityRange == 0) {
usplitIndexes = new HArray1OfInteger (1, 2);
usplitIndexes->SetValue (1, FirstUIndex);
usplitIndexes->SetValue (2, LastUIndex);
}
else {
Standard_Integer NbUKnots = BasisSurface->NbUKnots();
Array1OfInteger UMults (1, NbUKnots);
BasisSurface->UMultiplicities (UMults);
Standard_Integer Mmax = BSplCLib::MaxKnotMult (UMults, FirstUIndex, LastUIndex);
if (UDegree - Mmax >= UContinuityRange) {
usplitIndexes = new HArray1OfInteger (1, 2);
usplitIndexes->SetValue (1, FirstUIndex);
usplitIndexes->SetValue (2, LastUIndex);
}
else {
Array1OfInteger USplit (1, LastUIndex - FirstUIndex + 1);
Standard_Integer NbUSplit = 1;
Standard_Integer UIndex = FirstUIndex;
USplit (NbUSplit) = UIndex;
UIndex++;
NbUSplit++;
while (UIndex < LastUIndex) {
if (UDegree - UMults(UIndex) < UContinuityRange) {
USplit (NbUSplit) = UIndex;
NbUSplit++;
}
UIndex++;
}
USplit (NbUSplit) = UIndex;
usplitIndexes = new HArray1OfInteger (1, NbUSplit);
for (i = 1; i <= NbUSplit; i++) {
usplitIndexes->SetValue (i, USplit (i));
}
}
}
if (VContinuityRange == 0) {
vsplitIndexes = new HArray1OfInteger (1, 2);
vsplitIndexes->SetValue (1, FirstVIndex);
vsplitIndexes->SetValue (2, LastVIndex);
}
else {
Standard_Integer NbVKnots = BasisSurface->NbVKnots();
Array1OfInteger VMults (1, NbVKnots);
BasisSurface->VMultiplicities (VMults);
Standard_Integer Mmax = BSplCLib::MaxKnotMult (VMults, FirstVIndex, LastVIndex);
if (VDegree - Mmax >= VContinuityRange) {
usplitIndexes = new HArray1OfInteger (1, 2);
usplitIndexes->SetValue (1, FirstVIndex);
usplitIndexes->SetValue (2, LastVIndex);
}
else {
Array1OfInteger VSplit (1, LastVIndex - FirstVIndex + 1);
Standard_Integer NbVSplit = 1;
Standard_Integer VIndex = FirstVIndex;
VSplit (NbVSplit) = VIndex;
VIndex++;
NbVSplit++;
while (VIndex < LastVIndex) {
if (VDegree - VMults (VIndex) < VContinuityRange) {
VSplit (NbVSplit) = VIndex;
NbVSplit++;
}
VIndex++;
}
VSplit (NbVSplit) = VIndex;
vsplitIndexes = new HArray1OfInteger (1, NbVSplit);
for (i = 1; i <= NbVSplit; i++) {
vsplitIndexes->SetValue (i, VSplit (i));
}
}
}
}
Standard_Integer GeomConvert_BSplineSurfaceKnotSplitting::NbUSplits () const {
return usplitIndexes->Length();
}
Standard_Integer GeomConvert_BSplineSurfaceKnotSplitting::NbVSplits () const {
return vsplitIndexes->Length();
}
Standard_Integer GeomConvert_BSplineSurfaceKnotSplitting::USplitValue (
const Standard_Integer UIndex
) const {
Standard_RangeError_Raise_if (
UIndex < 1 || UIndex > usplitIndexes->Length(), " ");
return usplitIndexes->Value (UIndex);
}
Standard_Integer GeomConvert_BSplineSurfaceKnotSplitting::VSplitValue (
const Standard_Integer VIndex
) const {
Standard_RangeError_Raise_if (
VIndex < 1 || VIndex > vsplitIndexes->Length(), " ");
return vsplitIndexes->Value (VIndex);
}
void GeomConvert_BSplineSurfaceKnotSplitting::Splitting (
Array1OfInteger& USplit,
Array1OfInteger& VSplit
) const {
Standard_Integer i ;
for ( i = 1; i <= usplitIndexes->Length(); i++){
USplit (i) = usplitIndexes->Value (i);
}
for (i = 1; i <= vsplitIndexes->Length(); i++){
VSplit (i) = vsplitIndexes->Value (i);
}
}

View File

@@ -0,0 +1,186 @@
-- File: GeomConvert_BSplineSurfaceToBezierSurface.cdl
-- Created: Tue Mar 12 17:21:39 1996
-- Author: Bruno DUMORTIER
-- <dub@fuegox>
---Copyright: Matra Datavision 1996
class BSplineSurfaceToBezierSurface from GeomConvert
--- Purpose :
-- This algorithm converts a B-spline surface into several
-- Bezier surfaces. It uses an algorithm of knot insertion.
-- A BSplineSurfaceToBezierSurface object provides a framework for:
-- - defining the BSpline surface to be converted,
-- - implementing the construction algorithm, and
-- - consulting the results.
-- References :
-- Generating the Bezier points of B-spline curves and surfaces
-- (Wolfgang Bohm) CAD volume 13 number 6 november 1981
uses
Array1OfReal from TColStd,
Array2OfBezierSurface from TColGeom,
BezierSurface from Geom,
BSplineSurface from Geom
raises
DimensionError from Standard,
DomainError from Standard,
OutOfRange from Standard
is
Create (BasisSurface : BSplineSurface)
returns BSplineSurfaceToBezierSurface;
--- Purpose : Computes all the data needed to convert
-- - the BSpline surface BasisSurface into a series of adjacent Bezier surfaces.
-- The result consists of a grid of BasisSurface patches
-- limited by isoparametric curves corresponding to knot
-- values, both in the u and v parametric directions of
-- the surface. A row in the grid corresponds to a series
-- of adjacent patches, all limited by the same two
-- u-isoparametric curves. A column in the grid
-- corresponds to a series of adjacent patches, all
-- limited by the same two v-isoparametric curves.
-- Use the available interrogation functions to ascertain
-- the number of computed Bezier patches, and then to
-- construct each individual Bezier surface (or all Bezier surfaces).
-- Note: ParametricTolerance is not used.
Create (BasisSurface : BSplineSurface;
U1, U2, V1, V2 : Real;
ParametricTolerance : Real)
returns BSplineSurfaceToBezierSurface
--- Purpose : Computes all the data needed to convert
-- the patch of the BSpline surface BasisSurface
-- limited by the two parameter values U1 and U2 in
-- the u parametric direction, and by the two
-- parameter values V1 and V2 in the v parametric
-- direction, into a series of adjacent Bezier surfaces.
-- The result consists of a grid of BasisSurface patches
-- limited by isoparametric curves corresponding to knot
-- values, both in the u and v parametric directions of
-- the surface. A row in the grid corresponds to a series
-- of adjacent patches, all limited by the same two
-- u-isoparametric curves. A column in the grid
-- corresponds to a series of adjacent patches, all
-- limited by the same two v-isoparametric curves.
-- Use the available interrogation functions to ascertain
-- the number of computed Bezier patches, and then to
-- construct each individual Bezier surface (or all Bezier surfaces).
-- Note: ParametricTolerance is not used. Raises DomainError
-- if U1 or U2 or V1 or V2 are out of the parametric bounds
-- of the basis surface [FirstUKnotIndex, LastUKnotIndex] ,
-- [FirstVKnotIndex, LastVKnotIndex] The tolerance criterion is
-- ParametricTolerance.
-- Raised if U2 - U1 <= ParametricTolerance or
-- V2 - V1 <= ParametricTolerance.
raises DomainError;
Patch (me : in out; UIndex, VIndex : Integer)
returns mutable BezierSurface
--- Purpose : Constructs and returns the Bezier surface of indices
-- (UIndex, VIndex) to the patch grid computed on the
-- BSpline surface analyzed by this algorithm.
-- This Bezier surface has the same orientation as the
-- BSpline surface analyzed in this framework.
-- UIndex is an index common to a row in the patch
-- grid. A row in the grid corresponds to a series of
-- adjacent patches, all limited by the same two
-- u-isoparametric curves of the surface. VIndex is an
-- index common to a column in the patch grid. A column
-- in the grid corresponds to a series of adjacent
-- patches, all limited by the same two v-isoparametric
-- curves of the surface.
-- Exceptions
-- Standard_OutOfRange if:
-- - UIndex is less than 1 or greater than the number
-- of rows in the patch grid computed on the BSpline
-- surface analyzed by this algorithm (as returned by
-- the function NbUPatches); or if
-- - VIndex is less than 1 or greater than the number
-- of columns in the patch grid computed on the
-- BSpline surface analyzed by this algorithm (as
-- returned by the function NbVPatches).
raises OutOfRange
is static;
Patches (me : in out; Surfaces : in out Array2OfBezierSurface)
--- Purpose : Constructs all the Bezier surfaces whose data is
-- computed by this algorithm, and loads them into the Surfaces table.
-- These Bezier surfaces have the same orientation as
-- the BSpline surface analyzed in this framework.
-- The Surfaces array is organised in the same way as
-- the patch grid computed on the BSpline surface
-- analyzed by this algorithm. A row in the array
-- corresponds to a series of adjacent patches, all
-- limited by the same two u-isoparametric curves of
-- the surface. A column in the array corresponds to a
-- series of adjacent patches, all limited by the same two
-- v-isoparametric curves of the surface.
-- Exceptions
-- Standard_DimensionError if the Surfaces array
-- was not created with the following bounds:
-- - 1, and the number of adjacent patch series in the
-- u parametric direction of the patch grid computed
-- on the BSpline surface, analyzed by this algorithm
-- (as given by the function NbUPatches) as row bounds,
-- - 1, and the number of adjacent patch series in the
-- v parametric direction of the patch grid computed
-- on the BSpline surface, analyzed by this algorithm
-- (as given by the function NbVPatches) as column bounds.
raises DimensionError
is static;
UKnots(me; TKnots : out Array1OfReal from TColStd)
---Purpose: This methode returns the bspline's u-knots associated to
-- the converted Patches
raises DimensionError
--- Purpose : Raised if the length of Curves is not equal to
-- NbUPatches + 1.
is static;
VKnots(me; TKnots : out Array1OfReal from TColStd)
---Purpose: This methode returns the bspline's v-knots associated to
-- the converted Patches
raises DimensionError
--- Purpose : Raised if the length of Curves is not equal to
-- NbVPatches + 1.
is static;
NbUPatches (me) returns Integer is static;
--- Purpose :
-- Returns the number of Bezier surfaces in the U direction.
-- If at the creation time you have decomposed the basis Surface
-- between the parametric values UFirst, ULast the number of
-- Bezier surfaces in the U direction depends on the number of
-- knots included inside the interval [UFirst, ULast].
-- If you have decomposed the whole basis B-spline surface the
-- number of Bezier surfaces NbUPatches is equal to the number of
-- UKnots less one.
NbVPatches (me) returns Integer is static;
--- Purpose :
-- Returns the number of Bezier surfaces in the V direction.
-- If at the creation time you have decomposed the basis surface
-- between the parametric values VFirst, VLast the number of
-- Bezier surfaces in the V direction depends on the number of
-- knots included inside the interval [VFirst, VLast].
-- If you have decomposed the whole basis B-spline surface the
-- number of Bezier surfaces NbVPatches is equal to the number of
-- VKnots less one.
fields
mySurface : BSplineSurface from Geom;
end BSplineSurfaceToBezierSurface;

View File

@@ -0,0 +1,194 @@
// File: GeomConvert_BSplineSurfaceToBezierSurface.cxx
// Created: Tue Mar 12 17:33:28 1996
// Author: Bruno DUMORTIER
// <dub@fuegox>
#include <GeomConvert_BSplineSurfaceToBezierSurface.ixx>
#include <TColgp_Array2OfPnt.hxx>
#include <TColStd_Array2OfReal.hxx>
//=======================================================================
//function : GeomConvert_BSplineSurfaceToBezierSurface
//purpose :
//=======================================================================
GeomConvert_BSplineSurfaceToBezierSurface::GeomConvert_BSplineSurfaceToBezierSurface(const Handle(Geom_BSplineSurface)& BasisSurface)
{
mySurface = Handle(Geom_BSplineSurface)::DownCast(BasisSurface->Copy());
Standard_Real U1,U2,V1,V2;
mySurface->Bounds(U1,U2,V1,V2);
mySurface->Segment(U1,U2,V1,V2);
mySurface->IncreaseUMultiplicity(mySurface->FirstUKnotIndex(),
mySurface->LastUKnotIndex(),
mySurface->UDegree());
mySurface->IncreaseVMultiplicity(mySurface->FirstVKnotIndex(),
mySurface->LastVKnotIndex(),
mySurface->VDegree());
}
//=======================================================================
//function : GeomConvert_BSplineSurfaceToBezierSurface
//purpose :
//=======================================================================
GeomConvert_BSplineSurfaceToBezierSurface::GeomConvert_BSplineSurfaceToBezierSurface
(const Handle(Geom_BSplineSurface)& BasisSurface,
const Standard_Real U1,
const Standard_Real U2,
const Standard_Real V1,
const Standard_Real V2,
const Standard_Real ParametricTolerance)
{
if ( (U2 - U1 < ParametricTolerance) ||
(V2 - V1 < ParametricTolerance) )
Standard_DomainError::Raise("GeomConvert_BSplineSurfaceToBezierSurface");
Standard_Real Uf=U1, Ul=U2, Vf=V1, Vl=V2, PTol = ParametricTolerance/2;
Standard_Integer I1, I2;
mySurface = Handle(Geom_BSplineSurface)::DownCast(BasisSurface->Copy());
mySurface->LocateU(U1, PTol, I1, I2);
if (I1==I2) { // On est sur le noeud
if ( mySurface->UKnot(I1) > U1) Uf = mySurface->UKnot(I1);
}
mySurface->LocateU(U2, PTol, I1, I2);
if (I1==I2) { // On est sur le noeud
if ( mySurface->UKnot(I1) < U2) Ul = mySurface->UKnot(I1);
}
mySurface->LocateV(V1, PTol, I1, I2);
if (I1==I2) { // On est sur le noeud
if ( mySurface->VKnot(I1) > V1) Vf = mySurface->VKnot(I1);
}
mySurface->LocateV(V2, PTol, I1, I2);
if (I1==I2) { // On est sur le noeud
if ( mySurface->VKnot(I1) < V2) Vl = mySurface->VKnot(I1);
}
mySurface->Segment(Uf, Ul, Vf, Vl);
mySurface->IncreaseUMultiplicity(mySurface->FirstUKnotIndex(),
mySurface->LastUKnotIndex(),
mySurface->UDegree());
mySurface->IncreaseVMultiplicity(mySurface->FirstVKnotIndex(),
mySurface->LastVKnotIndex(),
mySurface->VDegree());
}
//=======================================================================
//function : Patch
//purpose :
//=======================================================================
Handle(Geom_BezierSurface) GeomConvert_BSplineSurfaceToBezierSurface::Patch
(const Standard_Integer UIndex,
const Standard_Integer VIndex)
{
if (UIndex < 1 || UIndex > mySurface->NbUKnots()-1 ||
VIndex < 1 || VIndex > mySurface->NbVKnots()-1 ) {
Standard_OutOfRange::Raise("GeomConvert_BSplineSurfaceToBezierSurface");
}
Standard_Integer UDeg = mySurface->UDegree();
Standard_Integer VDeg = mySurface->VDegree();
TColgp_Array2OfPnt Poles(1,UDeg+1,1,VDeg+1);
Handle(Geom_BezierSurface) S;
if ( mySurface->IsURational() || mySurface->IsVRational()) {
TColStd_Array2OfReal Weights(1,UDeg+1,1,VDeg+1);
for ( Standard_Integer i = 1; i <= UDeg+1; i++) {
Standard_Integer CurI = i+UDeg*(UIndex-1);
for ( Standard_Integer j = 1; j <= VDeg+1; j++) {
Poles(i,j) = mySurface->Pole(CurI,j+VDeg*(VIndex-1));
Weights(i,j) = mySurface->Weight(CurI,j+VDeg*(VIndex-1));
}
}
S = new Geom_BezierSurface(Poles,Weights);
}
else {
for ( Standard_Integer i = 1; i <= UDeg+1; i++) {
Standard_Integer CurI = i+UDeg*(UIndex-1);
for ( Standard_Integer j = 1; j <= VDeg+1; j++) {
Poles(i,j) = mySurface->Pole(CurI,j+VDeg*(VIndex-1));
}
}
S = new Geom_BezierSurface(Poles);
}
return S;
}
//=======================================================================
//function : Patches
//purpose :
//=======================================================================
void GeomConvert_BSplineSurfaceToBezierSurface::Patches
(TColGeom_Array2OfBezierSurface& Surfaces)
{
Standard_Integer NbU = NbUPatches();
Standard_Integer NbV = NbVPatches();
for (Standard_Integer i = 1; i <= NbU; i++) {
for (Standard_Integer j = 1; j <= NbV; j++) {
Surfaces(i,j) = Patch(i,j);
}
}
}
//=======================================================================
//function : UKnots
//purpose :
//=======================================================================
void GeomConvert_BSplineSurfaceToBezierSurface::UKnots
(TColStd_Array1OfReal& TKnots) const
{
Standard_Integer ii, kk;
for (ii = 1, kk = TKnots.Lower();
ii <= mySurface->NbUKnots(); ii++, kk++)
TKnots(kk) = mySurface->UKnot(ii);
}
//=======================================================================
//function : VKnots
//purpose :
//=======================================================================
void GeomConvert_BSplineSurfaceToBezierSurface::VKnots
(TColStd_Array1OfReal& TKnots) const
{
Standard_Integer ii, kk;
for (ii = 1, kk = TKnots.Lower();
ii <= mySurface->NbVKnots(); ii++, kk++)
TKnots(kk) = mySurface->VKnot(ii);
}
//=======================================================================
//function : NbUPatches
//purpose :
//=======================================================================
Standard_Integer GeomConvert_BSplineSurfaceToBezierSurface::NbUPatches() const
{
return (mySurface->NbUKnots()-1);
}
//=======================================================================
//function : NbVPatches
//purpose :
//=======================================================================
Standard_Integer GeomConvert_BSplineSurfaceToBezierSurface::NbVPatches() const
{
return (mySurface->NbVKnots()-1);
}

View File

@@ -0,0 +1,313 @@
-- File: GeomConvert_CompBezierSurfaceToBSplineSurfaces.cdl
-- Created: Thu Jun 6 18:11:13 1996
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1996
class CompBezierSurfacesToBSplineSurface from GeomConvert
---Purpose: An algorithm to convert a grid of adjacent
-- non-rational Bezier surfaces into a BSpline surface.
-- A CompBezierSurfacesToBSplineSurface object
-- provides a framework for:
-- - defining the grid of adjacent Bezier surfaces
-- which is to be converted into a BSpline surface,
-- - implementing the computation algorithm, and
-- - consulting the results.
-- Warning
-- Do not attempt to convert rational Bezier surfaces using such an algorithm.
-- Input is array of Bezier patch
-- 1 2 3 4 -> VIndex [1, NbVPatches] -> VDirection
-- -----------------------
-- 1 | | | | |
-- -----------------------
-- 2 | | | | |
-- -----------------------
-- 3 | | | | |
-- -----------------------
-- UIndex [1, NbUPatches] Udirection
--
-- Warning! Patches must have compatible parametrization
uses
Array2OfBezierSurface from TColGeom,
HArray2OfPnt from TColgp,
Array1OfReal from TColStd,
HArray1OfReal from TColStd,
Shape from GeomAbs,
HArray1OfInteger from TColStd
raises
DimensionError from Standard,
NotImplemented from Standard,
ConstructionError from Standard
is
Create(Beziers : Array2OfBezierSurface)
---Purpose : Computes all the data needed to build a "C0"
-- continuous BSpline surface equivalent to the grid of
-- adjacent non-rational Bezier surfaces Beziers.
-- Each surface in the Beziers grid becomes a natural
-- patch, limited by knots values, on the BSpline surface
-- whose data is computed. Surfaces in the grid must
-- satisfy the following conditions:
-- - Coincident bounding curves between two
-- consecutive surfaces in a row of the Beziers grid
-- must be u-isoparametric bounding curves of these two surfaces.
-- - Coincident bounding curves between two
-- consecutive surfaces in a column of the Beziers
-- grid must be v-isoparametric bounding curves of these two surfaces.
-- The BSpline surface whose data is computed has the
-- following characteristics:
-- - Its degree in the u (respectively v) parametric
-- direction is equal to that of the Bezier surface
-- which has the highest degree in the u
-- (respectively v) parametric direction in the Beziers grid.
-- - It is a "Piecewise Bezier" in both u and v
-- parametric directions, i.e.:
-- - the knots are regularly spaced in each
-- parametric direction (i.e. the difference between
-- two consecutive knots is a constant), and
-- - all the multiplicities of the surface knots in a
-- given parametric direction are equal to
-- Degree, which is the degree of the BSpline
-- surface in this parametric direction, except for
-- the first and last knots for which the multiplicity is
-- equal to Degree + 1.
-- - Coincident bounding curves between two
-- consecutive columns of Bezier surfaces in the
-- Beziers grid become u-isoparametric curves,
-- corresponding to knots values of the BSpline surface.
-- - Coincident bounding curves between two
-- consecutive rows of Bezier surfaces in the Beziers
-- grid become v-isoparametric curves
-- corresponding to knots values of the BSpline surface.
-- Use the available consultation functions to access the
-- computed data. This data may be used to construct the BSpline surface.
-- Warning
-- The surfaces in the Beziers grid must be adjacent, i.e.
-- two consecutive Bezier surfaces in the grid (in a row
-- or column) must have a coincident bounding curve. In
-- addition, the location of the parameterization on each
-- of these surfaces (i.e. the relative location of u and v
-- isoparametric curves on the surface) is of importance
-- with regard to the positioning of the surfaces in the
-- Beziers grid. Care must be taken with respect to the
-- above, as these properties are not checked and an
-- error may occur if they are not satisfied.
-- Exceptions
-- Standard_NotImplemented if one of the Bezier
-- surfaces of the Beziers grid is rational.
returns CompBezierSurfacesToBSplineSurface
raises NotImplemented;
Create(Beziers : Array2OfBezierSurface;
Tolerance : Real;
RemoveKnots : Boolean = Standard_True)
---Purpose : Build an Ci uniform (Rational) BSpline surface
-- The higest Continuity Ci is imposed, like the
-- maximal deformation is lower than <Tolerance>.
-- Warning: The Continuity C0 is imposed without any check.
returns CompBezierSurfacesToBSplineSurface
raises NotImplemented;
Create(Beziers : Array2OfBezierSurface;
UKnots : Array1OfReal;
VKnots : Array1OfReal;
UContinuity : Shape = GeomAbs_C0;
VContinuity : Shape = GeomAbs_C0;
Tolerance : Real = 1.0e-4)
---Purpose : Computes all the data needed to construct a BSpline
-- surface equivalent to the adjacent non-rational
-- Bezier surfaces Beziers grid.
-- Each surface in the Beziers grid becomes a natural
-- patch, limited by knots values, on the BSpline surface
-- whose data is computed. Surfaces in the grid must
-- satisfy the following conditions:
-- - Coincident bounding curves between two
-- consecutive surfaces in a row of the Beziers grid
-- must be u-isoparametric bounding curves of these two surfaces.
-- - Coincident bounding curves between two
-- consecutive surfaces in a column of the Beziers
-- grid must be v-isoparametric bounding curves of these two surfaces.
-- The BSpline surface whose data is computed has the
-- following characteristics:
-- - Its degree in the u (respectively v) parametric
-- direction is equal to that of the Bezier surface
-- which has the highest degree in the u
-- (respectively v) parametric direction in the Beziers grid.
-- - Coincident bounding curves between two
-- consecutive columns of Bezier surfaces in the
-- Beziers grid become u-isoparametric curves
-- corresponding to knots values of the BSpline surface.
-- - Coincident bounding curves between two
-- consecutive rows of Bezier surfaces in the Beziers
-- grid become v-isoparametric curves
-- corresponding to knots values of the BSpline surface.
-- Knots values of the BSpline surface are given in the two tables:
-- - UKnots for the u parametric direction (which
-- corresponds to the order of Bezier surface columns in the Beziers grid), and
-- - VKnots for the v parametric direction (which
-- corresponds to the order of Bezier surface rows in the Beziers grid).
-- The dimensions of UKnots (respectively VKnots)
-- must be equal to the number of columns (respectively,
-- rows) of the Beziers grid, plus 1 .
-- UContinuity and VContinuity, which are both
-- defaulted to GeomAbs_C0, specify the required
-- continuity on the BSpline surface. If the required
-- degree of continuity is greater than 0 in a given
-- parametric direction, a deformation is applied locally
-- on the initial surface (as defined by the Beziers grid)
-- to satisfy this condition. This local deformation is not
-- applied however, if it is greater than Tolerance
-- (defaulted to 1.0 e-7). In such cases, the
-- continuity condition is not satisfied, and the function
-- IsDone will return false. A small tolerance value
-- prevents any modification of the surface and a large
-- tolerance value "smoothes" the surface.
-- Use the available consultation functions to access the
-- computed data. This data may be used to construct the BSpline surface.
-- Warning
-- The surfaces in the Beziers grid must be adjacent, i.e.
-- two consecutive Bezier surfaces in the grid (in a row
-- or column) must have a coincident bounding curve. In
-- addition, the location of the parameterization on each
-- of these surfaces (i.e. the relative location of u and v
-- isoparametric curves on the surface) is of importance
-- with regard to the positioning of the surfaces in the
-- Beziers grid. Care must be taken with respect to the
-- above, as these properties are not checked and an
-- error may occur if they are not satisfied.
-- Exceptions
-- Standard_DimensionMismatch:
-- - if the number of knots in the UKnots table (i.e. the
-- length of the UKnots array) is not equal to the
-- number of columns of Bezier surfaces in the
-- Beziers grid plus 1, or
-- - if the number of knots in the VKnots table (i.e. the
-- length of the VKnots array) is not equal to the
-- number of rows of Bezier surfaces in the Beziers grid, plus 1.
-- Standard_ConstructionError:
-- - if UContinuity and VContinuity are not equal to
-- one of the following values: GeomAbs_C0,
-- GeomAbs_C1, GeomAbs_C2 and GeomAbs_C3; or
-- - if the number of columns in the Beziers grid is
-- greater than 1, and the required degree of
-- continuity in the u parametric direction is greater
-- than that of the Bezier surface with the highest
-- degree in the u parametric direction (in the Beziers grid), minus 1; or
-- - if the number of rows in the Beziers grid is
-- greater than 1, and the required degree of
-- continuity in the v parametric direction is greater
-- than that of the Bezier surface with the highest
-- degree in the v parametric direction (in the Beziers grid), minus 1 .
-- Standard_NotImplemented if one of the Bezier
-- surfaces in the Beziers grid is rational.
returns CompBezierSurfacesToBSplineSurface
raises ConstructionError,
DimensionError,
NotImplemented;
Perform (me : in out; Beziers : Array2OfBezierSurface)
---Purpose : It used internaly by the constructors.
is private;
NbUKnots (me) returns Integer;
---Purpose : Returns the number of knots in the U direction
-- of the BSpline surface whose data is computed in this framework.
---C++: inline
NbUPoles (me) returns Integer;
---Purpose : Returns number of poles in the U direction
-- of the BSpline surface whose data is computed in this framework.
---C++: inline
NbVKnots (me) returns Integer;
---Purpose : Returns the number of knots in the V direction
-- of the BSpline surface whose data is computed in this framework.
---C++: inline
NbVPoles (me) returns Integer;
---Purpose : Returns the number of poles in the V direction
-- of the BSpline surface whose data is computed in this framework.
---C++: inline
Poles(me)
---Purpose : Returns the table of poles of the BSpline surface
-- whose data is computed in this framework.
---C++: inline
---C++: return const &
returns HArray2OfPnt;
UKnots (me)
---Purpose : Returns the knots table for the u parametric
-- direction of the BSpline surface whose data is computed in this framework.
---C++: inline
---C++: return const &
returns HArray1OfReal;
UDegree (me) returns Integer;
---Purpose : Returns the degree for the u parametric
-- direction of the BSpline surface whose data is computed in this framework.
---C++: inline
VKnots (me)
---Purpose : Returns the knots table for the v parametric
-- direction of the BSpline surface whose data is computed in this framework.
---C++: inline
---C++: return const &
returns HArray1OfReal;
VDegree (me)
---Purpose : Returns the degree for the v parametric
-- direction of the BSpline surface whose data is computed in this framework.
---C++: inline
returns Integer;
UMultiplicities (me)
---Purpose :
-- Returns the multiplicities table for the u
-- parametric direction of the knots of the BSpline
-- surface whose data is computed in this framework.
---C++: inline
---C++: return const &
returns HArray1OfInteger;
VMultiplicities (me)
---Purpose : -- Returns the multiplicities table for the v
-- parametric direction of the knots of the BSpline
-- surface whose data is computed in this framework.
---C++: inline
---C++: return const &
returns HArray1OfInteger;
IsDone(me)
---Purpose : Returns true if the conversion was successful.
-- Unless an exception was raised at the time of
-- construction, the conversion of the Bezier surface
-- grid assigned to this algorithm is always carried out.
-- IsDone returns false if the constraints defined at the
-- time of construction cannot be respected. This occurs
-- when there is an incompatibility between a required
-- degree of continuity on the BSpline surface, and the
-- maximum tolerance accepted for local deformations
-- of the surface. In such a case the computed data
-- does not satisfy all the initial constraints.
returns Boolean ;
fields
myUDegree : Integer;
myVDegree : Integer;
myVMults : HArray1OfInteger;
myUMults : HArray1OfInteger;
myUKnots : HArray1OfReal;
myVKnots : HArray1OfReal;
myPoles : HArray2OfPnt;
isrational : Boolean;
myDone : Boolean;
end CompBezierSurfacesToBSplineSurface;

View File

@@ -0,0 +1,446 @@
// File: GeomConvert_CompBezierSurfacesToBSplineSurface.cxx
// Created: Fri Jun 7 10:29:17 1996
// Author: Philippe MANGIN
// <pmn@sgi29>
#include <GeomConvert_CompBezierSurfacesToBSplineSurface.ixx>
#include <Standard_ConstructionError.hxx>
#include <Standard_NotImplemented.hxx>
#include <Geom_BSplineSurface.hxx>
#include <Geom_BezierSurface.hxx>
#include <Geom_Curve.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <TColgp_HArray2OfPnt.hxx>
#include <gp_XYZ.hxx>
#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
#include <TColGeom_Array2OfBezierSurface.hxx>
#include <Precision.hxx>
// ============================================================================
GeomConvert_CompBezierSurfacesToBSplineSurface::
GeomConvert_CompBezierSurfacesToBSplineSurface(const TColGeom_Array2OfBezierSurface& Beziers)
// ============================================================================
{
Standard_Integer ii;
myDone = Standard_True;
// Choix des noeuds
myUKnots = new (TColStd_HArray1OfReal) (1, Beziers.ColLength()+1);
for (ii=0; ii<myUKnots->Length(); ii++) { myUKnots->SetValue(ii+1, ii); }
myVKnots = new (TColStd_HArray1OfReal) (1, Beziers.RowLength()+1);
for (ii=0; ii<myVKnots->Length(); ii++) { myVKnots->SetValue(ii+1, ii); }
// Calcul des Poles
Perform(Beziers);
}
// ============================================================================
GeomConvert_CompBezierSurfacesToBSplineSurface::
GeomConvert_CompBezierSurfacesToBSplineSurface(
const TColGeom_Array2OfBezierSurface& Beziers,
const Standard_Real Tolerance,
const Standard_Boolean RemoveKnots)
// ============================================================================
{
Standard_Integer ii, jj, multU=0, multV, minus;
Standard_Boolean Ok;
gp_Vec vec;
Standard_Real V1, V2, V3, Ratio, L1, L2, Tol, val;
gp_Pnt P1, P2, P3;
Handle(Geom_Curve) FirstCurve, SecondCurve;
myDone = Standard_True;
// Choix des noeuds
myUKnots = new (TColStd_HArray1OfReal) (1, Beziers.ColLength()+1);
myVKnots = new (TColStd_HArray1OfReal) (1, Beziers.RowLength()+1);
// --> en U
myUKnots->SetValue(1, 0);
jj = myVKnots->Length()/2;
FirstCurve = Beziers(1, jj)->VIso(0.3);
FirstCurve->D0(0, P1);
FirstCurve->D0(0.5, P2);
FirstCurve->D1(1, P3, vec);
L1 = P1.Distance(P2) + P2.Distance(P3);
myUKnots->SetValue(2, L1);
V1 = vec.Magnitude();
// si la Parametrisation est trop bizzare on garde la pseudo-longueur
if ((V1 > 1000 * L1) || (V1 < L1 * 1.e-3)) V1 = L1;
for (ii=2; ii<myUKnots->Length(); ii++) {
SecondCurve = Beziers(ii, jj)->VIso(0.3);
SecondCurve->D1(0, P1, vec);
V2 = vec.Magnitude();
SecondCurve->D0(0.5, P2);
SecondCurve->D1(1, P3, vec);
V3 = vec.Magnitude();
L2 = P1.Distance(P2) + P2.Distance(P3);
// On calcul le ratio, en evitant les cas tordus...
if ((V2 > 1000 * L2) || (V2 < L2 * 1.e-3)) V2 = L2;
if ((V3 > 1000 * L2) || (V3 < L2 * 1.e-3)) V3 = L2;
Ratio = 1;
if ( (V1 > Precision::Confusion()) && (V2 > Precision::Confusion()) ) {
Ratio = V2 / V1;
}
if ( (Ratio < Precision::Confusion())
|| (Ratio > 1/Precision::Confusion()) ) {Ratio = 1;}
// On en deduit un nouveau noeud
val = myUKnots->Value(ii);
myUKnots->SetValue(ii+1, val + Ratio*(val- myUKnots->Value(ii-1)) );
// Et c'est reparti, pour un tour
L1 = L2;
V1 = V3;
FirstCurve = SecondCurve;
}
// --> en V
myVKnots->SetValue(1, 0);
ii = myUKnots->Length()/2;
FirstCurve = Beziers(ii, 1)->UIso(0.3);
FirstCurve->D0(0, P1);
FirstCurve->D0(0.5, P2);
FirstCurve->D1(1, P3, vec);
L1 = P1.Distance(P2) + P2.Distance(P3);
myVKnots->SetValue(2, L1);
V1 = vec.Magnitude();
// si la Parametrisation est trop bizzare on garde la pseudo-longueur
if ((V1 > 1000 * L1) || (V1 < L1 * 1.e-3)) V1 = L1;
for (jj=2; jj<myVKnots->Length(); jj++) {
SecondCurve = Beziers(ii, jj)->UIso(0.3);
SecondCurve->D1(0, P1, vec);
V2 = vec.Magnitude();
SecondCurve->D0(0.5, P2);
SecondCurve->D1(1, P3, vec);
V3 = vec.Magnitude();
L2 = P1.Distance(P2) + P2.Distance(P3);
// On calcul le ratio, en evitant les cas tordus...
if ((V2 > 1000 * L2) || (V2 < L2 * 1.e-3)) V2 = L2;
if ((V3 > 1000 * L2) || (V3 < L2 * 1.e-3)) V3 = L2;
Ratio = 1;
if ( (V1 > Precision::Confusion()) && (V2 > Precision::Confusion()) ) {
Ratio = V2 / V1;
}
if ( (Ratio < Precision::Confusion())
|| (Ratio > 1/Precision::Confusion()) ) {Ratio = 1;}
// On en deduit un nouveau noeud
val = myVKnots->Value(jj);
myVKnots->SetValue(jj+1, val + Ratio*(val-myVKnots->Value(jj-1)) );
// Et c'est reparti, pour un tour
L1 = L2;
V1 = V3;
FirstCurve = SecondCurve;
}
// Calcul des Poles
Perform(Beziers);
// Reduction de la multiplicite
Handle(Geom_BSplineSurface) Surface = new (Geom_BSplineSurface)
(myPoles->Array2(),
myUKnots->Array1(),
myVKnots->Array1(),
myUMults->Array1(),
myVMults->Array1(),
myUDegree,
myVDegree);
if (RemoveKnots) minus = 0;
else minus = 1;
for (ii=myUKnots->Length()-1; ii>1; ii--) {
Ok=Standard_True;
Tol = Tolerance/2;
multU = myUMults->Value(ii)-1;
for ( ; Ok && multU > minus; multU--, Tol/=2) {
Ok = Surface->RemoveUKnot(ii, multU, Tol);
}
}
for (ii=myVKnots->Length()-1; ii>1; ii--) {
Ok=Standard_True;
Tol = Tolerance/2;
multV = myVMults->Value(ii)-1;
for ( ; Ok && multU > minus; multV--, Tol/=2) {
Ok = Surface->RemoveVKnot(ii, multV, Tol);
}
}
// Les nouveaux champs sont arrivees ....
myPoles = new (TColgp_HArray2OfPnt) (1, Surface->NbUPoles(), 1, Surface->NbVPoles());
Surface->Poles( myPoles->ChangeArray2());
myUMults = new (TColStd_HArray1OfInteger) (1, Surface->NbUKnots());
myVMults = new (TColStd_HArray1OfInteger) (1, Surface->NbVKnots());
myUKnots = new (TColStd_HArray1OfReal) (1, Surface->NbUKnots());
myVKnots = new (TColStd_HArray1OfReal) (1, Surface->NbVKnots());
Surface->UMultiplicities( myUMults->ChangeArray1());
Surface->VMultiplicities( myVMults->ChangeArray1());
Surface->UKnots( myUKnots->ChangeArray1());
Surface->VKnots( myVKnots->ChangeArray1());
}
// ============================================================================
GeomConvert_CompBezierSurfacesToBSplineSurface::
GeomConvert_CompBezierSurfacesToBSplineSurface(
const TColGeom_Array2OfBezierSurface& Beziers,
const TColStd_Array1OfReal& UKnots,
const TColStd_Array1OfReal& VKnots,
const GeomAbs_Shape UContinuity,
const GeomAbs_Shape VContinuity,
const Standard_Real Tolerance)
// ============================================================================
{
Standard_Integer decu=0, decv=0;
Standard_Boolean Ok;
myDone = Standard_True;
// Recuperation des noeuds
myUKnots = new (TColStd_HArray1OfReal) (1, Beziers.ColLength()+1);
myUKnots->ChangeArray1() = UKnots;
myVKnots = new (TColStd_HArray1OfReal) (1, Beziers.RowLength()+1);
myVKnots->ChangeArray1() = VKnots;
// Calcul des Poles
Perform(Beziers);
// Obtention des bonne continuitee
switch ( UContinuity ) {
case GeomAbs_C0 :
decu = 0;
break;
case GeomAbs_C1 :
decu = 1;
break;
case GeomAbs_C2 :
decu = 2;
break;
case GeomAbs_C3 :
decu = 3;
break;
default:
Standard_ConstructionError::Raise(
"GeomConvert_CompBezierSurfacesToBSpl:: UContinuity error");
}
switch ( VContinuity ) {
case GeomAbs_C0 :
decv = 0;
break;
case GeomAbs_C1 :
decv = 1;
break;
case GeomAbs_C2 :
decv = 2;
break;
case GeomAbs_C3 :
decv = 3;
break;
default:
Standard_ConstructionError::Raise(
"GeomConvert_CompBezierSurfacesToBSpl:: VContinuity error");
}
if ( (decu>0) || (decv>0) ) {
Standard_Integer ii;
Standard_Integer multU = myUDegree - decu;
Standard_ConstructionError_Raise_if(
((multU <= 0) && (myUKnots->Length()>2)) ,
"GeomConvert_CompBezierSurfacesToBSpl:: UContinuity or Udeg error");
Standard_Integer multV = myVDegree - decv;
Standard_ConstructionError_Raise_if(
((multV <= 0) && (myVKnots->Length()>2)) ,
"GeomConvert_CompBezierSurfacesToBSpl:: VContinuity or Vdeg error");
Handle(Geom_BSplineSurface) Surface = new (Geom_BSplineSurface)
(myPoles->Array2(),
myUKnots->Array1(),
myVKnots->Array1(),
myUMults->Array1(),
myVMults->Array1(),
myUDegree,
myVDegree);
if (decu>0) {
for (ii=2; ii<myUKnots->Length(); ii++) {
Ok = Surface->RemoveUKnot(ii, multU, Tolerance);
if (!Ok) {myDone = Ok;}
}
}
if (decv>0) {
for (ii=2; ii<myVKnots->Length(); ii++) {
Ok = Surface->RemoveVKnot(ii, multV, Tolerance);
if (!Ok) {myDone = Ok;}
}
}
// Les nouveaux champs sont arrivees ....
myPoles = new (TColgp_HArray2OfPnt) (1, Surface->NbUPoles(), 1, Surface->NbVPoles());
Surface->Poles( myPoles->ChangeArray2());
Surface->UMultiplicities( myUMults->ChangeArray1());
Surface->VMultiplicities( myVMults->ChangeArray1());
}
}
// ================================================================================
void GeomConvert_CompBezierSurfacesToBSplineSurface::Perform(
const TColGeom_Array2OfBezierSurface& Beziers)
// ================================================================================
{
Standard_Integer IU, IV;
// (1) Determination des degrees et si le resultat est rationnel.
isrational = Standard_False;
myUDegree = 1;
myVDegree = 1;
for (IU=Beziers.LowerRow(); IU <=Beziers.UpperRow(); IU++) {
for (IV=Beziers.LowerCol(); IV <=Beziers.UpperCol(); IV++) {
if ( Beziers(IU, IV)-> IsURational()
|| Beziers(IU, IV)-> IsVRational()) { isrational = Standard_True;}
myUDegree = ( Beziers(IU, IV)->UDegree() > myUDegree ) ?
Beziers(IU, IV)->UDegree() : myUDegree;
myVDegree = ( Beziers(IU, IV)->VDegree() > myVDegree ) ?
Beziers(IU, IV)->VDegree() : myVDegree;
}
}
Standard_NotImplemented_Raise_if(isrational,
"CompBezierSurfacesToBSpl : rational !");
// (2) Boucle sur les carreaux -----------------------------
Handle(Geom_BezierSurface) Patch;
Standard_Integer UIndex, VIndex, uindex, vindex, udeb, vdeb;
Standard_Integer upol, vpol, ii;
myPoles = new (TColgp_HArray2OfPnt)
( 1, (myUDegree+1)*Beziers.ColLength() - myUKnots->Length() + 2 ,
1, (myVDegree+1)*Beziers.RowLength() - myVKnots->Length() + 2 );
for (IU=Beziers.LowerRow(); IU <=Beziers.UpperRow(); IU++) {
UIndex = (IU-1)*myUDegree + 1;
for (IV=Beziers.LowerCol(); IV <=Beziers.UpperCol(); IV++) {
Patch = Beziers(IU, IV);
VIndex = (IV-1)*myVDegree + 1;
// (2.1) Augmentation du degree
Patch->Increase(myUDegree, myVDegree);
// (2.2) Poles a recopier
if (IU==1) {udeb = 1;}
else {udeb = 2;}
if (IV==1) {vdeb = 1;}
else {vdeb = 2;}
uindex = UIndex + udeb -1;
for (upol = udeb; upol <= myUDegree+1; upol++, uindex++ ) {
vindex = VIndex + vdeb - 1;
for (vpol = vdeb; vpol <= myVDegree+1; vpol++, vindex++) {
myPoles->ChangeValue(uindex, vindex) = Patch->Pole(upol, vpol);
}
}
// (2.3) Poles a sommer
if (udeb==2) {
vindex = VIndex + vdeb - 1;
for (vpol = vdeb; vpol <= myVDegree+1; vpol++, vindex++) {
myPoles->ChangeValue(UIndex, vindex).ChangeCoord() +=
Patch->Pole(1, vpol).Coord();
}
}
if (vdeb==2) {
uindex = UIndex + udeb - 1;
for (upol = udeb; upol <= myUDegree+1; upol++, uindex++) {
myPoles->ChangeValue(uindex, VIndex).ChangeCoord() +=
Patch->Pole(upol, 1).Coord();
}
}
if (udeb==2 && vdeb==2) {
myPoles->ChangeValue(UIndex, VIndex).ChangeCoord() +=
Patch->Pole(1, 1).Coord();
}
}
}
// (3) Elimination des redondances
// car dans la boucle precedente on compte :
// - 2 fois les poles associes aux noeuds simples
// - 4 fois les poles associes aux doubles noeuds (en U et V)
// (3.1) Elimination en U
for ( UIndex = myUDegree+1, ii=2;
ii< myUKnots->Length();
ii++, UIndex+=myUDegree) {
for (vpol = 1; vpol<=myPoles->UpperCol(); vpol++) {
myPoles->ChangeValue(UIndex, vpol).ChangeCoord() *= 0.5;
}
}
// (3.2) Elimination en V
for ( VIndex = myVDegree+1, ii=2;
ii< myVKnots->Length();
ii++, VIndex += myVDegree) {
for (upol = 1; upol<=myPoles->UpperRow(); upol++) {
myPoles->ChangeValue(upol, VIndex).ChangeCoord() *= 0.5;
}
}
// (4) Init des multiplicites
myUMults = new (TColStd_HArray1OfInteger) (1, myUKnots->Length());
myUMults->Init( myUDegree);
myUMults->SetValue(1, myUDegree+1);
myUMults->SetValue( myUMults->Upper(), myUDegree+1);
myVMults = new (TColStd_HArray1OfInteger) (1, myVKnots->Length());
myVMults->Init( myVDegree);
myVMults->SetValue(1, myVDegree+1);
myVMults->SetValue(myVMults->Upper(), myVDegree+1);
}
// ========================================================================
Standard_Boolean GeomConvert_CompBezierSurfacesToBSplineSurface::IsDone() const
// ========================================================================
{
return myDone;
}

View File

@@ -0,0 +1,96 @@
// File: GeomConvert_CompBezierSurfacesToBSplineSurface.lxx
// Created: Fri Jun 7 10:32:57 1996
// Author: Philippe MANGIN
// <pmn@sgi29>
#include <TColStd_HArray1OfReal.hxx>
#include <TColgp_HArray2OfPnt.hxx>
// ================================================================================
inline Standard_Integer
GeomConvert_CompBezierSurfacesToBSplineSurface::NbUKnots() const
// ================================================================================
{
return myUKnots->Length();
}
// ================================================================================
inline Standard_Integer
GeomConvert_CompBezierSurfacesToBSplineSurface::NbUPoles() const
// ================================================================================
{
return myPoles->ColLength();
}
// ================================================================================
inline Standard_Integer
GeomConvert_CompBezierSurfacesToBSplineSurface::NbVKnots() const
// ================================================================================
{
return myVKnots->Length();
}
// ================================================================================
inline Standard_Integer
GeomConvert_CompBezierSurfacesToBSplineSurface::NbVPoles() const
// ================================================================================
{
return myPoles->RowLength();
}
// ================================================================================
inline const Handle(TColgp_HArray2OfPnt)&
GeomConvert_CompBezierSurfacesToBSplineSurface::Poles() const
// ================================================================================
{
return myPoles;
}
// ================================================================================
inline const Handle(TColStd_HArray1OfReal)&
GeomConvert_CompBezierSurfacesToBSplineSurface::UKnots() const
// ================================================================================
{
return myUKnots;
}
// ================================================================================
inline Standard_Integer
GeomConvert_CompBezierSurfacesToBSplineSurface::UDegree() const
// ================================================================================
{
return myUDegree;
}
// ================================================================================
inline const Handle(TColStd_HArray1OfReal)&
GeomConvert_CompBezierSurfacesToBSplineSurface::VKnots() const
// ================================================================================
{
return myVKnots;
}
// ================================================================================
inline Standard_Integer
GeomConvert_CompBezierSurfacesToBSplineSurface::VDegree() const
// ================================================================================
{
return myVDegree;
}
// ================================================================================
inline const Handle(TColStd_HArray1OfInteger)&
GeomConvert_CompBezierSurfacesToBSplineSurface::UMultiplicities() const
// ================================================================================
{
return myUMults;
}
// ================================================================================
inline const Handle(TColStd_HArray1OfInteger)&
GeomConvert_CompBezierSurfacesToBSplineSurface::VMultiplicities() const
// ================================================================================
{
return myVMults;
}

View File

@@ -0,0 +1,60 @@
-- File: GeomConvert_CompCurveToBSplineCurve.cdl
-- Created: Mon Sep 23 13:22:25 1996
-- Author: Philippe MANGIN
-- <pmn@sgi29>
-- Modified: Fri Jul 10 11:23:35 1998
-- JCT : Add WithRatio,MinM
---Copyright: Matra Datavision 1996
class CompCurveToBSplineCurve from GeomConvert
---Purpose: Concat several curve in an BSplineCurve
uses
ParameterisationType from Convert,
BoundedCurve from Geom,
BSplineCurve from Geom
--raises
is
Create (BasisCurve : BoundedCurve from Geom;
Parameterisation : ParameterisationType from Convert
= Convert_TgtThetaOver2)
---Purpose: Initialize the algorithme with one curve
-- - Parameterisation is used to convert
returns CompCurveToBSplineCurve;
Add (me : in out;
NewCurve : BoundedCurve from Geom;
Tolerance : Real from Standard;
After : Boolean from Standard = Standard_False;
WithRatio : Boolean from Standard = Standard_True;
MinM : Integer from Standard = 0)
---Purpose: Append a curve in the BSpline Return False if the
-- curve is not G0 with the BSplineCurve. Tolerance
-- is used to check continuity and decrease
-- Multiplicity at the common Knot until MinM
-- if MinM = 0, the common Knot can be removed
returns Boolean;
Add (me : in out;
FirstCurve : in out BSplineCurve from Geom;
SecondCurve: in out BSplineCurve from Geom;
After : Boolean from Standard;
WithRatio : Boolean from Standard;
MinM : Integer from Standard)
---Purpose: Concat two BSplineCurves.
is private;
BSplineCurve(me) returns BSplineCurve from Geom;
fields
myCurve : BSplineCurve from Geom;
myTol : Real;
myType : ParameterisationType from Convert;
end CompCurveToBSplineCurve;

View File

@@ -0,0 +1,211 @@
// File: GeomConvert_CompCurveToBSplineCurve.cxx
// Created: Mon Sep 23 15:03:12 1996
// Author: Philippe MANGIN
// <pmn@sgi29>
// Modified: Fri Jul 10 11:23:35 1998
// JCT : Add WithRatio,MinM
#include <GeomConvert_CompCurveToBSplineCurve.ixx>
#include <Geom_BSplineCurve.hxx>
#include <GeomConvert.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <gp_Vec.hxx>
#include <gp_Pnt.hxx>
#include <Precision.hxx>
GeomConvert_CompCurveToBSplineCurve::
GeomConvert_CompCurveToBSplineCurve(const Handle(Geom_BoundedCurve)& BasisCurve,
const Convert_ParameterisationType Parameterisation) :
myTol(Precision::Confusion()),
myType(Parameterisation)
{
Handle(Geom_BSplineCurve) Bs =
Handle(Geom_BSplineCurve)::DownCast(BasisCurve);
if (!Bs.IsNull()) {
myCurve = Handle(Geom_BSplineCurve)::DownCast(BasisCurve->Copy());
}
else {
myCurve = GeomConvert::CurveToBSplineCurve (BasisCurve, myType);
}
}
//=======================================================================
//function : Add
//purpose :
//=======================================================================
Standard_Boolean GeomConvert_CompCurveToBSplineCurve::
Add(const Handle(Geom_BoundedCurve)& NewCurve,
const Standard_Real Tolerance,
const Standard_Boolean After,
const Standard_Boolean WithRatio,
const Standard_Integer MinM)
{
Standard_Boolean avant, apres;
myTol = Tolerance;
// Convertion
Handle(Geom_BSplineCurve) Bs =
Handle(Geom_BSplineCurve)::DownCast(NewCurve);
if (!Bs.IsNull() ) {
Bs = Handle(Geom_BSplineCurve)::DownCast(NewCurve->Copy());
}
else {
Bs = GeomConvert::CurveToBSplineCurve (NewCurve, myType);
}
Standard_Integer LBs = Bs->NbPoles(), LCb = myCurve->NbPoles();
avant = (( myCurve->Pole(1).Distance(Bs->Pole(1)) < myTol)||
( myCurve->Pole(1).Distance(Bs->Pole(LBs))< myTol));
apres = (( myCurve->Pole(LCb).Distance(Bs->Pole(1)) < myTol) ||
( myCurve->Pole(LCb).Distance(Bs->Pole(LBs))< myTol));
// myCurve est (sera) elle fermee ?
if (avant && apres) { // On leve l'ambiguite
if (After) avant = Standard_False;
else apres = Standard_False;
}
// Ajout Apres ?
if ( apres) {
if (myCurve->Pole(LCb).Distance(Bs->Pole(LBs)) < myTol) {Bs->Reverse();}
Add(myCurve, Bs, Standard_True, WithRatio, MinM);
return Standard_True;
}
// Ajout avant ?
else if (avant) {
if (myCurve->Pole(1).Distance(Bs->Pole(1)) < myTol) {Bs->Reverse();}
Add(Bs, myCurve, Standard_False, WithRatio, MinM);
return Standard_True;
}
return Standard_False;
}
void GeomConvert_CompCurveToBSplineCurve::Add(
Handle(Geom_BSplineCurve)& FirstCurve,
Handle(Geom_BSplineCurve)& SecondCurve,
const Standard_Boolean After,
const Standard_Boolean WithRatio,
const Standard_Integer MinM)
{
// Harmonisation des degres.
Standard_Integer Deg = Max(FirstCurve->Degree(), SecondCurve->Degree());
if (FirstCurve->Degree() < Deg) { FirstCurve->IncreaseDegree(Deg); }
if (SecondCurve->Degree() < Deg) { SecondCurve->IncreaseDegree(Deg); }
// Declarationd
Standard_Real L1, L2, U_de_raccord;
Standard_Integer ii, jj;
Standard_Real Ratio=1, Ratio1, Ratio2, Delta1, Delta2;
Standard_Integer NbP1 = FirstCurve->NbPoles(), NbP2 = SecondCurve->NbPoles();
Standard_Integer NbK1 = FirstCurve->NbKnots(), NbK2 = SecondCurve->NbKnots();
TColStd_Array1OfReal Noeuds (1, NbK1+NbK2-1);
TColgp_Array1OfPnt Poles (1, NbP1+ NbP2-1);
TColStd_Array1OfReal Poids (1, NbP1+ NbP2-1);
TColStd_Array1OfInteger Mults (1, NbK1+NbK2-1);
// Ratio de reparametrisation (C1 si possible)
if (WithRatio) {
L1 = FirstCurve->DN(FirstCurve->LastParameter(), 1).Magnitude();
L2 = SecondCurve->DN(SecondCurve->FirstParameter(), 1). Magnitude();
if ( (L1 > Precision::Confusion()) && (L2 > Precision::Confusion()) ) {
Ratio = L1 / L2;
}
if ( (Ratio < Precision::Confusion()) || (Ratio > 1/Precision::Confusion()) ) {Ratio = 1;}
}
if (After) {
// On ne bouge pas la premiere courbe
Ratio1 = 1;
Delta1 = 0;
Ratio2 = 1/Ratio;
Delta2 = Ratio2*SecondCurve->Knot(1) - FirstCurve->Knot(NbK1);
U_de_raccord = FirstCurve->LastParameter();
}
else {
// On ne bouge pas la seconde courbe
Ratio1 = Ratio;
Delta1 = Ratio1*FirstCurve->Knot(NbK1) - SecondCurve->Knot(1);
Ratio2 = 1;
Delta2 = 0;
U_de_raccord = SecondCurve->FirstParameter();
}
// Les Noeuds
Standard_Real eps;
for (ii=1; ii<NbK1; ii++) {
Noeuds(ii) = Ratio1*FirstCurve->Knot(ii) - Delta1;
if(ii > 1) {
eps = Epsilon (Abs(Noeuds(ii-1)));
if( eps < 5.e-10 ) eps = 5.e-10;
if(Noeuds(ii) - Noeuds(ii-1) <= eps) {
Noeuds(ii) += eps;
}
}
Mults(ii) = FirstCurve->Multiplicity(ii);
}
Noeuds(NbK1) = U_de_raccord;
eps = Epsilon (Abs(Noeuds(NbK1-1)));
if(Noeuds(NbK1) - Noeuds(NbK1-1) <= eps) {
Noeuds(NbK1) += eps;
}
Mults(NbK1) = FirstCurve->Degree();
for (ii=2, jj=NbK1+1; ii<=NbK2; ii++, jj++) {
Noeuds(jj) = Ratio2*SecondCurve->Knot(ii) - Delta2;
eps = Epsilon (Abs(Noeuds(jj-1)));
if( eps < 5.e-10 ) eps = 5.e-10;
if(Noeuds(jj) - Noeuds(jj-1) <= eps) {
Noeuds(jj) += eps;
}
Mults(jj) = SecondCurve->Multiplicity(ii);
}
Ratio = FirstCurve->Weight(NbP1) ;
Ratio /= SecondCurve->Weight(1) ;
// Les Poles et Poids
for (ii=1; ii<NbP1; ii++) {
Poles(ii) = FirstCurve->Pole(ii);
Poids(ii) = FirstCurve->Weight(ii);
}
for (ii=1, jj=NbP1; ii<=NbP2; ii++, jj++) {
Poles(jj) = SecondCurve->Pole(ii);
//
// attentiion les poids ne se raccord pas forcement C0
// d'ou Ratio
//
Poids(jj) = Ratio * SecondCurve->Weight(ii);
}
// Creation de la BSpline
myCurve = new (Geom_BSplineCurve) (Poles, Poids, Noeuds, Mults, Deg);
// Reduction eventuelle de la multiplicite jusqu'a MinM
Standard_Boolean Ok = Standard_True;
Standard_Integer M = Mults(NbK1);
while ( (M>MinM) && Ok) {
M--;
Ok = myCurve->RemoveKnot(NbK1, M, myTol);
}
}
Handle(Geom_BSplineCurve) GeomConvert_CompCurveToBSplineCurve::BSplineCurve() const
{
return myCurve;
}