Blender  V3.3
versioning_common.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
6 /* allow readfile to use deprecated functionality */
7 #define DNA_DEPRECATED_ALLOW
8 
9 #include <cstring>
10 
11 #include "DNA_node_types.h"
12 #include "DNA_screen_types.h"
13 
14 #include "BLI_listbase.h"
15 #include "BLI_string.h"
16 #include "BLI_string_ref.hh"
17 
18 #include "BKE_animsys.h"
19 #include "BKE_lib_id.h"
20 #include "BKE_main.h"
21 #include "BKE_main_namemap.h"
22 #include "BKE_node.h"
23 
24 #include "MEM_guardedalloc.h"
25 
26 #include "versioning_common.h"
27 
28 using blender::StringRef;
29 
31  int region_type,
32  const char *name,
33  int link_after_region_type)
34 {
35  ARegion *link_after_region = nullptr;
36  LISTBASE_FOREACH (ARegion *, region, regionbase) {
37  if (region->regiontype == region_type) {
38  return nullptr;
39  }
40  if (region->regiontype == link_after_region_type) {
41  link_after_region = region;
42  }
43  }
44 
45  ARegion *new_region = static_cast<ARegion *>(MEM_callocN(sizeof(ARegion), name));
46  new_region->regiontype = region_type;
47  BLI_insertlinkafter(regionbase, link_after_region, new_region);
48  return new_region;
49 }
50 
52  const short id_type,
53  const char *name_src,
54  const char *name_dst)
55 {
56  /* We can ignore libraries */
57  ListBase *lb = which_libbase(bmain, id_type);
58  ID *id = nullptr;
59  LISTBASE_FOREACH (ID *, idtest, lb) {
60  if (!ID_IS_LINKED(idtest)) {
61  if (STREQ(idtest->name + 2, name_src)) {
62  id = idtest;
63  }
64  if (STREQ(idtest->name + 2, name_dst)) {
65  return nullptr;
66  }
67  }
68  }
69  if (id != nullptr) {
70  BKE_main_namemap_remove_name(bmain, id, id->name + 2);
71  BLI_strncpy(id->name + 2, name_dst, sizeof(id->name) - 2);
72  /* We know it's unique, this just sorts. */
74  }
75  return id;
76 }
77 
78 static void change_node_socket_name(ListBase *sockets, const char *old_name, const char *new_name)
79 {
80  LISTBASE_FOREACH (bNodeSocket *, socket, sockets) {
81  if (STREQ(socket->name, old_name)) {
82  BLI_strncpy(socket->name, new_name, sizeof(socket->name));
83  }
84  if (STREQ(socket->identifier, old_name)) {
85  BLI_strncpy(socket->identifier, new_name, sizeof(socket->name));
86  }
87  }
88 }
89 
91 {
92  StringRef name = socket->name;
93  StringRef id = socket->identifier;
94 
95  if (!id.startswith(name)) {
96  /* We only need to affect the case where the identifier starts with the name. */
97  return;
98  }
99 
100  StringRef id_number = id.drop_known_prefix(name);
101  if (id_number.is_empty()) {
102  /* The name was already unique, and didn't need numbers at the end for the id. */
103  return;
104  }
105 
106  if (id_number.startswith(".")) {
107  socket->identifier[name.size()] = '_';
108  }
109 }
110 
112  const int node_type,
113  const char *old_name,
114  const char *new_name)
115 {
117  if (node->type == node_type) {
118  change_node_socket_name(&node->inputs, old_name, new_name);
119  change_node_socket_name(&node->outputs, old_name, new_name);
120  }
121  }
122 }
123 
125  const int node_type,
126  const char *old_name,
127  const char *new_name)
128 {
130  if (node->type == node_type) {
131  change_node_socket_name(&node->inputs, old_name, new_name);
132  }
133  }
134 }
135 
137  const int node_type,
138  const char *old_name,
139  const char *new_name)
140 {
142  if (node->type == node_type) {
143  change_node_socket_name(&node->outputs, old_name, new_name);
144  }
145  }
146 }
147 
149  bNode *node,
150  eNodeSocketInOut in_out,
151  int type,
152  int subtype,
153  const char *identifier,
154  const char *name)
155 {
156  bNodeSocket *sock = nodeFindSocket(node, in_out, identifier);
157  if (sock != nullptr) {
158  return sock;
159  }
160  return nodeAddStaticSocket(ntree, node, in_out, type, subtype, identifier, name);
161 }
162 
163 void version_node_id(bNodeTree *ntree, const int node_type, const char *new_name)
164 {
166  if (node->type == node_type) {
167  if (!STREQ(node->idname, new_name)) {
168  strcpy(node->idname, new_name);
169  }
170  }
171  }
172 }
173 
175  const int node_tree_type,
176  const int node_type,
177  const int socket_index_orig,
178  const int socket_index_offset,
179  const int total_number_of_sockets)
180 {
181 
182  /* The for loop for the input ids is at the top level otherwise we lose the animation
183  * keyframe data. Not sure what causes that, so I (Sybren) moved the code here from
184  * versioning_290.c as-is (structure-wise). */
185  for (int input_index = total_number_of_sockets - 1; input_index >= socket_index_orig;
186  input_index--) {
187  FOREACH_NODETREE_BEGIN (bmain, ntree, owner_id) {
188  if (ntree->type != node_tree_type) {
189  continue;
190  }
191 
193  if (node->type != node_type) {
194  continue;
195  }
196 
197  const size_t node_name_length = strlen(node->name);
198  const size_t node_name_escaped_max_length = (node_name_length * 2);
199  char *node_name_escaped = (char *)MEM_mallocN(node_name_escaped_max_length + 1,
200  "escaped name");
201  BLI_str_escape(node_name_escaped, node->name, node_name_escaped_max_length);
202  char *rna_path_prefix = BLI_sprintfN("nodes[\"%s\"].inputs", node_name_escaped);
203 
204  const int new_index = input_index + socket_index_offset;
206  bmain, owner_id, rna_path_prefix, nullptr, nullptr, input_index, new_index, false);
207  MEM_freeN(rna_path_prefix);
208  MEM_freeN(node_name_escaped);
209  }
210  }
212  }
213 }
214 
216 {
218  LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
219  socket->flag &= ~SOCK_IN_USE;
220  }
221  LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) {
222  socket->flag &= ~SOCK_IN_USE;
223  }
224  }
225  LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
226  link->fromsock->flag |= SOCK_IN_USE;
227  link->tosock->flag |= SOCK_IN_USE;
228  }
229 }
230 
231 ARegion *do_versions_add_region(int regiontype, const char *name)
232 {
233  ARegion *region = (ARegion *)MEM_callocN(sizeof(ARegion), name);
234  region->regiontype = regiontype;
235  return region;
236 }
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)
Definition: anim_data.c:1296
void BLI_libblock_ensure_unique_name(struct Main *bmain, const char *name) ATTR_NONNULL()
Definition: lib_id.c:1813
struct ListBase * which_libbase(struct Main *bmain, short type)
Definition: main.c:567
void BKE_main_namemap_remove_name(struct Main *bmain, struct ID *id, const char *name) ATTR_NONNULL()
struct bNodeSocket * nodeAddStaticSocket(struct bNodeTree *ntree, struct bNode *node, eNodeSocketInOut in_out, int type, int subtype, const char *identifier, const char *name)
Definition: node.cc:1897
#define FOREACH_NODETREE_END
Definition: BKE_node.h:1058
struct bNodeSocket * nodeFindSocket(const struct bNode *node, eNodeSocketInOut in_out, const char *identifier)
#define FOREACH_NODETREE_BEGIN(bmain, _nodetree, _id)
Definition: BKE_node.h:1048
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1)
Definition: listbase.c:301
size_t size_t char * BLI_sprintfN(const char *__restrict format,...) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
size_t size_t char size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL()
Definition: string.c:250
#define STREQ(a, b)
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:566
eNodeSocketInOut
@ SOCK_IN_USE
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
constexpr bool is_empty() const
constexpr bool startswith(StringRef prefix) const
constexpr int64_t size() const
constexpr StringRef drop_known_prefix(StringRef prefix) const
OperationNode * node
bNodeTree * ntree
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
short regiontype
Definition: DNA_ID.h:368
char name[66]
Definition: DNA_ID.h:378
Definition: BKE_main.h:121
char name[64]
char identifier[64]
ListBase nodes
ListBase links
void version_node_socket_id_delim(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)
ID * do_versions_rename_id(Main *bmain, const short id_type, const char *name_src, const char *name_dst)
void version_node_input_socket_name(bNodeTree *ntree, const int node_type, const char *old_name, const char *new_name)
ARegion * do_versions_add_region(int regiontype, const char *name)
void version_node_socket_name(bNodeTree *ntree, const int node_type, const char *old_name, const char *new_name)
void version_socket_update_is_used(bNodeTree *ntree)
bNodeSocket * version_node_add_socket_if_not_exist(bNodeTree *ntree, bNode *node, eNodeSocketInOut in_out, int type, int subtype, const char *identifier, const char *name)
ARegion * do_versions_add_region_if_not_found(ListBase *regionbase, int region_type, const char *name, int link_after_region_type)
static void change_node_socket_name(ListBase *sockets, const char *old_name, const char *new_name)
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)