// Image dimensions #declare xd = 300; #declare yd = 300; // Level of detail #declare dd = 20; //2; // Basic splitter ratios #declare xsr = 1/2; #declare ysr = 1/2; // Object indenter #declare is = 2; // Optional level limit #declare level_limit = 8; #version 3.5; #include "functions.inc" // ---------------------------------------- light_source { // light's position (translated below) color rgb <1, 1, 1> // light's color parallel point_at } camera { location //-600>//-1200> direction 1.5*z right x*image_width/image_height look_at } // Pigment to scan #declare scan_pigment = pigment { image_map { tga "red_blob.tga" } scale } ///////////////////////////////////////////////////////////////////////////////// #macro similar_colors(c1,c2,c3,c4) #local epsilon = 0.0001; #if ( (abs(c1.red - c2.red) < epsilon) & (abs(c1.green - c2.green) < epsilon) & (abs(c1.blue - c2.blue) < epsilon) & (abs(c1.red - c3.red) < epsilon) & (abs(c1.green - c3.green) < epsilon) & (abs(c1.blue - c3.blue) < epsilon) & (abs(c1.red - c4.red) < epsilon) & (abs(c1.green - c4.green) < epsilon) & (abs(c1.blue - c4.blue) < epsilon) & (abs(c2.red - c3.red) < epsilon) & (abs(c2.green - c3.green) < epsilon) & (abs(c2.blue - c3.blue) < epsilon) & (abs(c2.red - c4.red) < epsilon) & (abs(c2.green - c4.green) < epsilon) & (abs(c2.blue - c4.blue) < epsilon) & (abs(c3.red - c4.red) < epsilon) & (abs(c3.green - c4.green) < epsilon) & (abs(c3.blue - c4.blue) < epsilon) ) #declare similar_answer = true; #else #declare similar_answer = false; #end #end ///////////////////////////////////////////////////////////////////////////////// #macro emit_object(left_x,bottom_y,right_x,top_y,zpos,ecolor,level) /* box { , texture { pigment { color rgb } finish { diffuse 1 ambient 0 } } } */ disc { <(left_x+right_x)/2,(bottom_y+top_y)/2,0>, z, abs(right_x-left_x)/2 texture { pigment { color rgb } finish { diffuse 1 ambient 0 } } translate <0,0,zpos> } #end ///////////////////////////////////////////////////////////////////////////////// #macro emit(left_x,bottom_y,right_x,top_y,ecolor,level) #local os = 0; #declare cd = 1; #if (level = 2) emit_object(left_x+os,bottom_y+os,right_x+os,top_y+os,-2,ecolor*cd,level) #else emit_object(left_x,bottom_y,right_x,top_y,0,ecolor,level) #end #end ///////////////////////////////////////////////////////////////////////////////// #macro emit_control(left_x, top_y, right_x, bottom_y, top_left_data, top_right_data, bottom_left_data, bottom_right_data, cx,cy) #local emitted = off; // Disimilars get emitted if they have not already been so #if ((top_left_data[1].red = 0)) emit(left_x,bottom_y+cy, left_x+cx,top_y, top_left_data[0],level) #local emitted = on; #end #if ((top_right_data[1].red = 0)) emit(left_x+cx,bottom_y+cy, right_x,top_y, top_right_data[0],level) #local emitted = on; #end #if ((bottom_left_data[1].red = 0)) emit(left_x,bottom_y, left_x+cx,bottom_y+cy, bottom_left_data[0],level) #local emitted = on; #end #if ((bottom_right_data[1].red = 0)) emit(left_x+cx,bottom_y, right_x,bottom_y+cy, bottom_right_data[0],level) #local emitted = on; #end #if (emitted = on) #declare return_data = array[2] {, <1,1,1>}; #else #declare return_data = array[2] {, <0,0,0>}; #end #end ///////////////////////////////////////////////////////////////////////////////// #macro scan(left_x,bottom_y,right_x,top_y,level,level_limited) // Get locations etc. #local dx = abs(right_x - left_x); #local cx = dx*xsr; #local dy = abs(top_y - bottom_y); #local cy = dy*ysr; // Further depths to go? Then go down further #if ( ((dx > dd) & (dy > dd) & (level_limited = off)) | ((level < level_limit) & (level_limited = on)) ) // Top left scan(left_x,bottom_y+cy, left_x+cx,top_y,level+1,level_limited) #local top_left_data = return_data; // Top right scan(left_x+cx,bottom_y+cy, right_x,top_y,level+1,level_limited) #local top_right_data = return_data; // Bottom left scan(left_x,bottom_y, left_x+cx,bottom_y+cy,level+1,level_limited) #local bottom_left_data = return_data; // Bottom right scan(left_x+cx,bottom_y, right_x,bottom_y+cy,level+1,level_limited) #local bottom_right_data = return_data; // Now analyse that data similar_colors (top_left_data[0], top_right_data[0], bottom_left_data[0], bottom_right_data[0] ) // Similars float up #if (similar_answer = true) // Similar? Yes // Emitted? No. #if ((top_left_data[1].red = 0) & (top_right_data[1].red = 0) & (bottom_left_data[1].red = 0) & (bottom_right_data[1].red = 0) ) #declare return_data = array[2] {, <0,0,0>}; #else // Emitted? Yes, but emit those not yet emitted. emit_control(left_x, top_y, right_x, bottom_y, top_left_data, top_right_data, bottom_left_data, bottom_right_data, cx,cy) #end #else // Similar? No, check for required emits emit_control(left_x, top_y, right_x, bottom_y, top_left_data, top_right_data, bottom_left_data, bottom_right_data, cx,cy) #end #else // Get data #local bottom_left_color = eval_pigment(scan_pigment,); #declare return_data = array[2] {, <0,0,0>}; #end #end ///////////////////////////////////////////////////////////////////////////////// scan (0,0,xd,yd,1,on)