Blender  V2.93
node_xml.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2016 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 "graph/node_xml.h"
18 
19 #include "util/util_foreach.h"
20 #include "util/util_string.h"
21 #include "util/util_transform.h"
22 
24 
25 static bool xml_read_boolean(const char *value)
26 {
27  return string_iequals(value, "true") || (atoi(value) != 0);
28 }
29 
30 static const char *xml_write_boolean(bool value)
31 {
32  return (value) ? "true" : "false";
33 }
34 
35 template<int VECTOR_SIZE, typename T>
36 static void xml_read_float_array(T &value, xml_attribute attr)
37 {
38  vector<string> tokens;
39  string_split(tokens, attr.value());
40 
41  if (tokens.size() % VECTOR_SIZE != 0) {
42  return;
43  }
44 
45  value.resize(tokens.size() / VECTOR_SIZE);
46  for (size_t i = 0; i < value.size(); i++) {
47  float *value_float = (float *)&value[i];
48 
49  for (size_t j = 0; j < VECTOR_SIZE; j++)
50  value_float[j] = (float)atof(tokens[i * VECTOR_SIZE + j].c_str());
51  }
52 }
53 
54 void xml_read_node(XMLReader &reader, Node *node, xml_node xml_node)
55 {
56  xml_attribute name_attr = xml_node.attribute("name");
57  if (name_attr) {
58  node->name = ustring(name_attr.value());
59  }
60 
61  foreach (const SocketType &socket, node->type->inputs) {
62  if (socket.type == SocketType::CLOSURE || socket.type == SocketType::UNDEFINED) {
63  continue;
64  }
65  if (socket.flags & SocketType::INTERNAL) {
66  continue;
67  }
68 
69  xml_attribute attr = xml_node.attribute(socket.name.c_str());
70 
71  if (!attr) {
72  continue;
73  }
74 
75  switch (socket.type) {
76  case SocketType::BOOLEAN: {
77  node->set(socket, xml_read_boolean(attr.value()));
78  break;
79  }
81  vector<string> tokens;
82  string_split(tokens, attr.value());
83 
84  array<bool> value;
85  value.resize(tokens.size());
86  for (size_t i = 0; i < value.size(); i++)
87  value[i] = xml_read_boolean(tokens[i].c_str());
88  node->set(socket, value);
89  break;
90  }
91  case SocketType::FLOAT: {
92  node->set(socket, (float)atof(attr.value()));
93  break;
94  }
96  array<float> value;
97  xml_read_float_array<1>(value, attr);
98  node->set(socket, value);
99  break;
100  }
101  case SocketType::INT: {
102  node->set(socket, (int)atoi(attr.value()));
103  break;
104  }
105  case SocketType::UINT: {
106  node->set(socket, (uint)atoi(attr.value()));
107  break;
108  }
109  case SocketType::INT_ARRAY: {
110  vector<string> tokens;
111  string_split(tokens, attr.value());
112 
113  array<int> value;
114  value.resize(tokens.size());
115  for (size_t i = 0; i < value.size(); i++) {
116  value[i] = (int)atoi(attr.value());
117  }
118  node->set(socket, value);
119  break;
120  }
121  case SocketType::COLOR:
122  case SocketType::VECTOR:
123  case SocketType::POINT:
124  case SocketType::NORMAL: {
125  array<float3> value;
126  xml_read_float_array<3>(value, attr);
127  if (value.size() == 1) {
128  node->set(socket, value[0]);
129  }
130  break;
131  }
136  array<float3> value;
137  xml_read_float_array<3>(value, attr);
138  node->set(socket, value);
139  break;
140  }
141  case SocketType::POINT2: {
142  array<float2> value;
143  xml_read_float_array<2>(value, attr);
144  if (value.size() == 1) {
145  node->set(socket, value[0]);
146  }
147  break;
148  }
150  array<float2> value;
151  xml_read_float_array<2>(value, attr);
152  node->set(socket, value);
153  break;
154  }
155  case SocketType::STRING: {
156  node->set(socket, attr.value());
157  break;
158  }
159  case SocketType::ENUM: {
160  ustring value(attr.value());
161  if (socket.enum_values->exists(value)) {
162  node->set(socket, value);
163  }
164  else {
165  fprintf(stderr,
166  "Unknown value \"%s\" for attribute \"%s\".\n",
167  value.c_str(),
168  socket.name.c_str());
169  }
170  break;
171  }
173  vector<string> tokens;
174  string_split(tokens, attr.value());
175 
176  array<ustring> value;
177  value.resize(tokens.size());
178  for (size_t i = 0; i < value.size(); i++) {
179  value[i] = ustring(tokens[i]);
180  }
181  node->set(socket, value);
182  break;
183  }
184  case SocketType::TRANSFORM: {
185  array<Transform> value;
186  xml_read_float_array<12>(value, attr);
187  if (value.size() == 1) {
188  node->set(socket, value[0]);
189  }
190  break;
191  }
193  array<Transform> value;
194  xml_read_float_array<12>(value, attr);
195  node->set(socket, value);
196  break;
197  }
198  case SocketType::NODE: {
199  ustring value(attr.value());
200  map<ustring, Node *>::iterator it = reader.node_map.find(value);
201  if (it != reader.node_map.end()) {
202  Node *value_node = it->second;
203  if (value_node->is_a(socket.node_type))
204  node->set(socket, it->second);
205  }
206  break;
207  }
208  case SocketType::NODE_ARRAY: {
209  vector<string> tokens;
210  string_split(tokens, attr.value());
211 
212  array<Node *> value;
213  value.resize(tokens.size());
214  for (size_t i = 0; i < value.size(); i++) {
215  map<ustring, Node *>::iterator it = reader.node_map.find(ustring(tokens[i]));
216  if (it != reader.node_map.end()) {
217  Node *value_node = it->second;
218  value[i] = (value_node->is_a(socket.node_type)) ? value_node : NULL;
219  }
220  else {
221  value[i] = NULL;
222  }
223  }
224  node->set(socket, value);
225  break;
226  }
227  case SocketType::CLOSURE:
229  break;
230  }
231  }
232 
233  if (!node->name.empty())
234  reader.node_map[node->name] = node;
235 }
236 
237 xml_node xml_write_node(Node *node, xml_node xml_root)
238 {
239  xml_node xml_node = xml_root.append_child(node->type->name.c_str());
240 
241  xml_node.append_attribute("name") = node->name.c_str();
242 
243  foreach (const SocketType &socket, node->type->inputs) {
244  if (socket.type == SocketType::CLOSURE || socket.type == SocketType::UNDEFINED) {
245  continue;
246  }
247  if (socket.flags & SocketType::INTERNAL) {
248  continue;
249  }
250  if (node->has_default_value(socket)) {
251  continue;
252  }
253 
254  xml_attribute attr = xml_node.append_attribute(socket.name.c_str());
255 
256  switch (socket.type) {
257  case SocketType::BOOLEAN: {
258  attr = xml_write_boolean(node->get_bool(socket));
259  break;
260  }
262  std::stringstream ss;
263  const array<bool> &value = node->get_bool_array(socket);
264  for (size_t i = 0; i < value.size(); i++) {
265  ss << xml_write_boolean(value[i]);
266  if (i != value.size() - 1)
267  ss << " ";
268  }
269  attr = ss.str().c_str();
270  break;
271  }
272  case SocketType::FLOAT: {
273  attr = (double)node->get_float(socket);
274  break;
275  }
277  std::stringstream ss;
278  const array<float> &value = node->get_float_array(socket);
279  for (size_t i = 0; i < value.size(); i++) {
280  ss << value[i];
281  if (i != value.size() - 1) {
282  ss << " ";
283  }
284  }
285  attr = ss.str().c_str();
286  break;
287  }
288  case SocketType::INT: {
289  attr = node->get_int(socket);
290  break;
291  }
292  case SocketType::UINT: {
293  attr = node->get_uint(socket);
294  break;
295  }
296  case SocketType::INT_ARRAY: {
297  std::stringstream ss;
298  const array<int> &value = node->get_int_array(socket);
299  for (size_t i = 0; i < value.size(); i++) {
300  ss << value[i];
301  if (i != value.size() - 1) {
302  ss << " ";
303  }
304  }
305  attr = ss.str().c_str();
306  break;
307  }
308  case SocketType::COLOR:
309  case SocketType::VECTOR:
310  case SocketType::POINT:
311  case SocketType::NORMAL: {
312  float3 value = node->get_float3(socket);
313  attr =
314  string_printf("%g %g %g", (double)value.x, (double)value.y, (double)value.z).c_str();
315  break;
316  }
321  std::stringstream ss;
322  const array<float3> &value = node->get_float3_array(socket);
323  for (size_t i = 0; i < value.size(); i++) {
324  ss << string_printf(
325  "%g %g %g", (double)value[i].x, (double)value[i].y, (double)value[i].z);
326  if (i != value.size() - 1) {
327  ss << " ";
328  }
329  }
330  attr = ss.str().c_str();
331  break;
332  }
333  case SocketType::POINT2: {
334  float2 value = node->get_float2(socket);
335  attr = string_printf("%g %g", (double)value.x, (double)value.y).c_str();
336  break;
337  }
339  std::stringstream ss;
340  const array<float2> &value = node->get_float2_array(socket);
341  for (size_t i = 0; i < value.size(); i++) {
342  ss << string_printf("%g %g", (double)value[i].x, (double)value[i].y);
343  if (i != value.size() - 1) {
344  ss << " ";
345  }
346  }
347  attr = ss.str().c_str();
348  break;
349  }
350  case SocketType::STRING:
351  case SocketType::ENUM: {
352  attr = node->get_string(socket).c_str();
353  break;
354  }
356  std::stringstream ss;
357  const array<ustring> &value = node->get_string_array(socket);
358  for (size_t i = 0; i < value.size(); i++) {
359  ss << value[i];
360  if (i != value.size() - 1) {
361  ss << " ";
362  }
363  }
364  attr = ss.str().c_str();
365  break;
366  }
367  case SocketType::TRANSFORM: {
368  Transform tfm = node->get_transform(socket);
369  std::stringstream ss;
370  for (int i = 0; i < 3; i++) {
371  ss << string_printf("%g %g %g %g ",
372  (double)tfm[i][0],
373  (double)tfm[i][1],
374  (double)tfm[i][2],
375  (double)tfm[i][3]);
376  }
377  ss << string_printf("%g %g %g %g", 0.0, 0.0, 0.0, 1.0);
378  attr = ss.str().c_str();
379  break;
380  }
382  std::stringstream ss;
383  const array<Transform> &value = node->get_transform_array(socket);
384  for (size_t j = 0; j < value.size(); j++) {
385  const Transform &tfm = value[j];
386 
387  for (int i = 0; i < 3; i++) {
388  ss << string_printf("%g %g %g %g ",
389  (double)tfm[i][0],
390  (double)tfm[i][1],
391  (double)tfm[i][2],
392  (double)tfm[i][3]);
393  }
394  ss << string_printf("%g %g %g %g", 0.0, 0.0, 0.0, 1.0);
395  if (j != value.size() - 1) {
396  ss << " ";
397  }
398  }
399  attr = ss.str().c_str();
400  break;
401  }
402  case SocketType::NODE: {
403  Node *value = node->get_node(socket);
404  if (value) {
405  attr = value->name.c_str();
406  }
407  break;
408  }
409  case SocketType::NODE_ARRAY: {
410  std::stringstream ss;
411  const array<Node *> &value = node->get_node_array(socket);
412  for (size_t i = 0; i < value.size(); i++) {
413  if (value[i]) {
414  ss << value[i]->name.c_str();
415  }
416  if (i != value.size() - 1) {
417  ss << " ";
418  }
419  }
420  attr = ss.str().c_str();
421  break;
422  }
423  case SocketType::CLOSURE:
425  break;
426  }
427  }
428 
429  return xml_node;
430 }
431 
unsigned int uint
Definition: BLI_sys_types.h:83
typedef double(DMatrix)[4][4]
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
size_t size() const
Definition: util_array.h:203
T * resize(size_t newsize)
Definition: util_array.h:150
OperationNode * node
#define CCL_NAMESPACE_END
#define T
xml_node xml_write_node(Node *node, xml_node xml_root)
Definition: node_xml.cpp:237
static void xml_read_float_array(T &value, xml_attribute attr)
Definition: node_xml.cpp:36
void xml_read_node(XMLReader &reader, Node *node, xml_node xml_node)
Definition: node_xml.cpp:54
static const char * xml_write_boolean(bool value)
Definition: node_xml.cpp:30
static CCL_NAMESPACE_BEGIN bool xml_read_boolean(const char *value)
Definition: node_xml.cpp:25
bool exists(ustring x) const
Definition: node_enum.h:39
Definition: node.h:98
ustring name
Definition: node.h:174
bool is_a(const NodeType *type)
Definition: node.cpp:755
ustring name
Definition: node_type.h:85
const NodeType * node_type
Definition: node_type.h:90
@ BOOLEAN_ARRAY
Definition: node_type.h:54
@ TRANSFORM_ARRAY
Definition: node_type.h:63
@ NODE_ARRAY
Definition: node_type.h:64
@ POINT2_ARRAY
Definition: node_type.h:61
@ FLOAT_ARRAY
Definition: node_type.h:55
@ NORMAL_ARRAY
Definition: node_type.h:60
@ VECTOR_ARRAY
Definition: node_type.h:58
@ POINT_ARRAY
Definition: node_type.h:59
@ STRING_ARRAY
Definition: node_type.h:62
@ COLOR_ARRAY
Definition: node_type.h:57
Type type
Definition: node_type.h:86
const NodeEnum * enum_values
Definition: node_type.h:89
int flags
Definition: node_type.h:91
map< ustring, Node * > node_map
Definition: node_xml.h:28
float z
Definition: sky_float3.h:35
float y
Definition: sky_float3.h:35
float x
Definition: sky_float3.h:35
bool string_iequals(const string &a, const string &b)
Definition: util_string.cpp:64
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
Definition: util_string.cpp:32
void string_split(vector< string > &tokens, const string &str, const string &separators, bool skip_empty_tokens)
Definition: util_string.cpp:77