Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

scenesettingswrapper.cpp

Go to the documentation of this file.
00001 /*
00002     toxic - A Global Illumination Renderer
00003     Copyright (C) 2003-2004 Francois Beaune
00004     Contact: http://toxicengine.sourceforge.net/
00005 
00006     This file is part of toxic.
00007 
00008     toxic is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012 
00013     toxic is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016     GNU General Public License for more details.
00017 
00018     You should have received a copy of the GNU General Public License
00019     along with toxic; if not, write to the Free Software
00020     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 */
00022 
00023 #include "scenesettingswrapper.h"   // include first
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         // <Rendering>
00064         prefix.Push("/Rendering");
00065 
00066         // <Rendering> <PixelSampling>
00067         prefix.Push("/PixelSampling");
00068 
00069         if(f.Count(prefix() + "/Supersampling") > 0) {
00070             // <Rendering> <PixelSampling> <Supersampling>
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             // <Rendering> <PixelSampling> <WhittedAdaptiveSampling>
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         // <Rendering> <Components>
00087         prefix.Push("/Components");
00088 
00089         if(f.Count(prefix() + "/DirectLighting") > 0) {
00090             // <Rendering> <Components> <DirectLighting>
00091             prefix.Push("/DirectLighting");
00092             m_rendering.m_components.m_direct_lighting.m_enabled = true;
00093 
00094             // <Rendering> <Components> <DirectLighting> <ArealightSampling>
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             // <Rendering> <Components> <IndirectLighting>
00104             prefix.Push("/IndirectLighting");
00105             m_rendering.m_components.m_indirect_lighting.m_enabled = true;
00106 
00107             // <Rendering> <Components> <IndirectLighting> <PhotonTracing>
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                 // <Rendering> <Components> <IndirectLighting> <RadiancePrecomputation>
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             // <Rendering> <Components> <IndirectLighting> <RadianceEstimate>
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                 // <Rendering> <Components> <IndirectLighting> <PrimaryFinalGathering>
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                 // <Rendering> <Components> <IndirectLighting> <SecondaryFinalGathering>
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             // <Rendering> <Components> <SpecularReflections>
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             // <Rendering> <Components> <Caustics>
00157             prefix.Push("/Caustics");
00158             m_rendering.m_components.m_caustics.m_enabled = true;
00159 
00160             // <Rendering> <Components> <Caustics> <PhotonTracing>
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             // <Rendering> <Components> <Caustics> <RadianceEstimate>
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();   // <Components>
00175 
00176         prefix.Pop();   // <Rendering>
00177 
00178         // <Output>
00179         prefix.Push("/Output");
00180 
00181         if(f.Count(prefix() + "/RenderArea") > 0) {
00182             // <Output> <RenderArea>
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             // <Output> <GammaCorrection>
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();   // <Output>
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>";    // keep the compiler happy
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     // <Rendering>
00285     s << indenter() << "Rendering" << endl;
00286     indenter.Indent();
00287 
00288     // <Rendering> <PixelSampling>
00289     s << indenter() << "Pixel Sampling" << endl;
00290     switch(m_rendering.m_pixel_sampling.m_algorithm) {
00291     case Rendering::PixelSampling::SUPERSAMPLING:
00292         // <Rendering> <PixelSampling> <Supersampling>
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         // <Rendering> <PixelSampling> <WhittedAdaptiveSampling>
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     // <Rendering> <Components>
00313     s << indenter() << "Components" << endl;
00314     indenter.Indent();
00315 
00316     if(m_rendering.m_components.m_direct_lighting.m_enabled) {
00317         // <Rendering> <Components> <DirectLighting>
00318         s << indenter() << "+ Direct Lighting" << endl;
00319         indenter.Indent(4);
00320 
00321         // <Rendering> <Components> <DirectLighting> <ArealightSampling>
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         // <Rendering> <Components> <IndirectLighting>
00334         s << indenter() << "+ Indirect Lighting" << endl;
00335         indenter.Indent(4);
00336 
00337         // <Rendering> <Components> <IndirectLighting> <PhotonTracing>
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             // <Rendering> <Components> <IndirectLighting> <RadiancePrecomputation>
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         // <Rendering> <Components> <IndirectLighting> <RadianceEstimate>
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             // <Rendering> <Components> <IndirectLighting> <PrimaryFinalGathering>
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             // <Rendering> <Components> <IndirectLighting> <SecondaryFinalGathering>
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         // <Rendering> <Components> <SpecularReflections>
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         // <Rendering> <Components> <Caustics>
00409         s << indenter() << "+ Caustics" << endl;
00410         indenter.Indent(4);
00411 
00412         // <Rendering> <Components> <Caustics> <PhotonTracing>
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         // <Rendering> <Components> <Caustics> <RadianceEstimate>
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     // <Output>
00439     s << indenter() << "Output" << endl;
00440     indenter.Indent();
00441 
00442     if(m_output.m_render_area.m_enabled) {
00443         // <Output> <RenderArea>
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         // <Output> <GammaCorrection>
00454         s << indenter() << "Gamma Correction: "
00455             << m_output.m_gamma_correction.m_target_gamma
00456             << endl;
00457     }
00458 
00459     indenter.Unindent();
00460 }

Generated on Tue May 11 01:31:52 2004 for toxic by doxygen 1.3.6