2 * Copyright 2011, Blender Foundation.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
28 #include "integrator.h"
36 #include "subd_mesh.h"
37 #include "subd_patch.h"
38 #include "subd_split.h"
40 #include "util_debug.h"
41 #include "util_foreach.h"
42 #include "util_path.h"
43 #include "util_transform.h"
46 #include "cycles_xml.h"
50 /* XML reading state */
53 Scene *scene; /* scene pointer */
54 Transform tfm; /* current transform state */
55 bool smooth; /* smooth normal state */
56 int shader; /* current shader */
57 string base; /* base path to current file*/
58 float dicing_rate; /* current dicing rate */
59 Mesh::DisplacementMethod displacement_method;
62 /* Attribute Reading */
64 static bool xml_read_bool(bool *value, pugi::xml_node node, const char *name)
66 pugi::xml_attribute attr = node.attribute(name);
69 *value = (string_iequals(attr.value(), "true")) || (atoi(attr.value()) != 0);
76 static bool xml_read_int(int *value, pugi::xml_node node, const char *name)
78 pugi::xml_attribute attr = node.attribute(name);
81 *value = atoi(attr.value());
88 static bool xml_read_int_array(vector<int>& value, pugi::xml_node node, const char *name)
90 pugi::xml_attribute attr = node.attribute(name);
93 vector<string> tokens;
94 string_split(tokens, attr.value());
96 foreach(const string& token, tokens)
97 value.push_back(atoi(token.c_str()));
105 static bool xml_read_float(float *value, pugi::xml_node node, const char *name)
107 pugi::xml_attribute attr = node.attribute(name);
110 *value = atof(attr.value());
117 static bool xml_read_float_array(vector<float>& value, pugi::xml_node node, const char *name)
119 pugi::xml_attribute attr = node.attribute(name);
122 vector<string> tokens;
123 string_split(tokens, attr.value());
125 foreach(const string& token, tokens)
126 value.push_back(atof(token.c_str()));
134 static bool xml_read_float3(float3 *value, pugi::xml_node node, const char *name)
138 if(xml_read_float_array(array, node, name) && array.size() == 3) {
139 *value = make_float3(array[0], array[1], array[2]);
146 static bool xml_read_float3_array(vector<float3>& value, pugi::xml_node node, const char *name)
150 if(xml_read_float_array(array, node, name)) {
151 for(size_t i = 0; i < array.size(); i += 3)
152 value.push_back(make_float3(array[i+0], array[i+1], array[i+2]));
160 static bool xml_read_float4(float4 *value, pugi::xml_node node, const char *name)
164 if(xml_read_float_array(array, node, name) && array.size() == 4) {
165 *value = make_float4(array[0], array[1], array[2], array[3]);
172 static bool xml_read_string(string *str, pugi::xml_node node, const char *name)
174 pugi::xml_attribute attr = node.attribute(name);
184 static bool xml_read_ustring(ustring *str, pugi::xml_node node, const char *name)
186 pugi::xml_attribute attr = node.attribute(name);
189 *str = ustring(attr.value());
196 static bool xml_equal_string(pugi::xml_node node, const char *name, const char *value)
198 pugi::xml_attribute attr = node.attribute(name);
201 return string_iequals(attr.value(), value);
206 static bool xml_read_enum(ustring *str, ShaderEnum& enm, pugi::xml_node node, const char *name)
208 pugi::xml_attribute attr = node.attribute(name);
211 ustring ustr(attr.value());
213 if(enm.exists(ustr)) {
218 fprintf(stderr, "Unknown value \"%s\" for attribute \"%s\".\n", ustr.c_str(), name);
226 static void xml_read_film(const XMLReadState& state, pugi::xml_node node)
228 Camera *cam = state.scene->camera;
230 xml_read_int(&cam->width, node, "width");
231 xml_read_int(&cam->height, node, "height");
233 float aspect = (float)cam->width/(float)cam->height;
235 if(cam->width >= cam->height) {
244 cam->bottom = -1.0f/aspect;
245 cam->top = 1.0f/aspect;
248 cam->need_update = true;
254 static void xml_read_integrator(const XMLReadState& state, pugi::xml_node node)
256 Integrator *integrator = state.scene->integrator;
258 xml_read_int(&integrator->min_bounce, node, "min_bounce");
259 xml_read_int(&integrator->max_bounce, node, "max_bounce");
260 xml_read_bool(&integrator->no_caustics, node, "no_caustics");
261 xml_read_float(&integrator->blur_caustics, node, "blur_caustics");
266 static void xml_read_camera(const XMLReadState& state, pugi::xml_node node)
268 Camera *cam = state.scene->camera;
270 if(xml_read_float(&cam->fov, node, "fov"))
271 cam->fov *= M_PI/180.0f;
273 xml_read_float(&cam->nearclip, node, "nearclip");
274 xml_read_float(&cam->farclip, node, "farclip");
275 xml_read_float(&cam->aperturesize, node, "aperturesize"); // 0.5*focallength/fstop
276 xml_read_float(&cam->focaldistance, node, "focaldistance");
277 xml_read_float(&cam->shutteropen, node, "shutteropen");
278 xml_read_float(&cam->shutterclose, node, "shutterclose");
280 if(xml_equal_string(node, "type", "orthographic"))
282 else if(xml_equal_string(node, "type", "perspective"))
285 cam->matrix = state.tfm;
287 cam->need_update = true;
293 static string xml_socket_name(const char *name)
298 while((i = sname.find(" ")) != string::npos)
299 sname.replace(i, 1, "");
304 static void xml_read_shader_graph(const XMLReadState& state, Shader *shader, pugi::xml_node graph_node)
306 ShaderGraph *graph = new ShaderGraph();
308 map<string, ShaderNode*> nodemap;
310 nodemap["output"] = graph->output();
312 for(pugi::xml_node node = graph_node.first_child(); node; node = node.next_sibling()) {
313 ShaderNode *snode = NULL;
315 if(string_iequals(node.name(), "image_texture")) {
316 ImageTextureNode *img = new ImageTextureNode();
318 xml_read_string(&img->filename, node, "src");
319 img->filename = path_join(state.base, img->filename);
323 else if(string_iequals(node.name(), "environment_texture")) {
324 EnvironmentTextureNode *env = new EnvironmentTextureNode();
326 xml_read_string(&env->filename, node, "src");
327 env->filename = path_join(state.base, env->filename);
331 else if(string_iequals(node.name(), "sky_texture")) {
332 SkyTextureNode *sky = new SkyTextureNode();
334 xml_read_float3(&sky->sun_direction, node, "sun_direction");
335 xml_read_float(&sky->turbidity, node, "turbidity");
339 else if(string_iequals(node.name(), "noise_texture")) {
340 snode = new NoiseTextureNode();
342 else if(string_iequals(node.name(), "blend_texture")) {
343 BlendTextureNode *blend = new BlendTextureNode();
344 xml_read_enum(&blend->progression, BlendTextureNode::progression_enum, node, "progression");
345 xml_read_enum(&blend->axis, BlendTextureNode::axis_enum, node, "axis");
348 else if(string_iequals(node.name(), "clouds_texture")) {
349 CloudsTextureNode *clouds = new CloudsTextureNode();
350 xml_read_bool(&clouds->hard, node, "hard");
351 xml_read_int(&clouds->depth, node, "depth");
352 xml_read_enum(&clouds->basis, CloudsTextureNode::basis_enum, node, "basis");
355 else if(string_iequals(node.name(), "voronoi_texture")) {
356 VoronoiTextureNode *voronoi = new VoronoiTextureNode();
357 xml_read_enum(&voronoi->distance_metric, VoronoiTextureNode::distance_metric_enum, node, "distance_metric");
358 xml_read_enum(&voronoi->coloring, VoronoiTextureNode::coloring_enum, node, "coloring");
361 else if(string_iequals(node.name(), "musgrave_texture")) {
362 MusgraveTextureNode *musgrave = new MusgraveTextureNode();
363 xml_read_enum(&musgrave->type, MusgraveTextureNode::type_enum, node, "type");
364 xml_read_enum(&musgrave->basis, MusgraveTextureNode::basis_enum, node, "basis");
367 else if(string_iequals(node.name(), "marble_texture")) {
368 MarbleTextureNode *marble = new MarbleTextureNode();
369 xml_read_enum(&marble->type, MarbleTextureNode::type_enum, node, "type");
370 xml_read_enum(&marble->wave, MarbleTextureNode::wave_enum, node, "wave");
371 xml_read_enum(&marble->basis, MarbleTextureNode::basis_enum, node, "basis");
372 xml_read_bool(&marble->hard, node, "hard");
373 xml_read_int(&marble->depth, node, "depth");
376 else if(string_iequals(node.name(), "magic_texture")) {
377 MagicTextureNode *magic = new MagicTextureNode();
378 xml_read_int(&magic->depth, node, "depth");
381 else if(string_iequals(node.name(), "stucci_texture")) {
382 StucciTextureNode *stucci = new StucciTextureNode();
383 xml_read_enum(&stucci->type, StucciTextureNode::type_enum, node, "type");
384 xml_read_enum(&stucci->basis, StucciTextureNode::basis_enum, node, "basis");
385 xml_read_bool(&stucci->hard, node, "hard");
388 else if(string_iequals(node.name(), "distorted_noise_texture")) {
389 DistortedNoiseTextureNode *dist = new DistortedNoiseTextureNode();
390 xml_read_enum(&dist->basis, DistortedNoiseTextureNode::basis_enum, node, "basis");
391 xml_read_enum(&dist->distortion_basis, DistortedNoiseTextureNode::basis_enum, node, "distortion_basis");
394 else if(string_iequals(node.name(), "wood_texture")) {
395 WoodTextureNode *wood = new WoodTextureNode();
396 xml_read_enum(&wood->type, WoodTextureNode::type_enum, node, "type");
397 xml_read_enum(&wood->wave, WoodTextureNode::wave_enum, node, "wave");
398 xml_read_enum(&wood->basis, WoodTextureNode::basis_enum, node, "basis");
399 xml_read_bool(&wood->hard, node, "hard");
402 else if(string_iequals(node.name(), "mapping")) {
403 snode = new MappingNode();
405 else if(string_iequals(node.name(), "ward_bsdf")) {
406 snode = new WardBsdfNode();
408 else if(string_iequals(node.name(), "diffuse_bsdf")) {
409 snode = new DiffuseBsdfNode();
411 else if(string_iequals(node.name(), "translucent_bsdf")) {
412 snode = new TranslucentBsdfNode();
414 else if(string_iequals(node.name(), "transparent_bsdf")) {
415 snode = new TransparentBsdfNode();
417 else if(string_iequals(node.name(), "velvet_bsdf")) {
418 snode = new VelvetBsdfNode();
420 else if(string_iequals(node.name(), "glossy_bsdf")) {
421 GlossyBsdfNode *glossy = new GlossyBsdfNode();
422 xml_read_enum(&glossy->distribution, GlossyBsdfNode::distribution_enum, node, "distribution");
425 else if(string_iequals(node.name(), "glass_bsdf")) {
426 GlassBsdfNode *diel = new GlassBsdfNode();
427 xml_read_enum(&diel->distribution, GlassBsdfNode::distribution_enum, node, "distribution");
430 else if(string_iequals(node.name(), "emission")) {
431 EmissionNode *emission = new EmissionNode();
432 xml_read_bool(&emission->total_power, node, "total_power");
435 else if(string_iequals(node.name(), "background")) {
436 snode = new BackgroundNode();
438 else if(string_iequals(node.name(), "transparent_volume")) {
439 snode = new TransparentVolumeNode();
441 else if(string_iequals(node.name(), "isotropic_volume")) {
442 snode = new IsotropicVolumeNode();
444 else if(string_iequals(node.name(), "geometry")) {
445 snode = new GeometryNode();
447 else if(string_iequals(node.name(), "texture_coordinate")) {
448 snode = new TextureCoordinateNode();
450 else if(string_iequals(node.name(), "lightPath")) {
451 snode = new LightPathNode();
453 else if(string_iequals(node.name(), "value")) {
454 ValueNode *value = new ValueNode();
455 xml_read_float(&value->value, node, "value");
458 else if(string_iequals(node.name(), "color")) {
459 ColorNode *color = new ColorNode();
460 xml_read_float3(&color->value, node, "value");
463 else if(string_iequals(node.name(), "mix_closure")) {
464 snode = new MixClosureNode();
466 else if(string_iequals(node.name(), "add_closure")) {
467 snode = new AddClosureNode();
469 else if(string_iequals(node.name(), "mix")) {
470 MixNode *mix = new MixNode();
471 xml_read_enum(&mix->type, MixNode::type_enum, node, "type");
474 else if(string_iequals(node.name(), "combine_rgb")) {
475 snode = new CombineRGBNode();
477 else if(string_iequals(node.name(), "separate_rgb")) {
478 snode = new SeparateRGBNode();
480 else if(string_iequals(node.name(), "attribute")) {
481 AttributeNode *attr = new AttributeNode();
482 xml_read_ustring(&attr->attribute, node, "attribute");
485 else if(string_iequals(node.name(), "fresnel")) {
486 snode = new FresnelNode();
488 else if(string_iequals(node.name(), "math")) {
489 MathNode *math = new MathNode();
490 xml_read_enum(&math->type, MathNode::type_enum, node, "type");
493 else if(string_iequals(node.name(), "vector_math")) {
494 VectorMathNode *vmath = new VectorMathNode();
495 xml_read_enum(&vmath->type, VectorMathNode::type_enum, node, "type");
498 else if(string_iequals(node.name(), "connect")) {
500 vector<string> from_tokens, to_tokens;
502 string_split(from_tokens, node.attribute("from").value());
503 string_split(to_tokens, node.attribute("to").value());
505 if(from_tokens.size() == 2 && to_tokens.size() == 2) {
506 /* find nodes and sockets */
507 ShaderOutput *output = NULL;
508 ShaderInput *input = NULL;
510 if(nodemap.find(from_tokens[0]) != nodemap.end()) {
511 ShaderNode *fromnode = nodemap[from_tokens[0]];
513 foreach(ShaderOutput *out, fromnode->outputs)
514 if(string_iequals(xml_socket_name(out->name), from_tokens[1]))
518 fprintf(stderr, "Unknown output socket name \"%s\" on \"%s\".\n", from_tokens[1].c_str(), from_tokens[0].c_str());
521 fprintf(stderr, "Unknown shader node name \"%s\".\n", from_tokens[0].c_str());
523 if(nodemap.find(to_tokens[0]) != nodemap.end()) {
524 ShaderNode *tonode = nodemap[to_tokens[0]];
526 foreach(ShaderInput *in, tonode->inputs)
527 if(string_iequals(xml_socket_name(in->name), to_tokens[1]))
531 fprintf(stderr, "Unknown input socket name \"%s\" on \"%s\".\n", to_tokens[1].c_str(), to_tokens[0].c_str());
534 fprintf(stderr, "Unknown shader node name \"%s\".\n", to_tokens[0].c_str());
538 graph->connect(output, input);
541 fprintf(stderr, "Invalid from or to value for connect node.\n");
544 fprintf(stderr, "Unknown shader node \"%s\".\n", node.name());
550 /* add to map for name lookups */
552 xml_read_string(&name, node, "name");
554 nodemap[name] = snode;
556 /* read input values */
557 for(pugi::xml_attribute attr = node.first_attribute(); attr; attr = attr.next_attribute()) {
558 foreach(ShaderInput *in, snode->inputs) {
559 if(string_iequals(in->name, attr.name())) {
561 case SHADER_SOCKET_FLOAT:
562 xml_read_float(&in->value.x, node, attr.name());
564 case SHADER_SOCKET_COLOR:
565 case SHADER_SOCKET_VECTOR:
566 case SHADER_SOCKET_POINT:
567 case SHADER_SOCKET_NORMAL:
568 xml_read_float3(&in->value, node, attr.name());
579 shader->set_graph(graph);
580 shader->tag_update(state.scene);
583 static void xml_read_shader(const XMLReadState& state, pugi::xml_node node)
585 Shader *shader = new Shader();
586 xml_read_string(&shader->name, node, "name");
587 xml_read_shader_graph(state, shader, node);
588 state.scene->shaders.push_back(shader);
593 static void xml_read_background(const XMLReadState& state, pugi::xml_node node)
595 Shader *shader = state.scene->shaders[state.scene->default_background];
597 xml_read_shader_graph(state, shader, node);
602 static Mesh *xml_add_mesh(Scene *scene, const Transform& tfm)
605 Mesh *mesh = new Mesh();
606 scene->meshes.push_back(mesh);
609 Object *object = new Object();
612 scene->objects.push_back(object);
617 static void xml_read_mesh(const XMLReadState& state, pugi::xml_node node)
620 Mesh *mesh = xml_add_mesh(state.scene, state.tfm);
621 mesh->used_shaders.push_back(state.shader);
624 int shader = state.shader;
625 bool smooth = state.smooth;
627 mesh->displacement_method = state.displacement_method;
629 /* read vertices and polygons, RIB style */
631 vector<int> verts, nverts;
633 xml_read_float3_array(P, node, "P");
634 xml_read_int_array(verts, node, "verts");
635 xml_read_int_array(nverts, node, "nverts");
637 if(xml_equal_string(node, "subdivision", "catmull-clark")) {
638 /* create subd mesh */
641 /* create subd vertices */
642 for(size_t i = 0; i < P.size(); i++)
643 sdmesh.add_vert(P[i]);
645 /* create subd faces */
646 int index_offset = 0;
648 for(size_t i = 0; i < nverts.size(); i++) {
650 int v0 = verts[index_offset + 0];
651 int v1 = verts[index_offset + 1];
652 int v2 = verts[index_offset + 2];
653 int v3 = verts[index_offset + 3];
655 sdmesh.add_face(v0, v1, v2, v3);
658 for(int j = 0; j < nverts[i]-2; j++) {
659 int v0 = verts[index_offset];
660 int v1 = verts[index_offset + j + 1];
661 int v2 = verts[index_offset + j + 2];;
663 sdmesh.add_face(v0, v1, v2);
667 index_offset += nverts[i];
670 /* finalize subd mesh */
671 sdmesh.link_boundary();
675 //dsplit.camera = state.scene->camera;
676 //dsplit.dicing_rate = 5.0f;
677 dsplit.dicing_rate = state.dicing_rate;
678 xml_read_float(&dsplit.dicing_rate, node, "dicing_rate");
679 sdmesh.tesselate(&dsplit, false, mesh, shader, smooth);
682 /* create vertices */
685 /* create triangles */
686 int index_offset = 0;
688 for(size_t i = 0; i < nverts.size(); i++) {
689 for(int j = 0; j < nverts[i]-2; j++) {
690 int v0 = verts[index_offset];
691 int v1 = verts[index_offset + j + 1];
692 int v2 = verts[index_offset + j + 2];
694 assert(v0 < (int)P.size());
695 assert(v1 < (int)P.size());
696 assert(v2 < (int)P.size());
698 mesh->add_triangle(v0, v1, v2, shader, smooth);
701 index_offset += nverts[i];
705 /* temporary for test compatibility */
706 mesh->attributes.remove(Attribute::STD_VERTEX_NORMAL);
711 static void xml_read_patch(const XMLReadState& state, pugi::xml_node node)
717 xml_read_float3_array(P, node, "P");
719 if(xml_equal_string(node, "type", "bilinear")) {
722 LinearQuadPatch *bpatch = new LinearQuadPatch();
724 for(int i = 0; i < 4; i++)
725 P[i] = transform(&state.tfm, P[i]);
726 memcpy(bpatch->hull, &P[0], sizeof(bpatch->hull));
731 fprintf(stderr, "Invalid number of control points for bilinear patch.\n");
733 else if(xml_equal_string(node, "type", "bicubic")) {
736 BicubicPatch *bpatch = new BicubicPatch();
738 for(int i = 0; i < 16; i++)
739 P[i] = transform(&state.tfm, P[i]);
740 memcpy(bpatch->hull, &P[0], sizeof(bpatch->hull));
745 fprintf(stderr, "Invalid number of control points for bicubic patch.\n");
748 fprintf(stderr, "Unknown patch type.\n");
752 Mesh *mesh = xml_add_mesh(state.scene, transform_identity());
754 mesh->used_shaders.push_back(state.shader);
758 //dsplit.camera = state.scene->camera;
759 //dsplit.dicing_rate = 5.0f;
760 dsplit.dicing_rate = state.dicing_rate;
761 xml_read_float(&dsplit.dicing_rate, node, "dicing_rate");
762 dsplit.split_quad(mesh, patch, state.shader, state.smooth);
766 /* temporary for test compatibility */
767 mesh->attributes.remove(Attribute::STD_VERTEX_NORMAL);
773 static void xml_read_light(const XMLReadState& state, pugi::xml_node node)
775 Light *light = new Light();
776 light->shader = state.shader;
777 xml_read_float3(&light->co, node, "P");
778 light->co = transform(&state.tfm, light->co);
780 state.scene->lights.push_back(light);
785 static void xml_read_transform(pugi::xml_node node, Transform& tfm)
787 if(node.attribute("matrix")) {
788 vector<float> matrix;
789 if(xml_read_float_array(matrix, node, "matrix") && matrix.size() == 16)
790 tfm = tfm * transform_transpose((*(Transform*)&matrix[0]));
793 if(node.attribute("translate")) {
794 float3 translate = make_float3(0.0f, 0.0f, 0.0f);
795 xml_read_float3(&translate, node, "translate");
796 tfm = tfm * transform_translate(translate);
799 if(node.attribute("rotate")) {
800 float4 rotate = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
801 xml_read_float4(&rotate, node, "rotate");
802 tfm = tfm * transform_rotate(rotate.x*M_PI/180.0f, make_float3(rotate.y, rotate.z, rotate.w));
805 if(node.attribute("scale")) {
806 float3 scale = make_float3(0.0f, 0.0f, 0.0f);
807 xml_read_float3(&scale, node, "scale");
808 tfm = tfm * transform_scale(scale);
814 static void xml_read_state(XMLReadState& state, pugi::xml_node node)
819 if(xml_read_string(&shadername, node, "shader")) {
823 foreach(Shader *shader, state.scene->shaders) {
824 if(shader->name == shadername) {
834 fprintf(stderr, "Unknown shader \"%s\".\n", shadername.c_str());
837 xml_read_float(&state.dicing_rate, node, "dicing_rate");
839 /* read smooth/flat */
840 if(xml_equal_string(node, "interpolation", "smooth"))
842 else if(xml_equal_string(node, "interpolation", "flat"))
843 state.smooth = false;
845 /* read displacement method */
846 if(xml_equal_string(node, "displacement_method", "true"))
847 state.displacement_method = Mesh::DISPLACE_TRUE;
848 else if(xml_equal_string(node, "displacement_method", "bump"))
849 state.displacement_method = Mesh::DISPLACE_BUMP;
850 else if(xml_equal_string(node, "displacement_method", "both"))
851 state.displacement_method = Mesh::DISPLACE_BOTH;
856 static void xml_read_include(const XMLReadState& state, const string& src);
858 static void xml_read_scene(const XMLReadState& state, pugi::xml_node scene_node)
860 for(pugi::xml_node node = scene_node.first_child(); node; node = node.next_sibling()) {
861 if(string_iequals(node.name(), "film")) {
862 xml_read_film(state, node);
864 else if(string_iequals(node.name(), "integrator")) {
865 xml_read_integrator(state, node);
867 else if(string_iequals(node.name(), "camera")) {
868 xml_read_camera(state, node);
870 else if(string_iequals(node.name(), "shader")) {
871 xml_read_shader(state, node);
873 else if(string_iequals(node.name(), "background")) {
874 xml_read_background(state, node);
876 else if(string_iequals(node.name(), "mesh")) {
877 xml_read_mesh(state, node);
879 else if(string_iequals(node.name(), "patch")) {
880 xml_read_patch(state, node);
882 else if(string_iequals(node.name(), "light")) {
883 xml_read_light(state, node);
885 else if(string_iequals(node.name(), "transform")) {
886 XMLReadState substate = state;
888 xml_read_transform(node, substate.tfm);
889 xml_read_scene(substate, node);
891 else if(string_iequals(node.name(), "state")) {
892 XMLReadState substate = state;
894 xml_read_state(substate, node);
895 xml_read_scene(substate, node);
897 else if(string_iequals(node.name(), "include")) {
900 if(xml_read_string(&src, node, "src"))
901 xml_read_include(state, src);
904 fprintf(stderr, "Unknown node \"%s\".\n", node.name());
910 static void xml_read_include(const XMLReadState& state, const string& src)
912 /* open XML document */
913 pugi::xml_document doc;
914 pugi::xml_parse_result parse_result;
916 string path = path_join(state.base, src);
917 parse_result = doc.load_file(path.c_str());
920 XMLReadState substate = state;
921 substate.base = path_dirname(path);
923 xml_read_scene(substate, doc);
926 fprintf(stderr, "%s read error: %s\n", src.c_str(), parse_result.description());
931 void xml_read_file(Scene *scene, const char *filepath)
936 state.tfm = transform_identity();
937 state.shader = scene->default_surface;
938 state.smooth = false;
939 state.dicing_rate = 0.1f;
940 state.base = path_dirname(filepath);
942 xml_read_include(state, path_filename(filepath));
944 scene->params.bvh_type = SceneParams::BVH_STATIC;