00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "scenesettingswrapper.h"
00024 #include "common/misc/stringutils.h"
00025 #include "common/misc/xmlconfigfile.h"
00026 #include "error.h"
00027 #include "helpers.h"
00028
00029 #include <cassert>
00030 #include <cstdlib>
00031
00032 using namespace sheep;
00033 using namespace std;
00034 using namespace toxic;
00035
00036 namespace {
00037 void LoadSamplingSettings(const XMLConfigFile &f,
00038 const string &prefix,
00039 Settings::SamplingSettings *ss)
00040 {
00041 if(f.Count(prefix + "/RandomSampling") > 0) {
00042 ss->m_algorithm = Settings::SamplingSettings::RANDOM_SAMPLING;
00043 ss->m_random_sampling.m_samples = f.GetValue<int>(prefix + "/RandomSampling/@samples");
00044 } else if(f.Count(prefix + "/RegularSampling") > 0) {
00045 ss->m_algorithm = Settings::SamplingSettings::REGULAR_SAMPLING;
00046 ss->m_regular_sampling.m_width = f.GetValue<int>(prefix + "/RegularSampling/@width");
00047 ss->m_regular_sampling.m_height = f.GetValue<int>(prefix + "/RegularSampling/@height");
00048 } else if(f.Count(prefix + "/StratifiedSampling") > 0) {
00049 ss->m_algorithm = Settings::SamplingSettings::STRATIFIED_SAMPLING;
00050 ss->m_stratified_sampling.m_width = f.GetValue<int>(prefix + "/StratifiedSampling/@width");
00051 ss->m_stratified_sampling.m_height = f.GetValue<int>(prefix + "/StratifiedSampling/@height");
00052 } else {
00053 assert(!"Internal failure.");
00054 }
00055 }
00056 }
00057
00058 void SceneSettingsWrapper::Load(const string &filename, const string &home_path) {
00059 try {
00060 XMLConfigFile f(filename, home_path + "schemas/toxicscene.settings.xsd");
00061 PrefixStack prefix("/ToxicSceneSettings");
00062
00063
00064 prefix.Push("/Rendering");
00065
00066
00067 prefix.Push("/PixelSampling");
00068
00069 if(f.Count(prefix() + "/Supersampling") > 0) {
00070
00071 prefix.Push("/Supersampling");
00072 m_rendering.m_pixel_sampling.m_algorithm = Rendering::PixelSampling::SUPERSAMPLING;
00073 LoadSamplingSettings(f, prefix(), &m_rendering.m_pixel_sampling.m_supersampling);
00074 prefix.Pop();
00075 } else {
00076
00077 prefix.Push("/WhittedAdaptiveSampling");
00078 m_rendering.m_pixel_sampling.m_algorithm = Rendering::PixelSampling::WHITTED_ADAPTIVE_SAMPLING;
00079 m_rendering.m_pixel_sampling.m_whitted_adaptive_sampling.m_contrast_threshold = f.GetValue<Real>(prefix() + "/@contrastthreshold");
00080 m_rendering.m_pixel_sampling.m_whitted_adaptive_sampling.m_max_depth = f.GetValue<int>(prefix() + "/@maxdepth");
00081 prefix.Pop();
00082 }
00083
00084 prefix.Pop();
00085
00086
00087 prefix.Push("/Components");
00088
00089 if(f.Count(prefix() + "/DirectLighting") > 0) {
00090
00091 prefix.Push("/DirectLighting");
00092 m_rendering.m_components.m_direct_lighting.m_enabled = true;
00093
00094
00095 prefix.Push("/ArealightSampling");
00096 LoadSamplingSettings(f, prefix(), &m_rendering.m_components.m_direct_lighting.m_arealight_sampling);
00097 prefix.Pop();
00098
00099 prefix.Pop();
00100 } else m_rendering.m_components.m_direct_lighting.m_enabled = false;
00101
00102 if(f.Count(prefix() + "/IndirectLighting") > 0) {
00103
00104 prefix.Push("/IndirectLighting");
00105 m_rendering.m_components.m_indirect_lighting.m_enabled = true;
00106
00107
00108 prefix.Push("/PhotonTracing");
00109 m_rendering.m_components.m_indirect_lighting.m_photon_tracing.m_photons = f.GetValue<int>(prefix() + "/@photons");
00110 prefix.Pop();
00111
00112 if(f.Count(prefix() + "/RadiancePrecomputation") > 0) {
00113
00114 prefix.Push("/RadiancePrecomputation");
00115 m_rendering.m_components.m_indirect_lighting.m_radiance_precomp.m_enabled = true;
00116 m_rendering.m_components.m_indirect_lighting.m_radiance_precomp.m_spacing = f.GetValue<int>(prefix() + "/@spacing");
00117 m_rendering.m_components.m_indirect_lighting.m_radiance_precomp.m_max_search_dist = f.GetValue<Real>(prefix() + "/@maxsearchdistance");
00118 prefix.Pop();
00119 } else m_rendering.m_components.m_indirect_lighting.m_radiance_precomp.m_enabled = false;
00120
00121
00122 prefix.Push("/RadianceEstimate");
00123 m_rendering.m_components.m_indirect_lighting.m_radiance_est.m_max_photons = f.GetValue<int>(prefix() + "/@maxphotons");
00124 m_rendering.m_components.m_indirect_lighting.m_radiance_est.m_max_distance = f.GetValue<Real>(prefix() + "/@maxdistance");
00125 prefix.Pop();
00126
00127 if(f.Count(prefix() + "/PrimaryFinalGathering") > 0) {
00128
00129 prefix.Push("/PrimaryFinalGathering");
00130 m_rendering.m_components.m_indirect_lighting.m_primary_fg.m_enabled = true;
00131 LoadSamplingSettings(f, prefix(), &m_rendering.m_components.m_indirect_lighting.m_primary_fg);
00132 prefix.Pop();
00133 } else m_rendering.m_components.m_indirect_lighting.m_primary_fg.m_enabled = false;
00134
00135 if(f.Count(prefix() + "/SecondaryFinalGathering") > 0) {
00136
00137 prefix.Push("/SecondaryFinalGathering");
00138 m_rendering.m_components.m_indirect_lighting.m_secondary_fg.m_enabled = true;
00139 m_rendering.m_components.m_indirect_lighting.m_secondary_fg.m_distance_threshold = f.GetValue<Real>(prefix() + "/@distancethreshold");
00140 LoadSamplingSettings(f, prefix(), &m_rendering.m_components.m_indirect_lighting.m_secondary_fg);
00141 prefix.Pop();
00142 } else m_rendering.m_components.m_indirect_lighting.m_secondary_fg.m_enabled = false;
00143
00144 prefix.Pop();
00145 } else m_rendering.m_components.m_indirect_lighting.m_enabled = false;
00146
00147 if(f.Count(prefix() + "/SpecularReflections") > 0) {
00148
00149 prefix.Push("/SpecularReflections");
00150 m_rendering.m_components.m_specular_reflections.m_enabled = true;
00151 m_rendering.m_components.m_specular_reflections.m_max_depth = f.GetValue<int>(prefix() + "/@maxdepth");
00152 prefix.Pop();
00153 } else m_rendering.m_components.m_specular_reflections.m_enabled = false;
00154
00155 if(f.Count(prefix() + "/Caustics") > 0) {
00156
00157 prefix.Push("/Caustics");
00158 m_rendering.m_components.m_caustics.m_enabled = true;
00159
00160
00161 prefix.Push("/PhotonTracing");
00162 m_rendering.m_components.m_caustics.m_photon_tracing.m_photons = f.GetValue<int>(prefix() + "/@photons");
00163 prefix.Pop();
00164
00165
00166 prefix.Push("/RadianceEstimate");
00167 m_rendering.m_components.m_caustics.m_radiance_est.m_max_photons = f.GetValue<int>(prefix() + "/@maxphotons");
00168 m_rendering.m_components.m_caustics.m_radiance_est.m_max_distance = f.GetValue<Real>(prefix() + "/@maxdistance");
00169 prefix.Pop();
00170
00171 prefix.Pop();
00172 } else m_rendering.m_components.m_caustics.m_enabled = false;
00173
00174 prefix.Pop();
00175
00176 prefix.Pop();
00177
00178
00179 prefix.Push("/Output");
00180
00181 if(f.Count(prefix() + "/RenderArea") > 0) {
00182
00183 prefix.Push("/RenderArea");
00184 m_output.m_render_area.m_enabled = true;
00185 m_output.m_render_area.m_x0 = f.GetValue<int>(prefix() + "/@x0");
00186 m_output.m_render_area.m_y0 = f.GetValue<int>(prefix() + "/@y0");
00187 m_output.m_render_area.m_x1 = f.GetValue<int>(prefix() + "/@x1");
00188 m_output.m_render_area.m_y1 = f.GetValue<int>(prefix() + "/@y1");
00189 prefix.Pop();
00190 } else m_output.m_render_area.m_enabled = false;
00191
00192 if(f.Count(prefix() + "/GammaCorrection") > 0) {
00193
00194 prefix.Push("/GammaCorrection");
00195 m_output.m_gamma_correction.m_enabled = true;
00196 m_output.m_gamma_correction.m_target_gamma = f.GetValue<Real>(prefix() + "/@targetgamma");
00197 prefix.Pop();
00198 } else m_output.m_gamma_correction.m_enabled = false;
00199
00200 prefix.Pop();
00201
00202 return;
00203 }
00204 catch(const XMLConfigFile::LoadErrorException &e) {
00205 cerr << Error << e.m_message << endl;
00206 }
00207 catch(...) {}
00208
00209 cerr << Error << "Could not load the settings file '" << filename << "'." << endl;
00210 exit(EXIT_FAILURE);
00211 }
00212
00213 void SceneSettingsWrapper::CheckConsistency() const {
00214 if(!IsConsistent()) {
00215 cerr << Error << "Scene settings are not valid." << endl;
00216 exit(EXIT_FAILURE);
00217 }
00218 }
00219
00220 namespace {
00221 string GetSamplingAlgorithmName(const Settings::SamplingSettings *ss) {
00222 switch(ss->m_algorithm) {
00223 case Settings::SamplingSettings::RANDOM_SAMPLING:
00224 return "random sampling";
00225 case Settings::SamplingSettings::REGULAR_SAMPLING:
00226 return "regular sampling";
00227 case Settings::SamplingSettings::STRATIFIED_SAMPLING:
00228 return "stratified sampling";
00229 default:
00230 assert(!"Internal failure.");
00231 return "<Internal failure>";
00232 }
00233 }
00234
00235 void PrintSamplingSettings(ostream &s,
00236 Indenter &indenter,
00237 const Settings::SamplingSettings *ss)
00238 {
00239 indenter.Indent();
00240
00241 s << indenter() << "Algorithm: "
00242 << GetSamplingAlgorithmName(ss)
00243 << endl;
00244
00245 s << indenter();
00246
00247 switch(ss->m_algorithm) {
00248 case Settings::SamplingSettings::RANDOM_SAMPLING:
00249 s << "Samples: "
00250 << ConvertNumberToString(ss->m_random_sampling.m_samples);
00251 break;
00252 case Settings::SamplingSettings::REGULAR_SAMPLING:
00253 {
00254 const int w = ss->m_regular_sampling.m_width;
00255 const int h = ss->m_regular_sampling.m_height;
00256 s << "Grid: "
00257 << ConvertNumberToString(w) << "x" << ConvertNumberToString(h)
00258 << " (" << ConvertNumberToString(w * h) << " samples)";
00259 }
00260 break;
00261 case Settings::SamplingSettings::STRATIFIED_SAMPLING:
00262 {
00263 const int w = ss->m_stratified_sampling.m_width;
00264 const int h = ss->m_stratified_sampling.m_height;
00265 s << "Grid: "
00266 << ConvertNumberToString(w) << "x" << ConvertNumberToString(h)
00267 << " (" << ConvertNumberToString(w * h) << " samples)";
00268 }
00269 break;
00270 }
00271
00272 s << endl;
00273
00274 indenter.Unindent();
00275 }
00276 }
00277
00278 void SceneSettingsWrapper::Print(ostream &s) const {
00279 Indenter indenter;
00280
00281 s << indenter() << "Scene Settings:" << endl;
00282 indenter.Indent();
00283
00284
00285 s << indenter() << "Rendering" << endl;
00286 indenter.Indent();
00287
00288
00289 s << indenter() << "Pixel Sampling" << endl;
00290 switch(m_rendering.m_pixel_sampling.m_algorithm) {
00291 case Rendering::PixelSampling::SUPERSAMPLING:
00292
00293 PrintSamplingSettings(
00294 s,
00295 indenter,
00296 &m_rendering.m_pixel_sampling.m_supersampling
00297 );
00298 break;
00299 case Rendering::PixelSampling::WHITTED_ADAPTIVE_SAMPLING:
00300
00301 indenter.Indent();
00302 s << indenter() << "Algorithm: Whitted adaptive sampling" << endl;
00303 s << indenter() << "Contrast Threshold: "
00304 << m_rendering.m_pixel_sampling.m_whitted_adaptive_sampling.m_contrast_threshold
00305 << endl;
00306 s << indenter() << "Maximum Depth: "
00307 << ConvertNumberToString(m_rendering.m_pixel_sampling.m_whitted_adaptive_sampling.m_max_depth)
00308 << endl;
00309 indenter.Unindent();
00310 }
00311
00312
00313 s << indenter() << "Components" << endl;
00314 indenter.Indent();
00315
00316 if(m_rendering.m_components.m_direct_lighting.m_enabled) {
00317
00318 s << indenter() << "+ Direct Lighting" << endl;
00319 indenter.Indent(4);
00320
00321
00322 s << indenter() << "Arealight Sampling" << endl;
00323 PrintSamplingSettings(
00324 s,
00325 indenter,
00326 &m_rendering.m_components.m_direct_lighting.m_arealight_sampling
00327 );
00328
00329 indenter.Unindent();
00330 }
00331
00332 if(m_rendering.m_components.m_indirect_lighting.m_enabled) {
00333
00334 s << indenter() << "+ Indirect Lighting" << endl;
00335 indenter.Indent(4);
00336
00337
00338 s << indenter() << "Photon Tracing" << endl;
00339 indenter.Indent();
00340 s << indenter() << "Photons: "
00341 << ConvertNumberToString(m_rendering.m_components.m_indirect_lighting.m_photon_tracing.m_photons)
00342 << endl;
00343 indenter.Unindent();
00344
00345 if(m_rendering.m_components.m_indirect_lighting.m_radiance_precomp.m_enabled) {
00346
00347 s << indenter() << "Radiance Precomputation" << endl;
00348 indenter.Indent();
00349 s << indenter() << "Spacing: "
00350 << ConvertNumberToString(m_rendering.m_components.m_indirect_lighting.m_radiance_precomp.m_spacing)
00351 << endl;
00352 s << indenter() << "Maximum Search Distance: "
00353 << m_rendering.m_components.m_indirect_lighting.m_radiance_precomp.m_max_search_dist
00354 << endl;
00355 indenter.Unindent();
00356 }
00357
00358
00359 s << indenter() << "Radiance Estimate" << endl;
00360 indenter.Indent();
00361 s << indenter() << "Maximum Photons: "
00362 << ConvertNumberToString(m_rendering.m_components.m_indirect_lighting.m_radiance_est.m_max_photons)
00363 << endl;
00364 s << indenter() << "Maximum Distance: "
00365 << m_rendering.m_components.m_indirect_lighting.m_radiance_est.m_max_distance
00366 << endl;
00367 indenter.Unindent();
00368
00369 if(m_rendering.m_components.m_indirect_lighting.m_primary_fg.m_enabled) {
00370
00371 s << indenter() << "Primary Final Gathering" << endl;
00372 PrintSamplingSettings(
00373 s,
00374 indenter,
00375 &m_rendering.m_components.m_indirect_lighting.m_primary_fg
00376 );
00377 }
00378
00379 if(m_rendering.m_components.m_indirect_lighting.m_secondary_fg.m_enabled) {
00380
00381 s << indenter() << "Secondary Final Gathering" << endl;
00382 indenter.Indent();
00383 s << indenter() << "Distance Threshold: "
00384 << m_rendering.m_components.m_indirect_lighting.m_secondary_fg.m_distance_threshold
00385 << endl;
00386 indenter.Unindent();
00387 PrintSamplingSettings(
00388 s,
00389 indenter,
00390 &m_rendering.m_components.m_indirect_lighting.m_secondary_fg
00391 );
00392 }
00393
00394 indenter.Unindent();
00395 }
00396
00397 if(m_rendering.m_components.m_specular_reflections.m_enabled) {
00398
00399 s << indenter() << "+ Specular Reflections" << endl;
00400 indenter.Indent(4);
00401 s << indenter() << "Maximum Depth: "
00402 << ConvertNumberToString(m_rendering.m_components.m_specular_reflections.m_max_depth)
00403 << endl;
00404 indenter.Unindent();
00405 }
00406
00407 if(m_rendering.m_components.m_caustics.m_enabled) {
00408
00409 s << indenter() << "+ Caustics" << endl;
00410 indenter.Indent(4);
00411
00412
00413 s << indenter() << "Photon Tracing" << endl;
00414 indenter.Indent();
00415 s << indenter() << "Photons: "
00416 << ConvertNumberToString(m_rendering.m_components.m_caustics.m_photon_tracing.m_photons)
00417 << endl;
00418 indenter.Unindent();
00419
00420
00421 s << indenter() << "Radiance Estimate" << endl;
00422 indenter.Indent();
00423 s << indenter() << "Maximum Photons: "
00424 << ConvertNumberToString(m_rendering.m_components.m_caustics.m_radiance_est.m_max_photons)
00425 << endl;
00426 s << indenter() << "Maximum Distance: "
00427 << m_rendering.m_components.m_caustics.m_radiance_est.m_max_distance
00428 << endl;
00429 indenter.Unindent();
00430
00431 indenter.Unindent();
00432 }
00433
00434 indenter.Unindent();
00435
00436 indenter.Unindent();
00437
00438
00439 s << indenter() << "Output" << endl;
00440 indenter.Indent();
00441
00442 if(m_output.m_render_area.m_enabled) {
00443
00444 s << indenter() << "Render Area: ("
00445 << m_output.m_render_area.m_x0 << ','
00446 << m_output.m_render_area.m_y0 << ") to ("
00447 << m_output.m_render_area.m_x1 << ','
00448 << m_output.m_render_area.m_y1 << ')'
00449 << endl;
00450 }
00451
00452 if(m_output.m_gamma_correction.m_enabled) {
00453
00454 s << indenter() << "Gamma Correction: "
00455 << m_output.m_gamma_correction.m_target_gamma
00456 << endl;
00457 }
00458
00459 indenter.Unindent();
00460 }