#
# Some simple tests of trivariate functions.
#
#				Gershon Elber, December 1994.
#

iritstate( "dumplevel", 9 );

#
# A 2 by 2 by 2 trilinear trivariate:
#
tv1 = tbezier( list( list( list( ctlpt( E3, 0.1, 0.0, 0.8 ),
				 ctlpt( E3, 0.2, 0.1, 2.4 ) ),
			   list( ctlpt( E3, 0.3, 2.2, 0.2 ),
				 ctlpt( E3, 0.4, 2.3, 2.0 ) ) ),
		     list( list( ctlpt( E3, 2.4, 0.8, 0.1 ),
				 ctlpt( E3, 2.2, 0.7, 2.3 ) ),
			   list( ctlpt( E3, 2.3, 2.6, 0.5 ),
				 ctlpt( E3, 2.1, 2.5, 2.7) ) ) ) );
color( tv1, yellow );
view_mat = view_mat * sc( 0.2 );
viewobj( list( view_mat ) );
interact( tv1 );

#
# A 3 by 3 by 3 triquadratic trivariate:
#
tv2 = tbspline( 3, 3, 2,
		list( list( list( ctlpt( E3, 0.1, 0.1, 0.0 ),
				  ctlpt( E3, 0.2, 0.5, 1.1 ),
				  ctlpt( E3, 0.3, 0.1, 2.2 ) ),
			    list( ctlpt( E3, 0.4, 1.3, 0.5 ),
				  ctlpt( E3, 0.5, 1.7, 1.7 ),
				  ctlpt( E3, 0.6, 1.3, 2.9 ) ),
			    list( ctlpt( E3, 0.7, 2.4, 0.5 ),
				  ctlpt( E3, 0.8, 2.6, 1.4 ),
				  ctlpt( E3, 0.9, 2.8, 2.3 ) ) ),
		      list( list( ctlpt( E3, 1.1, 0.1, 0.5 ),
				  ctlpt( E3, 1.3, 0.2, 1.7 ),
				  ctlpt( E3, 1.5, 0.3, 2.9 ) ),
			    list( ctlpt( E3, 1.7, 1.2, 0.0 ),
				  ctlpt( E3, 1.9, 1.4, 1.2 ),
				  ctlpt( E3, 1.2, 1.6, 2.4 ) ),
			    list( ctlpt( E3, 1.4, 2.3, 0.9 ),
				  ctlpt( E3, 1.6, 2.5, 1.7 ),
				  ctlpt( E3, 1.8, 2.7, 2.5 ) ) ),
		      list( list( ctlpt( E3, 2.8, 0.1, 0.4 ),
				  ctlpt( E3, 2.6, 0.7, 1.3 ),
				  ctlpt( E3, 2.4, 0.2, 2.2 ) ),
			    list( ctlpt( E3, 2.2, 1.1, 0.4 ),
				  ctlpt( E3, 2.9, 1.2, 1.5 ),
				  ctlpt( E3, 2.7, 1.3, 2.6 ) ),
			    list( ctlpt( E3, 2.5, 2.9, 0.7 ),
				  ctlpt( E3, 2.3, 2.8, 1.7 ),
				  ctlpt( E3, 2.1, 2.7, 2.7 ) ) ) ),
		list( list( KV_OPEN ),
		      list( KV_OPEN ),
		      list( KV_OPEN ) ) );
color( tv2, yellow );
interact( tv2 );

fforder( tv1 );
ffmsize( tv1 );
# ffkntvec( tv1 );
ffctlpts( tv1 );
fforder( tv2 );
ffmsize( tv2 );
ffkntvec( tv2 );
ffctlpts( tv2 );

tv1t = tv1 * rotx( 50 ) * trans( vector( 1.5, -1.5, 2 ) );
color( tv1t, red );
tv2t = tv2 * sc( 0.75 ) * trans( vector( -1.5, 1.5, -2 ) );
color( tv2t, green );

interact( list( tv1, tv1t ) );
interact( list( tv2, tv2t ) );

pdomain( tv1 );
pdomain( tv2t );

free( tv1t );
free( tv2t );

#
# Interpolation.
#

tv1i = tinterp( tv1 ); # Identical for trilinears.
tv1i;
interact( tv1i );
tv2i = tinterp( tv2 );
tv2i;
interact( tv2i );
free( tv1i );
free( tv2i );

