Fix Cycles debug build assert on some platforms, tighten checks to avoid this in...
[blender.git] / intern / cycles / graph / node_type.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_type.h"
18 #include "util_foreach.h"
19 #include "util_transform.h"
20
21 CCL_NAMESPACE_BEGIN
22
23 /* Node Socket Type */
24
25 size_t SocketType::size() const
26 {
27         return size(type);
28 }
29
30 bool SocketType::is_array() const
31 {
32         return (type >= BOOLEAN_ARRAY);
33 }
34
35 size_t SocketType::size(Type type)
36 {
37         switch(type)
38         {
39                 case UNDEFINED: return 0;
40
41                 case BOOLEAN: return sizeof(bool);
42                 case FLOAT: return sizeof(float);
43                 case INT: return sizeof(int);
44                 case UINT: return sizeof(uint);
45                 case COLOR: return sizeof(float3);
46                 case VECTOR: return sizeof(float3);
47                 case POINT: return sizeof(float3);
48                 case NORMAL: return sizeof(float3);
49                 case POINT2: return sizeof(float2);
50                 case CLOSURE: return 0;
51                 case STRING: return sizeof(ustring);
52                 case ENUM: return sizeof(int);
53                 case TRANSFORM: return sizeof(Transform);
54                 case NODE: return sizeof(void*);
55
56                 case BOOLEAN_ARRAY: return sizeof(array<bool>);
57                 case FLOAT_ARRAY: return sizeof(array<float>);
58                 case INT_ARRAY: return sizeof(array<int>);
59                 case COLOR_ARRAY: return sizeof(array<float3>);
60                 case VECTOR_ARRAY: return sizeof(array<float3>);
61                 case POINT_ARRAY: return sizeof(array<float3>);
62                 case NORMAL_ARRAY: return sizeof(array<float3>);
63                 case POINT2_ARRAY: return sizeof(array<float2>);
64                 case STRING_ARRAY: return sizeof(array<ustring>);
65                 case TRANSFORM_ARRAY: return sizeof(array<Transform>);
66                 case NODE_ARRAY: return sizeof(array<void*>);
67         }
68
69         assert(0);
70         return 0;
71 }
72
73 size_t SocketType::max_size()
74 {
75         return sizeof(Transform);
76 }
77
78 void *SocketType::zero_default_value()
79 {
80         static Transform zero_transform = {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}};
81         return &zero_transform;
82 }
83
84 ustring SocketType::type_name(Type type)
85 {
86         static ustring names[] = {
87                 ustring("undefined"),
88
89                 ustring("boolean"),
90                 ustring("float"),
91                 ustring("int"),
92                 ustring("color"),
93                 ustring("vector"),
94                 ustring("point"),
95                 ustring("normal"),
96                 ustring("point2"),
97                 ustring("closure"),
98                 ustring("string"),
99                 ustring("enum"),
100                 ustring("transform"),
101                 ustring("node"),
102
103                 ustring("array_boolean"),
104                 ustring("array_float"),
105                 ustring("array_int"),
106                 ustring("array_color"),
107                 ustring("array_vector"),
108                 ustring("array_point"),
109                 ustring("array_normal"),
110                 ustring("array_point2"),
111                 ustring("array_string"),
112                 ustring("array_transform"),
113                 ustring("array_node")};
114
115         return names[(int)type];
116 }
117
118 bool SocketType::is_float3(Type type)
119 {
120         return (type == COLOR || type == VECTOR || type == POINT || type == NORMAL);
121 }
122
123 /* Node Type */
124
125 NodeType::NodeType(Type type_)
126 : type(type_)
127 {
128 }
129
130 NodeType::~NodeType()
131 {
132 }
133
134 void NodeType::register_input(ustring name, ustring ui_name, SocketType::Type type, int struct_offset,
135                               const void *default_value, const NodeEnum *enum_values,
136                                                           const NodeType **node_type, int flags, int extra_flags)
137 {
138         SocketType socket;
139         socket.name = name;
140         socket.ui_name = ui_name;
141         socket.type = type;
142         socket.struct_offset = struct_offset;
143         socket.default_value = default_value;
144         socket.enum_values = enum_values;
145         socket.node_type = node_type;
146         socket.flags = flags | extra_flags;
147         inputs.push_back(socket);
148 }
149
150 void NodeType::register_output(ustring name, ustring ui_name, SocketType::Type type)
151 {
152         SocketType socket;
153         socket.name = name;
154         socket.ui_name = ui_name;
155         socket.type = type;
156         socket.struct_offset = 0;
157         socket.default_value = NULL;
158         socket.enum_values = NULL;
159         socket.node_type = NULL;
160         socket.flags = SocketType::LINKABLE;
161         outputs.push_back(socket);
162 }
163
164 const SocketType *NodeType::find_input(ustring name) const
165 {
166         foreach(const SocketType& socket, inputs) {
167                 if(socket.name == name) {
168                         return &socket;
169                 }
170         }
171
172         return NULL;
173 }
174
175 const SocketType *NodeType::find_output(ustring name) const
176 {
177         foreach(const SocketType& socket, outputs) {
178                 if(socket.name == name) {
179                         return &socket;
180                 }
181         }
182
183         return NULL;
184 }
185
186 /* Node Type Registry */
187
188 unordered_map<ustring, NodeType, ustringHash>& NodeType::types()
189 {
190         static unordered_map<ustring, NodeType, ustringHash> _types;
191         return _types;
192 }
193
194 NodeType *NodeType::add(const char *name_, CreateFunc create_, Type type_)
195 {
196         ustring name(name_);
197
198         if(types().find(name) != types().end()) {
199                 fprintf(stderr, "Node type %s registered twice!\n", name_);
200                 assert(0);
201                 return NULL;
202         }
203
204         types()[name] = NodeType(type_);
205
206         NodeType *type = &types()[name];
207         type->name = name;
208         type->create = create_;
209         return type;
210 }
211
212 const NodeType *NodeType::find(ustring name)
213 {
214         unordered_map<ustring, NodeType, ustringHash>::iterator it = types().find(name);
215         return (it == types().end()) ? NULL : &it->second;
216 }
217
218 CCL_NAMESPACE_END
219