//----------------------------------------------------------------------------- // Fraktaly v pocitacove grafice // Autor: Pavel Tisnovsky // // Program urceny pro konverzi trojrozmerneho modelu systemu iterovanych funkci // ze souboru ve formatu SFL do zdrojoveho textu urceneho pro program POV-Ray. // // Pouziti programu: // fractals40_2 soubor.sfl soubor.pov // // kde: // fractals40_2 je jmeno spustitelneho souboru ziskaneho prekladem tohoto // zdrojoveho textu // soubor.sfl je jmeno souboru obsahujiciho popis 3D modelu systemu // iterovanych funkci // soubor.pov je jmeno souboru urceneho pro program POV-Ray, ktery ma byt // vytvoren //----------------------------------------------------------------------------- #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_LINE_LENGTH 80 typedef enum { file_type_unknown, file_type_position, file_type_position_size, } file_type_enum; typedef struct { float x; float y; float z; float size; } item; FILE *fin; FILE *fout; int item_no=0; item *items=NULL; file_type_enum file_type=file_type_unknown; // ---------------------------------------------------------------------------- // kontrola argumentu zadanych uzivatelem // ---------------------------------------------------------------------------- void check_arguments(int argc) { if (argc<=2) { puts("Neni zadano jmeno vstupniho a/nebo vystupniho souboru!\nPouziti: ifs2pov soubor.sfl soubor.pov"); exit(1); } } // ---------------------------------------------------------------------------- // pokus o otevreni vstupniho souboru // ---------------------------------------------------------------------------- FILE * open_input_file(const char *fin_name) { FILE *f; if (!(f=fopen(fin_name, "r"))) { printf("Nelze otevrit soubor %s\n", fin_name); exit(1); } return f; } // ---------------------------------------------------------------------------- // nacteni hlavicky souboru // ---------------------------------------------------------------------------- file_type_enum read_header_type(FILE *fin) { char input[MAX_LINE_LENGTH]; if (!fgets(input, MAX_LINE_LENGTH, fin)) { puts("Nelze precist hlavicku souboru"); fclose(fin); exit(1); } if (!strcmp(input, "pf\n")) { puts("Typ souboru: pozice bodu"); return file_type_position; } if (!strcmp(input, "pfsb\n")) { puts("Typ souboru: pozice bodu a velikost"); return file_type_position_size; } if (file_type==file_type_unknown) { puts("Neznamy typ souboru"); fclose(fin); exit(1); } return file_type_unknown; } // ---------------------------------------------------------------------------- // nacteni poctu prvku v souboru // ---------------------------------------------------------------------------- int read_header_items(FILE *fin) { char input[MAX_LINE_LENGTH]; int i; if (!fgets(input, MAX_LINE_LENGTH, fin)) { puts("Nelze precist hlavicku souboru"); fclose(fin); exit(1); } i=atoi(input); printf("Pocet prvku: %d\n", i); if (i<0 || i>100000) { puts("Nespravny pocet prvku"); fclose(fin); exit(1); } return i; } // ---------------------------------------------------------------------------- // alokace pameti pro vsechny prvky // ---------------------------------------------------------------------------- void alloc_memory(int item_no) { items=(item*)malloc(item_no*sizeof(item)); if (items==NULL) { puts("Chybna alokace pameti"); fclose(fin); exit(1); } } // ---------------------------------------------------------------------------- // nacteni prvku ze souboru // ---------------------------------------------------------------------------- void load_items(int item_no) { int i; char input[MAX_LINE_LENGTH]; float x, y, z; printf("Nacitani prvku ze souboru: "); for (i=0; i<item_no; i++) { if (!fgets(input, MAX_LINE_LENGTH, fin)) { puts("Nelze precist data ze souboru"); fclose(fin); exit(1); } sscanf(input, "%f %f %f", &x, &y, &z); items[i].x=x; items[i].y=y; items[i].z=z; } puts("OK"); } // ---------------------------------------------------------------------------- // zapis hlavicky POV souboru s nastavenim kamery, svetel, textur a "podlahy" // ---------------------------------------------------------------------------- void save_pov_header(const char *fout_name) { if (!(fout=fopen(fout_name, "w"))) { puts("Nelze otevrit vystupni soubor pro zapis"); fclose(fin); exit(1); } fputs("\n"\ "camera {\n"\ " location <125, 150, 200>\n"\ " look_at <0, -10, 0>\n"\ "}\n"\ "\n"\ "object { light_source { <300, 100, 350> color rgb <1.0, 1.0, 1.0> } }\n"\ "object { light_source { < 10, 200, -100> color rgb <1.0, 1.0, 1.0> } }\n"\ "\n"\ "#declare PVTXTEXT =\n"\ "texture {\n"\ " pigment {\n"\ " color rgbf <0.000, 0.500, 1.000, 0.000>\n"\ " turbulence <0.520, 0.600, 0.360>\n"\ " }\n"\ " normal {\n"\ " ripples 1.000\n"\ " octaves 8.400\n"\ " frequency 4.000\n"\ " }\n"\ " finish {\n"\ " phong 0.900\n"\ " reflection 0.0\n"\ " }\n"\ " scale 0.5\n"\ "}\n"\ "\n"\ "#declare OBJTEXT=\n"\ "texture {\n"\ " pigment {\n"\ " color rgb <1.0, 0.7, 0.7>\n"\ " }\n"\ " finish {\n"\ " diffuse 1.0\n"\ " ambient 0.5\n"\ " }\n"\ "}\n"\ "\n"\ "plane { y, -60\n"\ " texture {PVTXTEXT\n"\ " scale 300\n"\ " }\n"\ "}\n"\ "", fout); } // ---------------------------------------------------------------------------- // zapis informaci o bodech do sceny // ---------------------------------------------------------------------------- void save_pov_data(void) { int i; for (i=0; i<item_no; i++) fprintf(fout, "sphere { < %f, %f, %f>, 1 texture { OBJTEXT }}\n", items[i].x, items[i].y, items[i].z); fclose(fout); } // ---------------------------------------------------------------------------- // funkce zavolana po startu aplikace // ---------------------------------------------------------------------------- int main(int argc, char *argv[]) { check_arguments(argc); fin=open_input_file(argv[1]); file_type=read_header_type(fin); item_no=read_header_items(fin); alloc_memory(item_no); load_items(item_no); save_pov_header(argv[2]); save_pov_data(); fclose(fin); return 0; } // ---------------------------------------------------------------------------- // finito // ----------------------------------------------------------------------------