mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-06 18:26:22 +03:00
3543 lines
106 KiB
C++
3543 lines
106 KiB
C++
// Created on: 1991-08-26
|
|
// Created by: JCV
|
|
// Copyright (c) 1991-1999 Matra Datavision
|
|
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
// Modified RLE Aug 93 - Complete rewrite
|
|
// xab 21-Mar-95 implemented cache mechanism
|
|
// pmn 25-09-96 Interpolation
|
|
// jct 25-09-96 : Correction de l'alloc de LocalArray dans RationalDerivative.
|
|
// pmn 07-10-96 : Correction de DN dans le cas rationnal.
|
|
// pmn 06-02-97 : Correction des poids dans RationalDerivative. (PRO700)
|
|
|
|
#include <BSplCLib.hxx>
|
|
#include <BSplSLib.hxx>
|
|
#include <gp_Pnt.hxx>
|
|
#include <gp_Vec.hxx>
|
|
#include <math_Matrix.hxx>
|
|
#include <NCollection_LocalArray.hxx>
|
|
#include <PLib.hxx>
|
|
#include <Standard_ConstructionError.hxx>
|
|
#include <Standard_NotImplemented.hxx>
|
|
#include <TColgp_Array1OfXYZ.hxx>
|
|
#include <TColgp_Array2OfXYZ.hxx>
|
|
#include <TColStd_HArray1OfInteger.hxx>
|
|
|
|
// for null derivatives
|
|
static Standard_Real BSplSLib_zero[3] = {0.0, 0.0, 0.0};
|
|
|
|
//=======================================================================
|
|
//struct : BSplCLib_DataContainer
|
|
//purpose: Auxiliary structure providing buffers for poles and knots used in
|
|
// evaluation of bspline (allocated in the stack)
|
|
//=======================================================================
|
|
|
|
struct BSplSLib_DataContainer
|
|
{
|
|
BSplSLib_DataContainer (Standard_Integer UDegree, Standard_Integer VDegree)
|
|
{
|
|
(void)UDegree; (void)VDegree; // just to avoid compiler warning in Release mode
|
|
Standard_OutOfRange_Raise_if (UDegree > BSplCLib::MaxDegree() ||
|
|
VDegree > BSplCLib::MaxDegree() || BSplCLib::MaxDegree() > 25,
|
|
"BSplSLib: bspline degree is greater than maximum supported");
|
|
}
|
|
Standard_Real poles[4*(25+1)*(25+1)];
|
|
Standard_Real knots1[2*25];
|
|
Standard_Real knots2[2*25];
|
|
Standard_Real ders[48];
|
|
};
|
|
|
|
//**************************************************************************
|
|
// Evaluation methods
|
|
//**************************************************************************
|
|
|
|
//=======================================================================
|
|
//function : RationalDerivative
|
|
//purpose : computes the rational derivatives when we have the
|
|
// the derivatives of the homogeneous numerator and the
|
|
// the derivatives of the denominator
|
|
//=======================================================================
|
|
|
|
void BSplSLib::RationalDerivative(const Standard_Integer UDeg,
|
|
const Standard_Integer VDeg,
|
|
const Standard_Integer N,
|
|
const Standard_Integer M,
|
|
Standard_Real& HDerivatives,
|
|
Standard_Real& RDerivatives,
|
|
const Standard_Boolean All)
|
|
{
|
|
//
|
|
// if All is True all derivatives are computed. if Not only
|
|
// the requested N, M is computed
|
|
//
|
|
// Numerator(u,v)
|
|
// let f(u,v) be a rational function = ------------------
|
|
// Denominator(u,v)
|
|
//
|
|
//
|
|
// Let (N,M) the order of the derivatives we want : then since
|
|
// we have :
|
|
//
|
|
// Numerator = f * Denominator
|
|
//
|
|
// we derive :
|
|
//
|
|
// (N,M) 1 ( (N M) (p q) (N -p M-q) )
|
|
// f = ------------ ( Numerator - SUM SUM a * f * Denominator )
|
|
// (0,0) ( p<N q<M p q )
|
|
// Denominator
|
|
//
|
|
// with :
|
|
//
|
|
// ( N ) ( M )
|
|
// a = ( ) ( )
|
|
// p q ( p ) ( q )
|
|
//
|
|
//
|
|
// HDerivatives is an array where derivatives are stored in the following form
|
|
// Numerator is assumee to have 3 functions that is a vector of dimension
|
|
// 3
|
|
//
|
|
// (0,0) (0,0) (0, DegV) (0, DegV)
|
|
// Numerator Denominator ... Numerator Denominator
|
|
//
|
|
// (1,0) (1,0) (1, DegV) (1, DegV)
|
|
// Numerator Denominator ... Numerator Denominator
|
|
//
|
|
// ...........................................................
|
|
//
|
|
//
|
|
// (DegU,0) (DegU,0) (DegU, DegV) (DegU, DegV)
|
|
// Numerator Denominator ... Numerator Denominator
|
|
//
|
|
//
|
|
Standard_Integer ii,jj,pp,qq,index,index1,index2;
|
|
Standard_Integer M1,M3,M4,N1,iiM1,iiM3,jjM1,ppM1,ppM3;
|
|
Standard_Integer MinN,MinN1,MinM,MinM1;
|
|
Standard_Integer index_u,index_u1,index_v,index_v1,index_w;
|
|
|
|
M1 = M + 1;
|
|
N1 = N + 1;
|
|
ii = N1 * M1;
|
|
M3 = (M1 << 1) + M1;
|
|
M4 = (VDeg + 1) << 2;
|
|
|
|
NCollection_LocalArray<Standard_Real> StoreDerivatives (All ? 0 : ii * 3);
|
|
Standard_Real *RArray = (All ? &RDerivatives : (Standard_Real*)StoreDerivatives);
|
|
NCollection_LocalArray<Standard_Real> StoreW (ii);
|
|
Standard_Real *HomogeneousArray = &HDerivatives;
|
|
Standard_Real denominator,Pii,Pip,Pjq;
|
|
|
|
denominator = 1.0e0 / HomogeneousArray[3];
|
|
index_u = 0;
|
|
index_u1 = 0;
|
|
if (UDeg < N) MinN = UDeg;
|
|
else MinN = N;
|
|
if (VDeg < M) MinM = VDeg;
|
|
else MinM = M;
|
|
MinN1 = MinN + 1;
|
|
MinM1 = MinM + 1;
|
|
iiM1 = - M1;
|
|
|
|
for (ii = 0 ; ii < MinN1 ; ii++) {
|
|
iiM1 += M1;
|
|
index_v = index_u;
|
|
index_v1 = index_u1;
|
|
index_w = iiM1;
|
|
|
|
for (jj = 0 ; jj < MinM1 ; jj++) {
|
|
RArray[index_v++] = HomogeneousArray[index_v1++];
|
|
RArray[index_v++] = HomogeneousArray[index_v1++];
|
|
RArray[index_v++] = HomogeneousArray[index_v1++];
|
|
StoreW[index_w++] = HomogeneousArray[index_v1++];
|
|
}
|
|
|
|
for (jj = MinM1 ; jj < M1 ; jj++) {
|
|
RArray[index_v++] = 0.;
|
|
RArray[index_v++] = 0.;
|
|
RArray[index_v++] = 0.;
|
|
StoreW[index_w++] = 0.;
|
|
}
|
|
index_u1 += M4;
|
|
index_u += M3;
|
|
}
|
|
index_v = MinN1 * M3;
|
|
index_w = MinN1 * M1;
|
|
|
|
for (ii = MinN1 ; ii < N1 ; ii++) {
|
|
|
|
for (jj = 0 ; jj < M1 ; jj++) {
|
|
RArray[index_v++] = 0.0e0;
|
|
RArray[index_v++] = 0.0e0;
|
|
RArray[index_v++] = 0.0e0;
|
|
StoreW[index_w++] = 0.0e0;
|
|
}
|
|
}
|
|
|
|
// --------------- Calculation ----------------
|
|
|
|
iiM1 = - M1;
|
|
iiM3 = - M3;
|
|
|
|
for (ii = 0 ; ii <= N ; ii++) {
|
|
iiM1 += M1;
|
|
iiM3 += M3;
|
|
index1 = iiM3 - 3;
|
|
jjM1 = iiM1;
|
|
|
|
for (jj = 0 ; jj <= M ; jj++) {
|
|
jjM1 ++;
|
|
ppM1 = - M1;
|
|
ppM3 = - M3;
|
|
index1 += 3;
|
|
|
|
for (pp = 0 ; pp < ii ; pp++) {
|
|
ppM1 += M1;
|
|
ppM3 += M3;
|
|
index = ppM3;
|
|
index2 = jjM1 - ppM1;
|
|
Pip = PLib::Bin(ii,pp);
|
|
|
|
for (qq = 0 ; qq <= jj ; qq++) {
|
|
index2--;
|
|
Pjq = Pip * PLib::Bin(jj,qq) * StoreW[index2];
|
|
RArray[index1] -= Pjq * RArray[index]; index++; index1++;
|
|
RArray[index1] -= Pjq * RArray[index]; index++; index1++;
|
|
RArray[index1] -= Pjq * RArray[index]; index++;
|
|
index1 -= 2;
|
|
}
|
|
}
|
|
index = iiM3;
|
|
index2 = jj + 1;
|
|
Pii = PLib::Bin(ii,ii);
|
|
|
|
for (qq = 0 ; qq < jj ; qq++) {
|
|
index2--;
|
|
Pjq = Pii * PLib::Bin(jj,qq) * StoreW[index2];
|
|
RArray[index1] -= Pjq * RArray[index]; index++; index1++;
|
|
RArray[index1] -= Pjq * RArray[index]; index++; index1++;
|
|
RArray[index1] -= Pjq * RArray[index]; index++;
|
|
index1 -= 2;
|
|
}
|
|
RArray[index1] *= denominator; index1++;
|
|
RArray[index1] *= denominator; index1++;
|
|
RArray[index1] *= denominator;
|
|
index1 -= 2;
|
|
}
|
|
}
|
|
if (!All) {
|
|
RArray = &RDerivatives;
|
|
index = N * M1 + M;
|
|
index = (index << 1) + index;
|
|
RArray[0] = StoreDerivatives[index]; index++;
|
|
RArray[1] = StoreDerivatives[index]; index++;
|
|
RArray[2] = StoreDerivatives[index];
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : PrepareEval
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
//
|
|
// PrepareEval :
|
|
//
|
|
// Prepare all data for computing points :
|
|
// local arrays of knots
|
|
// local array of poles (multiplied by the weights if rational)
|
|
//
|
|
// The first direction to compute (smaller degree) is returned
|
|
// and the poles are stored according to this direction.
|
|
|
|
static Standard_Boolean PrepareEval (const Standard_Real U,
|
|
const Standard_Real V,
|
|
const Standard_Integer Uindex,
|
|
const Standard_Integer Vindex,
|
|
const Standard_Integer UDegree,
|
|
const Standard_Integer VDegree,
|
|
const Standard_Boolean URat,
|
|
const Standard_Boolean VRat,
|
|
const Standard_Boolean UPer,
|
|
const Standard_Boolean VPer,
|
|
const TColgp_Array2OfPnt& Poles,
|
|
const TColStd_Array2OfReal* Weights,
|
|
const TColStd_Array1OfReal& UKnots,
|
|
const TColStd_Array1OfReal& VKnots,
|
|
const TColStd_Array1OfInteger* UMults,
|
|
const TColStd_Array1OfInteger* VMults,
|
|
Standard_Real& u1, // first parameter to use
|
|
Standard_Real& u2, // second parameter to use
|
|
Standard_Integer& d1, // first degree
|
|
Standard_Integer& d2, // second degree
|
|
Standard_Boolean& rational,
|
|
BSplSLib_DataContainer& dc)
|
|
{
|
|
rational = URat || VRat;
|
|
Standard_Integer uindex = Uindex;
|
|
Standard_Integer vindex = Vindex;
|
|
Standard_Integer UKLower = UKnots.Lower();
|
|
Standard_Integer UKUpper = UKnots.Upper();
|
|
Standard_Integer VKLower = VKnots.Lower();
|
|
Standard_Integer VKUpper = VKnots.Upper();
|
|
|
|
if (UDegree <= VDegree)
|
|
{
|
|
// compute the indices
|
|
if (uindex < UKLower || uindex > UKUpper)
|
|
BSplCLib::LocateParameter(UDegree,UKnots,UMults,U,UPer,uindex,u1);
|
|
else
|
|
u1 = U;
|
|
|
|
if (vindex < VKLower || vindex > VKUpper)
|
|
BSplCLib::LocateParameter(VDegree,VKnots,VMults,V,VPer,vindex,u2);
|
|
else
|
|
u2 = V;
|
|
|
|
// get the knots
|
|
d1 = UDegree;
|
|
d2 = VDegree;
|
|
BSplCLib::BuildKnots(UDegree,uindex,UPer,UKnots,UMults,*dc.knots1);
|
|
BSplCLib::BuildKnots(VDegree,vindex,VPer,VKnots,VMults,*dc.knots2);
|
|
|
|
if (UMults == NULL)
|
|
uindex -= UKLower + UDegree;
|
|
else
|
|
uindex = BSplCLib::PoleIndex(UDegree,uindex,UPer,*UMults);
|
|
|
|
if (VMults == NULL)
|
|
vindex -= VKLower + VDegree;
|
|
else
|
|
vindex = BSplCLib::PoleIndex(VDegree,vindex,VPer,*VMults);
|
|
|
|
// get the poles
|
|
Standard_Integer i,j,ip,jp;
|
|
Standard_Real w, *pole = dc.poles;
|
|
d1 = UDegree;
|
|
d2 = VDegree;
|
|
Standard_Integer PLowerRow = Poles.LowerRow();
|
|
Standard_Integer PUpperRow = Poles.UpperRow();
|
|
Standard_Integer PLowerCol = Poles.LowerCol();
|
|
Standard_Integer PUpperCol = Poles.UpperCol();
|
|
|
|
// verify if locally non rational
|
|
if (rational)
|
|
{
|
|
rational = Standard_False;
|
|
ip = PLowerRow + uindex;
|
|
jp = PLowerCol + vindex;
|
|
|
|
if(ip < PLowerRow) ip = PUpperRow;
|
|
if(jp < PLowerCol) jp = PUpperCol;
|
|
|
|
w = Weights->Value(ip,jp);
|
|
Standard_Real eps = Epsilon(w);
|
|
Standard_Real dw;
|
|
|
|
for (i = 0; i <= UDegree && !rational; i++)
|
|
{
|
|
jp = PLowerCol + vindex;
|
|
|
|
if(jp < PLowerCol)
|
|
jp = PUpperCol;
|
|
|
|
for (j = 0; j <= VDegree && !rational; j++)
|
|
{
|
|
dw = Weights->Value(ip,jp) - w;
|
|
if (dw < 0)
|
|
dw = - dw;
|
|
|
|
rational = (dw > eps);
|
|
|
|
jp++;
|
|
|
|
if (jp > PUpperCol)
|
|
jp = PLowerCol;
|
|
}
|
|
|
|
ip++;
|
|
|
|
if (ip > PUpperRow)
|
|
ip = PLowerRow;
|
|
|
|
}
|
|
}
|
|
|
|
// copy the poles
|
|
ip = PLowerRow + uindex;
|
|
|
|
if(ip < PLowerRow)
|
|
ip = PUpperRow;
|
|
|
|
if (rational)
|
|
{
|
|
for (i = 0; i <= d1; i++)
|
|
{
|
|
jp = PLowerCol + vindex;
|
|
|
|
if(jp < PLowerCol)
|
|
jp = PUpperCol;
|
|
|
|
for (j = 0; j <= d2; j++)
|
|
{
|
|
const gp_Pnt& P = Poles .Value(ip,jp);
|
|
pole[3] = w = Weights->Value(ip,jp);
|
|
pole[0] = P.X() * w;
|
|
pole[1] = P.Y() * w;
|
|
pole[2] = P.Z() * w;
|
|
pole += 4;
|
|
jp++;
|
|
|
|
if (jp > PUpperCol)
|
|
jp = PLowerCol;
|
|
}
|
|
|
|
ip++;
|
|
|
|
if (ip > PUpperRow)
|
|
ip = PLowerRow;
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (i = 0; i <= d1; i++)
|
|
{
|
|
jp = PLowerCol + vindex;
|
|
|
|
if(jp < PLowerCol)
|
|
jp = PUpperCol;
|
|
|
|
for (j = 0; j <= d2; j++)
|
|
{
|
|
const gp_Pnt& P = Poles.Value(ip,jp);
|
|
pole[0] = P.X();
|
|
pole[1] = P.Y();
|
|
pole[2] = P.Z();
|
|
pole += 3;
|
|
jp++;
|
|
|
|
if (jp > PUpperCol)
|
|
jp = PLowerCol;
|
|
}
|
|
|
|
ip++;
|
|
|
|
if (ip > PUpperRow)
|
|
ip = PLowerRow;
|
|
}
|
|
}
|
|
|
|
return Standard_True;
|
|
}
|
|
else
|
|
{
|
|
// compute the indices
|
|
if (uindex < UKLower || uindex > UKUpper)
|
|
BSplCLib::LocateParameter(UDegree,UKnots,UMults,U,UPer,uindex,u2);
|
|
else
|
|
u2 = U;
|
|
|
|
if (vindex < VKLower || vindex > VKUpper)
|
|
BSplCLib::LocateParameter(VDegree,VKnots,VMults,V,VPer,vindex,u1);
|
|
else
|
|
u1 = V;
|
|
|
|
// get the knots
|
|
|
|
d2 = UDegree;
|
|
d1 = VDegree;
|
|
|
|
BSplCLib::BuildKnots(UDegree,uindex,UPer,UKnots,UMults,*dc.knots2);
|
|
BSplCLib::BuildKnots(VDegree,vindex,VPer,VKnots,VMults,*dc.knots1);
|
|
|
|
if (UMults == NULL)
|
|
uindex -= UKLower + UDegree;
|
|
else
|
|
uindex = BSplCLib::PoleIndex(UDegree,uindex,UPer,*UMults);
|
|
|
|
if (VMults == NULL)
|
|
vindex -= VKLower + VDegree;
|
|
else
|
|
vindex = BSplCLib::PoleIndex(VDegree,vindex,VPer,*VMults);
|
|
|
|
// get the poles
|
|
Standard_Integer i,j,ip,jp;
|
|
Standard_Real w, *pole = dc.poles;
|
|
d1 = VDegree;
|
|
d2 = UDegree;
|
|
Standard_Integer PLowerRow = Poles.LowerRow();
|
|
Standard_Integer PUpperRow = Poles.UpperRow();
|
|
Standard_Integer PLowerCol = Poles.LowerCol();
|
|
Standard_Integer PUpperCol = Poles.UpperCol();
|
|
|
|
// verify if locally non rational
|
|
if (rational)
|
|
{
|
|
rational = Standard_False;
|
|
ip = PLowerRow + uindex;
|
|
jp = PLowerCol + vindex;
|
|
|
|
if(ip < PLowerRow)
|
|
ip = PUpperRow;
|
|
|
|
if(jp < PLowerCol)
|
|
jp = PUpperCol;
|
|
|
|
w = Weights->Value(ip,jp);
|
|
Standard_Real eps = Epsilon(w);
|
|
Standard_Real dw;
|
|
|
|
for (i = 0; i <= UDegree && !rational; i++)
|
|
{
|
|
jp = PLowerCol + vindex;
|
|
|
|
if(jp < PLowerCol)
|
|
jp = PUpperCol;
|
|
|
|
for (j = 0; j <= VDegree && !rational; j++)
|
|
{
|
|
dw = Weights->Value(ip,jp) - w;
|
|
if (dw < 0) dw = - dw;
|
|
rational = dw > eps;
|
|
|
|
jp++;
|
|
|
|
if (jp > PUpperCol)
|
|
jp = PLowerCol;
|
|
}
|
|
|
|
ip++;
|
|
|
|
if (ip > PUpperRow)
|
|
ip = PLowerRow;
|
|
|
|
}
|
|
}
|
|
|
|
// copy the poles
|
|
jp = PLowerCol + vindex;
|
|
|
|
if(jp < PLowerCol)
|
|
jp = PUpperCol;
|
|
|
|
if (rational)
|
|
{
|
|
for (i = 0; i <= d1; i++)
|
|
{
|
|
ip = PLowerRow + uindex;
|
|
|
|
if(ip < PLowerRow)
|
|
ip = PUpperRow;
|
|
|
|
for (j = 0; j <= d2; j++)
|
|
{
|
|
const gp_Pnt& P = Poles.Value(ip,jp);
|
|
pole[3] = w = Weights->Value(ip,jp);
|
|
pole[0] = P.X() * w;
|
|
pole[1] = P.Y() * w;
|
|
pole[2] = P.Z() * w;
|
|
pole += 4;
|
|
ip++;
|
|
|
|
if (ip > PUpperRow)
|
|
ip = PLowerRow;
|
|
|
|
}
|
|
|
|
jp++;
|
|
|
|
if (jp > PUpperCol)
|
|
jp = PLowerCol;
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (i = 0; i <= d1; i++)
|
|
{
|
|
ip = PLowerRow + uindex;
|
|
|
|
if(ip < PLowerRow)
|
|
ip = PUpperRow;
|
|
|
|
if(ip > PUpperRow)
|
|
ip = PLowerRow;
|
|
|
|
for (j = 0; j <= d2; j++)
|
|
{
|
|
const gp_Pnt& P = Poles.Value(ip,jp);
|
|
pole[0] = P.X();
|
|
pole[1] = P.Y();
|
|
pole[2] = P.Z();
|
|
pole += 3;
|
|
ip++;
|
|
|
|
if (ip > PUpperRow)
|
|
ip = PLowerRow;
|
|
}
|
|
|
|
jp++;
|
|
|
|
if (jp > PUpperCol)
|
|
jp = PLowerCol;
|
|
|
|
}
|
|
}
|
|
|
|
return Standard_False;
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : D0
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BSplSLib::D0
|
|
(const Standard_Real U,
|
|
const Standard_Real V,
|
|
const Standard_Integer UIndex,
|
|
const Standard_Integer VIndex,
|
|
const TColgp_Array2OfPnt& Poles,
|
|
const TColStd_Array2OfReal* Weights,
|
|
const TColStd_Array1OfReal& UKnots,
|
|
const TColStd_Array1OfReal& VKnots,
|
|
const TColStd_Array1OfInteger* UMults,
|
|
const TColStd_Array1OfInteger* VMults,
|
|
const Standard_Integer UDegree,
|
|
const Standard_Integer VDegree,
|
|
const Standard_Boolean URat,
|
|
const Standard_Boolean VRat,
|
|
const Standard_Boolean UPer,
|
|
const Standard_Boolean VPer,
|
|
gp_Pnt& P)
|
|
{
|
|
// Standard_Integer k ;
|
|
Standard_Real W ;
|
|
HomogeneousD0(U,
|
|
V,
|
|
UIndex,
|
|
VIndex,
|
|
Poles,
|
|
Weights,
|
|
UKnots,
|
|
VKnots,
|
|
UMults,
|
|
VMults,
|
|
UDegree,
|
|
VDegree,
|
|
URat,
|
|
VRat,
|
|
UPer,
|
|
VPer,
|
|
W,
|
|
P) ;
|
|
P.SetX(P.X() / W);
|
|
P.SetY(P.Y() / W);
|
|
P.SetZ(P.Z() / W);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : D0
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BSplSLib::HomogeneousD0
|
|
(const Standard_Real U,
|
|
const Standard_Real V,
|
|
const Standard_Integer UIndex,
|
|
const Standard_Integer VIndex,
|
|
const TColgp_Array2OfPnt& Poles,
|
|
const TColStd_Array2OfReal* Weights,
|
|
const TColStd_Array1OfReal& UKnots,
|
|
const TColStd_Array1OfReal& VKnots,
|
|
const TColStd_Array1OfInteger* UMults,
|
|
const TColStd_Array1OfInteger* VMults,
|
|
const Standard_Integer UDegree,
|
|
const Standard_Integer VDegree,
|
|
const Standard_Boolean URat,
|
|
const Standard_Boolean VRat,
|
|
const Standard_Boolean UPer,
|
|
const Standard_Boolean VPer,
|
|
Standard_Real & W,
|
|
gp_Pnt& P)
|
|
{
|
|
Standard_Boolean rational;
|
|
// Standard_Integer k,dim;
|
|
Standard_Integer dim;
|
|
Standard_Real u1,u2;
|
|
Standard_Integer d1,d2;
|
|
W = 1.0e0 ;
|
|
|
|
BSplSLib_DataContainer dc (UDegree, VDegree);
|
|
PrepareEval(U,V,UIndex,VIndex,UDegree,VDegree,URat,VRat,UPer,VPer,
|
|
Poles,Weights,UKnots,VKnots,UMults,VMults,
|
|
u1,u2,d1,d2,rational,dc);
|
|
if (rational) {
|
|
dim = 4;
|
|
BSplCLib::Eval(u1,d1,*dc.knots1,dim * (d2 + 1),*dc.poles);
|
|
BSplCLib::Eval(u2,d2,*dc.knots2,dim,*dc.poles);
|
|
W = dc.poles[3];
|
|
P.SetX(dc.poles[0]);
|
|
P.SetY(dc.poles[1]);
|
|
P.SetZ(dc.poles[2]);
|
|
}
|
|
else {
|
|
dim = 3;
|
|
BSplCLib::Eval(u1,d1,*dc.knots1,dim * (d2 + 1),*dc.poles);
|
|
BSplCLib::Eval(u2,d2,*dc.knots2,dim,*dc.poles);
|
|
P.SetX(dc.poles[0]);
|
|
P.SetY(dc.poles[1]);
|
|
P.SetZ(dc.poles[2]);
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : D1
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BSplSLib::D1
|
|
(const Standard_Real U,
|
|
const Standard_Real V,
|
|
const Standard_Integer UIndex,
|
|
const Standard_Integer VIndex,
|
|
const TColgp_Array2OfPnt& Poles,
|
|
const TColStd_Array2OfReal* Weights,
|
|
const TColStd_Array1OfReal& UKnots,
|
|
const TColStd_Array1OfReal& VKnots,
|
|
const TColStd_Array1OfInteger* UMults,
|
|
const TColStd_Array1OfInteger* VMults,
|
|
const Standard_Integer UDegree,
|
|
const Standard_Integer VDegree,
|
|
const Standard_Boolean URat,
|
|
const Standard_Boolean VRat,
|
|
const Standard_Boolean UPer,
|
|
const Standard_Boolean VPer,
|
|
gp_Pnt& P,
|
|
gp_Vec& Vu,
|
|
gp_Vec& Vv)
|
|
{
|
|
Standard_Boolean rational;
|
|
// Standard_Integer k,dim,dim2;
|
|
Standard_Integer dim,dim2;
|
|
Standard_Real u1,u2;
|
|
Standard_Integer d1,d2;
|
|
Standard_Real *result, *resVu, *resVv;
|
|
BSplSLib_DataContainer dc (UDegree, VDegree);
|
|
if (PrepareEval
|
|
(U,V,UIndex,VIndex,UDegree,VDegree,URat,VRat,UPer,VPer,
|
|
Poles,Weights,UKnots,VKnots,UMults,VMults,
|
|
u1,u2,d1,d2,rational,dc)) {
|
|
if (rational) {
|
|
dim = 4;
|
|
dim2 = (d2 + 1) << 2;
|
|
BSplCLib::Bohm(u1,d1,1,*dc.knots1,dim2,*dc.poles);
|
|
BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*dc.poles);
|
|
BSplCLib::Eval(u2,d2, *dc.knots2,dim ,*(dc.poles + dim2));
|
|
BSplSLib::RationalDerivative(d1,d2,1,1,*dc.poles,*dc.ders);
|
|
result = dc.ders;
|
|
resVu = result + 6;
|
|
resVv = result + 3;
|
|
}
|
|
else {
|
|
dim = 3;
|
|
dim2 = d2 + 1;
|
|
dim2 = (dim2 << 1) + dim2;
|
|
BSplCLib::Bohm(u1,d1,1,*dc.knots1,dim2,*dc.poles);
|
|
BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*dc.poles);
|
|
BSplCLib::Eval(u2,d2, *dc.knots2,dim ,*(dc.poles + dim2));
|
|
result = dc.poles;
|
|
resVu = result + dim2;
|
|
resVv = result + 3;
|
|
}
|
|
}
|
|
else {
|
|
if (rational) {
|
|
dim = 4;
|
|
dim2 = (d2 + 1) << 2;
|
|
BSplCLib::Bohm(u1,d1,1,*dc.knots1,dim2,*dc.poles);
|
|
BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*dc.poles);
|
|
BSplCLib::Eval(u2,d2, *dc.knots2,dim ,*(dc.poles + dim2));
|
|
BSplSLib::RationalDerivative(d1,d2,1,1,*dc.poles,*dc.ders);
|
|
result = dc.ders;
|
|
resVu = result + 3;
|
|
resVv = result + 6;
|
|
}
|
|
else {
|
|
dim = 3;
|
|
dim2 = d2 + 1;
|
|
dim2 = (dim2 << 1) + dim2;
|
|
BSplCLib::Bohm(u1,d1,1,*dc.knots1,dim2,*dc.poles);
|
|
BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*dc.poles);
|
|
BSplCLib::Eval(u2,d2 ,*dc.knots2,dim ,*(dc.poles + dim2));
|
|
result = dc.poles;
|
|
resVu = result + 3;
|
|
resVv = result + dim2;
|
|
}
|
|
}
|
|
|
|
P .SetX(result[0]);
|
|
Vu.SetX(resVu [0]);
|
|
Vv.SetX(resVv [0]);
|
|
|
|
P .SetY(result[1]);
|
|
Vu.SetY(resVu [1]);
|
|
Vv.SetY(resVv [1]);
|
|
|
|
P .SetZ(result[2]);
|
|
Vu.SetZ(resVu [2]);
|
|
Vv.SetZ(resVv [2]);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : D1
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BSplSLib::HomogeneousD1
|
|
(const Standard_Real U,
|
|
const Standard_Real V,
|
|
const Standard_Integer UIndex,
|
|
const Standard_Integer VIndex,
|
|
const TColgp_Array2OfPnt& Poles,
|
|
const TColStd_Array2OfReal* Weights,
|
|
const TColStd_Array1OfReal& UKnots,
|
|
const TColStd_Array1OfReal& VKnots,
|
|
const TColStd_Array1OfInteger* UMults,
|
|
const TColStd_Array1OfInteger* VMults,
|
|
const Standard_Integer UDegree,
|
|
const Standard_Integer VDegree,
|
|
const Standard_Boolean URat,
|
|
const Standard_Boolean VRat,
|
|
const Standard_Boolean UPer,
|
|
const Standard_Boolean VPer,
|
|
gp_Pnt& N,
|
|
gp_Vec& Nu,
|
|
gp_Vec& Nv,
|
|
Standard_Real& D,
|
|
Standard_Real& Du,
|
|
Standard_Real& Dv)
|
|
{
|
|
Standard_Boolean rational;
|
|
// Standard_Integer k,dim;
|
|
Standard_Integer dim;
|
|
Standard_Real u1,u2;
|
|
Standard_Integer d1,d2;
|
|
|
|
D = 1.0e0 ;
|
|
Du = 0.0e0 ;
|
|
Dv = 0.0e0 ;
|
|
BSplSLib_DataContainer dc (UDegree, VDegree);
|
|
Standard_Boolean ufirst = PrepareEval
|
|
(U,V,UIndex,VIndex,UDegree,VDegree,URat,VRat,UPer,VPer,
|
|
Poles,Weights,UKnots,VKnots,UMults,VMults,
|
|
u1,u2,d1,d2,rational,dc);
|
|
dim = rational ? 4 : 3;
|
|
|
|
BSplCLib::Bohm(u1,d1,1,*dc.knots1,dim * (d2 + 1),*dc.poles);
|
|
BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim,*dc.poles);
|
|
BSplCLib::Eval(u2,d2,*dc.knots2,dim,*(dc.poles+dim*(d2+1)));
|
|
|
|
Standard_Real *result, *resVu, *resVv;
|
|
result = dc.poles;
|
|
resVu = result + (ufirst ? dim*(d2+1) : dim);
|
|
resVv = result + (ufirst ? dim : dim*(d2+1));
|
|
|
|
N .SetX(result[0]);
|
|
Nu.SetX(resVu [0]);
|
|
Nv.SetX(resVv [0]);
|
|
|
|
N .SetY(result[1]);
|
|
Nu.SetY(resVu [1]);
|
|
Nv.SetY(resVv [1]);
|
|
|
|
N .SetZ(result[2]);
|
|
Nu.SetZ(resVu [2]);
|
|
Nv.SetZ(resVv [2]);
|
|
|
|
if (rational) {
|
|
D = result[3];
|
|
Du = resVu [3];
|
|
Dv = resVv [3];
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : D2
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BSplSLib::D2
|
|
(const Standard_Real U,
|
|
const Standard_Real V,
|
|
const Standard_Integer UIndex,
|
|
const Standard_Integer VIndex,
|
|
const TColgp_Array2OfPnt& Poles,
|
|
const TColStd_Array2OfReal* Weights,
|
|
const TColStd_Array1OfReal& UKnots,
|
|
const TColStd_Array1OfReal& VKnots,
|
|
const TColStd_Array1OfInteger* UMults,
|
|
const TColStd_Array1OfInteger* VMults,
|
|
const Standard_Integer UDegree,
|
|
const Standard_Integer VDegree,
|
|
const Standard_Boolean URat,
|
|
const Standard_Boolean VRat,
|
|
const Standard_Boolean UPer,
|
|
const Standard_Boolean VPer,
|
|
gp_Pnt& P,
|
|
gp_Vec& Vu,
|
|
gp_Vec& Vv,
|
|
gp_Vec& Vuu,
|
|
gp_Vec& Vvv,
|
|
gp_Vec& Vuv)
|
|
{
|
|
Standard_Boolean rational;
|
|
// Standard_Integer k,dim,dim2;
|
|
Standard_Integer dim,dim2;
|
|
Standard_Real u1,u2;
|
|
Standard_Integer d1,d2;
|
|
Standard_Real *result, *resVu, *resVv, *resVuu, *resVvv, *resVuv;
|
|
BSplSLib_DataContainer dc (UDegree, VDegree);
|
|
if (PrepareEval
|
|
(U,V,UIndex,VIndex,UDegree,VDegree,URat,VRat,UPer,VPer,
|
|
Poles,Weights,UKnots,VKnots,UMults,VMults,
|
|
u1,u2,d1,d2,rational,dc)) {
|
|
if (rational) {
|
|
dim = 4;
|
|
dim2 = (d2 + 1) << 2;
|
|
BSplCLib::Bohm(u1,d1,2,*dc.knots1,dim2,*dc.poles);
|
|
BSplCLib::Bohm(u2,d2,2,*dc.knots2,dim ,*dc.poles);
|
|
BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*(dc.poles + dim2));
|
|
if (d1 > 1)
|
|
BSplCLib::Eval(u2,d2,*dc.knots2,dim ,*(dc.poles + (dim2 << 1)));
|
|
BSplSLib::RationalDerivative(d1,d2,2,2,*dc.poles,*dc.ders);
|
|
result = dc.ders;
|
|
resVu = result + 9;
|
|
resVv = result + 3;
|
|
resVuu = result + 18;
|
|
resVvv = result + 6;
|
|
resVuv = result + 12;
|
|
}
|
|
else {
|
|
dim = 3;
|
|
dim2 = d2 + 1;
|
|
dim2 = (dim2 << 1) + dim2;
|
|
BSplCLib::Bohm(u1,d1,2,*dc.knots1,dim2,*dc.poles);
|
|
BSplCLib::Bohm(u2,d2,2,*dc.knots2,dim ,*dc.poles);
|
|
BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*(dc.poles + dim2));
|
|
if (d1 > 1)
|
|
BSplCLib::Eval(u2,d2,*dc.knots2,dim ,*(dc.poles + (dim2 << 1)));
|
|
result = dc.poles;
|
|
resVu = result + dim2;
|
|
resVv = result + 3;
|
|
if (UDegree <= 1) resVuu = BSplSLib_zero;
|
|
else resVuu = result + (dim2 << 1);
|
|
if (VDegree <= 1) resVvv = BSplSLib_zero;
|
|
else resVvv = result + 6;
|
|
resVuv = result + (d2 << 1) + d2 + 6;
|
|
}
|
|
}
|
|
else {
|
|
if (rational) {
|
|
dim = 4;
|
|
dim2 = (d2 + 1) << 2;
|
|
BSplCLib::Bohm(u1,d1,2,*dc.knots1,dim2,*dc.poles);
|
|
BSplCLib::Bohm(u2,d2,2,*dc.knots2,dim ,*dc.poles);
|
|
BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*(dc.poles + dim2));
|
|
if (d1 > 1)
|
|
BSplCLib::Eval(u2,d2,*dc.knots2,dim ,*(dc.poles + (dim2 << 1)));
|
|
BSplSLib::RationalDerivative(d1,d2,2,2,*dc.poles,*dc.ders);
|
|
result = dc.ders;
|
|
resVu = result + 3;
|
|
resVv = result + 9;
|
|
resVuu = result + 6;
|
|
resVvv = result + 18;
|
|
resVuv = result + 12;
|
|
}
|
|
else {
|
|
dim = 3;
|
|
dim2 = d2 + 1;
|
|
dim2 = (dim2 << 1) + dim2;
|
|
BSplCLib::Bohm(u1,d1,2,*dc.knots1,dim2,*dc.poles);
|
|
BSplCLib::Bohm(u2,d2,2,*dc.knots2,dim ,*dc.poles);
|
|
BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*(dc.poles + dim2));
|
|
if (d1 > 1)
|
|
BSplCLib::Eval(u2,d2,*dc.knots2,dim ,*(dc.poles + (dim2 << 1)));
|
|
result = dc.poles;
|
|
resVu = result + 3;
|
|
resVv = result + dim2;
|
|
if (UDegree <= 1) resVuu = BSplSLib_zero;
|
|
else resVuu = result + 6;
|
|
if (VDegree <= 1) resVvv = BSplSLib_zero;
|
|
else resVvv = result + (dim2 << 1);
|
|
resVuv = result + (d2 << 1) + d2 + 6;
|
|
}
|
|
}
|
|
|
|
P .SetX(result[0]);
|
|
Vu .SetX(resVu [0]);
|
|
Vv .SetX(resVv [0]);
|
|
Vuu.SetX(resVuu[0]);
|
|
Vvv.SetX(resVvv[0]);
|
|
Vuv.SetX(resVuv[0]);
|
|
|
|
P .SetY(result[1]);
|
|
Vu .SetY(resVu [1]);
|
|
Vv .SetY(resVv [1]);
|
|
Vuu.SetY(resVuu[1]);
|
|
Vvv.SetY(resVvv[1]);
|
|
Vuv.SetY(resVuv[1]);
|
|
|
|
P .SetZ(result[2]);
|
|
Vu .SetZ(resVu [2]);
|
|
Vv .SetZ(resVv [2]);
|
|
Vuu.SetZ(resVuu[2]);
|
|
Vvv.SetZ(resVvv[2]);
|
|
Vuv.SetZ(resVuv[2]);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : D3
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BSplSLib::D3
|
|
(const Standard_Real U,
|
|
const Standard_Real V,
|
|
const Standard_Integer UIndex,
|
|
const Standard_Integer VIndex,
|
|
const TColgp_Array2OfPnt& Poles,
|
|
const TColStd_Array2OfReal* Weights,
|
|
const TColStd_Array1OfReal& UKnots,
|
|
const TColStd_Array1OfReal& VKnots,
|
|
const TColStd_Array1OfInteger* UMults,
|
|
const TColStd_Array1OfInteger* VMults,
|
|
const Standard_Integer UDegree,
|
|
const Standard_Integer VDegree,
|
|
const Standard_Boolean URat,
|
|
const Standard_Boolean VRat,
|
|
const Standard_Boolean UPer,
|
|
const Standard_Boolean VPer,
|
|
gp_Pnt& P,
|
|
gp_Vec& Vu,
|
|
gp_Vec& Vv,
|
|
gp_Vec& Vuu,
|
|
gp_Vec& Vvv,
|
|
gp_Vec& Vuv,
|
|
gp_Vec& Vuuu,
|
|
gp_Vec& Vvvv,
|
|
gp_Vec& Vuuv,
|
|
gp_Vec& Vuvv)
|
|
{
|
|
Standard_Boolean rational;
|
|
// Standard_Integer k,dim,dim2;
|
|
Standard_Integer dim,dim2;
|
|
Standard_Real u1,u2;
|
|
Standard_Integer d1,d2;
|
|
Standard_Real *result, *resVu, *resVv, *resVuu, *resVvv, *resVuv,
|
|
*resVuuu, *resVvvv, *resVuuv, *resVuvv;
|
|
BSplSLib_DataContainer dc (UDegree, VDegree);
|
|
if (PrepareEval
|
|
(U,V,UIndex,VIndex,UDegree,VDegree,URat,VRat,UPer,VPer,
|
|
Poles,Weights,UKnots,VKnots,UMults,VMults,
|
|
u1,u2,d1,d2,rational,dc)) {
|
|
if (rational) {
|
|
dim = 4;
|
|
dim2 = (d2 + 1) << 2;
|
|
BSplCLib::Bohm (u1,d1,3,*dc.knots1,dim2,*dc.poles);
|
|
BSplCLib::Bohm (u2,d2,3,*dc.knots2,dim ,*dc.poles);
|
|
BSplCLib::Bohm (u2,d2,2,*dc.knots2,dim ,*(dc.poles + dim2));
|
|
if (d1 > 1)
|
|
BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*(dc.poles + (dim2 << 1)));
|
|
if (d1 > 2)
|
|
BSplCLib::Eval(u2,d2 ,*dc.knots2,dim ,*(dc.poles + (dim2 << 1) + dim2));
|
|
BSplSLib::RationalDerivative(d1,d2,3,3,*dc.poles,*dc.ders);
|
|
result = dc.ders;
|
|
resVu = result + 12;
|
|
resVv = result + 3;
|
|
resVuu = result + 24;
|
|
resVvv = result + 6;
|
|
resVuv = result + 15;
|
|
resVuuu = result + 36;
|
|
resVvvv = result + 9;
|
|
resVuuv = result + 27;
|
|
resVuvv = result + 18;
|
|
}
|
|
else {
|
|
dim = 3;
|
|
dim2 = (d2 + 1);
|
|
dim2 = (dim2 << 1) + dim2;
|
|
BSplCLib::Bohm (u1,d1,3,*dc.knots1,dim2,*dc.poles);
|
|
BSplCLib::Bohm (u2,d2,3,*dc.knots2,dim ,*dc.poles);
|
|
BSplCLib::Bohm (u2,d2,2,*dc.knots2,dim ,*(dc.poles + dim2));
|
|
if (d1 > 1)
|
|
BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*(dc.poles + (dim2 << 1)));
|
|
if (d1 > 2)
|
|
BSplCLib::Eval(u2,d2 ,*dc.knots2,dim ,*(dc.poles + (dim2 << 1) + dim2));
|
|
result = dc.poles;
|
|
resVu = result + dim2;
|
|
resVv = result + 3;
|
|
if (UDegree <= 1) {
|
|
resVuu = BSplSLib_zero;
|
|
resVuuv = BSplSLib_zero;
|
|
}
|
|
else {
|
|
resVuu = result + (dim2 << 1);
|
|
resVuuv = result + (dim2 << 1) + 3;
|
|
}
|
|
if (VDegree <= 1) {
|
|
resVvv = BSplSLib_zero;
|
|
resVuvv = BSplSLib_zero;
|
|
}
|
|
else {
|
|
resVvv = result + 6;
|
|
resVuvv = result + dim2 + 6;
|
|
}
|
|
resVuv = result + (d2 << 1) + d2 + 6;
|
|
if (UDegree <= 2) resVuuu = BSplSLib_zero;
|
|
else resVuuu = result + (dim2 << 1) + dim2;
|
|
if (VDegree <= 2) resVvvv = BSplSLib_zero;
|
|
else resVvvv = result + 9;
|
|
}
|
|
}
|
|
else {
|
|
if (rational) {
|
|
dim = 4;
|
|
dim2 = (d2 + 1) << 2;
|
|
BSplCLib::Bohm (u1,d1,3,*dc.knots1,dim2,*dc.poles);
|
|
BSplCLib::Bohm (u2,d2,3,*dc.knots2,dim ,*dc.poles);
|
|
BSplCLib::Bohm (u2,d2,2,*dc.knots2,dim ,*(dc.poles + dim2));
|
|
if (d1 > 1)
|
|
BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*(dc.poles + (dim2 << 1)));
|
|
if (d1 > 2)
|
|
BSplCLib::Eval(u2,d2 ,*dc.knots2,dim ,*(dc.poles + (dim2 << 1) + dim2));
|
|
BSplSLib::RationalDerivative(d1,d2,3,3,*dc.poles,*dc.ders);
|
|
result = dc.ders;
|
|
resVu = result + 3;
|
|
resVv = result + 12;
|
|
resVuu = result + 6;
|
|
resVvv = result + 24;
|
|
resVuv = result + 15;
|
|
resVuuu = result + 9;
|
|
resVvvv = result + 36;
|
|
resVuuv = result + 18;
|
|
resVuvv = result + 27;
|
|
}
|
|
else {
|
|
dim = 3;
|
|
dim2 = (d2 + 1);
|
|
dim2 = (dim2 << 1) + dim2;
|
|
BSplCLib::Bohm (u1,d1,3,*dc.knots1,dim2,*dc.poles);
|
|
BSplCLib::Bohm (u2,d2,3,*dc.knots2,dim ,*dc.poles);
|
|
BSplCLib::Bohm (u2,d2,2,*dc.knots2,dim ,*(dc.poles + dim2));
|
|
if (d1 > 1)
|
|
BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*(dc.poles + (dim2 << 1)));
|
|
if (d1 > 2)
|
|
BSplCLib::Eval(u2,d2 ,*dc.knots2,dim ,*(dc.poles + (dim2 << 1) + dim2));
|
|
result = dc.poles;
|
|
resVu = result + 3;
|
|
resVv = result + dim2;
|
|
if (UDegree <= 1) {
|
|
resVuu = BSplSLib_zero;
|
|
resVuuv = BSplSLib_zero;
|
|
}
|
|
else {
|
|
resVuu = result + 6;
|
|
resVuuv = result + dim2 + 6;
|
|
}
|
|
if (VDegree <= 1) {
|
|
resVvv = BSplSLib_zero;
|
|
resVuvv = BSplSLib_zero;
|
|
}
|
|
else {
|
|
resVvv = result + (dim2 << 1);
|
|
resVuvv = result + (dim2 << 1) + 3;
|
|
}
|
|
resVuv = result + (d2 << 1) + d2 + 6;
|
|
if (UDegree <= 2) resVuuu = BSplSLib_zero;
|
|
else resVuuu = result + 9;
|
|
if (VDegree <= 2) resVvvv = BSplSLib_zero;
|
|
else resVvvv = result + (dim2 << 1) + dim2;
|
|
}
|
|
}
|
|
|
|
P .SetX(result [0]);
|
|
Vu .SetX(resVu [0]);
|
|
Vv .SetX(resVv [0]);
|
|
Vuu .SetX(resVuu [0]);
|
|
Vvv .SetX(resVvv [0]);
|
|
Vuv .SetX(resVuv [0]);
|
|
Vuuu.SetX(resVuuu[0]);
|
|
Vvvv.SetX(resVvvv[0]);
|
|
Vuuv.SetX(resVuuv[0]);
|
|
Vuvv.SetX(resVuvv[0]);
|
|
|
|
P .SetY(result [1]);
|
|
Vu .SetY(resVu [1]);
|
|
Vv .SetY(resVv [1]);
|
|
Vuu .SetY(resVuu [1]);
|
|
Vvv .SetY(resVvv [1]);
|
|
Vuv .SetY(resVuv [1]);
|
|
Vuuu.SetY(resVuuu[1]);
|
|
Vvvv.SetY(resVvvv[1]);
|
|
Vuuv.SetY(resVuuv[1]);
|
|
Vuvv.SetY(resVuvv[1]);
|
|
|
|
P .SetZ(result [2]);
|
|
Vu .SetZ(resVu [2]);
|
|
Vv .SetZ(resVv [2]);
|
|
Vuu .SetZ(resVuu [2]);
|
|
Vvv .SetZ(resVvv [2]);
|
|
Vuv .SetZ(resVuv [2]);
|
|
Vuuu.SetZ(resVuuu[2]);
|
|
Vvvv.SetZ(resVvvv[2]);
|
|
Vuuv.SetZ(resVuuv[2]);
|
|
Vuvv.SetZ(resVuvv[2]);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : DN
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BSplSLib::DN
|
|
(const Standard_Real U,
|
|
const Standard_Real V,
|
|
const Standard_Integer Nu,
|
|
const Standard_Integer Nv,
|
|
const Standard_Integer UIndex,
|
|
const Standard_Integer VIndex,
|
|
const TColgp_Array2OfPnt& Poles,
|
|
const TColStd_Array2OfReal* Weights,
|
|
const TColStd_Array1OfReal& UKnots,
|
|
const TColStd_Array1OfReal& VKnots,
|
|
const TColStd_Array1OfInteger* UMults,
|
|
const TColStd_Array1OfInteger* VMults,
|
|
const Standard_Integer UDegree,
|
|
const Standard_Integer VDegree,
|
|
const Standard_Boolean URat,
|
|
const Standard_Boolean VRat,
|
|
const Standard_Boolean UPer,
|
|
const Standard_Boolean VPer,
|
|
gp_Vec& Vn)
|
|
{
|
|
Standard_Boolean rational;
|
|
Standard_Integer k,dim;
|
|
Standard_Real u1,u2;
|
|
Standard_Integer d1,d2;
|
|
|
|
BSplSLib_DataContainer dc (UDegree, VDegree);
|
|
Standard_Boolean ufirst = PrepareEval
|
|
(U,V,UIndex,VIndex,UDegree,VDegree,URat,VRat,UPer,VPer,
|
|
Poles,Weights,UKnots,VKnots,UMults,VMults,
|
|
u1,u2,d1,d2,rational,dc);
|
|
dim = rational ? 4 : 3;
|
|
|
|
if (!rational) {
|
|
if ((Nu > UDegree) || (Nv > VDegree)) {
|
|
Vn.SetX(0.);
|
|
Vn.SetY(0.);
|
|
Vn.SetZ(0.);
|
|
return;
|
|
}
|
|
}
|
|
|
|
Standard_Integer n1 = ufirst ? Nu : Nv;
|
|
Standard_Integer n2 = ufirst ? Nv : Nu;
|
|
|
|
BSplCLib::Bohm(u1,d1,n1,*dc.knots1,dim * (d2 + 1),*dc.poles);
|
|
|
|
for (k = 0; k <= Min(n1,d1); k++)
|
|
BSplCLib::Bohm(u2,d2,n2,*dc.knots2,dim,*(dc.poles+k*dim*(d2+1)));
|
|
|
|
Standard_Real *result;
|
|
if (rational) {
|
|
BSplSLib::RationalDerivative(d1,d2,n1,n2,*dc.poles,*dc.ders,Standard_False);
|
|
result = dc.ders; // because Standard_False ci-dessus.
|
|
|
|
}
|
|
else {
|
|
result = dc.poles + (n1 * (d2+1) + n2) * dim ;
|
|
}
|
|
|
|
Vn.SetX(result[0]);
|
|
Vn.SetY(result[1]);
|
|
Vn.SetZ(result[2]);
|
|
}
|
|
|
|
//
|
|
// Surface modifications
|
|
//
|
|
// a surface is processed as a curve of curves.
|
|
// i.e : a curve of parameter u where the current point is the set of poles
|
|
// of the iso.
|
|
//
|
|
|
|
//=======================================================================
|
|
//function : Iso
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BSplSLib::Iso(const Standard_Real Param,
|
|
const Standard_Boolean IsU,
|
|
const TColgp_Array2OfPnt& Poles,
|
|
const TColStd_Array2OfReal* Weights,
|
|
const TColStd_Array1OfReal& Knots,
|
|
const TColStd_Array1OfInteger* Mults,
|
|
const Standard_Integer Degree,
|
|
const Standard_Boolean Periodic,
|
|
TColgp_Array1OfPnt& CPoles,
|
|
TColStd_Array1OfReal* CWeights)
|
|
{
|
|
Standard_Integer index = 0;
|
|
Standard_Real u = Param;
|
|
Standard_Boolean rational = Weights != NULL;
|
|
Standard_Integer dim = rational ? 4 : 3;
|
|
|
|
// compute local knots
|
|
|
|
NCollection_LocalArray<Standard_Real> locknots1 (2*Degree);
|
|
BSplCLib::LocateParameter(Degree,Knots,Mults,u,Periodic,index,u);
|
|
BSplCLib::BuildKnots(Degree,index,Periodic,Knots,Mults,*locknots1);
|
|
if (Mults == NULL)
|
|
index -= Knots.Lower() + Degree;
|
|
else
|
|
index = BSplCLib::PoleIndex(Degree,index,Periodic,*Mults);
|
|
|
|
|
|
// copy the local poles
|
|
|
|
// Standard_Integer f1,l1,f2,l2,i,j,k;
|
|
Standard_Integer f1,l1,f2,l2,i,j;
|
|
|
|
if (IsU) {
|
|
f1 = Poles.LowerRow();
|
|
l1 = Poles.UpperRow();
|
|
f2 = Poles.LowerCol();
|
|
l2 = Poles.UpperCol();
|
|
}
|
|
else {
|
|
f1 = Poles.LowerCol();
|
|
l1 = Poles.UpperCol();
|
|
f2 = Poles.LowerRow();
|
|
l2 = Poles.UpperRow();
|
|
}
|
|
|
|
NCollection_LocalArray<Standard_Real> locpoles ((Degree+1) * (l2-f2+1) * dim);
|
|
|
|
Standard_Real w, *pole = locpoles;
|
|
index += f1;
|
|
|
|
for (i = 0; i <= Degree; i++) {
|
|
|
|
for (j = f2; j <= l2; j++) {
|
|
|
|
const gp_Pnt& P = IsU ? Poles(index,j) : Poles(j,index);
|
|
if (rational) {
|
|
pole[3] = w = IsU ? (*Weights)(index,j) : (*Weights)(j,index);
|
|
pole[0] = P.X() * w;
|
|
pole[1] = P.Y() * w;
|
|
pole[2] = P.Z() * w;
|
|
}
|
|
else {
|
|
pole[0] = P.X();
|
|
pole[1] = P.Y();
|
|
pole[2] = P.Z();
|
|
}
|
|
pole += dim;
|
|
}
|
|
index++;
|
|
if (index > l1) index = f1;
|
|
}
|
|
|
|
// compute the iso
|
|
BSplCLib::Eval(u,Degree,*locknots1,(l2-f2+1)*dim,*locpoles);
|
|
|
|
// get the result
|
|
pole = locpoles;
|
|
|
|
for (i = CPoles.Lower(); i <= CPoles.Upper(); i++) {
|
|
gp_Pnt& P = CPoles(i);
|
|
if (rational) {
|
|
(*CWeights)(i) = w = pole[3];
|
|
P.SetX( pole[0] / w);
|
|
P.SetY( pole[1] / w);
|
|
P.SetZ( pole[2] / w);
|
|
}
|
|
else {
|
|
P.SetX( pole[0]);
|
|
P.SetY( pole[1]);
|
|
P.SetZ( pole[2]);
|
|
}
|
|
pole += dim;
|
|
}
|
|
|
|
// if the input is not rational but weights are wanted
|
|
if (!rational && (CWeights != NULL)) {
|
|
|
|
for (i = CWeights->Lower(); i <= CWeights->Upper(); i++)
|
|
(*CWeights)(i) = 1.;
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Reverse
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BSplSLib::Reverse( TColgp_Array2OfPnt& Poles,
|
|
const Standard_Integer Last,
|
|
const Standard_Boolean UDirection)
|
|
{
|
|
Standard_Integer i,j, l = Last;
|
|
if ( UDirection) {
|
|
l = Poles.LowerRow() +
|
|
(l - Poles.LowerRow())%(Poles.ColLength());
|
|
TColgp_Array2OfPnt temp(0, Poles.ColLength()-1,
|
|
Poles.LowerCol(), Poles.UpperCol());
|
|
|
|
for (i = Poles.LowerRow(); i <= l; i++) {
|
|
|
|
for (j = Poles.LowerCol(); j <= Poles.UpperCol(); j++) {
|
|
temp(l-i,j) = Poles(i,j);
|
|
}
|
|
}
|
|
|
|
for (i = l+1; i <= Poles.UpperRow(); i++) {
|
|
|
|
for (j = Poles.LowerCol(); j <= Poles.UpperCol(); j++) {
|
|
temp(l+Poles.ColLength()-i,j) = Poles(i,j);
|
|
}
|
|
}
|
|
|
|
for (i = Poles.LowerRow(); i <= Poles.UpperRow(); i++) {
|
|
|
|
for (j = Poles.LowerCol(); j <= Poles.UpperCol(); j++) {
|
|
Poles(i,j) = temp (i-Poles.LowerRow(),j);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
l = Poles.LowerCol() +
|
|
(l - Poles.LowerCol())%(Poles.RowLength());
|
|
TColgp_Array2OfPnt temp(Poles.LowerRow(), Poles.UpperRow(),
|
|
0, Poles.RowLength()-1);
|
|
|
|
for (j = Poles.LowerCol(); j <= l; j++) {
|
|
|
|
for (i = Poles.LowerRow(); i <= Poles.UpperRow(); i++) {
|
|
temp(i,l-j) = Poles(i,j);
|
|
}
|
|
}
|
|
|
|
for (j = l+1; j <= Poles.UpperCol(); j++) {
|
|
|
|
for (i = Poles.LowerRow(); i <= Poles.UpperRow(); i++) {
|
|
temp(i,l+Poles.RowLength()-j) = Poles(i,j);
|
|
}
|
|
}
|
|
|
|
for (i = Poles.LowerRow(); i <= Poles.UpperRow(); i++) {
|
|
|
|
for (j = Poles.LowerCol(); j <= Poles.UpperCol(); j++) {
|
|
Poles(i,j) = temp (i,j-Poles.LowerCol());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Reverse
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BSplSLib::Reverse( TColStd_Array2OfReal& Weights,
|
|
const Standard_Integer Last,
|
|
const Standard_Boolean UDirection)
|
|
{
|
|
Standard_Integer i,j, l = Last;
|
|
if ( UDirection) {
|
|
l = Weights.LowerRow() +
|
|
(l - Weights.LowerRow())%(Weights.ColLength());
|
|
TColStd_Array2OfReal temp(0, Weights.ColLength()-1,
|
|
Weights.LowerCol(), Weights.UpperCol());
|
|
|
|
for (i = Weights.LowerRow(); i <= l; i++) {
|
|
|
|
for (j = Weights.LowerCol(); j <= Weights.UpperCol(); j++) {
|
|
temp(l-i,j) = Weights(i,j);
|
|
}
|
|
}
|
|
|
|
for (i = l+1; i <= Weights.UpperRow(); i++) {
|
|
|
|
for (j = Weights.LowerCol(); j <= Weights.UpperCol(); j++) {
|
|
temp(l+Weights.ColLength()-i,j) = Weights(i,j);
|
|
}
|
|
}
|
|
|
|
for (i = Weights.LowerRow(); i <= Weights.UpperRow(); i++) {
|
|
|
|
for (j = Weights.LowerCol(); j <= Weights.UpperCol(); j++) {
|
|
Weights(i,j) = temp (i-Weights.LowerRow(),j);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
l = Weights.LowerCol() +
|
|
(l - Weights.LowerCol())%(Weights.RowLength());
|
|
TColStd_Array2OfReal temp(Weights.LowerRow(), Weights.UpperRow(),
|
|
0, Weights.RowLength()-1);
|
|
|
|
for (j = Weights.LowerCol(); j <= l; j++) {
|
|
|
|
for (i = Weights.LowerRow(); i <= Weights.UpperRow(); i++) {
|
|
temp(i,l-j) = Weights(i,j);
|
|
}
|
|
}
|
|
|
|
for (j = l+1; j <= Weights.UpperCol(); j++) {
|
|
|
|
for (i = Weights.LowerRow(); i <= Weights.UpperRow(); i++) {
|
|
temp(i,l+Weights.RowLength()-j) = Weights(i,j);
|
|
}
|
|
}
|
|
|
|
for (i = Weights.LowerRow(); i <= Weights.UpperRow(); i++) {
|
|
|
|
for (j = Weights.LowerCol(); j <= Weights.UpperCol(); j++) {
|
|
Weights(i,j) = temp (i,j-Weights.LowerCol());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : IsRational
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean BSplSLib::IsRational
|
|
(const TColStd_Array2OfReal& Weights,
|
|
const Standard_Integer I1,
|
|
const Standard_Integer I2,
|
|
const Standard_Integer J1,
|
|
const Standard_Integer J2,
|
|
const Standard_Real Epsi)
|
|
{
|
|
Standard_Real eps = (Epsi > 0.0) ? Epsi : Epsilon(Weights(I1,I2));
|
|
Standard_Integer i,j;
|
|
Standard_Integer fi = Weights.LowerRow(), li = Weights.ColLength();
|
|
Standard_Integer fj = Weights.LowerCol(), lj = Weights.RowLength();
|
|
|
|
for (i = I1 - fi; i < I2 - fi; i++) {
|
|
|
|
for (j = J1 - fj; j < J2 - fj; j++) {
|
|
if (Abs(Weights(fi+i%li,fj+j%lj)-Weights(fi+(i+1)%li,fj+j%lj))>eps)
|
|
return Standard_True;
|
|
}
|
|
}
|
|
return Standard_False;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : SetPoles
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BSplSLib::SetPoles(const TColgp_Array2OfPnt& Poles,
|
|
TColStd_Array1OfReal& FP,
|
|
const Standard_Boolean UDirection)
|
|
{
|
|
Standard_Integer i, j, l = FP.Lower();
|
|
Standard_Integer PLowerRow = Poles.LowerRow();
|
|
Standard_Integer PUpperRow = Poles.UpperRow();
|
|
Standard_Integer PLowerCol = Poles.LowerCol();
|
|
Standard_Integer PUpperCol = Poles.UpperCol();
|
|
if (UDirection) {
|
|
|
|
for ( i = PLowerRow; i <= PUpperRow; i++) {
|
|
|
|
for ( j = PLowerCol; j <= PUpperCol; j++) {
|
|
const gp_Pnt& P = Poles.Value(i,j);
|
|
FP(l) = P.X(); l++;
|
|
FP(l) = P.Y(); l++;
|
|
FP(l) = P.Z(); l++;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
|
|
for ( j = PLowerCol; j <= PUpperCol; j++) {
|
|
|
|
for ( i = PLowerRow; i <= PUpperRow; i++) {
|
|
const gp_Pnt& P = Poles.Value(i,j);
|
|
FP(l) = P.X(); l++;
|
|
FP(l) = P.Y(); l++;
|
|
FP(l) = P.Z(); l++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : SetPoles
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BSplSLib::SetPoles(const TColgp_Array2OfPnt& Poles,
|
|
const TColStd_Array2OfReal& Weights,
|
|
TColStd_Array1OfReal& FP,
|
|
const Standard_Boolean UDirection)
|
|
{
|
|
Standard_Integer i, j, l = FP.Lower();
|
|
Standard_Integer PLowerRow = Poles.LowerRow();
|
|
Standard_Integer PUpperRow = Poles.UpperRow();
|
|
Standard_Integer PLowerCol = Poles.LowerCol();
|
|
Standard_Integer PUpperCol = Poles.UpperCol();
|
|
if (UDirection) {
|
|
|
|
for ( i = PLowerRow; i <= PUpperRow; i++) {
|
|
|
|
for ( j = PLowerCol; j <= PUpperCol; j++) {
|
|
const gp_Pnt& P = Poles .Value(i,j);
|
|
Standard_Real w = Weights.Value(i,j);
|
|
FP(l) = P.X() * w; l++;
|
|
FP(l) = P.Y() * w; l++;
|
|
FP(l) = P.Z() * w; l++;
|
|
FP(l) = w; l++;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
|
|
for ( j = PLowerCol; j <= PUpperCol; j++) {
|
|
|
|
for ( i = PLowerRow; i <= PUpperRow; i++) {
|
|
const gp_Pnt& P = Poles .Value(i,j);
|
|
Standard_Real w = Weights.Value(i,j);
|
|
FP(l) = P.X() * w; l++;
|
|
FP(l) = P.Y() * w; l++;
|
|
FP(l) = P.Z() * w; l++;
|
|
FP(l) = w; l++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : GetPoles
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BSplSLib::GetPoles(const TColStd_Array1OfReal& FP,
|
|
TColgp_Array2OfPnt& Poles,
|
|
const Standard_Boolean UDirection)
|
|
{
|
|
Standard_Integer i, j, l = FP.Lower();
|
|
Standard_Integer PLowerRow = Poles.LowerRow();
|
|
Standard_Integer PUpperRow = Poles.UpperRow();
|
|
Standard_Integer PLowerCol = Poles.LowerCol();
|
|
Standard_Integer PUpperCol = Poles.UpperCol();
|
|
if (UDirection) {
|
|
|
|
for ( i = PLowerRow; i <= PUpperRow; i++) {
|
|
|
|
for ( j = PLowerCol; j <= PUpperCol; j++) {
|
|
gp_Pnt& P = Poles.ChangeValue(i,j);
|
|
P.SetX(FP(l)); l++;
|
|
P.SetY(FP(l)); l++;
|
|
P.SetZ(FP(l)); l++;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
|
|
for ( j = PLowerCol; j <= PUpperCol; j++) {
|
|
|
|
for ( i = PLowerRow; i <= PUpperRow; i++) {
|
|
gp_Pnt& P = Poles.ChangeValue(i,j);
|
|
P.SetX(FP(l)); l++;
|
|
P.SetY(FP(l)); l++;
|
|
P.SetZ(FP(l)); l++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : GetPoles
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BSplSLib::GetPoles(const TColStd_Array1OfReal& FP,
|
|
TColgp_Array2OfPnt& Poles,
|
|
TColStd_Array2OfReal& Weights,
|
|
const Standard_Boolean UDirection)
|
|
{
|
|
Standard_Integer i, j, l = FP.Lower();
|
|
Standard_Integer PLowerRow = Poles.LowerRow();
|
|
Standard_Integer PUpperRow = Poles.UpperRow();
|
|
Standard_Integer PLowerCol = Poles.LowerCol();
|
|
Standard_Integer PUpperCol = Poles.UpperCol();
|
|
if (UDirection) {
|
|
|
|
for ( i = PLowerRow; i <= PUpperRow; i++) {
|
|
|
|
for ( j = PLowerCol; j <= PUpperCol; j++) {
|
|
Standard_Real w = FP( l + 3);
|
|
Weights(i,j) = w;
|
|
gp_Pnt& P = Poles.ChangeValue(i,j);
|
|
P.SetX(FP(l) / w); l++;
|
|
P.SetY(FP(l) / w); l++;
|
|
P.SetZ(FP(l) / w); l++;
|
|
l++;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
|
|
for ( j = PLowerCol; j <= PUpperCol; j++) {
|
|
|
|
for ( i = PLowerRow; i <= PUpperRow; i++) {
|
|
Standard_Real w = FP( l + 3);
|
|
Weights(i,j) = w;
|
|
gp_Pnt& P = Poles.ChangeValue(i,j);
|
|
P.SetX(FP(l) / w); l++;
|
|
P.SetY(FP(l) / w); l++;
|
|
P.SetZ(FP(l) / w); l++;
|
|
l++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : InsertKnots
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BSplSLib::InsertKnots(const Standard_Boolean UDirection,
|
|
const Standard_Integer Degree,
|
|
const Standard_Boolean Periodic,
|
|
const TColgp_Array2OfPnt& Poles,
|
|
const TColStd_Array2OfReal* Weights,
|
|
const TColStd_Array1OfReal& Knots,
|
|
const TColStd_Array1OfInteger& Mults,
|
|
const TColStd_Array1OfReal& AddKnots,
|
|
const TColStd_Array1OfInteger* AddMults,
|
|
TColgp_Array2OfPnt& NewPoles,
|
|
TColStd_Array2OfReal* NewWeights,
|
|
TColStd_Array1OfReal& NewKnots,
|
|
TColStd_Array1OfInteger& NewMults,
|
|
const Standard_Real Epsilon,
|
|
const Standard_Boolean Add )
|
|
{
|
|
Standard_Boolean rational = Weights != NULL;
|
|
Standard_Integer dim = 3;
|
|
if (rational) dim++;
|
|
|
|
TColStd_Array1OfReal poles( 1, dim*Poles.RowLength()*Poles.ColLength());
|
|
TColStd_Array1OfReal
|
|
newpoles( 1, dim*NewPoles.RowLength()*NewPoles.ColLength());
|
|
|
|
if (rational) SetPoles(Poles,*Weights,poles,UDirection);
|
|
else SetPoles(Poles,poles,UDirection);
|
|
|
|
if (UDirection) {
|
|
dim *= Poles.RowLength();
|
|
}
|
|
else {
|
|
dim *= Poles.ColLength();
|
|
}
|
|
BSplCLib::InsertKnots(Degree,Periodic,dim,poles,Knots,Mults,
|
|
AddKnots,AddMults,newpoles,NewKnots,NewMults,
|
|
Epsilon,Add);
|
|
|
|
if (rational) GetPoles(newpoles,NewPoles,*NewWeights,UDirection);
|
|
else GetPoles(newpoles,NewPoles,UDirection);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : RemoveKnot
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
Standard_Boolean BSplSLib::RemoveKnot
|
|
(const Standard_Boolean UDirection,
|
|
const Standard_Integer Index,
|
|
const Standard_Integer Mult,
|
|
const Standard_Integer Degree,
|
|
const Standard_Boolean Periodic,
|
|
const TColgp_Array2OfPnt& Poles,
|
|
const TColStd_Array2OfReal* Weights,
|
|
const TColStd_Array1OfReal& Knots,
|
|
const TColStd_Array1OfInteger& Mults,
|
|
TColgp_Array2OfPnt& NewPoles,
|
|
TColStd_Array2OfReal* NewWeights,
|
|
TColStd_Array1OfReal& NewKnots,
|
|
TColStd_Array1OfInteger& NewMults,
|
|
const Standard_Real Tolerance)
|
|
{
|
|
Standard_Boolean rational = Weights != NULL;
|
|
Standard_Integer dim = 3;
|
|
if (rational) dim++;
|
|
|
|
TColStd_Array1OfReal poles( 1, dim*Poles.RowLength()*Poles.ColLength());
|
|
TColStd_Array1OfReal
|
|
newpoles( 1, dim*NewPoles.RowLength()*NewPoles.ColLength());
|
|
|
|
if (rational) SetPoles(Poles,*Weights,poles,UDirection);
|
|
else SetPoles(Poles,poles,UDirection);
|
|
|
|
if (UDirection) {
|
|
dim *= Poles.RowLength();
|
|
}
|
|
else {
|
|
dim *= Poles.ColLength();
|
|
}
|
|
|
|
if ( !BSplCLib::RemoveKnot(Index,Mult,Degree,Periodic,dim,
|
|
poles,Knots,Mults,newpoles,NewKnots,NewMults,
|
|
Tolerance))
|
|
return Standard_False;
|
|
|
|
if (rational) GetPoles(newpoles,NewPoles,*NewWeights,UDirection);
|
|
else GetPoles(newpoles,NewPoles,UDirection);
|
|
return Standard_True;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : IncreaseDegree
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BSplSLib::IncreaseDegree
|
|
(const Standard_Boolean UDirection,
|
|
const Standard_Integer Degree,
|
|
const Standard_Integer NewDegree,
|
|
const Standard_Boolean Periodic,
|
|
const TColgp_Array2OfPnt& Poles,
|
|
const TColStd_Array2OfReal* Weights,
|
|
const TColStd_Array1OfReal& Knots,
|
|
const TColStd_Array1OfInteger& Mults,
|
|
TColgp_Array2OfPnt& NewPoles,
|
|
TColStd_Array2OfReal* NewWeights,
|
|
TColStd_Array1OfReal& NewKnots,
|
|
TColStd_Array1OfInteger& NewMults)
|
|
{
|
|
Standard_Boolean rational = Weights != NULL;
|
|
Standard_Integer dim = 3;
|
|
if (rational) dim++;
|
|
|
|
TColStd_Array1OfReal poles( 1, dim*Poles.RowLength()*Poles.ColLength());
|
|
TColStd_Array1OfReal
|
|
newpoles( 1, dim*NewPoles.RowLength()*NewPoles.ColLength());
|
|
|
|
if (rational) SetPoles(Poles,*Weights,poles,UDirection);
|
|
else SetPoles(Poles,poles,UDirection);
|
|
|
|
if (UDirection) {
|
|
dim *= Poles.RowLength();
|
|
}
|
|
else {
|
|
dim *= Poles.ColLength();
|
|
}
|
|
|
|
BSplCLib::IncreaseDegree(Degree,NewDegree,Periodic,dim,poles,Knots,Mults,
|
|
newpoles,NewKnots,NewMults);
|
|
|
|
if (rational) GetPoles(newpoles,NewPoles,*NewWeights,UDirection);
|
|
else GetPoles(newpoles,NewPoles,UDirection);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Unperiodize
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BSplSLib::Unperiodize
|
|
(const Standard_Boolean UDirection,
|
|
const Standard_Integer Degree,
|
|
const TColStd_Array1OfInteger& Mults,
|
|
const TColStd_Array1OfReal& Knots,
|
|
const TColgp_Array2OfPnt& Poles,
|
|
const TColStd_Array2OfReal* Weights,
|
|
TColStd_Array1OfInteger& NewMults,
|
|
TColStd_Array1OfReal& NewKnots,
|
|
TColgp_Array2OfPnt& NewPoles,
|
|
TColStd_Array2OfReal* NewWeights)
|
|
{
|
|
Standard_Boolean rational = Weights != NULL;
|
|
Standard_Integer dim = 3;
|
|
if (rational) dim++;
|
|
|
|
TColStd_Array1OfReal poles( 1, dim*Poles.RowLength()*Poles.ColLength());
|
|
TColStd_Array1OfReal
|
|
newpoles( 1, dim*NewPoles.RowLength()*NewPoles.ColLength());
|
|
|
|
if (rational) SetPoles(Poles,*Weights,poles,UDirection);
|
|
else SetPoles(Poles,poles,UDirection);
|
|
|
|
if (UDirection) {
|
|
dim *= Poles.RowLength();
|
|
}
|
|
else {
|
|
dim *= Poles.ColLength();
|
|
}
|
|
|
|
BSplCLib::Unperiodize(Degree, dim, Mults, Knots, poles,
|
|
NewMults, NewKnots, newpoles);
|
|
|
|
if (rational) GetPoles(newpoles,NewPoles,*NewWeights,UDirection);
|
|
else GetPoles(newpoles,NewPoles,UDirection);
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : BuildCache
|
|
//purpose : Stores theTaylor expansion normalized between 0,1 in the
|
|
// Cache : in case of a rational function the Poles are
|
|
// stored in homogeneous form
|
|
//=======================================================================
|
|
|
|
void BSplSLib::BuildCache
|
|
(const Standard_Real U,
|
|
const Standard_Real V,
|
|
const Standard_Real USpanDomain,
|
|
const Standard_Real VSpanDomain,
|
|
const Standard_Boolean UPeriodic,
|
|
const Standard_Boolean VPeriodic,
|
|
const Standard_Integer UDegree,
|
|
const Standard_Integer VDegree,
|
|
const Standard_Integer UIndex,
|
|
const Standard_Integer VIndex,
|
|
const TColStd_Array1OfReal& UFlatKnots,
|
|
const TColStd_Array1OfReal& VFlatKnots,
|
|
const TColgp_Array2OfPnt& Poles,
|
|
const TColStd_Array2OfReal* Weights,
|
|
TColgp_Array2OfPnt& CachePoles,
|
|
TColStd_Array2OfReal* CacheWeights)
|
|
{
|
|
Standard_Boolean rational,rational_u,rational_v,flag_u_or_v;
|
|
Standard_Integer kk,d1,d1p1,d2,d2p1,ii,jj,iii,jjj,Index;
|
|
Standard_Real u1,min_degree_domain,max_degree_domain,f,factor[2],u2;
|
|
if (Weights != NULL)
|
|
rational_u = rational_v = Standard_True;
|
|
else
|
|
rational_u = rational_v = Standard_False;
|
|
BSplSLib_DataContainer dc (UDegree, VDegree);
|
|
flag_u_or_v =
|
|
PrepareEval (U,
|
|
V,
|
|
UIndex,
|
|
VIndex,
|
|
UDegree,
|
|
VDegree,
|
|
rational_u,
|
|
rational_v,
|
|
UPeriodic,
|
|
VPeriodic,
|
|
Poles,
|
|
Weights,
|
|
UFlatKnots,
|
|
VFlatKnots,
|
|
(BSplCLib::NoMults()),
|
|
(BSplCLib::NoMults()),
|
|
u1,
|
|
u2,
|
|
d1,
|
|
d2,
|
|
rational,
|
|
dc);
|
|
d1p1 = d1 + 1;
|
|
d2p1 = d2 + 1;
|
|
if (rational) {
|
|
BSplCLib::Bohm(u1,d1,d1,*dc.knots1,4 * d2p1,*dc.poles);
|
|
|
|
for (kk = 0; kk <= d1 ; kk++)
|
|
BSplCLib::Bohm(u2,d2,d2,*dc.knots2,4,*(dc.poles + kk * 4 * d2p1));
|
|
if (flag_u_or_v) {
|
|
min_degree_domain = USpanDomain ;
|
|
max_degree_domain = VSpanDomain ;
|
|
}
|
|
else {
|
|
min_degree_domain = VSpanDomain ;
|
|
max_degree_domain = USpanDomain ;
|
|
}
|
|
factor[0] = 1.0e0 ;
|
|
|
|
for (ii = 0 ; ii <= d2 ; ii++) {
|
|
iii = ii + 1;
|
|
factor[1] = 1.0e0 ;
|
|
|
|
for (jj = 0 ; jj <= d1 ; jj++) {
|
|
jjj = jj + 1;
|
|
Index = jj * d2p1 + ii ;
|
|
Index = Index << 2;
|
|
gp_Pnt& P = CachePoles(iii,jjj);
|
|
f = factor[0] * factor[1];
|
|
P.SetX( f * dc.poles[Index]); Index++;
|
|
P.SetY( f * dc.poles[Index]); Index++;
|
|
P.SetZ( f * dc.poles[Index]); Index++;
|
|
(*CacheWeights)(iii ,jjj) = f * dc.poles[Index] ;
|
|
factor[1] *= min_degree_domain / (Standard_Real) (jjj) ;
|
|
}
|
|
factor[0] *= max_degree_domain / (Standard_Real) (iii) ;
|
|
}
|
|
}
|
|
else {
|
|
BSplCLib::Bohm(u1,d1,d1,*dc.knots1,3 * d2p1,*dc.poles);
|
|
|
|
for (kk = 0; kk <= d1 ; kk++)
|
|
BSplCLib::Bohm(u2,d2,d2,*dc.knots2,3,*(dc.poles + kk * 3 * d2p1));
|
|
if (flag_u_or_v) {
|
|
min_degree_domain = USpanDomain ;
|
|
max_degree_domain = VSpanDomain ;
|
|
}
|
|
else {
|
|
min_degree_domain = VSpanDomain ;
|
|
max_degree_domain = USpanDomain ;
|
|
}
|
|
factor[0] = 1.0e0 ;
|
|
|
|
for (ii = 0 ; ii <= d2 ; ii++) {
|
|
iii = ii + 1;
|
|
factor[1] = 1.0e0 ;
|
|
|
|
for (jj = 0 ; jj <= d1 ; jj++) {
|
|
jjj = jj + 1;
|
|
Index = jj * d2p1 + ii ;
|
|
Index = (Index << 1) + Index;
|
|
gp_Pnt& P = CachePoles(iii,jjj);
|
|
f = factor[0] * factor[1];
|
|
P.SetX( f * dc.poles[Index]); Index++;
|
|
P.SetY( f * dc.poles[Index]); Index++;
|
|
P.SetZ( f * dc.poles[Index]);
|
|
factor[1] *= min_degree_domain / (Standard_Real) (jjj) ;
|
|
}
|
|
factor[0] *= max_degree_domain / (Standard_Real) (iii) ;
|
|
}
|
|
if (Weights != NULL) {
|
|
//
|
|
// means that PrepareEval did found out that the surface was
|
|
// locally polynomial but since the surface is constructed
|
|
// with some weights we need to set the weight polynomial to constant
|
|
//
|
|
|
|
for (ii = 1 ; ii <= d2p1 ; ii++) {
|
|
|
|
for (jj = 1 ; jj <= d1p1 ; jj++) {
|
|
(*CacheWeights)(ii,jj) = 0.0e0 ;
|
|
}
|
|
}
|
|
(*CacheWeights)(1,1) = 1.0e0 ;
|
|
}
|
|
}
|
|
}
|
|
|
|
void BSplSLib::BuildCache(const Standard_Real theU,
|
|
const Standard_Real theV,
|
|
const Standard_Real theUSpanDomain,
|
|
const Standard_Real theVSpanDomain,
|
|
const Standard_Boolean theUPeriodicFlag,
|
|
const Standard_Boolean theVPeriodicFlag,
|
|
const Standard_Integer theUDegree,
|
|
const Standard_Integer theVDegree,
|
|
const Standard_Integer theUIndex,
|
|
const Standard_Integer theVIndex,
|
|
const TColStd_Array1OfReal& theUFlatKnots,
|
|
const TColStd_Array1OfReal& theVFlatKnots,
|
|
const TColgp_Array2OfPnt& thePoles,
|
|
const TColStd_Array2OfReal* theWeights,
|
|
TColStd_Array2OfReal& theCacheArray)
|
|
{
|
|
Standard_Boolean flag_u_or_v;
|
|
Standard_Integer d1, d2;
|
|
Standard_Real u1, u2;
|
|
Standard_Boolean isRationalOnParam = (theWeights != NULL);
|
|
Standard_Boolean isRational;
|
|
|
|
BSplSLib_DataContainer dc(theUDegree, theVDegree);
|
|
flag_u_or_v =
|
|
PrepareEval(theU, theV, theUIndex, theVIndex, theUDegree, theVDegree,
|
|
isRationalOnParam, isRationalOnParam,
|
|
theUPeriodicFlag, theVPeriodicFlag,
|
|
thePoles, theWeights,
|
|
theUFlatKnots, theVFlatKnots,
|
|
(BSplCLib::NoMults()), (BSplCLib::NoMults()),
|
|
u1, u2, d1, d2, isRational, dc);
|
|
|
|
Standard_Integer d2p1 = d2 + 1;
|
|
Standard_Integer aDimension = isRational ? 4 : 3;
|
|
Standard_Integer aCacheShift = // helps to store weights when PrepareEval did not found that the surface is locally polynomial
|
|
(isRationalOnParam && !isRational) ? aDimension + 1 : aDimension;
|
|
|
|
Standard_Real aDomains[2];
|
|
// aDomains[0] corresponds to variable with minimal degree
|
|
// aDomains[1] corresponds to variable with maximal degree
|
|
if (flag_u_or_v)
|
|
{
|
|
aDomains[0] = theUSpanDomain;
|
|
aDomains[1] = theVSpanDomain;
|
|
}
|
|
else
|
|
{
|
|
aDomains[0] = theVSpanDomain;
|
|
aDomains[1] = theUSpanDomain;
|
|
}
|
|
|
|
BSplCLib::Bohm(u1, d1, d1, *dc.knots1, aDimension * d2p1, *dc.poles);
|
|
for (Standard_Integer kk = 0; kk <= d1 ; kk++)
|
|
BSplCLib::Bohm(u2, d2, d2, *dc.knots2, aDimension, *(dc.poles + kk * aDimension * d2p1));
|
|
|
|
Standard_Real* aCache = (Standard_Real *) &(theCacheArray(theCacheArray.LowerRow(), theCacheArray.LowerCol()));
|
|
Standard_Real* aPolyCoeffs = dc.poles;
|
|
|
|
Standard_Real aFactors[2];
|
|
// aFactors[0] corresponds to variable with minimal degree
|
|
// aFactors[1] corresponds to variable with maximal degree
|
|
aFactors[1] = 1.0;
|
|
Standard_Integer aRow, aCol, i;
|
|
Standard_Real aCoeff;
|
|
for (aRow = 0; aRow <= d2; aRow++)
|
|
{
|
|
aFactors[0] = 1.0;
|
|
for (aCol = 0; aCol <= d1; aCol++)
|
|
{
|
|
aPolyCoeffs = dc.poles + (aCol * d2p1 + aRow) * aDimension;
|
|
aCoeff = aFactors[0] * aFactors[1];
|
|
for (i = 0; i < aDimension; i++)
|
|
aCache[i] = aPolyCoeffs[i] * aCoeff;
|
|
aCache += aCacheShift;
|
|
aFactors[0] *= aDomains[0] / (aCol + 1);
|
|
}
|
|
aFactors[1] *= aDomains[1] / (aRow + 1);
|
|
}
|
|
|
|
// Fill the weights for the surface which is not locally polynomial
|
|
if (aCacheShift > aDimension)
|
|
{
|
|
aCache = (Standard_Real *) &(theCacheArray(theCacheArray.LowerRow(), theCacheArray.LowerCol()));
|
|
aCache += aCacheShift - 1;
|
|
for (aRow = 0; aRow <= d2; aRow++)
|
|
for (aCol = 0; aCol <= d1; aCol++)
|
|
{
|
|
*aCache = 0.0;
|
|
aCache += aCacheShift;
|
|
}
|
|
theCacheArray.SetValue(theCacheArray.LowerRow(), theCacheArray.LowerCol() + aCacheShift - 1, 1.0);
|
|
}
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
//function : CacheD0
|
|
//purpose : Evaluates the polynomial cache of the Bspline Curve
|
|
//
|
|
//=======================================================================
|
|
|
|
void BSplSLib::CacheD0(const Standard_Real UParameter,
|
|
const Standard_Real VParameter,
|
|
const Standard_Integer UDegree,
|
|
const Standard_Integer VDegree,
|
|
const Standard_Real UCacheParameter,
|
|
const Standard_Real VCacheParameter,
|
|
const Standard_Real USpanLenght,
|
|
const Standard_Real VSpanLenght,
|
|
const TColgp_Array2OfPnt& PolesArray,
|
|
const TColStd_Array2OfReal* WeightsArray,
|
|
gp_Pnt& aPoint)
|
|
{
|
|
//
|
|
// the CacheParameter is where the cache polynomial was evaluated in homogeneous
|
|
// form
|
|
// the SpanLenght is the normalizing factor so that the polynomial is between
|
|
// 0 and 1
|
|
Standard_Integer
|
|
// ii,
|
|
dimension,
|
|
min_degree,
|
|
max_degree ;
|
|
|
|
Standard_Real
|
|
new_parameter[2] ,
|
|
inverse ;
|
|
|
|
Standard_Real *
|
|
PArray = (Standard_Real *)
|
|
&(PolesArray(PolesArray.LowerCol(), PolesArray.LowerRow())) ;
|
|
Standard_Real *
|
|
myPoint = (Standard_Real *) &aPoint ;
|
|
if (UDegree <= VDegree) {
|
|
min_degree = UDegree ;
|
|
max_degree = VDegree ;
|
|
new_parameter[1] = (UParameter - UCacheParameter) / USpanLenght ;
|
|
new_parameter[0] = (VParameter - VCacheParameter) / VSpanLenght ;
|
|
dimension = 3 * (UDegree + 1) ;
|
|
}
|
|
else {
|
|
min_degree = VDegree ;
|
|
max_degree = UDegree ;
|
|
new_parameter[0] = (UParameter - UCacheParameter) / USpanLenght ;
|
|
new_parameter[1] = (VParameter - VCacheParameter) / VSpanLenght ;
|
|
dimension = 3 * (VDegree + 1) ;
|
|
}
|
|
NCollection_LocalArray<Standard_Real> locpoles(dimension);
|
|
|
|
PLib::NoDerivativeEvalPolynomial(new_parameter[0],
|
|
max_degree,
|
|
dimension,
|
|
max_degree*dimension,
|
|
PArray[0],
|
|
locpoles[0]) ;
|
|
|
|
PLib::NoDerivativeEvalPolynomial(new_parameter[1],
|
|
min_degree,
|
|
3,
|
|
(min_degree << 1) + min_degree,
|
|
locpoles[0],
|
|
myPoint[0]) ;
|
|
if (WeightsArray != NULL) {
|
|
dimension = min_degree + 1 ;
|
|
const TColStd_Array2OfReal& refWeights = *WeightsArray;
|
|
Standard_Real *
|
|
WArray = (Standard_Real *)
|
|
&refWeights(refWeights.LowerCol(),refWeights.LowerRow()) ;
|
|
PLib::NoDerivativeEvalPolynomial(new_parameter[0],
|
|
max_degree,
|
|
dimension,
|
|
max_degree*dimension,
|
|
WArray[0],
|
|
locpoles[0]) ;
|
|
|
|
PLib::NoDerivativeEvalPolynomial(new_parameter[1],
|
|
min_degree,
|
|
1,
|
|
min_degree,
|
|
locpoles[0],
|
|
inverse) ;
|
|
inverse = 1.0e0/ inverse ;
|
|
|
|
myPoint[0] *= inverse ;
|
|
myPoint[1] *= inverse ;
|
|
myPoint[2] *= inverse ;
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : CacheD1
|
|
//purpose : Evaluates the polynomial cache of the Bspline Curve
|
|
//
|
|
//=======================================================================
|
|
|
|
void BSplSLib::CacheD1(const Standard_Real UParameter,
|
|
const Standard_Real VParameter,
|
|
const Standard_Integer UDegree,
|
|
const Standard_Integer VDegree,
|
|
const Standard_Real UCacheParameter,
|
|
const Standard_Real VCacheParameter,
|
|
const Standard_Real USpanLenght,
|
|
const Standard_Real VSpanLenght,
|
|
const TColgp_Array2OfPnt& PolesArray,
|
|
const TColStd_Array2OfReal* WeightsArray,
|
|
gp_Pnt& aPoint,
|
|
gp_Vec& aVecU,
|
|
gp_Vec& aVecV)
|
|
{
|
|
//
|
|
// the CacheParameter is where the cache polynomial was evaluated in homogeneous
|
|
// form
|
|
// the SpanLenght is the normalizing factor so that the polynomial is between
|
|
// 0 and 1
|
|
Standard_Integer
|
|
// ii,
|
|
// jj,
|
|
// kk,
|
|
dimension,
|
|
min_degree,
|
|
max_degree ;
|
|
|
|
Standard_Real
|
|
inverse_min,
|
|
inverse_max,
|
|
new_parameter[2] ;
|
|
|
|
Standard_Real *
|
|
PArray = (Standard_Real *)
|
|
&(PolesArray(PolesArray.LowerCol(), PolesArray.LowerRow())) ;
|
|
Standard_Real local_poles_array[2][2][3],
|
|
local_poles_and_weights_array[2][2][4],
|
|
local_weights_array[2][2] ;
|
|
Standard_Real * my_vec_min,
|
|
* my_vec_max,
|
|
* my_point ;
|
|
my_point = (Standard_Real *) &aPoint ;
|
|
//
|
|
// initialize in case of rational evaluation
|
|
// because RationalDerivative will use all
|
|
// the coefficients
|
|
//
|
|
//
|
|
if (WeightsArray != NULL) {
|
|
|
|
local_poles_array [0][0][0] = 0.0e0 ;
|
|
local_poles_array [0][0][1] = 0.0e0 ;
|
|
local_poles_array [0][0][2] = 0.0e0 ;
|
|
local_weights_array [0][0] = 0.0e0 ;
|
|
local_poles_and_weights_array[0][0][0] = 0.0e0 ;
|
|
local_poles_and_weights_array[0][0][1] = 0.0e0 ;
|
|
local_poles_and_weights_array[0][0][2] = 0.0e0 ;
|
|
local_poles_and_weights_array[0][0][3] = 0.0e0 ;
|
|
|
|
local_poles_array [0][1][0] = 0.0e0 ;
|
|
local_poles_array [0][1][1] = 0.0e0 ;
|
|
local_poles_array [0][1][2] = 0.0e0 ;
|
|
local_weights_array [0][1] = 0.0e0 ;
|
|
local_poles_and_weights_array[0][1][0] = 0.0e0 ;
|
|
local_poles_and_weights_array[0][1][1] = 0.0e0 ;
|
|
local_poles_and_weights_array[0][1][2] = 0.0e0 ;
|
|
local_poles_and_weights_array[0][1][3] = 0.0e0 ;
|
|
|
|
local_poles_array [1][0][0] = 0.0e0 ;
|
|
local_poles_array [1][0][1] = 0.0e0 ;
|
|
local_poles_array [1][0][2] = 0.0e0 ;
|
|
local_weights_array [1][0] = 0.0e0 ;
|
|
local_poles_and_weights_array[1][0][0] = 0.0e0 ;
|
|
local_poles_and_weights_array[1][0][1] = 0.0e0 ;
|
|
local_poles_and_weights_array[1][0][2] = 0.0e0 ;
|
|
local_poles_and_weights_array[1][0][3] = 0.0e0 ;
|
|
|
|
local_poles_array [1][1][0] = 0.0e0 ;
|
|
local_poles_array [1][1][1] = 0.0e0 ;
|
|
local_poles_array [1][1][2] = 0.0e0 ;
|
|
local_weights_array [1][1] = 0.0e0 ;
|
|
local_poles_and_weights_array[1][1][0] = 0.0e0 ;
|
|
local_poles_and_weights_array[1][1][1] = 0.0e0 ;
|
|
local_poles_and_weights_array[1][1][2] = 0.0e0 ;
|
|
local_poles_and_weights_array[1][1][3] = 0.0e0 ;
|
|
}
|
|
|
|
if (UDegree <= VDegree) {
|
|
min_degree = UDegree ;
|
|
max_degree = VDegree ;
|
|
inverse_min = 1.0e0/USpanLenght ;
|
|
inverse_max = 1.0e0/VSpanLenght ;
|
|
new_parameter[0] = (VParameter - VCacheParameter) * inverse_max ;
|
|
new_parameter[1] = (UParameter - UCacheParameter) * inverse_min ;
|
|
|
|
dimension = 3 * (UDegree + 1) ;
|
|
my_vec_min = (Standard_Real *) &aVecU ;
|
|
my_vec_max = (Standard_Real *) &aVecV ;
|
|
}
|
|
else {
|
|
min_degree = VDegree ;
|
|
max_degree = UDegree ;
|
|
inverse_min = 1.0e0/VSpanLenght ;
|
|
inverse_max = 1.0e0/USpanLenght ;
|
|
new_parameter[0] = (UParameter - UCacheParameter) * inverse_max ;
|
|
new_parameter[1] = (VParameter - VCacheParameter) * inverse_min ;
|
|
dimension = 3 * (VDegree + 1) ;
|
|
my_vec_min = (Standard_Real *) &aVecV ;
|
|
my_vec_max = (Standard_Real *) &aVecU ;
|
|
}
|
|
|
|
NCollection_LocalArray<Standard_Real> locpoles (2 * dimension);
|
|
|
|
PLib::EvalPolynomial(new_parameter[0],
|
|
1,
|
|
max_degree,
|
|
dimension,
|
|
PArray[0],
|
|
locpoles[0]) ;
|
|
|
|
PLib::EvalPolynomial(new_parameter[1],
|
|
1,
|
|
min_degree,
|
|
3,
|
|
locpoles[0],
|
|
local_poles_array[0][0][0]) ;
|
|
PLib::NoDerivativeEvalPolynomial(new_parameter[1],
|
|
min_degree,
|
|
3,
|
|
(min_degree << 1) + min_degree,
|
|
locpoles[dimension],
|
|
local_poles_array[1][0][0]) ;
|
|
|
|
if (WeightsArray != NULL) {
|
|
dimension = min_degree + 1 ;
|
|
const TColStd_Array2OfReal& refWeights = *WeightsArray;
|
|
Standard_Real *
|
|
WArray = (Standard_Real *)
|
|
&refWeights(refWeights.LowerCol(),refWeights.LowerRow()) ;
|
|
PLib::EvalPolynomial(new_parameter[0],
|
|
1,
|
|
max_degree,
|
|
dimension,
|
|
WArray[0],
|
|
locpoles[0]) ;
|
|
|
|
PLib::EvalPolynomial(new_parameter[1],
|
|
1,
|
|
min_degree,
|
|
1,
|
|
locpoles[0],
|
|
local_weights_array[0][0]) ;
|
|
PLib::NoDerivativeEvalPolynomial(new_parameter[1],
|
|
min_degree,
|
|
1,
|
|
min_degree,
|
|
locpoles[dimension],
|
|
local_weights_array[1][0]) ;
|
|
|
|
local_poles_and_weights_array[0][0][0] = local_poles_array [0][0][0] ;
|
|
local_poles_and_weights_array[0][0][1] = local_poles_array [0][0][1] ;
|
|
local_poles_and_weights_array[0][0][2] = local_poles_array [0][0][2] ;
|
|
local_poles_and_weights_array[0][0][3] = local_weights_array[0][0] ;
|
|
|
|
local_poles_and_weights_array[0][1][0] = local_poles_array [0][1][0] ;
|
|
local_poles_and_weights_array[0][1][1] = local_poles_array [0][1][1] ;
|
|
local_poles_and_weights_array[0][1][2] = local_poles_array [0][1][2] ;
|
|
local_poles_and_weights_array[0][1][3] = local_weights_array[0][1] ;
|
|
|
|
local_poles_and_weights_array[1][0][0] = local_poles_array [1][0][0] ;
|
|
local_poles_and_weights_array[1][0][1] = local_poles_array [1][0][1] ;
|
|
local_poles_and_weights_array[1][0][2] = local_poles_array [1][0][2] ;
|
|
local_poles_and_weights_array[1][0][3] = local_weights_array[1][0] ;
|
|
|
|
local_poles_and_weights_array[1][1][0] = local_poles_array [1][1][0] ;
|
|
local_poles_and_weights_array[1][1][1] = local_poles_array [1][1][1] ;
|
|
local_poles_and_weights_array[1][1][2] = local_poles_array [1][1][2] ;
|
|
local_poles_and_weights_array[1][1][3] = local_weights_array[1][1] ;
|
|
|
|
BSplSLib::RationalDerivative(1,
|
|
1,
|
|
1,
|
|
1,
|
|
local_poles_and_weights_array[0][0][0],
|
|
local_poles_array[0][0][0]) ;
|
|
}
|
|
|
|
my_point [0] = local_poles_array [0][0][0] ;
|
|
my_vec_min[0] = inverse_min * local_poles_array[0][1][0] ;
|
|
my_vec_max[0] = inverse_max * local_poles_array[1][0][0] ;
|
|
|
|
my_point [1] = local_poles_array [0][0][1] ;
|
|
my_vec_min[1] = inverse_min * local_poles_array[0][1][1] ;
|
|
my_vec_max[1] = inverse_max * local_poles_array[1][0][1] ;
|
|
|
|
my_point [2] = local_poles_array [0][0][2] ;
|
|
my_vec_min[2] = inverse_min * local_poles_array[0][1][2] ;
|
|
my_vec_max[2] = inverse_max * local_poles_array[1][0][2] ;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : CacheD2
|
|
//purpose : Evaluates the polynomial cache of the Bspline Curve
|
|
//
|
|
//=======================================================================
|
|
|
|
void BSplSLib::CacheD2(const Standard_Real UParameter,
|
|
const Standard_Real VParameter,
|
|
const Standard_Integer UDegree,
|
|
const Standard_Integer VDegree,
|
|
const Standard_Real UCacheParameter,
|
|
const Standard_Real VCacheParameter,
|
|
const Standard_Real USpanLenght,
|
|
const Standard_Real VSpanLenght,
|
|
const TColgp_Array2OfPnt& PolesArray,
|
|
const TColStd_Array2OfReal* WeightsArray,
|
|
gp_Pnt& aPoint,
|
|
gp_Vec& aVecU,
|
|
gp_Vec& aVecV,
|
|
gp_Vec& aVecUU,
|
|
gp_Vec& aVecUV,
|
|
gp_Vec& aVecVV)
|
|
{
|
|
//
|
|
// the CacheParameter is where the cache polynomial was evaluated in homogeneous
|
|
// form
|
|
// the SpanLenght is the normalizing factor so that the polynomial is between
|
|
// 0 and 1
|
|
Standard_Integer
|
|
ii,
|
|
// jj,
|
|
kk,
|
|
index,
|
|
dimension,
|
|
min_degree,
|
|
max_degree ;
|
|
|
|
Standard_Real
|
|
inverse_min,
|
|
inverse_max,
|
|
new_parameter[2] ;
|
|
|
|
Standard_Real *
|
|
PArray = (Standard_Real *)
|
|
&(PolesArray(PolesArray.LowerCol(), PolesArray.LowerRow())) ;
|
|
Standard_Real local_poles_array[3][3][3],
|
|
local_poles_and_weights_array[3][3][4],
|
|
local_weights_array[3][3] ;
|
|
Standard_Real * my_vec_min,
|
|
* my_vec_max,
|
|
* my_vec_min_min,
|
|
* my_vec_max_max,
|
|
* my_vec_min_max,
|
|
* my_point ;
|
|
my_point = (Standard_Real *) &aPoint ;
|
|
|
|
//
|
|
// initialize in case the min and max degree are less than 2
|
|
//
|
|
local_poles_array[0][0][0] = 0.0e0 ;
|
|
local_poles_array[0][0][1] = 0.0e0 ;
|
|
local_poles_array[0][0][2] = 0.0e0 ;
|
|
local_poles_array[0][1][0] = 0.0e0 ;
|
|
local_poles_array[0][1][1] = 0.0e0 ;
|
|
local_poles_array[0][1][2] = 0.0e0 ;
|
|
local_poles_array[0][2][0] = 0.0e0 ;
|
|
local_poles_array[0][2][1] = 0.0e0 ;
|
|
local_poles_array[0][2][2] = 0.0e0 ;
|
|
|
|
local_poles_array[1][0][0] = 0.0e0 ;
|
|
local_poles_array[1][0][1] = 0.0e0 ;
|
|
local_poles_array[1][0][2] = 0.0e0 ;
|
|
local_poles_array[1][1][0] = 0.0e0 ;
|
|
local_poles_array[1][1][1] = 0.0e0 ;
|
|
local_poles_array[1][1][2] = 0.0e0 ;
|
|
local_poles_array[1][2][0] = 0.0e0 ;
|
|
local_poles_array[1][2][1] = 0.0e0 ;
|
|
local_poles_array[1][2][2] = 0.0e0 ;
|
|
|
|
local_poles_array[2][0][0] = 0.0e0 ;
|
|
local_poles_array[2][0][1] = 0.0e0 ;
|
|
local_poles_array[2][0][2] = 0.0e0 ;
|
|
local_poles_array[2][1][0] = 0.0e0 ;
|
|
local_poles_array[2][1][1] = 0.0e0 ;
|
|
local_poles_array[2][1][2] = 0.0e0 ;
|
|
local_poles_array[2][2][0] = 0.0e0 ;
|
|
local_poles_array[2][2][1] = 0.0e0 ;
|
|
local_poles_array[2][2][2] = 0.0e0 ;
|
|
//
|
|
// initialize in case of rational evaluation
|
|
// because RationalDerivative will use all
|
|
// the coefficients
|
|
//
|
|
//
|
|
if (WeightsArray != NULL) {
|
|
|
|
local_poles_and_weights_array[0][0][0] = 0.0e0 ;
|
|
local_poles_and_weights_array[0][0][1] = 0.0e0 ;
|
|
local_poles_and_weights_array[0][0][2] = 0.0e0 ;
|
|
local_poles_and_weights_array[0][1][0] = 0.0e0 ;
|
|
local_poles_and_weights_array[0][1][1] = 0.0e0 ;
|
|
local_poles_and_weights_array[0][1][2] = 0.0e0 ;
|
|
local_poles_and_weights_array[0][2][0] = 0.0e0 ;
|
|
local_poles_and_weights_array[0][2][1] = 0.0e0 ;
|
|
local_poles_and_weights_array[0][2][2] = 0.0e0 ;
|
|
|
|
local_poles_and_weights_array[1][0][0] = 0.0e0 ;
|
|
local_poles_and_weights_array[1][0][1] = 0.0e0 ;
|
|
local_poles_and_weights_array[1][0][2] = 0.0e0 ;
|
|
local_poles_and_weights_array[1][1][0] = 0.0e0 ;
|
|
local_poles_and_weights_array[1][1][1] = 0.0e0 ;
|
|
local_poles_and_weights_array[1][1][2] = 0.0e0 ;
|
|
local_poles_and_weights_array[1][2][0] = 0.0e0 ;
|
|
local_poles_and_weights_array[1][2][1] = 0.0e0 ;
|
|
local_poles_and_weights_array[1][2][2] = 0.0e0 ;
|
|
|
|
local_poles_and_weights_array[2][0][0] = 0.0e0 ;
|
|
local_poles_and_weights_array[2][0][1] = 0.0e0 ;
|
|
local_poles_and_weights_array[2][0][2] = 0.0e0 ;
|
|
local_poles_and_weights_array[2][1][0] = 0.0e0 ;
|
|
local_poles_and_weights_array[2][1][1] = 0.0e0 ;
|
|
local_poles_and_weights_array[2][1][2] = 0.0e0 ;
|
|
local_poles_and_weights_array[2][2][0] = 0.0e0 ;
|
|
local_poles_and_weights_array[2][2][1] = 0.0e0 ;
|
|
local_poles_and_weights_array[2][2][2] = 0.0e0 ;
|
|
|
|
local_poles_and_weights_array[0][0][3] =
|
|
local_weights_array[0][0] = 0.0e0 ;
|
|
local_poles_and_weights_array[0][1][3] =
|
|
local_weights_array[0][1] = 0.0e0 ;
|
|
local_poles_and_weights_array[0][2][3] =
|
|
local_weights_array[0][2] = 0.0e0 ;
|
|
local_poles_and_weights_array[1][0][3] =
|
|
local_weights_array[1][0] = 0.0e0 ;
|
|
local_poles_and_weights_array[1][1][3] =
|
|
local_weights_array[1][1] = 0.0e0 ;
|
|
local_poles_and_weights_array[1][2][3] =
|
|
local_weights_array[1][2] = 0.0e0 ;
|
|
local_poles_and_weights_array[2][0][3] =
|
|
local_weights_array[2][0] = 0.0e0 ;
|
|
local_poles_and_weights_array[2][1][3] =
|
|
local_weights_array[2][1] = 0.0e0 ;
|
|
local_poles_and_weights_array[2][2][3] =
|
|
local_weights_array[2][2] = 0.0e0 ;
|
|
}
|
|
|
|
if (UDegree <= VDegree) {
|
|
min_degree = UDegree ;
|
|
max_degree = VDegree ;
|
|
inverse_min = 1.0e0/USpanLenght ;
|
|
inverse_max = 1.0e0/VSpanLenght ;
|
|
new_parameter[0] = (VParameter - VCacheParameter) * inverse_max ;
|
|
new_parameter[1] = (UParameter - UCacheParameter) * inverse_min ;
|
|
|
|
dimension = 3 * (UDegree + 1) ;
|
|
my_vec_min = (Standard_Real *) &aVecU ;
|
|
my_vec_max = (Standard_Real *) &aVecV ;
|
|
my_vec_min_min = (Standard_Real *) &aVecUU ;
|
|
my_vec_min_max = (Standard_Real *) &aVecUV ;
|
|
my_vec_max_max = (Standard_Real *) &aVecVV ;
|
|
}
|
|
else {
|
|
min_degree = VDegree ;
|
|
max_degree = UDegree ;
|
|
inverse_min = 1.0e0/VSpanLenght ;
|
|
inverse_max = 1.0e0/USpanLenght ;
|
|
new_parameter[0] = (UParameter - UCacheParameter) * inverse_max ;
|
|
new_parameter[1] = (VParameter - VCacheParameter) * inverse_min ;
|
|
dimension = 3 * (VDegree + 1) ;
|
|
my_vec_min = (Standard_Real *) &aVecV ;
|
|
my_vec_max = (Standard_Real *) &aVecU ;
|
|
my_vec_min_min = (Standard_Real *) &aVecVV ;
|
|
my_vec_min_max = (Standard_Real *) &aVecUV ;
|
|
my_vec_max_max = (Standard_Real *) &aVecUU ;
|
|
}
|
|
|
|
NCollection_LocalArray<Standard_Real> locpoles (3 * dimension);
|
|
|
|
//
|
|
// initialize in case min or max degree are less than 2
|
|
//
|
|
Standard_Integer MinIndMax = 2;
|
|
if ( max_degree < 2) MinIndMax = max_degree;
|
|
Standard_Integer MinIndMin = 2;
|
|
if ( min_degree < 2) MinIndMin = min_degree;
|
|
|
|
index = MinIndMax * dimension ;
|
|
|
|
for (ii = MinIndMax ; ii < 3 ; ii++) {
|
|
|
|
for (kk = 0 ; kk < dimension ; kk++) {
|
|
locpoles[index] = 0.0e0 ;
|
|
index += 1 ;
|
|
}
|
|
}
|
|
|
|
PLib::EvalPolynomial(new_parameter[0],
|
|
MinIndMax,
|
|
max_degree,
|
|
dimension,
|
|
PArray[0],
|
|
locpoles[0]) ;
|
|
|
|
PLib::EvalPolynomial(new_parameter[1],
|
|
MinIndMin,
|
|
min_degree,
|
|
3,
|
|
locpoles[0],
|
|
local_poles_array[0][0][0]) ;
|
|
PLib::EvalPolynomial(new_parameter[1],
|
|
1,
|
|
min_degree,
|
|
3,
|
|
locpoles[dimension],
|
|
local_poles_array[1][0][0]) ;
|
|
|
|
PLib::NoDerivativeEvalPolynomial(new_parameter[1],
|
|
min_degree,
|
|
3,
|
|
(min_degree << 1) + min_degree,
|
|
locpoles[dimension + dimension],
|
|
local_poles_array[2][0][0]) ;
|
|
|
|
if (WeightsArray != NULL) {
|
|
dimension = min_degree + 1 ;
|
|
const TColStd_Array2OfReal& refWeights = *WeightsArray;
|
|
Standard_Real *
|
|
WArray = (Standard_Real *)
|
|
&refWeights(refWeights.LowerCol(),refWeights.LowerRow()) ;
|
|
PLib::EvalPolynomial(new_parameter[0],
|
|
MinIndMax,
|
|
max_degree,
|
|
dimension,
|
|
WArray[0],
|
|
locpoles[0]) ;
|
|
|
|
PLib::EvalPolynomial(new_parameter[1],
|
|
MinIndMin,
|
|
min_degree,
|
|
1,
|
|
locpoles[0],
|
|
local_weights_array[0][0]) ;
|
|
PLib::EvalPolynomial(new_parameter[1],
|
|
1,
|
|
min_degree,
|
|
1,
|
|
locpoles[dimension],
|
|
local_weights_array[1][0]) ;
|
|
PLib::NoDerivativeEvalPolynomial(new_parameter[1],
|
|
min_degree,
|
|
1,
|
|
min_degree,
|
|
locpoles[dimension + dimension],
|
|
local_weights_array[2][0]) ;
|
|
|
|
|
|
local_poles_and_weights_array[0][0][0] = local_poles_array[0][0][0];
|
|
local_poles_and_weights_array[0][0][1] = local_poles_array[0][0][1];
|
|
local_poles_and_weights_array[0][0][2] = local_poles_array[0][0][2];
|
|
local_poles_and_weights_array[0][1][0] = local_poles_array[0][1][0];
|
|
local_poles_and_weights_array[0][1][1] = local_poles_array[0][1][1];
|
|
local_poles_and_weights_array[0][1][2] = local_poles_array[0][1][2];
|
|
local_poles_and_weights_array[0][2][0] = local_poles_array[0][2][0];
|
|
local_poles_and_weights_array[0][2][1] = local_poles_array[0][2][1];
|
|
local_poles_and_weights_array[0][2][2] = local_poles_array[0][2][2];
|
|
|
|
local_poles_and_weights_array[1][0][0] = local_poles_array[1][0][0];
|
|
local_poles_and_weights_array[1][0][1] = local_poles_array[1][0][1];
|
|
local_poles_and_weights_array[1][0][2] = local_poles_array[1][0][2];
|
|
local_poles_and_weights_array[1][1][0] = local_poles_array[1][1][0];
|
|
local_poles_and_weights_array[1][1][1] = local_poles_array[1][1][1];
|
|
local_poles_and_weights_array[1][1][2] = local_poles_array[1][1][2];
|
|
local_poles_and_weights_array[1][2][0] = local_poles_array[1][2][0];
|
|
local_poles_and_weights_array[1][2][1] = local_poles_array[1][2][1];
|
|
local_poles_and_weights_array[1][2][2] = local_poles_array[1][2][2];
|
|
|
|
local_poles_and_weights_array[2][0][0] = local_poles_array[2][0][0];
|
|
local_poles_and_weights_array[2][0][1] = local_poles_array[2][0][1];
|
|
local_poles_and_weights_array[2][0][2] = local_poles_array[2][0][2];
|
|
local_poles_and_weights_array[2][1][0] = local_poles_array[2][1][0];
|
|
local_poles_and_weights_array[2][1][1] = local_poles_array[2][1][1];
|
|
local_poles_and_weights_array[2][1][2] = local_poles_array[2][1][2];
|
|
local_poles_and_weights_array[2][2][0] = local_poles_array[2][2][0];
|
|
local_poles_and_weights_array[2][2][1] = local_poles_array[2][2][1];
|
|
local_poles_and_weights_array[2][2][2] = local_poles_array[2][2][2];
|
|
|
|
|
|
local_poles_and_weights_array[0][0][3] = local_weights_array[0][0];
|
|
local_poles_and_weights_array[0][1][3] = local_weights_array[0][1];
|
|
local_poles_and_weights_array[0][2][3] = local_weights_array[0][2];
|
|
local_poles_and_weights_array[1][0][3] = local_weights_array[1][0];
|
|
local_poles_and_weights_array[1][1][3] = local_weights_array[1][1];
|
|
local_poles_and_weights_array[1][2][3] = local_weights_array[1][2];
|
|
local_poles_and_weights_array[2][0][3] = local_weights_array[2][0];
|
|
local_poles_and_weights_array[2][1][3] = local_weights_array[2][1];
|
|
local_poles_and_weights_array[2][2][3] = local_weights_array[2][2];
|
|
|
|
BSplSLib::RationalDerivative(2,
|
|
2,
|
|
2,
|
|
2,
|
|
local_poles_and_weights_array[0][0][0],
|
|
local_poles_array[0][0][0]) ;
|
|
}
|
|
|
|
|
|
Standard_Real minmin = inverse_min * inverse_min;
|
|
Standard_Real minmax = inverse_min * inverse_max;
|
|
Standard_Real maxmax = inverse_max * inverse_max;
|
|
|
|
my_point [0] = local_poles_array [0][0][0] ;
|
|
my_vec_min [0] = inverse_min * local_poles_array[0][1][0] ;
|
|
my_vec_max [0] = inverse_max * local_poles_array[1][0][0] ;
|
|
my_vec_min_min[0] = minmin * local_poles_array [0][2][0] ;
|
|
my_vec_min_max[0] = minmax * local_poles_array [1][1][0] ;
|
|
my_vec_max_max[0] = maxmax * local_poles_array [2][0][0] ;
|
|
|
|
my_point [1] = local_poles_array [0][0][1] ;
|
|
my_vec_min [1] = inverse_min * local_poles_array[0][1][1] ;
|
|
my_vec_max [1] = inverse_max * local_poles_array[1][0][1] ;
|
|
my_vec_min_min[1] = minmin * local_poles_array [0][2][1] ;
|
|
my_vec_min_max[1] = minmax * local_poles_array [1][1][1] ;
|
|
my_vec_max_max[1] = maxmax * local_poles_array [2][0][1] ;
|
|
|
|
my_point [2] = local_poles_array [0][0][2] ;
|
|
my_vec_min [2] = inverse_min * local_poles_array[0][1][2] ;
|
|
my_vec_max [2] = inverse_max * local_poles_array[1][0][2] ;
|
|
my_vec_min_min[2] = minmin * local_poles_array [0][2][2] ;
|
|
my_vec_min_max[2] = minmax * local_poles_array [1][1][2] ;
|
|
my_vec_max_max[2] = maxmax * local_poles_array [2][0][2] ;
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : MovePoint
|
|
//purpose : Find the new poles which allows an old point (with a
|
|
// given u and v as parameters) to reach a new position
|
|
//=======================================================================
|
|
|
|
void BSplSLib::MovePoint (const Standard_Real U,
|
|
const Standard_Real V,
|
|
const gp_Vec& Displ,
|
|
const Standard_Integer UIndex1,
|
|
const Standard_Integer UIndex2,
|
|
const Standard_Integer VIndex1,
|
|
const Standard_Integer VIndex2,
|
|
const Standard_Integer UDegree,
|
|
const Standard_Integer VDegree,
|
|
const Standard_Boolean Rational,
|
|
const TColgp_Array2OfPnt& Poles,
|
|
const TColStd_Array2OfReal& Weights,
|
|
const TColStd_Array1OfReal& UFlatKnots,
|
|
const TColStd_Array1OfReal& VFlatKnots,
|
|
Standard_Integer& UFirstIndex,
|
|
Standard_Integer& ULastIndex,
|
|
Standard_Integer& VFirstIndex,
|
|
Standard_Integer& VLastIndex,
|
|
TColgp_Array2OfPnt& NewPoles)
|
|
{
|
|
// calculate the UBSplineBasis in the parameter U
|
|
Standard_Integer UFirstNonZeroBsplineIndex;
|
|
math_Matrix UBSplineBasis(1, 1,
|
|
1, UDegree+1);
|
|
Standard_Integer ErrorCod1 = BSplCLib::EvalBsplineBasis(0,
|
|
UDegree+1,
|
|
UFlatKnots,
|
|
U,
|
|
UFirstNonZeroBsplineIndex,
|
|
UBSplineBasis);
|
|
// calculate the VBSplineBasis in the parameter V
|
|
Standard_Integer VFirstNonZeroBsplineIndex;
|
|
math_Matrix VBSplineBasis(1, 1,
|
|
1, VDegree+1);
|
|
Standard_Integer ErrorCod2 = BSplCLib::EvalBsplineBasis(0,
|
|
VDegree+1,
|
|
VFlatKnots,
|
|
V,
|
|
VFirstNonZeroBsplineIndex,
|
|
VBSplineBasis);
|
|
if (ErrorCod1 || ErrorCod2) {
|
|
UFirstIndex = 0;
|
|
ULastIndex = 0;
|
|
VFirstIndex = 0;
|
|
VLastIndex = 0;
|
|
return;
|
|
}
|
|
|
|
// find the span which is predominant for parameter U
|
|
UFirstIndex = UFirstNonZeroBsplineIndex;
|
|
ULastIndex = UFirstNonZeroBsplineIndex + UDegree ;
|
|
if (UFirstIndex < UIndex1) UFirstIndex = UIndex1;
|
|
if (ULastIndex > UIndex2) ULastIndex = UIndex2;
|
|
|
|
Standard_Real maxValue = 0.0;
|
|
Standard_Integer i, ukk1=0, ukk2;
|
|
|
|
for (i = UFirstIndex-UFirstNonZeroBsplineIndex+1; i <= ULastIndex-UFirstNonZeroBsplineIndex+1; i++) {
|
|
if (UBSplineBasis(1,i) > maxValue) {
|
|
ukk1 = i + UFirstNonZeroBsplineIndex - 1;
|
|
maxValue = UBSplineBasis(1,i);
|
|
}
|
|
}
|
|
|
|
// find a ukk2 if symetriy
|
|
ukk2 = ukk1;
|
|
i = ukk1 - UFirstNonZeroBsplineIndex + 2;
|
|
if ((ukk1+1) <= ULastIndex) {
|
|
if (Abs(UBSplineBasis(1, ukk1-UFirstNonZeroBsplineIndex+2) - maxValue) < 1.e-10) {
|
|
ukk2 = ukk1+1;
|
|
}
|
|
}
|
|
|
|
// find the span which is predominant for parameter V
|
|
VFirstIndex = VFirstNonZeroBsplineIndex;
|
|
VLastIndex = VFirstNonZeroBsplineIndex + VDegree ;
|
|
|
|
if (VFirstIndex < VIndex1) VFirstIndex = VIndex1;
|
|
if (VLastIndex > VIndex2) VLastIndex = VIndex2;
|
|
|
|
maxValue = 0.0;
|
|
Standard_Integer j, vkk1=0, vkk2;
|
|
|
|
for (j = VFirstIndex-VFirstNonZeroBsplineIndex+1; j <= VLastIndex-VFirstNonZeroBsplineIndex+1; j++) {
|
|
if (VBSplineBasis(1,j) > maxValue) {
|
|
vkk1 = j + VFirstNonZeroBsplineIndex - 1;
|
|
maxValue = VBSplineBasis(1,j);
|
|
}
|
|
}
|
|
|
|
// find a vkk2 if symetriy
|
|
vkk2 = vkk1;
|
|
j = vkk1 - VFirstNonZeroBsplineIndex + 2;
|
|
if ((vkk1+1) <= VLastIndex) {
|
|
if (Abs(VBSplineBasis(1, vkk1-VFirstNonZeroBsplineIndex+2) - maxValue) < 1.e-10) {
|
|
vkk2 = vkk1+1;
|
|
}
|
|
}
|
|
|
|
// compute the vector of displacement
|
|
Standard_Real D1 = 0.0;
|
|
Standard_Real D2 = 0.0;
|
|
Standard_Real hN, Coef, DvalU, DvalV;
|
|
|
|
Standard_Integer ii, jj;
|
|
|
|
for (i = 1; i <= UDegree+1; i++) {
|
|
ii = i + UFirstNonZeroBsplineIndex - 1;
|
|
if (ii < ukk1) {
|
|
DvalU = ukk1-ii;
|
|
}
|
|
else if (ii > ukk2) {
|
|
DvalU = ii - ukk2;
|
|
}
|
|
else {
|
|
DvalU = 0.0;
|
|
}
|
|
|
|
for (j = 1; j <= VDegree+1; j++) {
|
|
jj = j + VFirstNonZeroBsplineIndex - 1;
|
|
if (Rational) {
|
|
hN = Weights(ii, jj)*UBSplineBasis(1, i)*VBSplineBasis(1,j);
|
|
D2 += hN;
|
|
}
|
|
else {
|
|
hN = UBSplineBasis(1, i)*VBSplineBasis(1,j);
|
|
}
|
|
if (ii >= UFirstIndex && ii <= ULastIndex && jj >= VFirstIndex && jj <= VLastIndex) {
|
|
if (jj < vkk1) {
|
|
DvalV = vkk1-jj;
|
|
}
|
|
else if (jj > vkk2) {
|
|
DvalV = jj - vkk2;
|
|
}
|
|
else {
|
|
DvalV = 0.0;
|
|
}
|
|
D1 += 1./(DvalU + DvalV + 1.) * hN;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Rational) {
|
|
Coef = D2/D1;
|
|
}
|
|
else {
|
|
Coef = 1./D1;
|
|
}
|
|
|
|
// compute the new poles
|
|
|
|
for (i=Poles.LowerRow(); i<=Poles.UpperRow(); i++) {
|
|
if (i < ukk1) {
|
|
DvalU = ukk1-i;
|
|
}
|
|
else if (i > ukk2) {
|
|
DvalU = i - ukk2;
|
|
}
|
|
else {
|
|
DvalU = 0.0;
|
|
}
|
|
|
|
for (j=Poles.LowerCol(); j<=Poles.UpperCol(); j++) {
|
|
if (i >= UFirstIndex && i <= ULastIndex && j >= VFirstIndex && j <= VLastIndex) {
|
|
if (j < vkk1) {
|
|
DvalV = vkk1-j;
|
|
}
|
|
else if (j > vkk2) {
|
|
DvalV = j - vkk2;
|
|
}
|
|
else {
|
|
DvalV = 0.0;
|
|
}
|
|
NewPoles(i,j) = Poles(i,j).Translated((Coef/(DvalU + DvalV + 1.))*Displ);
|
|
}
|
|
else {
|
|
NewPoles(i,j) = Poles(i,j);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
// function : Resolution
|
|
// purpose : this computes an estimate for the maximum of the
|
|
// partial derivatives both in U and in V
|
|
//
|
|
//
|
|
// The calculation resembles at the calculation of curves with
|
|
// additional index for the control point. Let Si,j be the
|
|
// control points for ls surface and Di,j the weights.
|
|
// The checking of upper bounds for the partial derivatives
|
|
// will be omitted and Su is the next upper bound in the polynomial case :
|
|
//
|
|
//
|
|
//
|
|
// | Si,j - Si-1,j |
|
|
// d * Max | ------------- |
|
|
// i = 2,n | ti+d - ti |
|
|
// i=1.m
|
|
//
|
|
//
|
|
// and in the rational case :
|
|
//
|
|
//
|
|
//
|
|
// Di,j * (Si,j - Sk,j) - Di-1,j * (Si-1,j - Sk,j)
|
|
// Max Max d * -----------------------------------------------
|
|
// k=1,n i dans Rj ti+d - ti
|
|
// j=1,m
|
|
// ----------------------------------------------------------------------
|
|
//
|
|
// Min Di,j
|
|
// i=1,n
|
|
// j=1,m
|
|
//
|
|
//
|
|
//
|
|
// with Rj = {j-d, ...., j+d+d+1}.
|
|
//
|
|
//
|
|
//=======================================================================
|
|
|
|
void BSplSLib::Resolution(const TColgp_Array2OfPnt& Poles,
|
|
const TColStd_Array2OfReal* Weights,
|
|
const TColStd_Array1OfReal& UKnots,
|
|
const TColStd_Array1OfReal& VKnots,
|
|
const TColStd_Array1OfInteger& UMults,
|
|
const TColStd_Array1OfInteger& VMults,
|
|
const Standard_Integer UDegree,
|
|
const Standard_Integer VDegree,
|
|
const Standard_Boolean URational,
|
|
const Standard_Boolean VRational,
|
|
const Standard_Boolean UPeriodic,
|
|
const Standard_Boolean VPeriodic,
|
|
const Standard_Real Tolerance3D,
|
|
Standard_Real& UTolerance,
|
|
Standard_Real& VTolerance)
|
|
{
|
|
Standard_Real Wij,Wmj,Wji,Wjm;
|
|
Standard_Real Xij,Xmj,Xji,Xjm,Xpq,Xqp;
|
|
Standard_Real Yij,Ymj,Yji,Yjm,Ypq,Yqp;
|
|
Standard_Real Zij,Zmj,Zji,Zjm,Zpq,Zqp;
|
|
Standard_Real factor,value,min,min_weights=0,inverse,max_derivative[2];
|
|
|
|
max_derivative[0] = max_derivative[1] = 0.0e0 ;
|
|
|
|
Standard_Integer PRowLength, PColLength;
|
|
Standard_Integer ii,jj,pp,qq,ii_index,jj_index,pp_index,qq_index;
|
|
Standard_Integer ii_minus,upper[2],lower[2],poles_length[2];
|
|
Standard_Integer num_poles[2],num_flat_knots[2];
|
|
|
|
num_flat_knots[0] =
|
|
BSplCLib::KnotSequenceLength(UMults,
|
|
UDegree,
|
|
UPeriodic) ;
|
|
num_flat_knots[1] =
|
|
BSplCLib::KnotSequenceLength(VMults,
|
|
VDegree,
|
|
VPeriodic) ;
|
|
TColStd_Array1OfReal flat_knots_in_u(1,num_flat_knots[0]) ;
|
|
TColStd_Array1OfReal flat_knots_in_v(1,num_flat_knots[1]) ;
|
|
BSplCLib::KnotSequence(UKnots,
|
|
UMults,
|
|
UDegree,
|
|
UPeriodic,
|
|
flat_knots_in_u) ;
|
|
BSplCLib::KnotSequence(VKnots,
|
|
VMults,
|
|
VDegree,
|
|
VPeriodic,
|
|
flat_knots_in_v) ;
|
|
PRowLength = Poles.RowLength();
|
|
PColLength = Poles.ColLength();
|
|
if (URational || VRational) {
|
|
Standard_Integer Wsize = PRowLength * PColLength;
|
|
const TColStd_Array2OfReal& refWights = *Weights;
|
|
const Standard_Real * WG = &refWights(refWights.LowerRow(), refWights.LowerCol());
|
|
min_weights = WG[0];
|
|
|
|
for (ii = 1 ; ii < Wsize ; ii++) {
|
|
min = WG[ii];
|
|
if (min_weights > min) min_weights = min;
|
|
}
|
|
}
|
|
Standard_Integer UD1 = UDegree + 1;
|
|
Standard_Integer VD1 = VDegree + 1;
|
|
num_poles[0] = num_flat_knots[0] - UD1;
|
|
num_poles[1] = num_flat_knots[1] - VD1;
|
|
poles_length[0] = PColLength;
|
|
poles_length[1] = PRowLength;
|
|
if(URational) {
|
|
Standard_Integer UD2 = UDegree << 1;
|
|
Standard_Integer VD2 = VDegree << 1;
|
|
|
|
for (ii = 2 ; ii <= num_poles[0] ; ii++) {
|
|
ii_index = (ii - 1) % poles_length[0] + 1 ;
|
|
ii_minus = (ii - 2) % poles_length[0] + 1 ;
|
|
inverse = flat_knots_in_u(ii + UDegree) - flat_knots_in_u(ii) ;
|
|
inverse = 1.0e0 / inverse ;
|
|
lower[0] = ii - UD1;
|
|
if (lower[0] < 1) lower[0] = 1;
|
|
upper[0] = ii + UD2 + 1;
|
|
if (upper[0] > num_poles[0]) upper[0] = num_poles[0];
|
|
|
|
for ( jj = 1 ; jj <= num_poles[1] ; jj++) {
|
|
jj_index = (jj - 1) % poles_length[1] + 1 ;
|
|
lower[1] = jj - VD1;
|
|
if (lower[1] < 1) lower[1] = 1;
|
|
upper[1] = jj + VD2 + 1;
|
|
if (upper[1] > num_poles[1]) upper[1] = num_poles[1];
|
|
const gp_Pnt& Pij = Poles .Value(ii_index,jj_index);
|
|
Wij = Weights->Value(ii_index,jj_index);
|
|
const gp_Pnt& Pmj = Poles .Value(ii_minus,jj_index);
|
|
Wmj = Weights->Value(ii_minus,jj_index);
|
|
Xij = Pij.X();
|
|
Yij = Pij.Y();
|
|
Zij = Pij.Z();
|
|
Xmj = Pmj.X();
|
|
Ymj = Pmj.Y();
|
|
Zmj = Pmj.Z();
|
|
|
|
for (pp = lower[0] ; pp <= upper[0] ; pp++) {
|
|
pp_index = (pp - 1) % poles_length[0] + 1 ;
|
|
|
|
for (qq = lower[1] ; qq <= upper[1] ; qq++) {
|
|
value = 0.0e0 ;
|
|
qq_index = (qq - 1) % poles_length[1] + 1 ;
|
|
const gp_Pnt& Ppq = Poles.Value(pp_index,qq_index);
|
|
Xpq = Ppq.X();
|
|
Ypq = Ppq.Y();
|
|
Zpq = Ppq.Z();
|
|
factor = (Xpq - Xij) * Wij;
|
|
factor -= (Xpq - Xmj) * Wmj;
|
|
if (factor < 0) factor = - factor;
|
|
value += factor ;
|
|
factor = (Ypq - Yij) * Wij;
|
|
factor -= (Ypq - Ymj) * Wmj;
|
|
if (factor < 0) factor = - factor;
|
|
value += factor ;
|
|
factor = (Zpq - Zij) * Wij;
|
|
factor -= (Zpq - Zmj) * Wmj;
|
|
if (factor < 0) factor = - factor;
|
|
value += factor ;
|
|
value *= inverse ;
|
|
if (max_derivative[0] < value) max_derivative[0] = value ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
max_derivative[0] /= min_weights ;
|
|
}
|
|
else {
|
|
|
|
for (ii = 2 ; ii <= num_poles[0] ; ii++) {
|
|
ii_index = (ii - 1) % poles_length[0] + 1 ;
|
|
ii_minus = (ii - 2) % poles_length[0] + 1 ;
|
|
inverse = flat_knots_in_u(ii + UDegree) - flat_knots_in_u(ii) ;
|
|
inverse = 1.0e0 / inverse ;
|
|
|
|
for ( jj = 1 ; jj <= num_poles[1] ; jj++) {
|
|
jj_index = (jj - 1) % poles_length[1] + 1 ;
|
|
value = 0.0e0 ;
|
|
const gp_Pnt& Pij = Poles.Value(ii_index,jj_index);
|
|
const gp_Pnt& Pmj = Poles.Value(ii_minus,jj_index);
|
|
factor = Pij.X() - Pmj.X();
|
|
if (factor < 0) factor = - factor;
|
|
value += factor;
|
|
factor = Pij.Y() - Pmj.Y();
|
|
if (factor < 0) factor = - factor;
|
|
value += factor;
|
|
factor = Pij.Z() - Pmj.Z();
|
|
if (factor < 0) factor = - factor;
|
|
value += factor;
|
|
value *= inverse ;
|
|
if (max_derivative[0] < value) max_derivative[0] = value ;
|
|
}
|
|
}
|
|
}
|
|
max_derivative[0] *= UDegree ;
|
|
if(VRational) {
|
|
Standard_Integer UD2 = UDegree << 1;
|
|
Standard_Integer VD2 = VDegree << 1;
|
|
|
|
for (ii = 2 ; ii <= num_poles[1] ; ii++) {
|
|
ii_index = (ii - 1) % poles_length[1] + 1 ;
|
|
ii_minus = (ii - 2) % poles_length[1] + 1 ;
|
|
inverse = flat_knots_in_v(ii + VDegree) - flat_knots_in_v(ii) ;
|
|
inverse = 1.0e0 / inverse ;
|
|
lower[0] = ii - VD1;
|
|
if (lower[0] < 1) lower[0] = 1;
|
|
upper[0] = ii + VD2 + 1;
|
|
if (upper[0] > num_poles[1]) upper[0] = num_poles[1];
|
|
|
|
for ( jj = 1 ; jj <= num_poles[0] ; jj++) {
|
|
jj_index = (jj - 1) % poles_length[0] + 1 ;
|
|
lower[1] = jj - UD1;
|
|
if (lower[1] < 1) lower[1] = 1;
|
|
upper[1] = jj + UD2 + 1;
|
|
if (upper[1] > num_poles[0]) upper[1] = num_poles[0];
|
|
const gp_Pnt& Pji = Poles .Value(jj_index,ii_index);
|
|
Wji = Weights->Value(jj_index,ii_index);
|
|
const gp_Pnt& Pjm = Poles .Value(jj_index,ii_minus);
|
|
Wjm = Weights->Value(jj_index,ii_minus);
|
|
Xji = Pji.X();
|
|
Yji = Pji.Y();
|
|
Zji = Pji.Z();
|
|
Xjm = Pjm.X();
|
|
Yjm = Pjm.Y();
|
|
Zjm = Pjm.Z();
|
|
|
|
for (pp = lower[1] ; pp <= upper[1] ; pp++) {
|
|
pp_index = (pp - 1) % poles_length[1] + 1 ;
|
|
|
|
for (qq = lower[0] ; qq <= upper[0] ; qq++) {
|
|
value = 0.0e0 ;
|
|
qq_index = (qq - 1) % poles_length[0] + 1 ;
|
|
const gp_Pnt& Pqp = Poles.Value(qq_index,pp_index);
|
|
Xqp = Pqp.X();
|
|
Yqp = Pqp.Y();
|
|
Zqp = Pqp.Z();
|
|
factor = (Xqp - Xji) * Wji;
|
|
factor -= (Xqp - Xjm) * Wjm;
|
|
if (factor < 0) factor = - factor;
|
|
value += factor ;
|
|
factor = (Yqp - Yji) * Wji;
|
|
factor -= (Yqp - Yjm) * Wjm;
|
|
if (factor < 0) factor = - factor;
|
|
value += factor ;
|
|
factor = (Zqp - Zji) * Wji;
|
|
factor -= (Zqp - Zjm) * Wjm;
|
|
if (factor < 0) factor = - factor;
|
|
value += factor ;
|
|
value *= inverse ;
|
|
if (max_derivative[1] < value) max_derivative[1] = value ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
max_derivative[1] /= min_weights ;
|
|
}
|
|
else {
|
|
|
|
for (ii = 2 ; ii <= num_poles[1] ; ii++) {
|
|
ii_index = (ii - 1) % poles_length[1] + 1 ;
|
|
ii_minus = (ii - 2) % poles_length[1] + 1 ;
|
|
inverse = flat_knots_in_v(ii + VDegree) - flat_knots_in_v(ii) ;
|
|
inverse = 1.0e0 / inverse ;
|
|
|
|
for ( jj = 1 ; jj <= num_poles[0] ; jj++) {
|
|
jj_index = (jj - 1) % poles_length[0] + 1 ;
|
|
value = 0.0e0 ;
|
|
const gp_Pnt& Pji = Poles.Value(jj_index,ii_index);
|
|
const gp_Pnt& Pjm = Poles.Value(jj_index,ii_minus);
|
|
factor = Pji.X() - Pjm.X() ;
|
|
if (factor < 0) factor = - factor;
|
|
value += factor;
|
|
factor = Pji.Y() - Pjm.Y() ;
|
|
if (factor < 0) factor = - factor;
|
|
value += factor;
|
|
factor = Pji.Z() - Pjm.Z() ;
|
|
if (factor < 0) factor = - factor;
|
|
value += factor;
|
|
value *= inverse ;
|
|
if (max_derivative[1] < value) max_derivative[1] = value ;
|
|
}
|
|
}
|
|
}
|
|
max_derivative[1] *= VDegree ;
|
|
max_derivative[0] *= M_SQRT2 ;
|
|
max_derivative[1] *= M_SQRT2 ;
|
|
if(max_derivative[0] && max_derivative[1]) {
|
|
UTolerance = Tolerance3D / max_derivative[0] ;
|
|
VTolerance = Tolerance3D / max_derivative[1] ;
|
|
}
|
|
else {
|
|
UTolerance=VTolerance=0.0;
|
|
#ifdef OCCT_DEBUG
|
|
std::cout<<"ElSLib.cxx : maxderivative = 0.0 "<<std::endl;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Interpolate
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BSplSLib::Interpolate(const Standard_Integer UDegree,
|
|
const Standard_Integer VDegree,
|
|
const TColStd_Array1OfReal& UFlatKnots,
|
|
const TColStd_Array1OfReal& VFlatKnots,
|
|
const TColStd_Array1OfReal& UParameters,
|
|
const TColStd_Array1OfReal& VParameters,
|
|
TColgp_Array2OfPnt& Poles,
|
|
TColStd_Array2OfReal& Weights,
|
|
Standard_Integer& InversionProblem)
|
|
{
|
|
Standard_Integer ii, jj, ll, kk, dimension;
|
|
Standard_Integer ULength = UParameters.Length();
|
|
Standard_Integer VLength = VParameters.Length();
|
|
Standard_Real * poles_array;
|
|
|
|
// extraction of iso u
|
|
dimension = 4*ULength;
|
|
TColStd_Array2OfReal Points(1, VLength,
|
|
1, dimension);
|
|
|
|
Handle(TColStd_HArray1OfInteger) ContactOrder =
|
|
new (TColStd_HArray1OfInteger)(1, VLength);
|
|
ContactOrder->Init(0);
|
|
|
|
for (ii=1; ii <= VLength; ii++) {
|
|
|
|
for (jj=1, ll=1; jj<= ULength; jj++, ll+=4) {
|
|
Points(ii,ll) = Poles(jj, ii).X();
|
|
Points(ii,ll+1) = Poles(jj, ii).Y();
|
|
Points(ii,ll+2) = Poles(jj, ii).Z();
|
|
Points(ii,ll+3) = Weights(jj,ii) ;
|
|
}
|
|
}
|
|
|
|
// interpolation of iso u
|
|
poles_array = (Standard_Real *) &Points.ChangeValue(1,1) ;
|
|
BSplCLib::Interpolate(VDegree,
|
|
VFlatKnots,
|
|
VParameters,
|
|
ContactOrder->Array1(),
|
|
dimension,
|
|
poles_array[0],
|
|
InversionProblem) ;
|
|
if (InversionProblem != 0) return;
|
|
|
|
// extraction of iso v
|
|
|
|
dimension = VLength*4;
|
|
TColStd_Array2OfReal IsoPoles(1, ULength,
|
|
1, dimension);
|
|
|
|
ContactOrder = new (TColStd_HArray1OfInteger)(1, ULength);
|
|
ContactOrder->Init(0);
|
|
poles_array = (Standard_Real *) &IsoPoles.ChangeValue(1,1) ;
|
|
|
|
for (ii=1, kk=1; ii <= ULength; ii++, kk+=4) {
|
|
|
|
for (jj=1, ll=1; jj<= VLength; jj++, ll+=4) {
|
|
IsoPoles (ii,ll) = Points(jj, kk);
|
|
IsoPoles (ii,ll+1) = Points(jj, kk+1);
|
|
IsoPoles (ii,ll+2) = Points(jj, kk+2);
|
|
IsoPoles (ii,ll+3) = Points(jj, kk+3);
|
|
}
|
|
}
|
|
// interpolation of iso v
|
|
BSplCLib::Interpolate(UDegree,
|
|
UFlatKnots,
|
|
UParameters,
|
|
ContactOrder->Array1(),
|
|
dimension,
|
|
poles_array[0],
|
|
InversionProblem);
|
|
|
|
// return results
|
|
|
|
for (ii=1; ii <= ULength; ii++) {
|
|
|
|
for (jj=1, ll=1; jj<= VLength; jj++, ll+=4) {
|
|
gp_Pnt Pnt(IsoPoles(ii,ll), IsoPoles(ii,ll+1), IsoPoles(ii,ll+2));
|
|
Poles.SetValue(ii, jj, Pnt);
|
|
Weights.SetValue(ii,jj,IsoPoles(ii,ll+3)) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Interpolate
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BSplSLib::Interpolate(const Standard_Integer UDegree,
|
|
const Standard_Integer VDegree,
|
|
const TColStd_Array1OfReal& UFlatKnots,
|
|
const TColStd_Array1OfReal& VFlatKnots,
|
|
const TColStd_Array1OfReal& UParameters,
|
|
const TColStd_Array1OfReal& VParameters,
|
|
TColgp_Array2OfPnt& Poles,
|
|
Standard_Integer& InversionProblem)
|
|
{
|
|
Standard_Integer ii, jj, ll, kk, dimension;
|
|
Standard_Integer ULength = UParameters.Length();
|
|
Standard_Integer VLength = VParameters.Length();
|
|
Standard_Real * poles_array;
|
|
|
|
// extraction of iso u
|
|
dimension = 3*ULength;
|
|
TColStd_Array2OfReal Points(1, VLength,
|
|
1, dimension);
|
|
|
|
Handle(TColStd_HArray1OfInteger) ContactOrder =
|
|
new (TColStd_HArray1OfInteger)(1, VLength);
|
|
ContactOrder->Init(0);
|
|
|
|
for (ii=1; ii <= VLength; ii++) {
|
|
|
|
for (jj=1, ll=1; jj<= ULength; jj++, ll+=3) {
|
|
Points(ii,ll) = Poles(jj, ii).X();
|
|
Points(ii,ll+1) = Poles(jj, ii).Y();
|
|
Points(ii,ll+2) = Poles(jj, ii).Z();
|
|
}
|
|
}
|
|
|
|
// interpolation of iso u
|
|
poles_array = (Standard_Real *) &Points.ChangeValue(1,1) ;
|
|
BSplCLib::Interpolate(VDegree,
|
|
VFlatKnots,
|
|
VParameters,
|
|
ContactOrder->Array1(),
|
|
dimension,
|
|
poles_array[0],
|
|
InversionProblem) ;
|
|
if (InversionProblem != 0) return;
|
|
|
|
// extraction of iso v
|
|
|
|
dimension = VLength*3;
|
|
TColStd_Array2OfReal IsoPoles(1, ULength,
|
|
1, dimension);
|
|
|
|
ContactOrder = new (TColStd_HArray1OfInteger)(1, ULength);
|
|
ContactOrder->Init(0);
|
|
poles_array = (Standard_Real *) &IsoPoles.ChangeValue(1,1) ;
|
|
|
|
for (ii=1, kk=1; ii <= ULength; ii++, kk+=3) {
|
|
|
|
for (jj=1, ll=1; jj<= VLength; jj++, ll+=3) {
|
|
IsoPoles (ii,ll) = Points(jj, kk);
|
|
IsoPoles (ii,ll+1) = Points(jj, kk+1);
|
|
IsoPoles (ii,ll+2) = Points(jj, kk+2);
|
|
}
|
|
}
|
|
// interpolation of iso v
|
|
BSplCLib::Interpolate(UDegree,
|
|
UFlatKnots,
|
|
UParameters,
|
|
ContactOrder->Array1(),
|
|
dimension,
|
|
poles_array[0],
|
|
InversionProblem);
|
|
|
|
// return results
|
|
|
|
for (ii=1; ii <= ULength; ii++) {
|
|
|
|
for (jj=1, ll=1; jj<= VLength; jj++, ll+=3) {
|
|
gp_Pnt Pnt(IsoPoles(ii,ll), IsoPoles(ii,ll+1), IsoPoles(ii,ll+2));
|
|
Poles.SetValue(ii, jj, Pnt);
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : FunctionMultiply
|
|
//purpose :
|
|
//=======================================================================
|
|
|
|
void BSplSLib::FunctionMultiply
|
|
(const BSplSLib_EvaluatorFunction& Function,
|
|
const Standard_Integer UBSplineDegree,
|
|
const Standard_Integer VBSplineDegree,
|
|
const TColStd_Array1OfReal& UBSplineKnots,
|
|
const TColStd_Array1OfReal& VBSplineKnots,
|
|
const TColStd_Array1OfInteger * UMults,
|
|
const TColStd_Array1OfInteger * VMults,
|
|
const TColgp_Array2OfPnt& Poles,
|
|
const TColStd_Array2OfReal* Weights,
|
|
const TColStd_Array1OfReal& UFlatKnots,
|
|
const TColStd_Array1OfReal& VFlatKnots,
|
|
const Standard_Integer UNewDegree,
|
|
const Standard_Integer VNewDegree,
|
|
TColgp_Array2OfPnt& NewNumerator,
|
|
TColStd_Array2OfReal& NewDenominator,
|
|
Standard_Integer& theStatus)
|
|
{
|
|
Standard_Integer num_uparameters,
|
|
// ii,jj,kk,
|
|
ii,jj,
|
|
error_code,
|
|
num_vparameters ;
|
|
Standard_Real result ;
|
|
|
|
num_uparameters = UFlatKnots.Length() - UNewDegree - 1 ;
|
|
num_vparameters = VFlatKnots.Length() - VNewDegree - 1 ;
|
|
TColStd_Array1OfReal UParameters(1,num_uparameters) ;
|
|
TColStd_Array1OfReal VParameters(1,num_vparameters) ;
|
|
|
|
if ((NewNumerator.ColLength() == num_uparameters) &&
|
|
(NewNumerator.RowLength() == num_vparameters) &&
|
|
(NewDenominator.ColLength() == num_uparameters) &&
|
|
(NewDenominator.RowLength() == num_vparameters)) {
|
|
|
|
|
|
BSplCLib::BuildSchoenbergPoints(UNewDegree,
|
|
UFlatKnots,
|
|
UParameters) ;
|
|
|
|
BSplCLib::BuildSchoenbergPoints(VNewDegree,
|
|
VFlatKnots,
|
|
VParameters) ;
|
|
|
|
for (ii = 1 ; ii <= num_uparameters ; ii++) {
|
|
|
|
for (jj = 1 ; jj <= num_vparameters ; jj++) {
|
|
HomogeneousD0(UParameters(ii),
|
|
VParameters(jj),
|
|
0,
|
|
0,
|
|
Poles,
|
|
Weights,
|
|
UBSplineKnots,
|
|
VBSplineKnots,
|
|
UMults,
|
|
VMults,
|
|
UBSplineDegree,
|
|
VBSplineDegree,
|
|
Standard_True,
|
|
Standard_True,
|
|
Standard_False,
|
|
Standard_False,
|
|
NewDenominator(ii,jj),
|
|
NewNumerator(ii,jj)) ;
|
|
|
|
Function.Evaluate (0,
|
|
UParameters(ii),
|
|
VParameters(jj),
|
|
result,
|
|
error_code) ;
|
|
if (error_code) {
|
|
throw Standard_ConstructionError();
|
|
}
|
|
gp_Pnt& P = NewNumerator(ii,jj);
|
|
P.SetX(P.X() * result);
|
|
P.SetY(P.Y() * result);
|
|
P.SetZ(P.Z() * result);
|
|
NewDenominator(ii,jj) *= result ;
|
|
}
|
|
}
|
|
Interpolate(UNewDegree,
|
|
VNewDegree,
|
|
UFlatKnots,
|
|
VFlatKnots,
|
|
UParameters,
|
|
VParameters,
|
|
NewNumerator,
|
|
NewDenominator,
|
|
theStatus);
|
|
}
|
|
else {
|
|
throw Standard_ConstructionError();
|
|
}
|
|
}
|