// 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
}