Blender V4.3
cycles_xml.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include <stdio.h>
6
7#include <algorithm>
8#include <iterator>
9#include <sstream>
10
11#include "graph/node_xml.h"
12
13#include "scene/alembic.h"
14#include "scene/background.h"
15#include "scene/camera.h"
16#include "scene/film.h"
17#include "scene/integrator.h"
18#include "scene/light.h"
19#include "scene/mesh.h"
20#include "scene/object.h"
21#include "scene/osl.h"
22#include "scene/scene.h"
23#include "scene/shader.h"
24#include "scene/shader_graph.h"
25#include "scene/shader_nodes.h"
26
27#include "subd/patch.h"
28#include "subd/split.h"
29
30#include "util/foreach.h"
31#include "util/path.h"
32#include "util/projection.h"
33#include "util/transform.h"
34#include "util/xml.h"
35
36#include "app/cycles_xml.h"
37
39
40/* XML reading state */
41
42struct XMLReadState : public XMLReader {
43 Scene *scene; /* Scene pointer. */
44 Transform tfm; /* Current transform state. */
45 bool smooth; /* Smooth normal state. */
46 Shader *shader; /* Current shader. */
47 string base; /* Base path to current file. */
48 float dicing_rate; /* Current dicing rate. */
49 Object *object; /* Current object. */
50
51 XMLReadState() : scene(NULL), smooth(false), shader(NULL), dicing_rate(1.0f), object(NULL)
52 {
54 }
55};
56
57/* Attribute Reading */
58
59static bool xml_read_int(int *value, xml_node node, const char *name)
60{
61 xml_attribute attr = node.attribute(name);
62
63 if (attr) {
64 *value = atoi(attr.value());
65 return true;
66 }
67
68 return false;
69}
70
71static bool xml_read_int_array(vector<int> &value, xml_node node, const char *name)
72{
73 xml_attribute attr = node.attribute(name);
74
75 if (attr) {
76 vector<string> tokens;
77 string_split(tokens, attr.value());
78
79 foreach (const string &token, tokens)
80 value.push_back(atoi(token.c_str()));
81
82 return true;
83 }
84
85 return false;
86}
87
88static bool xml_read_float(float *value, xml_node node, const char *name)
89{
90 xml_attribute attr = node.attribute(name);
91
92 if (attr) {
93 *value = (float)atof(attr.value());
94 return true;
95 }
96
97 return false;
98}
99
100static bool xml_read_float_array(vector<float> &value, xml_node node, const char *name)
101{
102 xml_attribute attr = node.attribute(name);
103
104 if (attr) {
105 vector<string> tokens;
106 string_split(tokens, attr.value());
107
108 foreach (const string &token, tokens)
109 value.push_back((float)atof(token.c_str()));
110
111 return true;
112 }
113
114 return false;
115}
116
117static bool xml_read_float3(float3 *value, xml_node node, const char *name)
118{
120
121 if (xml_read_float_array(array, node, name) && array.size() == 3) {
122 *value = make_float3(array[0], array[1], array[2]);
123 return true;
124 }
125
126 return false;
127}
128
129static bool xml_read_float3_array(vector<float3> &value, xml_node node, const char *name)
130{
132
133 if (xml_read_float_array(array, node, name)) {
134 for (size_t i = 0; i < array.size(); i += 3) {
135 value.push_back(make_float3(array[i + 0], array[i + 1], array[i + 2]));
136 }
137
138 return true;
139 }
140
141 return false;
142}
143
144static bool xml_read_float4(float4 *value, xml_node node, const char *name)
145{
147
148 if (xml_read_float_array(array, node, name) && array.size() == 4) {
149 *value = make_float4(array[0], array[1], array[2], array[3]);
150 return true;
151 }
152
153 return false;
154}
155
156static bool xml_read_string(string *str, xml_node node, const char *name)
157{
158 xml_attribute attr = node.attribute(name);
159
160 if (attr) {
161 *str = attr.value();
162 return true;
163 }
164
165 return false;
166}
167
168static bool xml_equal_string(xml_node node, const char *name, const char *value)
169{
170 xml_attribute attr = node.attribute(name);
171
172 if (attr) {
173 return string_iequals(attr.value(), value);
174 }
175
176 return false;
177}
178
179/* Camera */
180
181static void xml_read_camera(XMLReadState &state, xml_node node)
182{
183 Camera *cam = state.scene->camera;
184
185 int width = -1, height = -1;
186 xml_read_int(&width, node, "width");
187 xml_read_int(&height, node, "height");
188
189 cam->set_full_width(width);
190 cam->set_full_height(height);
191
192 xml_read_node(state, cam, node);
193
194 cam->set_matrix(state.tfm);
195
196 cam->need_flags_update = true;
197 cam->update(state.scene);
198}
199
200/* Alembic */
201
202#ifdef WITH_ALEMBIC
203static void xml_read_alembic(XMLReadState &state, xml_node graph_node)
204{
205 AlembicProcedural *proc = state.scene->create_node<AlembicProcedural>();
206 xml_read_node(state, proc, graph_node);
207
208 for (xml_node node = graph_node.first_child(); node; node = node.next_sibling()) {
209 if (string_iequals(node.name(), "object")) {
210 string path;
211 if (xml_read_string(&path, node, "path")) {
212 ustring object_path(path, 0);
213 AlembicObject *object = static_cast<AlembicObject *>(
214 proc->get_or_create_object(object_path));
215
216 array<Node *> used_shaders = object->get_used_shaders();
217 used_shaders.push_back_slow(state.shader);
218 object->set_used_shaders(used_shaders);
219 }
220 }
221 }
222}
223#endif
224
225/* Shader */
226
227static void xml_read_shader_graph(XMLReadState &state, Shader *shader, xml_node graph_node)
228{
229 xml_read_node(state, shader, graph_node);
230
231 ShaderGraph *graph = new ShaderGraph();
232
233 /* local state, shader nodes can't link to nodes outside the shader graph */
234 XMLReader graph_reader;
235 graph_reader.node_map[ustring("output")] = graph->output();
236
237 for (xml_node node = graph_node.first_child(); node; node = node.next_sibling()) {
238 ustring node_name(node.name());
239
240 if (node_name == "connect") {
241 /* connect nodes */
242 vector<string> from_tokens, to_tokens;
243
244 string_split(from_tokens, node.attribute("from").value());
245 string_split(to_tokens, node.attribute("to").value());
246
247 if (from_tokens.size() == 2 && to_tokens.size() == 2) {
248 ustring from_node_name(from_tokens[0]);
249 ustring from_socket_name(from_tokens[1]);
250 ustring to_node_name(to_tokens[0]);
251 ustring to_socket_name(to_tokens[1]);
252
253 /* find nodes and sockets */
254 ShaderOutput *output = NULL;
255 ShaderInput *input = NULL;
256
257 if (graph_reader.node_map.find(from_node_name) != graph_reader.node_map.end()) {
258 ShaderNode *fromnode = (ShaderNode *)graph_reader.node_map[from_node_name];
259
260 foreach (ShaderOutput *out, fromnode->outputs)
261 if (string_iequals(out->socket_type.name.string(), from_socket_name.string())) {
262 output = out;
263 }
264
265 if (!output) {
266 fprintf(stderr,
267 "Unknown output socket name \"%s\" on \"%s\".\n",
268 from_node_name.c_str(),
269 from_socket_name.c_str());
270 }
271 }
272 else {
273 fprintf(stderr, "Unknown shader node name \"%s\".\n", from_node_name.c_str());
274 }
275
276 if (graph_reader.node_map.find(to_node_name) != graph_reader.node_map.end()) {
277 ShaderNode *tonode = (ShaderNode *)graph_reader.node_map[to_node_name];
278
279 foreach (ShaderInput *in, tonode->inputs)
280 if (string_iequals(in->socket_type.name.string(), to_socket_name.string())) {
281 input = in;
282 }
283
284 if (!input) {
285 fprintf(stderr,
286 "Unknown input socket name \"%s\" on \"%s\".\n",
287 to_socket_name.c_str(),
288 to_node_name.c_str());
289 }
290 }
291 else {
292 fprintf(stderr, "Unknown shader node name \"%s\".\n", to_node_name.c_str());
293 }
294
295 /* connect */
296 if (output && input) {
297 graph->connect(output, input);
298 }
299 }
300 else {
301 fprintf(stderr, "Invalid from or to value for connect node.\n");
302 }
303
304 continue;
305 }
306
307 ShaderNode *snode = NULL;
308
309#ifdef WITH_OSL
310 if (node_name == "osl_shader") {
311 ShaderManager *manager = state.scene->shader_manager;
312
313 if (manager->use_osl()) {
314 std::string filepath;
315
316 if (xml_read_string(&filepath, node, "src")) {
317 if (path_is_relative(filepath)) {
318 filepath = path_join(state.base, filepath);
319 }
320
321 snode = OSLShaderManager::osl_node(graph, manager, filepath, "");
322
323 if (!snode) {
324 fprintf(stderr, "Failed to create OSL node from \"%s\".\n", filepath.c_str());
325 continue;
326 }
327 }
328 else {
329 fprintf(stderr, "OSL node missing \"src\" attribute.\n");
330 continue;
331 }
332 }
333 else {
334 fprintf(stderr, "OSL node without using --shadingsys osl.\n");
335 continue;
336 }
337 }
338 else
339#endif
340 {
341 /* exception for name collision */
342 if (node_name == "background") {
343 node_name = "background_shader";
344 }
345
346 const NodeType *node_type = NodeType::find(node_name);
347
348 if (!node_type) {
349 fprintf(stderr, "Unknown shader node \"%s\".\n", node.name());
350 continue;
351 }
352 else if (node_type->type != NodeType::SHADER) {
353 fprintf(stderr, "Node type \"%s\" is not a shader node.\n", node_type->name.c_str());
354 continue;
355 }
356 else if (node_type->create == NULL) {
357 fprintf(stderr, "Can't create abstract node type \"%s\".\n", node_type->name.c_str());
358 continue;
359 }
360
361 snode = (ShaderNode *)node_type->create(node_type);
362 snode->set_owner(graph);
363 }
364
365 xml_read_node(graph_reader, snode, node);
366
367 if (node_name == "image_texture") {
368 ImageTextureNode *img = (ImageTextureNode *)snode;
369 ustring filename(path_join(state.base, img->get_filename().string()));
370 img->set_filename(filename);
371 }
372 else if (node_name == "environment_texture") {
374 ustring filename(path_join(state.base, env->get_filename().string()));
375 env->set_filename(filename);
376 }
377
378 if (snode) {
379 /* add to graph */
380 graph->add(snode);
381 }
382 }
383
384 shader->set_graph(graph);
385 shader->tag_update(state.scene);
386}
387
388static void xml_read_shader(XMLReadState &state, xml_node node)
389{
390 Shader *shader = new Shader();
391 xml_read_shader_graph(state, shader, node);
392 state.scene->shaders.push_back(shader);
393}
394
395/* Background */
396
397static void xml_read_background(XMLReadState &state, xml_node node)
398{
399 /* Background Settings */
400 xml_read_node(state, state.scene->background, node);
401
402 /* Background Shader */
403 Shader *shader = state.scene->default_background;
404 xml_read_shader_graph(state, shader, node);
405}
406
407/* Mesh */
408
409static Mesh *xml_add_mesh(Scene *scene, const Transform &tfm, Object *object)
410{
411 if (object && object->get_geometry()->is_mesh()) {
412 /* Use existing object and mesh */
413 object->set_tfm(tfm);
414 Geometry *geometry = object->get_geometry();
415 return static_cast<Mesh *>(geometry);
416 }
417 else {
418 /* Create mesh */
419 Mesh *mesh = new Mesh();
420 scene->geometry.push_back(mesh);
421
422 /* Create object. */
423 Object *object = new Object();
424 object->set_geometry(mesh);
425 object->set_tfm(tfm);
426 scene->objects.push_back(object);
427
428 return mesh;
429 }
430}
431
432static void xml_read_mesh(const XMLReadState &state, xml_node node)
433{
434 /* add mesh */
435 Mesh *mesh = xml_add_mesh(state.scene, state.tfm, state.object);
436 array<Node *> used_shaders = mesh->get_used_shaders();
437 used_shaders.push_back_slow(state.shader);
438 mesh->set_used_shaders(used_shaders);
439
440 /* read state */
441 int shader = 0;
442 bool smooth = state.smooth;
443
444 /* read vertices and polygons */
446 vector<float3> VN; /* Vertex normals */
447 vector<float> UV;
448 vector<float> T; /* UV tangents */
449 vector<float> TS; /* UV tangent signs */
450 vector<int> verts, nverts;
451
452 xml_read_float3_array(P, node, "P");
453 xml_read_int_array(verts, node, "verts");
454 xml_read_int_array(nverts, node, "nverts");
455
456 if (xml_equal_string(node, "subdivision", "catmull-clark")) {
457 mesh->set_subdivision_type(Mesh::SUBDIVISION_CATMULL_CLARK);
458 }
459 else if (xml_equal_string(node, "subdivision", "linear")) {
460 mesh->set_subdivision_type(Mesh::SUBDIVISION_LINEAR);
461 }
462
463 array<float3> P_array;
464 P_array = P;
465
466 if (mesh->get_subdivision_type() == Mesh::SUBDIVISION_NONE) {
467 /* create vertices */
468
469 mesh->set_verts(P_array);
470
471 size_t num_triangles = 0;
472 for (size_t i = 0; i < nverts.size(); i++) {
473 num_triangles += nverts[i] - 2;
474 }
475 mesh->reserve_mesh(mesh->get_verts().size(), num_triangles);
476
477 /* create triangles */
478 int index_offset = 0;
479
480 for (size_t i = 0; i < nverts.size(); i++) {
481 for (int j = 0; j < nverts[i] - 2; j++) {
482 int v0 = verts[index_offset];
483 int v1 = verts[index_offset + j + 1];
484 int v2 = verts[index_offset + j + 2];
485
486 assert(v0 < (int)P.size());
487 assert(v1 < (int)P.size());
488 assert(v2 < (int)P.size());
489
490 mesh->add_triangle(v0, v1, v2, shader, smooth);
491 }
492
493 index_offset += nverts[i];
494 }
495
496 /* Vertex normals */
498 Attribute *attr = mesh->attributes.add(ATTR_STD_VERTEX_NORMAL);
499 float3 *fdata = attr->data_float3();
500
501 /* Loop over the normals */
502 for (auto n : VN) {
503 fdata[0] = n;
504 fdata++;
505 }
506 }
507
508 /* UV map */
509 if (xml_read_float_array(UV, node, "UV") ||
511 {
512 Attribute *attr = mesh->attributes.add(ATTR_STD_UV);
513 float2 *fdata = attr->data_float2();
514
515 /* Loop over the triangles */
516 index_offset = 0;
517 for (size_t i = 0; i < nverts.size(); i++) {
518 for (int j = 0; j < nverts[i] - 2; j++) {
519 int v0 = index_offset;
520 int v1 = index_offset + j + 1;
521 int v2 = index_offset + j + 2;
522
523 assert(v0 * 2 + 1 < (int)UV.size());
524 assert(v1 * 2 + 1 < (int)UV.size());
525 assert(v2 * 2 + 1 < (int)UV.size());
526
527 fdata[0] = make_float2(UV[v0 * 2], UV[v0 * 2 + 1]);
528 fdata[1] = make_float2(UV[v1 * 2], UV[v1 * 2 + 1]);
529 fdata[2] = make_float2(UV[v2 * 2], UV[v2 * 2 + 1]);
530 fdata += 3;
531 }
532
533 index_offset += nverts[i];
534 }
535 }
536
537 /* Tangents */
539 Attribute *attr = mesh->attributes.add(ATTR_STD_UV_TANGENT);
540 float3 *fdata = attr->data_float3();
541
542 /* Loop over the triangles */
543 index_offset = 0;
544 for (size_t i = 0; i < nverts.size(); i++) {
545 for (int j = 0; j < nverts[i] - 2; j++) {
546 int v0 = index_offset;
547 int v1 = index_offset + j + 1;
548 int v2 = index_offset + j + 2;
549
550 assert(v0 * 3 + 2 < (int)T.size());
551 assert(v1 * 3 + 2 < (int)T.size());
552 assert(v2 * 3 + 2 < (int)T.size());
553
554 fdata[0] = make_float3(T[v0 * 3], T[v0 * 3 + 1], T[v0 * 3 + 2]);
555 fdata[1] = make_float3(T[v1 * 3], T[v1 * 3 + 1], T[v1 * 3 + 2]);
556 fdata[2] = make_float3(T[v2 * 3], T[v2 * 3 + 1], T[v2 * 3 + 2]);
557 fdata += 3;
558 }
559 index_offset += nverts[i];
560 }
561 }
562
563 /* Tangent signs */
565 Attribute *attr = mesh->attributes.add(ATTR_STD_UV_TANGENT_SIGN);
566 float *fdata = attr->data_float();
567
568 /* Loop over the triangles */
569 index_offset = 0;
570 for (size_t i = 0; i < nverts.size(); i++) {
571 for (int j = 0; j < nverts[i] - 2; j++) {
572 int v0 = index_offset;
573 int v1 = index_offset + j + 1;
574 int v2 = index_offset + j + 2;
575
576 assert(v0 < (int)TS.size());
577 assert(v1 < (int)TS.size());
578 assert(v2 < (int)TS.size());
579
580 fdata[0] = TS[v0];
581 fdata[1] = TS[v1];
582 fdata[2] = TS[v2];
583 fdata += 3;
584 }
585 index_offset += nverts[i];
586 }
587 }
588 }
589 else {
590 /* create vertices */
591 mesh->set_verts(P_array);
592
593 size_t num_ngons = 0;
594 size_t num_corners = 0;
595 for (size_t i = 0; i < nverts.size(); i++) {
596 num_ngons += (nverts[i] == 4) ? 0 : 1;
597 num_corners += nverts[i];
598 }
599 mesh->reserve_subd_faces(nverts.size(), num_ngons, num_corners);
600
601 /* create subd_faces */
602 int index_offset = 0;
603
604 for (size_t i = 0; i < nverts.size(); i++) {
605 mesh->add_subd_face(&verts[index_offset], nverts[i], shader, smooth);
606 index_offset += nverts[i];
607 }
608
609 /* UV map */
610 if (xml_read_float_array(UV, node, "UV") ||
612 {
613 Attribute *attr = mesh->subd_attributes.add(ATTR_STD_UV);
614 float3 *fdata = attr->data_float3();
615
616#if 0
617 if (subdivide_uvs) {
618 attr->flags |= ATTR_SUBDIVIDED;
619 }
620#endif
621
622 index_offset = 0;
623 for (size_t i = 0; i < nverts.size(); i++) {
624 for (int j = 0; j < nverts[i]; j++) {
625 *(fdata++) = make_float3(UV[index_offset++]);
626 }
627 }
628 }
629
630 /* setup subd params */
631 float dicing_rate = state.dicing_rate;
632 xml_read_float(&dicing_rate, node, "dicing_rate");
633 dicing_rate = std::max(0.1f, dicing_rate);
634
635 mesh->set_subd_dicing_rate(dicing_rate);
636 mesh->set_subd_objecttoworld(state.tfm);
637 }
638
639 /* we don't yet support arbitrary attributes, for now add vertex
640 * coordinates as generated coordinates if requested */
641 if (mesh->need_attribute(state.scene, ATTR_STD_GENERATED)) {
642 Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
643 memcpy(
644 attr->data_float3(), mesh->get_verts().data(), sizeof(float3) * mesh->get_verts().size());
645 }
646}
647
648/* Light */
649
650static void xml_read_light(XMLReadState &state, xml_node node)
651{
652 Light *light = new Light();
653
654 light->set_shader(state.shader);
655 xml_read_node(state, light, node);
656
657 state.scene->lights.push_back(light);
658}
659
660/* Transform */
661
662static void xml_read_transform(xml_node node, Transform &tfm)
663{
664 if (node.attribute("matrix")) {
665 vector<float> matrix;
666 if (xml_read_float_array(matrix, node, "matrix") && matrix.size() == 16) {
667 ProjectionTransform projection = *(ProjectionTransform *)&matrix[0];
668 tfm = tfm * projection_to_transform(projection_transpose(projection));
669 }
670 }
671
672 if (node.attribute("translate")) {
673 float3 translate = zero_float3();
674 xml_read_float3(&translate, node, "translate");
675 tfm = tfm * transform_translate(translate);
676 }
677
678 if (node.attribute("rotate")) {
679 float4 rotate = zero_float4();
680 xml_read_float4(&rotate, node, "rotate");
681 tfm = tfm * transform_rotate(DEG2RADF(rotate.x), make_float3(rotate.y, rotate.z, rotate.w));
682 }
683
684 if (node.attribute("scale")) {
685 float3 scale = zero_float3();
686 xml_read_float3(&scale, node, "scale");
687 tfm = tfm * transform_scale(scale);
688 }
689}
690
691/* State */
692
693static void xml_read_state(XMLReadState &state, xml_node node)
694{
695 /* Read shader */
696 string shadername;
697
698 if (xml_read_string(&shadername, node, "shader")) {
699 bool found = false;
700
701 foreach (Shader *shader, state.scene->shaders) {
702 if (shader->name == shadername) {
703 state.shader = shader;
704 found = true;
705 break;
706 }
707 }
708
709 if (!found) {
710 fprintf(stderr, "Unknown shader \"%s\".\n", shadername.c_str());
711 }
712 }
713
714 /* Read object */
715 string objectname;
716
717 if (xml_read_string(&objectname, node, "object")) {
718 bool found = false;
719
720 foreach (Object *object, state.scene->objects) {
721 if (object->name == objectname) {
722 state.object = object;
723 found = true;
724 break;
725 }
726 }
727
728 if (!found) {
729 fprintf(stderr, "Unknown object \"%s\".\n", objectname.c_str());
730 }
731 }
732
733 xml_read_float(&state.dicing_rate, node, "dicing_rate");
734
735 /* read smooth/flat */
736 if (xml_equal_string(node, "interpolation", "smooth")) {
737 state.smooth = true;
738 }
739 else if (xml_equal_string(node, "interpolation", "flat")) {
740 state.smooth = false;
741 }
742}
743
744/* Object */
745
746static void xml_read_object(XMLReadState &state, xml_node node)
747{
748 Scene *scene = state.scene;
749
750 /* create mesh */
751 Mesh *mesh = new Mesh();
752 scene->geometry.push_back(mesh);
753
754 /* create object */
755 Object *object = new Object();
756 object->set_geometry(mesh);
757 object->set_tfm(state.tfm);
758
759 xml_read_node(state, object, node);
760
761 scene->objects.push_back(object);
762}
763
764/* Scene */
765
766static void xml_read_include(XMLReadState &state, const string &src);
767
768static void xml_read_scene(XMLReadState &state, xml_node scene_node)
769{
770 for (xml_node node = scene_node.first_child(); node; node = node.next_sibling()) {
771 if (string_iequals(node.name(), "film")) {
772 xml_read_node(state, state.scene->film, node);
773 }
774 else if (string_iequals(node.name(), "integrator")) {
775 xml_read_node(state, state.scene->integrator, node);
776 }
777 else if (string_iequals(node.name(), "camera")) {
778 xml_read_camera(state, node);
779 }
780 else if (string_iequals(node.name(), "shader")) {
781 xml_read_shader(state, node);
782 }
783 else if (string_iequals(node.name(), "background")) {
785 }
786 else if (string_iequals(node.name(), "mesh")) {
787 xml_read_mesh(state, node);
788 }
789 else if (string_iequals(node.name(), "light")) {
790 xml_read_light(state, node);
791 }
792 else if (string_iequals(node.name(), "transform")) {
793 XMLReadState substate = state;
794
795 xml_read_transform(node, substate.tfm);
796 xml_read_scene(substate, node);
797 }
798 else if (string_iequals(node.name(), "state")) {
799 XMLReadState substate = state;
800
801 xml_read_state(substate, node);
802 xml_read_scene(substate, node);
803 }
804 else if (string_iequals(node.name(), "include")) {
805 string src;
806
807 if (xml_read_string(&src, node, "src")) {
809 }
810 }
811 else if (string_iequals(node.name(), "object")) {
812 XMLReadState substate = state;
813
814 xml_read_object(substate, node);
815 xml_read_scene(substate, node);
816 }
817#ifdef WITH_ALEMBIC
818 else if (string_iequals(node.name(), "alembic")) {
819 xml_read_alembic(state, node);
820 }
821#endif
822 else {
823 fprintf(stderr, "Unknown node \"%s\".\n", node.name());
824 }
825 }
826}
827
828/* Include */
829
830static void xml_read_include(XMLReadState &state, const string &src)
831{
832 /* open XML document */
833 xml_document doc;
834 xml_parse_result parse_result;
835
836 string path = path_join(state.base, src);
837 parse_result = doc.load_file(path.c_str());
838
839 if (parse_result) {
840 XMLReadState substate = state;
841 substate.base = path_dirname(path);
842
843 xml_node cycles = doc.child("cycles");
844 xml_read_scene(substate, cycles);
845 }
846 else {
847 fprintf(stderr, "%s read error: %s\n", src.c_str(), parse_result.description());
848 exit(EXIT_FAILURE);
849 }
850}
851
852/* File */
853
854void xml_read_file(Scene *scene, const char *filepath)
855{
857
858 state.scene = scene;
860 state.shader = scene->default_surface;
861 state.smooth = false;
862 state.dicing_rate = 1.0f;
863 state.base = path_dirname(filepath);
864
866
867 scene->params.bvh_type = BVH_TYPE_STATIC;
868}
869
#define DEG2RADF(_deg)
struct Light Light
struct Mesh Mesh
struct Object Object
ATTR_WARN_UNUSED_RESULT const BMVert * v2
static const char * standard_name(AttributeStandard std)
float * data_float()
float3 * data_float3()
void add(const float &f)
float2 * data_float2()
virtual bool use_osl()
vector< ShaderOutput * > outputs
size_t size() const
void push_back_slow(const T &t)
ccl_device_inline Transform projection_to_transform(const ProjectionTransform &a)
ccl_device_inline ProjectionTransform projection_transpose(const ProjectionTransform &a)
static bool xml_read_float4(float4 *value, xml_node node, const char *name)
static bool xml_read_float3(float3 *value, xml_node node, const char *name)
static void xml_read_include(XMLReadState &state, const string &src)
static void xml_read_object(XMLReadState &state, xml_node node)
static void xml_read_shader_graph(XMLReadState &state, Shader *shader, xml_node graph_node)
static bool xml_read_int_array(vector< int > &value, xml_node node, const char *name)
static bool xml_read_int(int *value, xml_node node, const char *name)
static bool xml_read_float_array(vector< float > &value, xml_node node, const char *name)
static Mesh * xml_add_mesh(Scene *scene, const Transform &tfm, Object *object)
void xml_read_file(Scene *scene, const char *filepath)
static bool xml_read_string(string *str, xml_node node, const char *name)
static void xml_read_mesh(const XMLReadState &state, xml_node node)
static bool xml_equal_string(xml_node node, const char *name, const char *value)
static bool xml_read_float3_array(vector< float3 > &value, xml_node node, const char *name)
static void xml_read_light(XMLReadState &state, xml_node node)
static void xml_read_state(XMLReadState &state, xml_node node)
static void xml_read_camera(XMLReadState &state, xml_node node)
static void xml_read_transform(xml_node node, Transform &tfm)
static bool xml_read_float(float *value, xml_node node, const char *name)
static void xml_read_scene(XMLReadState &state, xml_node scene_node)
static void xml_read_shader(XMLReadState &state, xml_node node)
static void xml_read_background(XMLReadState &state, xml_node node)
OperationNode * node
#define CCL_NAMESPACE_END
ccl_device_forceinline float4 make_float4(const float x, const float y, const float z, const float w)
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#define NULL
ccl_device_forceinline float2 make_float2(const float x, const float y)
draw_view in_light_buf[] float
#define str(s)
static float verts[][3]
@ ATTR_STD_UV
@ ATTR_STD_VERTEX_NORMAL
@ ATTR_STD_UV_TANGENT
@ ATTR_STD_UV_TANGENT_SIGN
@ ATTR_STD_GENERATED
@ ATTR_SUBDIVIDED
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:15
CCL_NAMESPACE_BEGIN ccl_device_inline float4 zero_float4()
Definition math_float4.h:15
static ulong state[N]
#define T
void xml_read_node(XMLReader &reader, Node *node, xml_node xml_node)
Definition node_xml.cpp:43
@ BVH_TYPE_STATIC
Definition params.h:41
string path_dirname(const string &path)
Definition path.cpp:403
bool path_is_relative(const string &path)
Definition path.cpp:446
string path_join(const string &dir, const string &file)
Definition path.cpp:417
string path_filename(const string &path)
Definition path.cpp:380
bool string_iequals(const string &a, const string &b)
Definition string.cpp:55
void string_split(vector< string > &tokens, const string &str, const string &separators, bool skip_empty_tokens)
Definition string.cpp:70
bool need_flags_update
void update(Scene *scene)
@ SUBDIVISION_NONE
Definition scene/mesh.h:121
@ SUBDIVISION_LINEAR
Definition scene/mesh.h:122
@ SUBDIVISION_CATMULL_CLARK
Definition scene/mesh.h:123
Type type
Definition node_type.h:123
static const NodeType * find(ustring name)
CreateFunc create
Definition node_type.h:127
ustring name
Definition node_type.h:122
void set_owner(const NodeOwner *owner_)
Scene * scene
Transform tfm
Shader * shader
Object * object
float dicing_rate
map< ustring, Node * > node_map
Definition node_xml.h:16
ccl_device_inline Transform transform_identity()
Definition transform.h:296
ccl_device_inline Transform transform_rotate(float angle, float3 axis)
Definition transform.h:264
ccl_device_inline Transform transform_translate(float3 t)
Definition transform.h:244
ccl_device_inline Transform transform_scale(float3 s)
Definition transform.h:254