Integer socket support in Cycles. Int values are already supported natively in OSL...
[blender.git] / intern / cycles / app / cycles_xml.cpp
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
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.
8  *
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.
13  *
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.
17  */
18
19 #include <stdio.h>
20
21 #include <sstream>
22 #include <algorithm>
23 #include <iterator>
24
25 #include "camera.h"
26 #include "film.h"
27 #include "graph.h"
28 #include "integrator.h"
29 #include "light.h"
30 #include "mesh.h"
31 #include "nodes.h"
32 #include "object.h"
33 #include "shader.h"
34 #include "scene.h"
35
36 #include "subd_mesh.h"
37 #include "subd_patch.h"
38 #include "subd_split.h"
39
40 #include "util_debug.h"
41 #include "util_foreach.h"
42 #include "util_path.h"
43 #include "util_transform.h"
44 #include "util_xml.h"
45
46 #include "cycles_xml.h"
47
48 CCL_NAMESPACE_BEGIN
49
50 /* XML reading state */
51
52 struct XMLReadState {
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;
60 };
61
62 /* Attribute Reading */
63
64 static bool xml_read_bool(bool *value, pugi::xml_node node, const char *name)
65 {
66         pugi::xml_attribute attr = node.attribute(name);
67
68         if(attr) {
69                 *value = (string_iequals(attr.value(), "true")) || (atoi(attr.value()) != 0);
70                 return true;
71         }
72
73         return false;
74 }
75
76 static bool xml_read_int(int *value, pugi::xml_node node, const char *name)
77 {
78         pugi::xml_attribute attr = node.attribute(name);
79
80         if(attr) {
81                 *value = atoi(attr.value());
82                 return true;
83         }
84
85         return false;
86 }
87
88 static bool xml_read_int_array(vector<int>& value, pugi::xml_node node, const char *name)
89 {
90         pugi::xml_attribute attr = node.attribute(name);
91
92         if(attr) {
93                 vector<string> tokens;
94                 string_split(tokens, attr.value());
95
96                 foreach(const string& token, tokens)
97                         value.push_back(atoi(token.c_str()));
98
99                 return true;
100         }
101
102         return false;
103 }
104
105 static bool xml_read_float(float *value, pugi::xml_node node, const char *name)
106 {
107         pugi::xml_attribute attr = node.attribute(name);
108
109         if(attr) {
110                 *value = atof(attr.value());
111                 return true;
112         }
113
114         return false;
115 }
116
117 static bool xml_read_float_array(vector<float>& value, pugi::xml_node node, const char *name)
118 {
119         pugi::xml_attribute attr = node.attribute(name);
120
121         if(attr) {
122                 vector<string> tokens;
123                 string_split(tokens, attr.value());
124
125                 foreach(const string& token, tokens)
126                         value.push_back(atof(token.c_str()));
127
128                 return true;
129         }
130
131         return false;
132 }
133
134 static bool xml_read_float3(float3 *value, pugi::xml_node node, const char *name)
135 {
136         vector<float> array;
137
138         if(xml_read_float_array(array, node, name) && array.size() == 3) {
139                 *value = make_float3(array[0], array[1], array[2]);
140                 return true;
141         }
142
143         return false;
144 }
145
146 static bool xml_read_float3_array(vector<float3>& value, pugi::xml_node node, const char *name)
147 {
148         vector<float> array;
149
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]));
153
154                 return true;
155         }
156
157         return false;
158 }
159
160 static bool xml_read_float4(float4 *value, pugi::xml_node node, const char *name)
161 {
162         vector<float> array;
163
164         if(xml_read_float_array(array, node, name) && array.size() == 4) {
165                 *value = make_float4(array[0], array[1], array[2], array[3]);
166                 return true;
167         }
168
169         return false;
170 }
171
172 static bool xml_read_string(string *str, pugi::xml_node node, const char *name)
173 {
174         pugi::xml_attribute attr = node.attribute(name);
175
176         if(attr) {
177                 *str = attr.value();
178                 return true;
179         }
180
181         return false;
182 }
183
184 static bool xml_read_ustring(ustring *str, pugi::xml_node node, const char *name)
185 {
186         pugi::xml_attribute attr = node.attribute(name);
187
188         if(attr) {
189                 *str = ustring(attr.value());
190                 return true;
191         }
192
193         return false;
194 }
195
196 static bool xml_equal_string(pugi::xml_node node, const char *name, const char *value)
197 {
198         pugi::xml_attribute attr = node.attribute(name);
199
200         if(attr)
201                 return string_iequals(attr.value(), value);
202         
203         return false;
204 }
205
206 static bool xml_read_enum(ustring *str, ShaderEnum& enm, pugi::xml_node node, const char *name)
207 {
208         pugi::xml_attribute attr = node.attribute(name);
209
210         if(attr) {
211                 ustring ustr(attr.value());
212
213                 if(enm.exists(ustr)) {
214                         *str = ustr;
215                         return true;
216                 }
217                 else
218                         fprintf(stderr, "Unknown value \"%s\" for attribute \"%s\".\n", ustr.c_str(), name);
219         }
220
221         return false;
222 }
223
224 /* Film */
225
226 static void xml_read_film(const XMLReadState& state, pugi::xml_node node)
227 {
228         Camera *cam = state.scene->camera;
229
230         xml_read_int(&cam->width, node, "width");
231         xml_read_int(&cam->height, node, "height");
232
233         float aspect = (float)cam->width/(float)cam->height;
234
235         if(cam->width >= cam->height) {
236                 cam->left = -aspect;
237                 cam->right = aspect;
238                 cam->bottom = -1.0f;
239                 cam->top = 1.0f;
240         }
241         else {
242                 cam->left = -1.0f;
243                 cam->right = 1.0f;
244                 cam->bottom = -1.0f/aspect;
245                 cam->top = 1.0f/aspect;
246         }
247
248         cam->need_update = true;
249         cam->update();
250 }
251
252 /* Integrator */
253
254 static void xml_read_integrator(const XMLReadState& state, pugi::xml_node node)
255 {
256         Integrator *integrator = state.scene->integrator;
257         
258         xml_read_bool(&integrator->progressive, node, "progressive");
259         
260         if(!integrator->progressive) {
261                 xml_read_int(&integrator->diffuse_samples, node, "diffuse_samples");
262                 xml_read_int(&integrator->glossy_samples, node, "glossy_samples");
263                 xml_read_int(&integrator->transmission_samples, node, "transmission_samples");
264                 xml_read_int(&integrator->ao_samples, node, "ao_samples");
265                 xml_read_int(&integrator->mesh_light_samples, node, "mesh_light_samples");
266         }
267
268         xml_read_int(&integrator->min_bounce, node, "min_bounce");
269         xml_read_int(&integrator->max_bounce, node, "max_bounce");
270         
271         xml_read_int(&integrator->max_diffuse_bounce, node, "max_diffuse_bounce");
272         xml_read_int(&integrator->max_glossy_bounce, node, "max_glossy_bounce");
273         xml_read_int(&integrator->max_transmission_bounce, node, "max_transmission_bounce");
274         
275         xml_read_int(&integrator->transparent_min_bounce, node, "transparent_min_bounce");
276         xml_read_int(&integrator->transparent_max_bounce, node, "transparent_max_bounce");
277         
278         xml_read_bool(&integrator->transparent_shadows, node, "transparent_shadows");
279         xml_read_bool(&integrator->no_caustics, node, "no_caustics");
280         xml_read_float(&integrator->filter_glossy, node, "blur_glossy");
281         
282         xml_read_int(&integrator->seed, node, "seed");
283         xml_read_float(&integrator->sample_clamp, node, "sample_clamp");
284 }
285
286 /* Camera */
287
288 static void xml_read_camera(const XMLReadState& state, pugi::xml_node node)
289 {
290         Camera *cam = state.scene->camera;
291
292         if(xml_read_float(&cam->fov, node, "fov"))
293                 cam->fov *= M_PI/180.0f;
294
295         xml_read_float(&cam->nearclip, node, "nearclip");
296         xml_read_float(&cam->farclip, node, "farclip");
297         xml_read_float(&cam->aperturesize, node, "aperturesize"); // 0.5*focallength/fstop
298         xml_read_float(&cam->focaldistance, node, "focaldistance");
299         xml_read_float(&cam->shuttertime, node, "shuttertime");
300
301         if(xml_equal_string(node, "type", "orthographic"))
302                 cam->type = CAMERA_ORTHOGRAPHIC;
303         else if(xml_equal_string(node, "type", "perspective"))
304                 cam->type = CAMERA_PERSPECTIVE;
305         else if(xml_equal_string(node, "type", "panorama"))
306                 cam->type = CAMERA_PANORAMA;
307
308         if(xml_equal_string(node, "panorama_type", "equirectangular"))
309                 cam->panorama_type = PANORAMA_EQUIRECTANGULAR;
310         else if(xml_equal_string(node, "panorama_type", "fisheye_equidistant"))
311                 cam->panorama_type = PANORAMA_FISHEYE_EQUIDISTANT;
312         else if(xml_equal_string(node, "panorama_type", "fisheye_equisolid"))
313                 cam->panorama_type = PANORAMA_FISHEYE_EQUISOLID;
314
315         xml_read_float(&cam->fisheye_fov, node, "fisheye_fov");
316         xml_read_float(&cam->fisheye_lens, node, "fisheye_lens");
317
318         xml_read_float(&cam->sensorwidth, node, "sensorwidth");
319         xml_read_float(&cam->sensorheight, node, "sensorheight");
320
321
322         cam->matrix = state.tfm;
323
324         cam->need_update = true;
325         cam->update();
326 }
327
328 /* Shader */
329
330 static string xml_socket_name(const char *name)
331 {
332         string sname = name;
333         size_t i;
334
335         while((i = sname.find(" ")) != string::npos)
336                 sname.replace(i, 1, "");
337         
338         return sname;
339 }
340
341 static void xml_read_shader_graph(const XMLReadState& state, Shader *shader, pugi::xml_node graph_node)
342 {
343         ShaderGraph *graph = new ShaderGraph();
344
345         map<string, ShaderNode*> nodemap;
346
347         nodemap["output"] = graph->output();
348
349         for(pugi::xml_node node = graph_node.first_child(); node; node = node.next_sibling()) {
350                 ShaderNode *snode = NULL;
351
352                 if(string_iequals(node.name(), "image_texture")) {
353                         ImageTextureNode *img = new ImageTextureNode();
354
355                         xml_read_string(&img->filename, node, "src");
356                         img->filename = path_join(state.base, img->filename);
357
358                         snode = img;
359                 }
360                 else if(string_iequals(node.name(), "environment_texture")) {
361                         EnvironmentTextureNode *env = new EnvironmentTextureNode();
362
363                         xml_read_string(&env->filename, node, "src");
364                         env->filename = path_join(state.base, env->filename);
365
366                         snode = env;
367                 }
368                 else if(string_iequals(node.name(), "sky_texture")) {
369                         SkyTextureNode *sky = new SkyTextureNode();
370
371                         xml_read_float3(&sky->sun_direction, node, "sun_direction");
372                         xml_read_float(&sky->turbidity, node, "turbidity");
373                         
374                         snode = sky;
375                 }
376                 else if(string_iequals(node.name(), "noise_texture")) {
377                         snode = new NoiseTextureNode();
378                 }
379                 else if(string_iequals(node.name(), "checker_texture")) {
380                         snode = new CheckerTextureNode();
381                 }
382                 else if(string_iequals(node.name(), "brick_texture")) {
383                         snode = new BrickTextureNode();
384                 }
385                 else if(string_iequals(node.name(), "gradient_texture")) {
386                         GradientTextureNode *blend = new GradientTextureNode();
387                         xml_read_enum(&blend->type, GradientTextureNode::type_enum, node, "type");
388                         snode = blend;
389                 }
390                 else if(string_iequals(node.name(), "voronoi_texture")) {
391                         VoronoiTextureNode *voronoi = new VoronoiTextureNode();
392                         xml_read_enum(&voronoi->coloring, VoronoiTextureNode::coloring_enum, node, "coloring");
393                         snode = voronoi;
394                 }
395                 else if(string_iequals(node.name(), "musgrave_texture")) {
396                         MusgraveTextureNode *musgrave = new MusgraveTextureNode();
397                         xml_read_enum(&musgrave->type, MusgraveTextureNode::type_enum, node, "type");
398                         snode = musgrave;
399                 }
400                 else if(string_iequals(node.name(), "magic_texture")) {
401                         MagicTextureNode *magic = new MagicTextureNode();
402                         xml_read_int(&magic->depth, node, "depth");
403                         snode = magic;
404                 }
405                 else if(string_iequals(node.name(), "noise_texture")) {
406                         NoiseTextureNode *dist = new NoiseTextureNode();
407                         snode = dist;
408                 }
409                 else if(string_iequals(node.name(), "wave_texture")) {
410                         WaveTextureNode *wave = new WaveTextureNode();
411                         xml_read_enum(&wave->type, WaveTextureNode::type_enum, node, "type");
412                         snode = wave;
413                 }
414                 else if(string_iequals(node.name(), "normal")) {
415                         snode = new NormalNode();
416                 }
417                 else if(string_iequals(node.name(), "mapping")) {
418                         snode = new MappingNode();
419                 }
420                 else if(string_iequals(node.name(), "ward_bsdf")) {
421                         snode = new WardBsdfNode();
422                 }
423                 else if(string_iequals(node.name(), "diffuse_bsdf")) {
424                         snode = new DiffuseBsdfNode();
425                 }
426                 else if(string_iequals(node.name(), "translucent_bsdf")) {
427                         snode = new TranslucentBsdfNode();
428                 }
429                 else if(string_iequals(node.name(), "transparent_bsdf")) {
430                         snode = new TransparentBsdfNode();
431                 }
432                 else if(string_iequals(node.name(), "velvet_bsdf")) {
433                         snode = new VelvetBsdfNode();
434                 }
435                 else if(string_iequals(node.name(), "glossy_bsdf")) {
436                         GlossyBsdfNode *glossy = new GlossyBsdfNode();
437                         xml_read_enum(&glossy->distribution, GlossyBsdfNode::distribution_enum, node, "distribution");
438                         snode = glossy;
439                 }
440                 else if(string_iequals(node.name(), "glass_bsdf")) {
441                         GlassBsdfNode *diel = new GlassBsdfNode();
442                         xml_read_enum(&diel->distribution, GlassBsdfNode::distribution_enum, node, "distribution");
443                         snode = diel;
444                 }
445                 else if(string_iequals(node.name(), "emission")) {
446                         EmissionNode *emission = new EmissionNode();
447                         xml_read_bool(&emission->total_power, node, "total_power");
448                         snode = emission;
449                 }
450                 else if(string_iequals(node.name(), "background")) {
451                         snode = new BackgroundNode();
452                 }
453                 else if(string_iequals(node.name(), "transparent_volume")) {
454                         snode = new TransparentVolumeNode();
455                 }
456                 else if(string_iequals(node.name(), "isotropic_volume")) {
457                         snode = new IsotropicVolumeNode();
458                 }
459                 else if(string_iequals(node.name(), "geometry")) {
460                         snode = new GeometryNode();
461                 }
462                 else if(string_iequals(node.name(), "texture_coordinate")) {
463                         snode = new TextureCoordinateNode();
464                 }
465                 else if(string_iequals(node.name(), "lightPath")) {
466                         snode = new LightPathNode();
467                 }
468                 else if(string_iequals(node.name(), "value")) {
469                         ValueNode *value = new ValueNode();
470                         xml_read_float(&value->value, node, "value");
471                         snode = value;
472                 }
473                 else if(string_iequals(node.name(), "color")) {
474                         ColorNode *color = new ColorNode();
475                         xml_read_float3(&color->value, node, "value");
476                         snode = color;
477                 }
478                 else if(string_iequals(node.name(), "mix_closure")) {
479                         snode = new MixClosureNode();
480                 }
481                 else if(string_iequals(node.name(), "add_closure")) {
482                         snode = new AddClosureNode();
483                 }
484                 else if(string_iequals(node.name(), "invert")) {
485                         snode = new InvertNode();
486                 }
487                 else if(string_iequals(node.name(), "mix")) {
488                         MixNode *mix = new MixNode();
489                         xml_read_enum(&mix->type, MixNode::type_enum, node, "type");
490                         xml_read_bool(&mix->use_clamp, node, "use_clamp");
491                         snode = mix;
492                 }
493                 else if(string_iequals(node.name(), "gamma")) {
494                         snode = new GammaNode();
495                 }
496                 else if(string_iequals(node.name(), "brightness")) {
497                         snode = new BrightContrastNode();
498                 }
499                 else if(string_iequals(node.name(), "combine_rgb")) {
500                         snode = new CombineRGBNode();
501                 }
502                 else if(string_iequals(node.name(), "separate_rgb")) {
503                         snode = new SeparateRGBNode();
504                 }
505                 else if(string_iequals(node.name(), "hsv")) {
506                         snode = new HSVNode();
507                 }
508                 else if(string_iequals(node.name(), "attribute")) {
509                         AttributeNode *attr = new AttributeNode();
510                         xml_read_ustring(&attr->attribute, node, "attribute");
511                         snode = attr;
512                 }
513                 else if(string_iequals(node.name(), "camera")) {
514                         snode = new CameraNode();
515                 }
516                 else if(string_iequals(node.name(), "fresnel")) {
517                         snode = new FresnelNode();
518                 }
519                 else if(string_iequals(node.name(), "math")) {
520                         MathNode *math = new MathNode();
521                         xml_read_enum(&math->type, MathNode::type_enum, node, "type");
522                         xml_read_bool(&math->use_clamp, node, "use_clamp");
523                         snode = math;
524                 }
525                 else if(string_iequals(node.name(), "vector_math")) {
526                         VectorMathNode *vmath = new VectorMathNode();
527                         xml_read_enum(&vmath->type, VectorMathNode::type_enum, node, "type");
528                         snode = vmath;
529                 }
530                 else if(string_iequals(node.name(), "connect")) {
531                         /* connect nodes */
532                         vector<string> from_tokens, to_tokens;
533
534                         string_split(from_tokens, node.attribute("from").value());
535                         string_split(to_tokens, node.attribute("to").value());
536
537                         if(from_tokens.size() == 2 && to_tokens.size() == 2) {
538                                 /* find nodes and sockets */
539                                 ShaderOutput *output = NULL;
540                                 ShaderInput *input = NULL;
541
542                                 if(nodemap.find(from_tokens[0]) != nodemap.end()) {
543                                         ShaderNode *fromnode = nodemap[from_tokens[0]];
544
545                                         foreach(ShaderOutput *out, fromnode->outputs)
546                                                 if(string_iequals(xml_socket_name(out->name), from_tokens[1]))
547                                                         output = out;
548
549                                         if(!output)
550                                                 fprintf(stderr, "Unknown output socket name \"%s\" on \"%s\".\n", from_tokens[1].c_str(), from_tokens[0].c_str());
551                                 }
552                                 else
553                                         fprintf(stderr, "Unknown shader node name \"%s\".\n", from_tokens[0].c_str());
554
555                                 if(nodemap.find(to_tokens[0]) != nodemap.end()) {
556                                         ShaderNode *tonode = nodemap[to_tokens[0]];
557
558                                         foreach(ShaderInput *in, tonode->inputs)
559                                                 if(string_iequals(xml_socket_name(in->name), to_tokens[1]))
560                                                         input = in;
561
562                                         if(!input)
563                                                 fprintf(stderr, "Unknown input socket name \"%s\" on \"%s\".\n", to_tokens[1].c_str(), to_tokens[0].c_str());
564                                 }
565                                 else
566                                         fprintf(stderr, "Unknown shader node name \"%s\".\n", to_tokens[0].c_str());
567
568                                 /* connect */
569                                 if(output && input)
570                                         graph->connect(output, input);
571                         }
572                         else
573                                 fprintf(stderr, "Invalid from or to value for connect node.\n");
574                 }
575                 else
576                         fprintf(stderr, "Unknown shader node \"%s\".\n", node.name());
577
578                 if(snode) {
579                         /* add to graph */
580                         graph->add(snode);
581
582                         /* add to map for name lookups */
583                         string name = "";
584                         xml_read_string(&name, node, "name");
585
586                         nodemap[name] = snode;
587
588                         /* read input values */
589                         for(pugi::xml_attribute attr = node.first_attribute(); attr; attr = attr.next_attribute()) {
590                                 foreach(ShaderInput *in, snode->inputs) {
591                                         if(string_iequals(in->name, attr.name())) {
592                                                 switch(in->type) {
593                                                         case SHADER_SOCKET_FLOAT:
594                                                         case SHADER_SOCKET_INT:
595                                                                 xml_read_float(&in->value.x, node, attr.name());
596                                                                 break;
597                                                         case SHADER_SOCKET_COLOR:
598                                                         case SHADER_SOCKET_VECTOR:
599                                                         case SHADER_SOCKET_POINT:
600                                                         case SHADER_SOCKET_NORMAL:
601                                                                 xml_read_float3(&in->value, node, attr.name());
602                                                                 break;
603                                                         default:
604                                                                 break;
605                                                 }
606                                         }
607                                 }
608                         }
609                 }
610         }
611
612         shader->set_graph(graph);
613         shader->tag_update(state.scene);
614 }
615
616 static void xml_read_shader(const XMLReadState& state, pugi::xml_node node)
617 {
618         Shader *shader = new Shader();
619         xml_read_string(&shader->name, node, "name");
620         xml_read_shader_graph(state, shader, node);
621         state.scene->shaders.push_back(shader);
622 }
623
624 /* Background */
625
626 static void xml_read_background(const XMLReadState& state, pugi::xml_node node)
627 {
628         Shader *shader = state.scene->shaders[state.scene->default_background];
629
630         xml_read_shader_graph(state, shader, node);
631 }
632
633 /* Mesh */
634
635 static Mesh *xml_add_mesh(Scene *scene, const Transform& tfm)
636 {
637         /* create mesh */
638         Mesh *mesh = new Mesh();
639         scene->meshes.push_back(mesh);
640
641         /* create object*/
642         Object *object = new Object();
643         object->mesh = mesh;
644         object->tfm = tfm;
645         scene->objects.push_back(object);
646
647         return mesh;
648 }
649
650 static void xml_read_mesh(const XMLReadState& state, pugi::xml_node node)
651 {
652         /* add mesh */
653         Mesh *mesh = xml_add_mesh(state.scene, state.tfm);
654         mesh->used_shaders.push_back(state.shader);
655
656         /* read state */
657         int shader = state.shader;
658         bool smooth = state.smooth;
659
660         mesh->displacement_method = state.displacement_method;
661
662         /* read vertices and polygons, RIB style */
663         vector<float3> P;
664         vector<int> verts, nverts;
665
666         xml_read_float3_array(P, node, "P");
667         xml_read_int_array(verts, node, "verts");
668         xml_read_int_array(nverts, node, "nverts");
669
670         if(xml_equal_string(node, "subdivision", "catmull-clark")) {
671                 /* create subd mesh */
672                 SubdMesh sdmesh;
673
674                 /* create subd vertices */
675                 for(size_t i = 0; i < P.size(); i++)
676                         sdmesh.add_vert(P[i]);
677
678                 /* create subd faces */
679                 int index_offset = 0;
680
681                 for(size_t i = 0; i < nverts.size(); i++) {
682                         if(nverts[i] == 4) {
683                                 int v0 = verts[index_offset + 0];
684                                 int v1 = verts[index_offset + 1];
685                                 int v2 = verts[index_offset + 2];
686                                 int v3 = verts[index_offset + 3];
687
688                                 sdmesh.add_face(v0, v1, v2, v3);
689                         }
690                         else {
691                                 for(int j = 0; j < nverts[i]-2; j++) {
692                                         int v0 = verts[index_offset];
693                                         int v1 = verts[index_offset + j + 1];
694                                         int v2 = verts[index_offset + j + 2];
695
696                                         sdmesh.add_face(v0, v1, v2);
697                                 }
698                         }
699
700                         index_offset += nverts[i];
701                 }
702
703                 /* finalize subd mesh */
704                 sdmesh.link_boundary();
705
706                 /* subdivide */
707                 DiagSplit dsplit;
708                 //dsplit.camera = state.scene->camera;
709                 //dsplit.dicing_rate = 5.0f;
710                 dsplit.dicing_rate = state.dicing_rate;
711                 xml_read_float(&dsplit.dicing_rate, node, "dicing_rate");
712                 sdmesh.tessellate(&dsplit, false, mesh, shader, smooth);
713         }
714         else {
715                 /* create vertices */
716                 mesh->verts = P;
717
718                 /* create triangles */
719                 int index_offset = 0;
720
721                 for(size_t i = 0; i < nverts.size(); i++) {
722                         for(int j = 0; j < nverts[i]-2; j++) {
723                                 int v0 = verts[index_offset];
724                                 int v1 = verts[index_offset + j + 1];
725                                 int v2 = verts[index_offset + j + 2];
726
727                                 assert(v0 < (int)P.size());
728                                 assert(v1 < (int)P.size());
729                                 assert(v2 < (int)P.size());
730
731                                 mesh->add_triangle(v0, v1, v2, shader, smooth);
732                         }
733
734                         index_offset += nverts[i];
735                 }
736         }
737
738         /* temporary for test compatibility */
739         mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
740 }
741
742 /* Patch */
743
744 static void xml_read_patch(const XMLReadState& state, pugi::xml_node node)
745 {
746         /* read patch */
747         Patch *patch = NULL;
748
749         vector<float3> P;
750         xml_read_float3_array(P, node, "P");
751
752         if(xml_equal_string(node, "type", "bilinear")) {
753                 /* bilinear patch */
754                 if(P.size() == 4) {
755                         LinearQuadPatch *bpatch = new LinearQuadPatch();
756
757                         for(int i = 0; i < 4; i++)
758                                 P[i] = transform_point(&state.tfm, P[i]);
759                         memcpy(bpatch->hull, &P[0], sizeof(bpatch->hull));
760
761                         patch = bpatch;
762                 }
763                 else
764                         fprintf(stderr, "Invalid number of control points for bilinear patch.\n");
765         }
766         else if(xml_equal_string(node, "type", "bicubic")) {
767                 /* bicubic patch */
768                 if(P.size() == 16) {
769                         BicubicPatch *bpatch = new BicubicPatch();
770
771                         for(int i = 0; i < 16; i++)
772                                 P[i] = transform_point(&state.tfm, P[i]);
773                         memcpy(bpatch->hull, &P[0], sizeof(bpatch->hull));
774
775                         patch = bpatch;
776                 }
777                 else
778                         fprintf(stderr, "Invalid number of control points for bicubic patch.\n");
779         }
780         else
781                 fprintf(stderr, "Unknown patch type.\n");
782
783         if(patch) {
784                 /* add mesh */
785                 Mesh *mesh = xml_add_mesh(state.scene, transform_identity());
786
787                 mesh->used_shaders.push_back(state.shader);
788
789                 /* split */
790                 DiagSplit dsplit;
791                 //dsplit.camera = state.scene->camera;
792                 //dsplit.dicing_rate = 5.0f;
793                 dsplit.dicing_rate = state.dicing_rate;
794                 xml_read_float(&dsplit.dicing_rate, node, "dicing_rate");
795                 dsplit.split_quad(mesh, patch, state.shader, state.smooth);
796
797                 delete patch;
798
799                 /* temporary for test compatibility */
800                 mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
801         }
802 }
803
804 /* Light */
805
806 static void xml_read_light(const XMLReadState& state, pugi::xml_node node)
807 {
808         Light *light = new Light();
809         light->shader = state.shader;
810         xml_read_float3(&light->co, node, "P");
811         light->co = transform_point(&state.tfm, light->co);
812
813         state.scene->lights.push_back(light);
814 }
815
816 /* Transform */
817
818 static void xml_read_transform(pugi::xml_node node, Transform& tfm)
819 {
820         if(node.attribute("matrix")) {
821                 vector<float> matrix;
822                 if(xml_read_float_array(matrix, node, "matrix") && matrix.size() == 16)
823                         tfm = tfm * transform_transpose((*(Transform*)&matrix[0]));
824         }
825
826         if(node.attribute("translate")) {
827                 float3 translate = make_float3(0.0f, 0.0f, 0.0f);
828                 xml_read_float3(&translate, node, "translate");
829                 tfm = tfm * transform_translate(translate);
830         }
831
832         if(node.attribute("rotate")) {
833                 float4 rotate = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
834                 xml_read_float4(&rotate, node, "rotate");
835                 tfm = tfm * transform_rotate(rotate.x*M_PI/180.0f, make_float3(rotate.y, rotate.z, rotate.w));
836         }
837
838         if(node.attribute("scale")) {
839                 float3 scale = make_float3(0.0f, 0.0f, 0.0f);
840                 xml_read_float3(&scale, node, "scale");
841                 tfm = tfm * transform_scale(scale);
842         }
843 }
844
845 /* State */
846
847 static void xml_read_state(XMLReadState& state, pugi::xml_node node)
848 {
849         /* read shader */
850         string shadername;
851
852         if(xml_read_string(&shadername, node, "shader")) {
853                 int i = 0;
854                 bool found = false;
855
856                 foreach(Shader *shader, state.scene->shaders) {
857                         if(shader->name == shadername) {
858                                 state.shader = i;
859                                 found = true;
860                                 break;
861                         }
862
863                         i++;
864                 }
865
866                 if(!found)
867                         fprintf(stderr, "Unknown shader \"%s\".\n", shadername.c_str());
868         }
869
870         xml_read_float(&state.dicing_rate, node, "dicing_rate");
871
872         /* read smooth/flat */
873         if(xml_equal_string(node, "interpolation", "smooth"))
874                 state.smooth = true;
875         else if(xml_equal_string(node, "interpolation", "flat"))
876                 state.smooth = false;
877
878         /* read displacement method */
879         if(xml_equal_string(node, "displacement_method", "true"))
880                 state.displacement_method = Mesh::DISPLACE_TRUE;
881         else if(xml_equal_string(node, "displacement_method", "bump"))
882                 state.displacement_method = Mesh::DISPLACE_BUMP;
883         else if(xml_equal_string(node, "displacement_method", "both"))
884                 state.displacement_method = Mesh::DISPLACE_BOTH;
885 }
886
887 /* Scene */
888
889 static void xml_read_include(const XMLReadState& state, const string& src);
890
891 static void xml_read_scene(const XMLReadState& state, pugi::xml_node scene_node)
892 {
893         for(pugi::xml_node node = scene_node.first_child(); node; node = node.next_sibling()) {
894                 if(string_iequals(node.name(), "film")) {
895                         xml_read_film(state, node);
896                 }
897                 else if(string_iequals(node.name(), "integrator")) {
898                         xml_read_integrator(state, node);
899                 }
900                 else if(string_iequals(node.name(), "camera")) {
901                         xml_read_camera(state, node);
902                 }
903                 else if(string_iequals(node.name(), "shader")) {
904                         xml_read_shader(state, node);
905                 }
906                 else if(string_iequals(node.name(), "background")) {
907                         xml_read_background(state, node);
908                 }
909                 else if(string_iequals(node.name(), "mesh")) {
910                         xml_read_mesh(state, node);
911                 }
912                 else if(string_iequals(node.name(), "patch")) {
913                         xml_read_patch(state, node);
914                 }
915                 else if(string_iequals(node.name(), "light")) {
916                         xml_read_light(state, node);
917                 }
918                 else if(string_iequals(node.name(), "transform")) {
919                         XMLReadState substate = state;
920
921                         xml_read_transform(node, substate.tfm);
922                         xml_read_scene(substate, node);
923                 }
924                 else if(string_iequals(node.name(), "state")) {
925                         XMLReadState substate = state;
926
927                         xml_read_state(substate, node);
928                         xml_read_scene(substate, node);
929                 }
930                 else if(string_iequals(node.name(), "include")) {
931                         string src;
932
933                         if(xml_read_string(&src, node, "src"))
934                                 xml_read_include(state, src);
935                 }
936                 else
937                         fprintf(stderr, "Unknown node \"%s\".\n", node.name());
938         }
939 }
940
941 /* Include */
942
943 static void xml_read_include(const XMLReadState& state, const string& src)
944 {
945         /* open XML document */
946         pugi::xml_document doc;
947         pugi::xml_parse_result parse_result;
948
949         string path = path_join(state.base, src);
950         parse_result = doc.load_file(path.c_str());
951
952         if(parse_result) {
953                 XMLReadState substate = state;
954                 substate.base = path_dirname(path);
955
956                 xml_read_scene(substate, doc);
957         }
958         else
959                 fprintf(stderr, "%s read error: %s\n", src.c_str(), parse_result.description());
960 }
961
962 /* File */
963
964 void xml_read_file(Scene *scene, const char *filepath)
965 {
966         XMLReadState state;
967
968         state.scene = scene;
969         state.tfm = transform_identity();
970         state.shader = scene->default_surface;
971         state.smooth = false;
972         state.dicing_rate = 0.1f;
973         state.base = path_dirname(filepath);
974
975         xml_read_include(state, path_filename(filepath));
976
977         scene->params.bvh_type = SceneParams::BVH_STATIC;
978 }
979
980 CCL_NAMESPACE_END
981