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