Cycles: Add fundamentals to test constant folding
[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 "node_xml.h"
24
25 #include "background.h"
26 #include "camera.h"
27 #include "film.h"
28 #include "graph.h"
29 #include "integrator.h"
30 #include "light.h"
31 #include "mesh.h"
32 #include "nodes.h"
33 #include "object.h"
34 #include "osl.h"
35 #include "shader.h"
36 #include "scene.h"
37
38 #include "subd_patch.h"
39 #include "subd_split.h"
40
41 #include "util_debug.h"
42 #include "util_foreach.h"
43 #include "util_path.h"
44 #include "util_transform.h"
45 #include "util_xml.h"
46
47 #include "cycles_xml.h"
48
49 CCL_NAMESPACE_BEGIN
50
51 /* XML reading state */
52
53 struct XMLReadState : public XMLReader {
54         Scene *scene;           /* scene pointer */
55         Transform tfm;          /* current transform state */
56         bool smooth;            /* smooth normal state */
57         Shader *shader;         /* current shader */
58         string base;            /* base path to current file*/
59         float dicing_rate;      /* current dicing rate */
60         Mesh::DisplacementMethod displacement_method;
61
62         XMLReadState()
63           : scene(NULL),
64             smooth(false),
65             shader(NULL),
66             dicing_rate(0.0f),
67             displacement_method(Mesh::DISPLACE_BUMP)
68         {
69                 tfm = transform_identity();
70         }
71 };
72
73 /* Attribute Reading */
74
75 static bool xml_read_int(int *value, pugi::xml_node node, const char *name)
76 {
77         pugi::xml_attribute attr = node.attribute(name);
78
79         if(attr) {
80                 *value = atoi(attr.value());
81                 return true;
82         }
83
84         return false;
85 }
86
87 static bool xml_read_int_array(vector<int>& value, pugi::xml_node node, const char *name)
88 {
89         pugi::xml_attribute attr = node.attribute(name);
90
91         if(attr) {
92                 vector<string> tokens;
93                 string_split(tokens, attr.value());
94
95                 foreach(const string& token, tokens)
96                         value.push_back(atoi(token.c_str()));
97
98                 return true;
99         }
100
101         return false;
102 }
103
104 static bool xml_read_float(float *value, pugi::xml_node node, const char *name)
105 {
106         pugi::xml_attribute attr = node.attribute(name);
107
108         if(attr) {
109                 *value = (float)atof(attr.value());
110                 return true;
111         }
112
113         return false;
114 }
115
116 static bool xml_read_float_array(vector<float>& value, pugi::xml_node node, const char *name)
117 {
118         pugi::xml_attribute attr = node.attribute(name);
119
120         if(attr) {
121                 vector<string> tokens;
122                 string_split(tokens, attr.value());
123
124                 foreach(const string& token, tokens)
125                         value.push_back((float)atof(token.c_str()));
126
127                 return true;
128         }
129
130         return false;
131 }
132
133 static bool xml_read_float3(float3 *value, pugi::xml_node node, const char *name)
134 {
135         vector<float> array;
136
137         if(xml_read_float_array(array, node, name) && array.size() == 3) {
138                 *value = make_float3(array[0], array[1], array[2]);
139                 return true;
140         }
141
142         return false;
143 }
144
145 static bool xml_read_float3_array(vector<float3>& value, pugi::xml_node node, const char *name)
146 {
147         vector<float> array;
148
149         if(xml_read_float_array(array, node, name)) {
150                 for(size_t i = 0; i < array.size(); i += 3)
151                         value.push_back(make_float3(array[i+0], array[i+1], array[i+2]));
152
153                 return true;
154         }
155
156         return false;
157 }
158
159 static bool xml_read_float4(float4 *value, pugi::xml_node node, const char *name)
160 {
161         vector<float> array;
162
163         if(xml_read_float_array(array, node, name) && array.size() == 4) {
164                 *value = make_float4(array[0], array[1], array[2], array[3]);
165                 return true;
166         }
167
168         return false;
169 }
170
171 static bool xml_read_string(string *str, pugi::xml_node node, const char *name)
172 {
173         pugi::xml_attribute attr = node.attribute(name);
174
175         if(attr) {
176                 *str = attr.value();
177                 return true;
178         }
179
180         return false;
181 }
182
183 static bool xml_equal_string(pugi::xml_node node, const char *name, const char *value)
184 {
185         pugi::xml_attribute attr = node.attribute(name);
186
187         if(attr)
188                 return string_iequals(attr.value(), value);
189         
190         return false;
191 }
192
193 /* Camera */
194
195 static void xml_read_camera(XMLReadState& state, pugi::xml_node node)
196 {
197         Camera *cam = state.scene->camera;
198
199         xml_read_int(&cam->width, node, "width");
200         xml_read_int(&cam->height, node, "height");
201
202         xml_read_node(state, cam, node);
203
204         cam->matrix = state.tfm;
205
206         cam->need_update = true;
207         cam->update();
208 }
209
210 /* Shader */
211
212 static string xml_socket_name(const char *name)
213 {
214         string sname = name;
215         size_t i;
216
217         while((i = sname.find(" ")) != string::npos)
218                 sname.replace(i, 1, "");
219         
220         return sname;
221 }
222
223 static void xml_read_shader_graph(XMLReadState& state, Shader *shader, pugi::xml_node graph_node)
224 {
225         xml_read_node(state, shader, graph_node);
226
227         ShaderGraph *graph = new ShaderGraph();
228
229         /* local state, shader nodes can't link to nodes outside the shader graph */
230         XMLReader graph_reader;
231         graph_reader.node_map[ustring("output")] = graph->output();
232
233         for(pugi::xml_node node = graph_node.first_child(); node; node = node.next_sibling()) {
234                 ustring node_name(node.name());
235
236                 if(node_name == "connect") {
237                         /* connect nodes */
238                         vector<string> from_tokens, to_tokens;
239
240                         string_split(from_tokens, node.attribute("from").value());
241                         string_split(to_tokens, node.attribute("to").value());
242
243                         if(from_tokens.size() == 2 && to_tokens.size() == 2) {
244                                 ustring from_node_name(from_tokens[0]);
245                                 ustring from_socket_name(from_tokens[1]);
246                                 ustring to_node_name(to_tokens[0]);
247                                 ustring to_socket_name(to_tokens[1]);
248
249                                 /* find nodes and sockets */
250                                 ShaderOutput *output = NULL;
251                                 ShaderInput *input = NULL;
252
253                                 if(graph_reader.node_map.find(from_node_name) != graph_reader.node_map.end()) {
254                                         ShaderNode *fromnode = (ShaderNode*)graph_reader.node_map[from_node_name];
255
256                                         foreach(ShaderOutput *out, fromnode->outputs)
257                                                 if(string_iequals(xml_socket_name(out->name().c_str()), from_socket_name.c_str()))
258                                                         output = out;
259
260                                         if(!output)
261                                                 fprintf(stderr, "Unknown output socket name \"%s\" on \"%s\".\n", from_node_name.c_str(), from_socket_name.c_str());
262                                 }
263                                 else
264                                         fprintf(stderr, "Unknown shader node name \"%s\".\n", from_node_name.c_str());
265
266                                 if(graph_reader.node_map.find(to_node_name) != graph_reader.node_map.end()) {
267                                         ShaderNode *tonode = (ShaderNode*)graph_reader.node_map[to_node_name];
268
269                                         foreach(ShaderInput *in, tonode->inputs)
270                                                 if(string_iequals(xml_socket_name(in->name().c_str()), to_socket_name.c_str()))
271                                                         input = in;
272
273                                         if(!input)
274                                                 fprintf(stderr, "Unknown input socket name \"%s\" on \"%s\".\n", to_socket_name.c_str(), to_node_name.c_str());
275                                 }
276                                 else
277                                         fprintf(stderr, "Unknown shader node name \"%s\".\n", to_node_name.c_str());
278
279                                 /* connect */
280                                 if(output && input)
281                                         graph->connect(output, input);
282                         }
283                         else
284                                 fprintf(stderr, "Invalid from or to value for connect node.\n");
285
286                         continue;
287                 }
288
289                 ShaderNode *snode = NULL;
290
291 #ifdef WITH_OSL
292                 if(node_name == "osl_shader") {
293                         ShaderManager *manager = state.scene->shader_manager;
294
295                         if(manager->use_osl()) {
296                                 std::string filepath;
297
298                                 if(xml_read_string(&filepath, node, "src")) {
299                                         if(path_is_relative(filepath)) {
300                                                 filepath = path_join(state.base, filepath);
301                                         }
302
303                                         snode = ((OSLShaderManager*)manager)->osl_node(filepath);
304
305                                         if(!snode) {
306                                                 fprintf(stderr, "Failed to create OSL node from \"%s\".\n", filepath.c_str());
307                                                 continue;
308                                         }
309                                 }
310                                 else {
311                                         fprintf(stderr, "OSL node missing \"src\" attribute.\n");
312                                         continue;
313                                 }
314                         }
315                         else {
316                                 fprintf(stderr, "OSL node without using --shadingsys osl.\n");
317                                 continue;
318                         }
319                 }
320                 else
321 #endif
322                 {
323                         /* exception for name collision */
324                         if(node_name == "background")
325                                 node_name = "background_shader";
326
327                         const NodeType *node_type = NodeType::find(node_name);
328
329                         if(!node_type) {
330                                 fprintf(stderr, "Unknown shader node \"%s\".\n", node.name());
331                                 continue;
332                         }
333                         else if(node_type->type != NodeType::SHADER) {
334                                 fprintf(stderr, "Node type \"%s\" is not a shader node.\n", node_type->name.c_str());
335                                 continue;
336                         }
337
338                         snode = (ShaderNode*) node_type->create(node_type);
339                 }
340
341                 xml_read_node(graph_reader, snode, node);
342
343                 if(node_name == "image_texture") {
344                         ImageTextureNode *img = (ImageTextureNode*) snode;
345                         img->filename = path_join(state.base, img->filename.string());
346                 }
347                 else if(node_name == "environment_texture") {
348                         EnvironmentTextureNode *env = (EnvironmentTextureNode*) snode;
349                         env->filename = path_join(state.base, env->filename.string());
350                 }
351
352                 if(snode) {
353                         /* add to graph */
354                         graph->add(snode);
355                 }
356         }
357
358         shader->set_graph(graph);
359         shader->tag_update(state.scene);
360 }
361
362 static void xml_read_shader(XMLReadState& state, pugi::xml_node node)
363 {
364         Shader *shader = new Shader();
365         xml_read_shader_graph(state, shader, node);
366         state.scene->shaders.push_back(shader);
367 }
368
369 /* Background */
370
371 static void xml_read_background(XMLReadState& state, pugi::xml_node node)
372 {
373         /* Background Settings */
374         xml_read_node(state, state.scene->background, node);
375
376         /* Background Shader */
377         Shader *shader = state.scene->default_background;
378         xml_read_shader_graph(state, shader, node);
379 }
380
381 /* Mesh */
382
383 static Mesh *xml_add_mesh(Scene *scene, const Transform& tfm)
384 {
385         /* create mesh */
386         Mesh *mesh = new Mesh();
387         scene->meshes.push_back(mesh);
388
389         /* create object*/
390         Object *object = new Object();
391         object->mesh = mesh;
392         object->tfm = tfm;
393         scene->objects.push_back(object);
394
395         return mesh;
396 }
397
398 static void xml_read_mesh(const XMLReadState& state, pugi::xml_node node)
399 {
400         /* add mesh */
401         Mesh *mesh = xml_add_mesh(state.scene, state.tfm);
402         mesh->used_shaders.push_back(state.shader);
403
404         /* read state */
405         int shader = 0;
406         bool smooth = state.smooth;
407
408         mesh->displacement_method = state.displacement_method;
409
410         /* read vertices and polygons, RIB style */
411         vector<float3> P;
412         vector<float> UV;
413         vector<int> verts, nverts;
414
415         xml_read_float3_array(P, node, "P");
416         xml_read_int_array(verts, node, "verts");
417         xml_read_int_array(nverts, node, "nverts");
418
419 #if 0
420         if(xml_equal_string(node, "subdivision", "catmull-clark")) {
421                 /* create subd mesh */
422                 SubdMesh sdmesh;
423
424                 /* create subd vertices */
425                 for(size_t i = 0; i < P.size(); i++)
426                         sdmesh.add_vert(P[i]);
427
428                 /* create subd faces */
429                 int index_offset = 0;
430
431                 for(size_t i = 0; i < nverts.size(); i++) {
432                         if(nverts[i] == 4) {
433                                 int v0 = verts[index_offset + 0];
434                                 int v1 = verts[index_offset + 1];
435                                 int v2 = verts[index_offset + 2];
436                                 int v3 = verts[index_offset + 3];
437
438                                 sdmesh.add_face(v0, v1, v2, v3);
439                         }
440                         else {
441                                 for(int j = 0; j < nverts[i]-2; j++) {
442                                         int v0 = verts[index_offset];
443                                         int v1 = verts[index_offset + j + 1];
444                                         int v2 = verts[index_offset + j + 2];
445
446                                         sdmesh.add_face(v0, v1, v2);
447                                 }
448                         }
449
450                         index_offset += nverts[i];
451                 }
452
453                 /* finalize subd mesh */
454                 sdmesh.finish();
455
456                 /* parameters */
457                 SubdParams sdparams(mesh, shader, smooth);
458                 xml_read_float(&sdparams.dicing_rate, node, "dicing_rate");
459
460                 DiagSplit dsplit(sdparams);
461                 sdmesh.tessellate(&dsplit);
462         }
463         else
464 #endif
465         {
466                 /* create vertices */
467                 mesh->verts = P;
468
469                 size_t num_triangles = 0;
470                 for(size_t i = 0; i < nverts.size(); i++)
471                         num_triangles += nverts[i]-2;
472                 mesh->reserve_mesh(mesh->verts.size(), num_triangles);
473
474                 /* create triangles */
475                 int index_offset = 0;
476
477                 for(size_t i = 0; i < nverts.size(); i++) {
478                         for(int j = 0; j < nverts[i]-2; j++) {
479                                 int v0 = verts[index_offset];
480                                 int v1 = verts[index_offset + j + 1];
481                                 int v2 = verts[index_offset + j + 2];
482
483                                 assert(v0 < (int)P.size());
484                                 assert(v1 < (int)P.size());
485                                 assert(v2 < (int)P.size());
486
487                                 mesh->add_triangle(v0, v1, v2, shader, smooth);
488                         }
489
490                         index_offset += nverts[i];
491                 }
492
493                 if(xml_read_float_array(UV, node, "UV")) {
494                         ustring name = ustring("UVMap");
495                         Attribute *attr = mesh->attributes.add(ATTR_STD_UV, name);
496                         float3 *fdata = attr->data_float3();
497
498                         /* loop over the triangles */
499                         index_offset = 0;
500                         for(size_t i = 0; i < nverts.size(); i++) {
501                                 for(int j = 0; j < nverts[i]-2; j++) {
502                                         int v0 = index_offset;
503                                         int v1 = index_offset + j + 1;
504                                         int v2 = index_offset + j + 2;
505
506                                         assert(v0*2+1 < (int)UV.size());
507                                         assert(v1*2+1 < (int)UV.size());
508                                         assert(v2*2+1 < (int)UV.size());
509
510                                         fdata[0] = make_float3(UV[v0*2], UV[v0*2+1], 0.0);
511                                         fdata[1] = make_float3(UV[v1*2], UV[v1*2+1], 0.0);
512                                         fdata[2] = make_float3(UV[v2*2], UV[v2*2+1], 0.0);
513                                         fdata += 3;
514                                 }
515
516                                 index_offset += nverts[i];
517                         }
518                 }
519         }
520
521         /* temporary for test compatibility */
522         mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
523 }
524
525 /* Patch */
526
527 static void xml_read_patch(const XMLReadState& state, pugi::xml_node node)
528 {
529         /* read patch */
530         Patch *patch = NULL;
531
532         vector<float3> P;
533         xml_read_float3_array(P, node, "P");
534
535         if(xml_equal_string(node, "type", "bilinear")) {
536                 /* bilinear patch */
537                 if(P.size() == 4) {
538                         LinearQuadPatch *bpatch = new LinearQuadPatch();
539
540                         for(int i = 0; i < 4; i++)
541                                 P[i] = transform_point(&state.tfm, P[i]);
542                         memcpy(bpatch->hull, &P[0], sizeof(bpatch->hull));
543
544                         patch = bpatch;
545                 }
546                 else
547                         fprintf(stderr, "Invalid number of control points for bilinear patch.\n");
548         }
549         else if(xml_equal_string(node, "type", "bicubic")) {
550                 /* bicubic patch */
551                 if(P.size() == 16) {
552                         BicubicPatch *bpatch = new BicubicPatch();
553
554                         for(int i = 0; i < 16; i++)
555                                 P[i] = transform_point(&state.tfm, P[i]);
556                         memcpy(bpatch->hull, &P[0], sizeof(bpatch->hull));
557
558                         patch = bpatch;
559                 }
560                 else
561                         fprintf(stderr, "Invalid number of control points for bicubic patch.\n");
562         }
563         else
564                 fprintf(stderr, "Unknown patch type.\n");
565
566         if(patch) {
567                 /* add mesh */
568                 Mesh *mesh = xml_add_mesh(state.scene, transform_identity());
569
570                 mesh->used_shaders.push_back(state.shader);
571
572                 /* split */
573                 SubdParams sdparams(mesh);
574                 xml_read_float(&sdparams.dicing_rate, node, "dicing_rate");
575
576                 DiagSplit dsplit(sdparams);
577                 dsplit.split_quad(patch);
578
579                 delete patch;
580
581                 /* temporary for test compatibility */
582                 mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
583         }
584 }
585
586 /* Light */
587
588 static void xml_read_light(XMLReadState& state, pugi::xml_node node)
589 {
590         Light *light = new Light();
591
592         light->shader = state.shader;
593         xml_read_node(state, light, node);
594
595         state.scene->lights.push_back(light);
596 }
597
598 /* Transform */
599
600 static void xml_read_transform(pugi::xml_node node, Transform& tfm)
601 {
602         if(node.attribute("matrix")) {
603                 vector<float> matrix;
604                 if(xml_read_float_array(matrix, node, "matrix") && matrix.size() == 16)
605                         tfm = tfm * transform_transpose((*(Transform*)&matrix[0]));
606         }
607
608         if(node.attribute("translate")) {
609                 float3 translate = make_float3(0.0f, 0.0f, 0.0f);
610                 xml_read_float3(&translate, node, "translate");
611                 tfm = tfm * transform_translate(translate);
612         }
613
614         if(node.attribute("rotate")) {
615                 float4 rotate = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
616                 xml_read_float4(&rotate, node, "rotate");
617                 tfm = tfm * transform_rotate(DEG2RADF(rotate.x), make_float3(rotate.y, rotate.z, rotate.w));
618         }
619
620         if(node.attribute("scale")) {
621                 float3 scale = make_float3(0.0f, 0.0f, 0.0f);
622                 xml_read_float3(&scale, node, "scale");
623                 tfm = tfm * transform_scale(scale);
624         }
625 }
626
627 /* State */
628
629 static void xml_read_state(XMLReadState& state, pugi::xml_node node)
630 {
631         /* read shader */
632         string shadername;
633
634         if(xml_read_string(&shadername, node, "shader")) {
635                 bool found = false;
636
637                 foreach(Shader *shader, state.scene->shaders) {
638                         if(shader->name == shadername) {
639                                 state.shader = shader;
640                                 found = true;
641                                 break;
642                         }
643                 }
644
645                 if(!found)
646                         fprintf(stderr, "Unknown shader \"%s\".\n", shadername.c_str());
647         }
648
649         xml_read_float(&state.dicing_rate, node, "dicing_rate");
650
651         /* read smooth/flat */
652         if(xml_equal_string(node, "interpolation", "smooth"))
653                 state.smooth = true;
654         else if(xml_equal_string(node, "interpolation", "flat"))
655                 state.smooth = false;
656
657         /* read displacement method */
658         if(xml_equal_string(node, "displacement_method", "true"))
659                 state.displacement_method = Mesh::DISPLACE_TRUE;
660         else if(xml_equal_string(node, "displacement_method", "bump"))
661                 state.displacement_method = Mesh::DISPLACE_BUMP;
662         else if(xml_equal_string(node, "displacement_method", "both"))
663                 state.displacement_method = Mesh::DISPLACE_BOTH;
664 }
665
666 /* Scene */
667
668 static void xml_read_include(XMLReadState& state, const string& src);
669
670 static void xml_read_scene(XMLReadState& state, pugi::xml_node scene_node)
671 {
672         for(pugi::xml_node node = scene_node.first_child(); node; node = node.next_sibling()) {
673                 if(string_iequals(node.name(), "film")) {
674                         xml_read_node(state, state.scene->film, node);
675                 }
676                 else if(string_iequals(node.name(), "integrator")) {
677                         xml_read_node(state, state.scene->integrator, node);
678                 }
679                 else if(string_iequals(node.name(), "camera")) {
680                         xml_read_camera(state, node);
681                 }
682                 else if(string_iequals(node.name(), "shader")) {
683                         xml_read_shader(state, node);
684                 }
685                 else if(string_iequals(node.name(), "background")) {
686                         xml_read_background(state, node);
687                 }
688                 else if(string_iequals(node.name(), "mesh")) {
689                         xml_read_mesh(state, node);
690                 }
691                 else if(string_iequals(node.name(), "patch")) {
692                         xml_read_patch(state, node);
693                 }
694                 else if(string_iequals(node.name(), "light")) {
695                         xml_read_light(state, node);
696                 }
697                 else if(string_iequals(node.name(), "transform")) {
698                         XMLReadState substate = state;
699
700                         xml_read_transform(node, substate.tfm);
701                         xml_read_scene(substate, node);
702                 }
703                 else if(string_iequals(node.name(), "state")) {
704                         XMLReadState substate = state;
705
706                         xml_read_state(substate, node);
707                         xml_read_scene(substate, node);
708                 }
709                 else if(string_iequals(node.name(), "include")) {
710                         string src;
711
712                         if(xml_read_string(&src, node, "src"))
713                                 xml_read_include(state, src);
714                 }
715                 else
716                         fprintf(stderr, "Unknown node \"%s\".\n", node.name());
717         }
718 }
719
720 /* Include */
721
722 static void xml_read_include(XMLReadState& state, const string& src)
723 {
724         /* open XML document */
725         pugi::xml_document doc;
726         pugi::xml_parse_result parse_result;
727
728         string path = path_join(state.base, src);
729         parse_result = doc.load_file(path.c_str());
730
731         if(parse_result) {
732                 XMLReadState substate = state;
733                 substate.base = path_dirname(path);
734
735                 pugi::xml_node cycles = doc.child("cycles");
736                 xml_read_scene(substate, cycles);
737         }
738         else {
739                 fprintf(stderr, "%s read error: %s\n", src.c_str(), parse_result.description());
740                 exit(EXIT_FAILURE);
741         }
742 }
743
744 /* File */
745
746 void xml_read_file(Scene *scene, const char *filepath)
747 {
748         XMLReadState state;
749
750         state.scene = scene;
751         state.tfm = transform_identity();
752         state.shader = scene->default_surface;
753         state.smooth = false;
754         state.dicing_rate = 0.1f;
755         state.base = path_dirname(filepath);
756
757         xml_read_include(state, path_filename(filepath));
758
759         scene->params.bvh_type = SceneParams::BVH_STATIC;
760 }
761
762 CCL_NAMESPACE_END
763