#
# Degree raise.
#
tv1r = traise( traise( traise( tv1, row, 4 ), col, 4 ), depth, 4 );
color( tv1r, red );
interact( list( tv1, tv1r * ty( -3.0 ) ) );

# Works on linear Bspline only...
# tv2r = traise( traise( traise( tv2, row, 4 ), col, 4 ), depth, 4 );
# color( tv2r, red );
# interact( list( tv2, tv2r * tx( 3.0 ) ) );

free( tv1r );

#
# Reparametrization
#
treparam( treparam( treparam( tv2, ROW, 0, 10 ),
                    COL, 0, 10 ),
          DEPTH, 0, 10 );

#
# Evaluation and bivariate surface extraction from a trivariate.
#
teval( tv1, 0.77, 0.375, 0.31 );
tv1s1 = strivar( tv1, col, 0.77 );
color( tv1s1, red );
seval( tv1s1, 0.375, 0.31 );
tv1s2 = strivar( tv1, row, 0.375 );
color( tv1s2, green );
seval( tv1s2, 0.77, 0.31 );
tv1s3 = strivar( tv1, depth, 0.31 );
color( tv1s3, cyan );
seval( tv1s3, 0.77, 0.375 );

free( tv1s1 );
free( tv1s2 );
free( tv1s3 );

teval( tv2, 0.4, 0.5, 0.6 );
tv2s1 = strivar( tv2, col, 0.4 );
color( tv2s1, red );
seval( tv2s1, 0.5, 0.6 );
tv2s2 = strivar( tv2, row, 0.5 );
color( tv2s2, green );
seval( tv2s2, 0.4, 0.6 );
tv2s3 = strivar( tv2, depth, 0.6 );
color( tv2s3, cyan );
seval( tv2s3, 0.4, 0.5 );

save_res = resolution;
resolution = 2;
tv2poly = gpolyline( tv2, false );
resolution = save_res;
interact( list( tv2poly, tv2s1, tv2s2, tv2s3 ) );

free( tv2s1 );
free( tv2s2 );
free( tv2s3 );

#
# Subdivision
#
tvdiv = tdivide( tv2, row, 0.3 );
tv2a = nth( tvdiv, 1 ) * ty( -1.7 );
color( tv2a, red );
tv2b = nth( tvdiv, 2 ) * ty( 2.3 );
color( tv2b, green );
interact( list( tv2, tv2a, tv2b ) );

tvdiv = tdivide( tv2, col, 0.7 );
tv2a = nth( tvdiv, 1 ) * tz( -2.2 );
color( tv2a, red );
tv2b = nth( tvdiv, 2 ) * tz( 1.8 );
color( tv2b, green );
interact( list( tv2, tv2a, tv2b ) );

tvdiv = tdivide( tv2, depth, 0.7 );
tv2a = nth( tvdiv, 1 ) * tx( -2.2 );
color( tv2a, red );
tv2b = nth( tvdiv, 2 ) * tx( 2.0 );
color( tv2b, green );
interact( list( tv2, tv2a, tv2b ) );

free( tvdiv );
free( tv2a );
free( tv2b );

#
# Refinement
#
tv1ref = trefine( tv1, row, false, list( 0.3, 0.6 ) );
color( tv1ref, red );
interact( list( tv1, tv1ref * ty( -3.0 ) ) );

tv2ref = trefine( tv2, row, false, list( 0.3, 0.6 ) );
color( tv2ref, red );
interact( list( tv2, tv2ref * ty( -3.0 ) ) );

tv2ref = trefine( tv2, col, false, list( 0.2, 0.4, 0.6, 0.6, 0.8 ) );
color( tv2ref, red );
interact( list( tv2, tv2ref * tz( -3.0 ) ) );

tv2ref = trefine( tv2, depth, false, list( 0.3, 0.6 ) );
color( tv2ref, red );
interact( list( tv2, tv2ref * tx( 3.0 ) ) );

tv2ref = trefine( tv2, row, true, list( 1, 2, 3, 4, 5, 6 ) );
color( tv2ref, red );
interact( list( tv2, tv2ref * tx( 3.0 ) ) );

