Cycles: Make all #include statements relative to cycles source directory
[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, pugi::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, pugi::xml_node xml_node)
55 {
56         pugi::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                 pugi::xml_attribute attr = xml_node.attribute(socket.name.c_str());
70
71                 if(!attr) {
72                         continue;
73                 }
74
75                 switch(socket.type)
76                 {
77                         case SocketType::BOOLEAN:
78                         {
79                                 node->set(socket, xml_read_boolean(attr.value()));
80                                 break;
81                         }
82                         case SocketType::BOOLEAN_ARRAY:
83                         {
84                                 vector<string> tokens;
85                                 string_split(tokens, attr.value());
86
87                                 array<bool> value;
88                                 value.resize(tokens.size());
89                                 for(size_t i = 0; i < value.size(); i++)
90                                         value[i] = xml_read_boolean(tokens[i].c_str());
91                                 node->set(socket, value);
92                                 break;
93                         }
94                         case SocketType::FLOAT:
95                         {
96                                 node->set(socket, (float)atof(attr.value()));
97                                 break;
98                         }
99                         case SocketType::FLOAT_ARRAY:
100                         {
101                                 array<float> value;
102                                 xml_read_float_array<1>(value, attr);
103                                 node->set(socket, value);
104                                 break;
105                         }
106                         case SocketType::INT:
107                         {
108                                 node->set(socket, (int)atoi(attr.value()));
109                                 break;
110                         }
111                         case SocketType::UINT:
112                         {
113                                 node->set(socket, (uint)atoi(attr.value()));
114                                 break;
115                         }
116                         case SocketType::INT_ARRAY:
117                         {
118                                 vector<string> tokens;
119                                 string_split(tokens, attr.value());
120
121                                 array<int> value;
122                                 value.resize(tokens.size());
123                                 for(size_t i = 0; i < value.size(); i++) {
124                                         value[i] = (int)atoi(attr.value());
125                                 }
126                                 node->set(socket, value);
127                                 break;
128                         }
129                         case SocketType::COLOR:
130                         case SocketType::VECTOR:
131                         case SocketType::POINT:
132                         case SocketType::NORMAL:
133                         {
134                                 array<float3> value;
135                                 xml_read_float_array<3>(value, attr);
136                                 if(value.size() == 1) {
137                                         node->set(socket, value[0]);
138                                 }
139                                 break;
140                         }
141                         case SocketType::COLOR_ARRAY:
142                         case SocketType::VECTOR_ARRAY:
143                         case SocketType::POINT_ARRAY:
144                         case SocketType::NORMAL_ARRAY:
145                         {
146                                 array<float3> value;
147                                 xml_read_float_array<3>(value, attr);
148                                 node->set(socket, value);
149                                 break;
150                         }
151                         case SocketType::POINT2:
152                         {
153                                 array<float2> value;
154                                 xml_read_float_array<2>(value, attr);
155                                 if(value.size() == 1) {
156                                         node->set(socket, value[0]);
157                                 }
158                                 break;
159                         }
160                         case SocketType::POINT2_ARRAY:
161                         {
162                                 array<float2> value;
163                                 xml_read_float_array<2>(value, attr);
164                                 node->set(socket, value);
165                                 break;
166                         }
167                         case SocketType::STRING:
168                         {
169                                 node->set(socket, attr.value());
170                                 break;
171                         }
172                         case SocketType::ENUM:
173                         {
174                                 ustring value(attr.value());
175                                 if(socket.enum_values->exists(value)) {
176                                         node->set(socket, value);
177                                 }
178                                 else {
179                                         fprintf(stderr, "Unknown value \"%s\" for attribute \"%s\".\n", value.c_str(), socket.name.c_str());
180                                 }
181                                 break;
182                         }
183                         case SocketType::STRING_ARRAY:
184                         {
185                                 vector<string> tokens;
186                                 string_split(tokens, attr.value());
187
188                                 array<ustring> value;
189                                 value.resize(tokens.size());
190                                 for(size_t i = 0; i < value.size(); i++) {
191                                         value[i] = ustring(tokens[i]);
192                                 }
193                                 node->set(socket, value);
194                                 break;
195                         }
196                         case SocketType::TRANSFORM:
197                         {
198                                 array<Transform> value;
199                                 xml_read_float_array<16>(value, attr);
200                                 if(value.size() == 1) {
201                                         node->set(socket, value[0]);
202                                 }
203                                 break;
204                         }
205                         case SocketType::TRANSFORM_ARRAY:
206                         {
207                                 array<Transform> value;
208                                 xml_read_float_array<16>(value, attr);
209                                 node->set(socket, value);
210                                 break;
211                         }
212                         case SocketType::NODE:
213                         {
214                                 ustring value(attr.value());
215                                 map<ustring, Node*>::iterator it = reader.node_map.find(value);
216                                 if(it != reader.node_map.end())
217                                 {
218                                         Node *value_node = it->second;
219                                         if(value_node->type == *(socket.node_type))
220                                                 node->set(socket, it->second);
221                                 }
222                                 break;
223                         }
224                         case SocketType::NODE_ARRAY:
225                         {
226                                 vector<string> tokens;
227                                 string_split(tokens, attr.value());
228
229                                 array<Node*> value;
230                                 value.resize(tokens.size());
231                                 for(size_t i = 0; i < value.size(); i++)
232                                 {
233                                         map<ustring, Node*>::iterator it = reader.node_map.find(ustring(tokens[i]));
234                                         if(it != reader.node_map.end())
235                                         {
236                                                 Node *value_node = it->second;
237                                                 value[i] = (value_node->type == *(socket.node_type)) ? value_node : NULL;
238                                         }
239                                         else
240                                         {
241                                                 value[i] = NULL;
242                                         }
243                                 }
244                                 node->set(socket, value);
245                                 break;
246                         }
247                         case SocketType::CLOSURE:
248                         case SocketType::UNDEFINED:
249                                 break;
250                 }
251         }
252
253         if(node->name)
254                 reader.node_map[node->name] = node;
255 }
256
257 pugi::xml_node xml_write_node(Node *node, pugi::xml_node xml_root)
258 {
259         pugi::xml_node xml_node = xml_root.append_child(node->type->name.c_str());
260
261         xml_node.append_attribute("name") = node->name.c_str();
262
263         foreach(const SocketType& socket, node->type->inputs) {
264                 if(socket.type == SocketType::CLOSURE || socket.type == SocketType::UNDEFINED) {
265                         continue;
266                 }
267                 if(socket.flags & SocketType::INTERNAL) {
268                         continue;
269                 }
270                 if(node->has_default_value(socket)) {
271                         continue;
272                 }
273
274                 pugi::xml_attribute attr = xml_node.append_attribute(socket.name.c_str());
275
276                 switch(socket.type)
277                 {
278                         case SocketType::BOOLEAN:
279                         {
280                                 attr = xml_write_boolean(node->get_bool(socket));
281                                 break;
282                         }
283                         case SocketType::BOOLEAN_ARRAY:
284                         {
285                                 std::stringstream ss;
286                                 const array<bool>& value = node->get_bool_array(socket);
287                                 for(size_t i = 0; i < value.size(); i++) {
288                                         ss << xml_write_boolean(value[i]);
289                                         if(i != value.size() - 1)
290                                                 ss << " ";
291                                 }
292                                 attr = ss.str().c_str();
293                                 break;
294                         }
295                         case SocketType::FLOAT:
296                         {
297                                 attr = (double)node->get_float(socket);
298                                 break;
299                         }
300                         case SocketType::FLOAT_ARRAY:
301                         {
302                                 std::stringstream ss;
303                                 const array<float>& value = node->get_float_array(socket);
304                                 for(size_t i = 0; i < value.size(); i++) {
305                                         ss << value[i];
306                                         if(i != value.size() - 1) {
307                                                 ss << " ";
308                                         }
309                                 }
310                                 attr = ss.str().c_str();
311                                 break;
312                         }
313                         case SocketType::INT:
314                         {
315                                 attr = node->get_int(socket);
316                                 break;
317                         }
318                         case SocketType::UINT:
319                         {
320                                 attr = node->get_uint(socket);
321                                 break;
322                         }
323                         case SocketType::INT_ARRAY:
324                         {
325                                 std::stringstream ss;
326                                 const array<int>& value = node->get_int_array(socket);
327                                 for(size_t i = 0; i < value.size(); i++) {
328                                         ss << value[i];
329                                         if(i != value.size() - 1) {
330                                                 ss << " ";
331                                         }
332                                 }
333                                 attr = ss.str().c_str();
334                                 break;
335                         }
336                         case SocketType::COLOR:
337                         case SocketType::VECTOR:
338                         case SocketType::POINT:
339                         case SocketType::NORMAL:
340                         {
341                                 float3 value = node->get_float3(socket);
342                                 attr = string_printf("%g %g %g", (double)value.x, (double)value.y, (double)value.z).c_str();
343                                 break;
344                         }
345                         case SocketType::COLOR_ARRAY:
346                         case SocketType::VECTOR_ARRAY:
347                         case SocketType::POINT_ARRAY:
348                         case SocketType::NORMAL_ARRAY:
349                         {
350                                 std::stringstream ss;
351                                 const array<float3>& value = node->get_float3_array(socket);
352                                 for(size_t i = 0; i < value.size(); i++) {
353                                         ss << string_printf("%g %g %g", (double)value[i].x, (double)value[i].y, (double)value[i].z);
354                                         if(i != value.size() - 1) {
355                                                 ss << " ";
356                                         }
357                                 }
358                                 attr = ss.str().c_str();
359                                 break;
360                         }
361                         case SocketType::POINT2:
362                         {
363                                 float2 value = node->get_float2(socket);
364                                 attr = string_printf("%g %g", (double)value.x, (double)value.y).c_str();
365                                 break;
366                         }
367                         case SocketType::POINT2_ARRAY:
368                         {
369                                 std::stringstream ss;
370                                 const array<float2>& value = node->get_float2_array(socket);
371                                 for(size_t i = 0; i < value.size(); i++) {
372                                         ss << string_printf("%g %g", (double)value[i].x, (double)value[i].y);
373                                         if(i != value.size() - 1) {
374                                                 ss << " ";
375                                         }
376                                 }
377                                 attr = ss.str().c_str();
378                                 break;
379                         }
380                         case SocketType::STRING:
381                         case SocketType::ENUM:
382                         {
383                                 attr = node->get_string(socket).c_str();
384                                 break;
385                         }
386                         case SocketType::STRING_ARRAY:
387                         {
388                                 std::stringstream ss;
389                                 const array<ustring>& value = node->get_string_array(socket);
390                                 for(size_t i = 0; i < value.size(); i++) {
391                                         ss << value[i];
392                                         if(i != value.size() - 1) {
393                                                 ss << " ";
394                                         }
395                                 }
396                                 attr = ss.str().c_str();
397                                 break;
398                         }
399                         case SocketType::TRANSFORM:
400                         {
401                                 Transform tfm = node->get_transform(socket);
402                                 std::stringstream ss;
403                                 for(int i = 0; i < 4; i++) {
404                                         ss << string_printf("%g %g %g %g", (double)tfm[i][0], (double)tfm[i][1], (double)tfm[i][2], (double)tfm[i][3]);
405                                         if(i != 3) {
406                                                 ss << " ";
407                                         }
408                                 }
409                                 attr = ss.str().c_str();
410                                 break;
411                         }
412                         case SocketType::TRANSFORM_ARRAY:
413                         {
414                                 std::stringstream ss;
415                                 const array<Transform>& value = node->get_transform_array(socket);
416                                 for(size_t j = 0; j < value.size(); j++) {
417                                         const Transform& tfm = value[j];
418
419                                         for(int i = 0; i < 4; i++) {
420                                                 ss << string_printf("%g %g %g %g", (double)tfm[i][0], (double)tfm[i][1], (double)tfm[i][2], (double)tfm[i][3]);
421                                                 if(j != value.size() - 1 || i != 3) {
422                                                         ss << " ";
423                                                 }
424                                         }
425                                 }
426                                 attr = ss.str().c_str();
427                                 break;
428                         }
429                         case SocketType::NODE:
430                         {
431                                 Node *value = node->get_node(socket);
432                                 if(value) {
433                                         attr = value->name.c_str();
434                                 }
435                                 break;
436                         }
437                         case SocketType::NODE_ARRAY:
438                         {
439                                 std::stringstream ss;
440                                 const array<Node*>& value = node->get_node_array(socket);
441                                 for(size_t i = 0; i < value.size(); i++) {
442                                         if(value[i]) {
443                                                 ss << value[i]->name.c_str();
444                                         }
445                                         if(i != value.size() - 1) {
446                                                 ss << " ";
447                                         }
448                                 }
449                                 attr = ss.str().c_str();
450                                 break;
451                         }
452                         case SocketType::CLOSURE:
453                         case SocketType::UNDEFINED:
454                                 break;
455                 }
456         }
457
458         return xml_node;
459 }
460
461 CCL_NAMESPACE_END
462