home *** CD-ROM | disk | FTP | other *** search
- /*-------------------------------------------------------------------------
-
- RAW to POV-Ray Converter
- Copyright (c) 1993 Steve Anger
-
- Reads a list of triangle coordinates in raw ASCII text format and
- outputs a POV-Ray compatable file. Automatically adds bounding shapes
- and produces smooth triangles. This file may be freely modified and
- distributed.
-
- CompuServe: 70714,3113
- Internet: 70714.3113@compuserve.com
- YCCMR BBS: (708)358-5611
-
- --------------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- /*#include <values.h> for MAXINT ? */
- #include <limits.h>
- #define MAXINT INT_MAX
- #include <ctype.h>
- #include "vect.h"
- #include "rayopt.h"
-
- #if defined(applec) || defined(THINK_C)
- #include "RAW2POV.mac.h"
- #else
- #define COOPERATE
- #endif
-
- #ifdef __TURBOC__
- extern unsigned _stklen = 16384;
- #endif
-
- #ifndef FALSE
- #define FALSE 0
- #define TRUE 1
- #endif
-
- #define OFF 0
- #define ON 1
- #define AUTO 2
-
- #define VERSION "v1.8"
- #define MAX_TEXTURE 500
-
- #define DEFAULT 0
- #define FRACTINT 1
- #define TEXTURE 2
-
- #define POV10 0
- #define POV20 1
- #define VIVID 2
- #define POLYRAY 3
-
- /* Function prototypes */
- static void process_args (int argc, char *argv[]);
- static void parse_option (char *option);
- static char *next_token (FILE *f);
- static int parse_input (FILE *f);
- static void make_camera (void);
- static void update_txtlist (char *new_texture);
- static void fswap (float *a, float *b);
- static char upcase (char c);
- static void write_light (FILE *f, Vector pos);
- static void write_camera (FILE *f, Vector pos, Vector target);
- static void write_texture (FILE *f, char *mat);
- static void write_intro (FILE *f);
-
-
- static char infile[64]; /* Name of input file */
- static char outfile[64]; /* Name of output file */
- static float smooth; /* Smooth triangles with angles < this value */
- static int bound; /* Type of bounding shape to use */
- static int verbose; /* Verbose status messages */
- static int one_object; /* Optimize file as a single object */
- static int swap_yz; /* Swap Y and Z coordinates */
- static int internal_bounding;/* Use internal bounding for POV-Ray */
- static int camera; /* Place a camera and light source in scene file */
- static int iformat; /* Input file format type */
- static int oformat; /* Output format */
- static long line_cnt; /* Line number */
-
- static float ax, ay, az;
- static float bx, by, bz;
- static float cx, cy, cz;
- static float red, green, blue;
- static char new_obj_name[80];
- static char new_texture[80];
-
- static char **txtlist;
- static int txtcnt = 0;
-
-
- int main (int argc, char *argv[])
- {
- FILE *f, *g;
- int obj_cnt, tri_cnt;
- int done, i;
- char obj_name[80] = "";
-
- txtlist = malloc((MAX_TEXTURE+1) * sizeof(char *));
- if (txtlist == NULL)
- abortmsg ("Out of memory", 1);
-
- process_args (argc, argv);
-
- f = fopen (infile, "r");
-
- if (f == NULL) {
- printf ("Error opening input file %s\n", infile);
- exit(1);
- }
-
- opt_set_format (oformat);
- opt_set_dec (4);
- opt_set_bound (bound);
- opt_set_smooth (smooth);
- opt_set_quiet (!verbose);
- opt_set_fname (outfile, "");
-
- /* Use the name of the file as default object name */
- strcpy (obj_name, infile);
- add_ext (obj_name, "", 1);
-
- line_cnt = 0;
- obj_cnt = 0;
- tri_cnt = 0;
- done = 0;
-
- printf ("Reading file...\n");
-
- g = fopen (outfile, "a");
- write_intro (g);
- fclose(g);
-
- while (!done) {
- COOPERATE /* support multitasking */
-
- switch (parse_input (f)) {
- /* End of file */
- case 0: done = 1;
- break;
-
- /* New triangle with RGB color */
- case 1: opt_set_color (red, green, blue);
- opt_add_tri (ax, ay, az, bx, by, bz, cx, cy, cz);
- ++tri_cnt;
- break;
-
- /* New triangle with named texture */
- case 2: update_txtlist (new_texture);
- opt_set_texture (new_texture);
- opt_add_tri (ax, ay, az, bx, by, bz, cx, cy, cz);
- ++tri_cnt;
- break;
-
- /* New object */
- case 3: if (!one_object) {
- if (tri_cnt > 0) {
- opt_write_file (obj_name);
- ++obj_cnt;
- }
-
- strcpy (obj_name, new_obj_name);
- printf ("Working on: %s\n", obj_name);
- }
- break;
- }
- }
-
- fclose (f);
-
- opt_write_pov (obj_name);
- ++obj_cnt;
-
- printf ("\n");
-
- g = fopen (outfile, "a");
-
- if (txtcnt > 0)
- fprintf (g, "\n/* Named textures, modify as needed */\n");
-
- for (i = 0; i < txtcnt; i++) {
- write_texture (g, txtlist[i]);
- free (txtlist[i]);
- }
-
- fclose(g);
-
- opt_finish();
-
- if (camera)
- make_camera();
-
- free(txtlist);
-
- return 0;
- }
-
-
- static void process_args (int argc, char *argv[])
- {
- int i;
- char *env_opt, *option;
-
- printf ("\n");
- printf ("RAW to POV-Ray (and others) Converter %s - Copyright (c) 1993 Steve Anger\n", VERSION);
- #if defined(__GNUC__) && defined(i386)
- printf ("32 bit version. DOS Extender Copyright (c) 1991 DJ Delorie\n");
- #endif
- printf ("This program is freely distributable\n");
- printf ("\n");
-
- if (argc < 2) {
- printf ("Usage: raw2pov inputfile[.raw] [outputfile[.pov]] [options]\n\n");
- printf ("Options: -snnn - Smooth triangles with angles < nnn\n");
- printf (" +v, -v - Turn verbose status messages on or off\n");
- printf (" +i, -i - Turn internal bounding on or off\n");
- printf (" -1 - Generate one object only\n");
- printf (" -x - Exchange the Y and Z coords\n");
- printf (" -c - Add camera and light source\n");
- printf (" -fc - Input file in fractint color format\n");
- printf (" -ft - Input file has textures specified\n");
- printf (" -op - Output to POV-Ray 2.0 format (default)\n");
- printf (" -op1 - Output to POV-Ray 1.0 format\n");
- printf (" -ov - Output to Vivid format\n");
- printf (" -ol - Output to poLyray format\n");
- printf ("\nex. raw2pov chess.raw chess.pov\n\n");
- exit(1);
- }
-
- infile[0] = '\0';
- outfile[0] = '\0';
- smooth = 70.0;
- bound = 0;
- verbose = 0;
- one_object = 0;
- swap_yz = 0;
- camera = 0;
- internal_bounding = AUTO;
- iformat = DEFAULT;
- oformat = POV20;
-
- /* Parse the enviroment string options */
- env_opt = getenv ("RAW2POV");
-
- if (env_opt != NULL) {
- option = strtok (env_opt, " ");
-
- while (option != NULL) {
- parse_option (option);
- option = strtok (NULL, " ");
- }
- }
-
- /* Parse the command line options */
- for (i = 1; i < argc; i++)
- parse_option (argv[i]);
-
- if (strlen(infile) == 0)
- abortmsg ("No input file specified", 1);
-
- if (strlen(outfile) == 0) {
- strcpy (outfile, infile);
-
- switch (oformat) {
- case POV10:
- case POV20: add_ext (outfile, "pov", 1); break;
- case VIVID: add_ext (outfile, "v", 1); break;
- case POLYRAY: add_ext (outfile, "pi", 1); break;
- }
- }
- else {
- switch (oformat) {
- case POV10:
- case POV20: add_ext (outfile, "pov", 0); break;
- case VIVID: add_ext (outfile, "v", 0); break;
- case POLYRAY: add_ext (outfile, "pi", 0); break;
- }
- }
-
- switch (internal_bounding) {
- case OFF: bound = 2; break;
- case ON: bound = 0; break;
- case AUTO: bound = (oformat == POV10) ? 0 : 2; break;
- }
- }
-
-
- static void parse_option (char *option)
- {
- if (option[0] == '-' || option[0] == '+') {
- switch (upcase(option[1])) {
- case 'C': camera = TRUE;
- break;
-
- case 'F': if (upcase(option[2]) == 'C')
- iformat = FRACTINT;
- else if (upcase(option[2]) == 'T')
- iformat = TEXTURE;
- break;
-
- case 'I': if (option[0] == '-')
- internal_bounding = OFF;
- else
- internal_bounding = ON;
- break;
-
- case 'O': switch (upcase (option[2])) {
- case 'P': if (option[3] == '1')
- oformat = POV10;
- else
- oformat = POV20;
- break;
-
- case 'V': oformat = VIVID;
- break;
-
- case 'L': oformat = POLYRAY;
- break;
- }
- break;
-
- case 'S': if (option[2] == '\0')
- smooth = 70.0;
- else
- sscanf (&option[2], "%f", &smooth);
- break;
-
- case 'U': printf ("Warning: -u parameter no long has any effect\n");
- printf (" use +i or -i instead.\n");
- break;
-
- case 'V': if (option[0] == '-')
- verbose = FALSE;
- else
- verbose = TRUE;
- break;
-
- case '1': one_object = TRUE;
- break;
-
- case 'X': swap_yz = TRUE;
- break;
-
- default : printf ("\nInvalid option -%c\n", option[1]);
- exit (1);
- }
- }
- else if (strlen(infile) == 0) {
- strcpy (infile, option);
- add_ext (infile, "raw", 0);
- }
- else if (strlen(outfile) == 0)
- strcpy (outfile, option);
- else
- abortmsg ("Too many file names specified.\n", 1);
- }
-
-
- static char *next_token (FILE *f)
- {
- static char token[128];
- int index, comment;
- char ch;
-
- index = 0;
- comment = 0;
-
- strcpy (token, "");
-
- /* Skip the white space */
- while (1) {
- ch = fgetc (f);
-
- if (feof(f))
- break;
-
- if (ch == '\n')
- ++line_cnt;
- else if (ch == '{')
- comment += 1;
- else if (ch == '}')
- comment = (comment > 0) ? (comment - 1) : 0;
- else if (!isspace(ch) && !comment)
- break;
- }
-
- if (feof(f))
- return token;
-
- ungetc (ch, f);
-
- while (1) {
- ch = fgetc (f);
-
- if (feof(f))
- break;
-
- if (ch == '\n')
- ++line_cnt;
-
- if (isspace(ch))
- break;
-
- if (index < 127)
- token[index++] = ch;
- }
-
- token[index] = '\0';
-
- return token;
- }
-
-
- static int parse_input (FILE *f)
- {
- int token_cnt, expected, result;
- char *token;
- char tokens[12][64];
-
- token_cnt = 0;
- expected = 0;
- result = -1;
-
- /* How many tokens to expect per triangle */
- switch (iformat) {
- case DEFAULT: expected = 9; break;
- case FRACTINT: expected = 12; break;
- case TEXTURE: expected = 10; break;
- }
-
- do {
- token = next_token (f);
-
- if (strlen(token) == 0)
- break;
-
- if (!isdigit(token[0]) && token[0] != '+' && token[0] != '-' && token[0] != '.') {
- if (token_cnt == 0) {
- strcpy (new_obj_name, token);
- cleanup_name (new_obj_name);
- return 3; /* New object name */
- }
- else if (token_cnt != 9 || expected != 10) {
- printf ("Error in input file, line %ld. Misplaced object name.\n", line_cnt);
- exit(1);
- }
- }
-
- strcpy (tokens[token_cnt++], token);
- } while (token_cnt < expected);
-
- if (token_cnt == 0)
- return 0; /* End of file */
-
- if (token_cnt != expected) {
- printf ("Error in input file, line %ld. Unexpected end of file.\n", line_cnt);
- exit(1);
- }
-
- switch (iformat) {
- case DEFAULT: /* Ax Ay Az Bx By Bz Cx Cy Cz */
- red = 1.0;
- green = 1.0;
- blue = 1.0;
- ax = atof(tokens[0]);
- ay = atof(tokens[1]);
- az = atof(tokens[2]);
- bx = atof(tokens[3]);
- by = atof(tokens[4]);
- bz = atof(tokens[5]);
- cx = atof(tokens[6]);
- cy = atof(tokens[7]);
- cz = atof(tokens[8]);
- result = 1;
- break;
-
- case FRACTINT: /* R G B Ax Ay Az Bx By Bz Cx Cy Cz */
- red = atof(tokens[0]);
- green = atof(tokens[1]);
- blue = atof(tokens[2]);
- ax = atof(tokens[3]);
- ay = atof(tokens[4]);
- az = atof(tokens[5]);
- bx = atof(tokens[6]);
- by = atof(tokens[7]);
- bz = atof(tokens[8]);
- cx = atof(tokens[9]);
- cy = atof(tokens[10]);
- cz = atof(tokens[11]);
- result = 1;
- break;
-
- case TEXTURE: /* Ax Ay Az Bx By Bz Cx Cy Cz Texture */
- ax = atof(tokens[0]);
- ay = atof(tokens[1]);
- az = atof(tokens[2]);
- bx = atof(tokens[3]);
- by = atof(tokens[4]);
- bz = atof(tokens[5]);
- cx = atof(tokens[6]);
- cy = atof(tokens[7]);
- cz = atof(tokens[8]);
- strcpy (new_texture, tokens[9]);
- cleanup_name (new_texture);
- result = 2;
- break;
- }
-
- if (swap_yz) {
- fswap (&ay, &az);
- fswap (&by, &bz);
- fswap (&cy, &cz);
- }
-
- return result;
- }
-
-
- static void make_camera()
- {
- Vector gmin, gmax, look;
- Vector size, scale, temp;
- float maxdim;
- FILE *f;
-
- f = fopen (outfile, "a");
-
- opt_get_glimits (&gmin[X], &gmin[Y], &gmin[Z], &gmax[X], &gmax[Y], &gmax[Z]);
-
- look[X] = (gmin[X] + gmax[X])/2.0;
- look[Y] = (gmin[Y] + gmax[Y])/2.0;
- look[Z] = (gmin[Z] + gmax[Z])/2.0;
-
- size[X] = gmax[X] - gmin[X];
- size[Y] = gmax[Y] - gmin[Y];
- size[Z] = gmax[Z] - gmin[Z];
-
- maxdim = -MAXINT;
-
- if (size[X] > maxdim) maxdim = size[X];
- if (size[Y] > maxdim) maxdim = size[Y];
- if (size[Z] > maxdim) maxdim = size[Z];
-
- if (oformat != POV10 && oformat != POV20)
- fswap (&size[Y], &size[Z]);
-
- if (size[X] > size[Z]) {
- scale[X] = 0.3;
- scale[Y] = 0.4;
- scale[Z] = -1.3;
- }
- else {
- scale[X] = 1.3;
- scale[Y] = 0.4;
- scale[Z] = 0.3;
- }
-
- if (oformat != POV10 && oformat != POV20)
- fswap (&scale[Y], &scale[Z]);
-
- fprintf (f, "\n");
-
- vect_scale (temp, scale, maxdim);
- vect_add (temp, temp, look);
- write_camera (f, temp, look);
-
- vect_scale (temp, scale, 4.0*maxdim);
- vect_add (temp, temp, look);
- write_light (f, temp);
-
- fclose(f);
- }
-
-
- static void update_txtlist (char *new_texture)
- {
- int i;
-
- for (i = 0; i < txtcnt; i++) {
- if (strcmp (new_texture, txtlist[i]) == 0)
- break;
- }
-
- if (i < txtcnt)
- return;
-
- if (i == MAX_TEXTURE)
- abortmsg ("Too many textures", 1);
-
- txtlist[i] = malloc (strlen (new_texture) + 1);
- strcpy (txtlist[i], new_texture);
-
- ++txtcnt;
- }
-
-
- static void fswap (float *a, float *b)
- {
- float temp;
-
- temp = *a;
- *a = *b;
- *b = temp;
- }
-
-
- /* Convert character 'c' top upper case */
- static char upcase (char c)
- {
- if (c >= 'a' && c <= 'z')
- c = c - 'a' + 'A';
-
- return c;
- }
-
-
- static void write_light (FILE *f, Vector pos)
- {
- switch (oformat) {
- case POV10:
- fprintf (f, "object {\n");
- fprintf (f, " light_source { <%.4f %.4f %.4f> color White }\n",
- pos[X], pos[Y], pos[Z]);
- fprintf (f, "}\n\n");
- break;
-
- case POV20:
- fprintf (f, "light_source {\n");
- fprintf (f, " <%.4f, %.4f, %.4f> color White\n",
- pos[X], pos[Y], pos[Z]);
- fprintf (f, "}\n\n");
- break;
-
- case VIVID:
- fprintf (f, "light {\n");
- fprintf (f, " type point\n");
- fprintf (f, " position %.4f %.4f %.4f\n",
- pos[X], pos[Y], pos[Z]);
- fprintf (f, " color white\n");
- fprintf (f, "}\n\n");
- break;
-
- case POLYRAY:
- fprintf (f, "light white, <%.4f, %.4f, %.4f>\n\n",
- pos[X], pos[Y], pos[Z]);
- break;
- }
- }
-
-
- static void write_camera (FILE *f, Vector pos, Vector target)
- {
- switch (oformat) {
- case POV10:
- fprintf (f, "camera {\n");
- fprintf (f, " location <%.4f %.4f %.4f>\n",
- pos[X], pos[Y], pos[Z]);
- fprintf (f, " look_at <%.4f %.4f %.4f>\n",
- target[X], target[Y], target[Z]);
- fprintf (f, "}\n\n");
- break;
-
- case POV20:
- fprintf (f, "camera {\n");
- fprintf (f, " location <%.4f, %.4f, %.4f>\n",
- pos[X], pos[Y], pos[Z]);
- fprintf (f, " look_at <%.4f, %.4f, %.4f>\n",
- target[X], target[Y], target[Z]);
- fprintf (f, "}\n\n");
- break;
-
- case VIVID:
- fprintf (f, "studio {\n");
- fprintf (f, " from %.4f %.4f %.4f\n",
- pos[X], pos[Y], pos[Z]);
- fprintf (f, " at %.4f %.4f %.4f\n",
- target[X], target[Y], target[Z]);
- fprintf (f, " up 0 0 1\n");
- fprintf (f, " angle 60.0\n");
- fprintf (f, " aspect 4/3\n");
- fprintf (f, " resolution 320 200\n");
- fprintf (f, " antialias none\n");
- fprintf (f, "}\n\n");
- break;
-
- case POLYRAY:
- fprintf (f, "viewpoint {\n");
- fprintf (f, " from <%.4f, %.4f, %.4f>\n",
- pos[X], pos[Y], pos[Z]);
- fprintf (f, " at <%.4f, %.4f, %.4f>\n",
- target[X], target[Y], target[Z]);
- fprintf (f, " up <0, 0, 1>\n");
- fprintf (f, " angle 60.0\n");
- fprintf (f, " aspect -4/3\n");
- fprintf (f, " resolution 320, 200\n");
- fprintf (f, "}\n\n");
- break;
- }
- }
-
-
- static void write_texture (FILE *f, char *mat)
- {
- switch (oformat) {
- case POV10:
- fprintf (f, "#declare %s = texture {\n", mat);
- fprintf (f, " Shiny\n");
- fprintf (f, " color White\n");
- fprintf (f, "}\n\n");
- break;
-
- case POV20:
- fprintf (f, "#declare %s = texture {\n", mat);
- fprintf (f, " finish { Shiny }\n");
- fprintf (f, " pigment { White }\n");
- fprintf (f, "}\n\n");
- break;
-
- case VIVID:
- fprintf (f, "#define %s \\ \n", mat);
- fprintf (f, " surface { \\ \n");
- fprintf (f, " ambient 0.1*white \\ \n");
- fprintf (f, " diffuse 0.8*white \\ \n");
- fprintf (f, " shine 70, white \\ \n");
- fprintf (f, " }\n\n");
- break;
-
- case POLYRAY:
- fprintf (f, "define %s\n", mat);
- fprintf (f, "texture {\n");
- fprintf (f, " surface {\n");
- fprintf (f, " ambient white, 0.1\n");
- fprintf (f, " diffuse white, 0.8\n");
- fprintf (f, " microfacet Reitz 20\n");
- fprintf (f, " }\n");
- fprintf (f, "}\n\n");
- break;
- }
- }
-
-
-
- static void write_intro (FILE *f)
- {
- switch (oformat) {
- case POV10:
- case POV20:
- fprintf (f, "#include \"colors.inc\"\n");
- fprintf (f, "#include \"shapes.inc\"\n");
- fprintf (f, "#include \"textures.inc\"\n");
- fprintf (f, "\n");
- break;
-
- case VIVID:
- fprintf (f, "#include color.vc\n");
- fprintf (f, "\n");
- break;
-
- case POLYRAY:
- fprintf (f, "include \"colors.inc\"\n");
- fprintf (f, "\n");
- break;
- }
- }
-
-