Blender V5.0
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#include "DNA_sequence_types.h"
16
17#include "BLI_listbase.h"
18#include "BLI_map.hh"
19#include "BLI_string.h"
20#include "BLI_string_ref.hh"
21#include "BLI_string_utf8.h"
22
23#include "BKE_animsys.h"
25#include "BKE_idprop.hh"
26#include "BKE_lib_id.hh"
27#include "BKE_lib_override.hh"
28#include "BKE_library.hh"
29#include "BKE_main.hh"
30#include "BKE_main_namemap.hh"
32#include "BKE_node.hh"
34#include "BKE_node_runtime.hh"
36#include "BKE_report.hh"
37#include "BKE_screen.hh"
38
39#include "ANIM_versioning.hh"
40
41#include "NOD_socket.hh"
42
43#include "BLT_translation.hh"
44
45#include "SEQ_sequencer.hh"
46
47#include "MEM_guardedalloc.h"
48
49#include "BLO_readfile.hh"
50#include "readfile.hh"
51#include "versioning_common.hh"
52
53using blender::Map;
55
56short do_versions_new_to_old_idcode_get(const short id_code_new)
57{
58 switch (id_code_new) {
59 case ID_GP:
60 /* ID_GD_LEGACY (Grease Pencil v2) is now converted to ID_GP (Grease Pencil v3). */
61 return ID_GD_LEGACY;
62 default:
64 }
65}
66
68 int region_type,
69 const char * /*allocname*/,
70 int link_after_region_type)
71{
72 ARegion *link_after_region = nullptr;
73 LISTBASE_FOREACH (ARegion *, region, regionbase) {
74 if (region->regiontype == region_type) {
75 return nullptr;
76 }
77 if (region->regiontype == link_after_region_type) {
78 link_after_region = region;
79 }
80 }
81
82 ARegion *new_region = BKE_area_region_new();
83 new_region->regiontype = region_type;
84 BLI_insertlinkafter(regionbase, link_after_region, new_region);
85 return new_region;
86}
87
89 int region_type,
90 const char * /*allocname*/,
91 int link_after_region_type)
92{
93 ARegion *link_after_region = nullptr;
94 LISTBASE_FOREACH (ARegion *, region, regionbase) {
95 if (region->regiontype == region_type) {
96 return region;
97 }
98 if (region->regiontype == link_after_region_type) {
99 link_after_region = region;
100 }
101 }
102
103 ARegion *new_region = BKE_area_region_new();
104 new_region->regiontype = region_type;
105 BLI_insertlinkafter(regionbase, link_after_region, new_region);
106 return new_region;
107}
108
110 const short id_type,
111 const char *name_src,
112 const char *name_dst)
113{
114 /* We can ignore libraries */
115 ListBase *lb = which_libbase(bmain, id_type);
116 ID *id = nullptr;
117 LISTBASE_FOREACH (ID *, idtest, lb) {
118 if (!ID_IS_LINKED(idtest)) {
119 if (STREQ(idtest->name + 2, name_src)) {
120 id = idtest;
121 }
122 if (STREQ(idtest->name + 2, name_dst)) {
123 return nullptr;
124 }
125 }
126 }
127 if (id != nullptr) {
128 BKE_libblock_rename(*bmain, *id, name_dst);
129 }
130 return id;
131}
132
133static void change_node_socket_name(ListBase *sockets, const char *old_name, const char *new_name)
134{
135 LISTBASE_FOREACH (bNodeSocket *, socket, sockets) {
136 if (STREQ(socket->name, old_name)) {
137 STRNCPY_UTF8(socket->name, new_name);
138 }
139 if (STREQ(socket->identifier, old_name)) {
140 STRNCPY_UTF8(socket->identifier, new_name);
141 }
142 }
143}
144
146{
147 BLI_assert(sock != nullptr);
148 return sock->flag & SOCK_IS_LINKED;
149}
150
152{
153 StringRef name = socket->name;
154 StringRef id = socket->identifier;
155
156 if (!id.startswith(name)) {
157 /* We only need to affect the case where the identifier starts with the name. */
158 return;
159 }
160
161 StringRef id_number = id.drop_known_prefix(name);
162 if (id_number.is_empty()) {
163 /* The name was already unique, and didn't need numbers at the end for the id. */
164 return;
165 }
166
167 if (id_number.startswith(".")) {
168 socket->identifier[name.size()] = '_';
169 }
170}
171
173 const int node_type,
174 const char *old_name,
175 const char *new_name)
176{
177 for (bNode *node : ntree->all_nodes()) {
178 if (node->type_legacy == node_type) {
179 change_node_socket_name(&node->inputs, old_name, new_name);
180 change_node_socket_name(&node->outputs, old_name, new_name);
181 }
182 }
183}
184
186 const int node_type,
187 const char *old_name,
188 const char *new_name)
189{
190 for (bNode *node : ntree->all_nodes()) {
191 if (node->type_legacy == node_type) {
192 change_node_socket_name(&node->inputs, old_name, new_name);
193 }
194 }
195}
196
198 const int node_type,
199 const char *old_name,
200 const char *new_name)
201{
202 for (bNode *node : ntree->all_nodes()) {
203 if (node->type_legacy == node_type) {
204 change_node_socket_name(&node->outputs, old_name, new_name);
205 }
206 }
207}
208
210{
211 using string_pair = std::pair<const char *, const char *>;
212 static const string_pair subtypes_map[] = {{"NodeSocketFloatUnsigned", "NodeSocketFloat"},
213 {"NodeSocketFloatPercentage", "NodeSocketFloat"},
214 {"NodeSocketFloatFactor", "NodeSocketFloat"},
215 {"NodeSocketFloatAngle", "NodeSocketFloat"},
216 {"NodeSocketFloatTime", "NodeSocketFloat"},
217 {"NodeSocketFloatTimeAbsolute", "NodeSocketFloat"},
218 {"NodeSocketFloatDistance", "NodeSocketFloat"},
219 {"NodeSocketIntUnsigned", "NodeSocketInt"},
220 {"NodeSocketIntPercentage", "NodeSocketInt"},
221 {"NodeSocketIntFactor", "NodeSocketInt"},
222 {"NodeSocketVectorTranslation", "NodeSocketVector"},
223 {"NodeSocketVectorDirection", "NodeSocketVector"},
224 {"NodeSocketVectorVelocity", "NodeSocketVector"},
225 {"NodeSocketVectorAcceleration", "NodeSocketVector"},
226 {"NodeSocketVectorEuler", "NodeSocketVector"},
227 {"NodeSocketVectorXYZ", "NodeSocketVector"}};
228 for (const string_pair &pair : subtypes_map) {
229 if (pair.first == idname) {
230 return pair.second;
231 }
232 }
233 /* Unchanged socket idname. */
234 return idname;
235}
236
237bNode &version_node_add_empty(bNodeTree &ntree, const char *idname)
238{
240
241 bNode *node = MEM_callocN<bNode>(__func__);
242 node->runtime = MEM_new<blender::bke::bNodeRuntime>(__func__);
243 BLI_addtail(&ntree.nodes, node);
244 blender::bke::node_unique_id(ntree, *node);
245
246 STRNCPY(node->idname, idname);
247 DATA_(ntype->ui_name).copy_utf8_truncated(node->name);
248 blender::bke::node_unique_name(ntree, *node);
249
251 node->width = ntype->width;
252 node->height = ntype->height;
253 node->color[0] = node->color[1] = node->color[2] = 0.608;
254
255 node->type_legacy = ntype->type_legacy;
256
257 BKE_ntree_update_tag_node_new(&ntree, node);
258 return *node;
259}
260
262{
265
266 blender::bke::node_free_node(&ntree, node);
268}
269
271 bNode &node,
272 const eNodeSocketInOut in_out,
273 const char *idname,
274 const char *identifier)
275{
277
278 bNodeSocket *socket = MEM_callocN<bNodeSocket>(__func__);
279 socket->runtime = MEM_new<blender::bke::bNodeSocketRuntime>(__func__);
280 socket->in_out = in_out;
281 socket->limit = (in_out == SOCK_IN ? 1 : 0xFFF);
282 socket->type = stype->type;
283
284 STRNCPY_UTF8(socket->idname, idname);
285 STRNCPY_UTF8(socket->identifier, identifier);
286 STRNCPY_UTF8(socket->name, identifier);
287
288 if (in_out == SOCK_IN) {
289 BLI_addtail(&node.inputs, socket);
290 }
291 else {
292 BLI_addtail(&node.outputs, socket);
293 }
294
296
297 BKE_ntree_update_tag_socket_new(&ntree, socket);
298 return *socket;
299}
300
302 bNodeTree &ntree, bNode &node_a, bNodeSocket &socket_a, bNode &node_b, bNodeSocket &socket_b)
303{
304 BLI_assert(socket_a.in_out != socket_b.in_out);
305 if (socket_a.in_out == SOCK_IN) {
306 return version_node_add_link(ntree, node_b, socket_b, node_a, socket_a);
307 }
308 bNode &node_from = node_a;
309 bNodeSocket &socket_from = socket_a;
310 bNode &node_to = node_b;
311 bNodeSocket &socket_to = socket_b;
312
313 bNodeLink *link = MEM_callocN<bNodeLink>(__func__);
314 link->fromnode = &node_from;
315 link->fromsock = &socket_from;
316 link->tonode = &node_to;
317 link->tosock = &socket_to;
318
319 BLI_addtail(&ntree.links, link);
320
322 return *link;
323}
324
326 bNode *node,
327 int in_out,
328 int type,
329 int subtype,
330 const char *identifier,
331 const char *name)
332{
333 bNodeSocket *sock = blender::bke::node_find_socket(*node, eNodeSocketInOut(in_out), identifier);
334 if (sock != nullptr) {
335 return sock;
336 }
338 *ntree, *node, eNodeSocketInOut(in_out), type, subtype, identifier, name);
339}
340
342{
343 ntree.tree_interface.clear_items();
344}
345
346void version_node_id(bNodeTree *ntree, const int node_type, const char *new_name)
347{
348 for (bNode *node : ntree->all_nodes()) {
349 if (node->type_legacy == node_type) {
350 if (!STREQ(node->idname, new_name)) {
351 STRNCPY(node->idname, new_name);
352 }
353 }
354 }
355}
356
358 const int node_tree_type,
359 const int node_type,
360 const int socket_index_orig,
361 const int socket_index_offset,
362 const int total_number_of_sockets)
363{
364
365 /* The for loop for the input ids is at the top level otherwise we lose the animation
366 * keyframe data. Not sure what causes that, so I (Sybren) moved the code here from
367 * versioning_290.cc as-is (structure-wise). */
368 for (int input_index = total_number_of_sockets - 1; input_index >= socket_index_orig;
369 input_index--)
370 {
371 FOREACH_NODETREE_BEGIN (bmain, ntree, owner_id) {
372 if (ntree->type != node_tree_type) {
373 continue;
374 }
375
376 for (bNode *node : ntree->all_nodes()) {
377 if (node->type_legacy != node_type) {
378 continue;
379 }
380
381 char node_name_escaped[sizeof(node->name) * 2];
382 BLI_str_escape(node_name_escaped, node->name, sizeof(node_name_escaped));
383 char *rna_path_prefix = BLI_sprintfN("nodes[\"%s\"].inputs", node_name_escaped);
384
385 const int new_index = input_index + socket_index_offset;
387 bmain, owner_id, rna_path_prefix, nullptr, nullptr, input_index, new_index, false);
388 MEM_freeN(rna_path_prefix);
389 }
390 }
392 }
393}
394
396{
397 for (bNode *node : ntree->all_nodes()) {
398 LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
399 socket->flag &= ~SOCK_IS_LINKED;
400 }
401 LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) {
402 socket->flag &= ~SOCK_IS_LINKED;
403 }
404 }
405 LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
406 link->fromsock->flag |= SOCK_IS_LINKED;
407 link->tosock->flag |= SOCK_IS_LINKED;
408 }
409}
410
411ARegion *do_versions_add_region(int regiontype, const char * /*name*/)
412{
413 ARegion *region = BKE_area_region_new();
414 region->regiontype = regiontype;
415 return region;
416}
417
419 bNode &old_node,
420 bNode &new_node,
422{
423 LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree.links) {
424 if (link->tonode == &old_node) {
425 bNodeSocket *old_socket = link->tosock;
426 if (old_socket->is_available()) {
427 if (const std::string *new_identifier = map.lookup_ptr_as(old_socket->identifier)) {
429 *&new_node, SOCK_IN, *new_identifier);
430 link->tonode = &new_node;
431 link->tosock = new_socket;
432 old_socket->link = nullptr;
433 }
434 }
435 }
436 if (link->fromnode == &old_node) {
437 bNodeSocket *old_socket = link->fromsock;
438 if (old_socket->is_available()) {
439 if (const std::string *new_identifier = map.lookup_ptr_as(old_socket->identifier)) {
441 *&new_node, SOCK_OUT, *new_identifier);
442 link->fromnode = &new_node;
443 link->fromsock = new_socket;
444 old_socket->link = nullptr;
445 }
446 }
447 }
448 }
449}
450
452{
454 LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
455 if (link->tosock == in_socket) {
456 links.append(link);
457 }
458 }
459 return links;
460}
461
463 bNode *node,
464 bNodeSocket *geometry_socket)
465{
466 BLI_assert(geometry_socket->type == SOCK_GEOMETRY);
467 blender::Vector<bNodeLink *> links = find_connected_links(ntree, geometry_socket);
468 for (bNodeLink *link : links) {
469 /* If the realize instances node is already before this socket, no need to continue. */
470 if (link->fromnode->type_legacy == GEO_NODE_REALIZE_INSTANCES) {
471 return;
472 }
473
475 nullptr, *ntree, GEO_NODE_REALIZE_INSTANCES);
476 realize_node->parent = node->parent;
477 realize_node->locx_legacy = node->locx_legacy - 100;
478 realize_node->locy_legacy = node->locy_legacy;
480 *link->fromnode,
481 *link->fromsock,
482 *realize_node,
483 *static_cast<bNodeSocket *>(realize_node->inputs.first));
484 link->fromnode = realize_node;
485 link->fromsock = static_cast<bNodeSocket *>(realize_node->outputs.first);
486 }
487}
488
490{
491 bNodeSocketValueFloat *socket_data = static_cast<bNodeSocketValueFloat *>(socket->default_value);
492 return &socket_data->value;
493}
494
496{
497 bNodeSocketValueRGBA *socket_data = static_cast<bNodeSocketValueRGBA *>(socket->default_value);
498 return socket_data->value;
499}
500
502{
503 bNodeSocketValueVector *socket_data = static_cast<bNodeSocketValueVector *>(
504 socket->default_value);
505 return socket_data->value;
506}
507
509{
511 return (idprop) ? IDP_GetPropertyTypeFromGroup(idprop, "cycles", IDP_GROUP) : nullptr;
512}
513
515{
516 IDProperty *idprop = view_layer->system_properties;
517 return (idprop) ? IDP_GetPropertyTypeFromGroup(idprop, "cycles", IDP_GROUP) : nullptr;
518}
519
521{
522 IDProperty *idprop = render_layer->prop;
523 return (idprop) ? IDP_GetPropertyTypeFromGroup(idprop, "cycles", IDP_GROUP) : nullptr;
524}
525
526float version_cycles_property_float(IDProperty *idprop, const char *name, float default_value)
527{
529 return (prop) ? IDP_float_get(prop) : default_value;
530}
531
532int version_cycles_property_int(IDProperty *idprop, const char *name, int default_value)
533{
535 return (prop) ? IDP_int_get(prop) : default_value;
536}
537
538void version_cycles_property_int_set(IDProperty *idprop, const char *name, int value)
539{
540 if (IDProperty *prop = IDP_GetPropertyTypeFromGroup(idprop, name, IDP_INT)) {
541 IDP_int_set(prop, value);
542 }
543 else {
544 IDP_AddToGroup(idprop, blender::bke::idprop::create(name, value).release());
545 }
546}
547
548bool version_cycles_property_boolean(IDProperty *idprop, const char *name, bool default_value)
549{
550 return version_cycles_property_int(idprop, name, default_value);
551}
552
553void version_cycles_property_boolean_set(IDProperty *idprop, const char *name, bool value)
554{
556}
557
559{
561 return (idprop) ? IDP_GetPropertyTypeFromGroup(idprop, "cycles_visibility", IDP_GROUP) : nullptr;
562}
563
565 bNodeTree *ntree,
566 FunctionRef<bool(bNode *)> check_node,
567 const char *socket_identifier,
568 FunctionRef<void(bNode *, bNodeSocket *)> update_input,
569 FunctionRef<void(bNode *, bNodeSocket *, bNode *, bNodeSocket *)> update_input_link)
570{
571 bool need_update = false;
572
573 /* Iterate backwards from end so we don't encounter newly added links. */
575 /* Detect link to replace. */
576 bNode *fromnode = link->fromnode;
577 bNodeSocket *fromsock = link->fromsock;
578 bNode *tonode = link->tonode;
579 bNodeSocket *tosock = link->tosock;
580
581 if (!(tonode != nullptr && check_node(tonode) && STREQ(tosock->identifier, socket_identifier)))
582 {
583 continue;
584 }
585
586 /* Replace links with updated equivalent */
587 blender::bke::node_remove_link(ntree, *link);
588 update_input_link(fromnode, fromsock, tonode, tosock);
589
590 need_update = true;
591 }
592
593 /* Update sockets and/or their default values.
594 * Do this after the link update in case it changes the identifier. */
595 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
596 if (check_node(node)) {
597 bNodeSocket *input = blender::bke::node_find_socket(*node, SOCK_IN, socket_identifier);
598 if (input != nullptr) {
599 update_input(node, input);
600 }
601 }
602 }
603
604 if (need_update) {
606 }
607}
608
610{
611 bNode *output_node = nullptr;
612 /* NOTE: duplicated from `ntreeShaderOutputNode` with small adjustments so it can be called
613 * during versioning. */
614 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
615 if (node->type_legacy != node_type) {
616 continue;
617 }
618 if (node->custom1 == SHD_OUTPUT_ALL) {
619 if (output_node == nullptr) {
620 output_node = node;
621 }
622 else if (output_node->custom1 == SHD_OUTPUT_ALL) {
623 if ((node->flag & NODE_DO_OUTPUT) && !(output_node->flag & NODE_DO_OUTPUT)) {
624 output_node = node;
625 }
626 }
627 }
628 else if (node->custom1 == SHD_OUTPUT_EEVEE) {
629 if (output_node == nullptr) {
630 output_node = node;
631 }
632 else if ((node->flag & NODE_DO_OUTPUT) && !(output_node->flag & NODE_DO_OUTPUT)) {
633 output_node = node;
634 }
635 }
636 }
637
638 return output_node;
639}
640
642{
643 if (!bmain->scenes.first) {
644 return false;
645 }
646
647 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
648 bool match = false;
649 for (const char *engine : engines) {
650 if (STREQ(scene->r.engine, engine)) {
651 match = true;
652 }
653 }
654 if (!match) {
655 return false;
656 }
657 }
658
659 return true;
660}
661
663{
664 if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 4)) {
665 return scene->nodetree;
666 }
667
668 return scene->compositing_node_group;
669}
670
672 const short versionfile,
673 const short subversionfile)
674{
675 if (!MAIN_VERSION_FILE_ATLEAST(bmain, versionfile, subversionfile)) {
676 return false;
677 }
678
679 LISTBASE_FOREACH (Library *, library, &bmain->libraries) {
680 if (!LIBRARY_VERSION_FILE_ATLEAST(library, versionfile, subversionfile)) {
681 return false;
682 }
683 }
684
685 return true;
686}
687
689 BlendfileLinkAppendContext *lapp_context,
690 BlendFileReadReport *reports)
691{
692 /* WARNING: The code below may add IDs. These IDs _will_ be (by definition) conforming to current
693 * code's version already, and _must not_ be *versioned* again.
694 *
695 * This means that when adding code here, _extreme_ care must be taken that it will not badly
696 * affect these 'modern' IDs potentially added by already existing processing.
697 *
698 * Adding code here should only be done in exceptional cases.
699 *
700 * Some further points to keep in mind:
701 * - While typically versioning order should be respected in code below (i.e. versioning
702 * affecting older versions should be done first), _this is not a hard rule_. And it should
703 * not be assumed older code must not be checked when adding newer code.
704 * - Do not rely strongly on versioning numbers here. This code may be run on data from
705 * different Blender versions (through the usage of linked data), and all existing data have
706 * already been processed through the whole do_version during blendfile reading itself. So
707 * decision to apply some versioning on some data should mostly rely on the data itself.
708 * - Unlike the regular do_version code, this one should _not_ be assumed as 'valid forever'.
709 * It is closer to the Editing or BKE code in that respect, changes to the logic or data
710 * model of an ID will require a careful update here as well.
711 *
712 * Another critical weakness of this code is that it is currently _not_ performed on data linked
713 * during an editing session, but only on data linked while reading a whole blendfile. This will
714 * have to be fixed at some point.
715 */
716
717 /* NOTE: Version number is checked against Main version (i.e. current blend file version), AND
718 * the versions of all the linked libraries. */
719
720 if (!blendfile_or_libraries_versions_atleast(new_bmain, 250, 0)) {
721 /* This happens here, because at this point in the versioning code there's
722 * 'reports' available. */
723 reports->pre_animato_file_loaded = true;
724 }
725
726 if (!blendfile_or_libraries_versions_atleast(new_bmain, 250, 0)) {
727 LISTBASE_FOREACH (Scene *, scene, &new_bmain->scenes) {
728 if (scene->ed) {
730 }
731 }
732 }
733
734 if (!blendfile_or_libraries_versions_atleast(new_bmain, 302, 1)) {
736 /* Currently liboverride code can generate invalid namemap. This is a known issue, requires
737 * #107847 to be properly fixed. */
739 }
740
741 if (!blendfile_or_libraries_versions_atleast(new_bmain, 302, 3)) {
742 /* Does not add any new IDs, but needs the full Main data-base. */
744 }
745
746 if (!blendfile_or_libraries_versions_atleast(new_bmain, 402, 22)) {
747 /* Initial auto smooth versioning started at (401, 2), but a bug caused the legacy flag to not
748 * be cleared, so it is re-run in a later version when the bug is fixed and the versioning has
749 * been made idempotent. */
751 }
752
753 if (!blendfile_or_libraries_versions_atleast(new_bmain, 404, 2)) {
754 /* Version all the action assignments of just-versioned datablocks. This MUST happen before the
755 * GreasePencil conversion, as that assumes the Action Slots have already been assigned. */
757 }
758
759 if (!blendfile_or_libraries_versions_atleast(new_bmain, 403, 3)) {
760 /* Convert all the legacy grease pencil objects. This does not touch annotations. */
761 blender::bke::greasepencil::convert::legacy_main(*new_bmain, lapp_context, *reports);
762 }
763
764 if (!blendfile_or_libraries_versions_atleast(new_bmain, 500, 4)) {
765 LISTBASE_FOREACH (Scene *, scene, &new_bmain->scenes) {
766 bNodeTree *ntree = scene->nodetree;
767 if (!ntree) {
768 continue;
769 }
771 ntree->owner_id = nullptr;
772 ntree->id.tag |= ID_TAG_NO_MAIN;
773
774 scene->compositing_node_group = ntree;
775 scene->nodetree = nullptr;
776
777 BKE_libblock_management_main_add(new_bmain, ntree);
778
779 /* NOTE: The user count remains zero at this point. It will get automatically updated after
780 * blend file reading is done. */
781 }
782 }
783}
Versioning of old animation data. Most animation versioning code lives in the versioning_xxx....
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_get(prop)
IDProperty * IDP_ID_system_properties_get(ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition idprop.cc:895
IDProperty * IDP_GetPropertyTypeFromGroup(const IDProperty *prop, blender::StringRef name, char type) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:768
#define IDP_int_get(prop)
#define IDP_int_set(prop, value)
bool IDP_AddToGroup(IDProperty *group, IDProperty *prop) ATTR_NONNULL()
Definition idprop.cc:717
IDNewNameResult BKE_libblock_rename(Main &bmain, ID &id, blender::StringRefNull name, const IDNewNameMode mode=IDNewNameMode::RenameExistingNever)
Definition lib_id.cc:2370
void BKE_libblock_management_main_add(Main *bmain, void *idv)
Definition lib_id.cc:1123
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:902
#define MAIN_VERSION_FILE_ATLEAST(main, ver, subver)
Definition BKE_main.hh:658
#define LIBRARY_VERSION_FILE_ATLEAST(lib, ver, subver)
Definition BKE_main.hh:673
bool BKE_main_namemap_validate_and_fix(Main &bmain)
void BKE_main_mesh_legacy_convert_auto_smooth(Main &bmain)
#define FOREACH_NODETREE_END
Definition BKE_node.hh:881
#define FOREACH_NODETREE_BEGIN(bmain, _nodetree, _id)
Definition BKE_node.hh:871
#define GEO_NODE_REALIZE_INSTANCES
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)
ARegion * BKE_area_region_new()
Definition screen.cc:387
#define BLI_assert(a)
Definition BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1)
Definition listbase.cc:332
#define LISTBASE_FOREACH_BACKWARD_MUTABLE(type, var, list)
char * BLI_sprintfN(const char *__restrict format,...) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:693
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)
@ ID_TAG_NO_MAIN
Definition DNA_ID.h:978
#define ID_IS_LINKED(_id)
Definition DNA_ID.h:694
@ ID_FLAG_EMBEDDED_DATA
Definition DNA_ID.h:774
@ ID_GD_LEGACY
@ ID_GP
@ IDP_FLOAT
@ IDP_INT
@ IDP_GROUP
#define ID_LINK_PLACEHOLDER
@ SHD_OUTPUT_ALL
@ SHD_OUTPUT_EEVEE
@ NODE_OPTIONS
@ NODE_DO_OUTPUT
@ NODE_INIT
@ NODE_SELECT
eNodeSocketInOut
@ SOCK_OUT
@ SOCK_IN
@ SOCK_IS_LINKED
@ SOCK_GEOMETRY
Read Guarded memory(de)allocation.
const Value * lookup_ptr_as(const ForwardKey &key) const
Definition BLI_map.hh:516
constexpr bool is_empty() const
constexpr bool startswith(StringRef prefix) const
constexpr StringRef drop_known_prefix(StringRef prefix) const
void append(const T &value)
#define input
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
void convert_legacy_action_assignments(Main &bmain, ReportList *reports)
void legacy_main(Main &bmain, BlendfileLinkAppendContext *lapp_context, BlendFileReadReport &reports)
std::unique_ptr< IDProperty, IDPropertyDeleter > create(StringRef prop_name, int32_t value, eIDPropertyFlag flags={})
Allocate a new IDProperty of type IDP_INT, set its name and value.
void node_unlink_node(bNodeTree &ntree, bNode &node)
Definition node.cc:4255
bNodeSocket * node_find_socket(bNode &node, eNodeSocketInOut in_out, StringRef identifier)
Definition node.cc:2532
void node_unique_id(bNodeTree &ntree, bNode &node)
Definition node.cc:3459
void node_remove_link(bNodeTree *ntree, bNodeLink &link)
Definition node.cc:3847
void node_unlink_attached(bNodeTree *ntree, const bNode *parent)
Definition node.cc:4282
void node_free_node(bNodeTree *tree, bNode &node)
Definition node.cc:4302
void node_rebuild_id_vector(bNodeTree &node_tree)
Definition node.cc:4291
bNodeSocketType * node_socket_type_find(StringRef idname)
Definition node.cc:2462
bNode * node_add_static_node(const bContext *C, bNodeTree &ntree, int type)
Definition node.cc:3500
bNodeLink & node_add_link(bNodeTree &ntree, bNode &fromnode, bNodeSocket &fromsock, bNode &tonode, bNodeSocket &tosock)
Definition node.cc:3810
bNodeSocket * node_add_static_socket(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_out, int type, int subtype, StringRefNull identifier, StringRefNull name)
Definition node.cc:3197
bNodeType * node_type_find(StringRef idname)
Definition node.cc:2379
void node_unique_name(bNodeTree &ntree, bNode &node)
Definition node.cc:3453
void doversion_250_sound_proxy_update(Main *bmain, Editing *ed)
void node_socket_init_default_value_data(eNodeSocketDatatype datatype, int subtype, void **data)
const char * name
Definition DNA_ID.h:414
int tag
Definition DNA_ID.h:442
short flag
Definition DNA_ID.h:438
void * first
ListBase scenes
Definition BKE_main.hh:278
ListBase libraries
Definition BKE_main.hh:279
struct bNodeTree * compositing_node_group
struct IDProperty * system_properties
bNodeSocketRuntimeHandle * runtime
struct bNodeLink * link
void * default_value
char identifier[64]
char idname[64]
bNodeTreeInterface tree_interface
ListBase nodes
ListBase links
int16_t custom1
float width
ListBase inputs
float height
float locx_legacy
float color[3]
struct bNode * parent
char name[64]
int16_t type_legacy
bNodeRuntimeHandle * runtime
float locy_legacy
char idname[64]
ListBase outputs
Defines a socket type.
Definition BKE_node.hh:158
eNodeSocketDatatype type
Definition BKE_node.hh:193
Defines a node type.
Definition BKE_node.hh:238
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)
bool all_scenes_use(Main *bmain, const blender::Span< const char * > engines)
void version_node_remove(bNodeTree &ntree, bNode &node)
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)
void version_node_tree_clear_interface(bNodeTree &ntree)
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)
StringRef legacy_socket_idname_to_socket_type(StringRef idname)
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)
ARegion * do_versions_add_region(int regiontype, const char *)
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)
ARegion * do_versions_ensure_region(ListBase *regionbase, int region_type, const char *, int link_after_region_type)
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)
bNodeTree * version_get_scene_compositor_node_tree(Main *bmain, Scene *scene)
ARegion * do_versions_add_region_if_not_found(ListBase *regionbase, int region_type, const char *, 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)
short do_versions_new_to_old_idcode_get(const short id_code_new)
void version_node_id(bNodeTree *ntree, const int node_type, const char *new_name)