// sponge // init array #macro init( arr, dx, dy, dz ) #declare X = 0; #while( X < dx ) #declare Y = 0; #while( Y < dy ) #declare Z = 0; #while( Z < dz ) #declare it[X][Y][Z] = 1; #declare Z = Z + 1; #end #declare Y = Y + 1; #end #declare X = X + 1; #render concat( "Init ", str(X,1,0), "/", str(dx,1,0), "\r" ) #end #end #macro cut( p1, diff ) #local X = p1.x; #while( X < min( res2, p1.x + diff.x ) ) #local Y = p1.y; #while( Y < min( res2, p1.y + diff.y ) ) #local Z = p1.z; #while( Z < min(res2, p1.z + diff.z) ) #declare it[X][Y][Z] = 0; #local Z = Z + 1; #end #local Y = Y + 1; #end #local X = X + 1; #end #end #macro sponge( p1, diff, iter ) #local dd = diff / 3; cut( p1 + <0, dd.y, dd.z>, dd ) cut( p1 + , dd ) cut( p1 + , dd ) cut( p1 + , dd ) cut( p1 + , dd ) cut( p1 + , dd ) cut( p1 + , dd ) #if( iter > 1 & p1.x < res2 & p1.y < res2 & p1.z < res2 ) #if (iter > 2 ) #render concat( "\nIter ", str(iter,1,0), " <", str(p1.x,1,0), ",", str(p1.y,1,0), ",", str(p1.z,1,0), ">\n" ) #else #render concat( str(iter,1,0), "<", str(p1.x,1,0), ",", str(p1.y,1,0), ",", str(p1.z,1,0), "> " ) #end sponge( p1 + <0, 0, 0>, dd, iter - 1 ) sponge( p1 + <0, 0, dd.z>, dd, iter - 1 ) sponge( p1 + <0, 0, 2 * dd.z>, dd, iter - 1 ) sponge( p1 + <0, dd.y, 0>, dd, iter -1 ) sponge( p1 + <0, dd.y, 2 * dd.z>, dd, iter -1 ) sponge( p1 + <0, 2 * dd.y, 0>, dd, iter -1 ) sponge( p1 + <0, 2 * dd.y, dd.z>, dd, iter -1 ) sponge( p1 + <0, 2 * dd.y, 2 * dd.z>, dd, iter -1 ) sponge( p1 + , dd, iter - 1 ) sponge( p1 + , dd, iter - 1 ) sponge( p1 + , dd, iter -1 ) sponge( p1 + , dd, iter -1 ) sponge( p1 + <2 * dd.x, 0, 0>, dd, iter - 1 ) sponge( p1 + <2 * dd.x, 0, dd.z>, dd, iter - 1 ) sponge( p1 + <2 * dd.x, 0, 2 * dd.z>, dd, iter - 1 ) sponge( p1 + <2 * dd.x, dd.y, 0>, dd, iter -1 ) sponge( p1 + <2 * dd.x, dd.y, 2 * dd.z>, dd, iter -1 ) sponge( p1 + <2 * dd.x, 2 * dd.y, 0>, dd, iter -1 ) sponge( p1 + <2 * dd.x, 2 * dd.y, dd.z>, dd, iter -1 ) sponge( p1 + <2 * dd.x, 2 * dd.y, 2 * dd.z>, dd, iter -1 ) #end #end // this translates from the 1/8th array until a full one #macro retr( X, Y, Z ) #local rX = X; #local rY = Y; #local rZ = Z; #if( rX >= res2 ) #local rX = res2 + res2 - rX - 2; #end #if( rY >= res2 ) #local rY = res2 + res2 - rY - 2; #end #if( rZ >= res2 ) #local rZ = res2 + res2 - rZ - 2; #end it[rX][rY][rZ] #end // make boxes #macro make_eigth( it, res2, size, obj, MESH ) #if( MESH ) mesh { #else union { #end #declare X = 0; #while( X < res2 ) #declare Y = 0; #while( Y < res2 ) #declare Z = 0; #while( Z < res2 ) #if( it[X][Y][Z] = 1 ) #if( MESH ) #if( X = 0 ? 1 : it[max(0,X-1)][Y][Z] ) triangle { * size, * size, * size } triangle { * size, * size, * size } #end #if( Y = 0 ? 1 : it[X][max(0,Y-1)][Z] ) triangle { * size, * size, * size } triangle { * size, * size, * size } #end #if( Z = 0 ? 1 : it[X][Y][max(0,Z-1)] ) triangle { * size, * size, * size } triangle { * size, * size, * size } #end #if( X = res2 ? 1 : !it[min(res2 - 1,X+1)][Y][Z] ) triangle { * size, * size, * size } triangle { * size, * size, * size } #end #if( Y = res2 ? 1 : !it[X][min(res2 - 1,Y+1)][Z] ) triangle { * size, * size, * size } triangle { * size, * size, * size } #end #if( Z = res2 ? 1 : !it[X][Y][min(res2 - 1,Z+1)] ) triangle { * size, * size, * size } triangle { * size, * size, * size } #end /* #local z1 = Z; #while( Z < res2 - 1 & it[X][Y][Z] = 1 ) //retr( X, Y, Z ) = 1 ) #declare it[X][Y][Z] = 0; #declare Z = Z + 1; #end #local z2 = Z; box { * size, * size } */ #else object { obj translate * size } #end #end #declare Z = Z + 1; #end #declare Y = Y + 1; #end #declare X = X + 1; #render concat( "Make ", str(X,1,0), "/", str(res2,1,0), "\r" ) #end #if( MESH ) } #else } #end #end #declare iterations = 4; #declare iterationsB = 3; #declare res = pow(3, iterations); #declare resB = pow(3, iterationsB); // since the box is mirrored in X, Y, and Z we only need 1/2 on all sides (1/8th memory) #declare res2 = int( res / 2 ) + 1; #declare it = array[res2][res2][res2] #declare size = 10 / res / resB; init( it, res2, res2, res2 ) #render "\n" sponge( <0,0,0>, , iterations ) #render "\n\n" #declare eighth = make_eigth( it, res2, size, 0, 1 ) #render "\n\n" #undef it #declare half = union { object { eighth } object { eighth rotate y * -90 translate x * size * res } object { eighth rotate y * 90 translate z * size * res } object { eighth rotate y * 180 translate } } #declare obj = union { object { half } object { half rotate x * 180 translate z * size * res translate y * size * res } } // since the box is mirrored in X, Y, and Z we only need 1/2 on all sides (1/8th memory) #declare res2 = int( resB / 2 ) + 1; #declare it = array[res2][res2][res2] #declare size = 10 / resB; init( it, res2, res2, res2 ) #render "\n" sponge( <0,0,0>, , iterationsB ) #render "\n\n" #declare eighth = make_eigth( it, res2, size, obj, 0 ) #render "\n\n" #undef it #declare half = union { object { eighth } object { eighth rotate y * -90 translate x * size * resB } object { eighth rotate y * 90 translate z * size * resB } object { eighth rotate y * 180 translate } } #declare whole = union { object { half } object { half rotate x * 180 translate z * size * resB translate y * size * resB } } object { whole rotate y*180 translate <1,0,1> * 10 texture { pigment { color <1,0,0> } finish { specular 0.5 roughness 0.2 } } } box { <-20, 0, -20>, <30, 30, 30> pigment { checker <1,1,1>, <0,0,1> scale 2 } hollow } light_source { <-5, 5, 5> color <1,1,1> } light_source { <4, 18, -15> color <1,1,1> } camera { up y #switch( 2 ) #case( 1 ) // top full location <-7, 13, -10> right 1*x look_at <1, 6, 0.0> #break #case( 2 ) // top full location <-0.3, 10.1, -0.5> right 1*x look_at <5, 7.0, 2.6> #break #end }