#define PROG_NAME "radioso" #define PROG_DESC "image synthesis with radiosity using various approx bases" #define PROG_VERS "1.0" #define PROG_C_COPYRIGHT "Copyright © 2008 Danillo Pereira and J. Stolfi, UNICAMP" /* Last edited on 2024-12-21 11:52:00 by stolfi */ /* !!! Introduzir a esfera celestial como um objeto no infinito. !!! */ /* !!! sites nesse objeto só tem normal (apontando para a origem) !!! */ /* !!! a distância a esses sites só depende da normal. !!! */ /* INCLUDES */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* ---------------------------------------------------------------------- */ /* TYPES */ typedef struct main_options_t dist_type_t distType; /* Type of distance function to use. */ sampling_options_t *opSmp; /* Other parameters for choosing the sampling sites. */ basis_elem_type_t basisType; /* Type of approx basis element to use. */ approx_basis_options_t *opBas; /* Other parameters for choosing the approx basis. */ int channels; /* Number of channels in the output image (usually 1 or 3). */ i2_t imageSize; /* Image dimensions (in pixels). */ synthesis_options_t *opSyn; /* Other parameters for image synthesis. */ char *outDir; /* Directory where to place output files. */ } main_options_t; /* Command line parameters. */ /* ---------------------------------------------------------------------- */ /* DEFINES AND PROTOTYPES */ #define MAX_IMAGE_SIZE (16*1024) /* Maximum dimension of the image along any axis (to avoid gargantual allocs). */ int main(int argc,char** argv); /* The fun starts here. */ main_options_t *rdo_main_options_parse(int argc, char **argv); /* Parses the command line options and packs them into a {main_options_t}. */ #define main_options_HELP \ " -solids {SOLIDS_FNAME} \\\n" \ " [ -sites {SITES_FNAME} ] \\\n" \ " [ -transferMatrix {TRANSFER_MATRIX_FNAME} ] \\\n" \ " [ -approxBasis {BASIS_FNAME} ] \\\n" \ " [ -basisMatrix {BASIS_MATRIX_FNAME} ] \\\n" \ " -finishes {FINISHES_FNAME} \\\n" \ " -camera {CAMERA_FNAME} \\\n" \ " -basisType { Ball | Radial | Shepard | RadialShepard } \\\n" \ " [ -distType { Euclidean | Directional } ] \\\n" \ " [ -channels {N_CHANNELS} ] \\\n" \ " [ -imageSize {NH} {NV} ] \\\n" \ " -outDir {OUT_DIR}" #define main_options_INFO \ main_options_files_INFO "\n" \ "\n" \ main_options_other_INFO #define main_options_files_INFO \ " -basisType { Ball | Radial | Shepard | RadialShepard }\n" \ " This mandatory parameter defines the type of elements" \ " to use in the approximation basis.\n" \ "\n" \ " -solids {SOLIDS_FNAME}\n" \ " This mandatory parameter is the full pathname of the" \ " file that describes the solid objects that comprise the" \ " scene to be rendered.\n" \ "\n" \ " -sites {SITES_FNAME}\n" \ " This optional parameter is the full pathname of the" \ " file that contains the pre-selected radiosity sampling" \ " sites for the scene. If omitted, the sites will be" \ " selected according to the parameters listed in the" \ " SITE SAMPLING OPTIONS section below.\n" \ "\n" \ " -transferMatrix {TRANSFER_MATRIX_FNAME}\n" \ " This poptional arameter is the full pathname of" \ " the file that contains the pre-computed radiance transfer" \ " matrix {T} between the radiosity sampling sites. If omitted," \ " the transfer matrix will be computed by tracing rays between" \ " the sampling sites.\n" \ "\n" \ " -approxBasis {BASIS_FNAME}\n" \ " This optional parameter is the full pathname of the file" \ " that contains the approximation basis to be used for radiosity" \ " computations. If omitted, the basis will be selected according" \ " to the to the parameters listed in the APPROXIMATION BASIS OPTIONS" \ " section below.\n" \ "\n" \ " -basisMatrix {BASIS_MATRIX_FNAME}\n" \ " This optional parameter is the full pathname of the file that" \ " contains the precomputed basis value matrix for the selected" \ " approximation basis and sampling sites. If omitted, the basis" \ " value matrix will be computed by the program.\n" \ "\n" \ " -finishes {FINISHES_FNAME}\n" \ " This mandatory parameter is the full pathname of the" \ " file that describes the surface finishes (colors," \ " emissivity, etc.) to be appplied to the solidobject" \ " in the scene.\n" \ "\n" \ " -camera {CAMERA_FNAME}\n" \ " This mandatory parameter is the full pathname of the" \ " file containing the parameters of the virtual camera" \ " (observer's position, aim point, focal distance, etc.)." \ #define main_options_other_INFO \ " -basisType { Ball | Radial | Shepard | RadialShepard }\n" \ " This mandatory parameter defines the type of" \ " approximation basis to use for modeling the radiance" \ " functions.\n" \ "\n" \ " -distType { Euclidean | Directional }\n" \ " This optional parameter defines the type of distance" \ " function to use when selecting the sampling sites, when" \ " choosing the nominal support radii of the approximation" \ " basis elements, and when evaluating those elements. The" \ " default is \"-distType Directional\".\n" \ "\n" \ " -channels {N_CHANNELS}\n" \ " This optional parameter specifies the number of channels" \ " in the output image: either 1 (monochromatic) or 3 (RGB color) .\n" \ "\n" \ " -imageSize {NH} {NV}\n" \ " This optional parameter specifies the horizontal and vertical" \ " dimensions of the output image, in pixels. The default" \ " is \"-imageSize 320 240\".\n" \ "\n" \ " -outDir {OUT_DIR}\n" \ " This mandatory parameter specifies the directory" \ " where to place all output files." void rdo_main_generate_image(main_options_t *o, scene_t *scn, camera_t *cam, image_t *img); /* Generates an image of the scene {scn}, as seen by the camera {cam}, with options {o}, and places it into the image {img}. If the auxiliary structures (sampling sites, approximation basis, matrices, etc.) are incomplete, completes them according to the parameters {o->opSmp} and {o->opBas}. */ /* ---------------------------------------------------------------------- */ /* FUNCTIONS */ int main(int argc, char** argv) { main_options_t *o = rdo_main_options_parse(argc, argv); /* Read the scene data and view-independent structures: */ scene_t *scn = rdo_scene_read ( o->solids_filename, o->sites_filename, o->transferMatrix_filename, o->approxBasis_filename, o->basisMatrix_filename, o->finishes_filename ); /* Read the virtual camera parameters: */ camera_t *cam; { FILE *camera_file = open_read(o->camera_filename, TRUE); cam = rdo_camera_read(camera_file); fclose(camera_file); } /* Allocate the output image: */ int nc = o->channels; int nh = o->imageSize.c[0]; int nv = o->imageSize.c[1]; image_t *img = float_image_new(nc, nh, nv); /* Generate the image and write it out: */ rdo_main_generate_image(o, scn, cam, img); rdo_image_map_max_to_one(img); rdo_image_write(o->outDir, "out", img, 2.200); /* Save the scene and its auxiliary structures: */ rdo_scene_write(o->outDir, "out", scn); /* Recycle the trash: */ float_image_free(img); rdo_camera_free(cam); rdo_scene_free(scn); return 0; } void rdo_main_generate_image(main_options_t *o, scene_t *scn, camera_t *cam, image_t *img) { rdo_synthesis_compute_image ( scn, cam, o->distType, o->basisType, o->opSmp, o->opBas, o->opSyn, img ); } main_options_t *rdo_main_options_parse(int argc, char *argv[]) { argparser_t *pp = argparser_new(stderr, argc, argv); argparser_set_help(pp, PROG_HELP); argparser_set_info(pp, PROG_INFO); argparser_process_help_info_options(pp); main_options_t *o = NOTNULL(malloc(sizeof(main_options_t))); /* ---------------------------------------------------------------------- */ if (argparser_keyword_present(pp, "-solids")) { o->solids_filename = argparser_get_next(pp); } else { argparser_error(pp, "missing parameter \"-solids\""); } /* ---------------------------------------------------------------------- */ if (argparser_keyword_present(pp, "-sites")) { o->sites_filename = argparser_get_next(pp); } else { o->sites_filename = NULL; } /* ---------------------------------------------------------------------- */ if (argparser_keyword_present(pp, "-transferMatrix")) { o->transferMatrix_filename = argparser_get_next(pp); } else { o->transferMatrix_filename = NULL; } /* ---------------------------------------------------------------------- */ if (argparser_keyword_present(pp, "-approxBasis")) { o->approxBasis_filename = argparser_get_next(pp); } else { o->approxBasis_filename = NULL; } /* ---------------------------------------------------------------------- */ if (argparser_keyword_present(pp, "-basisMatrix")) { o->basisMatrix_filename = argparser_get_next(pp); } else { o->basisMatrix_filename = NULL; } /* ---------------------------------------------------------------------- */ if (argparser_keyword_present(pp, "-finishes")) { o->finishes_filename = argparser_get_next(pp); } else { argparser_error(pp, "missing parameter \"-finishes\""); } /* ---------------------------------------------------------------------- */ if (argparser_keyword_present(pp, "-camera")) { o->camera_filename = argparser_get_next(pp); } else { argparser_error(pp, "missing parameter \"-camera\""); } /* ---------------------------------------------------------------------- */ if (argparser_keyword_present(pp, "-distType")) { if (argparser_keyword_present_next(pp, "Euclidean")) { o->distType = dist_type_Euclidean; } else if (argparser_keyword_present_next(pp, "Directional")) { o->distType = dist_type_Directional; } else { argparser_error(pp, "invalid parameter \"-distType\""); } } else { o->distType = dist_type_Directional; } /* ---------------------------------------------------------------------- */ if (argparser_keyword_present(pp, "-basisType")) { if (argparser_keyword_present_next(pp, "Ball")) { o->basisType = basis_elem_type_Ball; } else if (argparser_keyword_present_next(pp, "Radial")) { o->basisType = basis_elem_type_Radial; } else if (argparser_keyword_present_next(pp, "Shepard")) { o->basisType = basis_elem_type_Shepard; } else if (argparser_keyword_present_next(pp, "RadialShepard")) { o->basisType = basis_elem_type_RadialShepard; } else { argparser_error(pp, "invalid parameter \"-basisType\""); } } else { argparser_error(pp, "missing parameter \"-basisType\""); } /* ---------------------------------------------------------------------- */ if (argparser_keyword_present(pp, "-channels")) { o->channels = (int)argparser_get_next_int(pp, 1, 16); if ((o->channels != 1) && (o->channels != 3)) { argparser_error(pp, "parameter \"-channels\" must be 1 or 3"); } } else { o->channels = 3; } /* ---------------------------------------------------------------------- */ if (argparser_keyword_present(pp, "-imageSize")) { o->imageSize.c[0] = (int)argparser_get_next_int(pp, 1, MAX_IMAGE_SIZE); o->imageSize.c[1] = (int)argparser_get_next_int(pp, 1, MAX_IMAGE_SIZE); } else { o->imageSize = (i2_t){{ 320, 240 }}; } /* ---------------------------------------------------------------------- */ o->opSmp = rdo_sampling_options_parse(pp); o->opBas = rdo_approx_basis_options_parse(pp); o->opSyn = rdo_synthesis_options_parse(pp); /* ---------------------------------------------------------------------- */ if (argparser_keyword_present(pp, "-outDir")) { o->outDir = argparser_get_next(pp); } else { argparser_error(pp, "missing parameter \"-outDir\""); } /* ---------------------------------------------------------------------- */ argparser_finish(pp); return o; }