sceneparser.cpp

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 #include "sceneparser.h"
00007 #include "renderable.h"
00008 #include "scene.h"
00009 #include "xml_util.h"
00010 #include "raytrace_defs.h"
00011 
00012 #include "pluginfactory.h"
00013 
00014 #include <iostream>
00015 
00016 using std::map;
00017 using std::vector;
00018 using std::string;
00019 using Magick::Color;
00020 using Magick::ColorRGB;
00021 
00022 //{{{
00023 SceneParser::SceneParser(string scene_filename)
00024     : m_node_handlers(),
00025       m_scene_filename(scene_filename)
00026 
00027 {
00028     log_debug("SceneParser()\n");
00029     register_default_handlers();
00030 
00031     log_debug("%s\n", m_scene_filename.c_str());
00032     xmlDoc * doc = xmlReadFile(m_scene_filename.c_str(), NULL, 0);
00033 
00034     if ( doc == NULL ) {
00035         log_err("Could not read and parse %s!\n", m_scene_filename.c_str());
00036         exit_mbrt(EXIT_FAILURE);
00037     }
00038 
00039     xmlNode * root = xmlDocGetRootElement(doc);
00040     if ( root == NULL ) {
00041         log_err("Could not find root element in file %s!\n", m_scene_filename.c_str());
00042         exit_mbrt(EXIT_FAILURE);
00043     }
00044     parse(root);
00045 
00046     xmlFreeDoc(doc);
00047     xmlCleanupParser();
00048     log_debug("End SceneParser()\n");
00049 }
00050 //}}}
00051 
00052 //{{{
00053 void SceneParser::register_default_handlers() {
00054     m_node_handlers["meta"         ].connect(sigc::mem_fun(this, &SceneParser::parse_meta));
00055     m_node_handlers["camera"       ].connect(sigc::mem_fun(this, &SceneParser::parse_camera));
00056     m_node_handlers["light_sources"].connect(sigc::mem_fun(this, &SceneParser::parse_light_sources));
00057     m_node_handlers["objects"      ].connect(sigc::mem_fun(this, &SceneParser::parse_objects));
00058     m_node_handlers["materials"    ].connect(sigc::mem_fun(this, &SceneParser::parse_materials));
00059     m_node_handlers["bumpmaps"     ].connect(sigc::mem_fun(this, &SceneParser::parse_bumpmaps));
00060 }
00061 //}}}
00062 //{{{
00063 Renderable * SceneParser::parse_materials(Scene * scene, xmlNode * node) {
00064     xmlNode * child = node->children;
00065 
00066     // Parse all materials
00067     while(child != node->last) {
00068         if(strcmp((char *)child->name, "material") == 0) {
00069             map<string, string> props = get_properties(child);
00070 
00071             if ( props.empty() == false ) {
00072                 Material * material = MaterialFactory::get_instance()->create(props["type"], props);
00073                 if(material == NULL)
00074                 {
00075                     log_crit("Material of type '%s' unknown!\n", props["type"].c_str());
00076                     exit_mbrt(EXIT_FAILURE);
00077                 }
00078 
00079                 scene->add_material(props["name"], material);
00080             }
00081         }
00082 
00083         child = child->next;
00084     }
00085 
00086     return NULL;
00087 }
00088 //}}}
00089 //{{{
00090 Renderable * SceneParser::noop(Scene * scene, xmlNode * node) {
00091     return NULL;
00092 }
00093 //}}}
00094 //{{{
00095 Renderable * SceneParser::parse_objects(Scene * scene, xmlNode * node) {
00096     xmlNode * child = node->children;
00097 
00098     // Parse all objects.
00099     while(child != node->last) {
00100         log_debug("Renderable of type '%s'.\n", child->name);
00101         Renderable * prim = RenderableFactory::get_instance()->create((char *)child->name, child);
00102         if(prim == NULL) {
00103             log_warn("Renderable of type '%s' unknown...Skipping!\n", child->name);
00104         }
00105         else {
00106             prim->initialize(child);
00107             scene->add_primitive(prim);
00108         }
00109 
00110         child = child->next;
00111     }
00112 
00113     return NULL;
00114 }
00115 //}}}
00116 //{{{
00117 Renderable * SceneParser::parse_meta(Scene * scene, xmlNode * node) {
00118     log_debug("Entering SceneParser::parse_meta()\n");
00119 
00120     xmlNode * child = node->children;
00121     while(child != node->last) {
00122         map<string, string> props = get_properties(child);
00123 
00124         if(strcmp((char *)child->name, "width") == 0) {
00125             scene->set_pixel_width(strtol(props["pixels"].c_str(), NULL, 0));
00126         }
00127         else if(strcmp((char *)child->name, "height") == 0) {
00128             scene->set_pixel_height(strtol(props["pixels"].c_str(), NULL, 0));
00129         }
00130         else if(strcmp((char *)child->name, "file") == 0) {
00131             scene->set_output_filename(props["name"]);
00132         }
00133         else if(strcmp((char *)child->name, "subpixels") == 0) {
00134             scene->set_subpixel_sqrt(strtol(props["square_of"].c_str(), NULL, 0));
00135         }
00136         else if(strcmp((char *)child->name, "recurse") == 0) {
00137             scene->set_max_recurse_depth(strtol(props["max_depth"].c_str(), NULL, 0));
00138         }
00139 
00140         child = child->next;
00141     }
00142 
00143     log_debug("Leaving SceneParser::parse_meta()\n");
00144     return NULL;
00145 }
00146 //}}}
00147 //{{{
00148 Renderable * SceneParser::parse_camera(Scene * scene, xmlNode * node) {
00149     log_debug("Entering SceneParser::parse_camera()\n");
00150     map<string, string> props = get_properties(node);
00151     if(props.find("location") != props.end()) {
00152         Point3D coords(props["location"]);
00153         scene->set_camera(coords.x, coords.y, coords.z);
00154         log_debug("(%f, %f, %f)", coords.x, coords.y, coords.z);
00155     }
00156     else {
00157         scene->set_camera((double)strtod(props["x"].c_str(), NULL),
00158                           (double)strtod(props["y"].c_str(), NULL),
00159                           (double)strtod(props["z"].c_str(), NULL));
00160 
00161         log_debug("(%f, %f, %f)", (double)strtod(props["x"].c_str(), NULL),
00162                                   (double)strtod(props["y"].c_str(), NULL),
00163                                   (double)strtod(props["z"].c_str(), NULL));
00164     }
00165 
00166     log_debug("Leaving SceneParser::parse_camera()\n");
00167     return NULL;
00168 }
00169 //}}}
00170 //{{{
00171 Renderable * SceneParser::parse_light_sources(Scene * scene, xmlNode * node) {
00172     log_debug("Entering SceneParser::parse_light_sources()\n");
00174     xmlNode * child = node->children;
00175 
00176     child = node->children;
00177     while(child != node->last) {
00178         log_debug("Renderable of type '%s'\n", child->name);
00179         Renderable * prim = RenderableFactory::get_instance()->create((char *)child->name, child);
00180         if(prim == NULL) {
00181             log_warn("Renderable of type '%s' unknown...Skipping!\n", child->name);
00182         }
00183         else {
00184 
00185             prim->initialize(child);
00186             prim->set_is_light(true);
00187             scene->add_primitive(prim);
00188         }
00189 
00190         child = child->next;
00191     }
00192 
00193     log_debug("Leaving SceneParser::parse_light_sources()\n");
00194     return NULL;
00195 }
00196 //}}}
00197 //{{{
00198 Renderable * SceneParser::parse_bumpmaps(Scene * scene, xmlNode * node) {
00199     // This function was copy/paste/modify two things
00200     // Sounds like a candidate for refactoring.
00201     
00202     xmlNode * child = node->children;
00203 
00204     // Parse all objects.
00205     while(child != node->last) {
00206         if(strcmp((char *)child->name, "bumpmap") == 0) 
00207         {
00208             map<string, string> props = get_properties(child);
00209             string type = props["type"];
00210             log_debug("BumpMap of type '%s'.\n", type.c_str());
00211             BumpMap * bmap = BumpMapFactory::get_instance()->create(type, child);
00212         if(bmap == NULL) {
00213                 log_warn("BumpMap of type '%s' unknown...Skipping!\n", type.c_str());
00214         }
00215         else {
00216                 scene->add_bumpmap((char *)(type.c_str()), bmap);
00217             }
00218         }
00219 
00220         child = child->next;
00221     }
00222 
00223     return NULL;
00224 }
00225 //}}}
00226 //{{{
00227 void SceneParser::parse(xmlNode * node) {
00228     log_debug("Entering SceneParser::parse()\n");
00229 
00230     if(strcmp((char *)node->name, "scene") == 0) {
00231         Scene * scene        = Scene::get_instance();
00232         xmlNode * child      = node->children;
00233        
00234         while(child != node->last) {
00235             if(m_node_handlers.find((char *)child->name) != m_node_handlers.end()) {
00236                 m_node_handlers[(char *)child->name].emit(scene, child);
00237             }
00238             else {
00239                 log_warn("Cannot parse <%s> nodes.  Skipping...", child->name);
00240             }
00241 
00242             child = child->next;
00243         }
00244 
00245         log_info("==================== DONE PARSING XML ==========================");
00246     }
00247     else {
00248         log_err("Expecting <scene> node, but got <%s>.", node->name);
00249     }
00250 
00251     log_debug("Leaving SceneParser::parse()\n");
00252 }
00253 //}}}
00254 

Generated on Tue Oct 30 22:12:15 2007 for mbrt by  doxygen 1.5.2