// ================================================================ // $Id: environ.cpp,v 1.1 2004/02/16 14:45:59 bittner Exp $ // // environ.cpp // Implementation of the environment operations, ie. reading // environment file, reading command line parameters etc. // //#define _DEBUG_PARAMS #include #include #include #include #include #include "gzstream.h" #include "common.h" #include "Environment.h" #include "Vector3.h" Environment *environment = NULL; Environment::~Environment() { int i, j; // delete the params structure for (i = 0; i < numParams; i++) { for (j = 0; j < paramRows; j++) if (params[i][j] != NULL) delete[] params[i][j]; if (params[i] != NULL) delete[] params[i]; } if (params != NULL) delete[] params; // delete the options structure if (options != NULL) delete[] options; if (optionalParams != NULL) delete optionalParams; } bool Environment::CheckForSwitch(const int argc, char **argv, const char swtch) const { for (int i = 1; i < argc; i++) if ((argv[i][0] == '-') && (argv[i][1] == swtch)) return true; return false; } bool Environment::CheckType(const char *value, const EOptType type) const { char *s, *t, *u; switch (type) { case optInt: { strtol(value, &t, 10); if (value + strlen(value) != t) return false; else return true; } case optFloat: { strtod(value, &t); if (value + strlen(value) != t) return false; else return true; } case optBool: { if (!strcasecmp(value, "true") || !strcasecmp(value, "false") || !strcasecmp(value, "YES") || !strcasecmp(value, "NO") || !strcmp(value, "+") || !strcmp(value, "-") || !strcasecmp(value, "ON") || !strcasecmp(value, "OFF")) return true; return false; } case optVector:{ strtod(value, &s); if (*s == ' ' || *s == '\t') { while (*s == ' ' || *s == '\t') s++; if (*s != ',') s--; } if ((*s != ',' && *s != ' ' && *s != '\t') || value == s) return false; t = s; strtod(s + 1, &u); if (*u == ' ' || *u == '\t') { while (*u == ' ' || *u == '\t') u++; if (*u != ',') u--; } if ((*u != ',' && *s != ' ' && *s != '\t') || t == u) return false; t = u; strtod(u + 1, &s); if (t == s || value + strlen(value) != s) return false; return true; } case optString: { return true; } default: { Debug << "Internal error: Unknown type of option.\n" << flush; exit(1); } } return false; } void Environment::ReadCmdlineParams(const int argc, char **argv, const char *optParams) { int i; // Make sure we are called for the first time if (optionalParams != NULL) return; numParams = (int)strlen(optParams) + 1; optionalParams = new char[numParams]; strcpy(optionalParams, optParams); // First, count all non-optional parameters on the command line for (i = 1; i < argc; i++) if (argv[i][0] != '-') paramRows++; // if there is no non-optional parameter add a default one... if (paramRows == 0) paramRows = 1; // allocate and initialize the table for parameters params = new char **[numParams]; for (i = 0; i < numParams; i++) { params[i] = new char *[paramRows]; for (int j = 0; j < paramRows; j++) params[i][j] = NULL; } // Now read all non-optional and optional parameters into the table curRow = -1; for (i = 1; i < argc; i++) { if (argv[i][0] != '-') { // non-optional parameter encountered curRow++; params[0][curRow] = new char[strlen(argv[i]) + 1]; strcpy(params[0][curRow], argv[i]); } else { // option encountered char *t = strchr(optionalParams, argv[i][1]); if (t != NULL) { // this option is optional parameter int index = t - optionalParams + 1; if (curRow < 0) { // it's a global parameter for (int j = 0; j < paramRows; j++) { params[index][j] = new char[strlen(argv[i] + 2) + 1]; strcpy(params[index][j], argv[i] + 2); } } else { // it's a scene parameter if (params[index][curRow] != NULL) { delete[] params[index][curRow]; } params[index][curRow] = new char[strlen(argv[i] + 2) + 1]; strcpy(params[index][curRow], argv[i] + 2); } } } } curRow = 0; #ifdef _DEBUG_PARAMS // write out the parameter table cerr << "Parameter table for " << numParams << " columns and " << paramRows << " rows:\n"; for (int j = 0; j < paramRows; j++) { for (i = 0; i < numParams; i++) { if (params[i][j] != NULL) cerr << params[i][j]; else cerr << "NULL"; cerr << "\t"; } cerr << "\n"; } cerr << "Params done.\n" << flush; #endif // _DEBUG_PARAMS } bool Environment::GetParam(const char name, const int index, char *value) const { int column; if (index >= paramRows || index < 0) return false; if (name == ' ') column = 0; else { char *t = strchr(optionalParams, name); if (t == NULL) return false; column = t - optionalParams + 1; } if (params[column][index] == NULL) return false; // value = new char[strlen(params[column][index]) + 1]; strcpy(value, params[column][index]); return true; } void Environment::RegisterOption(const char *name, const EOptType type, const char *abbrev, const char *defValue) { int i; // make sure this option was not yet registered for (i = 0; i < numOptions; i++) if (!strcmp(name, options[i].name)) { Debug << "Error: Option " << name << " registered twice.\n"; exit(1); } // make sure we have enough room in memory if (numOptions >= maxOptions) { Debug << "Error: Too many options. Try enlarge the maxOptions " << "definition.\n"; exit(1); } // make sure the abbreviation doesn't start with 'D' if (abbrev != NULL && (abbrev[0] == 'D' )) { Debug << "Internal error: reserved switch " << abbrev << " used as an abbreviation.\n"; exit(1); } // new option options[numOptions].type = type; options[numOptions].name = strdup(name); // assign abbreviation, if requested if (abbrev != NULL) { options[numOptions].abbrev = strdup(abbrev); } // assign default value, if requested if (defValue != NULL) { options[numOptions].defaultValue = strdup(defValue); if (!CheckType(defValue, type)) { Debug << "Internal error: Inconsistent type and default value in option " << name << ".\n"; exit(1); } } // new option registered numOptions++; } bool Environment::OptionPresent(const char *name) const { bool found = false; int i; for (i = 0; i < numOptions; i++) if (!strcmp(options[i].name, name)) { found = true; break; } if (!found) { Debug << "Internal error: Option " << name << " not registered.\n" << flush; exit(1); } if (options[i].value != NULL || options[i].defaultValue != NULL) return true; else return false; } int Environment::FindOption(const char *name, const bool isFatal) const { int i; bool found = false; // is this option registered ? for (i = 0; i < numOptions; i++) if (!strcmp(options[i].name, name)) { found = true; break; } if (!found) { // no registration found Debug << "Internal error: Required option " << name << " not registered.\n" << flush; exit(1); } if (options[i].value == NULL && options[i].defaultValue == NULL) // this option was not initialised to some value if (isFatal) { Debug << "Error: Required option " << name << " not found.\n" << flush; exit(1); } else { Debug << "Error: Required option " << name << " not found.\n" << flush; return -1; } return i; } bool Environment::GetIntValue(const char *name, int &value, const bool isFatal) const { int i = FindOption(name, isFatal); if (i<0) return false; if (options[i].value != NULL) { // option was explicitly specified value = strtol(options[i].value, NULL, 10); } else { // option was not read, so use the default value = strtol(options[i].defaultValue, NULL, 10); } return true; } bool Environment::GetDoubleValue(const char *name, double &value, const bool isFatal) const { int i = FindOption(name, isFatal); if (i<0) return false; if (options[i].value != NULL) { // option was explicitly specified value = strtod(options[i].value, NULL); } else { // option was not read, so use the default value = strtod(options[i].defaultValue, NULL); } return true; } bool Environment::GetRealValue(const char *name, Real &value, const bool isFatal) const { int i = FindOption(name, isFatal); if (i<0) return false; if (options[i].value != NULL) { // option was explicitly specified value = (Real)strtod(options[i].value, NULL); } else { // option was not read, so use the default value = (Real)strtod(options[i].defaultValue, NULL); } return true; } bool Environment::GetFloatValue(const char *name, float &value, const bool isFatal) const { int i = FindOption(name, isFatal); if (i<0) return false; if (options[i].value != NULL) { // option was explicitly specified value = (float)strtod(options[i].value, NULL); } else { // option was not read, so use the default value = (float)strtod(options[i].defaultValue, NULL); } return true; } bool Environment::GetBool(const char *name, const bool isFatal) const { bool ret; if (GetBoolValue(name, ret, isFatal)) return ret; else return false; } bool Environment::ParseBool(const char *name) const { bool value = true; if (!strcasecmp(name, "false") || !strcasecmp(name, "NO") || !strcmp(name, "-") || !strcasecmp(name, "OFF")) value = false; return value; } void Environment::ParseVector(const char *name, Vector3 &v) const { // option was not read, so use the default char *s, *t; v.x = (Real)strtod(name, &s); v.y = (Real)strtod(s + 1, &t); v.z = (Real)strtod(t + 1, NULL); } bool Environment::GetBoolValue(const char *name, bool &value, const bool isFatal) const { int i = FindOption(name, isFatal); if (i<0) return false; if (options[i].value != NULL) value = ParseBool(options[i].value); else value = ParseBool(options[i].defaultValue); return true; } bool Environment::GetVectorValue(const char *name, Vector3 &v, const bool isFatal) const { int i = FindOption(name, isFatal); if (i<0) return false; if (options[i].value != NULL) if (options[i].value != NULL) { ParseVector(options[i].value, v); } else { ParseVector(options[i].defaultValue, v); } return true; } bool Environment::GetStringValue(const char *name, char *value, const bool isFatal) const { int i = FindOption(name, isFatal); if (i<0) return false; if (options[i].value != NULL) { // option was not read, so use the default strcpy(value, options[i].value); } else { // option was explicitly specified strcpy(value, options[i].defaultValue); } return true; } void Environment::SetInt(const char *name, const int value) { int i = FindOption(name); if (i<0) return; if (options[i].type == optInt) { delete options[i].value; options[i].value = new char[16]; sprintf(options[i].value, "%.15d", value); } else { Debug << "Internal error: Trying to set non-integer option " << name << " to integral value.\n" << flush; exit(1); } } void Environment::SetFloat(const char *name, const Real value) { int i = FindOption(name); if (i<0) return; if (options[i].type == optFloat) { delete options[i].value; options[i].value = new char[25]; sprintf(options[i].value, "%.15e", value); } else { Debug << "Internal error: Trying to set non-Real option " << name << " to Real value.\n" << flush; exit(1); } } void Environment::SetBool(const char *name, const bool value) { int i = FindOption(name); if (i<0) return; if (options[i].type == optBool) { delete options[i].value; options[i].value = new char[6]; if (value) sprintf(options[i].value, "true"); else sprintf(options[i].value, "false"); } else { Debug << "Internal error: Trying to set non-bool option " << name << " to boolean value.\n" << flush; exit(1); } } void Environment::SetVector(const char *name, const Vector3 &v) { int i = FindOption(name); if (i<0) return; if (options[i].type == optVector) { delete options[i].value; options[i].value = new char[128]; sprintf(options[i].value, "%.15e,%.15e,%.15e", v.x, v.y, v.z); } else { Debug << "Internal error: Trying to set non-vector option " << name << " to vector value.\n" << flush; exit(1); } } void Environment::SetString(const char *name, const char *value) { int i = FindOption(name); if (i<0) return; if (options[i].type == optString) { delete options[i].value; options[i].value = strdup(value); } else { Debug << "Internal error: Trying to set non-string option " << name << " to string value.\n" << flush; exit(1); } } void Environment::ParseCmdline(const int argc, char **argv, const int index) { int curIndex = -1; for (int i = 1; i < argc; i++) { // if this parameter is non-optional, skip it and increment the counter if (argv[i][0] != '-') { curIndex++; continue; } // make sure to skip all non-optional parameters char *t = strchr(optionalParams, argv[i][1]); if (t != NULL) continue; // if we are in the scope of the current parameter, parse it if (curIndex == -1 || curIndex == index) { if (argv[i][1] == 'D') { // it's a full name definition bool found = false; int j; char *t = strchr(argv[i] + 2, '='); if (t == NULL) { Debug << "Error: Missing '=' in option. " << "Syntax is -D=.\n" << flush; exit(1); } for (j = 0; j < numOptions; j++) if (!strncmp(options[j].name, argv[i] + 2, t - argv[i] - 2) && (unsigned)(t - argv[i] - 2) == strlen(options[j].name)) { found = true; break; } if (!found) { Debug << "Warning: Unregistered option " << argv[i] << ".\n" << flush; // exit(1); } if (found) { if (!CheckType(t + 1, options[j].type)) { Debug << "Error: invalid type of value " << t + 1 << " in option " << options[j].name << ".\n"; exit(1); } if (options[j].value != NULL) delete options[j].value; options[j].value = strdup(t + 1); } } else { // it's an abbreviation bool found = false; int j; for (j = 0; j < numOptions; j++) if (options[j].abbrev != NULL && !strncmp(options[j].abbrev, argv[i] + 1, strlen(options[j].abbrev))) { found = true; break; } if (!found) { Debug << "Warning: Unregistered option " << argv[i] << ".\n" << flush; // exit(1); } if (found) { if (!CheckType(argv[i] + 1 + strlen(options[j].abbrev), options[j].type)) { Debug << "Error: invalid type of value " << argv[i] + 1 + strlen(options[j].abbrev) << "in option " << options[j].name << ".\n"; exit(1); } if (options[j].value != NULL) delete options[j].value; options[j].value = strdup(argv[i] + 1 + strlen(options[j].abbrev)); } } } } #ifdef _DEBUG_PARAMS // write out the options table cerr << "Options table for " << numOptions << " options:\n"; for (int j = 0; j < numOptions; j++) { cerr << options[j]; cerr << "\n"; } cerr << "Options done.\n" << flush; #endif // _DEBUG_PARAMS } char * Environment::ParseString(char *buffer, char *string) const { char *s = buffer; char *t = string + strlen(string); // skip leading whitespaces while (*s == ' ' || *s == '\t') s++; if (*s == '\0') return NULL; while ((*s >= 'a' && *s <= 'z') || (*s >= 'A' && *s <= 'Z') || (*s >= '0' && *s <= '9') || *s == '_') *t++ = *s++; *t = '\0'; // skip trailing whitespaces while (*s == ' ' || *s == '\t') s++; return s; } const char code[] = "JIDHipewhfdhyd74387hHO&{WK:DOKQEIDKJPQ*H#@USX:#FWCQ*EJMQAHPQP(@G#RD"; void Environment::DecodeString(char *buff, int max) { buff[max] = 0; char *p = buff; const char *cp = code; for (; *p; p++) { if (*p != '\n') *p = *p ^ *cp; ++cp; if (*cp == 0) cp = code; } } void Environment::CodeString(char *buff, int max) { buff[max] = 0; char *p = buff; const char *cp = code; for (; *p; p++) { if (*p != '\n') *p = *p ^ *cp; ++cp; if (*cp == 0) cp = code; } } void Environment::SaveCodedFile(char *filenameText, char *filenameCoded) { ifstream envStream(filenameText); // some error had occured if (envStream.fail()) { cerr << "Error: Can't open file " << filenameText << " for reading (err. " << envStream.rdstate() << ").\n"; return; } char buff[256]; envStream.getline(buff, 255); buff[8] = 0; if (strcmp(buff, "CGX_CF10") == 0) return; ofstream cStream(filenameCoded); cStream<<"CGX_CF10"; // main loop for (;;) { // read in one line envStream.getline(buff, 255); if (!envStream) break; CodeString(buff, 255); cStream<= 'a' && *t <= 'z') || (*t >= 'A' && *t <= 'Z') || *t == '+' || *t == '-') t++; if (((!strncasecmp(s, "true", t - s) && t - s == 4) || (!strncasecmp(s, "false", t - s) && t - s == 5) || (!strncasecmp(s, "YES", t -s) && t - s == 3) || (!strncasecmp(s, "NO", t - s) && t - s == 2) || (!strncasecmp(s, "ON", t - s) && t - s == 2) || (!strncasecmp(s, "OFF", t - s) && t - s == 3) || (t - s == 1 && (*s == '+' || *s == '-'))) && (*t == ' ' || *t == '\t' || *t == '\0' || *t == '}')) { if (options[i].value != NULL) delete options[i].value; options[i].value = new char[t - s + 1]; strncpy(options[i].value, s, t - s); options[i].value[t - s] = '\0'; s = t; } else { cerr << "Error: Mismatch in bool variable " << name << " in " << "environment file " << envFilename << " (line " << line << ").\n"; envStream.close(); return false; } break; } case optVector:{ strtod(s, &t); if (*t == ' ' || *t == '\t') { while (*t == ' ' || *t == '\t') t++; if (*t != ',') t--; } if (t == s || (*t != ' ' && *t != '\t' && *t != ',')) { cerr << "Error: Mismatch in vector variable " << name << " in " << "environment file " << envFilename << " (line " << line << ").\n"; envStream.close(); return false; } char *u; strtod(t, &u); t = u; if (*t == ' ' || *t == '\t') { while (*t == ' ' || *t == '\t') t++; if (*t != ',') t--; } if (t == s || (*t != ' ' && *t != '\t' && *t != ',')) { cerr << "Error: Mismatch in vector variable " << name << " in " << "environment file " << envFilename << " (line " << line << ").\n"; envStream.close(); return false; } strtod(t, &u); t = u; if (t == s || (*t != ' ' && *t != '\t' && *t != '\0' && *t != '}')) { cerr << "Error: Mismatch in vector variable " << name << " in " << "environment file " << envFilename << " (line " << line << ").\n"; envStream.close(); return false; } if (options[i].value != NULL) delete options[i].value; options[i].value = new char[t - s + 1]; strncpy(options[i].value, s, t - s); options[i].value[t - s] = '\0'; s = t; break; } case optString: { if (options[i].value != NULL) delete options[i].value; options[i].value = new char[strlen(s) + 1]; strcpy(options[i].value, s); s += strlen(s); break; } default: { Debug << "Internal error: Unknown type of option.\n" << flush; exit(1); } } // prepare the variable name for next pass t = strrchr(name, '.'); if (t == NULL) name[0] = '\0'; else *(t + 1) = '\0'; // get next identifier s = ParseString(s, name); } } envStream.close(); return true; } void Environment::PrintUsage(ostream &s) const { // Print out all environment variable names s << "Registered options:\n"; for (int j = 0; j < numOptions; j++) s << options[j] << "\n"; s << flush; } Environment::Environment() { optionalParams = NULL; paramRows = 0; numParams = 0; params = NULL; maxOptions = 500; // this is maximal nuber of options. numOptions = 0; options = new COption[maxOptions]; if (options == NULL ) { Debug << "Error: Memory allocation failed.\n"; exit(1); } // register all basic options RegisterOption("Limits.threshold", optFloat, NULL, "0.01"); RegisterOption("Limits.small", optFloat, NULL, "1e-6"); RegisterOption("Limits.infinity", optFloat, NULL, "1e6"); RegisterOption("Scene.filename", optString, "scene_filename=", "atlanta2.x3d"); RegisterOption("Unigraphics.meshGrouping", optInt, "unigraphics_mesh_grouping=", "0"); RegisterOption("KdTree.Termination.minCost", optInt, "kd_term_min_cost=", "10"); RegisterOption("KdTree.Termination.maxNodes", optInt, "kd_term_max_nodes=", "200000"); RegisterOption("KdTree.Termination.maxDepth", optInt, "kd_term_max_depth=", "20"); RegisterOption("KdTree.Termination.maxCostRatio", optFloat, "kd_term_max_cost_ratio=", "1.5"); RegisterOption("KdTree.Termination.ct_div_ci", optFloat, "kd_term_ct_div_ci=", "1.0"); RegisterOption("KdTree.splitMethod", optString, "kd_split_method=", "spatialMedian"); RegisterOption("KdTree.splitBorder", optFloat, "kd_split_border=", "0.1"); RegisterOption("KdTree.sahUseFaces", optBool, "kd_sah_use_faces=", "true"); RegisterOption("MeshKdTree.Termination.minCost", optInt, "kd_term_min_cost=", "10"); RegisterOption("MeshKdTree.Termination.maxDepth", optInt, "kd_term_max_depth=", "20"); RegisterOption("MeshKdTree.Termination.maxCostRatio", optFloat, "kd_term_max_cost_ratio=", "1.5"); RegisterOption("MeshKdTree.Termination.ct_div_ci", optFloat, "kd_term_ct_div_ci=", "1.0"); RegisterOption("MeshKdTree.splitMethod", optString, "kd_split_method=", "spatialMedian"); RegisterOption("MeshKdTree.splitBorder", optFloat, "kd_split_border=", "0.1"); RegisterOption("SamplingPreprocessor.totalSamples", optInt, "total_samples=", "1000000"); RegisterOption("SamplingPreprocessor.samplesPerPass", optInt, "samples_per_pass=", "10"); RegisterOption("RenderSampler.samples", optInt, "render_sampler_samples=", "1000"); RegisterOption("VssPreprocessor.initialSamples", optInt, "initial_samples=", "100000"); RegisterOption("VssPreprocessor.testBeamSampling", optBool, "beam_sampling", "false"); RegisterOption("VssPreprocessor.vssSamples", optInt, "vss_samples=", "1000000"); RegisterOption("VssPreprocessor.vssSamplesPerPass", optInt, "vss_samples_per_pass=", "1000"); RegisterOption("VssPreprocessor.samplesPerPass", optInt, "samples_per_pass=", "100000"); RegisterOption("VssPreprocessor.useImportanceSampling", optBool, "vss_use_importance=", "true"); RegisterOption("VssPreprocessor.enlargeViewSpace", optBool, "vss_enlarge_viewspace=", "false"); RegisterOption("VssPreprocessor.loadInitialSamples", optBool, "vss_load_loadInitialSamples=", "false"); RegisterOption("VssPreprocessor.storeInitialSamples", optBool, "vss_store_storedInitialSamples=", "false"); RegisterOption("VssPreprocessor.useViewSpaceBox", optBool, "vss_use_viewspace_box=", "false"); /************************************************************************************/ /* View cells related options */ /************************************************************************************/ RegisterOption("ViewCells.type", optString, "view_cells_type=", "vspBspTree"); RegisterOption("ViewCells.samplingType", optString, "view_cells_sampling_type=", "box"); RegisterOption("ViewCells.mergeStats", optString, "view_cells_merge_stats=", "mergeStats.log"); RegisterOption("ViewCells.Evaluation.statsPrefix", optString, "view_cells_evaluation_stats_prefix=", "viewCells"); RegisterOption("ViewCells.Evaluation.histogram", optBool, "view_cells_evaluation_histogram=", "false"); RegisterOption("ViewCells.Evaluation.histoPasses", optInt, "view_cells_evaluation_histo_passes=", "5000"); RegisterOption("ViewCells.renderCostEvaluationType", optString, "view_cells_render_cost_evaluation=", "perobject"); RegisterOption("ViewCells.active", optInt, "view_cells_active=", "1000"); RegisterOption("ViewCells.Construction.samples", optInt, "view_cells_construction_samples=", "5000000"); RegisterOption("ViewCells.Construction.samplesPerPass", optInt, "view_cells_construction_samples_per_pass=", "500000"); RegisterOption("ViewCells.PostProcess.samples", optInt, "view_cells_post_process_samples=", "200000"); RegisterOption("ViewCells.Visualization.samples", optInt, "view_cells_visualization_samples=", "20000"); RegisterOption("ViewCells.Filter.maxSize", optInt, "view_cells_filter_max_size=", "4"); RegisterOption("ViewCells.Filter.width", optFloat, "view_cells_filter_width=", "200.0"); RegisterOption("ViewCells.loadFromFile", optBool, "view_cells_load_from_file=", "false"); RegisterOption("ViewCells.PostProcess.refine", optBool, "view_cells_refine=", "false"); RegisterOption("ViewCells.PostProcess.compress", optBool, "view_cells_post_process_compress=", "false"); RegisterOption("ViewCells.Evaluation.samples", optInt, "view_cells_evaluation_samples=", "8000000"); RegisterOption("ViewCells.Evaluation.samplingType", optString, "view_cells_evaluation_sampling_type=", "box"); RegisterOption("ViewCells.Evaluation.samplesPerPass", optInt, "view_cells_evaluation_samples_per_pass=", "300000"); RegisterOption("ViewCells.exportToFile", optBool, "view_cells_export_to_file=", "false"); RegisterOption("ViewCells.PostProcess.emptyViewCellsMerge", optBool, "view_cells_merge_empty=", "true"); RegisterOption("ViewCells.evaluateViewCells", optBool, "view_cells_evaluate=", "false"); RegisterOption("ViewCells.maxViewCells", optInt, "view_cells_max_view_cells=", "0"); RegisterOption("ViewCells.maxPvsRatio", optFloat, "view_cells_max_pvs_ratio=", "0.1"); RegisterOption("ViewCells.filename", optString, "view_cells_filename=", "atlanta_viewcells_large.x3d"); RegisterOption("ViewCells.height", optFloat, "view_cells_height=", "5.0"); RegisterOption("ViewCells.Visualization.colorCode", optString, "view_cells_visualization_color_code=", "PVS"); RegisterOption("ViewCells.Visualization.clipPlanePos", optFloat, "view_cells_visualization_clip_plane_pos=", "0.35"); RegisterOption("ViewCells.Visualization.exportGeometry", optBool, "view_cells_visualization_export_geometry=", "false"); RegisterOption("ViewCells.Visualization.exportRays", optBool, "view_cells_visualization_export_rays=", "false"); RegisterOption("ViewCells.pruneEmptyViewCells", optBool, "view_cells_prune_empty=", "false"); RegisterOption("ViewCells.processOnlyValidViewCells", optBool, "view_cells_process_only_valid_view_cells=", "false"); RegisterOption("ViewCells.PostProcess.maxCostRatio", optFloat, "view_cells_post_process_max_cost_ratio=", "0.9"); RegisterOption("ViewCells.PostProcess.renderCostWeight", optFloat, "view_cells_post_process_render_cost_weight", "0.5"); RegisterOption("ViewCells.PostProcess.avgCostMaxDeviation", optFloat, "vsp_bsp_avgcost_max_deviations", "0.5"); RegisterOption("ViewCells.PostProcess.maxMergesPerPass", optInt, "view_cells_post_process_max_merges_per_pass=", "500"); RegisterOption("ViewCells.PostProcess.minViewCells", optInt, "view_cells_post_process_min_view_cells=", "1000"); RegisterOption("ViewCells.PostProcess.useRaysForMerge", optBool, "view_cells_post_process_use_rays_for_merge=", "false"); RegisterOption("ViewCells.PostProcess.merge", optBool, "view_cells_post_process_merge=", "true"); RegisterOption("ViewCells.Visualization.exportMergedViewCells", optBool, "view_cells_viz_export_merged_viewcells=", "false"); RegisterOption("ViewCells.maxStaticMemory", optFloat, "view_cells_max_static_mem=", "8.0"); RegisterOption("ViewCells.Visualization.useClipPlane", optBool, "view_cells_viz_use_clip_plane=", "false"); RegisterOption("ViewCells.showVisualization", optBool, "view_cells_show_visualization=", "false"); RegisterOption("ViewCells.Visualization.clipPlaneAxis", optInt, "view_cells_viz_clip_plane_axis=", "0"); /************************************************************************************/ /* Render simulation related options */ /************************************************************************************/ RegisterOption("Simulation.objRenderCost", optFloat, "simulation_obj_render_cost", "1.0"); RegisterOption("Simulation.vcOverhead", optFloat, "simulation_vc_overhead", "0.05"); RegisterOption("Simulation.moveSpeed", optFloat, "simulation_moveSpeed", "1.0"); /************************************************************************************/ /* Bsp tree related options */ /************************************************************************************/ RegisterOption("BspTree.Construction.input", optString, "bsp_construction_input=", "fromViewCells"); RegisterOption("BspTree.subdivisionStats", optString, "bsp_subdivision_stats=", "bspSubdivisionStats.log"); RegisterOption("BspTree.Construction.samples", optInt, "bsp_construction_samples=", "100000"); RegisterOption("BspTree.Construction.epsilon", optFloat, "bsp_construction_side_tolerance=", "0.002"); RegisterOption("BspTree.Termination.minPolygons", optInt, "bsp_term_min_polygons=", "5"); RegisterOption("BspTree.Termination.minPvs", optInt, "bsp_term_min_pvs=", "20"); RegisterOption("BspTree.Termination.minProbability", optFloat, "bsp_term_min_probability=", "0.001"); RegisterOption("BspTree.Termination.maxRayContribution", optFloat, "bsp_term_ray_contribution=", "0.005"); RegisterOption("BspTree.Termination.minAccRayLenght", optFloat, "bsp_term_min_acc_ray_length=", "50"); RegisterOption("BspTree.Termination.minRays", optInt, "bsp_term_min_rays=", "-1"); RegisterOption("BspTree.Termination.ct_div_ci", optFloat, "bsp_term_ct_div_ci=", "0.0"); RegisterOption("BspTree.Termination.maxDepth", optInt, "bsp_term_max_depth=", "100"); RegisterOption("BspTree.Termination.maxCostRatio", optFloat, "bsp_term_axis_aligned_max_cost_ratio=", "1.5"); RegisterOption("BspTree.Termination.AxisAligned.ct_div_ci", optFloat, "bsp_term_axis_aligned_ct_div_ci=", "0.5"); RegisterOption("BspTree.AxisAligned.splitBorder", optFloat, "bsp__axis_aligned_split_border=", "0.1"); RegisterOption("BspTree.Termination.AxisAligned.minPolys", optInt, "bsp_term_axis_aligned_max_polygons=", "50"); RegisterOption("BspTree.Termination.AxisAligned.minObjects", optInt, "bsp_term_min_objects=", "3"); RegisterOption("BspTree.Termination.AxisAligned.minRays", optInt, "bsp_term_axis_aligned_min_rays=", "-1"); RegisterOption("BspTree.splitPlaneStrategy", optString, "bsp_split_method=", "leastSplits"); RegisterOption("BspTree.maxPolyCandidates", optInt, "bsp_max_poly_candidates=", "20"); RegisterOption("BspTree.maxRayCandidates", optInt, "bsp_max_plane_candidates=", "20"); RegisterOption("BspTree.maxTests", optInt, "bsp_max_tests=", "5000"); RegisterOption("BspTree.Termination.maxViewCells", optInt, "bsp_max_view_cells=", "5000"); RegisterOption("BspTree.Visualization.exportSplits", optBool, "bsp_visualization.export_splits", "false"); RegisterOption("BspTree.Factor.verticalSplits", optFloat, "bsp_factor_vertical=", "1.0"); RegisterOption("BspTree.Factor.largestPolyArea", optFloat, "bsp_factor_largest_poly=", "1.0"); RegisterOption("BspTree.Factor.blockedRays", optFloat, "bsp_factor_blocked=", "1.0"); RegisterOption("BspTree.Factor.leastSplits", optFloat, "bsp_factor_least_splits=", "1.0"); RegisterOption("BspTree.Factor.balancedPolys", optFloat, "bsp_factor_balanced_polys=", "1.0"); RegisterOption("BspTree.Factor.balancedViewCells", optFloat, "bsp_factor_balanced_view_cells=", "1.0"); RegisterOption("BspTree.Factor.leastRaySplits", optFloat, "bsp_factor_least_ray_splits=", "1.0"); RegisterOption("BspTree.Factor.balancedRays", optFloat, "bsp_factor_balanced_rays=", "1.0"); RegisterOption("BspTree.Factor.pvs", optFloat, "bsp_factor_pvs=", "1.0"); /************************************************************************************/ /* Preprocessor related options */ /************************************************************************************/ RegisterOption("Preprocessor.type", optString, "preprocessor=", "sampling"); RegisterOption("Preprocessor.samplesFilename", optString, "preprocessor_samples_filename=", "rays.out"); RegisterOption("Preprocessor.loadPolygonsAsMeshes", optBool, "loadPolygonsAsMeshes=", "false"); RegisterOption("Preprocessor.pvsRenderErrorSamples", optInt, "pvsRenderErrorSamples=", "10000"); RegisterOption("Preprocessor.useGlRenderer", optBool, "preprocessor_use_gl_renderer=", "false"); RegisterOption("Preprocessor.useGlDebugger", optBool, "preprocessor_use_gl_debugger=", "false"); RegisterOption("Preprocessor.detectEmptyViewSpace", optBool, "preprocessor_detect_empty_viewspace=", "false"); RegisterOption("Preprocessor.quitOnFinish", optBool, "preprocessor_quit_on_finish=", "true"); RegisterOption("Preprocessor.computeVisibility", optBool, "preprocessor_compute_visibility=", "true"); /**************************************************************************************/ /* View space partition KD tree related options */ /**************************************************************************************/ RegisterOption("VspKdTree.Construction.samples", optInt, "vsp_kd_construction_samples=", "100000"); RegisterOption("VspKdTree.Termination.maxDepth", optInt, "vsp_term_maxdepth=", "30"); RegisterOption("VspKdTree.Termination.minPvs", optInt, "vsp_minpvs=", "1"); RegisterOption("VspKdTree.Termination.minRays", optInt, "vsp_term_minrays=", "10"); RegisterOption("VspKdTree.Termination.minSize", optFloat, "vsp_term_minsize=", "0.001"); RegisterOption("VspKdTree.Termination.maxCostRatio", optFloat, "vsp_term_maxcost=", "0.95"); RegisterOption("VspKdTree.Termination.maxRayContribution", optFloat, "vsp_term_max_ray_contrib=", "0.5"); RegisterOption("VspKdTree.epsilon", optFloat, "kd_eps=", "1e-6"); RegisterOption("VspKdTree.ct_div_ci", optFloat, "vsp_ctdivci=", "1.0"); RegisterOption("VspKdTree.splitType", optString, "split=", "queries"); RegisterOption("VspKdTree.splitAxis", optString, "split=", "drivingAxis"); RegisterOption("VspKdTree.splitUseOnlyDrivingAxis", optBool, "vsp_kd_splitdriving=", "false"); RegisterOption("VspKdTree.numberOfEndPointDomains", optInt, "endpoints=", "10000"); RegisterOption("VspKdTree.maxTotalMemory", optFloat, "vsp_max_total_mem=", "60.0"); RegisterOption("VspKdTree.maxStaticMemory", optFloat, "vsp_max_static_mem=", "8.0"); RegisterOption("VspKdTree.queryType", optString, "qtype=", "static"); RegisterOption("VspKdTree.queryPosWeight", optFloat, "vsp_kd_qposweight=", "0.0"); RegisterOption("VspKdTree.accessTimeThreshold", optInt, "vsp_kd_accesstime=", "1000"); RegisterOption("VspKdTree.minCollapseDepth", optInt, "vsp_kd_min_colldepth=", "4"); RegisterOption("VspKdTree.PostProcess.maxCostRatio", optFloat, "vsp_kd_post_process_max_cost_ratio=", "0.9"); RegisterOption("VspKdTree.PostProcess.minViewCells", optInt, "vsp_kd_term_post_process_min_view_cells=", "1000"); RegisterOption("VspKdTree.Termination.maxViewCells", optInt, "vsp_kd_term_post_process_min_view_cells=", "300"); RegisterOption("VspKdTree.PostProcess.maxPvsSize", optInt, "vsp_kd_term_post_process_max_pvs_size=", "100"); RegisterOption("VspKdTree.Termination.missTolerance", optInt, "vsp_kd_term_miss_tolerance=", "4"); /************************************************************************************/ /* VSS Preprocessor cells related options */ /************************************************************************************/ RegisterOption("VssTree.maxDepth", optInt, "kd_depth=", "12"); RegisterOption("VssTree.minPvs", optInt, "kd_minpvs=", "1"); RegisterOption("VssTree.minRays", optInt, "kd_minrays=", "10"); RegisterOption("VssTree.maxCostRatio", optFloat, "maxcost=", "0.95"); RegisterOption("VssTree.maxRayContribution", optFloat, "maxraycontrib=", "0.5"); RegisterOption("VssTree.epsilon", optFloat, "kd_eps=", "1e-6"); RegisterOption("VssTree.ct_div_ci", optFloat, "kd_ctdivci=", "1.0"); RegisterOption("VssTree.randomize", optBool, "randomize", "false"); RegisterOption("VssTree.splitType", optString, "split=", "queries"); RegisterOption("VssTree.splitUseOnlyDrivingAxis", optBool, "splitdriving=", "false"); RegisterOption("VssTree.useRss", optBool, "rss=", "false"); RegisterOption("VssTree.numberOfEndPointDomains", optInt, "endpoints=", "10000"); RegisterOption("VssTree.minSize", optFloat, "minsize=", "0.001"); RegisterOption("VssTree.maxTotalMemory", optFloat, "mem=", "60.0"); RegisterOption("VssTree.maxStaticMemory", optFloat, "statmem=", "8.0"); RegisterOption("VssTree.queryType", optString, "qtype=", "static"); RegisterOption("VssTree.queryPosWeight", optFloat, "qposweight=", "0.0"); RegisterOption("VssTree.useRefDirSplits", optBool, "refdir", "false"); RegisterOption("VssTree.refDirAngle", optFloat, "refangle=", "10"); RegisterOption("VssTree.refDirBoxMaxSize", optFloat, "refboxsize=", "0.1"); RegisterOption("VssTree.accessTimeThreshold", optInt, "accesstime=", "1000"); RegisterOption("VssTree.minCollapseDepth", optInt, "colldepth=", "4"); RegisterOption("VssTree.interleaveDirSplits", optBool, "interleavedirsplits", "true"); RegisterOption("VssTree.dirSplitDepth", optInt, "dirsplidepth=", "10"); RegisterOption("RssPreprocessor.initialSamples", optInt, "initial_samples=", "100000"); RegisterOption("RssPreprocessor.vssSamples", optInt, "rss_vss_samples=", "1000000"); RegisterOption("RssPreprocessor.vssSamplesPerPass", optInt, "rss_vss_samples_per_pass=", "1000"); RegisterOption("RssPreprocessor.samplesPerPass", optInt, "rss_samples_per_pass=", "100000"); RegisterOption("RssPreprocessor.useImportanceSampling", optBool, "rss_use_importance", "true"); RegisterOption("RssPreprocessor.objectBasedSampling", optBool, "rss_object_based_sampling", "true"); RegisterOption("RssPreprocessor.directionalSampling", optBool, "rss_directional_sampling", "false"); RegisterOption("RssTree.maxDepth", optInt, "kd_depth=", "12"); RegisterOption("RssTree.minPvs", optInt, "kd_minpvs=", "1"); RegisterOption("RssTree.minRays", optInt, "kd_minrays=", "10"); RegisterOption("RssTree.maxCostRatio", optFloat, "maxcost=", "0.95"); RegisterOption("RssTree.maxRayContribution", optFloat, "maxraycontrib=", "0.5"); RegisterOption("RssTree.epsilon", optFloat, "kd_eps=", "1e-6"); RegisterOption("RssTree.ct_div_ci", optFloat, "kd_ctdivci=", "1.0"); RegisterOption("RssTree.randomize", optBool, "randomize", "false"); RegisterOption("RssTree.splitType", optString, "split=", "queries"); RegisterOption("RssTree.splitUseOnlyDrivingAxis", optBool, "splitdriving=", "false"); RegisterOption("RssTree.numberOfEndPointDomains", optInt, "endpoints=", "10000"); RegisterOption("RssTree.minSize", optFloat, "minsize=", "0.001"); RegisterOption("RssTree.maxTotalMemory", optFloat, "mem=", "60.0"); RegisterOption("RssTree.maxStaticMemory", optFloat, "statmem=", "8.0"); RegisterOption("RssTree.queryType", optString, "qtype=", "static"); RegisterOption("RssTree.queryPosWeight", optFloat, "qposweight=", "0.0"); RegisterOption("RssTree.useRefDirSplits", optBool, "refdir", "false"); RegisterOption("RssTree.refDirAngle", optFloat, "refangle=", "10"); RegisterOption("RssTree.refDirBoxMaxSize", optFloat, "refboxsize=", "0.1"); RegisterOption("RssTree.accessTimeThreshold", optInt, "accesstime=", "1000"); RegisterOption("RssTree.minCollapseDepth", optInt, "colldepth=", "4"); RegisterOption("RssTree.interleaveDirSplits", optBool, "interleavedirsplits", "true"); RegisterOption("RssTree.dirSplitDepth", optInt, "dirsplidepth=", "10"); RegisterOption("RssTree.importanceBasedCost", optBool, "importance_based_cost", "true"); RegisterOption("RssTree.maxRays", optInt, "rss_max_rays=", "2000000"); RegisterOption("RssTree.perObjectTree", optBool, "rss_per_object_tree", "false"); RegisterOption("RssPreprocessor.Export.pvs", optBool, "rss_export_pvs", "false"); RegisterOption("RssPreprocessor.Export.rssTree", optBool, "rss_export_rss_tree", "false"); RegisterOption("RssPreprocessor.Export.rays", optBool, "rss_export_rays", "false"); RegisterOption("RssPreprocessor.Export.numRays", optInt, "rss_export_num_rays=", "5000"); RegisterOption("RssPreprocessor.useViewcells", optBool, "rss_use_viewcells", "false"); RegisterOption("RssPreprocessor.updateSubdivision", optBool, "rss_update_subdivision", "false"); /************************************************************************************/ /* View space partition BSP tree related options */ /************************************************************************************/ RegisterOption("RssPreprocessor.loadInitialSamples", optBool, "vss_load_loadInitialSamples=", "false"); RegisterOption("RssPreprocessor.storeInitialSamples", optBool, "vss_store_storeInitialSamples=", "false"); /************************************************************************************/ /* View space partition BSP tree related options */ /************************************************************************************/ RegisterOption("VspBspTree.Termination.minGlobalCostRatio", optFloat, "vsp_bsp_term_min_global_cost_ratio", "0.0001"); RegisterOption("VspBspTree.useSplitCostQueue", optBool, "vsp_bsp_use_split_cost_queue=", "true"); RegisterOption("VspBspTree.Termination.globalCostMissTolerance", optInt, "vsp_bsp_term_global_cost_miss_tolerance", "4"); RegisterOption("VspBspTree.Termination.minPolygons", optInt, "vsp_bsp_term_min_polygons=", "5"); RegisterOption("VspBspTree.Termination.minPvs", optInt, "vsp_bsp_term_min_pvs=", "20"); RegisterOption("VspBspTree.Termination.minProbability", optFloat, "vsp_bsp_term_min_probability=", "0.001"); RegisterOption("VspBspTree.subdivisionStats", optString, "vsp_bsp_subdivision_stats=", "vspBspSubdivisionStats.log"); RegisterOption("VspBspTree.Termination.maxRayContribution", optFloat, "vsp_bsp_term_ray_contribution=", "0.005"); RegisterOption("VspBspTree.Termination.minAccRayLenght", optFloat, "vsp_bsp_term_min_acc_ray_length=", "50"); RegisterOption("VspBspTree.Termination.minRays", optInt, "vsp_bsp_term_min_rays=", "-1"); RegisterOption("VspBspTree.Termination.ct_div_ci", optFloat, "vsp_bsp_term_ct_div_ci=", "0.0"); RegisterOption("VspBspTree.Termination.maxDepth", optInt, "vsp_bsp_term_max_depth=", "100"); RegisterOption("VspBspTree.Termination.AxisAligned.maxCostRatio", optFloat, "vsp_bsp_term_axis_aligned_max_cost_ratio=", "1.5"); RegisterOption("VspBspTree.useCostHeuristics", optBool, "vsp_bsp_use_cost_heuristics=", "false"); RegisterOption("VspBspTree.Termination.maxViewCells", optInt, "vsp_bsp_term_max_view_cells=", "10000"); RegisterOption("VspBspTree.Termination.maxCostRatio", optFloat, "vsp_bsp_term_max_cost_ratio=", "1.5"); RegisterOption("VspBspTree.Termination.missTolerance", optInt, "vsp_bsp_term_miss_tolerance=", "4"); RegisterOption("VspBspTree.splitPlaneStrategy", optString, "vsp_bsp_split_method=", "leastSplits"); RegisterOption("VspBspTree.maxPolyCandidates", optInt, "vsp_bsp_max_poly_candidates=", "20"); RegisterOption("VspBspTree.maxRayCandidates", optInt, "vsp_bsp_max_plane_candidates=", "20"); RegisterOption("VspBspTree.maxTests", optInt, "vsp_bsp_max_tests=", "5000"); RegisterOption("VspBspTree.Construction.samples", optInt, "vsp_bsp_construction_samples=", "100000"); RegisterOption("VspBspTree.Construction.minBand", optFloat, "vsp_bsp_construction_min_band=", "0.1"); RegisterOption("VspBspTree.Construction.maxBand", optFloat, "vsp_bsp_construction_min_band=", "0.9"); RegisterOption("VspBspTree.Construction.useDrivingAxisForMaxCost", optBool, "vsp_bsp_construction_use_drivingaxis_for_maxcost=", "false"); RegisterOption("VspBspTree.Construction.epsilon", optFloat, "vsp_bsp_construction_side_tolerance=", "0.002"); RegisterOption("VspBspTree.Visualization.exportSplits", optBool, "vsp_bsp_visualization.export_splits", "false"); RegisterOption("VspBspTree.splitUseOnlyDrivingAxis", optBool, "vsp_bsp_split_only_driving_axis=", "false"); RegisterOption("VspBspTree.usePolygonSplitIfAvailable", optBool, "vsp_bsp_usePolygonSplitIfAvailable=", "false"); RegisterOption("VspBspTree.Termination.AxisAligned.minRays", optInt, "bsp_term_axis_aligned_min_rays=", "100"); RegisterOption("VspBspTree.Termination.AxisAligned.maxRayContribution", optFloat, "bsp_term_axis_aligned_min_rays=", "0.1"); RegisterOption("VspBspTree.Factor.leastRaySplits", optFloat, "vsp_bsp_factor_least_ray_splits=", "1.0"); RegisterOption("VspBspTree.Factor.balancedRays", optFloat, "vsp_bsp_factor_balanced_rays=", "1.0"); RegisterOption("VspBspTree.Factor.pvs", optFloat, "vsp_bsp_factor_pvs=", "1.0"); RegisterOption("VspBspTree.Construction.renderCostWeight", optFloat, "-vsp_bsp_post_process_render_cost_weight", "0.5"); RegisterOption("VspBspTree.Construction.randomize", optBool, "vsp_bsp_construction_randomize=", "false"); RegisterOption("VspBspTree.simulateOctree", optBool, "vsp_bsp_simulate_octree=", "false"); RegisterOption("VspBspTree.nodePriorityQueueType", optInt, "vsp_bsp_node_queue_type=", "0"); RegisterOption("VspBspTree.useRandomAxis", optBool, "-vsp_bsp_use_random_axis=", "false"); RegisterOption("VspBspTree.maxTotalMemory", optFloat, "vsp_bsp_max_total_mem=", "60.0"); RegisterOption("VspBspTree.maxStaticMemory", optFloat, "vsp_bsp_max_static_mem=", "8.0"); ////////////////////////////////////////////////////////////////////////////////// } void Environment::SetStaticOptions() { // get Global option values GetRealValue("Limits.threshold", Limits::Threshold); GetRealValue("Limits.small", Limits::Small); GetRealValue("Limits.infinity", Limits::Infinity); } void Environment::Parse(const int argc, char **argv, bool useExePath) { // Read the names of the scene, environment and output files ReadCmdlineParams(argc, argv, ""); char *envFilename = new char[128]; char filename[64]; // Get the environment file name if (!GetParam(' ', 0, filename)) { // user didn't specified environment file explicitly, so strcpy(filename, "default.env"); } if (useExePath) { char *path = GetPath(argv[0]); if (*path != 0) sprintf(envFilename, "%s/%s", path, filename); else strcpy(envFilename, filename); delete path; } else strcpy(envFilename, filename); // Now it's time to read in environment file. if (!ReadEnvFile(envFilename)) { // error - bad input file name specified ? cerr<<"Error parsing environment file "<