2 * Copyright 2011-2013 Blender Foundation
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 #include "graph/node_xml.h"
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"
38 #include "subd/subd_patch.h"
39 #include "subd/subd_split.h"
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"
47 #include "app/cycles_xml.h"
51 /* XML reading state */
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 */
61 XMLReadState() : scene(NULL), smooth(false), shader(NULL), dicing_rate(1.0f)
63 tfm = transform_identity();
67 /* Attribute Reading */
69 static bool xml_read_int(int *value, xml_node node, const char *name)
71 xml_attribute attr = node.attribute(name);
74 *value = atoi(attr.value());
81 static bool xml_read_int_array(vector<int> &value, xml_node node, const char *name)
83 xml_attribute attr = node.attribute(name);
86 vector<string> tokens;
87 string_split(tokens, attr.value());
89 foreach (const string &token, tokens)
90 value.push_back(atoi(token.c_str()));
98 static bool xml_read_float(float *value, xml_node node, const char *name)
100 xml_attribute attr = node.attribute(name);
103 *value = (float)atof(attr.value());
110 static bool xml_read_float_array(vector<float> &value, xml_node node, const char *name)
112 xml_attribute attr = node.attribute(name);
115 vector<string> tokens;
116 string_split(tokens, attr.value());
118 foreach (const string &token, tokens)
119 value.push_back((float)atof(token.c_str()));
127 static bool xml_read_float3(float3 *value, xml_node node, const char *name)
131 if (xml_read_float_array(array, node, name) && array.size() == 3) {
132 *value = make_float3(array[0], array[1], array[2]);
139 static bool xml_read_float3_array(vector<float3> &value, xml_node node, const char *name)
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]));
153 static bool xml_read_float4(float4 *value, xml_node node, const char *name)
157 if (xml_read_float_array(array, node, name) && array.size() == 4) {
158 *value = make_float4(array[0], array[1], array[2], array[3]);
165 static bool xml_read_string(string *str, xml_node node, const char *name)
167 xml_attribute attr = node.attribute(name);
177 static bool xml_equal_string(xml_node node, const char *name, const char *value)
179 xml_attribute attr = node.attribute(name);
182 return string_iequals(attr.value(), value);
189 static void xml_read_camera(XMLReadState &state, xml_node node)
191 Camera *cam = state.scene->camera;
193 xml_read_int(&cam->width, node, "width");
194 xml_read_int(&cam->height, node, "height");
196 cam->full_width = cam->width;
197 cam->full_height = cam->height;
199 xml_read_node(state, cam, node);
201 cam->matrix = state.tfm;
203 cam->need_update = true;
204 cam->update(state.scene);
209 static void xml_read_shader_graph(XMLReadState &state, Shader *shader, xml_node graph_node)
211 xml_read_node(state, shader, graph_node);
213 ShaderGraph *graph = new ShaderGraph();
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();
219 for (xml_node node = graph_node.first_child(); node; node = node.next_sibling()) {
220 ustring node_name(node.name());
222 if (node_name == "connect") {
224 vector<string> from_tokens, to_tokens;
226 string_split(from_tokens, node.attribute("from").value());
227 string_split(to_tokens, node.attribute("to").value());
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]);
235 /* find nodes and sockets */
236 ShaderOutput *output = NULL;
237 ShaderInput *input = NULL;
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];
242 foreach (ShaderOutput *out, fromnode->outputs)
243 if (string_iequals(out->socket_type.name.string(), from_socket_name.string()))
248 "Unknown output socket name \"%s\" on \"%s\".\n",
249 from_node_name.c_str(),
250 from_socket_name.c_str());
253 fprintf(stderr, "Unknown shader node name \"%s\".\n", from_node_name.c_str());
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];
258 foreach (ShaderInput *in, tonode->inputs)
259 if (string_iequals(in->socket_type.name.string(), to_socket_name.string()))
264 "Unknown input socket name \"%s\" on \"%s\".\n",
265 to_socket_name.c_str(),
266 to_node_name.c_str());
269 fprintf(stderr, "Unknown shader node name \"%s\".\n", to_node_name.c_str());
273 graph->connect(output, input);
276 fprintf(stderr, "Invalid from or to value for connect node.\n");
281 ShaderNode *snode = NULL;
284 if (node_name == "osl_shader") {
285 ShaderManager *manager = state.scene->shader_manager;
287 if (manager->use_osl()) {
288 std::string filepath;
290 if (xml_read_string(&filepath, node, "src")) {
291 if (path_is_relative(filepath)) {
292 filepath = path_join(state.base, filepath);
295 snode = OSLShaderManager::osl_node(graph, manager, filepath, "");
298 fprintf(stderr, "Failed to create OSL node from \"%s\".\n", filepath.c_str());
303 fprintf(stderr, "OSL node missing \"src\" attribute.\n");
308 fprintf(stderr, "OSL node without using --shadingsys osl.\n");
315 /* exception for name collision */
316 if (node_name == "background")
317 node_name = "background_shader";
319 const NodeType *node_type = NodeType::find(node_name);
322 fprintf(stderr, "Unknown shader node \"%s\".\n", node.name());
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());
329 else if (node_type->create == NULL) {
330 fprintf(stderr, "Can't create abstract node type \"%s\".\n", node_type->name.c_str());
334 snode = (ShaderNode *)node_type->create(node_type);
337 xml_read_node(graph_reader, snode, node);
339 if (node_name == "image_texture") {
340 ImageTextureNode *img = (ImageTextureNode *)snode;
341 img->filename = path_join(state.base, img->filename.string());
343 else if (node_name == "environment_texture") {
344 EnvironmentTextureNode *env = (EnvironmentTextureNode *)snode;
345 env->filename = path_join(state.base, env->filename.string());
354 shader->set_graph(graph);
355 shader->tag_update(state.scene);
358 static void xml_read_shader(XMLReadState &state, xml_node node)
360 Shader *shader = new Shader();
361 xml_read_shader_graph(state, shader, node);
362 state.scene->shaders.push_back(shader);
367 static void xml_read_background(XMLReadState &state, xml_node node)
369 /* Background Settings */
370 xml_read_node(state, state.scene->background, node);
372 /* Background Shader */
373 Shader *shader = state.scene->default_background;
374 xml_read_shader_graph(state, shader, node);
379 static Mesh *xml_add_mesh(Scene *scene, const Transform &tfm)
382 Mesh *mesh = new Mesh();
383 scene->geometry.push_back(mesh);
386 Object *object = new Object();
387 object->geometry = mesh;
389 scene->objects.push_back(object);
394 static void xml_read_mesh(const XMLReadState &state, xml_node node)
397 Mesh *mesh = xml_add_mesh(state.scene, state.tfm);
398 mesh->used_shaders.push_back(state.shader);
402 bool smooth = state.smooth;
404 /* read vertices and polygons */
407 vector<int> verts, nverts;
409 xml_read_float3_array(P, node, "P");
410 xml_read_int_array(verts, node, "verts");
411 xml_read_int_array(nverts, node, "nverts");
413 if (xml_equal_string(node, "subdivision", "catmull-clark")) {
414 mesh->subdivision_type = Mesh::SUBDIVISION_CATMULL_CLARK;
416 else if (xml_equal_string(node, "subdivision", "linear")) {
417 mesh->subdivision_type = Mesh::SUBDIVISION_LINEAR;
420 if (mesh->subdivision_type == Mesh::SUBDIVISION_NONE) {
421 /* create vertices */
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);
429 /* create triangles */
430 int index_offset = 0;
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];
438 assert(v0 < (int)P.size());
439 assert(v1 < (int)P.size());
440 assert(v2 < (int)P.size());
442 mesh->add_triangle(v0, v1, v2, shader, smooth);
445 index_offset += nverts[i];
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();
453 /* loop over the triangles */
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;
461 assert(v0 * 2 + 1 < (int)UV.size());
462 assert(v1 * 2 + 1 < (int)UV.size());
463 assert(v2 * 2 + 1 < (int)UV.size());
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]);
471 index_offset += nverts[i];
476 /* create vertices */
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];
485 mesh->reserve_subd_faces(nverts.size(), num_ngons, num_corners);
487 /* create subd_faces */
488 int index_offset = 0;
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];
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();
503 attr->flags |= ATTR_SUBDIVIDED;
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++]);
515 /* setup subd params */
516 if (!mesh->subd_params) {
517 mesh->subd_params = new SubdParams(mesh);
519 SubdParams &sdparams = *mesh->subd_params;
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);
525 sdparams.objecttoworld = state.tfm;
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());
538 static void xml_read_light(XMLReadState &state, xml_node node)
540 Light *light = new Light();
542 light->shader = state.shader;
543 xml_read_node(state, light, node);
545 state.scene->lights.push_back(light);
550 static void xml_read_transform(xml_node node, Transform &tfm)
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));
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);
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));
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);
581 static void xml_read_state(XMLReadState &state, xml_node node)
586 if (xml_read_string(&shadername, node, "shader")) {
589 foreach (Shader *shader, state.scene->shaders) {
590 if (shader->name == shadername) {
591 state.shader = shader;
598 fprintf(stderr, "Unknown shader \"%s\".\n", shadername.c_str());
601 xml_read_float(&state.dicing_rate, node, "dicing_rate");
603 /* read smooth/flat */
604 if (xml_equal_string(node, "interpolation", "smooth"))
606 else if (xml_equal_string(node, "interpolation", "flat"))
607 state.smooth = false;
612 static void xml_read_include(XMLReadState &state, const string &src);
614 static void xml_read_scene(XMLReadState &state, xml_node scene_node)
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);
620 else if (string_iequals(node.name(), "integrator")) {
621 xml_read_node(state, state.scene->integrator, node);
623 else if (string_iequals(node.name(), "camera")) {
624 xml_read_camera(state, node);
626 else if (string_iequals(node.name(), "shader")) {
627 xml_read_shader(state, node);
629 else if (string_iequals(node.name(), "background")) {
630 xml_read_background(state, node);
632 else if (string_iequals(node.name(), "mesh")) {
633 xml_read_mesh(state, node);
635 else if (string_iequals(node.name(), "light")) {
636 xml_read_light(state, node);
638 else if (string_iequals(node.name(), "transform")) {
639 XMLReadState substate = state;
641 xml_read_transform(node, substate.tfm);
642 xml_read_scene(substate, node);
644 else if (string_iequals(node.name(), "state")) {
645 XMLReadState substate = state;
647 xml_read_state(substate, node);
648 xml_read_scene(substate, node);
650 else if (string_iequals(node.name(), "include")) {
653 if (xml_read_string(&src, node, "src"))
654 xml_read_include(state, src);
657 fprintf(stderr, "Unknown node \"%s\".\n", node.name());
663 static void xml_read_include(XMLReadState &state, const string &src)
665 /* open XML document */
667 xml_parse_result parse_result;
669 string path = path_join(state.base, src);
670 parse_result = doc.load_file(path.c_str());
673 XMLReadState substate = state;
674 substate.base = path_dirname(path);
676 xml_node cycles = doc.child("cycles");
677 xml_read_scene(substate, cycles);
680 fprintf(stderr, "%s read error: %s\n", src.c_str(), parse_result.description());
687 void xml_read_file(Scene *scene, const char *filepath)
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);
698 xml_read_include(state, path_filename(filepath));
700 scene->params.bvh_type = SceneParams::BVH_STATIC;