40 #include "glimports.h"
45 #include "knotvector.h"
81 void insert( REAL * );
84 void copy( INREAL *, REAL * );
85 void breakpoints(
void );
87 void transform( REAL * );
88 void showpts( REAL * );
90 void pt_io_copy( REAL *, INREAL * );
91 void pt_oo_copy( REAL *, REAL * );
92 void pt_oo_sum( REAL*, REAL*, REAL*, Knot, Knot );
106 void setupquilt( Quilt_ptr );
107 void copy( INREAL * );
108 void transform(
void );
123 spline.kspecinit( knotvector );
125 spline.layout( ncoords );
126 spline.setupquilt(
this );
127 spline.copy( ctlpts );
139 spline.kspecinit( sknotvector, tknotvector );
141 spline.layout( ncoords );
142 spline.setupquilt(
this );
143 spline.copy( ctlpts );
146 Splinespec::Splinespec(
int dimen )
151 Splinespec::~Splinespec(
void )
174 Splinespec::kspecinit(
Knotvector& knotvector )
177 kspec->inkbegin = knotvector.knotlist;
178 kspec->inkend = knotvector.knotlist + knotvector.knotcount;
179 kspec->prestride = (int) knotvector.stride;
180 kspec->order = knotvector.order;
190 kspec->inkbegin = sknotvector.knotlist;
191 kspec->inkend = sknotvector.knotlist + sknotvector.knotcount;
192 kspec->prestride = (int) sknotvector.stride;
193 kspec->order = sknotvector.order;
194 kspec->next = tkspec;
196 tkspec->inkbegin = tknotvector.knotlist;
197 tkspec->inkend = tknotvector.knotlist + tknotvector.knotcount;
198 tkspec->prestride = (
int) tknotvector.stride;
199 tkspec->order = tknotvector.order;
212 Splinespec::select( )
214 for(
Knotspec *knotspec = kspec; knotspec; knotspec = knotspec->next ) {
215 knotspec->preselect();
228 Splinespec::layout(
long ncoords )
231 long stride = ncoords;
232 for(
Knotspec *knotspec = kspec; knotspec; knotspec=knotspec->next ) {
233 knotspec->poststride = (int) stride;
234 stride *= ((knotspec->bend-knotspec->bbegin)*knotspec->order + knotspec->postoffset);
235 knotspec->preoffset *= knotspec->prestride;
236 knotspec->prewidth *= knotspec->poststride;
237 knotspec->postwidth *= knotspec->poststride;
238 knotspec->postoffset *= knotspec->poststride;
239 knotspec->ncoords = (int) ncoords;
241 outcpts =
new REAL[stride];
242 assert( outcpts != 0 );
253 Splinespec::copy( INREAL *incpts )
255 kspec->copy( incpts, outcpts );
266 Splinespec::setupquilt( Quilt_ptr quilt )
269 quilt->eqspec = qspec + dim;
270 for(
Knotspec *knotspec = kspec; knotspec; knotspec=knotspec->next, qspec++ ) {
271 qspec->stride = knotspec->poststride;
272 qspec->width = knotspec->bend - knotspec->bbegin;
273 qspec->order = (int) knotspec->order;
274 qspec->offset = knotspec->postoffset;
276 qspec->bdry[0] = (knotspec->kleft == knotspec->kfirst) ? 1 : 0;
277 qspec->bdry[1] = (knotspec->kright == knotspec->klast) ? 1 : 0;
278 qspec->breakpoints =
new Knot[qspec->width+1];
279 Knot_ptr k = qspec->breakpoints;
280 for(
Breakpt *bk = knotspec->bbegin; bk <= knotspec->bend; bk++ )
283 quilt->cpts = outcpts;
295 Splinespec::transform(
void )
298 for( knotspec = kspec; knotspec; knotspec=knotspec->next )
299 knotspec->istransformed = 0;
301 for( knotspec = kspec; knotspec; knotspec=knotspec->next ) {
302 for(
Knotspec *kspec2 = kspec; kspec2; kspec2=kspec2->next )
303 kspec2->kspectotrans = knotspec;
304 kspec->transform( outcpts );
305 knotspec->istransformed = 1;
315 Knotspec::Knotspec(
void )
330 Knotspec::copy( INREAL *inpt, REAL *outpt )
332 inpt = (INREAL *) (((
char *) inpt) + preoffset);
335 for( REAL *lpt=outpt+prewidth; outpt != lpt; outpt += poststride ) {
336 next->copy( inpt, outpt );
337 inpt = (INREAL *) (((
char *) inpt) + prestride);
340 for( REAL *lpt=outpt+prewidth; outpt != lpt; outpt += poststride ) {
341 pt_io_copy( outpt, inpt );
342 inpt = (INREAL *) (((
char *) inpt) + prestride);
354 Knotspec::showpts( REAL *outpt )
357 for( REAL *lpt=outpt+prewidth; outpt != lpt; outpt += poststride )
358 next->showpts( outpt );
360 for( REAL *lpt=outpt+prewidth; outpt != lpt; outpt += poststride )
361 _glu_dprintf(
"show %g %g %g\n", outpt[0], outpt[1], outpt[2] );
374 Knotspec::factors(
void )
376 Knot *mid = (outkend - 1) - order + bend->multi;
377 Knot_ptr fptr = sbegin;
379 for(
Breakpt *bpt = bend; bpt >= bbegin; bpt-- ) {
381 int def = bpt->def - 1;
382 if( def <= 0 )
continue;
383 Knot kv = bpt->value;
385 Knot *kf = (mid-def) + (order-1);
386 for( Knot *kl = kf + def; kl != kf; kl-- ) {
388 for( kt=kl, kh=mid; kt != kf; kh--, kt-- )
389 *(fptr++) = (kv - *kh) / (*kt - *kh);
403 Knotspec::insert( REAL *p )
405 Knot_ptr fptr = sbegin;
406 REAL *srcpt = p + prewidth - poststride;
407 REAL *dstpt = p + postwidth + postoffset - poststride;
410 for( REAL *pend = srcpt - poststride*bpt->def; srcpt != pend; pend +=poststride ) {
412 for( REAL *p2 = srcpt-poststride; p2 != pend; p1 = p2, p2 -= poststride ) {
413 pt_oo_sum( p1, p1, p2, *fptr, 1.0-*fptr );
418 for( --bpt; bpt >= bbegin; bpt-- ) {
420 for(
int multi = bpt->multi; multi > 0; multi-- ) {
421 pt_oo_copy( dstpt, srcpt );
426 for( REAL *pend = srcpt - poststride*bpt->def; srcpt != pend; pend +=poststride, dstpt-=poststride ) {
427 pt_oo_copy( dstpt, srcpt );
430 for( REAL *p2 = srcpt-poststride; p2 != pend; p1=p2, p2 -= poststride ) {
431 pt_oo_sum( p1, p1, p2, *fptr, 1.0-*fptr );
446 Knotspec::preselect(
void )
451 for( klast = inkend - order, kval = *klast; klast != inkend; klast++ )
452 if( ! identical( *klast, kval ) )
break;
455 for( kfirst = inkbegin+order-1, kval= *kfirst; kfirst != inkend; kfirst++ )
456 if( ! identical( *kfirst, kval ) )
break;
460 for( k = kfirst - 1; k >= inkbegin; k-- )
461 if( ! identical( kval, *k ) )
break;
467 bbegin =
new Breakpt[(klast - kfirst)+1];
469 bbegin->multi = kfirst - k;
470 bbegin->value = kval;
473 kleft = kright = kfirst;
485 Knotspec::select(
void )
491 preoffset = kleft - (inkbegin + order);
492 postwidth = (int)((bend - bbegin) * order);
493 prewidth = (int)((outkend - outkbegin) - order);
494 postoffset = (bbegin->def > 1) ? (bbegin->def-1) : 0;
505 Knotspec::breakpoints(
void )
511 ubpt->value = ubend->value;
512 ubpt->multi = ubend->multi;
516 for( ; kright != klast; kright++ ) {
517 if ( identical(*kright,ubpt->value) ) {
520 ubpt->def = (int) (order - ubpt->multi);
521 nfactors += (ubpt->def * (ubpt->def - 1)) / 2;
522 (++ubpt)->value = *kright;
526 ubpt->def = (int) (order - ubpt->multi);
527 nfactors += (ubpt->def * (ubpt->def - 1)) / 2;
532 sbegin =
new Knot[nfactors];
547 Knotspec::knots(
void )
549 Knot_ptr inkpt = kleft - order;
550 Knot_ptr inkend = kright + bend->def;
553 outkbegin =
new Knot[inkend-inkpt];
555 for( outkpt = outkbegin; inkpt != inkend; inkpt++, outkpt++ )
570 Knotspec::transform( REAL *p )
573 if(
this == kspectotrans ) {
574 next->transform( p );
576 if( istransformed ) {
578 for( REAL *pend = p + postwidth; p != pend; p += poststride )
579 next->transform( p );
581 REAL *pend = p + prewidth;
582 for( ; p != pend; p += poststride )
583 next->transform( p );
587 if(
this == kspectotrans ) {
590 if( istransformed ) {
592 for( REAL *pend = p + postwidth; p != pend; p += poststride )
593 kspectotrans->insert( p );
595 REAL *pend = p + prewidth;
596 for( ; p != pend; p += poststride )
597 kspectotrans->insert( p );
608 Knotspec::~Knotspec(
void )
610 if( bbegin )
delete[] bbegin;
611 if( sbegin )
delete[] sbegin;
612 if( outkbegin )
delete[] outkbegin;
622 Knotspec::pt_io_copy( REAL *topt, INREAL *frompt )
626 topt[3] = (REAL) frompt[3];
628 topt[2] = (REAL) frompt[2];
630 topt[1] = (REAL) frompt[1];
632 topt[0] = (REAL) frompt[0];
635 for(
int i = 0; i < ncoords; i++ )
636 *topt++ = (REAL) *frompt++;
647 Knotspec::pt_oo_copy( REAL *topt, REAL *frompt )
660 memcpy( topt, frompt, ncoords *
sizeof( REAL ) );
670 Knotspec::pt_oo_sum( REAL *x, REAL *y, REAL *z, Knot a, Knot b )
674 x[3] = a * y[3] + b * z[3];
676 x[2] = a * y[2] + b * z[2];
678 x[1] = a * y[1] + b * z[1];
680 x[0] = a * y[0] + b * z[0];
683 for(
int i = 0; i < ncoords; i++ )
684 *x++ = a * *y++ + b * *z++;