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