Python API: Add link/append pre/post handlers. #128279
@ -7,16 +7,169 @@
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#include "BLI_bit_vector.hh"
|
||||
#include "BLI_function_ref.hh"
|
||||
#include "BLI_map.hh"
|
||||
|
||||
#include "BLO_readfile.hh"
|
||||
|
||||
struct BlendHandle;
|
||||
struct ID;
|
||||
struct Library;
|
||||
struct LibraryLink_Params;
|
||||
struct MainLibraryWeakReferenceMap;
|
||||
struct ReportList;
|
||||
|
||||
/* TODO: Rename file to `BKE_blendfile_import.hh`. */
|
||||
/* TODO: Replace `BlendfileLinkAppend` prefix by `blender::bke::blendfile::import` namespace. */
|
||||
/* TODO: Move these enums to scoped enum classes. */
|
||||
|
||||
/** Actions to apply to an item (i.e. linked ID). */
|
||||
enum {
|
||||
LINK_APPEND_ACT_UNSET = 0,
|
||||
LINK_APPEND_ACT_KEEP_LINKED,
|
||||
LINK_APPEND_ACT_REUSE_LOCAL,
|
||||
LINK_APPEND_ACT_MAKE_LOCAL,
|
||||
LINK_APPEND_ACT_COPY_LOCAL,
|
||||
};
|
||||
|
||||
/** Various status info about an item (i.e. linked ID). */
|
||||
enum {
|
||||
/** An indirectly linked ID. */
|
||||
LINK_APPEND_TAG_INDIRECT = 1 << 0,
|
||||
/**
|
||||
* An ID also used as liboverride dependency (either directly, as a liboverride reference, or
|
||||
* indirectly, as data used by a liboverride reference). It should never be directly made local.
|
||||
*
|
||||
* Mutually exclusive with #LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY_ONLY.
|
||||
*/
|
||||
LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY = 1 << 1,
|
||||
/**
|
||||
* An ID only used as liboverride dependency (either directly or indirectly, see
|
||||
* #LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY for precisions). It should not be considered during
|
||||
* the 'make local' process, and remain purely linked data.
|
||||
*
|
||||
* Mutually exclusive with #LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY.
|
||||
*/
|
||||
LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY_ONLY = 1 << 2,
|
||||
};
|
||||
|
||||
/* NOTE: These three structs are currently exposed in header to allow for their usage in RNA.
|
||||
* Regualr C++ code should not access their content directly.
|
||||
*
|
||||
* TODO: Refactor these three structs into classes, and integrated the whole API into them. */
|
||||
struct BlendfileLinkAppendContext;
|
||||
struct BlendfileLinkAppendContextItem;
|
||||
|
||||
/** A data-block (ID) entry in the `items` list from #BlendfileLinkAppendContext. */
|
||||
struct BlendfileLinkAppendContextItem {
|
||||
/**
|
||||
* Link/Append context owner of this item. Used in RNA API, could be removed once RNA paths are
|
||||
* functional.
|
||||
*/
|
||||
BlendfileLinkAppendContext *lapp_context;
|
||||
|
||||
/** Name of the ID (without the heading two-chars IDcode). */
|
||||
std::string name;
|
||||
/** All libraries (from #BlendfileLinkAppendContext.libraries) to try to load this ID from. */
|
||||
blender::BitVector<> libraries;
|
||||
/** ID type. */
|
||||
short idcode;
|
||||
|
||||
/** Type of action to perform on this item, and general status tag information.
|
||||
* NOTE: Mostly used by append post-linking processing. */
|
||||
char action;
|
||||
char tag;
|
||||
|
||||
/** Newly linked ID (nullptr until it has been successfully linked). */
|
||||
ID *new_id;
|
||||
/** Library ID from which the #new_id has been linked (nullptr until it has been successfully
|
||||
* linked). */
|
||||
Library *source_library;
|
||||
/** Liboverride of the linked ID (nullptr until it has been successfully created or an existing
|
||||
* one has been found). */
|
||||
ID *liboverride_id;
|
||||
/**
|
||||
* Whether the item has a matching local ID that was already appended from the same source
|
||||
* before, and has not been modified. In 'Append & Reuse' case, this local ID _may_ be reused
|
||||
* instead of making linked data local again.
|
||||
*/
|
||||
ID *reusable_local_id;
|
||||
|
||||
/** Opaque user data pointer. */
|
||||
void *userdata;
|
||||
};
|
||||
|
||||
/** A blendfile library entry in the `libraries` vector from #BlendfileLinkAppendContext. */
|
||||
struct BlendfileLinkAppendContextLibrary {
|
||||
std::string path; /* Absolute .blend file path. */
|
||||
BlendHandle *blo_handle; /* Blend file handle, if any. */
|
||||
bool blo_handle_is_owned; /* Whether the blend file handle is owned, or borrowed. */
|
||||
/* The blendfile report associated with the `blo_handle`, if owned. */
|
||||
BlendFileReadReport bf_reports;
|
||||
};
|
||||
|
||||
/**
|
||||
* General container for all relevant data for a library/linked-data related operation (linking,
|
||||
* appending, library relocating, etc.).
|
||||
*/
|
||||
struct BlendfileLinkAppendContext {
|
||||
/** List of library paths to search IDs in. */
|
||||
blender::Vector<BlendfileLinkAppendContextLibrary> libraries;
|
||||
/**
|
||||
* List of all ID to try to link from #libraries. This is a linked list because iterators must
|
||||
* not be invalidated when adding more items.
|
||||
*/
|
||||
std::list<BlendfileLinkAppendContextItem> items;
|
||||
using items_iterator_t = std::list<BlendfileLinkAppendContextItem>::iterator;
|
||||
/** Linking/appending parameters. Including `bmain`, `scene`, `viewlayer` and `view3d`. */
|
||||
LibraryLink_Params *params = nullptr;
|
||||
|
||||
/**
|
||||
* What is the current stage of the link/append process. Used mainly by the RNA wrappers for the
|
||||
* pre/post handlers currently.
|
||||
*/
|
||||
enum class ProcessStage {
|
||||
/**
|
||||
* The context data is being filled with data (Libraries and IDs) to process. Nothing has been
|
||||
* linked yet.
|
||||
*/
|
||||
Init = 0,
|
||||
/** The context data is being used to linked IDs. */
|
||||
Linking,
|
||||
/**
|
||||
* The context data is being used to append IDs (i.e. make local linked ones, or re-use already
|
||||
* existing local ones).
|
||||
*/
|
||||
Appending,
|
||||
/**
|
||||
* The context data is being used to instantiate (loose) IDs (i.e. ensure that Collections,
|
||||
* Objects and/or ObjectData IDs are added to the current scene).
|
||||
*/
|
||||
Instantiating,
|
||||
/**
|
||||
* All data has been linked or appended. The context state represents the final result of the
|
||||
* process.
|
||||
*/
|
||||
Done,
|
||||
|
||||
/* NOTE: For the time being, liboverride step is not considered here (#BKE_blendfile_override).
|
||||
* Mainly because it is only available through the BPY API currently. */
|
||||
};
|
||||
ProcessStage process_stage;
|
||||
|
||||
/** Allows to easily find an existing items from an ID pointer. */
|
||||
blender::Map<ID *, BlendfileLinkAppendContextItem *> new_id_to_item;
|
||||
|
||||
/** Runtime info used by append code to manage re-use of already appended matching IDs. */
|
||||
MainLibraryWeakReferenceMap *library_weak_reference_mapping = nullptr;
|
||||
|
||||
/** Embedded blendfile and its size, if needed. */
|
||||
const void *blendfile_mem = nullptr;
|
||||
size_t blendfile_memsize = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Allocate and initialize a new context to link/append data-blocks.
|
||||
@ -158,6 +311,18 @@ void BKE_blendfile_link_append_context_item_foreach(
|
||||
BlendfileLinkAppendContextItem *item)> callback_function,
|
||||
eBlendfileLinkAppendForeachItemFlag flag);
|
||||
|
||||
/**
|
||||
* Called once the link/append process has been fully initialized (all of its data has been set).
|
||||
*
|
||||
* NOTE: Currently only used to call the matching handler.
|
||||
*/
|
||||
void BKE_blendfile_link_append_context_init_done(BlendfileLinkAppendContext *lapp_context);
|
||||
|
||||
/**
|
||||
* Perform linking operation on all items added to given `lapp_context`.
|
||||
*/
|
||||
void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *reports);
|
||||
|
||||
/**
|
||||
* Perform append operation, using modern ID usage looper to detect which ID should be kept
|
||||
* linked, made local, duplicated as local, re-used from local etc.
|
||||
@ -166,10 +331,6 @@ void BKE_blendfile_link_append_context_item_foreach(
|
||||
* #BKE_blendfile_link on the same `lapp_context`.
|
||||
*/
|
||||
void BKE_blendfile_append(BlendfileLinkAppendContext *lapp_context, ReportList *reports);
|
||||
/**
|
||||
* Perform linking operation on all items added to given `lapp_context`.
|
||||
*/
|
||||
void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *reports);
|
||||
|
||||
/**
|
||||
* Instantiate loose data in the scene (e.g. add object to the active collection).
|
||||
@ -177,6 +338,13 @@ void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *re
|
||||
void BKE_blendfile_link_append_instantiate_loose(BlendfileLinkAppendContext *lapp_context,
|
||||
ReportList *reports);
|
||||
|
||||
/**
|
||||
* Finalize the link/append process.
|
||||
*
|
||||
* NOTE: Currently only used to call the matching handler..
|
||||
*/
|
||||
void BKE_blendfile_link_append_context_finalize(BlendfileLinkAppendContext *lapp_context);
|
||||
|
||||
/**
|
||||
* Options controlling the behavior of liboverrides creation.
|
||||
*/
|
||||
|
@ -110,6 +110,8 @@ enum eCbEvent {
|
||||
BKE_CB_EVT_EXTENSION_REPOS_UPDATE_POST,
|
||||
BKE_CB_EVT_EXTENSION_REPOS_SYNC,
|
||||
BKE_CB_EVT_EXTENSION_REPOS_FILES_CLEAR,
|
||||
BKE_CB_EVT_BLENDIMPORT_PRE,
|
||||
BKE_CB_EVT_BLENDIMPORT_POST,
|
||||
BKE_CB_EVT_TOT,
|
||||
};
|
||||
|
||||
|
@ -61,8 +61,12 @@ static ID *asset_link_id(Main &global_main,
|
||||
lapp_context, asset_name, id_type, nullptr);
|
||||
BKE_blendfile_link_append_context_item_library_index_enable(lapp_context, lapp_item, 0);
|
||||
|
||||
BKE_blendfile_link_append_context_init_done(lapp_context);
|
||||
|
||||
BKE_blendfile_link(lapp_context, nullptr);
|
||||
|
||||
BKE_blendfile_link_append_context_finalize(lapp_context);
|
||||
|
||||
ID *local_asset = BKE_blendfile_link_append_context_item_newid_get(lapp_context, lapp_item);
|
||||
|
||||
BKE_blendfile_link_append_context_free(lapp_context);
|
||||
|
@ -41,6 +41,8 @@ static void copybuffer_append(BlendfileLinkAppendContext *lapp_context,
|
||||
/* Tag existing IDs in given `bmain_dst` as already existing. */
|
||||
BKE_main_id_tag_all(bmain, ID_TAG_PRE_EXISTING, true);
|
||||
|
||||
BKE_blendfile_link_append_context_init_done(lapp_context);
|
||||
|
||||
BKE_blendfile_link(lapp_context, reports);
|
||||
|
||||
/* Mark all library linked objects to be updated. */
|
||||
@ -53,6 +55,8 @@ static void copybuffer_append(BlendfileLinkAppendContext *lapp_context,
|
||||
/* Instantiate loose data in the scene (e.g. add object to the active collection). */
|
||||
BKE_blendfile_link_append_instantiate_loose(lapp_context, reports);
|
||||
|
||||
BKE_blendfile_link_append_context_finalize(lapp_context);
|
||||
|
||||
/* This must be unset, otherwise these object won't link into other scenes from this blend
|
||||
* file. */
|
||||
BKE_main_id_tag_all(bmain, ID_TAG_PRE_EXISTING, false);
|
||||
|
@ -13,8 +13,6 @@
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#include "CLG_log.h"
|
||||
|
||||
@ -28,11 +26,9 @@
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
|
||||
#include "BLI_bit_vector.hh"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_string_ref.hh"
|
||||
#include "BLI_utildefines.h"
|
||||
@ -40,6 +36,10 @@
|
||||
|
||||
#include "BLT_translation.hh"
|
||||
|
||||
#include "RNA_access.hh"
|
||||
#include "RNA_prototypes.hh"
|
||||
|
||||
#include "BKE_callbacks.hh"
|
||||
#include "BKE_grease_pencil_legacy_convert.hh"
|
||||
#include "BKE_idtype.hh"
|
||||
#include "BKE_key.hh"
|
||||
@ -60,7 +60,6 @@
|
||||
|
||||
#include "BKE_blendfile_link_append.hh"
|
||||
|
||||
#include "BLO_readfile.hh"
|
||||
#include "BLO_writefile.hh"
|
||||
|
||||
static CLG_LogRef LOG = {"bke.blendfile_link_append"};
|
||||
@ -69,69 +68,6 @@ static CLG_LogRef LOG = {"bke.blendfile_link_append"};
|
||||
/** \name Link/append context implementation and public management API.
|
||||
* \{ */
|
||||
|
||||
struct BlendfileLinkAppendContextItem {
|
||||
/** Name of the ID (without the heading two-chars IDcode). */
|
||||
std::string name;
|
||||
/** All libraries (from #BlendfileLinkAppendContext.libraries) to try to load this ID from. */
|
||||
blender::BitVector<> libraries;
|
||||
/** ID type. */
|
||||
short idcode;
|
||||
|
||||
/** Type of action to perform on this item, and general status tag information.
|
||||
* NOTE: Mostly used by append post-linking processing. */
|
||||
char action;
|
||||
char tag;
|
||||
|
||||
/** Newly linked ID (nullptr until it has been successfully linked). */
|
||||
ID *new_id;
|
||||
/** Library ID from which the #new_id has been linked (nullptr until it has been successfully
|
||||
* linked). */
|
||||
Library *source_library;
|
||||
/** Liboverride of the linked ID (nullptr until it has been successfully created or an existing
|
||||
* one has been found). */
|
||||
ID *liboverride_id;
|
||||
/**
|
||||
* Whether the item has a matching local ID that was already appended from the same source
|
||||
* before, and has not been modified. In 'Append & Reuse' case, this local ID _may_ be reused
|
||||
* instead of making linked data local again.
|
||||
*/
|
||||
ID *reusable_local_id;
|
||||
|
||||
/** Opaque user data pointer. */
|
||||
void *userdata;
|
||||
};
|
||||
|
||||
/* A blendfile library entry in the `libraries` list of #BlendfileLinkAppendContext. */
|
||||
struct BlendfileLinkAppendContextLibrary {
|
||||
std::string path; /* Absolute .blend file path. */
|
||||
BlendHandle *blo_handle; /* Blend file handle, if any. */
|
||||
bool blo_handle_is_owned; /* Whether the blend file handle is owned, or borrowed. */
|
||||
/* The blendfile report associated with the `blo_handle`, if owned. */
|
||||
BlendFileReadReport bf_reports;
|
||||
};
|
||||
|
||||
struct BlendfileLinkAppendContext {
|
||||
/** List of library paths to search IDs in. */
|
||||
blender::Vector<BlendfileLinkAppendContextLibrary> libraries;
|
||||
/**
|
||||
* List of all ID to try to link from #libraries. This is a linked list because iterators must
|
||||
* not be invalidated when adding more items.
|
||||
*/
|
||||
std::list<BlendfileLinkAppendContextItem> items;
|
||||
/** Linking/appending parameters. Including `bmain`, `scene`, `viewlayer` and `view3d`. */
|
||||
LibraryLink_Params *params = nullptr;
|
||||
|
||||
/** Allows to easily find an existing items from an ID pointer. */
|
||||
blender::Map<ID *, BlendfileLinkAppendContextItem *> new_id_to_item;
|
||||
|
||||
/** Runtime info used by append code to manage re-use of already appended matching IDs. */
|
||||
MainLibraryWeakReferenceMap *library_weak_reference_mapping = nullptr;
|
||||
|
||||
/** Embedded blendfile and its size, if needed. */
|
||||
const void *blendfile_mem = nullptr;
|
||||
size_t blendfile_memsize = 0;
|
||||
};
|
||||
|
||||
struct BlendfileLinkAppendContextCallBack {
|
||||
BlendfileLinkAppendContext *lapp_context;
|
||||
BlendfileLinkAppendContextItem *item;
|
||||
@ -155,36 +91,6 @@ struct BlendfileLinkAppendContextCallBack {
|
||||
bool is_liboverride_dependency_only;
|
||||
};
|
||||
|
||||
/** Actions to apply to an item (i.e. linked ID). */
|
||||
enum {
|
||||
LINK_APPEND_ACT_UNSET = 0,
|
||||
LINK_APPEND_ACT_KEEP_LINKED,
|
||||
LINK_APPEND_ACT_REUSE_LOCAL,
|
||||
LINK_APPEND_ACT_MAKE_LOCAL,
|
||||
LINK_APPEND_ACT_COPY_LOCAL,
|
||||
};
|
||||
|
||||
/** Various status info about an item (i.e. linked ID). */
|
||||
enum {
|
||||
/** An indirectly linked ID. */
|
||||
LINK_APPEND_TAG_INDIRECT = 1 << 0,
|
||||
/**
|
||||
* An ID also used as liboverride dependency (either directly, as a liboverride reference, or
|
||||
* indirectly, as data used by a liboverride reference). It should never be directly made local.
|
||||
*
|
||||
* Mutually exclusive with #LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY_ONLY.
|
||||
*/
|
||||
LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY = 1 << 1,
|
||||
/**
|
||||
* An ID only used as liboverride dependency (either directly or indirectly, see
|
||||
* #LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY for precisions). It should not be considered during
|
||||
* the 'make local' process, and remain purely linked data.
|
||||
*
|
||||
* Mutually exclusive with #LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY.
|
||||
*/
|
||||
LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY_ONLY = 1 << 2,
|
||||
};
|
||||
|
||||
static BlendHandle *link_append_context_library_blohandle_ensure(
|
||||
BlendfileLinkAppendContext &lapp_context,
|
||||
BlendfileLinkAppendContextLibrary &lib_context,
|
||||
@ -225,6 +131,7 @@ BlendfileLinkAppendContext *BKE_blendfile_link_append_context_new(LibraryLink_Pa
|
||||
{
|
||||
BlendfileLinkAppendContext *lapp_context = MEM_new<BlendfileLinkAppendContext>(__func__);
|
||||
lapp_context->params = params;
|
||||
lapp_context->process_stage = BlendfileLinkAppendContext::ProcessStage::Init;
|
||||
return lapp_context;
|
||||
}
|
||||
|
||||
@ -273,6 +180,7 @@ void BKE_blendfile_link_append_context_library_add(BlendfileLinkAppendContext *l
|
||||
BlendHandle *blo_handle)
|
||||
{
|
||||
BLI_assert(lapp_context->items.empty());
|
||||
BLI_assert(lapp_context->process_stage == BlendfileLinkAppendContext::ProcessStage::Init);
|
||||
|
||||
BlendfileLinkAppendContextLibrary lib_context = {};
|
||||
|
||||
@ -293,6 +201,8 @@ BlendfileLinkAppendContextItem *BKE_blendfile_link_append_context_item_add(
|
||||
{
|
||||
BlendfileLinkAppendContextItem item = {};
|
||||
|
||||
item.lapp_context = lapp_context;
|
||||
|
||||
item.name = idname;
|
||||
item.idcode = idcode;
|
||||
item.libraries = blender::BitVector<>(lapp_context->libraries.size(), false);
|
||||
@ -312,6 +222,8 @@ int BKE_blendfile_link_append_context_item_idtypes_from_library_add(
|
||||
const uint64_t id_types_filter,
|
||||
const int library_index)
|
||||
{
|
||||
BLI_assert(lapp_context->process_stage == BlendfileLinkAppendContext::ProcessStage::Init);
|
||||
|
||||
int id_num = 0;
|
||||
int id_code_iter = 0;
|
||||
short id_code;
|
||||
@ -357,10 +269,12 @@ int BKE_blendfile_link_append_context_item_idtypes_from_library_add(
|
||||
}
|
||||
|
||||
void BKE_blendfile_link_append_context_item_library_index_enable(
|
||||
BlendfileLinkAppendContext * /*lapp_context*/,
|
||||
BlendfileLinkAppendContext *lapp_context,
|
||||
BlendfileLinkAppendContextItem *item,
|
||||
const int library_index)
|
||||
{
|
||||
BLI_assert(lapp_context->process_stage == BlendfileLinkAppendContext::ProcessStage::Init);
|
||||
UNUSED_VARS_NDEBUG(lapp_context);
|
||||
item->libraries[library_index].set();
|
||||
}
|
||||
|
||||
@ -375,9 +289,11 @@ void *BKE_blendfile_link_append_context_item_userdata_get(
|
||||
return item->userdata;
|
||||
}
|
||||
|
||||
ID *BKE_blendfile_link_append_context_item_newid_get(BlendfileLinkAppendContext * /*lapp_context*/,
|
||||
ID *BKE_blendfile_link_append_context_item_newid_get(BlendfileLinkAppendContext *lapp_context,
|
||||
BlendfileLinkAppendContextItem *item)
|
||||
{
|
||||
BLI_assert(lapp_context->process_stage != BlendfileLinkAppendContext::ProcessStage::Init);
|
||||
UNUSED_VARS_NDEBUG(lapp_context);
|
||||
return item->new_id;
|
||||
}
|
||||
|
||||
@ -385,6 +301,7 @@ void BKE_blendfile_link_append_context_item_newid_set(BlendfileLinkAppendContext
|
||||
BlendfileLinkAppendContextItem *item,
|
||||
ID *new_id)
|
||||
{
|
||||
BLI_assert(lapp_context->process_stage != BlendfileLinkAppendContext::ProcessStage::Init);
|
||||
BLI_assert(item->new_id);
|
||||
BLI_assert(!item->liboverride_id);
|
||||
BLI_assert(new_id->lib == item->new_id->lib);
|
||||
@ -396,8 +313,10 @@ void BKE_blendfile_link_append_context_item_newid_set(BlendfileLinkAppendContext
|
||||
}
|
||||
|
||||
ID *BKE_blendfile_link_append_context_item_liboverrideid_get(
|
||||
BlendfileLinkAppendContext * /*lapp_context*/, BlendfileLinkAppendContextItem *item)
|
||||
BlendfileLinkAppendContext *lapp_context, BlendfileLinkAppendContextItem *item)
|
||||
{
|
||||
BLI_assert(lapp_context->process_stage != BlendfileLinkAppendContext::ProcessStage::Init);
|
||||
UNUSED_VARS_NDEBUG(lapp_context);
|
||||
return item->liboverride_id;
|
||||
}
|
||||
|
||||
@ -431,6 +350,28 @@ void BKE_blendfile_link_append_context_item_foreach(
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_blendfile_link_append_context_init_done(BlendfileLinkAppendContext *lapp_context)
|
||||
{
|
||||
BLI_assert(lapp_context->process_stage == BlendfileLinkAppendContext::ProcessStage::Init);
|
||||
|
||||
PointerRNA ctx_ptr = RNA_pointer_create(nullptr, &RNA_BlendImportContext, lapp_context);
|
||||
PointerRNA *pointers[1] = {&ctx_ptr};
|
||||
BKE_callback_exec(lapp_context->params->bmain, pointers, 1, BKE_CB_EVT_BLENDIMPORT_PRE);
|
||||
}
|
||||
|
||||
void BKE_blendfile_link_append_context_finalize(BlendfileLinkAppendContext *lapp_context)
|
||||
{
|
||||
BLI_assert(ELEM(lapp_context->process_stage,
|
||||
BlendfileLinkAppendContext::ProcessStage::Linking,
|
||||
BlendfileLinkAppendContext::ProcessStage::Appending,
|
||||
BlendfileLinkAppendContext::ProcessStage::Instantiating));
|
||||
lapp_context->process_stage = BlendfileLinkAppendContext::ProcessStage::Done;
|
||||
|
||||
PointerRNA ctx_ptr = RNA_pointer_create(nullptr, &RNA_BlendImportContext, lapp_context);
|
||||
PointerRNA *pointers[1] = {&ctx_ptr};
|
||||
BKE_callback_exec(lapp_context->params->bmain, pointers, 1, BKE_CB_EVT_BLENDIMPORT_POST);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
@ -1334,6 +1275,9 @@ static void blendfile_append_define_actions(BlendfileLinkAppendContext &lapp_con
|
||||
|
||||
void BKE_blendfile_append(BlendfileLinkAppendContext *lapp_context, ReportList *reports)
|
||||
{
|
||||
BLI_assert(lapp_context->process_stage == BlendfileLinkAppendContext::ProcessStage::Linking);
|
||||
lapp_context->process_stage = BlendfileLinkAppendContext::ProcessStage::Appending;
|
||||
|
||||
if (lapp_context->items.empty()) {
|
||||
/* Nothing to append. */
|
||||
return;
|
||||
@ -1537,6 +1481,11 @@ static int foreach_libblock_link_finalize_cb(LibraryIDLinkCallbackData *cb_data)
|
||||
void BKE_blendfile_link_append_instantiate_loose(BlendfileLinkAppendContext *lapp_context,
|
||||
ReportList *reports)
|
||||
{
|
||||
BLI_assert(ELEM(lapp_context->process_stage,
|
||||
BlendfileLinkAppendContext::ProcessStage::Linking,
|
||||
BlendfileLinkAppendContext::ProcessStage::Appending));
|
||||
lapp_context->process_stage = BlendfileLinkAppendContext::ProcessStage::Instantiating;
|
||||
|
||||
if (!lapp_context->params->context.scene) {
|
||||
return;
|
||||
}
|
||||
@ -1574,6 +1523,9 @@ void BKE_blendfile_link_append_instantiate_loose(BlendfileLinkAppendContext *lap
|
||||
|
||||
void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *reports)
|
||||
{
|
||||
BLI_assert(lapp_context->process_stage == BlendfileLinkAppendContext::ProcessStage::Init);
|
||||
lapp_context->process_stage = BlendfileLinkAppendContext::ProcessStage::Linking;
|
||||
|
||||
if (lapp_context->items.empty()) {
|
||||
/* Nothing to be linked. */
|
||||
return;
|
||||
@ -1869,6 +1821,8 @@ void BKE_blendfile_library_relocate(BlendfileLinkAppendContext *lapp_context,
|
||||
|
||||
BKE_main_id_tag_all(bmain, ID_TAG_PRE_EXISTING, true);
|
||||
|
||||
BKE_blendfile_link_append_context_init_done(lapp_context);
|
||||
|
||||
/* We do not want any instantiation here! */
|
||||
BKE_blendfile_link(lapp_context, reports);
|
||||
|
||||
|
@ -55,6 +55,7 @@ set(DEFSRC
|
||||
rna_light.cc
|
||||
rna_lightprobe.cc
|
||||
rna_linestyle.cc
|
||||
rna_blendfile_import.cc
|
||||
rna_main.cc
|
||||
rna_mask.cc
|
||||
rna_material.cc
|
||||
|
@ -4827,6 +4827,7 @@ static RNAProcessItem PROCESS_ITEMS[] = {
|
||||
{"rna_lattice.cc", "rna_lattice_api.cc", RNA_def_lattice},
|
||||
{"rna_layer.cc", nullptr, RNA_def_view_layer},
|
||||
{"rna_linestyle.cc", nullptr, RNA_def_linestyle},
|
||||
{"rna_blendfile_import.cc", nullptr, RNA_def_blendfile_import},
|
||||
{"rna_main.cc", "rna_main_api.cc", RNA_def_main},
|
||||
{"rna_fluid.cc", nullptr, RNA_def_fluid},
|
||||
{"rna_material.cc", "rna_material_api.cc", RNA_def_material},
|
||||
|
556
source/blender/makesrna/intern/rna_blendfile_import.cc
Normal file
@ -0,0 +1,556 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup RNA
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include "BLO_readfile.hh"
|
||||
|
||||
#include "DNA_space_types.h"
|
||||
|
||||
#include "BKE_blendfile_link_append.hh"
|
||||
|
||||
#include "RNA_access.hh"
|
||||
#include "RNA_define.hh"
|
||||
#include "RNA_enum_types.hh"
|
||||
|
||||
#include "rna_internal.hh"
|
||||
|
||||
#ifdef RNA_RUNTIME
|
||||
|
||||
# include "BLI_bit_span.hh"
|
||||
# include "BLI_string_utils.hh"
|
||||
|
||||
void rna_BlendImportContextLibrary_filepath_get(PointerRNA *ptr, char *value)
|
||||
{
|
||||
BlendfileLinkAppendContextLibrary *ctx_lib = static_cast<BlendfileLinkAppendContextLibrary *>(
|
||||
ptr->data);
|
||||
const size_t str_len = ctx_lib->path.length();
|
||||
BLI_strncpy(value, ctx_lib->path.c_str(), str_len + 1);
|
||||
}
|
||||
|
||||
int rna_BlendImportContextLibrary_filepath_len(PointerRNA *ptr)
|
||||
{
|
||||
BlendfileLinkAppendContextLibrary *ctx_lib = static_cast<BlendfileLinkAppendContextLibrary *>(
|
||||
ptr->data);
|
||||
return int(ctx_lib->path.length());
|
||||
}
|
||||
|
||||
void rna_BlendImportContextItem_name_get(PointerRNA *ptr, char *value)
|
||||
{
|
||||
BlendfileLinkAppendContextItem *ctx_item = static_cast<BlendfileLinkAppendContextItem *>(
|
||||
ptr->data);
|
||||
const size_t str_len = ctx_item->name.length();
|
||||
BLI_strncpy(value, ctx_item->name.c_str(), str_len + 1);
|
||||
}
|
||||
|
||||
int rna_BlendImportContextItem_name_len(PointerRNA *ptr)
|
||||
{
|
||||
BlendfileLinkAppendContextItem *ctx_item = static_cast<BlendfileLinkAppendContextItem *>(
|
||||
ptr->data);
|
||||
return int(ctx_item->name.length());
|
||||
}
|
||||
|
||||
int rna_BlendImportContextItem_id_type_get(PointerRNA *ptr)
|
||||
{
|
||||
BlendfileLinkAppendContextItem *ctx_item = static_cast<BlendfileLinkAppendContextItem *>(
|
||||
ptr->data);
|
||||
return int(ctx_item->idcode);
|
||||
}
|
||||
|
||||
struct RNABlendImportContextItemLibrariesIterator {
|
||||
BlendfileLinkAppendContextItem *ctx_item;
|
||||
blender::bits::BitIterator iter;
|
||||
int iter_index;
|
||||
};
|
||||
|
||||
void rna_BlendImportContextItem_libraries_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
|
||||
{
|
||||
BlendfileLinkAppendContextItem *ctx_item = static_cast<BlendfileLinkAppendContextItem *>(
|
||||
ptr->data);
|
||||
|
||||
const blender::BitVector<> &libraries = ctx_item->libraries;
|
||||
RNABlendImportContextItemLibrariesIterator *libs_iter =
|
||||
MEM_new<RNABlendImportContextItemLibrariesIterator>(
|
||||
__func__, RNABlendImportContextItemLibrariesIterator{ctx_item, libraries.begin(), 0});
|
||||
iter->internal.custom = libs_iter;
|
||||
while (!(*libs_iter->iter) && libs_iter->iter != libs_iter->ctx_item->libraries.end()) {
|
||||
libs_iter->iter.operator++();
|
||||
libs_iter->iter_index++;
|
||||
}
|
||||
iter->valid = (libs_iter->iter != libs_iter->ctx_item->libraries.end());
|
||||
}
|
||||
|
||||
void rna_BlendImportContextItem_libraries_next(CollectionPropertyIterator *iter)
|
||||
{
|
||||
RNABlendImportContextItemLibrariesIterator *libs_iter =
|
||||
static_cast<RNABlendImportContextItemLibrariesIterator *>(iter->internal.custom);
|
||||
do {
|
||||
libs_iter->iter.operator++();
|
||||
libs_iter->iter_index++;
|
||||
} while (!(*libs_iter->iter) && libs_iter->iter != libs_iter->ctx_item->libraries.end());
|
||||
iter->valid = (libs_iter->iter != libs_iter->ctx_item->libraries.end());
|
||||
}
|
||||
|
||||
void rna_BlendImportContextItem_libraries_end(CollectionPropertyIterator *iter)
|
||||
{
|
||||
RNABlendImportContextItemLibrariesIterator *libs_iter =
|
||||
static_cast<RNABlendImportContextItemLibrariesIterator *>(iter->internal.custom);
|
||||
|
||||
iter->valid = false;
|
||||
iter->internal.custom = nullptr;
|
||||
MEM_delete(libs_iter);
|
||||
}
|
||||
|
||||
PointerRNA rna_BlendImportContextItem_libraries_get(CollectionPropertyIterator *iter)
|
||||
{
|
||||
RNABlendImportContextItemLibrariesIterator *libs_iter =
|
||||
static_cast<RNABlendImportContextItemLibrariesIterator *>(iter->internal.custom);
|
||||
|
||||
BlendfileLinkAppendContextLibrary &ctx_lib =
|
||||
libs_iter->ctx_item->lapp_context->libraries[libs_iter->iter_index];
|
||||
return rna_pointer_inherit_refine(&iter->parent, &RNA_BlendImportContextLibrary, &ctx_lib);
|
||||
}
|
||||
|
||||
int rna_BlendImportContextItem_libraries_len(PointerRNA *ptr)
|
||||
{
|
||||
BlendfileLinkAppendContextItem *ctx_item = static_cast<BlendfileLinkAppendContextItem *>(
|
||||
ptr->data);
|
||||
|
||||
/* Count amount of enabled libraries in the item's bitmask. */
|
||||
int count = 0;
|
||||
for (const blender::BitRef &bit : ctx_item->libraries) {
|
||||
if (bit) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int rna_BlendImportContextItem_append_action_get(PointerRNA *ptr)
|
||||
{
|
||||
BlendfileLinkAppendContextItem *ctx_item = static_cast<BlendfileLinkAppendContextItem *>(
|
||||
ptr->data);
|
||||
return int(ctx_item->action);
|
||||
}
|
||||
|
||||
int rna_BlendImportContextItem_import_info_get(PointerRNA *ptr)
|
||||
{
|
||||
BlendfileLinkAppendContextItem *ctx_item = static_cast<BlendfileLinkAppendContextItem *>(
|
||||
ptr->data);
|
||||
return int(ctx_item->tag);
|
||||
}
|
||||
|
||||
PointerRNA rna_BlendImportContextItem_id_get(PointerRNA *ptr)
|
||||
{
|
||||
BlendfileLinkAppendContextItem *ctx_item = static_cast<BlendfileLinkAppendContextItem *>(
|
||||
ptr->data);
|
||||
return rna_pointer_inherit_refine(&PointerRNA_NULL, &RNA_ID, ctx_item->new_id);
|
||||
}
|
||||
|
||||
PointerRNA rna_BlendImportContextItem_source_library_get(PointerRNA *ptr)
|
||||
{
|
||||
BlendfileLinkAppendContextItem *ctx_item = static_cast<BlendfileLinkAppendContextItem *>(
|
||||
ptr->data);
|
||||
return rna_pointer_inherit_refine(&PointerRNA_NULL, &RNA_Library, ctx_item->source_library);
|
||||
}
|
||||
|
||||
PointerRNA rna_BlendImportContextItem_library_override_id_get(PointerRNA *ptr)
|
||||
{
|
||||
BlendfileLinkAppendContextItem *ctx_item = static_cast<BlendfileLinkAppendContextItem *>(
|
||||
ptr->data);
|
||||
return rna_pointer_inherit_refine(&PointerRNA_NULL, &RNA_ID, ctx_item->liboverride_id);
|
||||
}
|
||||
|
||||
PointerRNA rna_BlendImportContextItem_reusable_local_id_get(PointerRNA *ptr)
|
||||
{
|
||||
BlendfileLinkAppendContextItem *ctx_item = static_cast<BlendfileLinkAppendContextItem *>(
|
||||
ptr->data);
|
||||
return rna_pointer_inherit_refine(&PointerRNA_NULL, &RNA_ID, ctx_item->reusable_local_id);
|
||||
}
|
||||
|
||||
struct RNABlendImportContextItemsIterator {
|
||||
BlendfileLinkAppendContext *ctx;
|
||||
BlendfileLinkAppendContext::items_iterator_t iter;
|
||||
};
|
||||
|
||||
void rna_BlendImportContext_import_items_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
|
||||
{
|
||||
BlendfileLinkAppendContext *ctx = static_cast<BlendfileLinkAppendContext *>(ptr->data);
|
||||
|
||||
RNABlendImportContextItemsIterator *items_iter = MEM_new<RNABlendImportContextItemsIterator>(
|
||||
__func__, RNABlendImportContextItemsIterator{ctx, ctx->items.begin()});
|
||||
iter->internal.custom = items_iter;
|
||||
iter->valid = (items_iter->iter != items_iter->ctx->items.end());
|
||||
}
|
||||
|
||||
void rna_BlendImportContext_import_items_next(CollectionPropertyIterator *iter)
|
||||
{
|
||||
RNABlendImportContextItemsIterator *items_iter =
|
||||
static_cast<RNABlendImportContextItemsIterator *>(iter->internal.custom);
|
||||
items_iter->iter++;
|
||||
iter->valid = (items_iter->iter != items_iter->ctx->items.end());
|
||||
}
|
||||
|
||||
void rna_BlendImportContext_import_items_end(CollectionPropertyIterator *iter)
|
||||
{
|
||||
RNABlendImportContextItemsIterator *items_iter =
|
||||
static_cast<RNABlendImportContextItemsIterator *>(iter->internal.custom);
|
||||
|
||||
iter->valid = false;
|
||||
iter->internal.custom = nullptr;
|
||||
MEM_delete(items_iter);
|
||||
}
|
||||
|
||||
PointerRNA rna_BlendImportContext_import_items_get(CollectionPropertyIterator *iter)
|
||||
{
|
||||
RNABlendImportContextItemsIterator *items_iter =
|
||||
static_cast<RNABlendImportContextItemsIterator *>(iter->internal.custom);
|
||||
|
||||
BlendfileLinkAppendContextItem &ctx_item = *items_iter->iter;
|
||||
return rna_pointer_inherit_refine(&iter->parent, &RNA_BlendImportContextItem, &ctx_item);
|
||||
}
|
||||
|
||||
int rna_BlendImportContext_import_items_len(PointerRNA *ptr)
|
||||
{
|
||||
BlendfileLinkAppendContext *ctx = static_cast<BlendfileLinkAppendContext *>(ptr->data);
|
||||
return int(ctx->items.size());
|
||||
}
|
||||
|
||||
int rna_BlendImportContext_options_get(PointerRNA *ptr)
|
||||
{
|
||||
BlendfileLinkAppendContext *ctx = static_cast<BlendfileLinkAppendContext *>(ptr->data);
|
||||
return int(ctx->params->flag);
|
||||
}
|
||||
|
||||
int rna_BlendImportContext_process_stage_get(PointerRNA *ptr)
|
||||
{
|
||||
BlendfileLinkAppendContext *ctx = static_cast<BlendfileLinkAppendContext *>(ptr->data);
|
||||
return int(ctx->process_stage);
|
||||
}
|
||||
|
||||
#else /* RNA_RUNTIME */
|
||||
|
||||
static void rna_def_blendfile_import_library(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "BlendImportContextLibrary", nullptr);
|
||||
RNA_def_struct_ui_text(
|
||||
srna,
|
||||
"Blendfile Import Context Library",
|
||||
"Library (blendfile) reference in a BlendImportContext data. Currently only "
|
||||
"exposed as read-only data for the pre/post blendimport handlers");
|
||||
|
||||
RNA_define_verify_sdna(false); /* not in sdna */
|
||||
|
||||
prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_string_funcs(prop,
|
||||
"rna_BlendImportContextLibrary_filepath_get",
|
||||
"rna_BlendImportContextLibrary_filepath_len",
|
||||
nullptr);
|
||||
|
||||
RNA_define_verify_sdna(true); /* not in sdna */
|
||||
}
|
||||
|
||||
static void RNA_def_blendfile_import_libraries(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
RNA_def_property_srna(cprop, "BlendImportContextLibraries");
|
||||
srna = RNA_def_struct(brna, "BlendImportContextLibraries", nullptr);
|
||||
RNA_def_struct_ui_text(srna,
|
||||
"Blendfile Import Context Libraries",
|
||||
"Collection of source libraries, i.e. blendfile paths");
|
||||
}
|
||||
|
||||
static void rna_def_blendfile_import_item(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "BlendImportContextItem", nullptr);
|
||||
RNA_def_struct_ui_text(
|
||||
srna,
|
||||
"Blendfile Import Context Item",
|
||||
"An item (representing a data-block) in a BlendImportContext data. Currently only "
|
||||
"exposed as read-only data for the pre/post linking handlers");
|
||||
|
||||
RNA_define_verify_sdna(false); /* not in sdna */
|
||||
|
||||
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "ID Name", "ID name of the item");
|
||||
RNA_def_property_string_funcs(
|
||||
prop, "rna_BlendImportContextItem_name_get", "rna_BlendImportContextItem_name_len", nullptr);
|
||||
|
||||
prop = RNA_def_property(srna, "id_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, rna_enum_id_type_items);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "ID Type", "ID type of the item");
|
||||
RNA_def_property_enum_funcs(prop, "rna_BlendImportContextItem_id_type_get", nullptr, nullptr);
|
||||
|
||||
prop = RNA_def_property(srna, "source_libraries", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "BlendImportContextLibrary");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Source Libraries",
|
||||
"List of libraries to search and import that ID from. The ID will be "
|
||||
"imported from the first file in that list that contains it");
|
||||
RNA_def_property_collection_funcs(prop,
|
||||
"rna_BlendImportContextItem_libraries_begin",
|
||||
"rna_BlendImportContextItem_libraries_next",
|
||||
"rna_BlendImportContextItem_libraries_end",
|
||||
"rna_BlendImportContextItem_libraries_get",
|
||||
"rna_BlendImportContextItem_libraries_len",
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr);
|
||||
RNA_def_blendfile_import_libraries(brna, prop);
|
||||
|
||||
static const EnumPropertyItem blend_import_item_append_action_items[] = {
|
||||
{LINK_APPEND_ACT_UNSET, "UNSET", 0, "", "Not yet defined"},
|
||||
{LINK_APPEND_ACT_KEEP_LINKED, "KEEP_LINKED", 0, "", "ID has been kept linked"},
|
||||
{LINK_APPEND_ACT_REUSE_LOCAL,
|
||||
"REUSE_LOCAL",
|
||||
0,
|
||||
"",
|
||||
"An existing matching local ID has been re-used"},
|
||||
{LINK_APPEND_ACT_MAKE_LOCAL, "MAKE_LOCAL", 0, "", "The newly linked ID has been made local"},
|
||||
{LINK_APPEND_ACT_COPY_LOCAL,
|
||||
"COPY_LOCAL",
|
||||
0,
|
||||
"",
|
||||
"The linked ID had other unrelated usages, so it has been duplicated into a local copy"},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
prop = RNA_def_property(srna, "append_action", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, blend_import_item_append_action_items);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Append Action",
|
||||
"How this item has been handled by the append operation. Only set if "
|
||||
"the data has been appended");
|
||||
RNA_def_property_enum_funcs(
|
||||
prop, "rna_BlendImportContextItem_append_action_get", nullptr, nullptr);
|
||||
|
||||
static const EnumPropertyItem blend_import_item_import_info_items[] = {
|
||||
{LINK_APPEND_TAG_INDIRECT,
|
||||
"INDIRECT_USAGE",
|
||||
0,
|
||||
"",
|
||||
"That item was added for an indirectly imported ID, as a dependency of another data-block"},
|
||||
{LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY,
|
||||
"LIBOVERRIDE_DEPENDENCY",
|
||||
0,
|
||||
"",
|
||||
"That item represents an ID also used as liboverride dependency (either directly, as a "
|
||||
"liboverride reference, or indirectly, as data used by a liboverride reference). It should "
|
||||
"never be directly made local. Mutually exclusive with `LIBOVERRIDE_DEPENDENCY_ONLY`"},
|
||||
{LINK_APPEND_TAG_LIBOVERRIDE_DEPENDENCY_ONLY,
|
||||
"LIBOVERRIDE_DEPENDENCY_ONLY",
|
||||
0,
|
||||
"",
|
||||
"That item represents an ID only used as liboverride dependency (either directly or "
|
||||
"indirectly, see `LIBOVERRIDE_DEPENDENCY` for precisions). It should not be considered "
|
||||
"during the 'make local' (append) process, and remain purely linked data. Mutually "
|
||||
"exclusive with `LIBOVERRIDE_DEPENDENCY`"},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
prop = RNA_def_property(srna, "import_info", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, blend_import_item_import_info_items);
|
||||
RNA_def_property_flag(prop, PROP_ENUM_FLAG);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Import Info", "Various status info about an item after it has been imported");
|
||||
RNA_def_property_enum_funcs(
|
||||
prop, "rna_BlendImportContextItem_import_info_get", nullptr, nullptr);
|
||||
|
||||
prop = RNA_def_property(srna, "id", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "ID");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Imported ID",
|
||||
"The imported ID. None until it has been linked or appended. May be "
|
||||
"the same as `reusable_local_id` when appended");
|
||||
RNA_def_property_pointer_funcs(
|
||||
prop, "rna_BlendImportContextItem_id_get", nullptr, nullptr, nullptr);
|
||||
|
||||
prop = RNA_def_property(srna, "source_library", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "Library");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Source Library",
|
||||
"Library ID representing the blendfile from which the ID was imported. "
|
||||
"None until the ID has been linked or appended");
|
||||
RNA_def_property_pointer_funcs(
|
||||
prop, "rna_BlendImportContextItem_source_library_get", nullptr, nullptr, nullptr);
|
||||
|
||||
prop = RNA_def_property(srna, "library_override_id", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "ID");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Library Overridden ID",
|
||||
"The library override of the linked ID. None until it has been created");
|
||||
RNA_def_property_pointer_funcs(
|
||||
prop, "rna_BlendImportContextItem_library_override_id_get", nullptr, nullptr, nullptr);
|
||||
|
||||
prop = RNA_def_property(srna, "reusable_local_id", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "ID");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Reusable Local ID",
|
||||
"The already existing local ID that may be reused in append & reuse "
|
||||
"case. None until it has been found");
|
||||
RNA_def_property_pointer_funcs(
|
||||
prop, "rna_BlendImportContextItem_reusable_local_id_get", nullptr, nullptr, nullptr);
|
||||
|
||||
RNA_define_verify_sdna(true); /* not in sdna */
|
||||
}
|
||||
|
||||
static void rna_def_blendfile_import_items(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
||||
RNA_def_property_srna(cprop, "BlendImportContextItems");
|
||||
srna = RNA_def_struct(brna, "BlendImportContextItems", nullptr);
|
||||
RNA_def_struct_ui_text(
|
||||
|
||||
srna, "Blendfile Import Context Items", "Collection of blendfile import context items");
|
||||
|
||||
/* TODO: Add/Remove items _before_ doing link/append (i.e. for 'pre' handlers). */
|
||||
}
|
||||
|
||||
static void rna_def_blendfile_import_context(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "BlendImportContext", nullptr);
|
||||
RNA_def_struct_ui_text(
|
||||
srna,
|
||||
"Blendfile Import Context",
|
||||
"Contextual data for a blendfile library/linked-data related operation. Currently "
|
||||
"only exposed as read-only data for the pre/post blendimport handlers");
|
||||
|
||||
RNA_define_verify_sdna(false); /* not in sdna */
|
||||
|
||||
Campbell Barton
commented
- `XXX` is more for warnings, this isn't something to resolve or fix, so it could be `NOTE: cannot use ...`.
- `elements` seems OK but also a bit odd,
Possible alternatives:
- `import_items`
- `data_items`
- `link_items`
- `datablock_items`
Bastien Montagne
commented
I'm fine with either I'm fine with either `elements` or `import_items`, both are somewhat weird but withing acceptable limits imho. No strong preference so will let you choose the one you prefer. ;)
Campbell Barton
commented
Slight preference for Slight preference for `import_items` matches (`keymap_items`, `enum_items` ... `filter_items_by_name` etc).
|
||||
/* NOTE: Cannot use just `items` here as this is a reserved Python dict method name. */
|
||||
prop = RNA_def_property(srna, "import_items", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "BlendImportContextItem");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_collection_funcs(prop,
|
||||
"rna_BlendImportContext_import_items_begin",
|
||||
"rna_BlendImportContext_import_items_next",
|
||||
"rna_BlendImportContext_import_items_end",
|
||||
"rna_BlendImportContext_import_items_get",
|
||||
"rna_BlendImportContext_import_items_len",
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr);
|
||||
rna_def_blendfile_import_items(brna, prop);
|
||||
|
||||
static const EnumPropertyItem blend_import_options_items[] = {
|
||||
{FILE_LINK, "LINK", 0, "", "Only link data, instead of appending it"},
|
||||
{FILE_RELPATH,
|
||||
"MAKE_PATHS_RELATIVE",
|
||||
0,
|
||||
"",
|
||||
"Make paths of used library blendfiles relative to current blendfile"},
|
||||
{BLO_LIBLINK_USE_PLACEHOLDERS,
|
||||
"USE_PLACEHOLDERS",
|
||||
0,
|
||||
"",
|
||||
"Generate a placeholder (empty ID) if not found in any library files"},
|
||||
{BLO_LIBLINK_FORCE_INDIRECT,
|
||||
"FORCE_INDIRECT",
|
||||
0,
|
||||
"",
|
||||
"Force loaded ID to be tagged as indirectly linked (used in reload context only)"},
|
||||
{BLO_LIBLINK_APPEND_SET_FAKEUSER,
|
||||
"APPEND_SET_FAKEUSER",
|
||||
0,
|
||||
"",
|
||||
"Set fake user on appended IDs"},
|
||||
{BLO_LIBLINK_APPEND_RECURSIVE,
|
||||
"APPEND_RECURSIVE",
|
||||
0,
|
||||
"",
|
||||
"Append (make local) also indirect dependencies of appended IDs coming from other "
|
||||
"libraries. NOTE: All IDs (including indirectly linked ones) coming from the same initial "
|
||||
"library are always made local"},
|
||||
{BLO_LIBLINK_APPEND_LOCAL_ID_REUSE,
|
||||
"APPEND_LOCAL_ID_REUSE",
|
||||
0,
|
||||
"",
|
||||
"Try to re-use previously appended matching IDs when appending them again, instead of "
|
||||
"creating local duplicates"},
|
||||
{BLO_LIBLINK_APPEND_ASSET_DATA_CLEAR,
|
||||
"APPEND_ASSET_DATA_CLEAR",
|
||||
0,
|
||||
"",
|
||||
"Clear the asset data on append (it is always kept for linked data)"},
|
||||
{FILE_AUTOSELECT, "SELECT_OBJECTS", 0, "", "Automatically select imported objects"},
|
||||
{FILE_ACTIVE_COLLECTION,
|
||||
"USE_ACTIVE_COLLECTION",
|
||||
0,
|
||||
"",
|
||||
"Use the active Collection of the current View Layer to instantiate imported "
|
||||
"collections and objects"},
|
||||
{BLO_LIBLINK_OBDATA_INSTANCE,
|
||||
"OBDATA_INSTANCE",
|
||||
0,
|
||||
"",
|
||||
"Instantiate object data IDs (i.e. create objects for them if needed)"},
|
||||
{BLO_LIBLINK_COLLECTION_INSTANCE,
|
||||
"COLLECTION_INSTANCE",
|
||||
0,
|
||||
"",
|
||||
"Instantiate collections as empties, instead of linking them into the current view layer"},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
prop = RNA_def_property(srna, "options", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, blend_import_options_items);
|
||||
RNA_def_property_flag(prop, PROP_ENUM_FLAG);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "", "Options for this blendfile import operation");
|
||||
RNA_def_property_enum_funcs(prop, "rna_BlendImportContext_options_get", nullptr, nullptr);
|
||||
|
||||
/* NOTE: Only stages currently exposed to handlers are listed here. */
|
||||
static const EnumPropertyItem blend_import_process_stage_items[] = {
|
||||
{int(BlendfileLinkAppendContext::ProcessStage::Init),
|
||||
"INIT",
|
||||
0,
|
||||
"",
|
||||
"Blendfile import context has been initialized and filled with a list of items to import, "
|
||||
"no data has been linked or appended yet"},
|
||||
{int(BlendfileLinkAppendContext::ProcessStage::Done),
|
||||
"DONE",
|
||||
0,
|
||||
"",
|
||||
"All data has been imported and is available in the list of `import_items`"},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
prop = RNA_def_property(srna, "process_stage", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, blend_import_process_stage_items);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "", "Current stage of the import process");
|
||||
RNA_def_property_enum_funcs(prop, "rna_BlendImportContext_process_stage_get", nullptr, nullptr);
|
||||
|
||||
RNA_define_verify_sdna(true); /* not in sdna */
|
||||
}
|
||||
|
||||
void RNA_def_blendfile_import(BlenderRNA *brna)
|
||||
{
|
||||
rna_def_blendfile_import_library(brna);
|
||||
rna_def_blendfile_import_item(brna);
|
||||
rna_def_blendfile_import_context(brna);
|
||||
}
|
||||
|
||||
#endif /* RNA_RUNTIME */
|
@ -166,6 +166,7 @@ void RNA_def_key(BlenderRNA *brna);
|
||||
void RNA_def_light(BlenderRNA *brna);
|
||||
void RNA_def_lattice(BlenderRNA *brna);
|
||||
void RNA_def_linestyle(BlenderRNA *brna);
|
||||
void RNA_def_blendfile_import(BlenderRNA *brna);
|
||||
void RNA_def_main(BlenderRNA *brna);
|
||||
void RNA_def_material(BlenderRNA *brna);
|
||||
void RNA_def_mesh(BlenderRNA *brna);
|
||||
|
@ -99,6 +99,10 @@ static PyStructSequence_Field app_cb_info_fields[] = {
|
||||
{"_extension_repos_sync", "on creating or synchronizing the active repository"},
|
||||
{"_extension_repos_files_clear",
|
||||
"remove files from the repository directory (uses as a string argument)"},
|
||||
{"blend_import_pre",
|
||||
mont29 marked this conversation as resolved
Outdated
Campbell Barton
commented
It'd be interesting to know if script authors would find it useful to separate: link & append. It'd be interesting to know if script authors would find it useful to separate: link & append.
It seems plausible a developer might only want to add a handler for the "append" case - if they intend to modify appended data for e.g. which doesn't make sense for library data.
Nika Kutsniashvili
commented
I would find that useful personally. But it would be lower on my priority list, so if it can take time I wouldnt mind if this lands in 4.3 without it. I would find that useful personally. But it would be lower on my priority list, so if it can take time I wouldnt mind if this lands in 4.3 without it.
Bastien Montagne
commented
It is fairly trivial to filter it by checking It is fairly trivial to filter it by checking `'LINK' in link_append_context.flags` (in current build, again will be renamed soon), so don't really see the benefit of adding several handlers here. Not to mention that more 'modes' already exist (append or reuse), and more are likely to be added soon-ish (embedded linking).
|
||||
"on linking or appending data (before), get a single `BlendImportContext` parameter"},
|
||||
{"blend_import_post",
|
||||
"on linking or appending data (after), get a single `BlendImportContext` parameter"},
|
||||
|
||||
/* sets the permanent tag */
|
||||
#define APP_CB_OTHER_FIELDS 1
|
||||
|
@ -527,6 +527,8 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject * /*args*/)
|
||||
}
|
||||
}
|
||||
|
||||
BKE_blendfile_link_append_context_init_done(lapp_context);
|
||||
|
||||
BKE_blendfile_link(lapp_context, nullptr);
|
||||
if (do_append) {
|
||||
BKE_blendfile_append(lapp_context, nullptr);
|
||||
@ -535,6 +537,8 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject * /*args*/)
|
||||
BKE_blendfile_override(lapp_context, self->liboverride_flags, nullptr);
|
||||
}
|
||||
|
||||
BKE_blendfile_link_append_context_finalize(lapp_context);
|
||||
|
||||
/* If enabled, replace named items in given lists by the final matching new ID pointer. */
|
||||
#ifdef USE_RNA_DATABLOCKS
|
||||
idcode_step = 0;
|
||||
|
@ -350,6 +350,8 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
BKE_blendfile_link_append_context_init_done(lapp_context);
|
||||
|
||||
/* XXX We'd need re-entrant locking on Main for this to work... */
|
||||
// BKE_main_lock(bmain);
|
||||
|
||||
@ -369,6 +371,8 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
|
||||
/* Instantiate loose data in the scene (e.g. add object to the active collection). */
|
||||
BKE_blendfile_link_append_instantiate_loose(lapp_context, op->reports);
|
||||
|
||||
BKE_blendfile_link_append_context_finalize(lapp_context);
|
||||
|
||||
BKE_blendfile_link_append_context_free(lapp_context);
|
||||
|
||||
/* Important we unset, otherwise these object won't
|
||||
@ -543,6 +547,8 @@ static ID *wm_file_link_append_datablock_ex(Main *bmain,
|
||||
lapp_context, id_name, id_code, nullptr);
|
||||
BKE_blendfile_link_append_context_item_library_index_enable(lapp_context, item, 0);
|
||||
|
||||
BKE_blendfile_link_append_context_init_done(lapp_context);
|
||||
|
||||
/* Link datablock. */
|
||||
BKE_blendfile_link(lapp_context, nullptr);
|
||||
|
||||
@ -552,6 +558,8 @@ static ID *wm_file_link_append_datablock_ex(Main *bmain,
|
||||
|
||||
BKE_blendfile_link_append_instantiate_loose(lapp_context, nullptr);
|
||||
|
||||
BKE_blendfile_link_append_context_finalize(lapp_context);
|
||||
|
||||
/* Get linked datablock and free working data. */
|
||||
ID *id = BKE_blendfile_link_append_context_item_newid_get(lapp_context, item);
|
||||
|
||||
|
Should "Link Append" be renamed to "Import" here? (description mentions link/append).
One other instance of "Link Append" exists here too.