Blender V5.0
rna_blendfile_import.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
9#include <cstdlib>
10
11#include "BLO_readfile.hh"
12
13#include "BLT_translation.hh"
14
15#include "DNA_space_types.h"
16
18
19#include "RNA_define.hh"
20#include "RNA_enum_types.hh"
21
22#include "rna_internal.hh"
23
24#ifdef RNA_RUNTIME
25
26# include "BLI_bit_span.hh"
27# include "BLI_string.h"
28
29void rna_BlendImportContextLibrary_filepath_get(PointerRNA *ptr, char *value)
30{
32 ptr->data);
33 const size_t str_len = ctx_lib->path.length();
34 BLI_strncpy(value, ctx_lib->path.c_str(), str_len + 1);
35}
36
37int rna_BlendImportContextLibrary_filepath_len(PointerRNA *ptr)
38{
40 ptr->data);
41 return int(ctx_lib->path.length());
42}
43
44void rna_BlendImportContextItem_name_get(PointerRNA *ptr, char *value)
45{
47 ptr->data);
48 const size_t str_len = ctx_item->name.length();
49 BLI_strncpy(value, ctx_item->name.c_str(), str_len + 1);
50}
51
52int rna_BlendImportContextItem_name_len(PointerRNA *ptr)
53{
55 ptr->data);
56 return int(ctx_item->name.length());
57}
58
59int rna_BlendImportContextItem_id_type_get(PointerRNA *ptr)
60{
62 ptr->data);
63 return int(ctx_item->idcode);
64}
65
66struct RNABlendImportContextItemLibrariesIterator {
67 BlendfileLinkAppendContextItem *ctx_item;
68 blender::bits::BitIterator iter;
69 int iter_index;
70};
71
72void rna_BlendImportContextItem_libraries_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
73{
75 ptr->data);
76
77 const blender::BitVector<> &libraries = ctx_item->libraries;
78 RNABlendImportContextItemLibrariesIterator *libs_iter =
79 MEM_new<RNABlendImportContextItemLibrariesIterator>(
80 __func__, RNABlendImportContextItemLibrariesIterator{ctx_item, libraries.begin(), 0});
81 iter->internal.custom = libs_iter;
82 while (!(*libs_iter->iter) && libs_iter->iter != libs_iter->ctx_item->libraries.end()) {
83 libs_iter->iter.operator++();
84 libs_iter->iter_index++;
85 }
86 iter->valid = (libs_iter->iter != libs_iter->ctx_item->libraries.end());
87}
88
89void rna_BlendImportContextItem_libraries_next(CollectionPropertyIterator *iter)
90{
91 RNABlendImportContextItemLibrariesIterator *libs_iter =
92 static_cast<RNABlendImportContextItemLibrariesIterator *>(iter->internal.custom);
93 do {
94 libs_iter->iter.operator++();
95 libs_iter->iter_index++;
96 } while (!(*libs_iter->iter) && libs_iter->iter != libs_iter->ctx_item->libraries.end());
97 iter->valid = (libs_iter->iter != libs_iter->ctx_item->libraries.end());
98}
99
100void rna_BlendImportContextItem_libraries_end(CollectionPropertyIterator *iter)
101{
102 RNABlendImportContextItemLibrariesIterator *libs_iter =
103 static_cast<RNABlendImportContextItemLibrariesIterator *>(iter->internal.custom);
104
105 iter->valid = false;
106 iter->internal.custom = nullptr;
107 MEM_delete(libs_iter);
108}
109
110PointerRNA rna_BlendImportContextItem_libraries_get(CollectionPropertyIterator *iter)
111{
112 RNABlendImportContextItemLibrariesIterator *libs_iter =
113 static_cast<RNABlendImportContextItemLibrariesIterator *>(iter->internal.custom);
114
116 libs_iter->ctx_item->lapp_context->libraries[libs_iter->iter_index];
117 return RNA_pointer_create_with_parent(iter->parent, &RNA_BlendImportContextLibrary, &ctx_lib);
118}
119
120int rna_BlendImportContextItem_libraries_len(PointerRNA *ptr)
121{
123 ptr->data);
124
125 /* Count amount of enabled libraries in the item's bitmask. */
126 int count = 0;
127 for (const blender::BitRef &bit : ctx_item->libraries) {
128 if (bit) {
129 count++;
130 }
131 }
132 return count;
133}
134
135int rna_BlendImportContextItem_append_action_get(PointerRNA *ptr)
136{
138 ptr->data);
139 return int(ctx_item->action);
140}
141
142int rna_BlendImportContextItem_import_info_get(PointerRNA *ptr)
143{
145 ptr->data);
146 return int(ctx_item->tag);
147}
148
149PointerRNA rna_BlendImportContextItem_id_get(PointerRNA *ptr)
150{
152 ptr->data);
153 return RNA_id_pointer_create(ctx_item->new_id);
154}
155
156PointerRNA rna_BlendImportContextItem_source_library_get(PointerRNA *ptr)
157{
159 ptr->data);
160 return RNA_id_pointer_create(&ctx_item->source_library->id);
161}
162
163PointerRNA rna_BlendImportContextItem_library_override_id_get(PointerRNA *ptr)
164{
166 ptr->data);
167 return RNA_id_pointer_create(ctx_item->liboverride_id);
168}
169
170PointerRNA rna_BlendImportContextItem_reusable_local_id_get(PointerRNA *ptr)
171{
173 ptr->data);
175}
176
177struct RNABlendImportContextItemsIterator {
178 BlendfileLinkAppendContext *ctx;
180};
181
182void rna_BlendImportContext_import_items_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
183{
184 BlendfileLinkAppendContext *ctx = static_cast<BlendfileLinkAppendContext *>(ptr->data);
185
186 RNABlendImportContextItemsIterator *items_iter = MEM_new<RNABlendImportContextItemsIterator>(
187 __func__, RNABlendImportContextItemsIterator{ctx, ctx->items.begin()});
188 iter->internal.custom = items_iter;
189 iter->valid = (items_iter->iter != items_iter->ctx->items.end());
190}
191
192void rna_BlendImportContext_import_items_next(CollectionPropertyIterator *iter)
193{
194 RNABlendImportContextItemsIterator *items_iter =
195 static_cast<RNABlendImportContextItemsIterator *>(iter->internal.custom);
196 items_iter->iter++;
197 iter->valid = (items_iter->iter != items_iter->ctx->items.end());
198}
199
200void rna_BlendImportContext_import_items_end(CollectionPropertyIterator *iter)
201{
202 RNABlendImportContextItemsIterator *items_iter =
203 static_cast<RNABlendImportContextItemsIterator *>(iter->internal.custom);
204
205 iter->valid = false;
206 iter->internal.custom = nullptr;
207 MEM_delete(items_iter);
208}
209
210PointerRNA rna_BlendImportContext_import_items_get(CollectionPropertyIterator *iter)
211{
212 RNABlendImportContextItemsIterator *items_iter =
213 static_cast<RNABlendImportContextItemsIterator *>(iter->internal.custom);
214
215 BlendfileLinkAppendContextItem &ctx_item = *items_iter->iter;
216 return RNA_pointer_create_with_parent(iter->parent, &RNA_BlendImportContextItem, &ctx_item);
217}
218
219int rna_BlendImportContext_import_items_len(PointerRNA *ptr)
220{
221 BlendfileLinkAppendContext *ctx = static_cast<BlendfileLinkAppendContext *>(ptr->data);
222 return int(ctx->items.size());
223}
224
225int rna_BlendImportContext_options_get(PointerRNA *ptr)
226{
227 BlendfileLinkAppendContext *ctx = static_cast<BlendfileLinkAppendContext *>(ptr->data);
228 return ctx->params->flag;
229}
230
231int rna_BlendImportContext_process_stage_get(PointerRNA *ptr)
232{
233 BlendfileLinkAppendContext *ctx = static_cast<BlendfileLinkAppendContext *>(ptr->data);
234 return int(ctx->process_stage);
235}
236
237#else /* RNA_RUNTIME */
238
240{
241 StructRNA *srna;
242 PropertyRNA *prop;
243
244 srna = RNA_def_struct(brna, "BlendImportContextLibrary", nullptr);
246 srna,
247 "Blendfile Import Context Library",
248 "Library (blendfile) reference in a BlendImportContext data. Currently only "
249 "exposed as read-only data for the pre/post blendimport handlers");
250
251 RNA_define_verify_sdna(false); /* not in sdna */
252
253 prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
256 "rna_BlendImportContextLibrary_filepath_get",
257 "rna_BlendImportContextLibrary_filepath_len",
258 nullptr);
259
260 RNA_define_verify_sdna(true); /* not in sdna */
261}
262
264{
265 StructRNA *srna;
266
267 RNA_def_property_srna(cprop, "BlendImportContextLibraries");
268 srna = RNA_def_struct(brna, "BlendImportContextLibraries", nullptr);
270 "Blendfile Import Context Libraries",
271 "Collection of source libraries, i.e. blendfile paths");
272}
273
275{
276 StructRNA *srna;
277 PropertyRNA *prop;
278
279 srna = RNA_def_struct(brna, "BlendImportContextItem", nullptr);
281 srna,
282 "Blendfile Import Context Item",
283 "An item (representing a data-block) in a BlendImportContext data. Currently only "
284 "exposed as read-only data for the pre/post linking handlers");
285
286 RNA_define_verify_sdna(false); /* not in sdna */
287
288 prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
290 RNA_def_property_ui_text(prop, "ID Name", "ID name of the item");
292 prop, "rna_BlendImportContextItem_name_get", "rna_BlendImportContextItem_name_len", nullptr);
293
294 prop = RNA_def_property(srna, "id_type", PROP_ENUM, PROP_NONE);
297 RNA_def_property_ui_text(prop, "ID Type", "ID type of the item");
299 RNA_def_property_enum_funcs(prop, "rna_BlendImportContextItem_id_type_get", nullptr, nullptr);
300
301 prop = RNA_def_property(srna, "source_libraries", PROP_COLLECTION, PROP_NONE);
302 RNA_def_property_struct_type(prop, "BlendImportContextLibrary");
305 "Source Libraries",
306 "List of libraries to search and import that ID from. The ID will be "
307 "imported from the first file in that list that contains it");
309 "rna_BlendImportContextItem_libraries_begin",
310 "rna_BlendImportContextItem_libraries_next",
311 "rna_BlendImportContextItem_libraries_end",
312 "rna_BlendImportContextItem_libraries_get",
313 "rna_BlendImportContextItem_libraries_len",
314 nullptr,
315 nullptr,
316 nullptr);
318
319 static const EnumPropertyItem blend_import_item_append_action_items[] = {
320 {LINK_APPEND_ACT_UNSET, "UNSET", 0, "", "Not yet defined"},
321 {LINK_APPEND_ACT_KEEP_LINKED, "KEEP_LINKED", 0, "", "ID has been kept linked"},
323 "REUSE_LOCAL",
324 0,
325 "",
326 "An existing matching local ID has been re-used"},
327 {LINK_APPEND_ACT_MAKE_LOCAL, "MAKE_LOCAL", 0, "", "The newly linked ID has been made local"},
329 "COPY_LOCAL",
330 0,
331 "",
332 "The linked ID had other unrelated usages, so it has been duplicated into a local copy"},
333 {0, nullptr, 0, nullptr, nullptr},
334 };
335 prop = RNA_def_property(srna, "append_action", PROP_ENUM, PROP_NONE);
336 RNA_def_property_enum_items(prop, blend_import_item_append_action_items);
339 "Append Action",
340 "How this item has been handled by the append operation. Only set if "
341 "the data has been appended");
343 prop, "rna_BlendImportContextItem_append_action_get", nullptr, nullptr);
344
345 static const EnumPropertyItem blend_import_item_import_info_items[] = {
347 "INDIRECT_USAGE",
348 0,
349 "",
350 "That item was added for an indirectly imported ID, as a dependency of another data-block"},
352 "LIBOVERRIDE_DEPENDENCY",
353 0,
354 "",
355 "That item represents an ID also used as liboverride dependency (either directly, as a "
356 "liboverride reference, or indirectly, as data used by a liboverride reference). It should "
357 "never be directly made local. Mutually exclusive with `LIBOVERRIDE_DEPENDENCY_ONLY`"},
359 "LIBOVERRIDE_DEPENDENCY_ONLY",
360 0,
361 "",
362 "That item represents an ID only used as liboverride dependency (either directly or "
363 "indirectly, see `LIBOVERRIDE_DEPENDENCY` for precisions). It should not be considered "
364 "during the 'make local' (append) process, and remain purely linked data. Mutually "
365 "exclusive with `LIBOVERRIDE_DEPENDENCY`"},
366 {0, nullptr, 0, nullptr, nullptr},
367 };
368 prop = RNA_def_property(srna, "import_info", PROP_ENUM, PROP_NONE);
371 RNA_def_property_enum_items(prop, blend_import_item_import_info_items);
373 prop, "Import Info", "Various status info about an item after it has been imported");
375 prop, "rna_BlendImportContextItem_import_info_get", nullptr, nullptr);
376
377 prop = RNA_def_property(srna, "id", PROP_POINTER, PROP_NONE);
381 "Imported ID",
382 "The imported ID. None until it has been linked or appended. "
383 "May be the same as ``reusable_local_id`` when appended");
385 prop, "rna_BlendImportContextItem_id_get", nullptr, nullptr, nullptr);
386
387 prop = RNA_def_property(srna, "source_library", PROP_POINTER, PROP_NONE);
388 RNA_def_property_struct_type(prop, "Library");
391 "Source Library",
392 "Library ID representing the blendfile from which the ID was imported. "
393 "None until the ID has been linked or appended");
395 prop, "rna_BlendImportContextItem_source_library_get", nullptr, nullptr, nullptr);
396
397 prop = RNA_def_property(srna, "library_override_id", PROP_POINTER, PROP_NONE);
401 prop,
402 "Library Overridden ID",
403 "The library override of the linked ID. None until it has been created");
405 prop, "rna_BlendImportContextItem_library_override_id_get", nullptr, nullptr, nullptr);
406
407 prop = RNA_def_property(srna, "reusable_local_id", PROP_POINTER, PROP_NONE);
411 "Reusable Local ID",
412 "The already existing local ID that may be reused in append & reuse "
413 "case. None until it has been found");
415 prop, "rna_BlendImportContextItem_reusable_local_id_get", nullptr, nullptr, nullptr);
416
417 RNA_define_verify_sdna(true); /* not in sdna */
418}
419
421{
422 StructRNA *srna;
423
424 RNA_def_property_srna(cprop, "BlendImportContextItems");
425 srna = RNA_def_struct(brna, "BlendImportContextItems", nullptr);
427 srna, "Blendfile Import Context Items", "Collection of blendfile import context items");
428
429 /* TODO: Add/Remove items _before_ doing link/append (i.e. for 'pre' handlers). */
430}
431
433{
434 StructRNA *srna;
435 PropertyRNA *prop;
436
437 srna = RNA_def_struct(brna, "BlendImportContext", nullptr);
439 srna,
440 "Blendfile Import Context",
441 "Contextual data for a blendfile library/linked-data related operation. Currently "
442 "only exposed as read-only data for the pre/post blendimport handlers");
443
444 RNA_define_verify_sdna(false); /* not in sdna */
445
446 /* NOTE: Cannot use just `items` here as this is a reserved Python dict method name. */
447 prop = RNA_def_property(srna, "import_items", PROP_COLLECTION, PROP_NONE);
448 RNA_def_property_struct_type(prop, "BlendImportContextItem");
451 "rna_BlendImportContext_import_items_begin",
452 "rna_BlendImportContext_import_items_next",
453 "rna_BlendImportContext_import_items_end",
454 "rna_BlendImportContext_import_items_get",
455 "rna_BlendImportContext_import_items_len",
456 nullptr,
457 nullptr,
458 nullptr);
460
461 static const EnumPropertyItem blend_import_options_items[] = {
462 {FILE_LINK, "LINK", 0, "", "Only link data, instead of appending it"},
464 "MAKE_PATHS_RELATIVE",
465 0,
466 "",
467 "Make paths of used library blendfiles relative to current blendfile"},
469 "USE_PLACEHOLDERS",
470 0,
471 "",
472 "Generate a placeholder (empty ID) if not found in any library files"},
474 "FORCE_INDIRECT",
475 0,
476 "",
477 "Force loaded ID to be tagged as indirectly linked (used in reload context only)"},
479 "APPEND_SET_FAKEUSER",
480 0,
481 "",
482 "Set fake user on appended IDs"},
484 "APPEND_RECURSIVE",
485 0,
486 "",
487 "Append (make local) also indirect dependencies of appended IDs coming from other "
488 "libraries. NOTE: All IDs (including indirectly linked ones) coming from the same initial "
489 "library are always made local"},
491 "APPEND_LOCAL_ID_REUSE",
492 0,
493 "",
494 "Try to re-use previously appended matching IDs when appending them again, instead of "
495 "creating local duplicates"},
497 "APPEND_ASSET_DATA_CLEAR",
498 0,
499 "",
500 "Clear the asset data on append (it is always kept for linked data)"},
501 {FILE_AUTOSELECT, "SELECT_OBJECTS", 0, "", "Automatically select imported objects"},
503 "USE_ACTIVE_COLLECTION",
504 0,
505 "",
506 "Use the active Collection of the current View Layer to instantiate imported "
507 "collections and objects"},
509 "OBDATA_INSTANCE",
510 0,
511 "",
512 "Instantiate object data IDs (i.e. create objects for them if needed)"},
514 "COLLECTION_INSTANCE",
515 0,
516 "",
517 "Instantiate collections as empties, instead of linking them into the current view layer"},
518 {0, nullptr, 0, nullptr, nullptr},
519 };
520 prop = RNA_def_property(srna, "options", PROP_ENUM, PROP_NONE);
523 RNA_def_property_enum_items(prop, blend_import_options_items);
524 RNA_def_property_enum_funcs(prop, "rna_BlendImportContext_options_get", nullptr, nullptr);
525 RNA_def_property_ui_text(prop, "", "Options for this blendfile import operation");
526
527 /* NOTE: Only stages currently exposed to handlers are listed here. */
528 static const EnumPropertyItem blend_import_process_stage_items[] = {
530 "INIT",
531 0,
532 "",
533 "Blendfile import context has been initialized and filled with a list of items to import, "
534 "no data has been linked or appended yet"},
536 "DONE",
537 0,
538 "",
539 "All data has been imported and is available in the list of \"import_items\""},
540 {0, nullptr, 0, nullptr, nullptr},
541 };
542 prop = RNA_def_property(srna, "process_stage", PROP_ENUM, PROP_NONE);
543 RNA_def_property_enum_items(prop, blend_import_process_stage_items);
545 RNA_def_property_ui_text(prop, "", "Current stage of the import process");
546 RNA_def_property_enum_funcs(prop, "rna_BlendImportContext_process_stage_get", nullptr, nullptr);
547
548 RNA_define_verify_sdna(true); /* not in sdna */
549}
550
557
558#endif /* RNA_RUNTIME */
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
external readfile function prototypes.
@ BLO_LIBLINK_APPEND_RECURSIVE
@ BLO_LIBLINK_USE_PLACEHOLDERS
@ BLO_LIBLINK_APPEND_ASSET_DATA_CLEAR
@ BLO_LIBLINK_OBDATA_INSTANCE
@ BLO_LIBLINK_APPEND_SET_FAKEUSER
@ BLO_LIBLINK_FORCE_INDIRECT
@ BLO_LIBLINK_APPEND_LOCAL_ID_REUSE
@ BLO_LIBLINK_COLLECTION_INSTANCE
#define BLT_I18NCONTEXT_ID_ID
@ FILE_ACTIVE_COLLECTION
@ FILE_RELPATH
@ FILE_AUTOSELECT
@ FILE_LINK
@ PROP_ENUM
Definition RNA_types.hh:166
@ PROP_STRING
Definition RNA_types.hh:165
@ PROP_POINTER
Definition RNA_types.hh:167
@ PROP_COLLECTION
Definition RNA_types.hh:168
@ PROP_EDITABLE
Definition RNA_types.hh:306
@ PROP_ENUM_FLAG
Definition RNA_types.hh:404
@ PROP_NONE
Definition RNA_types.hh:233
@ PROP_FILEPATH
Definition RNA_types.hh:236
BitIterator begin() const
int count
const EnumPropertyItem rna_enum_id_type_items[]
Definition rna_ID.cc:29
PointerRNA RNA_pointer_create_with_parent(const PointerRNA &parent, StructRNA *type, void *data)
PointerRNA RNA_id_pointer_create(ID *id)
static void rna_def_blendfile_import_context(BlenderRNA *brna)
static void rna_def_blendfile_import_library(BlenderRNA *brna)
static void RNA_def_blendfile_import_libraries(BlenderRNA *brna, PropertyRNA *cprop)
static void rna_def_blendfile_import_items(BlenderRNA *brna, PropertyRNA *cprop)
void RNA_def_blendfile_import(BlenderRNA *brna)
static void rna_def_blendfile_import_item(BlenderRNA *brna)
void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const char *length, const char *set)
void RNA_define_verify_sdna(bool verify)
void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
void RNA_def_property_srna(PropertyRNA *prop, const char *type)
void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, const char *next, const char *end, const char *get, const char *length, const char *lookupint, const char *lookupstring, const char *assignint)
void RNA_def_struct_ui_text(StructRNA *srna, const char *name, const char *description)
void RNA_def_property_enum_items(PropertyRNA *prop, const EnumPropertyItem *item)
void RNA_def_property_struct_type(PropertyRNA *prop, const char *type)
PropertyRNA * RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier, int type, int subtype)
void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char *set, const char *item)
StructRNA * RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from)
void RNA_def_property_clear_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const char *set, const char *type_fn, const char *poll)
void RNA_def_property_translation_context(PropertyRNA *prop, const char *context)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
std::list< BlendfileLinkAppendContextItem >::iterator items_iterator_t
std::list< BlendfileLinkAppendContextItem > items
union CollectionPropertyIterator::@220100362304005352221007113371015217044252346141 internal
ID id
Definition DNA_ID.h:550
PointerRNA * ptr
Definition wm_files.cc:4238