#ifndef(SPRAYPAINT_INC) #declare SPRAYPAINT_INC = version; #version 3.7; #end #ifdef(View_POV_Include_Stack) #debug "including spraypaint.inc\n" #end #include "rand.inc" #include "math.inc" // easyBlob macro curtesy of Rune Johansen #macro easyBlob(_threshold, _visibleRadius, _blobbiness) #local _strength = (1 + 1/_blobbiness)*_threshold; #local _actualRadius = _visibleRadius / sqrt( 1 - sqrt(_threshold / _strength ) ); _actualRadius, _strength #end /*********************************************************** * Name: SprayCan Date: Oct 18, 2012 * * * * Auth: Anthony D. Baye * * Vers: 1.1.0 * * Desc: Creates a blob object from spheres scattered on * * a surface by using the trace() function. The pattern * * can be limited by using the Template keyword. * * Args: * * Object -> The environment to trace against. * * Template -> The pigment used to evaluate the pattern. * * If no template is desired, use pigment { rgb 0 }. * ePath -> A spline delineating the path of the emitter. * * tPath -> A spline delineating the path of the target. * * FlowRate -> The number of particles per second. * * A good value for a scale of 1 unit = 1 foot is * * 20000. * * Angle -> Maximum angle for the spray cone. * * with a statistically normal distribution, 99.6% * * of the particles should be inside this angle. * * Duration -> The number of seconds it takes to complete * * the path. * * File -> Name the file that the resulting object will * * be saved in. No extension required, .inc will be * * appended. If no file is desired, enter "". * * Note: Even with optimizations, this macro can still take * * several minutes to parse. * **********************************************************/ #macro SprayCan(Object, Template, ePath, tPath, flowRate, Angle, Duration, File) #declare Clock = 1; #declare Slice_Delta = 1 / (Duration * 24.0); #if(File != "") #fopen paintFile concat(File, ".inc") write #write(paintFile, "#declare sprayPaintObject =\nunion {\n") #end #declare Pattern = union { // threshold 0.85 #local i = 0; #while(i < 1) #local pCount = 0; #while(pCount < flowRate*Slice_Delta*Duration) #local PHI = Rand_Normal(0.0, 0.33, RdmA)*(Angle/2); #local THETA = Rand_Normal(0.0, 1.0, RdmB)*180; #local Z = vnormalize(tPath(i) - ePath(i)); #if(abs(vdot(Z,z)) != 1) #local X = vcross(Z,z); #local Y = vcross(X,Z); #else #local X = x; #local Y = y; #end // #debug concat("PHI: " str(PHI, 0, 6) "\n") // #debug concat("THETA: " str(THETA, 0, 6) "\n") #local T = X*sind(PHI)*cosd(THETA) + Y*sind(PHI)*sind(THETA) + Z*cosd(PHI); #local T = vnormalize(T); // #debug concat("T: " vstr(3, T, ", ", 0, 6) "\n") // Begin trace #local Norm = <0, 0, 0> ; // degenerate Normal vector. #local Start = ePath(i) ; // The object starts here. #local Pos = trace (Object, Start, T, Norm) ; // And comes to rest here. // #debug concat("Pos: " vstr(3, Pos, ", ", 0, 6) "\n") // End trace #local dP = eval_pigment(Template, Pos); #if( vlength( ) = 0 ) sphere { Pos, 0.001 } #ifdef(paintFile) #write(paintFile, concat("\tsphere { <" vstr(3, Pos, ", ", 0, 6) "> 0.001 }\n")) #end // sphere { Pos, easyBlob(0.85, 0.001, 0.98) } #end #local pCount = pCount + 1; #end #local i = i + Slice_Delta; #end } #local Extents = concat("paint object extends from " vstr(3, min_extent(Pattern), ", ", 0, 3) " to " vstr(3, max_extent(Pattern), ", ", 0, 3) "\n") #ifdef(paintFile) #write(paintFile, "\t}\n") #write(paintFile, concat("/*\n" Extents "*/\n")) #fclose paintFile #debug concat("Spraypaint object saved in file \"" File ".inc\"\n") #end #debug Extents Pattern #end