############################################################################# # # Warping polygons/teapot out of the teapot's spout, using FFD trivariates. # # Gershon Elber, Sep 2002. # save_mat2 = view_mat; save_res = resolution; view_mat = rotx( 0 ); # # Get a model of a teapot. # EchoSrc2 = iritState( "EchoSource", false ); interact = procedure( none ): viewclear(); include("teapot"); TeapotOrig = load( "teapot" ); free( Body ); free( Spout ); free( Handle ); free( Cap ); interact = procedure( none ): viewdclear(): viewobj(none): pause(); EchoSrc2 = iritState( "EchoSource", EchoSrc2 ); free( EchoSrc2 ); # # Define our warping function. # WarpSrf = function( OrigSrf, Tv ): Srf: i: USize: VSize: Pt: x: y: z: u: v: Srf = -sreparam( sreparam( OrigSrf, row, 0, 1 ), col, 0, 1 ): Srf = srefine( srefine( Srf, col, false, list( 0.111, 0.222, 0.333, 0.444, 0.555, 0.666, 0.777, 0.888 ) ), row, false, list( 0.111, 0.222, 0.333, 0.444, 0.555, 0.666, 0.777, 0.888 ) ): USize = nth( ffmsize( Srf ), 1 ): VSize = nth( ffmsize( Srf ), 2 ): for ( i = 0, 1, USize * VSize - 1, Pt = coord( Srf, i ): x = coord( Pt, 1 ): y = coord( Pt, 2 ): z = coord( Pt, 3 ): Pt = teval( Tv, x, y, z ): v = floor( i / USize ): u = i - v * USize: Srf = sEditPt( Srf, Pt, u, v ) ): return = Srf: cpattr( return, OrigSrf ); WarpPoly = function( Pl, Tv ): i: j: P: VList: Pt: V: return = 0: for ( i = 0, 1, sizeof( Pl ) - 1, P = coord( Pl, i ): VList = nil(): for ( j = 0, 1, sizeof( P ) - 1, V = coord( P, j ): snoc( coerce( teval( Tv, coord( V, 0 ), coord( V, 1 ), coord( V, 2 ) ), point_type ), VList ) ): if ( thisobj("return") == numeric_type, return = poly( VList, false ), return = mergePoly( list( poly( VList, false ), return ) ) ) ): cpattr( return, Pl ); WarpObj = function( Obj, Tv ): return = nil(); WarpObj = function( Obj, Tv ): i: if ( thisobj("Obj") == list_type, return = nil(): for ( i = 1, 1, sizeof( Obj ), snoc( WarpObj( nth( Obj, i ), Tv ), return ) ), if ( thisobj("Obj") == surface_type, return = WarpSrf( Obj, Tv ), if ( thisobj("Obj") == poly_type, return = WarpPoly( Obj, Tv ), return = Obj * tx( 0 ) ) ) ); # # Define the FFD trivariate # Teapot = TeapotOrig * sc( 0.2 ) * sx( -1 ) * rx( 90 ) * rz( 180 ); s = planeSrf( -1, -1, 1, 1 ) * sc( 2.4 ); Discs = list( s * sc( 0.02 ) * sx( 2 ) * tx( 0.56 ) * tz( 0.42 ), s * sc( 0.02 ) * sx( 2 ) * trans( vector( 0.66, 0, 0.5 ) ), s * sc( 0.04 ) * sx( 1.5 ) * trans( vector( 0.66, 0, 0.7 ) ), s * sc( 0.15 ) * sx( 1.5 ) * trans( vector( 0.1, -0.1, 1 ) ), s * sc( 0.21 ) * sx( 1.5 ) * trans( vector( 0.25, -0.1, 1.2 ) ), s * sc( 0.2 ) * sx( 1.5 ) * trans( vector( 0.2, 0.1, 1.4) ), s * sc( 0.18 ) * tx( 0.1 ) * tz( 1.5 ) ); Tv = tFromSrfs( Discs, 3, kv_open ); attrib( Tv, "transp", 0.5 ); # view( list( axes, Tv, Teapot ), 1 ); ############################################################################# # # Let the Teapot and Spheres come out of the teapot... # resolution = 10; s1 = sphere( vector( 0.2, 0.2, 0.8 ), 0.18 ); color( s1, yellow ); s2 = sphere( vector( 0.75, 0.25, 0.16667 ), 0.12 ) * sz( 3 ); color( s2, magenta ); c1 = MaxEdgeLen( triangl( cylin( vector( 0.15, 0.85, 0.01 ), vector( 0, 0, 0.98 ), 0.1, 3 ), 1 ), 0.2 ); color( c1, cyan ); c2 = MaxEdgeLen( triangl( cylin( vector( 0.85, 0.85, 0.01 ), vector( 0, 0, 0.98 ), 0.1, 3 ), 1 ), 0.2 ); color( c2, cyan ); Genie = list( TeapotOrig * sc( 0.15 ) * ry( -90 ) * trans( vector( 0.5, 0.4, 0.47 ) ), s1, s2, c1, c2 ); b = box( vector( 0, 0, 0 ), 1, 1, 1 ); attrib( b, "transp", 0.5 ); interact( list( axes, b, Genie ) ); WGenie = WarpObj( Genie, Tv ); interact( list( Teapot, WGenie, Tv ) ); save( "GeniTpot", list( Teapot, WGenie, Tv ) ); ############################################################################# view_mat = save_mat2; resolution = save_res; free( TeapotOrig ); free( Teapot ); free( s ); free( Tv ); free( Genie ); free( WGenie ); free( Discs ); free( s1 ); free( s2 ); free( c1 ); free( c2 ); free( b );