|
|
The latest version of my spraypaint macro. Example in p.b.a
Comments, Suggestions?
A.D.B.
#ifndef(SPRAYCAN_INC)
#declare SPRAYCAN_INC = version;
#end
#ifdef(View_POV_Include_Stack)
#debug "including spraycan.inc\n"
#end
#include "rand.inc"
#include "math.inc"
#include "arrays.inc"
#declare PARTICLES = array[5000]
#declare PARTICLE_COUNT = 0;
#macro addParticle(LOCATION, INDEX)
#declare PARTICLE_COUNT = PARTICLE_COUNT + 1;
#if(PARTICLE_COUNT > dimension_size(PARTICLES, 1))
Resize_Array(PARTICLES, dimension_size(PARTICLES, 1)+5000)
#end
#local PARTICLE = array[2] {LOCATION, <INDEX,0,0>}
#declare PARTICLES[PARTICLE_COUNT - 1] = PARTICLE;
#end
#macro reconstructFromFile()
#local Ind = 0.0;
#read(paintFile,Col)
#ifndef(__IGNOREFILECOLOR__)
#declare MyColor = Col;
#end
#while(defined(paintFile) & Ind <= TOTALITY)
#read(paintFile,Loc,Ind)
addParticle(Loc,Ind)
#end
#end
/***********************************************************
* Name: SprayCan Date: Oct 18, 2012 *
* *
* Auth: Anthony D. Baye *
* Vers: 2.0 *
* Desc: Creates a union from spheres scattered on a surface *
* by using the trace() function. The pattern can be *
* limited by giving a pigment in the TEMPLATE slot. *
* 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.7% *
* of the particles should be inside this angle. *
* DURATION -> The number of seconds it takes to complete *
* the path. *
* TOTALITY -> 0...1 inclusive. Mainly used for animation *
* but can be used in single image mode as well. *
* 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 "". *
* Cache file will be preferred if one exists, unless*
* __FORCE_CREATE__ is defined. *
* Global Constants: *
* __FRAMERATE__ -> Set custom framerate. Default: 24fps *
* __FORCE_CREATE__ -> When defined, overrides default *
* behavior of preferring a cache file. *
* When the clock is running, this will cause the *
* cache to be rebuilt on the first frame only. *
* __SPRAYDEBUG__ -> Turn debug streams on when defined. *
* __IGNOREFILECOLOR__ -> Always use the color specified *
* in the macro call. Useful for experimenting with *
* colors, without rebuilding the pattern. *
* Note: Even with optimizations, this macro can still take *
* several minutes to parse. *
**********************************************************/
// Animation!
// File now saves temporal data for each particle
// Saved data is now in flatfile format as comma-separated values.
#macro SprayCan(OBJECT, TEMPLATE, EPATH, TPATH, Color, FLOWRATE, ANGLE,
DURATION, TOTALITY, FILE)
#local MyColor = Color;
#local extension = ".spr"
#ifndef(__FRAMERATE__)
#local __FRAMERATE__ = 24;
#end
#if((FILE != "" & !file_exists(concat(FILE, extension))) |
(defined(__FORCE_CREATE__) & (! clock_on | frame_number = initial_frame)))
#declare doCreate = true;
#debug "doCreate set to True.\n"
#else
#declare doCreate = false;
#debug "doCreate set to False.\n"
#end
// A warning is needed in animation mode if the file has not been specified.
#if(FILE = "")
#warning "SprayCan: Warning! No file specified, pattern will not be saved!\n"
#end
#if(doCreate)
#declare Slice_Delta = 1 / (DURATION * __FRAMERATE__);
#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
#local _T = _X*sind(PHI)*cosd(THETA) + _Y*sind(PHI)*sind(THETA) +
_Z*cosd(PHI);
#local _T = vnormalize(_T);
// 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.
// End trace
#local dP = eval_pigment(TEMPLATE, Pos);
#if( vlength( <dP.red, dP.green, dP.blue> ) = 0 )
addParticle(Pos, i)
#end
#local pCount = pCount + 1;
#end
#local i = i + Slice_Delta;
#end
#if(FILE != "")
#fopen paintFile concat(FILE, extension) write
#write (paintFile, concat("<" vstr(3, MyColor,",",0,6) ">,"))
#end
#else
#if(FILE != "")
#fopen paintFile concat(FILE, extension) read
#end
#ifdef(__SPRAYDEBUG__)
#debug concat("Loading paint data from file " FILE extension "...\n")
#end
reconstructFromFile()
#end
// TODO: Pattern should obey TOTALITY even when doCreate = true.
#declare Pattern =
union {
#for(i,0,PARTICLE_COUNT-1,1)
#if(!doCreate | PARTICLES[i][1].x <= TOTALITY)
sphere { PARTICLES[i][0], 0.001 }
#end
#if(doCreate)
#ifdef(paintFile)
#write(paintFile,concat("<"vstr(3,PARTICLES[i][0],",",0,6) ">,"
str(PARTICLES[i][1].x,0,10) ","))
#end
#end
#end
pigment { rgb MyColor }
}
#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)
#fclose paintFile
#if(defined(__SPRAYDEBUG__) & doCreate)
#debug concat("Spraypaint object saved in file \"" FILE extension"\"\n")
#end
#end
#ifdef(__SPRAYDEBUG__)
#debug concat(str(PARTICLE_COUNT,0,1) " particles deposited.\n")
#debug Extents
#end
#declare PARTICLES = array[5000]
#declare PARTICLE_COUNT = 0;
Pattern
#end
Post a reply to this message
|
|