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