Simple test for asyncio.library.
[AROS-Contrib.git] / gfx / povray / parstxtr.c
blob0c812d79d28559190c9abef8d6e529646dc25b11
1 /****************************************************************************
2 * parstxtr.c
4 * This module parses textures and atmosphere effects.
6 * from Persistence of Vision(tm) Ray Tracer
7 * Copyright 1996,1999 Persistence of Vision Team
8 *---------------------------------------------------------------------------
9 * NOTICE: This source code file is provided so that users may experiment
10 * with enhancements to POV-Ray and to port the software to platforms other
11 * than those supported by the POV-Ray Team. There are strict rules under
12 * which you are permitted to use this file. The rules are in the file
13 * named POVLEGAL.DOC which should be distributed with this file.
14 * If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
15 * Team Coordinator by email to team-coord@povray.org or visit us on the web at
16 * http://www.povray.org. The latest version of POV-Ray may be found at this site.
18 * This program is based on the popular DKB raytracer version 2.12.
19 * DKBTrace was originally written by David K. Buck.
20 * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
22 * Modifications by Thomas Willhalm, March 1999, used with permission.
24 *****************************************************************************/
26 #include "frame.h"
27 #include "vector.h"
28 #include "povproto.h"
29 #include "parse.h"
30 #include "parstxtr.h"
31 #include "colour.h"
32 #include "express.h"
33 #include "gif.h"
34 #include "iff.h"
35 #include "image.h"
36 #include "matrices.h"
37 #include "media.h"
38 #include "normal.h"
39 #include "pigment.h"
40 #include "povray.h"
41 #include "pgm.h"
42 #include "ppm.h"
43 #include "targa.h"
44 #include "png_pov.h"
45 #include "texture.h"
46 #include "tokenize.h"
49 /*****************************************************************************
50 * Local preprocessor defines
51 ******************************************************************************/
53 #define ADD_TNORMAL if (Tnormal == NULL) {if ((Default_Texture->Tnormal) != NULL) \
54 Tnormal = Copy_Tnormal ((Default_Texture->Tnormal)); else Tnormal = Create_Tnormal ();\
55 Texture->Tnormal=Tnormal;};
57 /*****************************************************************************
58 * Local typedefs
59 ******************************************************************************/
63 /*****************************************************************************
64 * Local variables
65 ******************************************************************************/
67 TEXTURE *Default_Texture;
71 /*****************************************************************************
72 * Static functions
73 ******************************************************************************/
75 static void Parse_Bump_Map (TNORMAL *Tnormal);
76 static void Parse_Image_Map (PIGMENT *Pigment);
77 static void Parse_Pattern (TPATTERN *New, int TPat_Type);
78 static TEXTURE *Parse_Vers1_Texture (void);
79 static TEXTURE *Parse_Tiles (void);
80 static TEXTURE *Parse_Material_Map (void);
81 static void Parse_Texture_Transform (TEXTURE *Texture);
82 static TURB *Check_Turb (WARP **Warps_Ptr);
83 static void Parse_Warp (WARP **Warp_Ptr);
84 static void Check_BH_Parameters (BLACK_HOLE *bh);
85 static void Warn_Interior (char *s);
89 /*****************************************************************************
91 * FUNCTION
93 * INPUT
95 * OUTPUT
97 * RETURNS
99 * AUTHOR
101 * POV-Ray Team
103 * DESCRIPTION
105 * CHANGES
107 ******************************************************************************/
109 IMAGE *Parse_Image (int Legal)
111 IMAGE *Image;
112 VECTOR Local_Vector;
113 char *Name;
115 Image = Create_Image ();
117 Image->Image_Type = Legal;
119 if (Legal & GRAD_FILE)
121 EXPECT
122 CASE_VECTOR
123 Warn(1.5, "Old style orientation vector or map type not supported. Ignoring value.");
124 Parse_Vector (Local_Vector);
125 END_CASE
127 OTHERWISE
128 UNGET
129 EXIT
130 END_CASE
131 END_EXPECT
134 EXPECT
135 CASE (IFF_TOKEN)
136 Image->File_Type = IFF_FILE;
137 Name=Parse_String();
138 Read_Iff_Image (Image, Name);
139 POV_FREE(Name);
140 EXIT
141 END_CASE
143 CASE (GIF_TOKEN)
144 Image->File_Type = GIF_FILE;
145 Name=Parse_String();
146 Read_Gif_Image(Image, Name);
147 POV_FREE(Name);
148 EXIT
149 END_CASE
151 CASE (POT_TOKEN)
152 Image->File_Type = POT_FILE;
153 Name=Parse_String();
154 Read_Gif_Image(Image, Name);
155 POV_FREE(Name);
156 EXIT
157 END_CASE
159 CASE (SYS_TOKEN)
160 Image->File_Type = SYS_FILE;
161 Name=Parse_String();
162 READ_SYS_IMAGE(Image, Name);
163 POV_FREE(Name);
164 EXIT
165 END_CASE
167 CASE (TGA_TOKEN)
168 Image->File_Type = TGA_FILE;
169 Name=Parse_String();
170 Read_Targa_Image(Image, Name);
171 POV_FREE(Name);
172 EXIT
173 END_CASE
175 CASE (PNG_TOKEN)
176 Image->File_Type = PNG_FILE;
177 Name=Parse_String();
178 Read_Png_Image(Image, Name);
179 POV_FREE(Name);
180 EXIT
181 END_CASE
183 CASE (PGM_TOKEN)
184 Image->File_Type = PGM_FILE;
185 Name=Parse_String();
186 Read_PGM_Image(Image, Name);
187 POV_FREE(Name);
188 EXIT
189 END_CASE
191 CASE (PPM_TOKEN)
192 Image->File_Type = PPM_FILE;
193 Name=Parse_String();
194 Read_PPM_Image(Image, Name);
195 POV_FREE(Name);
196 EXIT
197 END_CASE
199 OTHERWISE
200 Parse_Error_Str ("map file spec");
201 END_CASE
202 END_EXPECT
204 if (!(Image->File_Type & Legal))
205 Error ("File type not supported here.");
206 return (Image);
211 /*****************************************************************************
213 * FUNCTION
215 * INPUT
217 * OUTPUT
219 * RETURNS
221 * AUTHOR
223 * POV-Ray Team
225 * DESCRIPTION
227 * CHANGES
229 ******************************************************************************/
231 static void Parse_Image_Map (PIGMENT *Pigment)
233 int reg;
234 IMAGE *Image;
236 Parse_Begin();
238 Image = Parse_Image (IMAGE_FILE);
239 Image->Use_Colour_Flag = TRUE;
241 EXPECT /* Look for image_attribs */
242 CASE (ONCE_TOKEN)
243 Image->Once_Flag=TRUE;
244 END_CASE
246 CASE (INTERPOLATE_TOKEN)
247 Image->Interpolation_Type = (int)Parse_Float();
248 END_CASE
250 CASE (MAP_TYPE_TOKEN)
251 Image->Map_Type = (int) Parse_Float ();
252 END_CASE
254 CASE (USE_COLOUR_TOKEN)
255 Image->Use_Colour_Flag = TRUE;
256 END_CASE
258 CASE (USE_INDEX_TOKEN)
259 Image->Use_Colour_Flag = FALSE;
260 END_CASE
262 CASE (ALPHA_TOKEN)
263 Warn(1.55, "Keyword ALPHA discontinued. Use FILTER instead.");
265 CASE (COLOUR_KEY_TOKEN)
266 switch(Token.Function_Id)
268 case FILTER_TOKEN:
269 EXPECT
270 CASE (ALL_TOKEN)
272 DBL filter;
273 filter = Parse_Float();
274 for (reg = 0 ; reg < Image->Colour_Map_Size ; reg++)
275 Image->Colour_Map[reg].Filter
276 = (unsigned short) (filter *255.0);
278 EXIT
279 END_CASE
281 OTHERWISE
282 UNGET
283 reg = (int)(Parse_Float() + 0.01);
284 if (Image->Colour_Map == NULL)
285 Not_With ("filter","non color-mapped image");
286 if ((reg < 0) || (reg >= Image->Colour_Map_Size))
287 Error ("FILTER color register value out of range.");
289 Parse_Comma();
290 Image->Colour_Map[reg].Filter
291 = (unsigned short) (255.0 * Parse_Float());
292 EXIT
293 END_CASE
295 END_EXPECT
296 Pigment->Flags |= HAS_FILTER;
297 break;
299 case TRANSMIT_TOKEN:
300 EXPECT
301 CASE (ALL_TOKEN)
303 DBL transmit;
304 transmit = Parse_Float();
305 for (reg = 0 ; reg < Image->Colour_Map_Size ; reg++)
306 Image->Colour_Map[reg].Transmit
307 = (unsigned short) (transmit *255.0);
309 EXIT
310 END_CASE
312 OTHERWISE
313 UNGET
314 reg = (int)(Parse_Float() + 0.01);
315 if (Image->Colour_Map == NULL)
316 Not_With ("transmit","non color-mapped image");
317 if ((reg < 0) || (reg >= Image->Colour_Map_Size))
318 Error ("TRANSMIT color register value out of range.");
320 Parse_Comma();
321 Image->Colour_Map[reg].Transmit
322 = (unsigned short) (255.0 * Parse_Float());
323 EXIT
324 END_CASE
326 END_EXPECT
327 Pigment->Flags |= HAS_FILTER;
328 break;
330 default:
331 UNGET
332 Parse_Error_Str ("filter or transmit");
333 break;
335 END_CASE
337 OTHERWISE
338 UNGET
339 EXIT
340 END_CASE
341 END_EXPECT
343 Pigment->Vals.Image=Image;
344 Parse_End();
349 /*****************************************************************************
351 * FUNCTION
353 * INPUT
355 * OUTPUT
357 * RETURNS
359 * AUTHOR
361 * POV-Ray Team
363 * DESCRIPTION
365 * CHANGES
367 ******************************************************************************/
369 static void Parse_Bump_Map (TNORMAL *Tnormal)
371 IMAGE *Image;
373 Parse_Begin();
375 Image = Parse_Image(IMAGE_FILE);
376 Image->Use_Colour_Flag = TRUE;
378 EXPECT
379 CASE (ONCE_TOKEN)
380 Image->Once_Flag=TRUE;
381 END_CASE
383 CASE (MAP_TYPE_TOKEN)
384 Image->Map_Type = (int) Parse_Float ();
385 END_CASE
387 CASE (INTERPOLATE_TOKEN)
388 Image->Interpolation_Type = (int)Parse_Float();
389 END_CASE
391 CASE (BUMP_SIZE_TOKEN)
392 Tnormal->Amount = Parse_Float ();
393 END_CASE
395 CASE (USE_COLOUR_TOKEN)
396 Image->Use_Colour_Flag = TRUE;
397 END_CASE
399 CASE (USE_INDEX_TOKEN)
400 Image->Use_Colour_Flag = FALSE;
401 END_CASE
403 OTHERWISE
404 UNGET
405 EXIT
406 END_CASE
407 END_EXPECT
409 Tnormal->Vals.Image=Image;
411 Parse_End();
416 /*****************************************************************************
418 * FUNCTION
420 * INPUT
422 * OUTPUT
424 * RETURNS
426 * AUTHOR
428 * POV-Ray Team
430 * DESCRIPTION
432 * CHANGES
434 ******************************************************************************/
436 void Parse_Pigment (PIGMENT **Pigment_Ptr)
438 EXPECT /* Look for [pigment_id] */
439 CASE (PIGMENT_ID_TOKEN)
440 Destroy_Pigment(*Pigment_Ptr);
441 *Pigment_Ptr = Copy_Pigment ((PIGMENT *) Token.Data);
442 EXIT
443 END_CASE
445 OTHERWISE
446 UNGET
447 EXIT
448 END_CASE
449 END_EXPECT /* End pigment_id */
451 Parse_Pattern((TPATTERN *)(*Pigment_Ptr),PIGMENT_TYPE);
453 if (Not_In_Default && ((*Pigment_Ptr)->Type == NO_PATTERN))
455 Warn(1.7, "Pigment type unspecified or not 1st item.");
461 /*****************************************************************************
463 * FUNCTION
465 * INPUT
467 * OUTPUT
469 * RETURNS
471 * AUTHOR
473 * POV-Ray Team
475 * DESCRIPTION
477 * CHANGES
479 ******************************************************************************/
481 static void Parse_Pattern (TPATTERN *New, int TPat_Type)
483 VECTOR Local_Vector;
484 COLOUR Local_Colour;
485 MATRIX Local_Matrix;
486 TRANSFORM Local_Trans;
487 TURB *Local_Turb;
488 unsigned short Old_Type=New->Type;
489 IMAGE *Old_Image = NULL;
490 DENSITY_FILE *Old_Density_File = NULL;
492 if (Old_Type==BITMAP_PATTERN)
494 Old_Image=New->Vals.Image;
497 if (Old_Type==DENSITY_FILE_PATTERN)
499 Old_Density_File=New->Vals.Density_File;
502 EXPECT
503 CASE (AGATE_TOKEN)
504 New->Type = AGATE_PATTERN;
505 Check_Turb(&(New->Warps));
506 New->Vals.Agate_Turb_Scale = 1.0;
507 EXIT
508 END_CASE
510 CASE (BOZO_TOKEN)
511 New->Type = BOZO_PATTERN;
512 EXIT
513 END_CASE
515 CASE (GRANITE_TOKEN)
516 New->Type = GRANITE_PATTERN;
517 EXIT
518 END_CASE
520 CASE (LEOPARD_TOKEN)
521 New->Type = LEOPARD_PATTERN;
522 EXIT
523 END_CASE
525 CASE (MARBLE_TOKEN)
526 New->Type = MARBLE_PATTERN;
527 New->Wave_Type = TRIANGLE_WAVE;
528 EXIT
529 END_CASE
531 CASE (MANDEL_TOKEN)
532 New->Type = MANDEL_PATTERN;
533 New->Vals.Iterations = (int)Parse_Float();
534 EXIT
535 END_CASE
537 CASE (ONION_TOKEN)
538 New->Type = ONION_PATTERN;
539 EXIT
540 END_CASE
542 CASE (SPIRAL1_TOKEN)
543 New->Type = SPIRAL1_PATTERN;
544 New->Vals.Arms = (short)Parse_Float ();
545 New->Wave_Type = TRIANGLE_WAVE;
546 EXIT
547 END_CASE
549 CASE (SPIRAL2_TOKEN)
550 New->Type = SPIRAL2_PATTERN;
551 New->Vals.Arms = (short)Parse_Float ();
552 New->Wave_Type = TRIANGLE_WAVE;
553 EXIT
554 END_CASE
556 CASE (SPOTTED_TOKEN)
557 New->Type = SPOTTED_PATTERN;
558 EXIT
559 END_CASE
561 CASE (WOOD_TOKEN)
562 New->Type = WOOD_PATTERN;
563 New->Wave_Type = TRIANGLE_WAVE;
564 EXIT
565 END_CASE
567 CASE (GRADIENT_TOKEN)
568 New->Type = GRADIENT_PATTERN;
569 Parse_Vector (New->Vals.Gradient);
570 EXIT
571 END_CASE
573 CASE (RADIAL_TOKEN)
574 New->Type = RADIAL_PATTERN;
575 EXIT
576 END_CASE
578 CASE (CRACKLE_TOKEN)
579 New->Type = CRACKLE_PATTERN;
580 EXIT
581 END_CASE
583 CASE_COLOUR
584 if ((TPat_Type != PIGMENT_TYPE) && (TPat_Type != DENSITY_TYPE))
586 Only_In("color","pigment or density");
588 New->Type = PLAIN_PATTERN;
589 Parse_Colour (((PIGMENT *)New)->Colour);
590 EXIT
591 END_CASE
593 CASE (CHECKER_TOKEN)
594 New->Type = CHECKER_PATTERN;
595 New->Frequency = 0.0;
596 Destroy_Blend_Map(New->Blend_Map);
597 New->Blend_Map = Parse_Blend_List(2,&Check_Default_Map,TPat_Type);
598 EXIT
599 END_CASE
601 CASE (BRICK_TOKEN)
602 if (New->Type!=BRICK_PATTERN)
604 Make_Vector(New->Vals.Brick.Size,8.0,3.0,4.5);
605 New->Vals.Brick.Mortar=0.5-Small_Tolerance*2.0;
606 New->Type = BRICK_PATTERN;
608 New->Frequency = 0.0;
609 Destroy_Blend_Map(New->Blend_Map);
610 New->Blend_Map = Parse_Blend_List(2,&Brick_Default_Map,TPat_Type);
611 EXIT
612 END_CASE
614 CASE (HEXAGON_TOKEN)
615 New->Type = HEXAGON_PATTERN;
616 New->Frequency = 0.0;
617 Destroy_Blend_Map(New->Blend_Map);
618 New->Blend_Map = Parse_Blend_List(3,&Hex_Default_Map,TPat_Type);
619 EXIT
620 END_CASE
622 CASE (IMAGE_MAP_TOKEN)
623 if (TPat_Type != PIGMENT_TYPE)
625 Only_In("image_map","pigment");
628 if (Old_Type==BITMAP_PATTERN)
630 Destroy_Image(Old_Image);
633 New->Type = BITMAP_PATTERN;
634 New->Frequency = 0.0;
635 Parse_Image_Map ((PIGMENT *)New);
636 EXIT
637 END_CASE
639 CASE (BUMP_MAP_TOKEN)
640 if (TPat_Type != NORMAL_TYPE)
642 Only_In("bump_map","normal");
645 if (Old_Type==BITMAP_PATTERN)
647 Destroy_Image(Old_Image);
650 New->Type = BITMAP_PATTERN;
651 New->Frequency = 0.0;
652 Parse_Bump_Map ((TNORMAL *)New);
653 EXIT
654 END_CASE
656 CASE (WAVES_TOKEN)
657 New->Type = WAVES_PATTERN;
658 EXIT
659 END_CASE
661 CASE (RIPPLES_TOKEN)
662 New->Type = RIPPLES_PATTERN;
663 EXIT
664 END_CASE
666 CASE (WRINKLES_TOKEN)
667 New->Type = WRINKLES_PATTERN;
668 EXIT
669 END_CASE
671 CASE (BUMPS_TOKEN)
672 New->Type = BUMPS_PATTERN;
673 EXIT
674 END_CASE
676 CASE (DENTS_TOKEN)
677 New->Type = DENTS_PATTERN;
678 EXIT
679 END_CASE
681 CASE (QUILTED_TOKEN)
682 New->Type = QUILTED_PATTERN;
683 New->Vals.Quilted.Control0 = 1.0;
684 New->Vals.Quilted.Control1 = 1.0;
685 New->Frequency = 0.0;
686 EXIT
687 END_CASE
689 CASE (AVERAGE_TOKEN)
690 New->Type = AVERAGE_PATTERN;
691 EXIT
692 END_CASE
694 CASE (PLANAR_TOKEN)
695 New->Type = PLANAR_PATTERN;
696 EXIT
697 END_CASE
699 CASE (BOXED_TOKEN)
700 New->Type = BOXED_PATTERN;
701 EXIT
702 END_CASE
704 CASE (SPHERICAL_TOKEN)
705 New->Type = SPHERICAL_PATTERN;
706 EXIT
707 END_CASE
709 CASE (CYLINDRICAL_TOKEN)
710 New->Type = CYLINDRICAL_PATTERN;
711 EXIT
712 END_CASE
714 CASE (DENSITY_FILE_TOKEN)
715 if (Old_Type==DENSITY_FILE_PATTERN)
717 Destroy_Density_File(Old_Density_File);
719 New->Type = DENSITY_FILE_PATTERN;
720 New->Vals.Density_File = Create_Density_File();
721 GET(DF3_TOKEN);
722 New->Vals.Density_File->Data->Name = Parse_String();
723 Read_Density_File(New->Vals.Density_File);
724 EXIT
725 END_CASE
727 OTHERWISE
728 UNGET
729 EXIT
730 END_CASE
731 END_EXPECT /* Concludes pattern_body */
733 if ((Old_Type==BITMAP_PATTERN) && (New->Type!=BITMAP_PATTERN))
735 Destroy_Image(Old_Image);
738 if ((Old_Type==DENSITY_FILE_PATTERN) && (New->Type!=DENSITY_FILE_PATTERN))
740 Destroy_Density_File(Old_Density_File);
743 if (TPat_Type == NORMAL_TYPE)
745 Parse_Comma();
746 ((TNORMAL *)New)->Amount = Allow_Float (((TNORMAL *)New)->Amount );
749 EXPECT /* Look for pattern_modifier */
750 CASE (TURBULENCE_TOKEN)
751 Local_Turb=Check_Turb(&(New->Warps));
752 Parse_Vector(Local_Turb->Turbulence);
753 END_CASE
755 CASE (COLOUR_MAP_TOKEN)
756 if ((TPat_Type != PIGMENT_TYPE) && (TPat_Type != DENSITY_TYPE))
758 Only_In("color_map","pigment");
760 if (New->Type == CHECKER_PATTERN ||
761 New->Type == BRICK_PATTERN ||
762 New->Type == HEXAGON_PATTERN ||
763 New->Type == PLAIN_PATTERN ||
764 New->Type == AVERAGE_PATTERN ||
765 New->Type == BITMAP_PATTERN)
767 Error("Cannot use color_map with this pattern type.");
769 Destroy_Blend_Map(New->Blend_Map);
770 New->Blend_Map = Parse_Colour_Map ();
771 END_CASE
773 CASE (PIGMENT_MAP_TOKEN)
774 if (TPat_Type != PIGMENT_TYPE)
776 Only_In("pigment_map","pigment");
778 if (New->Type == CHECKER_PATTERN ||
779 New->Type == BRICK_PATTERN ||
780 New->Type == HEXAGON_PATTERN ||
781 New->Type == PLAIN_PATTERN ||
782 New->Type == BITMAP_PATTERN)
783 Not_With ("pigment_map","this pigment type");
784 Destroy_Blend_Map(New->Blend_Map);
785 New->Blend_Map = Parse_Blend_Map (PIGMENT_TYPE,New->Type);
786 END_CASE
788 CASE (DENSITY_MAP_TOKEN)
789 if (TPat_Type != DENSITY_TYPE)
791 Only_In("density_map","density");
793 if (New->Type == CHECKER_PATTERN ||
794 New->Type == BRICK_PATTERN ||
795 New->Type == HEXAGON_PATTERN ||
796 New->Type == PLAIN_PATTERN ||
797 New->Type == BITMAP_PATTERN)
798 Not_With ("density_map","this density type");
799 Destroy_Blend_Map(New->Blend_Map);
800 New->Blend_Map = Parse_Blend_Map (DENSITY_TYPE,New->Type);
801 END_CASE
803 CASE (SLOPE_MAP_TOKEN)
804 if (TPat_Type != NORMAL_TYPE)
806 Only_In("slope_map","normal");
808 if (New->Type == CHECKER_PATTERN ||
809 New->Type == BRICK_PATTERN ||
810 New->Type == HEXAGON_PATTERN ||
811 New->Type == PLAIN_PATTERN ||
812 New->Type == AVERAGE_PATTERN ||
813 New->Type == BITMAP_PATTERN)
814 Not_With ("slope_map","this normal type");
815 Destroy_Blend_Map(New->Blend_Map);
816 New->Blend_Map = Parse_Blend_Map (SLOPE_TYPE,New->Type);
817 END_CASE
819 CASE (NORMAL_MAP_TOKEN)
820 if (TPat_Type != NORMAL_TYPE)
822 Only_In("normal_map","normal");
824 if (New->Type == CHECKER_PATTERN ||
825 New->Type == BRICK_PATTERN ||
826 New->Type == HEXAGON_PATTERN ||
827 New->Type == PLAIN_PATTERN ||
828 New->Type == BITMAP_PATTERN)
829 Not_With ("normal_map","this normal type");
830 Destroy_Blend_Map(New->Blend_Map);
831 New->Blend_Map = Parse_Blend_Map (NORMAL_TYPE,New->Type);
832 END_CASE
834 CASE (TEXTURE_MAP_TOKEN)
835 if (TPat_Type != TEXTURE_TYPE)
837 Only_In("texture_map","texture");
839 if (New->Type == CHECKER_PATTERN ||
840 New->Type == BRICK_PATTERN ||
841 New->Type == HEXAGON_PATTERN ||
842 New->Type == PLAIN_PATTERN ||
843 New->Type == BITMAP_PATTERN)
844 Not_With ("texture_map","this pattern type");
845 Destroy_Blend_Map(New->Blend_Map);
846 New->Blend_Map = Parse_Blend_Map (TEXTURE_TYPE,New->Type);
847 END_CASE
849 CASE (QUICK_COLOUR_TOKEN)
850 if (TPat_Type != PIGMENT_TYPE)
852 Only_In("quick_color","pigment");
854 Parse_Colour (Local_Colour);
855 if (opts.Quality_Flags & Q_QUICKC)
857 New->Type = PLAIN_PATTERN;
858 Assign_Colour(((PIGMENT *)New)->Colour,Local_Colour);
860 END_CASE
862 CASE (CONTROL0_TOKEN)
863 if (New->Type == QUILTED_PATTERN)
865 New->Vals.Quilted.Control0 = Parse_Float ();
867 else
869 Not_With ("control0","this normal");
871 END_CASE
873 CASE (CONTROL1_TOKEN)
874 if (New->Type == QUILTED_PATTERN)
876 New->Vals.Quilted.Control1 = Parse_Float ();
878 else
880 Not_With ("control1","this normal");
882 END_CASE
884 CASE (OCTAVES_TOKEN)
885 Local_Turb=Check_Turb(&(New->Warps));
886 Local_Turb->Octaves = (int)Parse_Float();
887 if(Local_Turb->Octaves < 1)
888 Local_Turb->Octaves = 1;
889 if(Local_Turb->Octaves > 10) /* Avoid DOMAIN errors */
890 Local_Turb->Octaves = 10;
891 END_CASE
893 CASE (OMEGA_TOKEN)
894 Local_Turb=Check_Turb(&(New->Warps));
895 Local_Turb->Omega = Parse_Float();
896 END_CASE
898 CASE (LAMBDA_TOKEN)
899 Local_Turb=Check_Turb(&(New->Warps));
900 Local_Turb->Lambda = Parse_Float();
901 END_CASE
903 CASE (FREQUENCY_TOKEN)
904 New->Frequency = Parse_Float();
905 END_CASE
907 CASE (RAMP_WAVE_TOKEN)
908 New->Wave_Type = RAMP_WAVE;
909 END_CASE
911 CASE (TRIANGLE_WAVE_TOKEN)
912 New->Wave_Type = TRIANGLE_WAVE;
913 END_CASE
915 CASE (SINE_WAVE_TOKEN)
916 New->Wave_Type = SINE_WAVE;
917 END_CASE
919 CASE (SCALLOP_WAVE_TOKEN)
920 New->Wave_Type = SCALLOP_WAVE;
921 END_CASE
923 CASE (CUBIC_WAVE_TOKEN)
924 New->Wave_Type = CUBIC_WAVE;
925 END_CASE
927 CASE (POLY_WAVE_TOKEN)
928 New->Wave_Type = POLY_WAVE;
929 New->Exponent = Allow_Float(New->Exponent);
930 END_CASE
932 CASE (PHASE_TOKEN)
933 New->Phase = Parse_Float();
934 END_CASE
936 CASE (BUMP_SIZE_TOKEN)
937 if (TPat_Type != NORMAL_TYPE)
938 Only_In ("bump_size","normal");
939 ((TNORMAL *)New)->Amount = Parse_Float ();
940 END_CASE
942 CASE (AGATE_TURB_TOKEN)
943 if (New->Type != AGATE_PATTERN)
944 Not_With ("agate_turb","non-agate");
945 New->Vals.Agate_Turb_Scale = Parse_Float();
946 Check_Turb(&(New->Warps)); /* agate needs Octaves, Lambda etc. */
947 END_CASE
949 CASE (BRICK_SIZE_TOKEN)
950 if (New->Type != BRICK_PATTERN)
951 Not_With ("brick_size","non-brick");
952 Parse_Vector(New->Vals.Brick.Size);
953 END_CASE
955 CASE (MORTAR_TOKEN)
956 if (New->Type != BRICK_PATTERN)
957 Not_With ("mortar","non-brick");
958 New->Vals.Brick.Mortar = Parse_Float()-Small_Tolerance*2.0;
959 END_CASE
961 CASE (INTERPOLATE_TOKEN)
962 if (New->Type != DENSITY_FILE_PATTERN)
963 Not_With ("interpolate","non-density_file");
964 New->Vals.Density_File->Interpolation = (int)Parse_Float();
965 END_CASE
967 CASE (WARP_TOKEN)
968 Parse_Warp(&(New->Warps));
969 END_CASE
971 CASE (TRANSLATE_TOKEN)
972 Parse_Vector (Local_Vector);
973 Translate_Tpattern (New, Local_Vector);
974 END_CASE
976 CASE (ROTATE_TOKEN)
977 Parse_Vector (Local_Vector);
978 Rotate_Tpattern (New, Local_Vector);
979 END_CASE
981 CASE (SCALE_TOKEN)
982 Parse_Scale_Vector (Local_Vector);
983 Scale_Tpattern (New, Local_Vector);
984 END_CASE
986 CASE (MATRIX_TOKEN)
987 Parse_Matrix(Local_Matrix);
988 Compute_Matrix_Transform(&Local_Trans, Local_Matrix);
989 Transform_Tpattern (New, &Local_Trans);
990 END_CASE
992 CASE (TRANSFORM_TOKEN)
993 GET(TRANSFORM_ID_TOKEN)
994 Transform_Tpattern (New, (TRANSFORM *)Token.Data);
995 END_CASE
997 OTHERWISE
998 UNGET
999 EXIT
1000 END_CASE
1001 END_EXPECT
1003 if ((New->Type==AVERAGE_PATTERN) && (New->Blend_Map==NULL))
1005 Error("Average must have map.");
1008 if ((TPat_Type==TEXTURE_TYPE) && (New->Type!=PLAIN_PATTERN) &&
1009 (New->Blend_Map==NULL))
1011 Error("Patterned texture must have texture_map.");
1017 /*****************************************************************************
1019 * FUNCTION
1021 * INPUT
1023 * OUTPUT
1025 * RETURNS
1027 * AUTHOR
1029 * POV-Ray Team
1031 * DESCRIPTION
1033 * CHANGES
1035 ******************************************************************************/
1037 void Parse_Tnormal (TNORMAL **Tnormal_Ptr)
1039 EXPECT /* Look for [tnormal_id] */
1040 CASE (TNORMAL_ID_TOKEN)
1041 Destroy_Tnormal(*Tnormal_Ptr);
1042 *Tnormal_Ptr = Copy_Tnormal ((TNORMAL *) Token.Data);
1043 EXIT
1044 END_CASE
1046 OTHERWISE
1047 UNGET
1048 EXIT
1049 END_CASE
1050 END_EXPECT /* End [tnormal_id] */
1052 if (*Tnormal_Ptr == NULL)
1053 { /* tw */
1054 if ((Default_Texture->Tnormal) != NULL)
1055 *Tnormal_Ptr = Copy_Tnormal ((Default_Texture->Tnormal));
1056 else
1057 *Tnormal_Ptr = Create_Tnormal ();
1058 } /* tw */
1060 Parse_Pattern((TPATTERN *)*Tnormal_Ptr,NORMAL_TYPE);
1065 /*****************************************************************************
1067 * FUNCTION
1069 * INPUT
1071 * OUTPUT
1073 * RETURNS
1075 * AUTHOR
1077 * POV-Ray Team
1079 * DESCRIPTION
1081 * CHANGES
1083 ******************************************************************************/
1085 void Parse_Finish (FINISH **Finish_Ptr)
1087 COLOUR Temp_Colour;
1088 FINISH *New;
1089 VECTOR Local_Vector;
1091 Parse_Begin ();
1093 EXPECT /* Look for zero or one finish_id */
1094 CASE (FINISH_ID_TOKEN)
1095 Destroy_Finish(*Finish_Ptr);
1096 *Finish_Ptr = Copy_Finish ((FINISH *) Token.Data);
1097 EXIT
1098 END_CASE
1100 OTHERWISE
1101 UNGET
1102 EXIT
1103 END_CASE
1104 END_EXPECT /* End finish_id */
1106 New = *Finish_Ptr;
1108 EXPECT /* Look for zero or more finish_body */
1109 CASE (AMBIENT_TOKEN)
1110 Parse_Colour(Temp_Colour);
1111 New->Ambient[RED] = Temp_Colour[RED];
1112 New->Ambient[GREEN] = Temp_Colour[GREEN];
1113 New->Ambient[BLUE] = Temp_Colour[BLUE];
1114 END_CASE
1116 CASE (BRILLIANCE_TOKEN)
1117 New->Brilliance = Parse_Float ();
1118 END_CASE
1120 CASE (DIFFUSE_TOKEN)
1121 New->Diffuse = Parse_Float ();
1122 END_CASE
1124 CASE (REFLECTION_TOKEN)
1125 Parse_Colour(Temp_Colour);
1126 New->Reflection[RED] = Temp_Colour[RED];
1127 New->Reflection[GREEN] = Temp_Colour[GREEN];
1128 New->Reflection[BLUE] = Temp_Colour[BLUE];
1129 END_CASE
1131 CASE (REFLECTION_EXPONENT_TOKEN)
1132 New->Reflect_Exp = 1.0 / Parse_Float ();
1133 END_CASE
1135 CASE (PHONG_TOKEN)
1136 New->Phong = Parse_Float ();
1137 END_CASE
1139 CASE (PHONG_SIZE_TOKEN)
1140 New->Phong_Size = Parse_Float ();
1141 END_CASE
1143 CASE (SPECULAR_TOKEN)
1144 New->Specular = Parse_Float ();
1145 END_CASE
1147 CASE (ROUGHNESS_TOKEN)
1148 New->Roughness = Parse_Float ();
1149 if (New->Roughness != 0.0)
1150 New->Roughness = 1.0/New->Roughness; /* CEY 12/92 */
1151 else
1152 Warn(0.0, "Zero roughness used.");
1153 END_CASE
1155 CASE (METALLIC_TOKEN)
1156 New->Metallic = 1.0;
1157 EXPECT
1158 CASE_FLOAT
1159 New->Metallic = Parse_Float();
1160 EXIT
1161 END_CASE
1163 OTHERWISE
1164 UNGET
1165 EXIT
1166 END_CASE
1167 END_EXPECT
1168 END_CASE
1170 CASE (CRAND_TOKEN)
1171 New->Crand = Parse_Float();
1172 END_CASE
1174 CASE (IRID_TOKEN) /* DMF */
1175 Parse_Begin();
1176 New->Irid = Parse_Float();
1178 EXPECT
1179 CASE (THICKNESS_TOKEN) /* DMF */
1180 New->Irid_Film_Thickness = Parse_Float();
1181 END_CASE
1183 CASE (TURBULENCE_TOKEN) /* DMF */
1184 Parse_Vector(Local_Vector);
1185 New->Irid_Turb = Local_Vector[X];
1186 END_CASE
1188 OTHERWISE
1189 UNGET
1190 EXIT
1191 END_CASE
1192 END_EXPECT
1193 Parse_End();
1194 END_CASE
1196 CASE (IOR_TOKEN)
1197 New->Temp_IOR = Parse_Float();
1198 Warn_Interior("Index of refraction value");
1199 END_CASE
1201 CASE (CAUSTICS_TOKEN)
1202 New->Temp_Caustics = Parse_Float();
1203 Warn_Interior("Caustics value");
1204 END_CASE
1206 CASE (REFRACTION_TOKEN)
1207 New->Temp_Refract = Parse_Float();
1208 Warn_Interior("Refraction value unnecessary to turn on refraction.\nTo attenuate, the fade_power and fade_distance keywords ");
1209 END_CASE
1211 OTHERWISE
1212 UNGET
1213 EXIT
1214 END_CASE
1216 END_EXPECT /* End of finish_body */
1218 EXPECT /* Look for finish_mods */
1220 /* CASE none implemented
1221 END_CASE */
1223 OTHERWISE
1224 UNGET
1225 EXIT
1226 END_CASE
1227 END_EXPECT /* End of finish_mods */
1229 Parse_End ();
1234 /*****************************************************************************
1236 * FUNCTION
1238 * INPUT
1240 * OUTPUT
1242 * RETURNS
1244 * AUTHOR
1246 * POV-Ray Team
1248 * DESCRIPTION
1250 * CHANGES
1252 ******************************************************************************/
1254 TEXTURE *Parse_Texture ()
1256 VECTOR Local_Vector;
1257 MATRIX Local_Matrix;
1258 TRANSFORM Local_Trans;
1259 TEXTURE *Texture;
1260 int Modified_Pnf;
1262 if (opts.Language_Version < 3.0)
1264 return(Parse_Vers1_Texture());
1267 Modified_Pnf = FALSE;
1269 EXPECT /* First allow a texture identifier */
1270 CASE (TEXTURE_ID_TOKEN)
1271 Texture = Copy_Textures((TEXTURE *) Token.Data);
1272 Modified_Pnf = TRUE;
1273 EXIT
1274 END_CASE
1276 OTHERWISE
1277 UNGET
1278 Texture = Copy_Textures (Default_Texture);
1279 EXIT
1280 END_CASE
1281 END_EXPECT
1283 /* If the texture identifer or the default texture was a PLAIN_PATTERN
1284 then allow its pigment, normal or finish to be overridden by
1285 pigment identifier, normal identifier and finish identifiers.
1286 This is a consession to backwards compatibility so that
1287 "texture{PIGMENT_IDENTIFIER}" etc. is legal even though it should
1288 be "texture{pigment{PIGMENT_IDENTIFIER}}"
1291 /* Look for [pnf_texture] */
1292 if (Texture->Type == PLAIN_PATTERN)
1294 EXPECT /* Look for [pnf_ids] */
1295 CASE (PIGMENT_ID_TOKEN)
1296 Warn_State(Token.Token_Id, PIGMENT_TOKEN);
1297 Destroy_Pigment(Texture->Pigment);
1298 Texture->Pigment = Copy_Pigment ((PIGMENT *) Token.Data);
1299 Modified_Pnf = TRUE;
1300 END_CASE
1302 CASE (TNORMAL_ID_TOKEN)
1303 Warn_State(Token.Token_Id, TNORMAL_TOKEN);
1304 Destroy_Tnormal(Texture->Tnormal);
1305 Texture->Tnormal = Copy_Tnormal ((TNORMAL *) Token.Data);
1306 Modified_Pnf = TRUE;
1307 END_CASE
1309 CASE (FINISH_ID_TOKEN)
1310 Warn_State(Token.Token_Id, FINISH_TOKEN);
1311 Destroy_Finish(Texture->Finish);
1312 Texture->Finish = Copy_Finish ((FINISH *) Token.Data);
1313 Modified_Pnf = TRUE;
1314 END_CASE
1316 OTHERWISE
1317 UNGET
1318 EXIT
1319 END_CASE
1320 END_EXPECT
1322 /* If the texture identifer or the default texture was a PLAIN_PATTERN
1323 then allow its pigment, normal or finish to be overridden by
1324 pigment, normal or finish statement. Also allow transformations.
1327 EXPECT /* Modify previous pnf */
1328 CASE (PIGMENT_TOKEN)
1329 Parse_Begin ();
1330 Parse_Pigment ( &(Texture->Pigment) );
1331 Parse_End ();
1332 Modified_Pnf = TRUE;
1333 END_CASE
1335 CASE (TNORMAL_TOKEN)
1336 Parse_Begin ();
1337 Parse_Tnormal ( &(Texture->Tnormal) );
1338 Parse_End ();
1339 Modified_Pnf = TRUE;
1340 END_CASE
1342 CASE (FINISH_TOKEN)
1343 Parse_Finish ( &(Texture->Finish) );
1344 Modified_Pnf = TRUE;
1345 END_CASE
1347 CASE (TRANSLATE_TOKEN)
1348 Parse_Vector (Local_Vector);
1349 Compute_Translation_Transform(&Local_Trans, Local_Vector);
1350 Transform_Textures (Texture, &Local_Trans);
1351 Modified_Pnf = TRUE;
1352 END_CASE
1354 CASE (ROTATE_TOKEN)
1355 Parse_Vector (Local_Vector);
1356 Compute_Rotation_Transform(&Local_Trans, Local_Vector);
1357 Transform_Textures (Texture, &Local_Trans);
1358 Modified_Pnf = TRUE;
1359 END_CASE
1361 CASE (SCALE_TOKEN)
1362 Parse_Scale_Vector (Local_Vector);
1363 Compute_Scaling_Transform(&Local_Trans, Local_Vector);
1364 Transform_Textures (Texture, &Local_Trans);
1365 Modified_Pnf = TRUE;
1366 END_CASE
1368 CASE (MATRIX_TOKEN)
1369 Parse_Matrix(Local_Matrix);
1370 Compute_Matrix_Transform(&Local_Trans, Local_Matrix);
1371 Transform_Textures (Texture, &Local_Trans);
1372 Modified_Pnf = TRUE;
1373 END_CASE
1375 CASE (TRANSFORM_TOKEN)
1376 GET(TRANSFORM_ID_TOKEN)
1377 Transform_Textures (Texture, (TRANSFORM *)Token.Data);
1378 Modified_Pnf = TRUE;
1379 END_CASE
1381 OTHERWISE
1382 UNGET
1383 EXIT
1384 END_CASE
1385 END_EXPECT
1387 else
1389 /* Here it is not a PLAIN_PATTERN texture and since default textures
1390 must be plain then this was a texture identifier that was a special
1391 texture. Allow transforms. The "if(!Modified_Pnf)..." below
1392 will always fail if we came here. So we return after the
1393 transforms. */
1394 Parse_Texture_Transform(Texture);
1397 /* If we've modified the default texture with a p,n, or f then this
1398 has to stay a PLAIN_PATTERN pnf texture. We won't allow
1399 a texture_map or pattern. Therefore quit now.
1402 if (!Modified_Pnf)
1404 /* At this point we've either got a texture statement that had
1405 no p, n or f. Nor any texture identifier. Its probably
1406 a patterned texture_map texture. It could be an empty
1407 statement such as "texture{}" */
1409 EXPECT
1410 CASE (TILES_TOKEN)
1411 Destroy_Textures (Texture);
1412 Texture = Parse_Tiles();
1413 Parse_Texture_Transform(Texture);
1414 EXIT
1415 END_CASE
1417 CASE (MATERIAL_MAP_TOKEN)
1418 Destroy_Textures (Texture);
1419 Texture = Parse_Material_Map ();
1420 Parse_Texture_Transform(Texture);
1421 EXIT
1422 END_CASE
1424 OTHERWISE
1425 UNGET;
1426 Destroy_Pigment(Texture->Pigment);
1427 Destroy_Tnormal(Texture->Tnormal);
1428 Destroy_Finish(Texture->Finish);
1429 Texture->Pigment = NULL;
1430 Texture->Tnormal = NULL;
1431 Texture->Finish = NULL;
1432 Parse_Pattern((TPATTERN *)Texture,TEXTURE_TYPE);
1433 /* if following is true, parsed "texture{}" so restore
1434 default texture.
1436 if (Texture->Type <= PLAIN_PATTERN)
1438 Destroy_Textures(Texture);
1439 Texture = Copy_Textures (Default_Texture);
1441 EXIT
1442 END_CASE
1443 END_EXPECT
1446 return (Texture);
1451 /*****************************************************************************
1453 * FUNCTION
1455 * INPUT
1457 * OUTPUT
1459 * RETURNS
1461 * AUTHOR
1463 * POV-Ray Team
1465 * DESCRIPTION
1467 * CHANGES
1469 ******************************************************************************/
1471 static TEXTURE *Parse_Tiles()
1473 TEXTURE *Texture, *Local_Texture;
1474 BLEND_MAP_ENTRY *Entry;
1476 Parse_Begin ();
1478 Texture = Create_Texture ();
1479 Destroy_Pigment(Texture->Pigment);
1480 Destroy_Tnormal(Texture->Tnormal);
1481 Destroy_Finish(Texture->Finish);
1482 Texture->Pigment = NULL;
1483 Texture->Tnormal = NULL;
1484 Texture->Finish = NULL;
1485 Texture->Type = CHECKER_PATTERN;
1487 Texture->Blend_Map = Create_Blend_Map();
1488 Texture->Blend_Map->Number_Of_Entries = 2;
1489 Texture->Blend_Map->Blend_Map_Entries = Entry = Create_BMap_Entries (2);
1490 Texture->Blend_Map->Type = TEXTURE_TYPE;
1491 Entry[0].Vals.Texture=NULL;
1492 Entry[0].value=0.0;
1493 Entry[0].Same=FALSE;
1494 Entry[1].Vals.Texture=NULL;
1495 Entry[1].value=1.0;
1496 Entry[1].Same=FALSE;
1498 /* Note first tile is 1, 2nd tile is 0 to keep compatible with old tiles */
1500 EXPECT
1501 CASE (TEXTURE_TOKEN)
1502 Parse_Begin ();
1503 Local_Texture = Parse_Texture ();
1504 Link_Textures(&(Entry[1].Vals.Texture),Local_Texture);
1505 Parse_End ();
1506 END_CASE
1508 OTHERWISE
1509 UNGET
1510 EXIT
1511 END_CASE
1512 END_EXPECT
1514 GET (TILE2_TOKEN);
1516 EXPECT
1517 CASE (TEXTURE_TOKEN)
1518 Parse_Begin ();
1519 Local_Texture = Parse_Texture ();
1520 Link_Textures(&(Entry[0].Vals.Texture),Local_Texture);
1521 Parse_End ();
1522 END_CASE
1524 OTHERWISE
1525 UNGET
1526 EXIT
1527 END_CASE
1528 END_EXPECT
1530 Parse_End ();
1532 return (Texture);
1537 /*****************************************************************************
1539 * FUNCTION
1541 * INPUT
1543 * OUTPUT
1545 * RETURNS
1547 * AUTHOR
1549 * POV-Ray Team
1551 * DESCRIPTION
1553 * CHANGES
1555 ******************************************************************************/
1557 static TEXTURE *Parse_Material_Map()
1559 TEXTURE *Texture, *Local_Texture;
1560 Parse_Begin ();
1562 Texture = Create_Texture ();
1563 Destroy_Pigment(Texture->Pigment);
1564 Destroy_Tnormal(Texture->Tnormal);
1565 Destroy_Finish(Texture->Finish);
1566 Texture->Pigment = NULL;
1567 Texture->Tnormal = NULL;
1568 Texture->Finish = NULL;
1569 Texture->Type = BITMAP_PATTERN;
1571 Texture->Vals.Image = Parse_Image(MATERIAL_FILE);
1572 Texture->Vals.Image->Use_Colour_Flag = FALSE;
1574 EXPECT
1575 CASE (ONCE_TOKEN)
1576 Texture->Vals.Image->Once_Flag=TRUE;
1577 END_CASE
1579 CASE (INTERPOLATE_TOKEN)
1580 Texture->Vals.Image->Interpolation_Type=(int)Parse_Float();
1581 END_CASE
1583 CASE (MAP_TYPE_TOKEN)
1584 Texture->Vals.Image->Map_Type = (int) Parse_Float ();
1585 END_CASE
1587 OTHERWISE
1588 UNGET
1589 EXIT
1590 END_CASE
1591 END_EXPECT
1593 GET (TEXTURE_TOKEN) /* First material */
1594 Parse_Begin();
1595 Texture->Materials = Local_Texture = Parse_Texture ();
1596 Parse_End();
1597 Texture->Num_Of_Mats++;
1599 EXPECT /* Subsequent materials */
1600 CASE (TEXTURE_TOKEN)
1601 Parse_Begin();
1602 Local_Texture->Next_Material = Parse_Texture ();
1603 Parse_End();
1604 Local_Texture = Local_Texture->Next_Material;
1605 Texture->Num_Of_Mats++;
1606 END_CASE
1608 OTHERWISE
1609 UNGET
1610 EXIT
1611 END_CASE
1612 END_EXPECT
1614 Parse_End ();
1616 return(Texture);
1621 /*****************************************************************************
1623 * FUNCTION
1625 * INPUT
1627 * OUTPUT
1629 * RETURNS
1631 * AUTHOR
1633 * POV-Ray Team
1635 * DESCRIPTION
1637 * CHANGES
1639 ******************************************************************************/
1641 static TEXTURE *Parse_Vers1_Texture ()
1643 VECTOR Local_Vector;
1644 COLOUR Local_Colour;
1645 MATRIX Local_Matrix;
1646 TRANSFORM Local_Trans;
1647 TURB *Local_Turb;
1648 TEXTURE *Texture;
1649 PIGMENT *Pigment;
1650 TNORMAL *Tnormal;
1651 FINISH *Finish;
1653 EXPECT /* Look for texture_body */
1654 CASE (TILES_TOKEN)
1655 Texture = Parse_Tiles();
1656 EXIT
1657 END_CASE
1659 CASE (MATERIAL_MAP_TOKEN)
1660 Texture = Parse_Material_Map ();
1661 EXIT
1662 END_CASE
1664 CASE (TEXTURE_ID_TOKEN)
1665 Texture = Copy_Textures((TEXTURE *) Token.Data);
1666 EXIT
1667 END_CASE
1669 OTHERWISE
1670 UNGET
1671 Texture = Copy_Textures (Default_Texture);
1672 EXIT
1673 END_CASE
1674 END_EXPECT
1676 /* Look for [pnf_texture] */
1677 if (Texture->Type == PLAIN_PATTERN)
1679 EXPECT /* Look for [pnf_ids] */
1680 CASE (PIGMENT_ID_TOKEN)
1681 Destroy_Pigment(Texture->Pigment);
1682 Texture->Pigment = Copy_Pigment ((PIGMENT *) Token.Data);
1683 END_CASE
1685 CASE (TNORMAL_ID_TOKEN)
1686 Destroy_Tnormal(Texture->Tnormal);
1687 Texture->Tnormal = Copy_Tnormal ((TNORMAL *) Token.Data);
1688 END_CASE
1690 CASE (FINISH_ID_TOKEN)
1691 Destroy_Finish(Texture->Finish);
1692 Texture->Finish = Copy_Finish ((FINISH *) Token.Data);
1693 END_CASE
1695 OTHERWISE
1696 UNGET
1697 EXIT
1698 END_CASE
1699 END_EXPECT
1701 Pigment = Texture->Pigment;
1702 Tnormal = Texture->Tnormal;
1703 Finish = Texture->Finish;
1705 EXPECT
1706 CASE (PIGMENT_TOKEN)
1707 Parse_Begin ();
1708 Parse_Pigment ( &(Texture->Pigment) );
1709 Parse_End ();
1710 END_CASE
1712 CASE (TNORMAL_TOKEN)
1713 Parse_Begin ();
1714 Parse_Tnormal ( &(Texture->Tnormal) );
1715 Parse_End ();
1716 END_CASE
1718 CASE (FINISH_TOKEN)
1719 Parse_Finish ( &(Texture->Finish) );
1720 END_CASE
1722 /***********************************************************************
1723 PIGMENT STUFF OUTSIDE PIGMENT{}
1724 NOTE: Do not add new keywords to this section. Use 1.0 syntax only.
1725 ***********************************************************************/
1726 CASE (AGATE_TOKEN)
1727 Warn_State(Token.Token_Id, PIGMENT_TOKEN);
1728 Pigment->Type = AGATE_PATTERN;
1729 Pigment->Vals.Agate_Turb_Scale = 1.0;
1730 Check_Turb(&(Pigment->Warps)); /* agate needs Octaves, Lambda etc. */
1731 END_CASE
1733 CASE (BOZO_TOKEN)
1734 Warn_State(Token.Token_Id, PIGMENT_TOKEN);
1735 Pigment->Type = BOZO_PATTERN;
1736 END_CASE
1738 CASE (GRANITE_TOKEN)
1739 Warn_State(Token.Token_Id, PIGMENT_TOKEN);
1740 Pigment->Type = GRANITE_PATTERN;
1741 END_CASE
1743 CASE (LEOPARD_TOKEN)
1744 Warn_State(Token.Token_Id, PIGMENT_TOKEN);
1745 Pigment->Type = LEOPARD_PATTERN;
1746 END_CASE
1748 CASE (MARBLE_TOKEN)
1749 Warn_State(Token.Token_Id, PIGMENT_TOKEN);
1750 Pigment->Type = MARBLE_PATTERN;
1751 END_CASE
1753 CASE (MANDEL_TOKEN)
1754 Warn_State(Token.Token_Id, PIGMENT_TOKEN);
1755 Pigment->Type = MANDEL_PATTERN;
1756 Pigment->Vals.Iterations = (int)Parse_Float();
1757 END_CASE
1759 CASE (ONION_TOKEN)
1760 Warn_State(Token.Token_Id, PIGMENT_TOKEN);
1761 Pigment->Type = ONION_PATTERN;
1762 END_CASE
1764 CASE (SPOTTED_TOKEN)
1765 Warn_State(Token.Token_Id, PIGMENT_TOKEN);
1766 Pigment->Type = SPOTTED_PATTERN;
1767 END_CASE
1769 CASE (WOOD_TOKEN)
1770 Warn_State(Token.Token_Id, PIGMENT_TOKEN);
1771 Pigment->Type = WOOD_PATTERN;
1772 END_CASE
1774 CASE (GRADIENT_TOKEN)
1775 Warn_State(Token.Token_Id, PIGMENT_TOKEN);
1776 Pigment->Type = GRADIENT_PATTERN;
1777 Parse_Vector (Pigment->Vals.Gradient);
1778 END_CASE
1780 CASE_COLOUR
1781 Warn_State(Token.Token_Id, PIGMENT_TOKEN);
1782 Pigment->Type = PLAIN_PATTERN;
1783 Parse_Colour (Pigment->Colour);
1784 END_CASE
1786 CASE (CHECKER_TOKEN)
1787 Warn_State(Token.Token_Id, PIGMENT_TOKEN);
1788 Pigment->Type = CHECKER_PATTERN;
1789 Pigment->Frequency = 0.0;
1790 Destroy_Blend_Map(Pigment->Blend_Map);
1791 Pigment->Blend_Map = Parse_Blend_List(2,&Check_Default_Map,COLOUR_TYPE);
1792 END_CASE
1794 CASE (HEXAGON_TOKEN)
1795 Warn_State(Token.Token_Id, PIGMENT_TOKEN);
1796 Pigment->Type = HEXAGON_PATTERN;
1797 Pigment->Frequency = 0.0;
1798 Destroy_Blend_Map(Pigment->Blend_Map);
1799 Pigment->Blend_Map = Parse_Blend_List(3,&Hex_Default_Map,COLOUR_TYPE);
1800 END_CASE
1802 CASE (IMAGE_MAP_TOKEN)
1803 Warn_State(Token.Token_Id, PIGMENT_TOKEN);
1804 Pigment->Type = BITMAP_PATTERN;
1805 Pigment->Frequency = 0.0;
1806 Parse_Image_Map (Pigment);
1807 END_CASE
1809 CASE (TURBULENCE_TOKEN)
1810 Local_Turb=Check_Turb(&(Pigment->Warps));
1811 Parse_Vector(Local_Turb->Turbulence);
1812 END_CASE
1814 CASE (COLOUR_MAP_TOKEN)
1815 Warn_State(Token.Token_Id, PIGMENT_TOKEN);
1816 if (Pigment->Type == CHECKER_PATTERN ||
1817 Pigment->Type == HEXAGON_PATTERN ||
1818 Pigment->Type == PLAIN_PATTERN ||
1819 Pigment->Type == BITMAP_PATTERN)
1820 Warn(1.5, "Cannot use color map with this pigment type.");
1821 Destroy_Blend_Map(Pigment->Blend_Map);
1822 Pigment->Blend_Map = Parse_Colour_Map ();
1823 END_CASE
1825 CASE (QUICK_COLOUR_TOKEN)
1826 Warn_State(Token.Token_Id, PIGMENT_TOKEN);
1827 Parse_Colour (Local_Colour);
1828 if (opts.Quality_Flags & Q_QUICKC)
1830 Assign_Colour(Pigment->Colour,Local_Colour);
1832 END_CASE
1834 CASE (OCTAVES_TOKEN)
1835 Local_Turb=Check_Turb(&(Pigment->Warps));
1836 Local_Turb->Octaves = (int)Parse_Float();
1837 if(Local_Turb->Octaves < 1)
1838 Local_Turb->Octaves = 1;
1839 if(Local_Turb->Octaves > 10) /* Avoid DOMAIN errors */
1840 Local_Turb->Octaves = 10;
1841 END_CASE
1843 CASE (OMEGA_TOKEN)
1844 Local_Turb=Check_Turb(&(Pigment->Warps));
1845 Local_Turb->Omega = Parse_Float();
1846 END_CASE
1848 CASE (LAMBDA_TOKEN)
1849 Local_Turb=Check_Turb(&(Pigment->Warps));
1850 Local_Turb->Lambda = Parse_Float();
1851 END_CASE
1853 /***********************************************************************
1854 TNORMAL STUFF OUTSIDE NORMAL{}
1855 NOTE: Do not add new keywords to this section. Use 1.0 syntax only.
1856 ***********************************************************************/
1857 CASE (BUMPS_TOKEN)
1858 Warn_State(Token.Token_Id, TNORMAL_TOKEN);
1859 ADD_TNORMAL
1860 Tnormal->Type = BUMPS_PATTERN;
1861 Tnormal->Amount = Parse_Float ();
1862 END_CASE
1864 CASE (DENTS_TOKEN)
1865 Warn_State(Token.Token_Id, TNORMAL_TOKEN);
1866 ADD_TNORMAL
1867 Tnormal->Type = DENTS_PATTERN;
1868 Tnormal->Amount = Parse_Float ();
1869 END_CASE
1871 CASE (RIPPLES_TOKEN)
1872 Warn_State(Token.Token_Id, TNORMAL_TOKEN);
1873 ADD_TNORMAL
1874 Tnormal->Type = RIPPLES_PATTERN;
1875 Tnormal->Amount = Parse_Float ();
1876 END_CASE
1878 CASE (WAVES_TOKEN)
1879 Warn_State(Token.Token_Id, TNORMAL_TOKEN);
1880 ADD_TNORMAL
1881 Tnormal->Type = WAVES_PATTERN;
1882 Tnormal->Amount = Parse_Float ();
1883 END_CASE
1885 CASE (WRINKLES_TOKEN)
1886 Warn_State(Token.Token_Id, TNORMAL_TOKEN);
1887 ADD_TNORMAL
1888 Tnormal->Type = WRINKLES_PATTERN;
1889 Tnormal->Amount = Parse_Float ();
1890 END_CASE
1892 CASE (BUMP_MAP_TOKEN)
1893 Warn_State(Token.Token_Id, TNORMAL_TOKEN);
1894 ADD_TNORMAL
1895 Tnormal->Type = BITMAP_PATTERN;
1896 Tnormal->Frequency = 0.0;
1897 Parse_Bump_Map (Tnormal);
1898 END_CASE
1900 CASE (FREQUENCY_TOKEN)
1901 Warn_State(Token.Token_Id, TNORMAL_TOKEN);
1902 ADD_TNORMAL
1903 if (!(Tnormal->Type == RIPPLES_PATTERN || Tnormal->Type == WAVES_PATTERN))
1904 if (opts.Language_Version >= 1.5)
1905 Warn(1.5, "Cannot use frequency with this normal.");
1906 Tnormal->Frequency = Parse_Float();
1907 END_CASE
1909 CASE (PHASE_TOKEN)
1910 Warn_State(Token.Token_Id, TNORMAL_TOKEN);
1911 ADD_TNORMAL
1912 if (!(Tnormal->Type == RIPPLES_PATTERN || Tnormal->Type == WAVES_PATTERN))
1913 if (opts.Language_Version >= 1.5)
1914 Warn(1.5, "Cannot use phase with this normal.");
1915 Tnormal->Phase = Parse_Float();
1916 END_CASE
1919 /***********************************************************************
1920 FINISH STUFF OUTSIDE FINISH{}
1921 NOTE: Do not add new keywords to this section. Use 1.0 syntax only.
1922 ***********************************************************************/
1923 CASE (AMBIENT_TOKEN)
1924 Warn_State(Token.Token_Id, FINISH_TOKEN);
1925 Finish->Ambient[RED] =
1926 Finish->Ambient[GREEN] =
1927 Finish->Ambient[BLUE] = Parse_Float ();
1928 END_CASE
1930 CASE (BRILLIANCE_TOKEN)
1931 Warn_State(Token.Token_Id, FINISH_TOKEN);
1932 Finish->Brilliance = Parse_Float ();
1933 END_CASE
1935 CASE (DIFFUSE_TOKEN)
1936 Warn_State(Token.Token_Id, FINISH_TOKEN);
1937 Finish->Diffuse = Parse_Float ();
1938 END_CASE
1940 CASE (REFLECTION_TOKEN)
1941 Warn_State(Token.Token_Id, FINISH_TOKEN);
1942 Finish->Reflection[RED] =
1943 Finish->Reflection[GREEN] =
1944 Finish->Reflection[BLUE] = Parse_Float ();
1945 END_CASE
1947 CASE (PHONG_TOKEN)
1948 Warn_State(Token.Token_Id, FINISH_TOKEN);
1949 Finish->Phong = Parse_Float ();
1950 END_CASE
1952 CASE (PHONG_SIZE_TOKEN)
1953 Warn_State(Token.Token_Id, FINISH_TOKEN);
1954 Finish->Phong_Size = Parse_Float ();
1955 END_CASE
1957 CASE (SPECULAR_TOKEN)
1958 Warn_State(Token.Token_Id, FINISH_TOKEN);
1959 Finish->Specular = Parse_Float ();
1960 END_CASE
1962 CASE (ROUGHNESS_TOKEN)
1963 Warn_State(Token.Token_Id, FINISH_TOKEN);
1964 Finish->Roughness = Parse_Float ();
1965 if (Finish->Roughness != 0.0)
1966 Finish->Roughness = 1.0/Finish->Roughness; /* CEY 12/92 */
1967 else
1968 Warn(0.0, "Zero roughness used.");
1969 END_CASE
1971 CASE (METALLIC_TOKEN)
1972 Warn_State(Token.Token_Id, FINISH_TOKEN);
1973 Finish->Metallic = 1.0;
1974 END_CASE
1976 CASE (CRAND_TOKEN)
1977 Warn_State(Token.Token_Id, FINISH_TOKEN);
1978 Finish->Crand = Parse_Float();
1979 END_CASE
1981 CASE_FLOAT
1982 Finish->Crand = Parse_Float();
1983 Warn(1.5, "Should use crand keyword in finish statement.");
1984 END_CASE
1986 CASE (IOR_TOKEN)
1987 Warn_State(Token.Token_Id, INTERIOR_TOKEN);
1988 Finish->Temp_IOR = Parse_Float();
1989 Warn_Interior("Index of refraction value");
1990 END_CASE
1992 CASE (REFRACTION_TOKEN)
1993 Warn_State(Token.Token_Id, INTERIOR_TOKEN);
1994 Finish->Temp_Refract = Parse_Float();
1995 Warn_Interior("Refraction value unnecessary to turn on refraction.\nTo attenuate, the fade_power and fade_distance keywords ");
1996 END_CASE
1998 CASE (TRANSLATE_TOKEN)
1999 Parse_Vector (Local_Vector);
2000 Compute_Translation_Transform(&Local_Trans, Local_Vector);
2001 Transform_Textures (Texture, &Local_Trans);
2002 END_CASE
2004 CASE (ROTATE_TOKEN)
2005 Parse_Vector (Local_Vector);
2006 Compute_Rotation_Transform(&Local_Trans, Local_Vector);
2007 Transform_Textures (Texture, &Local_Trans);
2008 END_CASE
2010 CASE (SCALE_TOKEN)
2011 Parse_Scale_Vector (Local_Vector);
2012 Compute_Scaling_Transform(&Local_Trans, Local_Vector);
2013 Transform_Textures (Texture, &Local_Trans);
2014 END_CASE
2016 CASE (MATRIX_TOKEN)
2017 Parse_Matrix(Local_Matrix);
2018 Compute_Matrix_Transform(&Local_Trans, Local_Matrix);
2019 Transform_Textures (Texture, &Local_Trans);
2020 END_CASE
2022 CASE (TRANSFORM_TOKEN)
2023 GET(TRANSFORM_ID_TOKEN)
2024 Transform_Textures (Texture, (TRANSFORM *)Token.Data);
2025 END_CASE
2027 CASE (TEXTURE_ID_TOKEN)
2028 Warn(0.0, "Texture identifier overwriting previous values.");
2029 Destroy_Textures(Texture);
2030 Texture = Copy_Textures((TEXTURE *) Token.Data);
2031 Pigment = Texture->Pigment;
2032 Tnormal = Texture->Tnormal;
2033 Finish = Texture->Finish;
2034 END_CASE
2036 OTHERWISE
2037 UNGET
2038 EXIT
2039 END_CASE
2041 /***********************************************************************/
2043 END_EXPECT
2045 if (Not_In_Default && (Texture->Pigment->Type == NO_PATTERN) &&
2046 !(opts.Language_Version < 1.5))
2047 Parse_Error(PIGMENT_ID_TOKEN);
2051 Parse_Texture_Transform(Texture);
2053 return (Texture);
2058 /*****************************************************************************
2060 * FUNCTION
2062 * INPUT
2064 * OUTPUT
2066 * RETURNS
2068 * AUTHOR
2070 * POV-Ray Team
2072 * DESCRIPTION
2074 * CHANGES
2076 ******************************************************************************/
2078 static void Parse_Texture_Transform (TEXTURE *Texture)
2080 VECTOR Local_Vector;
2081 MATRIX Local_Matrix;
2082 TRANSFORM Local_Trans;
2084 EXPECT
2085 CASE (TRANSLATE_TOKEN)
2086 Parse_Vector (Local_Vector);
2087 Compute_Translation_Transform(&Local_Trans, Local_Vector);
2088 Transform_Textures (Texture, &Local_Trans);
2089 END_CASE
2091 CASE (ROTATE_TOKEN)
2092 Parse_Vector (Local_Vector);
2093 Compute_Rotation_Transform(&Local_Trans, Local_Vector);
2094 Transform_Textures (Texture, &Local_Trans);
2095 END_CASE
2097 CASE (SCALE_TOKEN)
2098 Parse_Scale_Vector (Local_Vector);
2099 Compute_Scaling_Transform(&Local_Trans, Local_Vector);
2100 Transform_Textures (Texture, &Local_Trans);
2101 END_CASE
2103 CASE (MATRIX_TOKEN)
2104 Parse_Matrix(Local_Matrix);
2105 Compute_Matrix_Transform(&Local_Trans, Local_Matrix);
2106 Transform_Textures (Texture, &Local_Trans);
2107 END_CASE
2109 CASE (TRANSFORM_TOKEN)
2110 GET(TRANSFORM_ID_TOKEN)
2111 Transform_Textures (Texture, (TRANSFORM *)Token.Data);
2112 END_CASE
2114 OTHERWISE
2115 UNGET
2116 EXIT
2117 END_CASE
2118 END_EXPECT
2122 /*****************************************************************************
2124 * FUNCTION
2126 * Parse_Media
2128 * INPUT
2130 * OUTPUT
2132 * RETURNS
2134 * AUTHOR
2136 * Dieter Bayer
2138 * DESCRIPTION
2142 * CHANGES
2144 * Dec 1996 : Creation.
2146 ******************************************************************************/
2148 void Parse_Media(IMEDIA **Media_Ptr)
2150 IMEDIA *IMedia, *Next_Media;
2151 TRANSFORM Local_Trans;
2152 VECTOR Local_Vector;
2153 MATRIX Local_Matrix;
2155 Next_Media = *Media_Ptr;
2157 Parse_Begin();
2159 EXPECT
2160 CASE(MEDIA_ID_TOKEN)
2161 IMedia = Copy_Media((IMEDIA *)Token.Data);
2162 EXIT
2163 END_CASE
2165 OTHERWISE
2166 UNGET
2167 IMedia = Create_Media();
2168 EXIT
2169 END_CASE
2170 END_EXPECT
2172 EXPECT
2173 CASE (INTERVALS_TOKEN)
2174 if ((IMedia->Intervals = (int)Parse_Float()) < 1)
2176 Error("At least one interval is needed in media.\n");
2178 END_CASE
2180 CASE (SAMPLES_TOKEN)
2181 IMedia->Min_Samples = (int)Parse_Float();
2182 Parse_Comma();
2183 IMedia->Max_Samples = (int)Parse_Float();
2184 if (IMedia->Min_Samples < 1)
2186 Error("At least one sample per interval is needed in media.\n");
2188 if (IMedia->Max_Samples < IMedia->Min_Samples)
2190 Error("Maximum number of samples per interval smaller than minimum number.\n");
2192 END_CASE
2194 CASE (ABSORPTION_TOKEN)
2195 Parse_Colour(IMedia->Absorption);
2196 END_CASE
2198 CASE (EMISSION_TOKEN)
2199 Parse_Colour(IMedia->Emission);
2200 END_CASE
2202 CASE (SCATTERING_TOKEN)
2203 Parse_Begin();
2204 IMedia->Type = (int)Parse_Float();
2205 if ((IMedia->Type < 1) || (IMedia->Type > SCATTERING_TYPES))
2207 Warn(0.0, "Unknown atmospheric scattering type.");
2209 Parse_Comma();
2210 Parse_Colour(IMedia->Scattering);
2212 EXPECT
2213 CASE (ECCENTRICITY_TOKEN)
2214 if (IMedia->Type != HENYEY_GREENSTEIN_SCATTERING)
2216 Error("Eccentricity cannot be used with this scattering type.");
2218 IMedia->Eccentricity = Parse_Float();
2219 END_CASE
2221 CASE (EXTINCTION_TOKEN)
2222 IMedia->sc_ext = Parse_Float();
2223 END_CASE
2225 OTHERWISE
2226 UNGET
2227 EXIT
2228 END_CASE
2229 END_EXPECT
2231 Parse_End();
2232 END_CASE
2234 CASE (CONFIDENCE_TOKEN)
2235 IMedia->Confidence = Parse_Float();
2236 if ((IMedia->Confidence <= 0.0) || (IMedia->Confidence >= 1.0))
2238 Error("Illegal confidence value in media.\n");
2240 END_CASE
2242 CASE (VARIANCE_TOKEN)
2243 IMedia->Variance = Parse_Float();
2244 END_CASE
2246 CASE (RATIO_TOKEN)
2247 IMedia->Ratio = Parse_Float();
2248 END_CASE
2250 CASE (DENSITY_TOKEN)
2251 Parse_Begin();
2252 Parse_Media_Density_Pattern(&(IMedia->Density));
2253 Parse_End();
2254 END_CASE
2256 CASE (TRANSLATE_TOKEN)
2257 Parse_Vector (Local_Vector);
2258 Compute_Translation_Transform(&Local_Trans, Local_Vector);
2259 Transform_Density (IMedia->Density, &Local_Trans);
2260 END_CASE
2262 CASE (ROTATE_TOKEN)
2263 Parse_Vector (Local_Vector);
2264 Compute_Rotation_Transform(&Local_Trans, Local_Vector);
2265 Transform_Density (IMedia->Density, &Local_Trans);
2266 END_CASE
2268 CASE (SCALE_TOKEN)
2269 Parse_Scale_Vector (Local_Vector);
2270 Compute_Scaling_Transform(&Local_Trans, Local_Vector);
2271 Transform_Density (IMedia->Density, &Local_Trans);
2272 END_CASE
2274 CASE (MATRIX_TOKEN)
2275 Parse_Matrix(Local_Matrix);
2276 Compute_Matrix_Transform(&Local_Trans, Local_Matrix);
2277 Transform_Density (IMedia->Density, &Local_Trans);
2278 END_CASE
2280 CASE (TRANSFORM_TOKEN)
2281 GET(TRANSFORM_ID_TOKEN)
2282 Transform_Density (IMedia->Density, &Local_Trans);
2283 END_CASE
2285 OTHERWISE
2286 UNGET
2287 EXIT
2288 END_CASE
2289 END_EXPECT
2291 Parse_End();
2293 IMedia->Next_Media = Next_Media;
2295 *Media_Ptr = IMedia;
2300 /*****************************************************************************
2302 * FUNCTION
2304 * Parse_Interior
2306 * INPUT
2308 * OUTPUT
2310 * RETURNS
2312 * AUTHOR
2314 * Dieter Bayer
2316 * DESCRIPTION
2320 * CHANGES
2322 * Jan 1997 : Creation.
2324 ******************************************************************************/
2326 void Parse_Interior(INTERIOR **Interior_Ptr)
2328 INTERIOR *Interior;
2330 Parse_Begin();
2332 EXPECT
2333 CASE(INTERIOR_ID_TOKEN)
2334 Destroy_Interior(*Interior_Ptr);
2335 *Interior_Ptr = Copy_Interior((INTERIOR *)Token.Data);
2336 EXIT
2337 END_CASE
2339 OTHERWISE
2340 UNGET
2341 EXIT
2342 END_CASE
2343 END_EXPECT
2345 if(*Interior_Ptr == NULL)
2347 *Interior_Ptr = Create_Interior();
2350 Interior = *Interior_Ptr;
2352 EXPECT
2353 CASE (IOR_TOKEN)
2354 Interior->IOR = Parse_Float();
2355 END_CASE
2357 CASE (CAUSTICS_TOKEN)
2358 Interior->Caustics = Parse_Float() * 45.0;
2359 END_CASE
2361 CASE (FADE_DISTANCE_TOKEN)
2362 Interior->Fade_Distance = Parse_Float();
2363 END_CASE
2365 CASE (FADE_POWER_TOKEN)
2366 Interior->Fade_Power = Parse_Float();
2367 END_CASE
2369 CASE (MEDIA_TOKEN)
2370 Parse_Media((IMEDIA **)(&Interior->IMedia));
2371 END_CASE
2373 CASE (REFRACTION_TOKEN)
2374 Interior->Old_Refract = Parse_Float();
2375 Warn_Interior("Refraction value unnecessary to turn on refraction.\nTo attenuate, the fade_power and fade_distance keywords ");
2376 END_CASE
2378 OTHERWISE
2379 UNGET
2380 EXIT
2381 END_CASE
2382 END_EXPECT
2384 Parse_End();
2386 Init_Interior(Interior);
2391 /*****************************************************************************
2393 * FUNCTION
2395 * Parse_Media_Density_Pattern
2397 * INPUT
2399 * OUTPUT
2401 * RETURNS
2403 * AUTHOR
2405 * Dieter Bayer
2407 * DESCRIPTION
2411 * CHANGES
2413 * Dez 1996 : Creation.
2415 ******************************************************************************/
2417 void Parse_Media_Density_Pattern(PIGMENT **Density_Ptr)
2419 PIGMENT *New;
2421 EXPECT
2422 CASE (DENSITY_ID_TOKEN)
2423 New = Copy_Pigment ((PIGMENT *) Token.Data);
2424 EXIT
2425 END_CASE
2427 OTHERWISE
2428 New = Create_Pigment();
2429 UNGET
2430 EXIT
2431 END_CASE
2432 END_EXPECT
2434 Parse_Pattern((TPATTERN *)New,DENSITY_TYPE);
2436 New->Next = (TPATTERN *)(*Density_Ptr);
2437 *Density_Ptr = New;
2446 /*****************************************************************************
2448 * FUNCTION
2450 * INPUT
2452 * OUTPUT
2454 * RETURNS
2456 * AUTHOR
2458 * POV-Ray Team
2460 * DESCRIPTION
2462 * CHANGES
2464 ******************************************************************************/
2466 FOG *Parse_Fog()
2468 VECTOR Vector;
2469 MATRIX Matrix;
2470 TRANSFORM Trans;
2471 FOG *Fog;
2473 Parse_Begin();
2475 EXPECT
2476 CASE(FOG_ID_TOKEN)
2477 Fog = Copy_Fog ((FOG *) Token.Data);
2478 EXIT
2479 END_CASE
2481 OTHERWISE
2482 UNGET
2483 Fog = Create_Fog();
2484 EXIT
2485 END_CASE
2486 END_EXPECT
2488 EXPECT
2489 CASE_COLOUR
2490 Parse_Colour(Fog->Colour);
2491 END_CASE
2493 CASE (DISTANCE_TOKEN)
2494 Fog->Distance = Parse_Float();
2495 END_CASE
2497 CASE_FLOAT
2498 Warn(1.5, "Should use distance keyword.");
2499 Fog->Distance = Parse_Float();
2500 END_CASE
2502 CASE (FOG_TYPE_TOKEN)
2503 Fog->Type = (int)Parse_Float();
2504 if ((Fog->Type < ORIG_FOG) || (Fog->Type > FOG_TYPES))
2506 Warn(0.0, "Unknown fog type.");
2508 END_CASE
2510 CASE (FOG_ALT_TOKEN)
2511 Fog->Alt = Parse_Float();
2512 END_CASE
2514 CASE (FOG_OFFSET_TOKEN)
2515 Fog->Offset = Parse_Float();
2516 END_CASE
2518 CASE (TURB_DEPTH_TOKEN)
2519 Fog->Turb_Depth = Parse_Float();
2520 END_CASE
2522 CASE (UP_TOKEN)
2523 Parse_Vector(Fog->Up);
2524 END_CASE
2526 CASE (TURBULENCE_TOKEN)
2527 if (Fog->Turb == NULL)
2529 Fog->Turb=(TURB *)Create_Warp(CLASSIC_TURB_WARP);
2531 Parse_Vector(Fog->Turb->Turbulence);
2532 END_CASE
2534 CASE (OCTAVES_TOKEN)
2535 if (Fog->Turb == NULL)
2537 Fog->Turb=(TURB *)Create_Warp(CLASSIC_TURB_WARP);
2539 Fog->Turb->Octaves = (int)Parse_Float();
2540 if(Fog->Turb->Octaves < 1)
2541 Fog->Turb->Octaves = 1;
2542 if(Fog->Turb->Octaves > 10)
2543 Fog->Turb->Octaves = 10;
2544 END_CASE
2546 CASE (OMEGA_TOKEN)
2547 if (Fog->Turb == NULL)
2549 Fog->Turb=(TURB *)Create_Warp(CLASSIC_TURB_WARP);
2551 Fog->Turb->Omega = Parse_Float();
2552 END_CASE
2554 CASE (LAMBDA_TOKEN)
2555 if (Fog->Turb == NULL)
2557 Fog->Turb=(TURB *)Create_Warp(CLASSIC_TURB_WARP);
2559 Fog->Turb->Lambda = Parse_Float();
2560 END_CASE
2562 CASE (ROTATE_TOKEN)
2563 Parse_Vector(Vector);
2564 Compute_Rotation_Transform(&Trans, Vector);
2565 MTransDirection(Fog->Up, Fog->Up, &Trans);
2566 END_CASE
2568 CASE (SCALE_TOKEN)
2569 Parse_Vector(Vector);
2570 Compute_Scaling_Transform(&Trans, Vector);
2571 MTransDirection(Fog->Up, Fog->Up, &Trans);
2572 END_CASE
2574 CASE (TRANSLATE_TOKEN)
2575 Parse_Vector(Vector);
2576 Warn(0.0, "A fog's up vector can't be translated.");
2578 Compute_Translation_Transform(&Trans, Vector);
2579 MTransDirection(Fog->Up, Fog->Up, &Trans);
2581 END_CASE
2583 CASE (MATRIX_TOKEN)
2584 Parse_Matrix(Matrix);
2585 Compute_Matrix_Transform(&Trans, Matrix);
2586 MTransDirection(Fog->Up, Fog->Up, &Trans);
2587 END_CASE
2589 CASE (TRANSFORM_TOKEN)
2590 GET(TRANSFORM_ID_TOKEN)
2591 MTransDirection(Fog->Up, Fog->Up, (TRANSFORM *)Token.Data);
2592 END_CASE
2594 OTHERWISE
2595 UNGET
2596 EXIT
2597 END_CASE
2598 END_EXPECT
2600 Parse_End ();
2602 /* Make sure the up vector is normalized. */
2604 VNormalize(Fog->Up, Fog->Up);
2606 return(Fog);
2611 /*****************************************************************************
2613 * FUNCTION
2615 * Parse_Rainbow
2617 * INPUT
2619 * OUTPUT
2621 * RETURNS
2623 * AUTHOR
2625 * Dieter Bayer
2627 * DESCRIPTION
2631 * CHANGES
2633 * Jul 1994 : Creation.
2635 * Dec 1994 : Modified to work with multiple rainbows. [DB]
2637 * Apr 1995 : Added code for rainbow arcs. [DB]
2639 ******************************************************************************/
2641 RAINBOW *Parse_Rainbow()
2643 int Angle1, Angle2;
2644 DBL dot;
2645 RAINBOW *Rainbow;
2647 Angle1 = Angle2 = FALSE;
2649 Parse_Begin();
2651 EXPECT
2652 CASE(RAINBOW_ID_TOKEN)
2653 Rainbow = Copy_Rainbow ((RAINBOW *) Token.Data);
2654 EXIT
2655 END_CASE
2657 OTHERWISE
2658 UNGET
2659 Rainbow = Create_Rainbow();
2660 EXIT
2661 END_CASE
2662 END_EXPECT
2664 EXPECT
2665 CASE (ANGLE_TOKEN)
2666 Rainbow->Angle = Parse_Float();
2667 END_CASE
2669 CASE (DIRECTION_TOKEN)
2670 Parse_Vector(Rainbow->Antisolar_Vector);
2671 END_CASE
2673 CASE (COLOUR_MAP_TOKEN)
2674 Rainbow->Pigment = Create_Pigment();
2675 Rainbow->Pigment->Blend_Map = Parse_Colour_Map();
2676 Rainbow->Pigment->Type = GRADIENT_PATTERN;
2677 Make_Vector (Rainbow->Pigment->Vals.Gradient,1.0,0.0,0.0);
2678 END_CASE
2680 CASE (DISTANCE_TOKEN)
2681 Rainbow->Distance = Parse_Float();
2682 END_CASE
2684 CASE (JITTER_TOKEN)
2685 Rainbow->Jitter = Parse_Float();
2686 END_CASE
2688 CASE (WIDTH_TOKEN)
2689 Rainbow->Width = Parse_Float();
2690 END_CASE
2692 CASE (UP_TOKEN)
2693 Parse_Vector(Rainbow->Up_Vector);
2694 END_CASE
2696 CASE (FALLOFF_ANGLE_TOKEN)
2697 Angle1 = TRUE;
2698 Rainbow->Falloff_Angle = Parse_Float();
2699 if ((Rainbow->Falloff_Angle < 0.0) || (Rainbow->Falloff_Angle > 360.0))
2701 Error("Illegal falloff angle in rainbow (Use value from 0 to 360 degrees).\n");
2703 Rainbow->Falloff_Angle *= M_PI_360;
2704 END_CASE
2706 CASE (ARC_ANGLE_TOKEN)
2707 Angle2 = TRUE;
2708 Rainbow->Arc_Angle = Parse_Float();
2709 if ((Rainbow->Arc_Angle < 0.0) || (Rainbow->Arc_Angle > 360.0))
2711 Error("Illegal arc angle in rainbow (Use value from 0 to 360 degrees).\n");
2713 Rainbow->Arc_Angle *= M_PI_360;
2714 END_CASE
2716 OTHERWISE
2717 UNGET
2718 EXIT
2719 END_CASE
2720 END_EXPECT
2722 Parse_End();
2724 /* Setup falloff angle. */
2726 if (Angle2 && !Angle1)
2728 Rainbow->Falloff_Angle = Rainbow->Arc_Angle;
2731 /* Test if arc angle is greater or equal to falloff angle. */
2733 if (Rainbow->Arc_Angle < Rainbow->Falloff_Angle)
2735 Error("Arc angle is smaller than falloff angle in rainbow.\n");
2738 /* Get falloff region width.*/
2740 Rainbow->Falloff_Width = Rainbow->Arc_Angle - Rainbow->Falloff_Angle;
2742 /* Check for illegal vectors. */
2744 VDot(dot, Rainbow->Antisolar_Vector, Rainbow->Antisolar_Vector);
2746 if (fabs(dot) < EPSILON)
2748 Error("Rainbow's direction vector is zero.\n");
2751 VDot(dot, Rainbow->Up_Vector, Rainbow->Up_Vector);
2753 if (fabs(dot) < EPSILON)
2755 Error("Rainbow's up vector is zero.\n");
2758 VNormalizeEq(Rainbow->Antisolar_Vector);
2759 VNormalizeEq(Rainbow->Up_Vector);
2761 VDot(dot, Rainbow->Up_Vector, Rainbow->Antisolar_Vector);
2763 if (fabs(1.0 - fabs(dot)) < EPSILON)
2765 Error("Rainbow's up and direction vector are co-linear.\n");
2768 /* Make sure that up and antisolar vector are perpendicular. */
2770 VCross(Rainbow->Right_Vector, Rainbow->Up_Vector, Rainbow->Antisolar_Vector);
2772 VCross(Rainbow->Up_Vector, Rainbow->Antisolar_Vector, Rainbow->Right_Vector);
2774 VNormalizeEq(Rainbow->Up_Vector);
2775 VNormalizeEq(Rainbow->Right_Vector);
2777 /* Adjust rainbow angle and width. */
2779 Rainbow->Angle -= 0.5 * Rainbow->Width;
2781 Rainbow->Angle *= M_PI_180;
2782 Rainbow->Width *= M_PI_180;
2784 return(Rainbow);
2789 /*****************************************************************************
2791 * FUNCTION
2793 * Parse_Skysphere
2795 * INPUT
2797 * OUTPUT
2799 * RETURNS
2801 * AUTHOR
2803 * Dieter Bayer
2805 * DESCRIPTION
2809 * CHANGES
2811 * Jul 1994 : Creation.
2813 * Dec 1994 : Modified to work with multiple skyspheres. [DB]
2815 ******************************************************************************/
2817 SKYSPHERE *Parse_Skysphere()
2819 VECTOR Local_Vector;
2820 MATRIX Local_Matrix;
2821 TRANSFORM Local_Trans;
2822 SKYSPHERE *Skysphere;
2824 Parse_Begin();
2826 EXPECT
2827 CASE(SKYSPHERE_ID_TOKEN)
2828 Skysphere = Copy_Skysphere((SKYSPHERE *)Token.Data);
2829 EXIT
2830 END_CASE
2832 OTHERWISE
2833 UNGET
2834 Skysphere = Create_Skysphere();
2835 EXIT
2836 END_CASE
2837 END_EXPECT
2839 EXPECT
2840 CASE (PIGMENT_TOKEN)
2841 Skysphere->Count++;
2842 Skysphere->Pigments = (PIGMENT **)POV_REALLOC(Skysphere->Pigments, Skysphere->Count*sizeof(SKYSPHERE *), "sky-sphere pigment");
2843 Skysphere->Pigments[Skysphere->Count-1] = Create_Pigment();
2844 Parse_Begin();
2845 Parse_Pigment(&(Skysphere->Pigments[Skysphere->Count-1]));
2846 Parse_End();
2847 END_CASE
2849 CASE (TRANSLATE_TOKEN)
2850 Parse_Vector (Local_Vector);
2851 Translate_Skysphere(Skysphere, Local_Vector);
2852 END_CASE
2854 CASE (ROTATE_TOKEN)
2855 Parse_Vector (Local_Vector);
2856 Rotate_Skysphere(Skysphere, Local_Vector);
2857 END_CASE
2859 CASE (SCALE_TOKEN)
2860 Parse_Scale_Vector (Local_Vector);
2861 Scale_Skysphere(Skysphere, Local_Vector);
2862 END_CASE
2864 CASE (MATRIX_TOKEN)
2865 Parse_Matrix(Local_Matrix);
2866 Compute_Matrix_Transform(&Local_Trans, Local_Matrix);
2867 Transform_Skysphere(Skysphere, &Local_Trans);
2868 END_CASE
2870 CASE (TRANSFORM_TOKEN)
2871 GET(TRANSFORM_ID_TOKEN)
2872 Transform_Skysphere(Skysphere, (TRANSFORM *)Token.Data);
2873 END_CASE
2875 OTHERWISE
2876 UNGET
2877 EXIT
2878 END_CASE
2879 END_EXPECT
2881 Parse_End();
2883 if (Skysphere->Count==0)
2885 Error("Empty sky_sphere statement.");
2888 return(Skysphere);
2891 /*****************************************************************************
2893 * FUNCTION : Check_BH_Parameters
2895 * ARGUMENTS : bh - pointer to Black_Hole
2897 * AUTHOR : CJC [7/95]
2899 * DESCRIPTION : Applies sanity checks to the parameters of a black hole.
2901 * CHANGES
2903 ******************************************************************************/
2905 static void Check_BH_Parameters (BLACK_HOLE *bh)
2907 if (bh->Repeat == FALSE) return ;
2909 if (bh->Repeat_Vector [X] > 0.0)
2911 if (bh->Center [X] < bh->Radius)
2912 bh->Center [X] = bh->Radius ;
2913 if (bh->Repeat_Vector [X] < bh->Center [X] + bh->Radius + bh->Uncertainty_Vector [X])
2915 bh->Repeat_Vector [X] = bh->Center [X] + bh->Radius + bh->Uncertainty_Vector [X] ;
2916 Warning (0.0, "Black Hole repeat vector X too small ; increased to %g\n", bh->Repeat_Vector [X]) ;
2918 if (bh->Repeat_Vector [X] < Small_Tolerance)
2920 Warning (0.0,"Black Hole repeat vector X is less than %f ; ignored\n", (float) Small_Tolerance) ;
2921 bh->Repeat_Vector [X] = 0.0 ;
2925 if (bh->Repeat_Vector [Y] > 0.0)
2927 if (bh->Center [Y] < bh->Radius)
2928 bh->Center [Y] = bh->Radius ;
2929 if (bh->Repeat_Vector [Y] < bh->Center [Y] + bh->Radius + bh->Uncertainty_Vector [Y])
2931 bh->Repeat_Vector [Y] = bh->Center [Y] + bh->Radius + bh->Uncertainty_Vector [Y] ;
2932 Warning (0.0, "Black Hole repeat vector Y too small ; increased to %g\n", bh->Repeat_Vector [Y]) ;
2934 if (bh->Repeat_Vector [Y] < Small_Tolerance)
2936 Warning (0.0, "Black Hole repeat vector Y is less than %f ; ignored\n", (float) Small_Tolerance) ;
2937 bh->Repeat_Vector [Y] = 0.0 ;
2941 if (bh->Repeat_Vector [Z] > 0.0)
2943 if (bh->Center [Z] < bh->Radius)
2944 bh->Center [Z] = bh->Radius ;
2945 if (bh->Repeat_Vector [Z] < bh->Center [Z] + bh->Radius + bh->Uncertainty_Vector [Z])
2947 bh->Repeat_Vector [Z] = bh->Center [Z] + bh->Radius + bh->Uncertainty_Vector [Z] ;
2948 Warning (0.0, "Black Hole repeat vector Z too small ; increased to %g\n", bh->Repeat_Vector [Z]) ;
2950 if (bh->Repeat_Vector [Z] < Small_Tolerance)
2952 Warning (0.0, "Black Hole repeat vector Z is less than %f ; ignored\n", (float) Small_Tolerance) ;
2953 bh->Repeat_Vector [Z] = 0.0 ;
2958 /*****************************************************************************
2960 * FUNCTION
2962 * Check_Turb
2964 * INPUT
2966 * Warps_Ptr : Address where the root warp of a warp list
2967 * is stored.
2969 * OUTPUT
2971 * Warps_Ptr : If *Warps_Ptr is NULL, a classic turb warp
2972 * is created and a pointer to it is stored
2974 * RETURNS
2976 * A pointer to the last warp in the chain which is guarenteed
2977 * to be a classic turb.
2979 * AUTHOR
2981 * CEY [2/95]
2983 * DESCRIPTION : This routine is called when a classic outside-the-warp
2984 * turbulence parameter is parsed. One and only one classic turb may exist
2985 * in a warp chain. If there is one, it must be the last. This routine
2986 * traverses the warp chain and looks at the last link. If it is not a
2987 * classic turb then it adds one to the end and returns a pointer to it.
2988 * If the chain is empty, it creates a single link chain consisting of a
2989 * classic turb link. Future warp links get added ahead of the chain so
2990 * that any classic turb link is always last.
2992 * CHANGES
2994 ******************************************************************************/
2996 static TURB *Check_Turb (WARP **Warps_Ptr)
2998 WARP *Temp=*Warps_Ptr;
3000 if (Temp == NULL)
3002 *Warps_Ptr = Temp = Create_Warp(CLASSIC_TURB_WARP);
3004 else
3006 while (Temp->Next_Warp != NULL)
3008 Temp=Temp->Next_Warp;
3011 if (Temp->Warp_Type != CLASSIC_TURB_WARP)
3013 Temp->Next_Warp=Create_Warp(CLASSIC_TURB_WARP);
3014 Temp=Temp->Next_Warp;
3017 return((TURB *)Temp);
3022 /*****************************************************************************
3024 * FUNCTION
3026 * INPUT
3028 * OUTPUT
3030 * RETURNS
3032 * AUTHOR
3034 * POV-Ray Team
3036 * DESCRIPTION
3038 * CHANGES
3040 ******************************************************************************/
3042 static void Parse_Warp (WARP **Warp_Ptr)
3044 WARP *New = NULL;
3045 TURB *Turb;
3046 REPEAT *Repeat;
3047 BLACK_HOLE *Black_Hole;
3048 VECTOR Local_Vector;
3050 Parse_Begin();
3052 EXPECT
3053 CASE(TURBULENCE_TOKEN)
3054 New=Create_Warp(EXTRA_TURB_WARP);
3055 Turb=(TURB *)New;
3056 Parse_Vector(Turb->Turbulence);
3057 EXPECT
3058 CASE(OCTAVES_TOKEN)
3059 Turb->Octaves = (int)Parse_Float();
3060 if(Turb->Octaves < 1)
3061 Turb->Octaves = 1;
3062 if(Turb->Octaves > 10) /* Avoid DOMAIN errors */
3063 Turb->Octaves = 10;
3064 END_CASE
3066 CASE (OMEGA_TOKEN)
3067 Turb->Omega = Parse_Float();
3068 END_CASE
3070 CASE (LAMBDA_TOKEN)
3071 Turb->Lambda = Parse_Float();
3072 END_CASE
3074 OTHERWISE
3075 UNGET
3076 EXIT
3077 END_CASE
3078 END_EXPECT
3079 EXIT
3080 END_CASE
3082 CASE(REPEAT_TOKEN)
3083 New=Create_Warp(REPEAT_WARP);
3084 Repeat=(REPEAT *)New;
3085 Parse_Vector(Local_Vector);
3086 Repeat->Axis=-1;
3087 if (Local_Vector[X]!=0.0)
3088 Repeat->Axis=X;
3089 if (Local_Vector[Y]!=0.0)
3090 { /* tw */
3091 if (Repeat->Axis < X)
3092 Repeat->Axis=Y;
3093 else
3094 Error("Can only repeat along 1 axis.");
3095 } /* tw */
3096 if (Local_Vector[Z]!=0.0)
3097 { /* tw */
3098 if (Repeat->Axis < X)
3099 Repeat->Axis=Z;
3100 else
3101 Error("Can only repeat along 1 axis.");
3102 } /* tw */
3103 if (Repeat->Axis < X)
3104 Error("No axis specified in repeat.");
3105 Repeat->Width=Local_Vector[Repeat->Axis];
3107 EXPECT
3108 CASE(OFFSET_TOKEN)
3109 Parse_Vector(Repeat->Offset);
3110 END_CASE
3112 CASE(FLIP_TOKEN)
3113 Parse_Vector(Repeat->Flip);
3114 if (Repeat->Flip[X]!=0.0) Repeat->Flip[X]=-1.0; else Repeat->Flip[X]=1.0;
3115 if (Repeat->Flip[Y]!=0.0) Repeat->Flip[Y]=-1.0; else Repeat->Flip[Y]=1.0;
3116 if (Repeat->Flip[Z]!=0.0) Repeat->Flip[Z]=-1.0; else Repeat->Flip[Z]=1.0;
3117 END_CASE
3119 OTHERWISE
3120 UNGET
3121 EXIT
3122 END_CASE
3123 END_EXPECT
3124 EXIT
3125 END_CASE
3127 CASE(BLACK_HOLE_TOKEN)
3128 New = Create_Warp(BLACK_HOLE_WARP) ;
3129 Black_Hole = (BLACK_HOLE *) New ;
3130 Parse_Vector (Local_Vector) ;
3131 Assign_Vector (Black_Hole->Center, Local_Vector) ;
3132 Parse_Comma () ;
3133 Black_Hole->Radius = Parse_Float () ;
3134 Black_Hole->Radius_Squared = Black_Hole->Radius * Black_Hole->Radius ;
3135 Black_Hole->Inverse_Radius = 1.0 / Black_Hole->Radius;
3136 Black_Hole->Strength = 1.0 ;
3137 Black_Hole->Power = 2.0 ;
3138 Black_Hole->Inverted = FALSE ;
3139 Black_Hole->Type = 0 ;
3141 EXPECT
3142 CASE(STRENGTH_TOKEN)
3143 Black_Hole->Strength = Parse_Float () ;
3144 END_CASE
3146 CASE(FALLOFF_TOKEN)
3147 Black_Hole->Power = Parse_Float () ;
3148 END_CASE
3150 CASE(INVERSE_TOKEN)
3151 Black_Hole->Inverted = TRUE ;
3152 END_CASE
3154 CASE(TYPE_TOKEN)
3155 Black_Hole->Type = (int) Parse_Float () ;
3156 END_CASE
3158 CASE(REPEAT_TOKEN)
3159 Parse_Vector (Black_Hole->Repeat_Vector) ;
3160 Black_Hole->Repeat = TRUE ;
3161 Check_BH_Parameters (Black_Hole) ;
3162 END_CASE
3164 CASE(TURBULENCE_TOKEN)
3165 Parse_Vector (Black_Hole->Uncertainty_Vector) ;
3166 Black_Hole->Uncertain = TRUE ;
3167 Check_BH_Parameters (Black_Hole) ;
3168 END_CASE
3170 OTHERWISE
3171 UNGET
3172 EXIT
3173 END_CASE
3174 END_EXPECT
3175 EXIT
3176 END_CASE
3178 OTHERWISE
3179 Parse_Error_Str ("warp type");
3180 END_CASE
3181 END_EXPECT
3183 if (New==NULL)
3185 Error("Empty warp statement.");
3188 New->Next_Warp=*Warp_Ptr;
3189 *Warp_Ptr=New;
3191 Parse_End();
3195 static void Warn_Interior(char *s)
3197 Warn(0.0,s);
3198 Warning(0.0,"should be specified in 'interior{...}' statement.\n");
3199 Warn_Compat(0);
3202 void Parse_Material(MATERIAL *Material)
3204 MATERIAL *Temp;
3205 TEXTURE *Texture;
3206 VECTOR Local_Vector;
3207 MATRIX Local_Matrix;
3208 TRANSFORM Local_Trans;
3210 Parse_Begin();
3212 EXPECT
3213 CASE(MATERIAL_ID_TOKEN)
3214 Temp = (MATERIAL *)Token.Data;
3215 Texture = Copy_Textures(Temp->Texture);
3216 Link_Textures(&(Material->Texture),Texture);
3217 Destroy_Interior(Material->Interior);
3218 Material->Interior = Copy_Interior(Temp->Interior);
3219 EXIT
3220 END_CASE
3222 OTHERWISE
3223 UNGET
3224 EXIT
3225 END_CASE
3226 END_EXPECT
3228 EXPECT
3229 CASE (TEXTURE_TOKEN)
3230 Parse_Begin ();
3231 Texture = Parse_Texture ();
3232 Parse_End ();
3233 Link_Textures(&(Material->Texture),Texture);
3234 END_CASE
3236 CASE (INTERIOR_TOKEN)
3237 Parse_Interior((INTERIOR **)(&(Material->Interior)));
3238 END_CASE
3240 CASE (TRANSLATE_TOKEN)
3241 Parse_Vector (Local_Vector);
3242 Compute_Translation_Transform(&Local_Trans, Local_Vector);
3243 Transform_Textures (Material->Texture, &Local_Trans);
3244 Transform_Interior (Material->Interior,&Local_Trans);
3245 END_CASE
3247 CASE (ROTATE_TOKEN)
3248 Parse_Vector (Local_Vector);
3249 Compute_Rotation_Transform(&Local_Trans, Local_Vector);
3250 Transform_Textures (Material->Texture, &Local_Trans);
3251 Transform_Interior (Material->Interior,&Local_Trans);
3252 END_CASE
3254 CASE (SCALE_TOKEN)
3255 Parse_Scale_Vector (Local_Vector);
3256 Compute_Scaling_Transform(&Local_Trans, Local_Vector);
3257 Transform_Textures (Material->Texture, &Local_Trans);
3258 Transform_Interior (Material->Interior,&Local_Trans);
3259 END_CASE
3261 CASE (MATRIX_TOKEN)
3262 Parse_Matrix(Local_Matrix);
3263 Compute_Matrix_Transform(&Local_Trans, Local_Matrix);
3264 Transform_Textures (Material->Texture, &Local_Trans);
3265 Transform_Interior (Material->Interior,&Local_Trans);
3266 END_CASE
3268 CASE (TRANSFORM_TOKEN)
3269 GET(TRANSFORM_ID_TOKEN)
3270 Transform_Textures (Material->Texture, (TRANSFORM *)Token.Data);
3271 Transform_Interior (Material->Interior,(TRANSFORM *)Token.Data);
3272 END_CASE
3274 OTHERWISE
3275 UNGET
3276 EXIT
3277 END_CASE
3278 END_EXPECT
3280 Parse_End();