Ejemplo n.º 1
0
Array1D_Real NURBSCurve<Real>::insertKnot(Real u, int k, int s, int r, Array1D_Vector3 & Qw, int * uq)
{
    Array1D_Real	UP = GetKnotVector();
    Array1D_Vector3 Pw = mCtrlPoint;
    Array1D_Real	UQ;

    Array1D_Vector3 Rw;
    Scalar alpha;
    int L = 0;

    int order = this->GetDegree() + 1;
    int p = order - 1;
    int np = Pw.size() - 1;

    int mp = np+p+1;
    int nq = np+r;

    // Define array
    UQ.resize(mp+r+1);
    Qw.resize(nq+1);
    Rw.resize(p+1);

    // Load new knot vector
    for (int i=0; i<=k; i++)	UQ[i]	= UP[i];
    for (int i=1; i<=r; i++)	UQ[k+i] = u;
    for (int i=k+1; i<=mp; i++)	UQ[i+r] = UP[i];

    // Save unaltered control points
    for (int i=0; i<=k-p; i++)	Qw[i]	= Pw[i];
    for (int i=k-s; i<=np; i++)	Qw[i+r] = Pw[i];
    for (int i=0; i<=p-s; i++)	Rw[i]	= Pw[k-p+i];

    // Insert the knot r times
    for (int j=1; j<=r; j++)
    {
        L = k-p+j;
        for (int i=0; i<=p-j-s; i++)
        {
            alpha = (u-UP[L+i])/(UP[i+k+1]-UP[L+i]);
            Rw[i] = alpha*Rw[i+1] + (1.0 - alpha) * Rw[i];
        }
        Qw[L] = Rw[0];
        Qw[k+r-j-s] = Rw[p-j-s];
    }

    // Load remaining control points
    for (int i=L+1; i<k-s; i++)
        Qw[i] = Rw[i-L];

    if(uq) *uq = k-p+1;

    return UQ;
}
Ejemplo n.º 2
0
Array1D_Vector3 NURBSCurve<Real>::removeKnots(int iterations)
{
    NURBSCurve<Real> curCurve = *this;

    for(int itr = 0; itr < iterations; itr++)
    {
        Array1D_Real	U = curCurve.GetKnotVector();
        Array1D_Vector3 P = curCurve.mCtrlPoint;
        int p = curCurve.GetDegree();

        QMap<Real, int> errors;
        for(int i = p + 1; i < (int)U.size() - 1; i++)
        {
            if(U[i] < U[i+1])
                errors[ curCurve.KnotRemovalError(i, 1) ] = i;
        }

        int r = errors.values().at(itr); // Knot to remove

        int num = 1;
        int s = 1;

        int deg_ = curCurve.GetDegree();
        int m = U.size() ;
        int ord = deg_+1 ;
        int fout = (2*r-s-deg_)/2 ;
        int last = r-s ;
        int first = r-deg_ ;
        Real alfi, alfj ;
        int i,j,k,ii,jj,off ;
        Real u ;

        Array1D_Vector3 temp( 2*deg_+1, Vector3(0,0,0) ) ;

        u = U[r] ;

        int t;
        for(t=0; t<num; ++t)
        {
            off = first-1 ;
            temp[0] = P[off] ;
            temp[last+1-off] = P[last+1] ;
            i = first;
            j = last ;
            ii = 1 ;
            jj = last-off ;
            while(j-i > t) {
                alfi = (u-U[i])/(U[i+ord+t]-U[i]) ;
                alfj = (u-U[j-t])/(U[j+ord]-U[j-t]) ;
                temp[ii] = (P[i]-(1.0-alfi)*temp[ii-1])/alfi ;
                temp[jj] = (P[j]-alfj*temp[jj+1])/(1.0-alfj) ;
                ++i ;
                ++ii ;
                --j ;
                --jj ;
            }
            i = first ;
            j = last ;
            while(j-i>t) {
                P[i] = temp[i-off] ;
                P[j] = temp[j-off] ;
                ++i;
                --j ;
            }
            --first ;
            ++last ;
        }
        if(t == 0)
            return P;

        for(k=r+1; k<m ; ++k)
            U[k-t] = U[k] ;
        j = fout ;
        i=j ; // Pj thru Pi will be overwritten
        for(k=1; k<t; k++)
            if( (k%2) == 1)
                ++i ;
            else
                --j ;
        for(k=i+1; k<(int)P.size() ; k++) {// Shift
            P[j++] = P[k] ;
        }

        P.resize(P.size() - t);
        curCurve = createCurveFromPoints(P);
    }

    return curCurve.mCtrlPoint;
}
Ejemplo n.º 3
0
void NURBSCurve<Real>::refine(Array1D_Real & insknts, Array1D_Vector3 & Qw, Array1D_Real & Ubar )
{
    // Input
    Array1D_Real X		= insknts;
    Array1D_Vector3 Pw	= this->mCtrlPoint;
    Array1D_Real U		= GetKnotVector();

    int s = insknts.size();
    int order = this->GetDegree() + 1;
    int p = order - 1;
    int n = Pw.size() - 1;
    int r = X.size() - 1;
    int m = n+p+1;

    // Output
    Qw.resize	( n+s+1, Vector3(0,0,0) );
    Ubar.resize	( m+s+1, 0 );

    int a = findSpan(n,p,X[0],U);
    int b = findSpan(n,p,X[r],U) + 1;

    int j = 0;
    for(j=0	 ; j<=a-p; j++)  Qw[j]		 = Pw[j];
    for(j=b-1; j<=n	 ; j++)  Qw[j+r+1]	 = Pw[j];
    for(j=0	 ; j<=a	 ; j++)  Ubar[j]	 = U[j];
    for(j=b+p; j<=m	 ; j++)  Ubar[j+r+1] = U[j];

    int i = b+p-1;
    int k = b+p+r;

    Real alfa = 0;

    for (int j=r; j>=0; j--)
    {
        while (X[j] <= U[i] && i > a) {
            Qw[k-p-1] = Pw[i-p-1];
            Ubar[k] = U[i];
            k = k - 1;
            i = i - 1;
        }

        Qw[k-p-1] = Qw[k-p];

        for (int l=1; l<=p; l++)
        {
            int ind = k-p+l;
            alfa = Ubar[k+l] - X[j];
            if (fabs(alfa) == 0.0)
            {
                Qw[ind-1] = Qw[ind];
            }
            else
            {
                alfa = alfa / (Ubar[k+l] - U[i-p+l]);
                Qw[ind-1] = alfa * Qw[ind-1] + (1.0 - alfa) * Qw[ind];
            }
        }
        Ubar[k] = X[j];
        k = k - 1;
    }
}