home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Graphics / Graphics.zip / povsrc31.zip / pigment.c < prev    next >
C/C++ Source or Header  |  2001-01-21  |  25KB  |  860 lines

  1. /****************************************************************************
  2. *                pigment.c
  3. *
  4. *  This module implements solid texturing functions that modify the color
  5. *  transparency of an object's surface.
  6. *
  7. *  from Persistence of Vision(tm) Ray Tracer
  8. *  Copyright 1996,1999 Persistence of Vision Team
  9. *---------------------------------------------------------------------------
  10. *  NOTICE: This source code file is provided so that users may experiment
  11. *  with enhancements to POV-Ray and to port the software to platforms other
  12. *  than those supported by the POV-Ray Team.  There are strict rules under
  13. *  which you are permitted to use this file.  The rules are in the file
  14. *  named POVLEGAL.DOC which should be distributed with this file.
  15. *  If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  16. *  Team Coordinator by email to team-coord@povray.org or visit us on the web at
  17. *  http://www.povray.org. The latest version of POV-Ray may be found at this site.
  18. *
  19. * This program is based on the popular DKB raytracer version 2.12.
  20. * DKBTrace was originally written by David K. Buck.
  21. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  22. *
  23. *****************************************************************************/
  24.  
  25. /*
  26.    Some texture ideas garnered from SIGGRAPH '85 Volume 19 Number 3, 
  27.    "An Image Synthesizer" By Ken Perlin.
  28.    Further Ideas Garnered from "The RenderMan Companion" (Addison Wesley).
  29. */
  30.  
  31. #include "frame.h"
  32. #include "vector.h"
  33. #include "povproto.h"
  34. #include "texture.h"
  35. #include "colour.h"   
  36. #include "image.h"    
  37. #include "matrices.h" 
  38. #include "pigment.h"  
  39. #include "txttest.h"
  40. #ifdef BlobPatternPatch
  41. #include "pattern.h"/*Chris Huff blob pigment*/
  42. #endif                    
  43.  
  44. /*****************************************************************************
  45. * Local preprocessor defines
  46. ******************************************************************************/
  47.  
  48.  
  49.  
  50. /*****************************************************************************
  51. * Local typedefs
  52. ******************************************************************************/
  53.  
  54.  
  55.  
  56. /*****************************************************************************
  57. * Local variables
  58. ******************************************************************************/
  59.  
  60. static BLEND_MAP_ENTRY Black_White_Entries[2] /* =
  61.   {{0.0, FALSE, {{0.0, 0.0, 0.0, 0.0, 0.0}}},
  62.   {1.0, FALSE, {{1.0, 1.0, 1.0, 0.0, 0.0}}}} */ ;
  63.  
  64. static BLEND_MAP Gray_Default_Map =
  65.   { 2,  FALSE, COLOUR_TYPE,  -1,  Black_White_Entries};
  66.  
  67. static BLEND_MAP_ENTRY Bozo_Entries[6] /* =
  68.   {{0.4, FALSE, {{1.0, 1.0, 1.0, 0.0, 0.0}}},
  69.    {0.4, FALSE, {{0.0, 1.0, 0.0, 0.0, 0.0}}},
  70.    {0.6, FALSE, {{0.0, 1.0, 0.0, 0.0, 0.0}}},
  71.    {0.6, FALSE, {{0.0, 0.0, 1.0, 0.0, 0.0}}},
  72.    {0.8, FALSE, {{0.0, 0.0, 1.0, 0.0, 0.0}}},
  73.    {0.8, FALSE, {{1.0, 0.0, 0.0, 0.0, 0.0}}}} */ ;
  74.  
  75. static BLEND_MAP Bozo_Default_Map =
  76.   { 6,  FALSE, COLOUR_TYPE,  -1,  Bozo_Entries};
  77.  
  78. static BLEND_MAP_ENTRY Wood_Entries[2] /* =
  79.   {{0.6, FALSE, {{0.666, 0.312,  0.2,   0.0, 0.0}}},
  80.    {0.6, FALSE, {{0.4,   0.1333, 0.066, 0.0, 0.0}}}} */ ;
  81.     
  82. static BLEND_MAP Wood_Default_Map =
  83.   { 2,  FALSE, COLOUR_TYPE,  -1,  Wood_Entries};
  84.  
  85. static BLEND_MAP_ENTRY Mandel_Entries[5] /* =
  86.   {{0.001, FALSE, {{0.0, 0.0, 0.0, 0.0, 0.0}}},
  87.    {0.001, FALSE, {{0.0, 1.0, 1.0, 0.0, 0.0}}},
  88.    {0.012, FALSE, {{1.0, 1.0, 0.0, 0.0, 0.0}}},
  89.    {0.015, FALSE, {{1.0, 0.0, 1.0, 0.0, 0.0}}},
  90.    {0.1,   FALSE, {{0.0, 1.0, 1.0, 0.0, 0.0}}}} */ ;
  91.  
  92. static BLEND_MAP Mandel_Default_Map =
  93.   { 5,  FALSE, COLOUR_TYPE,  -1,  Mandel_Entries};
  94.  
  95. static BLEND_MAP_ENTRY Agate_Entries[6] /* =
  96.   {{0.0, FALSE, {{1.0,  1.0,  1.0,  0.0, 0.0}}},
  97.    {0.5, FALSE, {{0.95, 0.75, 0.5,  0.0, 0.0}}},
  98.    {0.5, FALSE, {{0.9,  0.7,  0.5,  0.0, 0.0}}},
  99.    {0.6, FALSE, {{0.9,  0.7,  0.4,  0.0, 0.0}}},
  100.    {0.6, FALSE, {{1.0,  0.7,  0.4,  0.0, 0.0}}},
  101.    {1.0, FALSE, {{0.6,  0.3,  0.0,  0.0, 0.0}}}} */ ;
  102.  
  103. static BLEND_MAP Agate_Default_Map =
  104.   { 6,  FALSE, COLOUR_TYPE,  -1,  Agate_Entries};
  105.  
  106. static BLEND_MAP_ENTRY Radial_Entries[4] /* =
  107.   {{0.0,   FALSE, {{0.0, 1.0, 1.0, 0.0, 0.0}}},
  108.    {0.333, FALSE, {{1.0, 1.0, 0.0, 0.0, 0.0}}},
  109.    {0.666, FALSE, {{1.0, 0.0, 1.0, 0.0, 0.0}}},
  110.    {1.0,   FALSE, {{0.0, 1.0, 1.0, 0.0, 0.0}}}} */ ;
  111.  
  112. static BLEND_MAP Radial_Default_Map =
  113.   { 4,  FALSE, COLOUR_TYPE,  -1,  Radial_Entries};
  114.  
  115. static BLEND_MAP_ENTRY Marble_Entries[3] /* =
  116.   {{0.0, FALSE, {{0.9, 0.8,  0.8,  0.0, 0.0}}},
  117.    {0.9, FALSE, {{0.9, 0.08, 0.08, 0.0, 0.0}}},
  118.    {0.9, FALSE, {{0.0, 0.0, 0.0, 0.0, 0.0}}}} */ ;
  119.  
  120. static BLEND_MAP Marble_Default_Map =
  121.   { 3,  FALSE, COLOUR_TYPE,  -1,  Marble_Entries};
  122.  
  123. static BLEND_MAP_ENTRY Brick_Entries[2] /* =
  124.   {{0.0, FALSE, {{0.5, 0.5,  0.5,  0.0, 0.0}}},
  125.    {1.0, FALSE, {{0.6, 0.15, 0.15, 0.0, 0.0}}}} */ ;
  126.  
  127. BLEND_MAP Brick_Default_Map =
  128.   { 2,  FALSE, COLOUR_TYPE,  -1,  Brick_Entries};
  129.  
  130. #ifdef TrianglulairSquarePatch 
  131. static BLEND_MAP_ENTRY Hex_Entries[3] =
  132.   {{0.0, FALSE, {{0.0, 0.0, 1.0, 0.0, 0.0}}},
  133.    {1.0, FALSE, {{0.0, 1.0, 0.0, 0.0, 0.0}}},
  134.    {2.0, FALSE, {{1.0, 0.0, 0.0, 0.0, 0.0}}}} ;
  135.  
  136. static BLEND_MAP_ENTRY Ter_Entries[6] =
  137.   {{0.0, FALSE, {{0.0, 0.0, 1.0, 0.0, 0.0}}},
  138.    {1.0, FALSE, {{1.0, 0.0, 0.0, 0.0, 0.0}}},
  139.    {2.0, FALSE, {{1.0, 0.0, 1.0, 0.0, 0.0}}},
  140.    {3.0, FALSE, {{0.0, 1.0, 0.0, 0.0, 0.0}}},
  141.    {4.0, FALSE, {{0.0, 1.0, 1.0, 0.0, 0.0}}},
  142.    {5.0, FALSE, {{1.0, 1.0, 0.0, 0.0, 0.0}}}} ;
  143.  
  144. static BLEND_MAP_ENTRY Square_Entries[4] =
  145.   {{0.0, FALSE, {{0.0, 0.0, 0.0, 0.0, 0.0}}},
  146.    {1.0, FALSE, {{0.0, 1.0, 0.0, 0.0, 0.0}}},
  147.    {2.0, FALSE, {{1.0, 0.0, 0.0, 0.0, 0.0}}},
  148.    {3.0, FALSE, {{1.0, 1.0, 1.0, 0.0, 0.0}}}} ;
  149. #else
  150. static BLEND_MAP_ENTRY Hex_Entries[3] /*=
  151.   {{0.0, FALSE, {{0.0, 0.0, 1.0, 0.0, 0.0}}},
  152.    {1.0, FALSE, {{0.0, 1.0, 0.0, 0.0, 0.0}}},
  153.    {2.0, FALSE, {{1.0, 0.0, 0.0, 0.0, 0.0}}}} */;
  154. #endif
  155.  
  156. BLEND_MAP Hex_Default_Map =
  157.   { 3, FALSE,COLOUR_TYPE, -1, Hex_Entries};
  158.  
  159. #ifdef TrianglulairSquarePatch 
  160. BLEND_MAP Ter_Default_Map =
  161.   { 6, FALSE,COLOUR_TYPE, -1, Ter_Entries};
  162.  
  163. BLEND_MAP Square_Default_Map =
  164.   { 4, FALSE,COLOUR_TYPE, -1, Square_Entries};
  165. #endif
  166. BLEND_MAP Check_Default_Map =
  167.   { 2, FALSE,COLOUR_TYPE, -1, Hex_Entries}; /* Yes... Hex_Entries, not Check [CY] */
  168.  
  169.  
  170.  
  171. /*****************************************************************************
  172. * Static functions
  173. ******************************************************************************/
  174. static void Do_Average_Pigments (COLOUR Colour, PIGMENT *Pigment, VECTOR EPoint,INTERSECTION *Intersection);
  175.  
  176. #ifdef BlobPatternPatch
  177. static int blob_pigment(VECTOR TPoint, PIGMENT * Pigment, COLOUR Colour, INTERSECTION *Intersection);
  178. #endif
  179.  
  180. /*****************************************************************************
  181. *
  182. * FUNCTION
  183. *
  184. *   Create_Pigment
  185. *
  186. * INPUT
  187. *   
  188. * OUTPUT
  189. *   
  190. * RETURNS
  191. *
  192. *   pointer to the created pigment
  193. *   
  194. * AUTHOR
  195. *
  196. *   POV-Ray Team
  197. *   
  198. * DESCRIPTION   : Allocate memory for new pigment and initialize it to
  199. *                 system default values.
  200. *
  201. * CHANGES
  202. *
  203. ******************************************************************************/
  204.  
  205. PIGMENT *Create_Pigment ()
  206. {
  207.   PIGMENT *New;
  208.  
  209.   New = (PIGMENT *)POV_MALLOC(sizeof (PIGMENT), "pigment");
  210.  
  211.   Init_TPat_Fields((TPATTERN *)New);
  212.  
  213.   Make_Colour(New->Colour, 0.0,0.0,0.0) ;
  214.  
  215.   New->Blend_Map = NULL;
  216.  
  217.   return (New);
  218. }
  219.  
  220.  
  221.  
  222. /*****************************************************************************
  223. *
  224. * FUNCTION
  225. *
  226. *   Copy_Pigment
  227. *
  228. * INPUT
  229. *
  230. *   Old -- point to pigment to be copied
  231. *   
  232. * RETURNS
  233. *
  234. *   pointer to the created pigment
  235. *   
  236. * AUTHOR
  237. *
  238. *   POV-Ray Team
  239. *   
  240. * DESCRIPTION   : Allocate memory for new pigment and initialize it to
  241. *                 values in existing pigment Old.
  242. *
  243. * CHANGES
  244. *
  245. ******************************************************************************/
  246.  
  247. PIGMENT *Copy_Pigment (PIGMENT *Old)
  248. {
  249.   PIGMENT *New;
  250.  
  251.   if (Old != NULL)
  252.   {
  253.     New = Create_Pigment ();
  254.  
  255.     Copy_TPat_Fields ((TPATTERN *)New, (TPATTERN *)Old);
  256.  
  257.     if (Old->Type == PLAIN_PATTERN)
  258.     {
  259.       Assign_Colour(New->Colour,Old->Colour);
  260.     }
  261.     New->Next = (TPATTERN *)Copy_Pigment((PIGMENT *)Old->Next);
  262.   }
  263.   else
  264.   {
  265.     New = NULL;
  266.   }
  267.  
  268.   return (New);
  269. }
  270.  
  271.  
  272.  
  273. /*****************************************************************************
  274. *
  275. * FUNCTION
  276. *
  277. *   Destroy_Pigment
  278. *
  279. * INPUT
  280. *
  281. *   pointer to pigment to destroied
  282. *   
  283. * OUTPUT
  284. *   
  285. * RETURNS
  286. *   
  287. * AUTHOR
  288. *
  289. *   POV-Ray Team
  290. *   
  291. * DESCRIPTION   : free all memory associated with given pigment
  292. *
  293. * CHANGES
  294. *
  295. ******************************************************************************/
  296.  
  297. void Destroy_Pigment (PIGMENT *Pigment)
  298. {
  299.   if (Pigment != NULL)
  300.   {
  301.     Destroy_Pigment((PIGMENT *)Pigment->Next);
  302.  
  303.     Destroy_TPat_Fields ((TPATTERN *)Pigment);
  304.  
  305.     POV_FREE(Pigment);
  306.   }
  307. }
  308.  
  309.  
  310.  
  311. /*****************************************************************************
  312. *
  313. * FUNCTION
  314. *
  315. *   Post_Pigment
  316. *
  317. * INPUT
  318. *   
  319. * OUTPUT
  320. *   
  321. * RETURNS
  322. *   
  323. * AUTHOR
  324. *
  325. *   Chris Young
  326. *   
  327. * DESCRIPTION
  328. *
  329. * CHANGES
  330. *
  331. ******************************************************************************/
  332.  
  333. int Post_Pigment(PIGMENT *Pigment)
  334. {
  335.   int i, Has_Filter;
  336.   BLEND_MAP *Map;
  337.  
  338.   if (Pigment == NULL)
  339.   {
  340.     Error("Missing pigment");
  341.   }
  342.  
  343.   if (Pigment->Flags & POST_DONE)
  344.   {
  345.     return(Pigment->Flags & HAS_FILTER);
  346.   }
  347.  
  348.   if (Pigment->Type == NO_PATTERN)
  349.   {
  350.     Pigment->Type = PLAIN_PATTERN;
  351.  
  352.     Make_Colour(Pigment->Colour, 0.0, 0.0, 0.0) ;
  353.  
  354.     Warning(150, "No pigment type given.\n");
  355.   }
  356.  
  357.   Pigment->Flags |= POST_DONE;
  358.  
  359.   switch (Pigment->Type)
  360.   {
  361.     case PLAIN_PATTERN:
  362.  
  363.       Destroy_Warps (Pigment->Warps);
  364.  
  365.       Pigment->Warps = NULL;
  366.  
  367.       break;
  368.  
  369.     case NO_PATTERN:
  370.     case BITMAP_PATTERN:
  371.  
  372.       break;
  373.  
  374.     default:
  375.  
  376.       if (Pigment->Blend_Map == NULL)
  377.       {
  378.         switch (Pigment->Type)
  379.         {
  380.           case BOZO_PATTERN:    Pigment->Blend_Map = &Bozo_Default_Map;  break;
  381.           case BRICK_PATTERN:   Pigment->Blend_Map = &Brick_Default_Map; break;
  382.           case WOOD_PATTERN:    Pigment->Blend_Map = &Wood_Default_Map;  break;
  383.           case MAGNET1M_PATTERN:
  384.           case MAGNET1J_PATTERN:
  385.           case MAGNET2M_PATTERN:
  386.           case MAGNET2J_PATTERN:
  387.           case MANDEL3_PATTERN:
  388.           case MANDEL4_PATTERN:
  389.           case JULIA_PATTERN:
  390.           case JULIA3_PATTERN:
  391.           case JULIA4_PATTERN:
  392.           case MANDEL_PATTERN:  Pigment->Blend_Map = &Mandel_Default_Map;break;
  393.           case RADIAL_PATTERN:  Pigment->Blend_Map = &Radial_Default_Map;break;
  394.           case AGATE_PATTERN:   Pigment->Blend_Map = &Agate_Default_Map; break;
  395.           case MARBLE_PATTERN:  Pigment->Blend_Map = &Marble_Default_Map;break;
  396.           case HEXAGON_PATTERN: Pigment->Blend_Map = &Hex_Default_Map;   break;
  397. #ifdef TrianglulairSquarePatch 
  398.           case TERNAIRE_PATTERN: Pigment->Blend_Map = &Ter_Default_Map;   break;
  399.           case SQUARE_PATTERN: Pigment->Blend_Map = &Square_Default_Map; break;
  400. #endif
  401.           case CHECKER_PATTERN: Pigment->Blend_Map = &Check_Default_Map; break;
  402. #ifdef ObjectPatternPatch
  403.           case OBJECT_PATTERN: Pigment->Blend_Map = &Check_Default_Map; break;/*Chris Huff object pattern*/
  404. #endif
  405.           case AVERAGE_PATTERN: Error("Missing pigment_map in average pigment"); break;
  406.           default:              Pigment->Blend_Map = &Gray_Default_Map;  break;
  407.         }
  408.       }
  409.  
  410.       break;
  411.   }
  412.  
  413.   /* Now we test wether this pigment is opaque or not. [DB 8/94] */
  414.  
  415.   Has_Filter = FALSE;
  416.  
  417.   if ((fabs(Pigment->Colour[FILTER]) > EPSILON) ||
  418.       (fabs(Pigment->Colour[TRANSM]) > EPSILON))
  419.   {
  420.     Has_Filter = TRUE;
  421.   }
  422.  
  423.   if ((Map = Pigment->Blend_Map) != NULL)
  424.   {
  425.     if ((Map->Type == PIGMENT_TYPE) || (Map->Type == DENSITY_TYPE))
  426.     {
  427.        for (i = 0; i < Map->Number_Of_Entries; i++)
  428.        {
  429.          Has_Filter |= Post_Pigment(Map->Blend_Map_Entries[i].Vals.Pigment);
  430.        }
  431.     }
  432.     else
  433.     {
  434.        for (i = 0; i < Map->Number_Of_Entries; i++)
  435.        {
  436.          Has_Filter |= fabs(Map->Blend_Map_Entries[i].Vals.Colour[FILTER])>EPSILON;
  437.          Has_Filter |= fabs(Map->Blend_Map_Entries[i].Vals.Colour[TRANSM])>EPSILON;
  438.        }
  439.     }
  440.   }
  441.  
  442.   if (Has_Filter)
  443.   {
  444.     Pigment->Flags |= HAS_FILTER;
  445.   }
  446.   
  447.   if (Pigment->Next != NULL)
  448.   {
  449.     Post_Pigment((PIGMENT *)Pigment->Next);
  450.   }
  451.  
  452.   return(Has_Filter);
  453. }
  454.  
  455.  
  456.  
  457. /*****************************************************************************
  458. *
  459. * FUNCTION
  460. *
  461. *   Compute_Pigment
  462. *
  463. * INPUT
  464. *
  465. *   Pigment - Info about this pigment
  466. *   EPoint  - 3-D point at which pattern is evaluated
  467. *   Intersection - structure holding info about object at intersection point
  468. *
  469. * OUTPUT
  470. *
  471. *   Colour  - Resulting color is returned here.
  472. *
  473. * RETURNS
  474. *
  475. *   int - TRUE,  if a color was found for the given point
  476. *         FALSE, if no color was found (e.g. areas outside an image map
  477. *                that has the once option)
  478. *
  479. * AUTHOR
  480. *
  481. *   POV-Ray Team
  482. *
  483. * DESCRIPTION
  484. *   Given a 3d point and a pigment, compute colour from that layer.
  485. *   (Formerly called "Colour_At", or "Add_Pigment")
  486. *
  487. * CHANGES
  488. *   Added pigment map support [CY 11/94]
  489. *   Added Intersection parameter for UV support NK 1998
  490. *
  491. ******************************************************************************/
  492.  
  493. int Compute_Pigment (COLOUR Colour, PIGMENT *Pigment, VECTOR EPoint, INTERSECTION *Intersection)
  494. {
  495.   int Colour_Found;
  496.   VECTOR TPoint;
  497.   DBL value;
  498.   register DBL fraction;
  499.   BLEND_MAP_ENTRY *Cur, *Prev;
  500.   COLOUR Temp_Colour;
  501.   BLEND_MAP *Blend_Map = Pigment->Blend_Map;
  502.  
  503.   if (Pigment->Type <= LAST_SPECIAL_PATTERN)
  504.   {
  505.     Colour_Found = TRUE;
  506.  
  507.     switch (Pigment->Type)
  508.     {
  509.       case NO_PATTERN:
  510.  
  511.         Make_Colour(Colour, 0.0, 0.0, 0.0);
  512.  
  513.         break;
  514.  
  515.       case PLAIN_PATTERN:
  516.  
  517.         Assign_Colour(Colour,Pigment->Colour);
  518.  
  519.         break;
  520.  
  521.       case AVERAGE_PATTERN:
  522.  
  523.         /* NK 1998 reset_children - added TRUE */
  524.         Warp_EPoint (TPoint, EPoint, (TPATTERN *)Pigment, TRUE);
  525.  
  526.         Do_Average_Pigments(Colour,Pigment,TPoint,Intersection);
  527.  
  528.         break;
  529.  
  530.       case BITMAP_PATTERN:
  531.  
  532.         /* NK 1998 reset_children - added FALSE - do not execute RESET_CHILDREN warps */
  533.         Warp_EPoint (TPoint, EPoint, (TPATTERN *)Pigment, FALSE);
  534.  
  535.         Make_Colour(Colour, 0.0, 0.0, 0.0);
  536.  
  537.         Colour_Found = image_map (TPoint, Pigment, Colour);
  538.  
  539.         break;
  540. #ifdef NoisePigmentPatch
  541.       case NOISE_PIGMENT:/*Chris Huff noise pigment*/
  542.       {
  543.         COLC mnR = Pigment->Vals.NoisePigment.Min[0];
  544.         COLC mnG = Pigment->Vals.NoisePigment.Min[1];
  545.         COLC mnB = Pigment->Vals.NoisePigment.Min[2];
  546.         
  547.         COLC mxR = Pigment->Vals.NoisePigment.Max[0];
  548.         COLC mxG = Pigment->Vals.NoisePigment.Max[1];
  549.         COLC mxB = Pigment->Vals.NoisePigment.Max[2];
  550.         
  551.         Warp_EPoint (TPoint, EPoint, (TPATTERN *)Pigment,FALSE);
  552.  
  553.         Make_Colour(Colour, 0.0, 0.0, 0.0);
  554.         
  555.         switch(Pigment->Vals.NoisePigment.NoiseType)
  556.         {
  557.             case 0:/*plain color*/
  558.             {
  559.                 Colour[0] = (FRAND()*(mxR-mnR))+mnR;
  560.                 Colour[1] = (FRAND()*(mxG-mnG))+mnG;
  561.                 Colour[2] = (FRAND()*(mxB-mnB))+mnB;
  562.             }
  563.             break;
  564.             
  565.             case 1:/*plain monochrome*/
  566.             {
  567.                 DBL n = FRAND();
  568.                 Colour[0] = (n*(mxR-mnR))+mnR;
  569.                 Colour[1] = (n*(mxG-mnG))+mnG;
  570.                 Colour[2] = (n*(mxB-mnB))+mnB;
  571.             }
  572.             break;
  573.             
  574.             case 2:/*gaussian color*/
  575.             {
  576.                 Colour[0] = (((FRAND()+FRAND()+FRAND())/3)*(mxR-mnR))+mnR;
  577.                 Colour[1] = (((FRAND()+FRAND()+FRAND())/3)*(mxG-mnG))+mnG;
  578.                 Colour[2] = (((FRAND()+FRAND()+FRAND())/3)*(mxB-mnB))+mnB;
  579.             }
  580.             break;
  581.             
  582.             case 3:/*gaussian monochrome*/
  583.             {
  584.                 DBL n = (FRAND()+FRAND()+FRAND())/3;
  585.                 Colour[0] = (n*(mxR-mnR))+mnR;
  586.                 Colour[1] = (n*(mxG-mnG))+mnG;
  587.                 Colour[2] = (n*(mxB-mnB))+mnB;
  588.             }
  589.             break;
  590.             
  591.             default:/*plain color*/
  592.             {
  593.                 Colour[0] = FRAND();
  594.                 Colour[1] = FRAND();
  595.                 Colour[2] = FRAND();
  596.             }
  597.         }
  598.         Colour_Found = TRUE;
  599.       }
  600.       break;
  601. #endif
  602. #ifdef BlobPatternPatch
  603.       case BLOB_PIGMENT:/*Chris Huff blob pigment*/
  604.  
  605.         Warp_EPoint (TPoint, EPoint, (TPATTERN *)Pigment,FALSE);
  606.  
  607.         Make_Colour(Colour, 0.0, 0.0, 0.0);
  608.  
  609.         Colour_Found = blob_pigment(TPoint, Pigment, Colour,Intersection);
  610.  
  611.         break;
  612. #endif
  613.       default:
  614.  
  615.         Error("Pigment type %d not yet implemented",Pigment->Type);
  616.     }
  617.  
  618.     return(Colour_Found);
  619.   }
  620.  
  621.   Colour_Found = FALSE;
  622.  
  623.   /* NK 19 Nov 1999 added Warp_EPoint */
  624.   Warp_EPoint (TPoint, EPoint, (TPATTERN *)Pigment, FALSE);
  625.   value = Evaluate_TPat ((TPATTERN *)Pigment,TPoint,Intersection);
  626.  
  627.   Search_Blend_Map (value, Blend_Map, &Prev, &Cur);
  628.  
  629.   if (Blend_Map->Type == COLOUR_TYPE)
  630.   {
  631.     Colour_Found = TRUE;
  632.  
  633.     Assign_Colour(Colour, Cur->Vals.Colour);
  634.   }
  635.   else
  636.   {
  637.     /* NK 1998 reset_children - added ", TRUE" - RESET_CHILDREN warps will be executed */
  638.     Warp_EPoint (TPoint, EPoint, (TPATTERN *)Pigment, TRUE);
  639.  
  640.     if (Compute_Pigment(Colour, Cur->Vals.Pigment,TPoint,Intersection))
  641.     {
  642.       Colour_Found = TRUE;
  643.     }
  644.   }
  645.  
  646.   if (Prev != Cur)
  647.   {
  648.     if (Blend_Map->Type == COLOUR_TYPE)
  649.     {
  650.       Colour_Found = TRUE;
  651.  
  652.       Assign_Colour(Temp_Colour, Prev->Vals.Colour);
  653.     }
  654.     else
  655.     {
  656.       if (Compute_Pigment(Temp_Colour, Prev->Vals.Pigment, TPoint,Intersection))
  657.       {
  658.         Colour_Found = TRUE;
  659.       }
  660.     }
  661.  
  662.     fraction = (value - Prev->value) / (Cur->value - Prev->value);
  663.  
  664.     Colour[RED]    = Temp_Colour[RED]    + fraction * (Colour[RED]    - Temp_Colour[RED]);
  665.     Colour[GREEN]  = Temp_Colour[GREEN]  + fraction * (Colour[GREEN]  - Temp_Colour[GREEN]);
  666.     Colour[BLUE]   = Temp_Colour[BLUE]   + fraction * (Colour[BLUE]   - Temp_Colour[BLUE]);
  667.     Colour[FILTER] = Temp_Colour[FILTER] + fraction * (Colour[FILTER] - Temp_Colour[FILTER]);
  668.     Colour[TRANSM] = Temp_Colour[TRANSM] + fraction * (Colour[TRANSM] - Temp_Colour[TRANSM]);
  669.   }
  670.  
  671.   return(Colour_Found);
  672. }
  673.  
  674.  
  675.  
  676. /*****************************************************************************
  677. *
  678. * FUNCTION
  679. *
  680. * INPUT
  681. *
  682. * OUTPUT
  683. *   
  684. * RETURNS
  685. *   
  686. * AUTHOR
  687. *   
  688. * DESCRIPTION
  689. *
  690. * CHANGES
  691. *   Added Intersection parameter for UV support NK 1998
  692. *
  693. ******************************************************************************/
  694.  
  695. static void Do_Average_Pigments (COLOUR Colour, PIGMENT *Pigment, VECTOR EPoint, INTERSECTION *Intersection)
  696. {
  697.    int i;
  698.    COLOUR LC;
  699.    BLEND_MAP *Map = Pigment->Blend_Map;
  700.    SNGL Value;
  701.    SNGL Total = 0.0;
  702.    
  703.    Make_Colour (Colour, 0.0, 0.0, 0.0);
  704.  
  705.    for (i = 0; i < Map->Number_Of_Entries; i++)
  706.    {
  707.      Value = Map->Blend_Map_Entries[i].value;
  708.  
  709.      Compute_Pigment (LC,Map->Blend_Map_Entries[i].Vals.Pigment,EPoint,Intersection);
  710.      
  711.      Colour[RED]   += LC[RED]   *Value;
  712.      Colour[GREEN] += LC[GREEN] *Value;
  713.      Colour[BLUE]  += LC[BLUE]  *Value;
  714.      Colour[FILTER]+= LC[FILTER]*Value;
  715.      Colour[TRANSM]+= LC[TRANSM]*Value;
  716.  
  717.      Total += Value;
  718.    }
  719.    Colour[RED]   /= Total;
  720.    Colour[GREEN] /= Total;
  721.    Colour[BLUE]  /= Total;
  722.    Colour[FILTER]/= Total;
  723.    Colour[TRANSM]/= Total;
  724. }
  725.  
  726.  
  727.  
  728. /*****************************************************************************
  729. *
  730. * FUNCTION  Make_Pigment_Entries
  731. *
  732. * INPUT  None
  733. *   
  734. * OUTPUT  Initializes default pigment blend_map values.
  735. *   
  736. * RETURNS  None
  737. *   
  738. * AUTHOR  Steve Demlow, Dec. '95
  739. *   
  740. * DESCRIPTION  Some pre-ANSI compilers won't auto-initialize unions, so these
  741. *   have to be done in regular code.
  742. *
  743. * CHANGES
  744. *
  745. ******************************************************************************/
  746.  
  747. void Make_Pigment_Entries()
  748. {
  749.   static unsigned char Made = FALSE;
  750.  
  751.   if (Made) {
  752.     return;
  753.   }
  754.   Made = TRUE;
  755.  
  756.   Make_Blend_Map_Entry(Black_White_Entries[0] , 0.0, FALSE, 0.0, 0.0, 0.0, 0.0, 0.0);
  757.   Make_Blend_Map_Entry(Black_White_Entries[1] , 1.0, FALSE, 1.0, 1.0, 1.0, 0.0, 0.0);
  758.   
  759.   Make_Blend_Map_Entry(Bozo_Entries[0], 0.4, FALSE, 1.0, 1.0, 1.0, 0.0, 0.0);
  760.   Make_Blend_Map_Entry(Bozo_Entries[1], 0.4, FALSE, 0.0, 1.0, 0.0, 0.0, 0.0);
  761.   Make_Blend_Map_Entry(Bozo_Entries[2], 0.6, FALSE, 0.0, 1.0, 0.0, 0.0, 0.0);
  762.   Make_Blend_Map_Entry(Bozo_Entries[3], 0.6, FALSE, 0.0, 0.0, 1.0, 0.0, 0.0);
  763.   Make_Blend_Map_Entry(Bozo_Entries[4], 0.8, FALSE, 0.0, 0.0, 1.0, 0.0, 0.0);
  764.   Make_Blend_Map_Entry(Bozo_Entries[5], 0.8, FALSE, 1.0, 0.0, 0.0, 0.0, 0.0);
  765.   
  766.   Make_Blend_Map_Entry(Wood_Entries[0], 0.6, FALSE, 0.666, 0.312,  0.2,   0.0, 0.0);
  767.   Make_Blend_Map_Entry(Wood_Entries[1], 0.6, FALSE, 0.4,   0.1333, 0.066, 0.0, 0.0);
  768.   
  769.   Make_Blend_Map_Entry(Mandel_Entries[0], 0.001, FALSE, 0.0, 0.0, 0.0, 0.0, 0.0);
  770.   Make_Blend_Map_Entry(Mandel_Entries[1], 0.001, FALSE, 0.0, 1.0, 1.0, 0.0, 0.0);
  771.   Make_Blend_Map_Entry(Mandel_Entries[2], 0.012, FALSE, 1.0, 1.0, 0.0, 0.0, 0.0);
  772.   Make_Blend_Map_Entry(Mandel_Entries[3], 0.015, FALSE, 1.0, 0.0, 1.0, 0.0, 0.0);
  773.   Make_Blend_Map_Entry(Mandel_Entries[4], 0.1,   FALSE, 0.0, 1.0, 1.0, 0.0, 0.0);
  774.   
  775.   Make_Blend_Map_Entry(Agate_Entries[0], 0.0, FALSE, 1.0,  1.0,  1.0,  0.0, 0.0);
  776.   Make_Blend_Map_Entry(Agate_Entries[1], 0.5, FALSE, 0.95, 0.75, 0.5,  0.0, 0.0);
  777.   Make_Blend_Map_Entry(Agate_Entries[2], 0.5, FALSE, 0.9,  0.7,  0.5,  0.0, 0.0);
  778.   Make_Blend_Map_Entry(Agate_Entries[3], 0.6, FALSE, 0.9,  0.7,  0.4,  0.0, 0.0);
  779.   Make_Blend_Map_Entry(Agate_Entries[4], 0.6, FALSE, 1.0,  0.7,  0.4,  0.0, 0.0);
  780.   Make_Blend_Map_Entry(Agate_Entries[5], 1.0, FALSE, 0.6,  0.3,  0.0,  0.0, 0.0);
  781.   
  782.   Make_Blend_Map_Entry(Radial_Entries[0], 0.0,   FALSE, 0.0, 1.0, 1.0, 0.0, 0.0);
  783.   Make_Blend_Map_Entry(Radial_Entries[1], 0.333, FALSE, 1.0, 1.0, 0.0, 0.0, 0.0);
  784.   Make_Blend_Map_Entry(Radial_Entries[2], 0.666, FALSE, 1.0, 0.0, 1.0, 0.0, 0.0);
  785.   Make_Blend_Map_Entry(Radial_Entries[3], 1.0,   FALSE, 0.0, 1.0, 1.0, 0.0, 0.0);
  786.   
  787.   Make_Blend_Map_Entry(Marble_Entries[0], 0.0, FALSE, 0.9, 0.8, 0.8, 0.0, 0.0);
  788.   Make_Blend_Map_Entry(Marble_Entries[1], 0.9, FALSE, 0.9, 0.08, 0.08, 0.0, 0.0);
  789.   Make_Blend_Map_Entry(Marble_Entries[2], 0.9, FALSE, 0.0, 0.0, 0.0, 0.0, 0.0);
  790.   
  791.   Make_Blend_Map_Entry(Brick_Entries[0], 0.0, FALSE, 0.5, 0.5,  0.5,  0.0, 0.0);
  792.   Make_Blend_Map_Entry(Brick_Entries[1], 1.0, FALSE, 0.6, 0.15, 0.15, 0.0, 0.0);
  793.   
  794.   Make_Blend_Map_Entry(Hex_Entries[0], 0.0, FALSE, 0.0, 0.0, 1.0, 0.0, 0.0);
  795.   Make_Blend_Map_Entry(Hex_Entries[1], 1.0, FALSE, 0.0, 1.0, 0.0, 0.0, 0.0);
  796.   Make_Blend_Map_Entry(Hex_Entries[2], 2.0, FALSE, 1.0, 0.0, 0.0, 0.0, 0.0);
  797. }
  798.  
  799.  
  800.  
  801. #ifdef BlobPatternPatch
  802. /*Chris Huff-blob pattern*/
  803. static int blob_pigment(VECTOR TPoint, PIGMENT * Pigment, COLOUR Colour, INTERSECTION *Intersection)
  804. {
  805.     COLOUR totalCol;
  806.     DBL totalStrength = 0;
  807.     DBL threshold = Pigment->Vals.Blob.blob_threshold;
  808.     DBL max_density = Pigment->Vals.Blob.max_density;
  809.  
  810.     BLOB_PATTERN_DATA * currentComponent = Pigment->Vals.Blob.blob_dat;
  811.     if(currentComponent == NULL)
  812.         return 0;/*If the list of components is empty, don't do anything*/
  813.     totalCol[0] = 0;
  814.     totalCol[1] = 0;
  815.     totalCol[2] = 0;
  816.  
  817.  
  818.     while(currentComponent != NULL)
  819.     {
  820.         DBL temp = 0;
  821.         COLOUR tempColour;
  822.         if(currentComponent->type == 3)
  823.         {/*intercept "pigment" component, must be handled here*/
  824.             Compute_Pigment(tempColour, currentComponent->pigment, TPoint, Intersection);
  825.         if(currentComponent->inverse == TRUE)
  826.             temp = 1-(GREY_SCALE(tempColour));
  827.         else
  828.             temp = GREY_SCALE(tempColour);
  829.             temp *= currentComponent->strength*eval_density_func(temp, currentComponent->falloff, currentComponent->function);
  830.             totalStrength += temp;
  831.         }
  832.         else
  833.         {
  834.             temp = blob_comp_strength(TPoint, currentComponent);
  835.             totalStrength += temp;
  836.             Compute_Pigment(tempColour, currentComponent->pigment, TPoint, Intersection);
  837.         }
  838.         totalCol[0] += tempColour[0]*temp;
  839.         totalCol[1] += tempColour[1]*temp;
  840.         totalCol[2] += tempColour[2]*temp;
  841.         currentComponent = currentComponent->next;
  842.     }
  843.  
  844.     if(totalStrength < threshold) 
  845.         totalStrength = threshold;
  846.     if(totalStrength > max_density) 
  847.         totalStrength = max_density;
  848.  
  849.     totalCol[0] = totalCol[0]*(totalStrength - threshold)/(max_density-threshold);
  850.     totalCol[1] = totalCol[1]*(totalStrength - threshold)/(max_density-threshold);
  851.     totalCol[2] = totalCol[2]*(totalStrength - threshold)/(max_density-threshold);
  852.  
  853.     Colour[0] = totalCol[0];
  854.     Colour[1] = totalCol[1];
  855.     Colour[2] = totalCol[2];
  856.     return 1;
  857. }
  858.  
  859.  
  860. #endif