ClangFormat: apply to source, most of intern
[blender.git] / intern / cycles / graph / node_xml.cpp
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
23 CCL_NAMESPACE_BEGIN
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       }
80       case SocketType::BOOLEAN_ARRAY: {
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       }
95       case SocketType::FLOAT_ARRAY: {
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       }
132       case SocketType::COLOR_ARRAY:
133       case SocketType::VECTOR_ARRAY:
134       case SocketType::POINT_ARRAY:
135       case SocketType::NORMAL_ARRAY: {
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       }
149       case SocketType::POINT2_ARRAY: {
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       }
172       case SocketType::STRING_ARRAY: {
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       }
192       case SocketType::TRANSFORM_ARRAY: {
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->type == *(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->type == *(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:
228       case SocketType::UNDEFINED:
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       }
261       case SocketType::BOOLEAN_ARRAY: {
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       }
276       case SocketType::FLOAT_ARRAY: {
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       }
317       case SocketType::COLOR_ARRAY:
318       case SocketType::VECTOR_ARRAY:
319       case SocketType::POINT_ARRAY:
320       case SocketType::NORMAL_ARRAY: {
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       }
338       case SocketType::POINT2_ARRAY: {
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       }
355       case SocketType::STRING_ARRAY: {
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       }
381       case SocketType::TRANSFORM_ARRAY: {
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:
424       case SocketType::UNDEFINED:
425         break;
426     }
427   }
428
429   return xml_node;
430 }
431
432 CCL_NAMESPACE_END