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