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