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
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
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
00200
00201
00202 xmlNode * child = node->children;
00203
00204
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