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