free( tv1ref );
free( tv2ref );

#
# Region extraction.
#

tv1poly = gpolyline( tv1, false );
color( tv1poly, white );

tv1r1 = tregion( tv1, row, 0.5, 0.7 );
color ( tv1r1, red );
tv1r2 = tregion( tv1, col, 0.4, 0.6 );
color ( tv1r2, green );
tv1r3 = tregion( tv1, depth, 0.2, 0.4 );
color ( tv1r3, blue );
interact( list( tv1poly, tv1r1, tv1r2, tv1r3 ) );
free( tv1poly );
free( tv1r1 );
free( tv1r2 );
free( tv1r3 );

tv2poly = gpolyline( tv2, false );
color( tv2poly, cyan );

interact( list( tv2poly,
		tregion( tv2, row, 0.2, 0.3 ),
		tregion( tv2, row, 0.4, 0.5 ),
		tregion( tv2, row, 0.6, 0.7 ),
		tregion( tv2, row, 0.8, 0.9 ) ) );
interact( list( tv2poly,
		tregion( tv2, col, 0.0, 0.3 ),
		tregion( tv2, col, 0.4, 0.5 ),
		tregion( tv2, col, 0.6, 0.9 ) ) );
interact( list( tv2poly,
		tregion( tv2, depth, 0.0, 0.3 ),
		tregion( tv2, depth, 0.6, 1.0 ),
		tregion( tv2, depth, 1.2, 1.9 ) ) );
free( tv2poly );

#
# Differentiation
#
tv2d = tderive( tv2, col );
interact( tv2d );
tv2d = tderive( tv2, row );
interact( tv2d );
tv2d = tderive( tv2, depth );
interact( tv2d );

free( tv2d );

#
# Constructs a trivariate from a list of surfaces.
#
s1 = sbezier( list( list( ctlpt( E3, -0.5, -0.5, 0 ),
			  ctlpt( E3, -0.5,  0.5, 0 ) ),
		    list( ctlpt( E3,  0.5, -0.5, 0 ),
			  ctlpt( E3,  0.5,  0.5, 0 ) ) ) ) * sc( 0.3 );
Srfs = list( s1 * sc( 2.0 ),
	     s1 * sx( 1.4 ) * ry( 45 ) * tz( 1.0 ),
	     s1 * ry( 90 ) * trans( vector( 1.0, 0.0, 1.1 ) ),
	     s1 * sx( 1.4 ) * ry( 135 ) * trans( vector( 2.0, 0.0, 1.0 ) ),
	     s1 * sc( 2.0 ) * ry( 180 ) * trans( vector( 2.0, 0.0, 0.0 ) ) );
color( Srfs, red );
free( s1 );

ts = tfromsrfs( Srfs, 3 );
color( ts, green );
interact( list( Srfs, ts ) );

ts = tfromsrfs( Srfs, 5 );
color( ts, green );
interact( list( Srfs, ts ) );

s2 = ruledsrf( circle( vector( 0, 0, 0 ), 1 ),
	       circle( vector( 0, 0, 0 ), 0.7 ) );

Srfs = list( s2,
	     s2 * sc( 0.5 ) * tz( 0.4 ),
	     s2 * tz( 0.8 ),
	     s2 * sc( 0.5 ) * tz( 1.2 ) );
color( Srfs, red );
free( s2 );

ts = tfromsrfs( Srfs, 3 );
color( ts, green );
interact( list( Srfs, ts ) );
free( Srfs );
free( ts );

#
# Curvature analysis
#
tv1a = coerce( tv1, E1 );
tcrvtr( tv1a, point( 0, 0, 0 ), -1 ); # Prelude
tcrvtr( tv1a, point( 0, 0, 0 ),  1 );
tcrvtr( tv1a, point( 0, 0, 1 ),  1 );
tcrvtr( tv1a, point( 0, 1, 0 ),  1 );
tcrvtr( tv1a, point( 1, 0, 0 ),  1 );
tcrvtr( tv1a, point( 0, 0, 0 ), 0 ); #Postlude
free( tv1a );

#
# IO
#
save( "trivar", list( tv1, tv2 ) );
l = load( "trivar" );
l;

free( l );
free( tv1 );
free( tv2 );

iritstate( "dumplevel", 1 );
