Make dynamic node labels possible as a registerable function 'draw_label' (simple...
[blender.git] / source / blender / nodes / intern / node_util.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version. 
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2007 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Nathan Letwory.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/nodes/intern/node_util.c
29  *  \ingroup nodes
30  */
31
32 #include <limits.h>
33 #include <string.h>
34
35 #include "DNA_action_types.h"
36 #include "DNA_node_types.h"
37
38 #include "BLI_listbase.h"
39 #include "BLI_string.h"
40 #include "BLI_utildefines.h"
41
42 #include "BLF_translation.h"
43
44 #include "BKE_colortools.h"
45 #include "BKE_node.h"
46
47 #include "RNA_access.h"
48 #include "RNA_enum_types.h"
49
50 #include "MEM_guardedalloc.h"
51
52 #include "node_util.h"
53
54 /**** Storage Data ****/
55
56 void node_free_curves(bNode *node)
57 {
58         curvemapping_free(node->storage);
59 }
60
61 void node_free_standard_storage(bNode *node)
62 {
63         if (node->storage) {
64                 MEM_freeN(node->storage);
65         }
66 }
67
68 void node_copy_curves(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, bNode *src_node)
69 {
70         dest_node->storage = curvemapping_copy(src_node->storage);
71 }
72
73 void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, bNode *src_node)
74 {
75         dest_node->storage = MEM_dupallocN(src_node->storage);
76 }
77
78 void *node_initexec_curves(bNodeExecContext *UNUSED(context), bNode *node, bNodeInstanceKey UNUSED(key))
79 {
80         curvemapping_initialize(node->storage);
81         return NULL;  /* unused return */
82 }
83
84 /**** Labels ****/
85
86 void node_blend_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen)
87 {
88         const char *name;
89         RNA_enum_name(ramp_blend_items, node->custom1, &name);
90         BLI_strncpy(label, IFACE_(name), maxlen);
91 }
92
93 void node_math_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen)
94 {
95         const char *name;
96         RNA_enum_name(node_math_items, node->custom1, &name);
97         BLI_strncpy(label, IFACE_(name), maxlen);
98 }
99
100 void node_vect_math_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen)
101 {
102         const char *name;
103         RNA_enum_name(node_vec_math_items, node->custom1, &name);
104         BLI_strncpy(label, IFACE_(name), maxlen);
105 }
106
107 void node_filter_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen)
108 {
109         const char *name;
110         RNA_enum_name(node_filter_items, node->custom1, &name);
111         BLI_strncpy(label, IFACE_(name), maxlen);
112 }
113
114 void node_update_internal_links_default(bNodeTree *ntree, bNode *node)
115 {
116         bNodeLink *link;
117         bNodeSocket *output, *input, *selected;
118
119         /* sanity check */
120         if (!ntree)
121                 return;
122
123         /* use link pointer as a tag for handled sockets (for outputs is unused anyway) */
124         for (output = node->outputs.first; output; output = output->next)
125                 output->link = NULL;
126         
127         for (link = ntree->links.first; link; link = link->next) {
128                 output = link->fromsock;
129                 if (link->fromnode != node || output->link)
130                         continue;
131                 output->link = link; /* not really used, just for tagging handled sockets */
132                 
133                 /* look for suitable input */
134                 selected = NULL;
135                 for (input = node->inputs.first; input; input = input->next) {
136                         /* only use if same type */
137                         if (input->type == output->type) {
138                                 if (!selected) {
139                                         selected = input;
140                                 }
141                                 else {
142                                         /* linked inputs preferred */
143                                         if (input->link && !selected->link)
144                                                 selected = input;
145                                 }
146                         }
147                 }
148                 
149                 if (selected) {
150                         bNodeLink *ilink = MEM_callocN(sizeof(bNodeLink), "internal node link");
151                         ilink->fromnode = node;
152                         ilink->fromsock = selected;
153                         ilink->tonode = node;
154                         ilink->tosock = output;
155                         /* internal link is always valid */
156                         ilink->flag |= NODE_LINK_VALID;
157                         BLI_addtail(&node->internal_links, ilink);
158                 }
159         }
160         
161         /* clean up */
162         for (output = node->outputs.first; output; output = output->next)
163                 output->link = NULL;
164 }
165
166 float node_socket_get_float(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock)
167 {
168         PointerRNA ptr;
169         RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
170         return RNA_float_get(&ptr, "default_value");
171 }
172
173 void node_socket_set_float(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock, float value)
174 {
175         PointerRNA ptr;
176         RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
177         RNA_float_set(&ptr, "default_value", value);
178 }
179
180 void node_socket_get_color(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock, float *value)
181 {
182         PointerRNA ptr;
183         RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
184         RNA_float_get_array(&ptr, "default_value", value);
185 }
186
187 void node_socket_set_color(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock, const float *value)
188 {
189         PointerRNA ptr;
190         RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
191         RNA_float_set_array(&ptr, "default_value", value);
192 }
193
194 void node_socket_get_vector(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock, float *value)
195 {
196         PointerRNA ptr;
197         RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
198         RNA_float_get_array(&ptr, "default_value", value);
199 }
200
201 void node_socket_set_vector(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock, const float *value)
202 {
203         PointerRNA ptr;
204         RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr);
205         RNA_float_set_array(&ptr, "default_value", value);
206 }