// Geometric Tools, LLC
// Copyright (c) 1998-2012
// Distributed under the Boost Software License, Version 1.0.
#pragma once
#include "NURBSGlobal.h"
#include "ParametricSurface.h"
#include "BSplineBasis.h"
namespace NURBS
{
template <typename Real>
class BSplineRectangle : public ParametricSurface<Real>
{
public:
// Construction and destruction. The caller is responsible for deleting
// the input arrays if they were dynamically allocated. Internal copies
// of the arrays are made, so to dynamically change control points or
// knots you must use the 'SetControlPoint', 'GetControlPoint', and
// 'Knot' member functions.
// Spline types for curves are
// open uniform (OU)
// periodic uniform (PU)
// open nonuniform (ON)
// For tensor product surfaces, you have to choose a type for each of two
// dimensions, leading to nine possible spline types for surfaces. The
// constructors below represent these choices.
// (OU,OU), (OU,PU), (PU,OU), or (PU,PU)
BSplineRectangle (int numUCtrlPoints, int numVCtrlPoints,
Vector3** ctrlPoint, int uDegree, int vDegree, bool uLoop,
bool vLoop, bool uOpen, bool vOpen);
// (OU,ON) or (PU,ON)
BSplineRectangle (int numUCtrlPoints, int numVCtrlPoints,
Vector3** ctrlPoint, int uDegree, int vDegree, bool uLoop,
bool vLoop, bool uOpen, Real* vKnot);
// (ON,OU) or (ON,PU)
BSplineRectangle (int numUCtrlPoints, int numVCtrlPoints,
Vector3** ctrlPoint, int uDegree, int vDegree, bool uLoop,
bool vLoop, Real* uKnot, bool vOpen);
// (ON,ON)
BSplineRectangle (int numUCtrlPoints, int numVCtrlPoints,
Vector3** ctrlPoint, int uDegree, int vDegree, bool uLoop,
bool vLoop, Real* uKnot, Real* vKnot);
int GetNumCtrlPoints (int dim) const;
int GetDegree (int dim) const;
bool IsOpen (int dim) const;
bool IsUniform (int dim) const;
bool IsLoop (int dim) const;
// Control points may be changed at any time. If either input index is
// invalid, GetControlPoint returns a vector whose components are all
// MAX_REAL.
void SetControlPoint (int uIndex, int vIndex, const Vector3& ctrl);
Vector3 GetControlPoint (int uIndex, int vIndex) const;
// The knot values can be changed only if the surface is nonuniform in the
// selected dimension and only if the input index is valid. If these
// conditions are not satisfied, GetKnot returns MAX_REAL.
void SetKnot (int dim, int i, Real knot);
Real GetKnot (int dim, int i) const;
// The spline is defined for 0 <= u <= 1 and 0 <= v <= 1. The input
// values should be in this domain. Any inputs smaller than 0 are clamped
// to 0. Any inputs larger than 1 are clamped to 1.
virtual Vector3 P (Real u, Real v) ;
virtual Vector3 PU (Real u, Real v) ;
virtual Vector3 PV (Real u, Real v) ;
virtual Vector3 PUU (Real u, Real v) ;
virtual Vector3 PUV (Real u, Real v) ;
virtual Vector3 PVV (Real u, Real v) ;
// If you need position and derivatives at the same time, it is more
// efficient to call these functions. Pass the addresses of those
// quantities whose values you want. You may pass 0 in any argument
// whose value you do not want.
void Get (Real u, Real v, Vector3* pos, Vector3* derU,
Vector3* derV, Vector3* derUU, Vector3* derUV,
Vector3* derVV);
protected:
// Replicate the necessary number of control points when the Create
// function has bLoop equal to true, in which case the spline surface
// must be a closed surface in the corresponding dimension.
void CreateControl (Vector3** ctrlPoint);
int mNumUCtrlPoints, mNumVCtrlPoints;
Array2D_Vector3 mCtrlPoint; // ctrl[unum][vnum]
std::vector<bool> mLoop;
std::vector< BSplineBasis<Real> > mBasis;
int mUReplicate, mVReplicate;
};
typedef BSplineRectangle<float> BSplineRectanglef;
typedef BSplineRectangle<double> BSplineRectangled;
}