//-----------------------------------------------------------------------------
// 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
// ----------------------------------------------------------------------------