Raw File
BSplineRectangle.cpp
// Geometric Tools, LLC
// Copyright (c) 1998-2012
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
// http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
//
// File Version: 5.0.1 (2010/10/01)


#include "BSplineRectangle.h"


namespace NURBS
{
//----------------------------------------------------------------------------
template <typename Real>
BSplineRectangle<Real>::BSplineRectangle (int numUCtrlPoints,
    int numVCtrlPoints, Vector3** ctrlPoint, int uDegree,
    int vDegree, bool uLoop, bool vLoop, bool uOpen, bool vOpen)
    :
    ParametricSurface<Real>((Real)0, (Real)1, (Real)0, (Real)1, true)
{
    assertion(numUCtrlPoints >= 2, "Invalid input\n");
    assertion(1 <= uDegree && uDegree <= numUCtrlPoints - 1,
        "Invalid input\n");
    assertion(numVCtrlPoints >= 2, "Invalid input\n");
    assertion(1 <= vDegree && vDegree <= numVCtrlPoints - 1,
        "Invalid input\n");

    mLoop[0] = uLoop;
    mLoop[1] = vLoop;

    mNumUCtrlPoints = numUCtrlPoints;
    mNumVCtrlPoints = numVCtrlPoints;
    mUReplicate = (uLoop ? (uOpen ? 1 : uDegree) : 0);
    mVReplicate = (vLoop ? (vOpen ? 1 : vDegree) : 0);
    CreateControl(ctrlPoint);

    mBasis[0].Create(mNumUCtrlPoints + mUReplicate, uDegree, uOpen);
    mBasis[1].Create(mNumVCtrlPoints + mVReplicate, vDegree, vOpen);
}
//----------------------------------------------------------------------------
template <typename Real>
BSplineRectangle<Real>::BSplineRectangle (int numUCtrlPoints,
    int numVCtrlPoints, Vector3** ctrlPoint, int uDegree,
    int vDegree, bool uLoop, bool vLoop, bool uOpen, Real* vKnot)
    :
    ParametricSurface<Real>((Real)0, (Real)1, (Real)0, (Real)1, true)
{
    assertion(numUCtrlPoints >= 2, "Invalid input\n");
    assertion(1 <= uDegree && uDegree <= numUCtrlPoints - 1,
        "Invalid input\n");
    assertion(numVCtrlPoints >= 2, "Invalid input\n");
    assertion(1 <= vDegree && vDegree <= numVCtrlPoints - 1,
        "Invalid input\n");

    mLoop[0] = uLoop;
    mLoop[1] = vLoop;

    mNumUCtrlPoints = numUCtrlPoints;
    mNumVCtrlPoints = numVCtrlPoints;
    mUReplicate = (uLoop ? (uOpen ? 1 : uDegree) : 0);
    mVReplicate = (vLoop ? 1 : 0);
    CreateControl(ctrlPoint);

    mBasis[0].Create(mNumUCtrlPoints + mUReplicate, uDegree, uOpen);
    mBasis[1].Create(mNumVCtrlPoints + mVReplicate, vDegree, vKnot);
}
//----------------------------------------------------------------------------
template <typename Real>
BSplineRectangle<Real>::BSplineRectangle (int numUCtrlPoints,
    int numVCtrlPoints, Vector3** ctrlPoint, int uDegree,
    int vDegree, bool uLoop, bool vLoop, Real* uKnot, bool vOpen)
    :
    ParametricSurface<Real>((Real)0, (Real)1, (Real)0, (Real)1, true)
{
    assertion(numUCtrlPoints >= 2, "Invalid input\n");
    assertion(1 <= uDegree && uDegree <= numUCtrlPoints - 1,
        "Invalid input\n");
    assertion(numVCtrlPoints >= 2, "Invalid input\n");
    assertion(1 <= vDegree && vDegree <= numVCtrlPoints - 1,
        "Invalid input\n");

    mLoop[0] = uLoop;
    mLoop[1] = vLoop;

    mNumUCtrlPoints = numUCtrlPoints;
    mNumVCtrlPoints = numVCtrlPoints;
    mUReplicate = (uLoop ? 1 : 0);
    mVReplicate = (vLoop ? (vOpen ? 1 : vDegree) : 0);
    CreateControl(ctrlPoint);

    mBasis[0].Create(mNumUCtrlPoints + mUReplicate, uDegree, uKnot);
    mBasis[1].Create(mNumVCtrlPoints + mVReplicate, vDegree, vOpen);
}
//----------------------------------------------------------------------------
template <typename Real>
BSplineRectangle<Real>::BSplineRectangle (int numUCtrlPoints,
    int numVCtrlPoints, Vector3** ctrlPoint, int uDegree,
    int vDegree, bool uLoop, bool vLoop, Real* uKnot, Real* vKnot)
    :
    ParametricSurface<Real>((Real)0, (Real)1, (Real)0, (Real)1, true)
{
    assertion(numUCtrlPoints >= 2, "Invalid input\n");
    assertion(1 <= uDegree && uDegree <= numUCtrlPoints - 1,
        "Invalid input\n");
    assertion(numVCtrlPoints >= 2, "Invalid input\n");
    assertion(1 <= vDegree && vDegree <= numVCtrlPoints - 1,
        "Invalid input\n");

    mLoop[0] = uLoop;
    mLoop[1] = vLoop;

    mNumUCtrlPoints = numUCtrlPoints;
    mNumVCtrlPoints = numVCtrlPoints;
    mUReplicate = (uLoop ? 1 : 0);
    mVReplicate = (vLoop ? 1 : 0);
    CreateControl(ctrlPoint);

    mBasis[0].Create(mNumUCtrlPoints + mUReplicate, uDegree, uKnot);
    mBasis[1].Create(mNumVCtrlPoints + mVReplicate, vDegree, vKnot);
}

//----------------------------------------------------------------------------
template <typename Real>
void BSplineRectangle<Real>::CreateControl (Vector3** ctrlPoint)
{
    int newNumUCtrlPoints = mNumUCtrlPoints + mUReplicate;
    int newNumVCtrlPoints = mNumVCtrlPoints + mVReplicate;
    mCtrlPoint = new2< Vector3 >(newNumVCtrlPoints, newNumUCtrlPoints);

    for (int u = 0; u < newNumUCtrlPoints; ++u)
    {
        int uOld = u % mNumUCtrlPoints;
        for (int v = 0; v < newNumVCtrlPoints; ++v)
        {
            int vOld = v % mNumVCtrlPoints;
            mCtrlPoint[u][v] = ctrlPoint[uOld][vOld];
        }
    }
}
//----------------------------------------------------------------------------
template <typename Real>
int BSplineRectangle<Real>::GetNumCtrlPoints (int dim) const
{
    return mBasis[dim].GetNumCtrlPoints();
}
//----------------------------------------------------------------------------
template <typename Real>
int BSplineRectangle<Real>::GetDegree (int dim) const
{
    return mBasis[dim].GetDegree();
}
//----------------------------------------------------------------------------
template <typename Real>
bool BSplineRectangle<Real>::IsOpen (int dim) const
{
    return mBasis[dim].IsOpen();
}
//----------------------------------------------------------------------------
template <typename Real>
bool BSplineRectangle<Real>::IsUniform (int dim) const
{
    return mBasis[dim].IsUniform();
}
//----------------------------------------------------------------------------
template <typename Real>
bool BSplineRectangle<Real>::IsLoop (int dim) const
{
    return mLoop[dim];
}
//----------------------------------------------------------------------------
template <typename Real>
void BSplineRectangle<Real>::SetControlPoint (int uIndex, int vIndex,
    const Vector3& ctrl)
{
    if (0 <= uIndex && uIndex < mNumUCtrlPoints
    &&  0 <= vIndex && vIndex < mNumVCtrlPoints)
    {
        // Set the control point.
        mCtrlPoint[uIndex][vIndex] = ctrl;

        // Set the replicated control point.
        bool doUReplicate = (uIndex < mUReplicate);
        bool doVReplicate = (vIndex < mVReplicate);
        int iUExt = 0, iVExt = 0;

        if (doUReplicate)
        {
            iUExt = mNumUCtrlPoints + uIndex;
            mCtrlPoint[iUExt][vIndex] = ctrl;
        }
        if (doVReplicate)
        {
            iVExt = mNumVCtrlPoints + vIndex;
            mCtrlPoint[uIndex][iVExt] = ctrl;
        }
        if (doUReplicate && doVReplicate)
        {
            mCtrlPoint[iUExt][iVExt] = ctrl;
        }
    }
}
//----------------------------------------------------------------------------
template <typename Real>
Vector3 BSplineRectangle<Real>::GetControlPoint (int uIndex,
    int vIndex) const
{
    if (0 <= uIndex && uIndex < mNumUCtrlPoints
    &&  0 <= vIndex && vIndex < mNumVCtrlPoints)
    {
        return mCtrlPoint[uIndex][vIndex];
    }

    return Vector3(std::numeric_limits<Real>::max(), std::numeric_limits<Real>::max(),
        std::numeric_limits<Real>::max());
}
//----------------------------------------------------------------------------
template <typename Real>
void BSplineRectangle<Real>::SetKnot (int dim, int i, Real knot)
{
    if (0 <= dim && dim <= 1)
    {
        mBasis[dim].SetKnot(i,knot);
    }
}
//----------------------------------------------------------------------------
template <typename Real>
Real BSplineRectangle<Real>::GetKnot (int dim, int i) const
{
    if (0 <= dim && dim <= 1)
    {
        return mBasis[dim].GetKnot(i);
    }

    return std::numeric_limits<Real>::max();
}
//----------------------------------------------------------------------------
template <typename Real>
void BSplineRectangle<Real>::Get (Real u, Real v, Vector3* pos,
    Vector3* derU, Vector3* derV, Vector3* derUU,
    Vector3* derUV, Vector3* derVV)
{
    int iu, iumin, iumax;
    if (derUU)
    {
        mBasis[0].Compute(u, 0, iumin, iumax);
        mBasis[0].Compute(u, 1, iumin, iumax);
        mBasis[0].Compute(u, 2, iumin, iumax);
    }
    else if (derUV || derU)
    {
        mBasis[0].Compute(u, 0, iumin, iumax);
        mBasis[0].Compute(u, 1, iumin, iumax);
    }
    else
    {
        mBasis[0].Compute(u, 0, iumin, iumax);
    }

    int iv, ivmin, ivmax;
    if (derVV)
    {
        mBasis[1].Compute(v, 0, ivmin, ivmax);
        mBasis[1].Compute(v, 1, ivmin, ivmax);
        mBasis[1].Compute(v, 2, ivmin, ivmax);
    }
    else if (derUV || derV)
    {
        mBasis[1].Compute(v, 0, ivmin, ivmax);
        mBasis[1].Compute(v, 1, ivmin, ivmax);
    }
    else
    {
        mBasis[1].Compute(v, 0, ivmin, ivmax);
    }

    Real tmp;

    if (pos)
    {
        *pos = Vector3_ZERO;
        for (iu = iumin; iu <= iumax; ++iu)
        {
            for (iv = ivmin; iv <= ivmax; ++iv)
            {
                tmp = mBasis[0].GetD0(iu)*mBasis[1].GetD0(iv);
                *pos += tmp*mCtrlPoint[iu][iv];
            }
        }
    }

    if (derU)
    {
        *derU = Vector3_ZERO;
        for (iu = iumin; iu <= iumax; ++iu)
        {
            for (iv = ivmin; iv <= ivmax; ++iv)
            {
                tmp = mBasis[0].GetD1(iu)*mBasis[1].GetD0(iv);
                *derU += tmp*mCtrlPoint[iu][iv];
            }
        }
    }

    if (derV)
    {
        *derV = Vector3_ZERO;
        for (iu = iumin; iu <= iumax; ++iu)
        {
            for (iv = ivmin; iv <= ivmax; ++iv)
            {
                tmp = mBasis[0].GetD0(iu)*mBasis[1].GetD1(iv);
                *derV += tmp*mCtrlPoint[iu][iv];
            }
        }
    }

    if (derUU)
    {
        *derUU = Vector3_ZERO;
        for (iu = iumin; iu <= iumax; ++iu)
        {
            for (iv = ivmin; iv <= ivmax; ++iv)
            {
                tmp = mBasis[0].GetD2(iu)*mBasis[1].GetD0(iv);
                *derUU += tmp*mCtrlPoint[iu][iv];
            }
        }
    }

    if (derUV)
    {
        *derUV = Vector3_ZERO;
        for (iu = iumin; iu <= iumax; ++iu)
        {
            for (iv = ivmin; iv <= ivmax; ++iv)
            {
                tmp = mBasis[0].GetD1(iu)*mBasis[1].GetD1(iv);
                *derUV += tmp*mCtrlPoint[iu][iv];
            }
        }
    }

    if (derVV)
    {
        *derVV = Vector3_ZERO;
        for (iu = iumin; iu <= iumax; ++iu)
        {
            for (iv = ivmin; iv <= ivmax; ++iv)
            {
                tmp = mBasis[0].GetD0(iu)*mBasis[1].GetD2(iv);
                *derVV += tmp*mCtrlPoint[iu][iv];
            }
        }
    }
}
//----------------------------------------------------------------------------
template <typename Real>
Vector3 BSplineRectangle<Real>::P (Real u, Real v)
{
    Vector3 pos;
    Get(u, v, &pos, 0, 0, 0, 0, 0);
    return pos;
}
//----------------------------------------------------------------------------
template <typename Real>
Vector3 BSplineRectangle<Real>::PU (Real u, Real v)
{
    Vector3 derU;
    Get(u, v, 0, &derU, 0, 0, 0, 0);
    return derU;
}
//----------------------------------------------------------------------------
template <typename Real>
Vector3 BSplineRectangle<Real>::PV (Real u, Real v)
{
    Vector3 derV;
    Get(u, v, 0, 0, &derV, 0, 0, 0);
    return derV;
}
//----------------------------------------------------------------------------
template <typename Real>
Vector3 BSplineRectangle<Real>::PUU (Real u, Real v)
{
    Vector3 derUU;
    Get(u, v, 0, 0, 0, &derUU, 0, 0);
    return derUU;
}
//----------------------------------------------------------------------------
template <typename Real>
Vector3 BSplineRectangle<Real>::PUV (Real u, Real v)
{
    Vector3 derUV;
    Get(u, v, 0, 0, 0, 0, &derUV, 0);
    return derUV;
}
//----------------------------------------------------------------------------
template <typename Real>
Vector3 BSplineRectangle<Real>::PVV (Real u, Real v)
{
    Vector3 derVV;
    Get(u, v, 0, 0, 0, 0, 0, &derVV);
    return derVV;
}
//----------------------------------------------------------------------------

//----------------------------------------------------------------------------
// Explicit instantiation.
//----------------------------------------------------------------------------
//template
//class BSplineRectangle<float>;

template
class BSplineRectangle<double>;
//----------------------------------------------------------------------------
}
back to top