Fix T48604: Crash on undo due to bad drawing code.
[blender.git] / intern / cycles / graph / node.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 "node.h"
18 #include "node_type.h"
19
20 #include "util_foreach.h"
21 #include "util_param.h"
22 #include "util_transform.h"
23
24 CCL_NAMESPACE_BEGIN
25
26 /* Node Type */
27
28 Node::Node(const NodeType *type_, ustring name_)
29 : name(name_), type(type_)
30 {
31         assert(type);
32
33         /* assign non-empty name, convenient for debugging */
34         if(name.empty()) {
35                 name = type->name;
36         }
37
38         /* initialize default values */
39         foreach(const SocketType& socket, type->inputs) {
40                 set_default_value(socket);
41         }
42 }
43
44 Node::~Node()
45 {
46 }
47
48 template<typename T>
49 static T& get_socket_value(const Node *node, const SocketType& socket)
50 {
51         return (T&)*(((char*)node) + socket.struct_offset);
52 }
53
54 #ifndef NDEBUG
55 static bool is_socket_float3(const SocketType& socket)
56 {
57         return socket.type == SocketType::COLOR ||
58                socket.type == SocketType::POINT ||
59                    socket.type == SocketType::VECTOR ||
60                    socket.type == SocketType::NORMAL;
61 }
62
63 static bool is_socket_array_float3(const SocketType& socket)
64 {
65         return socket.type == SocketType::COLOR_ARRAY ||
66                socket.type == SocketType::POINT_ARRAY ||
67                    socket.type == SocketType::VECTOR_ARRAY ||
68                    socket.type == SocketType::NORMAL_ARRAY;
69 }
70 #endif
71
72 /* set values */
73 void Node::set(const SocketType& input, bool value)
74 {
75         assert(input.type == SocketType::BOOLEAN);
76         get_socket_value<bool>(this, input) = value;
77 }
78
79 void Node::set(const SocketType& input, int value)
80 {
81         assert((input.type == SocketType::INT || input.type == SocketType::ENUM));
82         get_socket_value<int>(this, input) = value;
83 }
84
85 void Node::set(const SocketType& input, float value)
86 {
87         assert(input.type == SocketType::FLOAT);
88         get_socket_value<float>(this, input) = value;
89 }
90
91 void Node::set(const SocketType& input, float2 value)
92 {
93         assert(input.type == SocketType::FLOAT);
94         get_socket_value<float2>(this, input) = value;
95 }
96
97 void Node::set(const SocketType& input, float3 value)
98 {
99         assert(is_socket_float3(input));
100         get_socket_value<float3>(this, input) = value;
101 }
102
103 void Node::set(const SocketType& input, const char *value)
104 {
105         set(input, ustring(value));
106 }
107
108 void Node::set(const SocketType& input, ustring value)
109 {
110         if(input.type == SocketType::STRING) {
111                 get_socket_value<ustring>(this, input) = value;
112         }
113         else if(input.type == SocketType::ENUM) {
114                 const NodeEnum& enm = *input.enum_values;
115                 if(enm.exists(value)) {
116                         get_socket_value<int>(this, input) = enm[value];
117                 }
118                 else {
119                         assert(0);
120                 }
121         }
122         else {
123                 assert(0);
124         }
125 }
126
127 void Node::set(const SocketType& input, const Transform& value)
128 {
129         assert(input.type == SocketType::TRANSFORM);
130         get_socket_value<Transform>(this, input) = value;
131 }
132
133 void Node::set(const SocketType& input, Node *value)
134 {
135         assert(input.type == SocketType::TRANSFORM);
136         get_socket_value<Node*>(this, input) = value;
137 }
138
139 /* set array values */
140 void Node::set(const SocketType& input, array<bool>& value)
141 {
142         assert(input.type == SocketType::BOOLEAN_ARRAY);
143         get_socket_value<array<bool> >(this, input).steal_data(value);
144 }
145
146 void Node::set(const SocketType& input, array<int>& value)
147 {
148         assert(input.type == SocketType::INT_ARRAY);
149         get_socket_value<array<int> >(this, input).steal_data(value);
150 }
151
152 void Node::set(const SocketType& input, array<float>& value)
153 {
154         assert(input.type == SocketType::FLOAT_ARRAY);
155         get_socket_value<array<float> >(this, input).steal_data(value);
156 }
157
158 void Node::set(const SocketType& input, array<float2>& value)
159 {
160         assert(input.type == SocketType::FLOAT_ARRAY);
161         get_socket_value<array<float2> >(this, input).steal_data(value);
162 }
163
164 void Node::set(const SocketType& input, array<float3>& value)
165 {
166         assert(is_socket_array_float3(input));
167         get_socket_value<array<float3> >(this, input).steal_data(value);
168 }
169
170 void Node::set(const SocketType& input, array<ustring>& value)
171 {
172         assert(input.type == SocketType::STRING_ARRAY);
173         get_socket_value<array<ustring> >(this, input).steal_data(value);
174 }
175
176 void Node::set(const SocketType& input, array<Transform>& value)
177 {
178         assert(input.type == SocketType::TRANSFORM_ARRAY);
179         get_socket_value<array<Transform> >(this, input).steal_data(value);
180 }
181
182 void Node::set(const SocketType& input, array<Node*>& value)
183 {
184         assert(input.type == SocketType::TRANSFORM_ARRAY);
185         get_socket_value<array<Node*> >(this, input).steal_data(value);
186 }
187
188 /* get values */
189 bool Node::get_bool(const SocketType& input) const
190 {
191         assert(input.type == SocketType::BOOLEAN);
192         return get_socket_value<bool>(this, input);
193 }
194
195 int Node::get_int(const SocketType& input) const
196 {
197         assert(input.type == SocketType::INT || input.type == SocketType::ENUM);
198         return get_socket_value<int>(this, input);
199 }
200
201 float Node::get_float(const SocketType& input) const
202 {
203         assert(input.type == SocketType::FLOAT);
204         return get_socket_value<float>(this, input);
205 }
206
207 float2 Node::get_float2(const SocketType& input) const
208 {
209         assert(input.type == SocketType::FLOAT);
210         return get_socket_value<float2>(this, input);
211 }
212
213 float3 Node::get_float3(const SocketType& input) const
214 {
215         assert(is_socket_float3(input));
216         return get_socket_value<float3>(this, input);
217 }
218
219 ustring Node::get_string(const SocketType& input) const
220 {
221         if(input.type == SocketType::STRING) {
222                 return get_socket_value<ustring>(this, input);
223         }
224         else if(input.type == SocketType::ENUM) {
225                 const NodeEnum& enm = *input.enum_values;
226                 int intvalue = get_socket_value<int>(this, input);
227                 return (enm.exists(intvalue)) ? enm[intvalue] : ustring();
228         }
229         else {
230                 assert(0);
231                 return ustring();
232         }
233 }
234
235 Transform Node::get_transform(const SocketType& input) const
236 {
237         assert(input.type == SocketType::TRANSFORM);
238         return get_socket_value<Transform>(this, input);
239 }
240
241 Node *Node::get_node(const SocketType& input) const
242 {
243         assert(input.type == SocketType::NODE);
244         return get_socket_value<Node*>(this, input);
245 }
246
247 /* get array values */
248 const array<bool>& Node::get_bool_array(const SocketType& input) const
249 {
250         assert(input.type == SocketType::BOOLEAN_ARRAY);
251         return get_socket_value<array<bool> >(this, input);
252 }
253
254 const array<int>& Node::get_int_array(const SocketType& input) const
255 {
256         assert(input.type == SocketType::INT_ARRAY);
257         return get_socket_value<array<int> >(this, input);
258 }
259
260 const array<float>& Node::get_float_array(const SocketType& input) const
261 {
262         assert(input.type == SocketType::FLOAT_ARRAY);
263         return get_socket_value<array<float> >(this, input);
264 }
265
266 const array<float2>& Node::get_float2_array(const SocketType& input) const
267 {
268         assert(input.type == SocketType::FLOAT_ARRAY);
269         return get_socket_value<array<float2> >(this, input);
270 }
271
272 const array<float3>& Node::get_float3_array(const SocketType& input) const
273 {
274         assert(is_socket_array_float3(input));
275         return get_socket_value<array<float3> >(this, input);
276 }
277
278 const array<ustring>& Node::get_string_array(const SocketType& input) const
279 {
280         assert(input.type == SocketType::STRING_ARRAY);
281         return get_socket_value<array<ustring> >(this, input);
282 }
283
284 const array<Transform>& Node::get_transform_array(const SocketType& input) const
285 {
286         assert(input.type == SocketType::TRANSFORM_ARRAY);
287         return get_socket_value<array<Transform> >(this, input);
288 }
289
290 const array<Node*>& Node::get_node_array(const SocketType& input) const
291 {
292         assert(input.type == SocketType::NODE_ARRAY);
293         return get_socket_value<array<Node*> >(this, input);
294 }
295
296 /* generic value operations */
297
298 bool Node::has_default_value(const SocketType& input) const
299 {
300         const void *src = input.default_value;
301         void *dst = &get_socket_value<char>(this, input);
302         return memcmp(dst, src, input.size()) == 0;
303 }
304
305 void Node::set_default_value(const SocketType& socket)
306 {
307         const void *src = socket.default_value;
308         void *dst = ((char*)this) + socket.struct_offset;
309         memcpy(dst, src, socket.size());
310 }
311
312 template<typename T>
313 static void copy_array(const Node *node, const SocketType& socket, const Node *other, const SocketType& other_socket)
314 {
315         const array<T>* src = (const array<T>*)(((char*)other) + other_socket.struct_offset);
316         array<T>* dst = (array<T>*)(((char*)node) + socket.struct_offset);
317         *dst = *src;
318 }
319
320 void Node::copy_value(const SocketType& socket, const Node& other, const SocketType& other_socket)
321 {
322         assert(socket.type == other_socket.type);
323
324         if(socket.is_array()) {
325                 switch(socket.type) {
326                         case SocketType::BOOLEAN_ARRAY: copy_array<bool>(this, socket, &other, other_socket); break;
327                         case SocketType::FLOAT_ARRAY: copy_array<float>(this, socket, &other, other_socket); break;
328                         case SocketType::INT_ARRAY: copy_array<int>(this, socket, &other, other_socket); break;
329                         case SocketType::COLOR_ARRAY: copy_array<float3>(this, socket, &other, other_socket); break;
330                         case SocketType::VECTOR_ARRAY: copy_array<float3>(this, socket, &other, other_socket); break;
331                         case SocketType::POINT_ARRAY: copy_array<float3>(this, socket, &other, other_socket); break;
332                         case SocketType::NORMAL_ARRAY: copy_array<float3>(this, socket, &other, other_socket); break;
333                         case SocketType::POINT2_ARRAY: copy_array<float2>(this, socket, &other, other_socket); break;
334                         case SocketType::STRING_ARRAY: copy_array<ustring>(this, socket, &other, other_socket); break;
335                         case SocketType::TRANSFORM_ARRAY: copy_array<Transform>(this, socket, &other, other_socket); break;
336                         case SocketType::NODE_ARRAY: copy_array<void*>(this, socket, &other, other_socket); break;
337                         default: assert(0); break;
338                 }
339         }
340         else {
341                 const void *src = ((char*)&other) + other_socket.struct_offset;
342                 void *dst = ((char*)this) + socket.struct_offset;
343                 memcpy(dst, src, socket.size());
344         }
345 }
346
347 template<typename T>
348 static bool is_array_equal(const Node *node, const Node *other, const SocketType& socket)
349 {
350         const array<T>* a = (const array<T>*)(((char*)node) + socket.struct_offset);
351         const array<T>* b = (const array<T>*)(((char*)other) + socket.struct_offset);
352         return *a == *b;
353 }
354
355 bool Node::equals_value(const Node& other, const SocketType& socket) const
356 {
357         if(socket.is_array()) {
358                 switch(socket.type) {
359                         case SocketType::BOOLEAN_ARRAY: return is_array_equal<bool>(this, &other, socket);
360                         case SocketType::FLOAT_ARRAY: return is_array_equal<float>(this, &other, socket);
361                         case SocketType::INT_ARRAY: return is_array_equal<int>(this, &other, socket);
362                         case SocketType::COLOR_ARRAY: return is_array_equal<float3>(this, &other, socket);
363                         case SocketType::VECTOR_ARRAY: return is_array_equal<float3>(this, &other, socket);
364                         case SocketType::POINT_ARRAY: return is_array_equal<float3>(this, &other, socket);
365                         case SocketType::NORMAL_ARRAY: return is_array_equal<float3>(this, &other, socket);
366                         case SocketType::POINT2_ARRAY: return is_array_equal<float2>(this, &other, socket);
367                         case SocketType::STRING_ARRAY: return is_array_equal<ustring>(this, &other, socket);
368                         case SocketType::TRANSFORM_ARRAY: return is_array_equal<Transform>(this, &other, socket);
369                         case SocketType::NODE_ARRAY: return is_array_equal<void*>(this, &other, socket);
370                         default: assert(0); return true;
371                 }
372         }
373         else {
374                 const void *a = ((char*)this) + socket.struct_offset;
375                 const void *b = ((char*)&other) + socket.struct_offset;
376                 return (memcmp(a, b, socket.size()) == 0);
377         }
378 }
379
380 /* equals */
381
382 bool Node::equals(const Node& other) const
383 {
384         assert(type == other.type);
385
386         foreach(const SocketType& socket, type->inputs) {
387                 if(!equals_value(other, socket))
388                         return false;
389         }
390
391         return true;
392 }
393
394 CCL_NAMESPACE_END
395