1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-08 18:40:55 +03:00
occt/src/Geom/Geom_BSplineSurface_1.cxx

2197 lines
65 KiB
C++
Executable File

// File: Geom_BSplineSurface_1.cxx
// Created: Tue Mar 9 19:45:52 1993
// Author: JCV
// <fid@phylox>
// Copyright: Matra Datavision 1993
// File Geom_BSplineSurface.cxx jcv - Juillet 1991
//
// xab : 30-Mar-95 introduced cache mechanism for surfaces
// xab : 21-Jun-95 in remove knots sync size of weights and poles
// pmn : 28-Jun-96 Distinction entre la continuite en U et V (bug PRO4625)
// pmn : 07-Jan-97 Centralisation des verif rational (PRO6834)
// et ajout des InvalideCache() dans les SetPole* (PRO6833)
// pmn : 03-Feb-97 Prise en compte de la periode dans Locate(U/V) (PRO6963)
// + bon appel a LocateParameter (PRO6973).
// RBD : 15/10/98 ; Le cache est desormais defini sur [-1,1] (pro15537).
//
#define No_Standard_OutOfRange
#define No_Standard_DimensionError
#include <Geom_BSplineSurface.jxx>
#include <gp.hxx>
#include <BSplSLib.hxx>
#include <BSplCLib.hxx>
#include <Precision.hxx>
#include <TColgp_Array1OfXYZ.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_UndefinedDerivative.hxx>
#include <Standard_OutOfRange.hxx>
#include <Standard_RangeError.hxx>
#include <Standard_DomainError.hxx>
#include <Standard_DimensionError.hxx>
#include <Standard_ConstructionError.hxx>
#include <Standard_NotImplemented.hxx>
#define POLES (poles->Array2())
#define WEIGHTS (weights->Array2())
#define UKNOTS (uknots->Array1())
#define VKNOTS (vknots->Array1())
#define UFKNOTS (ufknots->Array1())
#define VFKNOTS (vfknots->Array1())
#define FMULTS (BSplCLib::NoMults())
//=======================================================================
//function : IsCNu
//purpose :
//=======================================================================
Standard_Boolean Geom_BSplineSurface::IsCNu
(const Standard_Integer N) const
{
Standard_RangeError_Raise_if (N < 0, " ");
switch (Usmooth) {
case GeomAbs_CN : return Standard_True;
case GeomAbs_C0 : return N <= 0;
case GeomAbs_G1 : return N <= 0;
case GeomAbs_C1 : return N <= 1;
case GeomAbs_G2 : return N <= 1;
case GeomAbs_C2 : return N <= 2;
case GeomAbs_C3 :
return N <= 3 ? Standard_True :
N <= udeg - BSplCLib::MaxKnotMult (umults->Array1(), umults->Lower() + 1, umults->Upper() - 1);
default:
return Standard_False;
}
}
//=======================================================================
//function : IsCNv
//purpose :
//=======================================================================
Standard_Boolean Geom_BSplineSurface::IsCNv
(const Standard_Integer N) const
{
Standard_RangeError_Raise_if (N < 0, " ");
switch (Vsmooth) {
case GeomAbs_CN : return Standard_True;
case GeomAbs_C0 : return N <= 0;
case GeomAbs_G1 : return N <= 0;
case GeomAbs_C1 : return N <= 1;
case GeomAbs_G2 : return N <= 1;
case GeomAbs_C2 : return N <= 2;
case GeomAbs_C3 :
return N <= 3 ? Standard_True :
N <= vdeg - BSplCLib::MaxKnotMult (vmults->Array1(), vmults->Lower() + 1, vmults->Upper() - 1);
default:
return Standard_False;
}
}
//=======================================================================
//function : D0
//purpose :
//=======================================================================
void Geom_BSplineSurface::D0 (const Standard_Real U,
const Standard_Real V,
gp_Pnt& P ) const
{
Standard_Real new_u = U,
new_v = V ;
PeriodicNormalization(new_u,
new_v) ;
if (!IsCacheValid(new_u,
new_v))
{
Geom_BSplineSurface * my_surface = (Geom_BSplineSurface *) this ;
my_surface->ValidateCache(new_u,
new_v) ;
}
Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
uspanlenght_11 = ucachespanlenght/2,
vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
vspanlenght_11 = vcachespanlenght/2 ;
if (cacheweights.IsNull()) {
BSplSLib::CacheD0(new_u,
new_v,
udeg,
vdeg,
uparameter_11,
vparameter_11,
uspanlenght_11,
vspanlenght_11,
cachepoles->Array2(),
*((TColStd_Array2OfReal*) NULL),
P) ;
}
else {
BSplSLib::CacheD0(new_u,
new_v,
udeg,
vdeg,
uparameter_11,
vparameter_11,
uspanlenght_11,
vspanlenght_11,
cachepoles->Array2(),
cacheweights->Array2(),
P) ;
}
}
//=======================================================================
//function : D1
//purpose :
//=======================================================================
void Geom_BSplineSurface::D1 (const Standard_Real U,
const Standard_Real V,
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D1V) const
{
Standard_Real new_u = U,
new_v = V ;
PeriodicNormalization(new_u,
new_v) ;
if (!IsCacheValid(new_u,
new_v))
{
Geom_BSplineSurface * my_surface = (Geom_BSplineSurface *) this ;
my_surface->ValidateCache(new_u,
new_v) ;
}
Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
uspanlenght_11 = ucachespanlenght/2,
vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
vspanlenght_11 = vcachespanlenght/2 ;
if (cacheweights.IsNull()) {
BSplSLib::CacheD1(new_u,
new_v,
udeg,
vdeg,
uparameter_11,
vparameter_11,
uspanlenght_11,
vspanlenght_11,
cachepoles->Array2(),
*((TColStd_Array2OfReal*) NULL),
P,
D1U,
D1V) ;
}
else {
BSplSLib::CacheD1(new_u,
new_v,
udeg,
vdeg,
uparameter_11,
vparameter_11,
uspanlenght_11,
vspanlenght_11,
cachepoles->Array2(),
cacheweights->Array2(),
P,
D1U,
D1V) ;
}
}
//=======================================================================
//function : D2
//purpose :
//=======================================================================
void Geom_BSplineSurface::D2 (const Standard_Real U,
const Standard_Real V,
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D1V,
gp_Vec& D2U,
gp_Vec& D2V,
gp_Vec& D2UV) const
{
Standard_Real new_u = U,
new_v = V ;
PeriodicNormalization(new_u,
new_v) ;
if (!IsCacheValid(new_u,
new_v))
{
Geom_BSplineSurface * my_surface = (Geom_BSplineSurface *) this ;
my_surface->ValidateCache(new_u,
new_v) ;
}
Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
uspanlenght_11 = ucachespanlenght/2,
vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
vspanlenght_11 = vcachespanlenght/2 ;
if (cacheweights.IsNull()) {
BSplSLib::CacheD2(new_u,
new_v,
udeg,
vdeg,
uparameter_11,
vparameter_11,
uspanlenght_11,
vspanlenght_11,
cachepoles->Array2(),
*((TColStd_Array2OfReal*) NULL),
P,
D1U,
D1V,
D2U,
D2UV,
D2V);
}
else {
BSplSLib::CacheD2(new_u,
new_v,
udeg,
vdeg,
uparameter_11,
vparameter_11,
uspanlenght_11,
vspanlenght_11,
cachepoles->Array2(),
cacheweights->Array2(),
P,
D1U,
D1V,
D2U,
D2UV,
D2V);
}
}
//=======================================================================
//function : D3
//purpose :
//=======================================================================
void Geom_BSplineSurface::D3 (const Standard_Real U,
const Standard_Real V,
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D1V,
gp_Vec& D2U,
gp_Vec& D2V,
gp_Vec& D2UV,
gp_Vec& D3U,
gp_Vec& D3V,
gp_Vec& D3UUV,
gp_Vec& D3UVV) const
{
BSplSLib::D3(U,V,0,0,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
udeg,vdeg,urational,vrational,uperiodic,vperiodic,
P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
}
//=======================================================================
//function : DN
//purpose :
//=======================================================================
gp_Vec Geom_BSplineSurface::DN (const Standard_Real U,
const Standard_Real V,
const Standard_Integer Nu,
const Standard_Integer Nv ) const
{
gp_Vec Vn;
BSplSLib::DN(U,V,Nu,Nv,0,0,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
udeg,vdeg,urational,vrational,uperiodic,vperiodic,
Vn);
return Vn;
}
//=======================================================================
//function : LocalValue
//purpose :
//=======================================================================
gp_Pnt Geom_BSplineSurface::LocalValue (const Standard_Real U,
const Standard_Real V,
const Standard_Integer FromUK1,
const Standard_Integer ToUK2,
const Standard_Integer FromVK1,
const Standard_Integer ToVK2) const
{
gp_Pnt P;
LocalD0(U,V,FromUK1,ToUK2,FromVK1,ToVK2,P);
return P;
}
//=======================================================================
//function : LocalD0
//purpose :
//=======================================================================
void Geom_BSplineSurface::LocalD0 (const Standard_Real U,
const Standard_Real V,
const Standard_Integer FromUK1,
const Standard_Integer ToUK2,
const Standard_Integer FromVK1,
const Standard_Integer ToVK2,
gp_Pnt& P ) const
{
Standard_DomainError_Raise_if (FromUK1 == ToUK2 || FromVK1 == ToVK2,
"Geom_BSplineSurface::LocalD0");
Standard_Real u = U, v = V;
Standard_Integer uindex = 0, vindex = 0;
BSplCLib::LocateParameter(udeg, UFKNOTS, U, uperiodic,FromUK1,ToUK2,
uindex,u);
uindex = BSplCLib::FlatIndex(udeg,uindex,umults->Array1(),uperiodic);
BSplCLib::LocateParameter(vdeg, VFKNOTS, V, vperiodic,FromVK1,ToVK2,
vindex,v);
vindex = BSplCLib::FlatIndex(vdeg,vindex,vmults->Array1(),vperiodic);
// BSplSLib::D0(U,V,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
BSplSLib::D0(u,v,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
udeg,vdeg,urational,vrational,uperiodic,vperiodic,
P);
}
//=======================================================================
//function : LocalD1
//purpose :
//=======================================================================
void Geom_BSplineSurface::LocalD1 (const Standard_Real U,
const Standard_Real V,
const Standard_Integer FromUK1,
const Standard_Integer ToUK2,
const Standard_Integer FromVK1,
const Standard_Integer ToVK2,
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D1V) const
{
Standard_DomainError_Raise_if (FromUK1 == ToUK2 || FromVK1 == ToVK2,
"Geom_BSplineSurface::LocalD1");
Standard_Real u = U, v = V;
Standard_Integer uindex = 0, vindex = 0;
BSplCLib::LocateParameter(udeg, UFKNOTS, U, uperiodic,FromUK1,ToUK2,
uindex,u);
uindex = BSplCLib::FlatIndex(udeg,uindex,umults->Array1(),uperiodic);
BSplCLib::LocateParameter(vdeg, VFKNOTS, V, vperiodic,FromVK1,ToVK2,
vindex,v);
vindex = BSplCLib::FlatIndex(vdeg,vindex,vmults->Array1(),vperiodic);
BSplSLib::D1(u,v,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
udeg,vdeg,urational,vrational,uperiodic,vperiodic,
P,D1U,D1V);
}
//=======================================================================
//function : LocalD2
//purpose :
//=======================================================================
void Geom_BSplineSurface::LocalD2 (const Standard_Real U,
const Standard_Real V,
const Standard_Integer FromUK1,
const Standard_Integer ToUK2,
const Standard_Integer FromVK1,
const Standard_Integer ToVK2,
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D1V,
gp_Vec& D2U,
gp_Vec& D2V,
gp_Vec& D2UV) const
{
Standard_DomainError_Raise_if (FromUK1 == ToUK2 || FromVK1 == ToVK2,
"Geom_BSplineSurface::LocalD2");
Standard_Real u = U, v = V;
Standard_Integer uindex = 0, vindex = 0;
BSplCLib::LocateParameter(udeg, UFKNOTS, U, uperiodic,FromUK1,ToUK2,
uindex,u);
uindex = BSplCLib::FlatIndex(udeg,uindex,umults->Array1(),uperiodic);
BSplCLib::LocateParameter(vdeg, VFKNOTS, V, vperiodic,FromVK1,ToVK2,
vindex,v);
vindex = BSplCLib::FlatIndex(vdeg,vindex,vmults->Array1(),vperiodic);
BSplSLib::D2(u,v,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
udeg,vdeg,urational,vrational,uperiodic,vperiodic,
P,D1U,D1V,D2U,D2V,D2UV);
}
//=======================================================================
//function : LocalD3
//purpose :
//=======================================================================
void Geom_BSplineSurface::LocalD3 (const Standard_Real U,
const Standard_Real V,
const Standard_Integer FromUK1,
const Standard_Integer ToUK2,
const Standard_Integer FromVK1,
const Standard_Integer ToVK2,
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D1V,
gp_Vec& D2U,
gp_Vec& D2V,
gp_Vec& D2UV,
gp_Vec& D3U,
gp_Vec& D3V,
gp_Vec& D3UUV,
gp_Vec& D3UVV) const
{
Standard_DomainError_Raise_if (FromUK1 == ToUK2 || FromVK1 == ToVK2,
"Geom_BSplineSurface::LocalD3");
Standard_Real u = U, v = V;
Standard_Integer uindex = 0, vindex = 0;
BSplCLib::LocateParameter(udeg, UFKNOTS, U, uperiodic,FromUK1,ToUK2,
uindex,u);
uindex = BSplCLib::FlatIndex(udeg,uindex,umults->Array1(),uperiodic);
BSplCLib::LocateParameter(vdeg, VFKNOTS, V, vperiodic,FromVK1,ToVK2,
vindex,v);
vindex = BSplCLib::FlatIndex(vdeg,vindex,vmults->Array1(),vperiodic);
BSplSLib::D3(u,v,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
udeg,vdeg,urational,vrational,uperiodic,vperiodic,
P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
}
//=======================================================================
//function : LocalDN
//purpose :
//=======================================================================
gp_Vec Geom_BSplineSurface::LocalDN (const Standard_Real U,
const Standard_Real V,
const Standard_Integer FromUK1,
const Standard_Integer ToUK2,
const Standard_Integer FromVK1,
const Standard_Integer ToVK2,
const Standard_Integer Nu,
const Standard_Integer Nv) const
{
Standard_DomainError_Raise_if (FromUK1 == ToUK2 || FromVK1 == ToVK2,
"Geom_BSplineSurface::LocalDN");
Standard_Real u = U, v = V;
Standard_Integer uindex = 0, vindex = 0;
BSplCLib::LocateParameter(udeg, UFKNOTS, U, uperiodic,FromUK1,ToUK2,
uindex,u);
uindex = BSplCLib::FlatIndex(udeg,uindex,umults->Array1(),uperiodic);
BSplCLib::LocateParameter(vdeg, VFKNOTS, V, vperiodic,FromVK1,ToVK2,
vindex,v);
vindex = BSplCLib::FlatIndex(vdeg,vindex,vmults->Array1(),vperiodic);
gp_Vec Vn;
BSplSLib::DN(u,v,Nu,Nv,uindex,vindex,
POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
udeg,vdeg,urational,vrational,uperiodic,vperiodic,
Vn);
return Vn;
}
//=======================================================================
//function : Pole
//purpose :
//=======================================================================
gp_Pnt Geom_BSplineSurface::Pole (const Standard_Integer UIndex,
const Standard_Integer VIndex) const
{
Standard_OutOfRange_Raise_if
(UIndex < 1 || UIndex > poles->ColLength() ||
VIndex < 1 || VIndex > poles->RowLength(), " ");
return poles->Value (UIndex, VIndex);
}
//=======================================================================
//function : Poles
//purpose :
//=======================================================================
void Geom_BSplineSurface::Poles (TColgp_Array2OfPnt& P) const
{
Standard_DimensionError_Raise_if
(P.ColLength() != poles->ColLength() ||
P.RowLength() != poles->RowLength(), " ");
P = poles->Array2();
}
//=======================================================================
//function : UIso
//purpose :
//=======================================================================
Handle(Geom_Curve) Geom_BSplineSurface::UIso (const Standard_Real U) const
{
TColgp_Array1OfPnt cpoles(1,poles->RowLength());
TColStd_Array1OfReal cweights(1,poles->RowLength());
Handle(Geom_BSplineCurve) C;
if ( urational || vrational) {
BSplSLib::Iso(U,Standard_True,POLES,WEIGHTS,UFKNOTS,FMULTS,udeg,uperiodic,
cpoles,cweights);
C = new Geom_BSplineCurve(cpoles,cweights,
vknots->Array1(),
vmults->Array1(),
vdeg,vperiodic);
}
else {
BSplSLib::Iso(U,Standard_True,POLES,
*((TColStd_Array2OfReal*) NULL),
UFKNOTS,FMULTS,udeg,uperiodic,
cpoles,cweights);
C = new Geom_BSplineCurve(cpoles,
vknots->Array1(),
vmults->Array1(),
vdeg,vperiodic);
}
return C;
}
//=======================================================================
//function : UIso
//purpose : If CheckRational=False, no try to make it non-rational
//=======================================================================
Handle(Geom_Curve) Geom_BSplineSurface::UIso (const Standard_Real U,
const Standard_Boolean CheckRational) const
{
TColgp_Array1OfPnt cpoles(1,poles->RowLength());
TColStd_Array1OfReal cweights(1,poles->RowLength());
Handle(Geom_BSplineCurve) C;
if ( urational || vrational) {
BSplSLib::Iso(U,Standard_True,POLES,WEIGHTS,UFKNOTS,FMULTS,udeg,uperiodic,
cpoles,cweights);
C = new Geom_BSplineCurve(cpoles,cweights,
vknots->Array1(),
vmults->Array1(),
vdeg,vperiodic,
CheckRational);
}
else {
BSplSLib::Iso(U,Standard_True,POLES,
*((TColStd_Array2OfReal*) NULL),
UFKNOTS,FMULTS,udeg,uperiodic,
cpoles,cweights);
C = new Geom_BSplineCurve(cpoles,
vknots->Array1(),
vmults->Array1(),
vdeg,vperiodic);
}
return C;
}
//=======================================================================
//function : UKnot
//purpose :
//=======================================================================
Standard_Real Geom_BSplineSurface::UKnot(const Standard_Integer UIndex) const
{
Standard_OutOfRange_Raise_if (UIndex < 1 || UIndex > uknots->Length(), " ");
return uknots->Value (UIndex);
}
//=======================================================================
//function : VKnot
//purpose :
//=======================================================================
Standard_Real Geom_BSplineSurface::VKnot(const Standard_Integer VIndex) const
{
Standard_OutOfRange_Raise_if (VIndex < 1 || VIndex > vknots->Length(), " ");
return vknots->Value (VIndex);
}
//=======================================================================
//function : UKnots
//purpose :
//=======================================================================
void Geom_BSplineSurface::UKnots (TColStd_Array1OfReal& Ku) const
{
Standard_DimensionError_Raise_if (Ku.Length() != uknots->Length(), " ");
Ku = uknots->Array1();
}
//=======================================================================
//function : VKnots
//purpose :
//=======================================================================
void Geom_BSplineSurface::VKnots (TColStd_Array1OfReal& Kv) const
{
Standard_DimensionError_Raise_if (Kv.Length() != vknots->Length(), " ");
Kv = vknots->Array1();
}
//=======================================================================
//function : UKnotSequence
//purpose :
//=======================================================================
void Geom_BSplineSurface::UKnotSequence (TColStd_Array1OfReal& Ku) const
{
Standard_DimensionError_Raise_if (Ku.Length() != ufknots->Length(), " ");
Ku = ufknots->Array1();
}
//=======================================================================
//function : VKnotSequence
//purpose :
//=======================================================================
void Geom_BSplineSurface::VKnotSequence (TColStd_Array1OfReal& Kv) const
{
Standard_DimensionError_Raise_if (Kv.Length() != vfknots->Length(), " ");
Kv = vfknots->Array1();
}
//=======================================================================
//function : UMultiplicity
//purpose :
//=======================================================================
Standard_Integer Geom_BSplineSurface::UMultiplicity
(const Standard_Integer UIndex) const
{
Standard_OutOfRange_Raise_if (UIndex < 1 || UIndex > umults->Length()," ");
return umults->Value (UIndex);
}
//=======================================================================
//function : UMultiplicities
//purpose :
//=======================================================================
void Geom_BSplineSurface::UMultiplicities (TColStd_Array1OfInteger& Mu) const
{
Standard_DimensionError_Raise_if (Mu.Length() != umults->Length(), " ");
Mu = umults->Array1();
}
//=======================================================================
//function : VIso
//purpose :
//=======================================================================
Handle(Geom_Curve) Geom_BSplineSurface::VIso (const Standard_Real V) const
{
TColgp_Array1OfPnt cpoles(1,poles->ColLength());
TColStd_Array1OfReal cweights(1,poles->ColLength());
Handle(Geom_BSplineCurve) C;
if ( urational || vrational) {
BSplSLib::Iso(V,Standard_False,POLES,
WEIGHTS,
VFKNOTS,FMULTS,vdeg,vperiodic,
cpoles,cweights);
C = new Geom_BSplineCurve(cpoles,cweights,
uknots->Array1(),
umults->Array1(),
udeg,uperiodic);
}
else {
BSplSLib::Iso(V,Standard_False,POLES,
*((TColStd_Array2OfReal*) NULL),
VFKNOTS,FMULTS,vdeg,vperiodic,
cpoles,cweights);
C = new Geom_BSplineCurve(cpoles,
uknots->Array1(),
umults->Array1(),
udeg,uperiodic);
}
return C;
}
//=======================================================================
//function : VIso
//purpose : If CheckRational=False, no try to make it non-rational
//=======================================================================
Handle(Geom_Curve) Geom_BSplineSurface::VIso (const Standard_Real V,
const Standard_Boolean CheckRational) const
{
TColgp_Array1OfPnt cpoles(1,poles->ColLength());
TColStd_Array1OfReal cweights(1,poles->ColLength());
Handle(Geom_BSplineCurve) C;
if ( urational || vrational) {
BSplSLib::Iso(V,Standard_False,POLES,
WEIGHTS,
VFKNOTS,FMULTS,vdeg,vperiodic,
cpoles,cweights);
C = new Geom_BSplineCurve(cpoles,cweights,
uknots->Array1(),
umults->Array1(),
udeg,uperiodic,
CheckRational);
}
else {
BSplSLib::Iso(V,Standard_False,POLES,
*((TColStd_Array2OfReal*) NULL),
VFKNOTS,FMULTS,vdeg,vperiodic,
cpoles,cweights);
C = new Geom_BSplineCurve(cpoles,
uknots->Array1(),
umults->Array1(),
udeg,uperiodic);
}
return C;
}
//=======================================================================
//function : VMultiplicity
//purpose :
//=======================================================================
Standard_Integer Geom_BSplineSurface::VMultiplicity
(const Standard_Integer VIndex) const
{
Standard_OutOfRange_Raise_if (VIndex < 1 || VIndex > vmults->Length()," ");
return vmults->Value (VIndex);
}
//=======================================================================
//function : VMultiplicities
//purpose :
//=======================================================================
void Geom_BSplineSurface::VMultiplicities (TColStd_Array1OfInteger& Mv) const
{
Standard_DimensionError_Raise_if (Mv.Length() != vmults->Length(), " ");
Mv = vmults->Array1();
}
//=======================================================================
//function : Weight
//purpose :
//=======================================================================
Standard_Real Geom_BSplineSurface::Weight
(const Standard_Integer UIndex,
const Standard_Integer VIndex ) const
{
Standard_OutOfRange_Raise_if
(UIndex < 1 || UIndex > weights->ColLength() ||
VIndex < 1 || VIndex > weights->RowLength(), " ");
return weights->Value (UIndex, VIndex);
}
//=======================================================================
//function : Weights
//purpose :
//=======================================================================
void Geom_BSplineSurface::Weights (TColStd_Array2OfReal& W) const
{
Standard_DimensionError_Raise_if
(W.ColLength() != weights->ColLength() ||
W.RowLength() != weights->RowLength(), " ");
W = weights->Array2();
}
//=======================================================================
//function : Transform
//purpose :
//=======================================================================
void Geom_BSplineSurface::Transform (const gp_Trsf& T)
{
TColgp_Array2OfPnt & VPoles = poles->ChangeArray2();
for (Standard_Integer j = VPoles.LowerCol(); j <= VPoles.UpperCol(); j++) {
for (Standard_Integer i = VPoles.LowerRow(); i <= VPoles.UpperRow(); i++) {
VPoles (i, j).Transform (T);
}
}
InvalidateCache();
}
//=======================================================================
//function : SetUPeriodic
//purpose :
//=======================================================================
void Geom_BSplineSurface::SetUPeriodic ()
{
Standard_Integer i,j;
Standard_Integer first = FirstUKnotIndex();
Standard_Integer last = LastUKnotIndex();
Handle(TColStd_HArray1OfReal) tk = uknots;
TColStd_Array1OfReal cknots((uknots->Array1())(first),first,last);
uknots = new TColStd_HArray1OfReal(1,cknots.Length());
uknots->ChangeArray1() = cknots;
Handle(TColStd_HArray1OfInteger) tm = umults;
TColStd_Array1OfInteger cmults((umults->Array1())(first),first,last);
// Modified by Sergey KHROMOV - Mon Feb 10 10:59:00 2003 Begin
// cmults(first) = cmults(last) = Max( cmults(first), cmults(last));
cmults(first) = cmults(last) = Min(udeg, Max( cmults(first), cmults(last)));
// Modified by Sergey KHROMOV - Mon Feb 10 10:59:00 2003 End
umults = new TColStd_HArray1OfInteger(1,cmults.Length());
umults->ChangeArray1() = cmults;
// compute new number of poles;
Standard_Integer nbp = BSplCLib::NbPoles(udeg,Standard_True,cmults);
TColgp_Array2OfPnt cpoles(1,nbp,poles->LowerCol(),poles->UpperCol());
for (i = 1; i <= nbp; i++) {
for (j = poles->LowerCol(); j <= poles->UpperCol(); j++) {
cpoles(i,j) = poles->Value(i,j);
}
}
poles =
new TColgp_HArray2OfPnt(1,nbp,cpoles.LowerCol(),cpoles.UpperCol());
poles->ChangeArray2() = cpoles;
TColStd_Array2OfReal
cweights(1,nbp,weights->LowerCol(),weights->UpperCol());
if (urational || vrational) {
for (i = 1; i <= nbp; i++) {
for (j = weights->LowerCol(); j <= weights->UpperCol(); j++) {
cweights(i,j) = weights->Value(i,j);
}
}
}
else {
for (i = 1; i <= nbp; i++) {
for (j = weights->LowerCol(); j <= weights->UpperCol(); j++) {
cweights(i,j) = 1;
}
}
}
weights = new
TColStd_HArray2OfReal(1,nbp,cweights.LowerCol(),cweights.UpperCol());
weights->ChangeArray2() = cweights;
uperiodic = Standard_True;
maxderivinvok = 0;
UpdateUKnots();
}
//=======================================================================
//function : SetVPeriodic
//purpose :
//=======================================================================
void Geom_BSplineSurface::SetVPeriodic ()
{
Standard_Integer i,j;
Standard_Integer first = FirstVKnotIndex();
Standard_Integer last = LastVKnotIndex();
Handle(TColStd_HArray1OfReal) tk = vknots;
TColStd_Array1OfReal cknots((vknots->Array1())(first),first,last);
vknots = new TColStd_HArray1OfReal(1,cknots.Length());
vknots->ChangeArray1() = cknots;
Handle(TColStd_HArray1OfInteger) tm = vmults;
TColStd_Array1OfInteger cmults((vmults->Array1())(first),first,last);
// Modified by Sergey KHROMOV - Mon Feb 10 11:00:33 2003 Begin
// cmults(first) = cmults(last) = Max( cmults(first), cmults(last));
cmults(first) = cmults(last) = Min(vdeg, Max( cmults(first), cmults(last)));
// Modified by Sergey KHROMOV - Mon Feb 10 11:00:34 2003 End
vmults = new TColStd_HArray1OfInteger(1,cmults.Length());
vmults->ChangeArray1() = cmults;
// compute new number of poles;
Standard_Integer nbp = BSplCLib::NbPoles(vdeg,Standard_True,cmults);
TColgp_Array2OfPnt cpoles(poles->LowerRow(),poles->UpperRow(),1,nbp);
for (i = poles->LowerRow(); i <= poles->UpperRow(); i++) {
for (j = 1; j <= nbp; j++) {
cpoles(i,j) = poles->Value(i,j);
}
}
poles =
new TColgp_HArray2OfPnt(cpoles.LowerRow(),cpoles.UpperRow(),1,nbp);
poles->ChangeArray2() = cpoles;
if (urational || vrational) {
TColStd_Array2OfReal
cweights(weights->LowerRow(),weights->UpperRow(),1,nbp);
for (i = weights->LowerRow(); i <= weights->UpperRow(); i++) {
for (j = 1; j <= nbp; j++) {
cweights(i,j) = weights->Value(i,j);
}
}
weights = new
TColStd_HArray2OfReal(cweights.LowerRow(),cweights.UpperRow(),1,nbp);
weights->ChangeArray2() = cweights;
}
vperiodic = Standard_True;
maxderivinvok = 0;
UpdateVKnots();
}
//=======================================================================
//function : SetUOrigin
//purpose :
//=======================================================================
void Geom_BSplineSurface::SetUOrigin(const Standard_Integer Index)
{
Standard_NoSuchObject_Raise_if( !uperiodic,
"Geom_BSplineSurface::SetUOrigin");
Standard_Integer i,j,k;
Standard_Integer first = FirstUKnotIndex();
Standard_Integer last = LastUKnotIndex();
Standard_DomainError_Raise_if( (Index < first) || (Index > last),
"Geom_BSplineCurve::SetUOrigine");
Standard_Integer nbknots = uknots->Length();
Standard_Integer nbpoles = poles->ColLength();
Handle(TColStd_HArray1OfReal) nknots =
new TColStd_HArray1OfReal(1,nbknots);
TColStd_Array1OfReal& newknots = nknots->ChangeArray1();
Handle(TColStd_HArray1OfInteger) nmults =
new TColStd_HArray1OfInteger(1,nbknots);
TColStd_Array1OfInteger& newmults = nmults->ChangeArray1();
// set the knots and mults
Standard_Real period = uknots->Value(last) - uknots->Value(first);
k = 1;
for ( i = Index; i <= last ; i++) {
newknots(k) = uknots->Value(i);
newmults(k) = umults->Value(i);
k++;
}
for ( i = first+1; i <= Index; i++) {
newknots(k) = uknots->Value(i) + period;
newmults(k) = umults->Value(i);
k++;
}
Standard_Integer index = 1;
for (i = first+1; i <= Index; i++)
index += umults->Value(i);
// set the poles and weights
Standard_Integer nbvp = poles->RowLength();
Handle(TColgp_HArray2OfPnt) npoles =
new TColgp_HArray2OfPnt(1,nbpoles,1,nbvp);
Handle(TColStd_HArray2OfReal) nweights =
new TColStd_HArray2OfReal(1,nbpoles,1,nbvp);
TColgp_Array2OfPnt & newpoles = npoles->ChangeArray2();
TColStd_Array2OfReal & newweights = nweights->ChangeArray2();
first = poles->LowerRow();
last = poles->UpperRow();
if ( urational || vrational) {
k = 1;
for ( i = index; i <= last; i++) {
for ( j = 1; j <= nbvp; j++) {
newpoles(k,j) = poles->Value(i,j);
newweights(k,j) = weights->Value(i,j);
}
k++;
}
for ( i = first; i < index; i++) {
for ( j = 1; j <= nbvp; j++) {
newpoles(k,j) = poles->Value(i,j);
newweights(k,j) = weights->Value(i,j);
}
k++;
}
}
else {
k = 1;
for ( i = index; i <= last; i++) {
for ( j = 1; j <= nbvp; j++) {
newpoles(k,j) = poles->Value(i,j);
}
k++;
}
for ( i = first; i < index; i++) {
for ( j = 1; j <= nbvp; j++) {
newpoles(k,j) = poles->Value(i,j);
}
k++;
}
}
poles = npoles;
uknots = nknots;
umults = nmults;
if (urational || vrational)
weights = nweights;
UpdateUKnots();
}
//=======================================================================
//function : SetVOrigin
//purpose :
//=======================================================================
void Geom_BSplineSurface::SetVOrigin(const Standard_Integer Index)
{
Standard_NoSuchObject_Raise_if( !vperiodic,
"Geom_BSplineSurface::SetVOrigin");
Standard_Integer i,j,k;
Standard_Integer first = FirstVKnotIndex();
Standard_Integer last = LastVKnotIndex();
Standard_DomainError_Raise_if( (Index < first) || (Index > last),
"Geom_BSplineCurve::SetVOrigine");
Standard_Integer nbknots = vknots->Length();
Standard_Integer nbpoles = poles->RowLength();
Handle(TColStd_HArray1OfReal) nknots =
new TColStd_HArray1OfReal(1,nbknots);
TColStd_Array1OfReal& newknots = nknots->ChangeArray1();
Handle(TColStd_HArray1OfInteger) nmults =
new TColStd_HArray1OfInteger(1,nbknots);
TColStd_Array1OfInteger& newmults = nmults->ChangeArray1();
// set the knots and mults
Standard_Real period = vknots->Value(last) - vknots->Value(first);
k = 1;
for ( i = Index; i <= last ; i++) {
newknots(k) = vknots->Value(i);
newmults(k) = vmults->Value(i);
k++;
}
for ( i = first+1; i <= Index; i++) {
newknots(k) = vknots->Value(i) + period;
newmults(k) = vmults->Value(i);
k++;
}
Standard_Integer index = 1;
for (i = first+1; i <= Index; i++)
index += vmults->Value(i);
// set the poles and weights
Standard_Integer nbup = poles->ColLength();
Handle(TColgp_HArray2OfPnt) npoles =
new TColgp_HArray2OfPnt(1,nbup,1,nbpoles);
Handle(TColStd_HArray2OfReal) nweights =
new TColStd_HArray2OfReal(1,nbup,1,nbpoles);
TColgp_Array2OfPnt & newpoles = npoles->ChangeArray2();
TColStd_Array2OfReal & newweights = nweights->ChangeArray2();
first = poles->LowerCol();
last = poles->UpperCol();
if ( urational || vrational) {
k = 1;
for ( j = index; j <= last; j++) {
for ( i = 1; i <= nbup; i++) {
newpoles(i,k) = poles->Value(i,j);
newweights(i,k) = weights->Value(i,j);
}
k++;
}
for ( j = first; j < index; j++) {
for ( i = 1; i <= nbup; i++) {
newpoles(i,k) = poles->Value(i,j);
newweights(i,k) = weights->Value(i,j);
}
k++;
}
}
else {
k = 1;
for ( j = index; j <= last; j++) {
for ( i = 1; i <= nbup; i++) {
newpoles(i,k) = poles->Value(i,j);
}
k++;
}
for ( j = first; j < index; j++) {
for ( i = 1; i <= nbup; i++) {
newpoles(i,k) = poles->Value(i,j);
}
k++;
}
}
poles = npoles;
vknots = nknots;
vmults = nmults;
if (urational || vrational)
weights = nweights;
UpdateVKnots();
}
//=======================================================================
//function : SetUNotPeriodic
//purpose :
//=======================================================================
void Geom_BSplineSurface::SetUNotPeriodic ()
{
if ( uperiodic) {
Standard_Integer NbKnots, NbPoles;
BSplCLib::PrepareUnperiodize( udeg, umults->Array1(), NbKnots, NbPoles);
Handle(TColgp_HArray2OfPnt) npoles =
new TColgp_HArray2OfPnt(1,NbPoles, 1, poles->RowLength());
Handle(TColStd_HArray1OfReal) nknots
= new TColStd_HArray1OfReal(1,NbKnots);
Handle(TColStd_HArray1OfInteger) nmults
= new TColStd_HArray1OfInteger(1,NbKnots);
Handle(TColStd_HArray2OfReal) nweights = new TColStd_HArray2OfReal(1,NbPoles, 1, poles->RowLength(), 0);
if ( urational || vrational) {
BSplSLib::Unperiodize(Standard_True , udeg,
umults->Array1() , uknots->Array1(),
poles->Array2() , weights->Array2(),
nmults->ChangeArray1(), nknots->ChangeArray1(),
npoles->ChangeArray2(),
nweights->ChangeArray2());
}
else {
BSplSLib::Unperiodize(Standard_True , udeg,
umults->Array1() , uknots->Array1(),
poles->Array2() , BSplSLib::NoWeights(),
nmults->ChangeArray1(), nknots->ChangeArray1(),
npoles->ChangeArray2(),
*((TColStd_Array2OfReal*) NULL));
}
poles = npoles;
weights = nweights;
umults = nmults;
uknots = nknots;
uperiodic = Standard_False;
maxderivinvok = 0;
UpdateUKnots();
}
}
//=======================================================================
//function : SetVNotPeriodic
//purpose :
//=======================================================================
void Geom_BSplineSurface::SetVNotPeriodic ()
{
if ( vperiodic) {
Standard_Integer NbKnots, NbPoles;
BSplCLib::PrepareUnperiodize( vdeg, vmults->Array1(), NbKnots, NbPoles);
Handle(TColgp_HArray2OfPnt) npoles =
new TColgp_HArray2OfPnt(1, poles->ColLength(), 1, NbPoles);
Handle(TColStd_HArray1OfReal) nknots
= new TColStd_HArray1OfReal(1,NbKnots);
Handle(TColStd_HArray1OfInteger) nmults
= new TColStd_HArray1OfInteger(1,NbKnots) ;
Handle(TColStd_HArray2OfReal) nweights = new TColStd_HArray2OfReal(1, poles->ColLength(), 1, NbPoles, 0);
if ( urational || vrational) {
BSplSLib::Unperiodize(Standard_False , vdeg,
vmults->Array1() , vknots->Array1(),
poles->Array2() , weights->Array2(),
nmults->ChangeArray1(), nknots->ChangeArray1(),
npoles->ChangeArray2(),
nweights->ChangeArray2());
}
else {
BSplSLib::Unperiodize(Standard_False , vdeg,
vmults->Array1() , vknots->Array1(),
poles->Array2() , BSplSLib::NoWeights(),
nmults->ChangeArray1(), nknots->ChangeArray1(),
npoles->ChangeArray2(),
*((TColStd_Array2OfReal*) NULL));
}
poles = npoles;
weights = nweights;
vmults = nmults;
vknots = nknots;
vperiodic = Standard_False;
maxderivinvok = 0;
UpdateVKnots();
}
}
//=======================================================================
//function : IsUClosed
//purpose :
//=======================================================================
Standard_Boolean Geom_BSplineSurface::IsUClosed () const
{
if (uperiodic)
return Standard_True;
Standard_Boolean Closed = Standard_True;
TColgp_Array2OfPnt & VPoles = poles->ChangeArray2();
Standard_Integer PLower = VPoles.LowerRow();
Standard_Integer PUpper = VPoles.UpperRow();
Standard_Integer PLength = VPoles.RowLength();
Standard_Integer j = VPoles.LowerCol();
if ( urational || vrational) {
TColStd_Array2OfReal & VWeights = weights->ChangeArray2();
Standard_Integer WLower = VWeights.LowerRow();
Standard_Integer WUpper = VWeights.UpperRow();
Standard_Real Alfa = VWeights(WLower,VWeights.LowerCol());
Alfa /= VWeights(WUpper,VWeights.LowerCol());
Standard_Integer k = VWeights.LowerCol();
while (Closed && j <= PLength) {
Closed =
(VPoles (PLower, j).Distance (VPoles (PUpper, j)) <= Precision::Confusion());
j++;
Closed = (Closed &&
((VWeights(WLower,k) / VWeights(WUpper,k)) - Alfa)
< Epsilon(Alfa));
k++;
}
}
else {
while (Closed && j <= PLength) {
Closed =
(VPoles (PLower, j).Distance (VPoles (PUpper, j)) <= Precision::Confusion());
j++;
}
}
return Closed;
}
//=======================================================================
//function : IsVClosed
//purpose :
//=======================================================================
Standard_Boolean Geom_BSplineSurface::IsVClosed () const
{
if (vperiodic)
return Standard_True;
Standard_Boolean Closed = Standard_True;
TColgp_Array2OfPnt & VPoles = poles->ChangeArray2();
Standard_Integer PLower = VPoles.LowerCol();
Standard_Integer PUpper = VPoles.UpperCol();
Standard_Integer PLength = VPoles.ColLength();
Standard_Integer i = VPoles.LowerRow();
if ( urational || vrational) {
TColStd_Array2OfReal & VWeights = weights->ChangeArray2();
Standard_Integer WLower = VWeights.LowerCol();
Standard_Integer WUpper = VWeights.UpperCol();
Standard_Real Alfa = VWeights(VWeights.LowerRow(),WLower);
Alfa /= VWeights(VWeights.LowerRow(),WUpper);
Standard_Integer k = VWeights.LowerRow();
while (Closed && i <= PLength) {
Closed =
(VPoles (i, PLower).Distance (VPoles (i, PUpper)) <= Precision::Confusion());
i++;
Closed = (Closed &&
((VWeights(k,WLower) / VWeights(k,WUpper)) - Alfa)
< Epsilon(Alfa));
k++;
}
}
else {
while (Closed && i <= PLength) {
Closed =
(VPoles (i, PLower).Distance (VPoles (i, PUpper)) <= Precision::Confusion());
i++;
}
}
return Closed;
}
//=======================================================================
//function : IsUPeriodic
//purpose :
//=======================================================================
Standard_Boolean Geom_BSplineSurface::IsUPeriodic () const
{
return uperiodic;
}
//=======================================================================
//function : IsVPeriodic
//purpose :
//=======================================================================
Standard_Boolean Geom_BSplineSurface::IsVPeriodic () const
{
return vperiodic;
}
//=======================================================================
//function : FirstUKnotIndex
//purpose :
//=======================================================================
Standard_Integer Geom_BSplineSurface::FirstUKnotIndex () const
{
if (uperiodic) return 1;
else return BSplCLib::FirstUKnotIndex(udeg,umults->Array1());
}
//=======================================================================
//function : FirstVKnotIndex
//purpose :
//=======================================================================
Standard_Integer Geom_BSplineSurface::FirstVKnotIndex () const
{
if (vperiodic) return 1;
else return BSplCLib::FirstUKnotIndex(vdeg,vmults->Array1());
}
//=======================================================================
//function : LastUKnotIndex
//purpose :
//=======================================================================
Standard_Integer Geom_BSplineSurface::LastUKnotIndex() const
{
if (uperiodic) return uknots->Length();
else return BSplCLib::LastUKnotIndex(udeg,umults->Array1());
}
//=======================================================================
//function : LastVKnotIndex
//purpose :
//=======================================================================
Standard_Integer Geom_BSplineSurface::LastVKnotIndex() const
{
if (vperiodic) return vknots->Length();
else return BSplCLib::LastUKnotIndex(vdeg,vmults->Array1());
}
//=======================================================================
//function : LocateU
//purpose :
//=======================================================================
void Geom_BSplineSurface::LocateU
(const Standard_Real U,
const Standard_Real ParametricTolerance,
Standard_Integer& I1,
Standard_Integer& I2,
const Standard_Boolean WithKnotRepetition ) const
{
Standard_Real NewU =U, vbid = vknots->Value(1);
Handle(TColStd_HArray1OfReal) TheKnots;
if (WithKnotRepetition) TheKnots = ufknots;
else TheKnots = uknots;
PeriodicNormalization(NewU, vbid); //Attention a la periode
const TColStd_Array1OfReal & Knots = TheKnots->Array1();
Standard_Real UFirst = Knots (1);
Standard_Real ULast = Knots (Knots.Length());
Standard_Real PParametricTolerance = Abs(ParametricTolerance);
if (Abs (NewU - UFirst) <= PParametricTolerance) {
I1 = I2 = 1;
}
else if (Abs (NewU - ULast) <= PParametricTolerance) {
I1 = I2 = Knots.Length();
}
else if (NewU < UFirst) {
I2 = 1;
I1 = 0;
}
else if (NewU > ULast) {
I1 = Knots.Length();
I2 = I1 + 1;
}
else {
I1 = 1;
BSplCLib::Hunt (Knots, NewU, I1);
while ( Abs( Knots(I1+1) - NewU) <= PParametricTolerance) I1++;
if ( Abs( Knots(I1) - NewU) <= PParametricTolerance) {
I2 = I1;
}
else {
I2 = I1 + 1;
}
}
}
//=======================================================================
//function : LocateV
//purpose :
//=======================================================================
void Geom_BSplineSurface::LocateV
(const Standard_Real V,
const Standard_Real ParametricTolerance,
Standard_Integer& I1,
Standard_Integer& I2,
const Standard_Boolean WithKnotRepetition ) const
{
Standard_Real NewV =V, ubid = uknots->Value(1);
Handle(TColStd_HArray1OfReal) TheKnots;
if (WithKnotRepetition) TheKnots = vfknots;
else TheKnots = vknots;
PeriodicNormalization(ubid, NewV); //Attention a la periode
const TColStd_Array1OfReal & Knots = TheKnots->Array1();
Standard_Real VFirst = Knots (1);
Standard_Real VLast = Knots (Knots.Length());
Standard_Real PParametricTolerance = Abs(ParametricTolerance);
if (Abs (NewV - VFirst) <= PParametricTolerance) { I1 = I2 = 1; }
else if (Abs (NewV - VLast) <= PParametricTolerance) {
I1 = I2 = Knots.Length();
}
else if (NewV < VFirst - PParametricTolerance) {
I2 = 1;
I1 = 0;
}
else if (NewV > VLast + PParametricTolerance) {
I1 = Knots.Length();
I2 = I1 + 1;
}
else {
I1 = 1;
BSplCLib::Hunt (Knots, NewV, I1);
while ( Abs( Knots(I1+1) - NewV) <= PParametricTolerance) I1++;
if ( Abs( Knots(I1) - NewV) <= PParametricTolerance) {
I2 = I1;
}
else {
I2 = I1 + 1;
}
}
}
//=======================================================================
//function : UReverse
//purpose :
//=======================================================================
void Geom_BSplineSurface::UReverse ()
{
BSplCLib::Reverse(umults->ChangeArray1());
BSplCLib::Reverse(uknots->ChangeArray1());
Standard_Integer last;
if (uperiodic)
last = ufknots->Upper() - udeg -1;
else
last = poles->UpperRow();
BSplSLib::Reverse(poles->ChangeArray2(),last,Standard_True);
if (urational || vrational)
BSplSLib::Reverse(weights->ChangeArray2(),last,Standard_True);
UpdateUKnots();
}
//=======================================================================
//function : UReversedParameter
//purpose :
//=======================================================================
Standard_Real Geom_BSplineSurface::UReversedParameter
( const Standard_Real U) const
{
return ( uknots->Value( 1) + uknots->Value( uknots->Length()) - U);
}
//=======================================================================
//function : VReverse
//purpose :
//=======================================================================
void Geom_BSplineSurface::VReverse ()
{
BSplCLib::Reverse(vmults->ChangeArray1());
BSplCLib::Reverse(vknots->ChangeArray1());
Standard_Integer last;
if (vperiodic)
last = vfknots->Upper() - vdeg -1;
else
last = poles->UpperCol();
BSplSLib::Reverse(poles->ChangeArray2(),last,Standard_False);
if (urational || vrational)
BSplSLib::Reverse(weights->ChangeArray2(),last,Standard_False);
UpdateVKnots();
}
//=======================================================================
//function : VReversedParameter
//purpose :
//=======================================================================
Standard_Real Geom_BSplineSurface::VReversedParameter
( const Standard_Real V) const
{
return ( vknots->Value( 1) + vknots->Value( vknots->Length()) - V);
}
//=======================================================================
//function : SetPoleCol
//purpose :
//=======================================================================
void Geom_BSplineSurface::SetPoleCol (const Standard_Integer VIndex,
const TColgp_Array1OfPnt& CPoles)
{
if (VIndex < 1 || VIndex > poles->RowLength()) {
Standard_OutOfRange::Raise();
}
if (CPoles.Lower() < 1 || CPoles.Lower() > poles->ColLength() ||
CPoles.Upper() < 1 || CPoles.Upper() > poles->ColLength()) {
Standard_ConstructionError::Raise();
}
TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
Poles (I+Poles.LowerRow()-1, VIndex+Poles.LowerCol()-1) = CPoles(I);
}
InvalidateCache();
}
//=======================================================================
//function : SetPoleCol
//purpose :
//=======================================================================
void Geom_BSplineSurface::SetPoleCol (const Standard_Integer VIndex,
const TColgp_Array1OfPnt& CPoles,
const TColStd_Array1OfReal& CPoleWeights)
{
SetPoleCol (VIndex, CPoles);
SetWeightCol(VIndex, CPoleWeights);
}
//=======================================================================
//function : SetPoleRow
//purpose :
//=======================================================================
void Geom_BSplineSurface::SetPoleRow (const Standard_Integer UIndex,
const TColgp_Array1OfPnt& CPoles)
{
if (UIndex < 1 || UIndex > poles->ColLength() ) {
Standard_OutOfRange::Raise();
}
if (CPoles.Lower() < 1 || CPoles.Lower() > poles->RowLength() ||
CPoles.Upper() < 1 || CPoles.Upper() > poles->RowLength() ) {
Standard_ConstructionError::Raise();
}
TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
Poles (UIndex+Poles.LowerRow()-1, I+Poles.LowerCol()-1) = CPoles (I);
}
InvalidateCache();
}
//=======================================================================
//function : SetPoleRow
//purpose :
//=======================================================================
void Geom_BSplineSurface::SetPoleRow(const Standard_Integer UIndex,
const TColgp_Array1OfPnt & CPoles,
const TColStd_Array1OfReal& CPoleWeights)
{
SetPoleRow (UIndex, CPoles);
SetWeightRow(UIndex, CPoleWeights);
}
//=======================================================================
//function : SetPole
//purpose :
//=======================================================================
void Geom_BSplineSurface::SetPole (const Standard_Integer UIndex,
const Standard_Integer VIndex,
const gp_Pnt& P)
{
poles->SetValue (UIndex+poles->LowerRow()-1, VIndex+poles->LowerCol()-1, P);
InvalidateCache();
}
//=======================================================================
//function : SetPole
//purpose :
//=======================================================================
void Geom_BSplineSurface::SetPole (const Standard_Integer UIndex,
const Standard_Integer VIndex,
const gp_Pnt& P,
const Standard_Real Weight)
{
SetWeight(UIndex, VIndex, Weight);
SetPole (UIndex, VIndex, P);
}
//=======================================================================
//function : MovePoint
//purpose :
//=======================================================================
void Geom_BSplineSurface::MovePoint(const Standard_Real U,
const Standard_Real V,
const gp_Pnt& P,
const Standard_Integer UIndex1,
const Standard_Integer UIndex2,
const Standard_Integer VIndex1,
const Standard_Integer VIndex2,
Standard_Integer& UFirstModifiedPole,
Standard_Integer& ULastmodifiedPole,
Standard_Integer& VFirstModifiedPole,
Standard_Integer& VLastmodifiedPole)
{
if (UIndex1 < 1 || UIndex1 > poles->UpperRow() ||
UIndex2 < 1 || UIndex2 > poles->UpperRow() || UIndex1 > UIndex2 ||
VIndex1 < 1 || VIndex1 > poles->UpperCol() ||
VIndex2 < 1 || VIndex2 > poles->UpperCol() || VIndex1 > VIndex2) {
Standard_OutOfRange::Raise();
}
TColgp_Array2OfPnt npoles(1, poles->UpperRow(), 1, poles->UpperCol());
gp_Pnt P0;
D0(U, V, P0);
gp_Vec Displ(P0, P);
Standard_Boolean rational = (urational || vrational);
BSplSLib::MovePoint(U, V, Displ, UIndex1, UIndex2, VIndex1, VIndex2, udeg, vdeg,
rational, poles->Array2(), weights->Array2(),
ufknots->Array1(), vfknots->Array1(),
UFirstModifiedPole, ULastmodifiedPole,
VFirstModifiedPole, VLastmodifiedPole,
npoles);
if (UFirstModifiedPole) {
poles->ChangeArray2() = npoles;
}
maxderivinvok = 0;
InvalidateCache() ;
}
//=======================================================================
//function : Bounds
//purpose :
//=======================================================================
void Geom_BSplineSurface::Bounds (Standard_Real& U1,
Standard_Real& U2,
Standard_Real& V1,
Standard_Real& V2) const
{
U1 = ufknots->Value (udeg+1);
U2 = ufknots->Value (ufknots->Upper()-udeg);
V1 = vfknots->Value (vdeg+1);
V2 = vfknots->Value (vfknots->Upper()-vdeg);
}
//=======================================================================
//function : MaxDegree
//purpose :
//=======================================================================
Standard_Integer Geom_BSplineSurface::MaxDegree ()
{
return BSplCLib::MaxDegree();
}
//=======================================================================
//function : IsURational
//purpose :
//=======================================================================
Standard_Boolean Geom_BSplineSurface::IsURational () const
{
return urational;
}
//=======================================================================
//function : IsVRational
//purpose :
//=======================================================================
Standard_Boolean Geom_BSplineSurface::IsVRational () const
{
return vrational;
}
//=======================================================================
//function : Continuity
//purpose :
//=======================================================================
GeomAbs_Shape Geom_BSplineSurface::Continuity () const
{
return ((Usmooth < Vsmooth) ? Usmooth : Vsmooth) ;
}
//=======================================================================
//function : NbUKnots
//purpose :
//=======================================================================
Standard_Integer Geom_BSplineSurface::NbUKnots () const
{
return uknots->Length();
}
//=======================================================================
//function : NbUPoles
//purpose :
//=======================================================================
Standard_Integer Geom_BSplineSurface::NbUPoles () const
{
return poles->ColLength();
}
//=======================================================================
//function : NbVKnots
//purpose :
//=======================================================================
Standard_Integer Geom_BSplineSurface::NbVKnots () const
{
return vknots->Length();
}
//=======================================================================
//function : NbVPoles
//purpose :
//=======================================================================
Standard_Integer Geom_BSplineSurface::NbVPoles () const
{
return poles->RowLength();
}
//=======================================================================
//function : UDegree
//purpose :
//=======================================================================
Standard_Integer Geom_BSplineSurface::UDegree () const
{
return udeg;
}
//=======================================================================
//function : VDegree
//purpose :
//=======================================================================
Standard_Integer Geom_BSplineSurface::VDegree () const
{
return vdeg;
}
//=======================================================================
//function : UKnotDistribution
//purpose :
//=======================================================================
GeomAbs_BSplKnotDistribution Geom_BSplineSurface::UKnotDistribution() const
{
return uknotSet;
}
//=======================================================================
//function : VKnotDistribution
//purpose :
//=======================================================================
GeomAbs_BSplKnotDistribution Geom_BSplineSurface::VKnotDistribution() const
{
return vknotSet;
}
//=======================================================================
//function : InsertUKnots
//purpose :
//=======================================================================
void Geom_BSplineSurface::InsertUKnots
(const TColStd_Array1OfReal& Knots,
const TColStd_Array1OfInteger& Mults,
const Standard_Real ParametricTolerance,
const Standard_Boolean Add)
{
// Check and compute new sizes
Standard_Integer nbpoles, nbknots;
if ( !BSplCLib::PrepareInsertKnots(udeg,uperiodic,
uknots->Array1(),umults->Array1(),
Knots,Mults,nbpoles,nbknots,
ParametricTolerance,Add))
Standard_ConstructionError::Raise("Geom_BSplineSurface::InsertUKnots");
if ( nbpoles == poles->ColLength()) return;
Handle(TColgp_HArray2OfPnt) npoles
= new TColgp_HArray2OfPnt(1,nbpoles, 1,poles->RowLength());
Handle(TColStd_HArray2OfReal) nweights =
new TColStd_HArray2OfReal(1,nbpoles,
1,poles->RowLength(),
1.0);
Handle(TColStd_HArray1OfReal) nknots = uknots;
Handle(TColStd_HArray1OfInteger) nmults = umults;
if ( nbknots != uknots->Length()) {
nknots = new TColStd_HArray1OfReal(1,nbknots);
nmults = new TColStd_HArray1OfInteger(1,nbknots);
}
if ( urational || vrational) {
BSplSLib::InsertKnots(Standard_True,
udeg, uperiodic,
poles->Array2() , weights->Array2(),
uknots->Array1(), umults->Array1(),
Knots, Mults,
npoles->ChangeArray2(),
nweights->ChangeArray2(),
nknots->ChangeArray1(), nmults->ChangeArray1(),
ParametricTolerance, Add);
}
else {
BSplSLib::InsertKnots(Standard_True,
udeg, uperiodic,
poles->Array2() , BSplSLib::NoWeights(),
uknots->Array1(), umults->Array1(),
Knots, Mults,
npoles->ChangeArray2(),
*((TColStd_Array2OfReal*) NULL),
nknots->ChangeArray1(), nmults->ChangeArray1(),
ParametricTolerance, Add);
}
poles = npoles;
weights = nweights;
uknots = nknots;
umults = nmults;
UpdateUKnots();
}
//=======================================================================
//function : InsertVKnots
//purpose :
//=======================================================================
void Geom_BSplineSurface::InsertVKnots
(const TColStd_Array1OfReal& Knots,
const TColStd_Array1OfInteger& Mults,
const Standard_Real ParametricTolerance,
const Standard_Boolean Add)
{
// Check and compute new sizes
Standard_Integer nbpoles, nbknots;
if ( !BSplCLib::PrepareInsertKnots(vdeg,vperiodic,
vknots->Array1(),vmults->Array1(),
Knots,Mults,nbpoles,nbknots,
ParametricTolerance, Add))
Standard_ConstructionError::Raise("Geom_BSplineSurface::InsertVKnots");
if ( nbpoles == poles->RowLength()) return;
Handle(TColgp_HArray2OfPnt) npoles
= new TColgp_HArray2OfPnt(1,poles->ColLength(), 1,nbpoles);
Handle(TColStd_HArray2OfReal) nweights =
new TColStd_HArray2OfReal(1,poles->ColLength(),
1,nbpoles,
1.0);
Handle(TColStd_HArray1OfReal) nknots = vknots;
Handle(TColStd_HArray1OfInteger) nmults = vmults;
if ( nbknots != vknots->Length()) {
nknots = new TColStd_HArray1OfReal(1,nbknots);
nmults = new TColStd_HArray1OfInteger(1,nbknots);
}
if ( urational || vrational) {
BSplSLib::InsertKnots(Standard_False,
vdeg, vperiodic,
poles->Array2() , weights->Array2(),
vknots->Array1(), vmults->Array1(),
Knots, Mults,
npoles->ChangeArray2(),
nweights->ChangeArray2(),
nknots->ChangeArray1(), nmults->ChangeArray1(),
ParametricTolerance, Add);
}
else {
BSplSLib::InsertKnots(Standard_False,
vdeg, vperiodic,
poles->Array2() , BSplSLib::NoWeights(),
vknots->Array1(), vmults->Array1(),
Knots, Mults,
npoles->ChangeArray2(),
*((TColStd_Array2OfReal*) NULL),
nknots->ChangeArray1(), nmults->ChangeArray1(),
ParametricTolerance, Add);
}
poles = npoles;
weights = nweights;
vknots = nknots;
vmults = nmults;
UpdateVKnots();
}
//=======================================================================
//function : RemoveUKnot
//purpose :
//=======================================================================
Standard_Boolean Geom_BSplineSurface::RemoveUKnot
(const Standard_Integer Index,
const Standard_Integer M,
const Standard_Real Tolerance)
{
if ( M < 0 ) return Standard_True;
Standard_Integer I1 = FirstUKnotIndex ();
Standard_Integer I2 = LastUKnotIndex ();
if ( !uperiodic && (Index <= I1 || Index >= I2) ) {
Standard_OutOfRange::Raise();
}
else if ( uperiodic && (Index < I1 || Index > I2)) {
Standard_OutOfRange::Raise();
}
const TColgp_Array2OfPnt & oldpoles = poles->Array2();
Standard_Integer step = umults->Value(Index) - M;
if (step <= 0 ) return Standard_True;
Handle(TColgp_HArray2OfPnt) npoles =
new TColgp_HArray2OfPnt( 1, oldpoles.ColLength() - step,
1, oldpoles.RowLength());
Handle(TColStd_HArray1OfReal) nknots = uknots;
Handle(TColStd_HArray1OfInteger) nmults = umults;
if ( M == 0) {
nknots = new TColStd_HArray1OfReal(1,uknots->Length()-1);
nmults = new TColStd_HArray1OfInteger(1,uknots->Length()-1);
}
Handle(TColStd_HArray2OfReal) nweights ;
if (urational || vrational) {
nweights =
new TColStd_HArray2OfReal( 1, npoles->ColLength(),
1, npoles->RowLength());
if (!BSplSLib::RemoveKnot(Standard_True,
Index,M,udeg,uperiodic,
poles->Array2(),weights->Array2(),
uknots->Array1(),umults->Array1(),
npoles->ChangeArray2(),
nweights->ChangeArray2(),
nknots->ChangeArray1(),nmults->ChangeArray1(),
Tolerance))
return Standard_False;
}
else {
//
// sync the size of the weights
//
nweights =
new TColStd_HArray2OfReal(1, npoles->ColLength(),
1, npoles->RowLength(),
1.0e0 );
if (!BSplSLib::RemoveKnot(Standard_True,
Index,M,udeg,uperiodic,
poles->Array2(),BSplSLib::NoWeights(),
uknots->Array1(),umults->Array1(),
npoles->ChangeArray2(),
*((TColStd_Array2OfReal*) NULL),
nknots->ChangeArray1(),nmults->ChangeArray1(),
Tolerance))
return Standard_False;
}
poles = npoles;
weights = nweights;
uknots = nknots;
umults = nmults;
maxderivinvok = 0;
UpdateUKnots();
return Standard_True;
}
//=======================================================================
//function : RemoveVKnot
//purpose :
//=======================================================================
Standard_Boolean Geom_BSplineSurface::RemoveVKnot
(const Standard_Integer Index,
const Standard_Integer M,
const Standard_Real Tolerance)
{
if ( M < 0 ) return Standard_True;
Standard_Integer I1 = FirstVKnotIndex ();
Standard_Integer I2 = LastVKnotIndex ();
if ( !vperiodic && (Index <= I1 || Index >= I2) ) {
Standard_OutOfRange::Raise();
}
else if ( vperiodic && (Index < I1 || Index > I2)) {
Standard_OutOfRange::Raise();
}
const TColgp_Array2OfPnt & oldpoles = poles->Array2();
Standard_Integer step = vmults->Value(Index) - M;
if (step <= 0 ) return Standard_True;
Handle(TColgp_HArray2OfPnt) npoles =
new TColgp_HArray2OfPnt( 1, oldpoles.ColLength(),
1, oldpoles.RowLength() - step);
Handle(TColStd_HArray1OfReal) nknots = vknots;
Handle(TColStd_HArray1OfInteger) nmults = vmults;
if ( M == 0) {
nknots = new TColStd_HArray1OfReal(1,vknots->Length()-1);
nmults = new TColStd_HArray1OfInteger(1,vknots->Length()-1);
}
Handle(TColStd_HArray2OfReal) nweights ;
if (urational || vrational) {
nweights =
new TColStd_HArray2OfReal( 1, npoles->ColLength(),
1, npoles->RowLength()) ;
if (!BSplSLib::RemoveKnot(Standard_False,
Index,M,vdeg,vperiodic,
poles->Array2(),weights->Array2(),
vknots->Array1(),vmults->Array1(),
npoles->ChangeArray2(),
nweights->ChangeArray2(),
nknots->ChangeArray1(),nmults->ChangeArray1(),
Tolerance))
return Standard_False;
}
else {
//
// sync the size of the weights array
//
nweights =
new TColStd_HArray2OfReal(1, npoles->ColLength(),
1, npoles->RowLength(),
1.0e0 );
if (!BSplSLib::RemoveKnot(Standard_False,
Index,M,vdeg,vperiodic,
poles->Array2(),BSplSLib::NoWeights(),
vknots->Array1(),vmults->Array1(),
npoles->ChangeArray2(),
*((TColStd_Array2OfReal*) NULL),
nknots->ChangeArray1(),nmults->ChangeArray1(),
Tolerance))
return Standard_False;
}
poles = npoles;
vknots = nknots;
vmults = nmults;
weights = nweights;
maxderivinvok = 0;
UpdateVKnots();
return Standard_True;
}
//=======================================================================
//function : Resolution
//purpose :
//=======================================================================
void Geom_BSplineSurface::Resolution( const Standard_Real Tolerance3D,
Standard_Real& UTolerance,
Standard_Real& VTolerance)
{
if(!maxderivinvok){
BSplSLib::Resolution(poles ->Array2(),
weights->Array2(),
uknots ->Array1(),
vknots ->Array1(),
umults ->Array1(),
vmults ->Array1(),
udeg,
vdeg,
urational,
vrational,
uperiodic,
vperiodic,
1.,
umaxderivinv,
vmaxderivinv) ;
maxderivinvok = 1;
}
UTolerance = Tolerance3D * umaxderivinv;
VTolerance = Tolerance3D * vmaxderivinv;
}