Blender V4.3
versioning_common.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8/* allow readfile to use deprecated functionality */
9#define DNA_DEPRECATED_ALLOW
10
11#include <cstring>
12
13#include "DNA_node_types.h"
14#include "DNA_screen_types.h"
15
16#include "BLI_listbase.h"
17#include "BLI_map.hh"
18#include "BLI_string.h"
19#include "BLI_string_ref.hh"
20#include "BLI_string_utf8.h"
21
22#include "BKE_animsys.h"
24#include "BKE_idprop.hh"
25#include "BKE_ipo.h"
26#include "BKE_lib_id.hh"
27#include "BKE_lib_override.hh"
28#include "BKE_main.hh"
29#include "BKE_main_namemap.hh"
31#include "BKE_node.hh"
32#include "BKE_node_runtime.hh"
34
35#include "NOD_socket.hh"
36
37#include "BLT_translation.hh"
38
39#include "SEQ_sequencer.hh"
40
41#include "MEM_guardedalloc.h"
42
43#include "BLO_readfile.hh"
44#include "readfile.hh"
45#include "versioning_common.hh"
46
47using blender::Map;
49
51 int region_type,
52 const char *allocname,
53 int link_after_region_type)
54{
55 ARegion *link_after_region = nullptr;
56 LISTBASE_FOREACH (ARegion *, region, regionbase) {
57 if (region->regiontype == region_type) {
58 return nullptr;
59 }
60 if (region->regiontype == link_after_region_type) {
61 link_after_region = region;
62 }
63 }
64
65 ARegion *new_region = static_cast<ARegion *>(MEM_callocN(sizeof(ARegion), allocname));
66 new_region->regiontype = region_type;
67 BLI_insertlinkafter(regionbase, link_after_region, new_region);
68 return new_region;
69}
70
72 int region_type,
73 const char *allocname,
74 int link_after_region_type)
75{
76 ARegion *link_after_region = nullptr;
77 LISTBASE_FOREACH (ARegion *, region, regionbase) {
78 if (region->regiontype == region_type) {
79 return region;
80 }
81 if (region->regiontype == link_after_region_type) {
82 link_after_region = region;
83 }
84 }
85
86 ARegion *new_region = MEM_cnew<ARegion>(allocname);
87 new_region->regiontype = region_type;
88 BLI_insertlinkafter(regionbase, link_after_region, new_region);
89 return new_region;
90}
91
93 const short id_type,
94 const char *name_src,
95 const char *name_dst)
96{
97 /* We can ignore libraries */
98 ListBase *lb = which_libbase(bmain, id_type);
99 ID *id = nullptr;
100 LISTBASE_FOREACH (ID *, idtest, lb) {
101 if (!ID_IS_LINKED(idtest)) {
102 if (STREQ(idtest->name + 2, name_src)) {
103 id = idtest;
104 }
105 if (STREQ(idtest->name + 2, name_dst)) {
106 return nullptr;
107 }
108 }
109 }
110 if (id != nullptr) {
111 BKE_libblock_rename(*bmain, *id, name_dst);
112 }
113 return id;
114}
115
116static void change_node_socket_name(ListBase *sockets, const char *old_name, const char *new_name)
117{
118 LISTBASE_FOREACH (bNodeSocket *, socket, sockets) {
119 if (STREQ(socket->name, old_name)) {
120 STRNCPY(socket->name, new_name);
121 }
122 if (STREQ(socket->identifier, old_name)) {
123 STRNCPY(socket->identifier, new_name);
124 }
125 }
126}
127
129{
130 return sock->flag & SOCK_IS_LINKED;
131}
132
134{
135 StringRef name = socket->name;
136 StringRef id = socket->identifier;
137
138 if (!id.startswith(name)) {
139 /* We only need to affect the case where the identifier starts with the name. */
140 return;
141 }
142
143 StringRef id_number = id.drop_known_prefix(name);
144 if (id_number.is_empty()) {
145 /* The name was already unique, and didn't need numbers at the end for the id. */
146 return;
147 }
148
149 if (id_number.startswith(".")) {
150 socket->identifier[name.size()] = '_';
151 }
152}
153
155 const int node_type,
156 const char *old_name,
157 const char *new_name)
158{
159 for (bNode *node : ntree->all_nodes()) {
160 if (node->type == node_type) {
161 change_node_socket_name(&node->inputs, old_name, new_name);
162 change_node_socket_name(&node->outputs, old_name, new_name);
163 }
164 }
165}
166
168 const int node_type,
169 const char *old_name,
170 const char *new_name)
171{
172 for (bNode *node : ntree->all_nodes()) {
173 if (node->type == node_type) {
174 change_node_socket_name(&node->inputs, old_name, new_name);
175 }
176 }
177}
178
180 const int node_type,
181 const char *old_name,
182 const char *new_name)
183{
184 for (bNode *node : ntree->all_nodes()) {
185 if (node->type == node_type) {
186 change_node_socket_name(&node->outputs, old_name, new_name);
187 }
188 }
189}
190
191bNode &version_node_add_empty(bNodeTree &ntree, const char *idname)
192{
194
195 bNode *node = MEM_cnew<bNode>(__func__);
196 node->runtime = MEM_new<blender::bke::bNodeRuntime>(__func__);
197 BLI_addtail(&ntree.nodes, node);
198 blender::bke::node_unique_id(&ntree, node);
199
200 STRNCPY(node->idname, idname);
201 STRNCPY_UTF8(node->name, DATA_(ntype->ui_name));
202 blender::bke::node_unique_name(&ntree, node);
203
204 node->flag = NODE_SELECT | NODE_OPTIONS | NODE_INIT;
205 node->width = ntype->width;
206 node->height = ntype->height;
207 node->color[0] = node->color[1] = node->color[2] = 0.608;
208
209 node->type = ntype->type;
210
211 BKE_ntree_update_tag_node_new(&ntree, node);
212 return *node;
213}
214
216 bNode &node,
217 const eNodeSocketInOut in_out,
218 const char *idname,
219 const char *identifier)
220{
222
223 bNodeSocket *socket = MEM_cnew<bNodeSocket>(__func__);
224 socket->runtime = MEM_new<blender::bke::bNodeSocketRuntime>(__func__);
225 socket->in_out = in_out;
226 socket->limit = (in_out == SOCK_IN ? 1 : 0xFFF);
227 socket->type = stype->type;
228
229 STRNCPY(socket->idname, idname);
230 STRNCPY(socket->identifier, identifier);
231 STRNCPY(socket->name, identifier);
232
233 if (in_out == SOCK_IN) {
234 BLI_addtail(&node.inputs, socket);
235 }
236 else {
237 BLI_addtail(&node.outputs, socket);
238 }
239
241 eNodeSocketDatatype(stype->type), stype->subtype, &socket->default_value);
242
243 BKE_ntree_update_tag_socket_new(&ntree, socket);
244 return *socket;
245}
246
248 bNodeTree &ntree, bNode &node_a, bNodeSocket &socket_a, bNode &node_b, bNodeSocket &socket_b)
249{
250 BLI_assert(socket_a.in_out != socket_b.in_out);
251 if (socket_a.in_out == SOCK_IN) {
252 return version_node_add_link(ntree, node_b, socket_b, node_a, socket_a);
253 }
254 bNode &node_from = node_a;
255 bNodeSocket &socket_from = socket_a;
256 bNode &node_to = node_b;
257 bNodeSocket &socket_to = socket_b;
258
259 bNodeLink *link = MEM_cnew<bNodeLink>(__func__);
260 link->fromnode = &node_from;
261 link->fromsock = &socket_from;
262 link->tonode = &node_to;
263 link->tosock = &socket_to;
264
265 BLI_addtail(&ntree.links, link);
266
268 return *link;
269}
270
272 bNode *node,
273 int in_out,
274 int type,
275 int subtype,
276 const char *identifier,
277 const char *name)
278{
279 bNodeSocket *sock = blender::bke::node_find_socket(node, eNodeSocketInOut(in_out), identifier);
280 if (sock != nullptr) {
281 return sock;
282 }
284 ntree, node, eNodeSocketInOut(in_out), type, subtype, identifier, name);
285}
286
287void version_node_id(bNodeTree *ntree, const int node_type, const char *new_name)
288{
289 for (bNode *node : ntree->all_nodes()) {
290 if (node->type == node_type) {
291 if (!STREQ(node->idname, new_name)) {
292 STRNCPY(node->idname, new_name);
293 }
294 }
295 }
296}
297
299 const int node_tree_type,
300 const int node_type,
301 const int socket_index_orig,
302 const int socket_index_offset,
303 const int total_number_of_sockets)
304{
305
306 /* The for loop for the input ids is at the top level otherwise we lose the animation
307 * keyframe data. Not sure what causes that, so I (Sybren) moved the code here from
308 * versioning_290.cc as-is (structure-wise). */
309 for (int input_index = total_number_of_sockets - 1; input_index >= socket_index_orig;
310 input_index--)
311 {
312 FOREACH_NODETREE_BEGIN (bmain, ntree, owner_id) {
313 if (ntree->type != node_tree_type) {
314 continue;
315 }
316
317 for (bNode *node : ntree->all_nodes()) {
318 if (node->type != node_type) {
319 continue;
320 }
321
322 const size_t node_name_length = strlen(node->name);
323 const size_t node_name_escaped_max_length = (node_name_length * 2);
324 char *node_name_escaped = (char *)MEM_mallocN(node_name_escaped_max_length + 1,
325 "escaped name");
326 BLI_str_escape(node_name_escaped, node->name, node_name_escaped_max_length);
327 char *rna_path_prefix = BLI_sprintfN("nodes[\"%s\"].inputs", node_name_escaped);
328
329 const int new_index = input_index + socket_index_offset;
331 bmain, owner_id, rna_path_prefix, nullptr, nullptr, input_index, new_index, false);
332 MEM_freeN(rna_path_prefix);
333 MEM_freeN(node_name_escaped);
334 }
335 }
337 }
338}
339
341{
342 for (bNode *node : ntree->all_nodes()) {
343 LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
344 socket->flag &= ~SOCK_IS_LINKED;
345 }
346 LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) {
347 socket->flag &= ~SOCK_IS_LINKED;
348 }
349 }
350 LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
351 link->fromsock->flag |= SOCK_IS_LINKED;
352 link->tosock->flag |= SOCK_IS_LINKED;
353 }
354}
355
356ARegion *do_versions_add_region(int regiontype, const char *name)
357{
358 ARegion *region = (ARegion *)MEM_callocN(sizeof(ARegion), name);
359 region->regiontype = regiontype;
360 return region;
361}
362
364 bNode &old_node,
365 bNode &new_node,
367{
368 LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree.links) {
369 if (link->tonode == &old_node) {
370 bNodeSocket *old_socket = link->tosock;
371 if (old_socket->is_available()) {
372 if (const std::string *new_identifier = map.lookup_ptr_as(old_socket->identifier)) {
374 &new_node, SOCK_IN, *new_identifier);
375 link->tonode = &new_node;
376 link->tosock = new_socket;
377 old_socket->link = nullptr;
378 }
379 }
380 }
381 if (link->fromnode == &old_node) {
382 bNodeSocket *old_socket = link->fromsock;
383 if (old_socket->is_available()) {
384 if (const std::string *new_identifier = map.lookup_ptr_as(old_socket->identifier)) {
386 &new_node, SOCK_OUT, *new_identifier);
387 link->fromnode = &new_node;
388 link->fromsock = new_socket;
389 old_socket->link = nullptr;
390 }
391 }
392 }
393 }
394}
395
397{
399 LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
400 if (link->tosock == in_socket) {
401 links.append(link);
402 }
403 }
404 return links;
405}
406
408 bNode *node,
409 bNodeSocket *geometry_socket)
410{
411 BLI_assert(geometry_socket->type == SOCK_GEOMETRY);
412 blender::Vector<bNodeLink *> links = find_connected_links(ntree, geometry_socket);
413 for (bNodeLink *link : links) {
414 /* If the realize instances node is already before this socket, no need to continue. */
415 if (link->fromnode->type == GEO_NODE_REALIZE_INSTANCES) {
416 return;
417 }
418
420 nullptr, ntree, GEO_NODE_REALIZE_INSTANCES);
421 realize_node->parent = node->parent;
422 realize_node->locx = node->locx - 100;
423 realize_node->locy = node->locy;
425 link->fromnode,
426 link->fromsock,
427 realize_node,
428 static_cast<bNodeSocket *>(realize_node->inputs.first));
429 link->fromnode = realize_node;
430 link->fromsock = static_cast<bNodeSocket *>(realize_node->outputs.first);
431 }
432}
433
435{
436 bNodeSocketValueFloat *socket_data = static_cast<bNodeSocketValueFloat *>(socket->default_value);
437 return &socket_data->value;
438}
439
441{
442 bNodeSocketValueRGBA *socket_data = static_cast<bNodeSocketValueRGBA *>(socket->default_value);
443 return socket_data->value;
444}
445
447{
448 bNodeSocketValueVector *socket_data = static_cast<bNodeSocketValueVector *>(
449 socket->default_value);
450 return socket_data->value;
451}
452
454{
455 IDProperty *idprop = IDP_GetProperties(id);
456 return (idprop) ? IDP_GetPropertyTypeFromGroup(idprop, "cycles", IDP_GROUP) : nullptr;
457}
458
460{
461 IDProperty *idprop = view_layer->id_properties;
462 return (idprop) ? IDP_GetPropertyTypeFromGroup(idprop, "cycles", IDP_GROUP) : nullptr;
463}
464
466{
467 IDProperty *idprop = render_layer->prop;
468 return (idprop) ? IDP_GetPropertyTypeFromGroup(idprop, "cycles", IDP_GROUP) : nullptr;
469}
470
471float version_cycles_property_float(IDProperty *idprop, const char *name, float default_value)
472{
474 return (prop) ? IDP_Float(prop) : default_value;
475}
476
477int version_cycles_property_int(IDProperty *idprop, const char *name, int default_value)
478{
479 IDProperty *prop = IDP_GetPropertyTypeFromGroup(idprop, name, IDP_INT);
480 return (prop) ? IDP_Int(prop) : default_value;
481}
482
483void version_cycles_property_int_set(IDProperty *idprop, const char *name, int value)
484{
485 if (IDProperty *prop = IDP_GetPropertyTypeFromGroup(idprop, name, IDP_INT)) {
486 IDP_Int(prop) = value;
487 }
488 else {
489 IDP_AddToGroup(idprop, blender::bke::idprop::create(name, value).release());
490 }
491}
492
493bool version_cycles_property_boolean(IDProperty *idprop, const char *name, bool default_value)
494{
495 return version_cycles_property_int(idprop, name, default_value);
496}
497
498void version_cycles_property_boolean_set(IDProperty *idprop, const char *name, bool value)
499{
500 version_cycles_property_int_set(idprop, name, value);
501}
502
504{
505 IDProperty *idprop = IDP_GetProperties(id);
506 return (idprop) ? IDP_GetPropertyTypeFromGroup(idprop, "cycles_visibility", IDP_GROUP) : nullptr;
507}
508
510 bNodeTree *ntree,
511 FunctionRef<bool(bNode *)> check_node,
512 const char *socket_identifier,
513 FunctionRef<void(bNode *, bNodeSocket *)> update_input,
514 FunctionRef<void(bNode *, bNodeSocket *, bNode *, bNodeSocket *)> update_input_link)
515{
516 bool need_update = false;
517
518 /* Iterate backwards from end so we don't encounter newly added links. */
520 /* Detect link to replace. */
521 bNode *fromnode = link->fromnode;
522 bNodeSocket *fromsock = link->fromsock;
523 bNode *tonode = link->tonode;
524 bNodeSocket *tosock = link->tosock;
525
526 if (!(tonode != nullptr && check_node(tonode) && STREQ(tosock->identifier, socket_identifier)))
527 {
528 continue;
529 }
530
531 /* Replace links with updated equivalent */
533 update_input_link(fromnode, fromsock, tonode, tosock);
534
535 need_update = true;
536 }
537
538 /* Update sockets and/or their default values.
539 * Do this after the link update in case it changes the identifier. */
540 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
541 if (check_node(node)) {
542 bNodeSocket *input = blender::bke::node_find_socket(node, SOCK_IN, socket_identifier);
543 if (input != nullptr) {
544 update_input(node, input);
545 }
546 }
547 }
548
549 if (need_update) {
551 }
552}
553
555{
556 bNode *output_node = nullptr;
557 /* NOTE: duplicated from `ntreeShaderOutputNode` with small adjustments so it can be called
558 * during versioning. */
559 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
560 if (node->type != node_type) {
561 continue;
562 }
563 if (node->custom1 == SHD_OUTPUT_ALL) {
564 if (output_node == nullptr) {
565 output_node = node;
566 }
567 else if (output_node->custom1 == SHD_OUTPUT_ALL) {
568 if ((node->flag & NODE_DO_OUTPUT) && !(output_node->flag & NODE_DO_OUTPUT)) {
569 output_node = node;
570 }
571 }
572 }
573 else if (node->custom1 == SHD_OUTPUT_EEVEE) {
574 if (output_node == nullptr) {
575 output_node = node;
576 }
577 else if ((node->flag & NODE_DO_OUTPUT) && !(output_node->flag & NODE_DO_OUTPUT)) {
578 output_node = node;
579 }
580 }
581 }
582
583 return output_node;
584}
585
587 const short versionfile,
588 const short subversionfile)
589{
590 if (!MAIN_VERSION_FILE_ATLEAST(bmain, versionfile, subversionfile)) {
591 return false;
592 }
593
594 LISTBASE_FOREACH (Library *, library, &bmain->libraries) {
595 if (!LIBRARY_VERSION_FILE_ATLEAST(library, versionfile, subversionfile)) {
596 return false;
597 }
598 }
599
600 return true;
601}
602
604 BlendfileLinkAppendContext *lapp_context,
605 BlendFileReadReport *reports)
606{
607 /* WARNING: The code below may add IDs. These IDs _will_ be (by definition) conforming to current
608 * code's version already, and _must not_ be 'versionned' again.
609 *
610 * This means that when adding code here, _extreme_ care must be taken that it will not badly
611 * affect these 'modern' IDs potentially added by already existing processing.
612 *
613 * Adding code here should only be done in exceptional cases.
614 *
615 * Some further points to keep in mind:
616 * - While typically versioning order should be respected in code below (i.e. versioning
617 * affecting older versions should be done first), _this is not a hard rule_. And it should
618 * not be assumed older code must not be checked when adding newer code.
619 * - Do not rely strongly on versioning numbers here. This code may be run on data from
620 * different Blender versions (through the usage of linked data), and all existing data have
621 * already been processed through the whole do_version during blendfile reading itself. So
622 * decision to apply some versioning on some data should mostly rely on the data itself.
623 * - Unlike the regular do_version code, this one should _not_ be assumed as 'valid forever'.
624 * It is closer to the Editing or BKE code in that respect, changes to the logic or data
625 * model of an ID will require a careful update here as well.
626 *
627 * Another critical weakness of this code is that it is currently _not_ performed on data linked
628 * during an editing session, but only on data linked while reading a whole blendfile. This will
629 * have to be fixed at some point.
630 */
631
632 /* NOTE: Version number is checked against Main version (i.e. current blend file version), AND
633 * the versions of all the linked libraries. */
634
635 if (!blendfile_or_libraries_versions_atleast(new_bmain, 250, 0)) {
637 }
638
639 if (!blendfile_or_libraries_versions_atleast(new_bmain, 250, 0)) {
640 LISTBASE_FOREACH (Scene *, scene, &new_bmain->scenes) {
641 if (scene->ed) {
642 SEQ_doversion_250_sound_proxy_update(new_bmain, scene->ed);
643 }
644 }
645 }
646
647 if (!blendfile_or_libraries_versions_atleast(new_bmain, 302, 1)) {
649 /* Currently liboverride code can generate invalid namemap. This is a known issue, requires
650 * #107847 to be properly fixed. */
652 }
653
654 if (!blendfile_or_libraries_versions_atleast(new_bmain, 302, 3)) {
655 /* Does not add any new IDs, but needs the full Main data-base. */
657 }
658
659 if (!blendfile_or_libraries_versions_atleast(new_bmain, 402, 22)) {
660 /* Initial auto smooth versioning started at (401, 2), but a bug caused the legacy flag to not
661 * be cleared, so it is re-run in a later version when the bug is fixed and the versioning has
662 * been made idempotent. */
664 }
665
666 if (!blendfile_or_libraries_versions_atleast(new_bmain, 403, 3)) {
667 /* Convert all the legacy grease pencil objects. This does not touch annotations. */
668 blender::bke::greasepencil::convert::legacy_main(*new_bmain, lapp_context, *reports);
669 }
670}
void BKE_animdata_fix_paths_rename_all_ex(struct Main *bmain, struct ID *ref_id, const char *prefix, const char *oldName, const char *newName, int oldSubscript, int newSubscript, bool verify_paths)
#define IDP_Float(prop)
#define IDP_Int(prop)
IDProperty * IDP_GetPropertyTypeFromGroup(const IDProperty *prop, const char *name, char type) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:769
bool IDP_AddToGroup(IDProperty *group, IDProperty *prop) ATTR_NONNULL()
Definition idprop.cc:722
IDProperty * IDP_GetProperties(ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition idprop.cc:875
void do_versions_ipos_to_animato(struct Main *bmain)
Definition ipo.cc:2091
IDNewNameResult BKE_libblock_rename(Main &bmain, ID &id, blender::StringRefNull name, const IDNewNameMode mode=IDNewNameMode::RenameExistingNever)
Definition lib_id.cc:2316
void BKE_lib_override_library_main_hierarchy_root_ensure(Main *bmain)
void BKE_lib_override_library_main_proxy_convert(Main *bmain, BlendFileReadReport *reports)
ListBase * which_libbase(Main *bmain, short type)
Definition main.cc:842
#define MAIN_VERSION_FILE_ATLEAST(main, ver, subver)
Definition BKE_main.hh:572
#define LIBRARY_VERSION_FILE_ATLEAST(lib, ver, subver)
Definition BKE_main.hh:584
bool BKE_main_namemap_validate_and_fix(Main *bmain) ATTR_NONNULL()
void BKE_main_mesh_legacy_convert_auto_smooth(Main &bmain)
#define FOREACH_NODETREE_END
Definition BKE_node.hh:870
#define FOREACH_NODETREE_BEGIN(bmain, _nodetree, _id)
Definition BKE_node.hh:860
void BKE_ntree_update_tag_node_new(bNodeTree *ntree, bNode *node)
void BKE_ntree_update_tag_socket_new(bNodeTree *ntree, bNodeSocket *socket)
void BKE_ntree_update_tag_link_added(bNodeTree *ntree, bNodeLink *link)
#define BLI_assert(a)
Definition BLI_assert.h:50
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1)
Definition listbase.cc:331
#define LISTBASE_FOREACH_BACKWARD_MUTABLE(type, var, list)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
char * BLI_sprintfN(const char *__restrict format,...) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1
#define STRNCPY(dst, src)
Definition BLI_string.h:593
size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define STRNCPY_UTF8(dst, src)
#define STREQ(a, b)
external readfile function prototypes.
#define DATA_(msgid)
#define ID_IS_LINKED(_id)
Definition DNA_ID.h:654
@ IDP_FLOAT
@ IDP_INT
@ IDP_GROUP
@ NODE_OPTIONS
@ NODE_DO_OUTPUT
@ NODE_INIT
@ NODE_SELECT
@ SHD_OUTPUT_ALL
@ SHD_OUTPUT_EEVEE
eNodeSocketInOut
@ SOCK_OUT
@ SOCK_IN
@ SOCK_IS_LINKED
eNodeSocketDatatype
@ SOCK_GEOMETRY
Read Guarded memory(de)allocation.
constexpr bool is_empty() const
constexpr bool startswith(StringRef prefix) const
constexpr StringRef drop_known_prefix(StringRef prefix) const
void append(const T &value)
OperationNode * node
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
void legacy_main(Main &bmain, BlendfileLinkAppendContext *lapp_context, BlendFileReadReport &reports)
std::unique_ptr< IDProperty, IDPropertyDeleter > create(StringRefNull prop_name, int32_t value, eIDPropertyFlag flags={})
Allocate a new IDProperty of type IDP_INT, set its name and value.
bNode * node_add_static_node(const bContext *C, bNodeTree *ntree, int type)
Definition node.cc:2642
bNodeLink * node_add_link(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, bNode *tonode, bNodeSocket *tosock)
Definition node.cc:2912
bNodeSocket * node_add_static_socket(bNodeTree *ntree, bNode *node, eNodeSocketInOut in_out, int type, int subtype, const char *identifier, const char *name)
Definition node.cc:2359
bNodeType * node_type_find(const char *idname)
Definition node.cc:1667
bNodeSocketType * node_socket_type_find(const char *idname)
Definition node.cc:1763
void node_remove_link(bNodeTree *ntree, bNodeLink *link)
Definition node.cc:2958
void node_unique_id(bNodeTree *ntree, bNode *node)
Definition node.cc:2599
bNodeSocket * node_find_socket(bNode *node, eNodeSocketInOut in_out, StringRef identifier)
Definition node.cc:1829
void node_unique_name(bNodeTree *ntree, bNode *node)
Definition node.cc:2593
void node_socket_init_default_value_data(eNodeSocketDatatype datatype, int subtype, void **data)
void SEQ_doversion_250_sound_proxy_update(Main *bmain, Editing *ed)
Definition sequencer.cc:941
signed short int16_t
Definition stdint.h:76
Definition DNA_ID.h:413
void * first
ListBase scenes
Definition BKE_main.hh:210
ListBase libraries
Definition BKE_main.hh:211
struct IDProperty * id_properties
bNodeSocketRuntimeHandle * runtime
struct bNodeLink * link
void * default_value
char identifier[64]
char idname[64]
ListBase nodes
ListBase links
int16_t custom1
float locy
ListBase inputs
struct bNode * parent
float locx
ListBase outputs
Defines a socket type.
Definition BKE_node.hh:151
Defines a node type.
Definition BKE_node.hh:218
void add_realize_instances_before_socket(bNodeTree *ntree, bNode *node, bNodeSocket *geometry_socket)
ID * do_versions_rename_id(Main *bmain, const short id_type, const char *name_src, const char *name_dst)
bNode * version_eevee_output_node_get(bNodeTree *ntree, int16_t node_type)
ARegion * do_versions_add_region(int regiontype, const char *name)
static blender::Vector< bNodeLink * > find_connected_links(bNodeTree *ntree, bNodeSocket *in_socket)
float * version_cycles_node_socket_float_value(bNodeSocket *socket)
void version_cycles_property_int_set(IDProperty *idprop, const char *name, int value)
IDProperty * version_cycles_properties_from_ID(ID *id)
int version_cycles_property_int(IDProperty *idprop, const char *name, int default_value)
IDProperty * version_cycles_properties_from_render_layer(SceneRenderLayer *render_layer)
ARegion * do_versions_add_region_if_not_found(ListBase *regionbase, int region_type, const char *allocname, int link_after_region_type)
bool version_node_socket_is_used(bNodeSocket *sock)
bNodeSocket & version_node_add_socket(bNodeTree &ntree, bNode &node, const eNodeSocketInOut in_out, const char *idname, const char *identifier)
void version_update_node_input(bNodeTree *ntree, FunctionRef< bool(bNode *)> check_node, const char *socket_identifier, FunctionRef< void(bNode *, bNodeSocket *)> update_input, FunctionRef< void(bNode *, bNodeSocket *, bNode *, bNodeSocket *)> update_input_link)
void version_node_socket_id_delim(bNodeSocket *socket)
float * version_cycles_node_socket_rgba_value(bNodeSocket *socket)
void version_node_socket_index_animdata(Main *bmain, const int node_tree_type, const int node_type, const int socket_index_orig, const int socket_index_offset, const int total_number_of_sockets)
void version_node_input_socket_name(bNodeTree *ntree, const int node_type, const char *old_name, const char *new_name)
bNode & version_node_add_empty(bNodeTree &ntree, const char *idname)
void version_node_socket_name(bNodeTree *ntree, const int node_type, const char *old_name, const char *new_name)
float * version_cycles_node_socket_vector_value(bNodeSocket *socket)
bool version_cycles_property_boolean(IDProperty *idprop, const char *name, bool default_value)
void version_socket_update_is_used(bNodeTree *ntree)
IDProperty * version_cycles_visibility_properties_from_ID(ID *id)
void node_tree_relink_with_socket_id_map(bNodeTree &ntree, bNode &old_node, bNode &new_node, const Map< std::string, std::string > &map)
void do_versions_after_setup(Main *new_bmain, BlendfileLinkAppendContext *lapp_context, BlendFileReadReport *reports)
bNodeLink & version_node_add_link(bNodeTree &ntree, bNode &node_a, bNodeSocket &socket_a, bNode &node_b, bNodeSocket &socket_b)
IDProperty * version_cycles_properties_from_view_layer(ViewLayer *view_layer)
bNodeSocket * version_node_add_socket_if_not_exist(bNodeTree *ntree, bNode *node, int in_out, int type, int subtype, const char *identifier, const char *name)
float version_cycles_property_float(IDProperty *idprop, const char *name, float default_value)
static bool blendfile_or_libraries_versions_atleast(Main *bmain, const short versionfile, const short subversionfile)
static void change_node_socket_name(ListBase *sockets, const char *old_name, const char *new_name)
void version_cycles_property_boolean_set(IDProperty *idprop, const char *name, bool value)
ARegion * do_versions_ensure_region(ListBase *regionbase, int region_type, const char *allocname, int link_after_region_type)
void version_node_output_socket_name(bNodeTree *ntree, const int node_type, const char *old_name, const char *new_name)
void version_node_id(bNodeTree *ntree, const int node_type, const char *new_name)