Link/Append: separate instantiation of loose data from core link/append code

When appending e.g. an object, it's generally expected that it is not just
appended but also added to the active collection. Something similar happens for
adding collections, or just geometry like a mesh data-block. This is called
"loose data instantiation" in the source code.

Which data is instantiated and how depends on context. Generally, it's best to
first do the low-level link or append operation and only afterwards do the
instantiation at a higher level where more context is known. For example, when
dragging an object asset into the 3D view, it's expected that the object is
added to the active collection. When dragging a node group into the node editor
that uses an object internally (e.g. as mesh storage), not so much.

This patch adds a new `BKE_blendfile_link_append_instantiate_loose` method that
does the "default instantiation", i.e. the one we want to happen when using the
general link/append operator to import data. Instead of calling this directly
from low level `BKE_blendfile_append`, it's now called in `wm_link_append_exec`
(and other places where desired).

Furthermore, `view3d_ob_drop_copy_external_asset` does not use this anymore, but
explicitly adds only the dragged object to the active collection. Some places,
e.g. when linking/appending using the Python API, don't do any instantiation at
all. They didn't do this before either, but it was way less obvious (it used
`BLO_library_link_params_init` instead of
`BLO_library_link_params_init_with_context`). Now there is always an explicit
call to do instantiation in higher level code.

Pull Request: https://projects.blender.org/blender/blender/pulls/125814
This commit is contained in:
Jacques Lucke
2024-08-07 09:35:10 +02:00
parent 91de9acc61
commit 2858c3b287
5 changed files with 46 additions and 29 deletions

View File

@@ -168,6 +168,12 @@ void BKE_blendfile_append(BlendfileLinkAppendContext *lapp_context, ReportList *
*/
void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *reports);
/**
* Instantiate loose data in the scene (e.g. add object to the active collection).
*/
void BKE_blendfile_link_append_instantiate_loose(BlendfileLinkAppendContext *lapp_context,
ReportList *reports);
/**
* Options controlling the behavior of liboverrides creation.
*/

View File

@@ -50,6 +50,9 @@ static void copybuffer_append(BlendfileLinkAppendContext *lapp_context,
/* Append, rather than linking */
BKE_blendfile_append(lapp_context, reports);
/* Instantiate loose data in the scene (e.g. add object to the active collection). */
BKE_blendfile_link_append_instantiate_loose(lapp_context, reports);
/* This must be unset, otherwise these object won't link into other scenes from this blend
* file. */
BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false);

View File

@@ -1476,12 +1476,6 @@ void BKE_blendfile_append(BlendfileLinkAppendContext *lapp_context, ReportList *
}
BKE_id_multi_tagged_delete(bmain);
/* Instantiate newly created (duplicated) IDs as needed. */
LooseDataInstantiateContext instantiate_context{};
instantiate_context.lapp_context = lapp_context;
instantiate_context.active_collection = nullptr;
loose_data_instantiate(&instantiate_context);
BKE_main_id_newptr_and_tag_clear(bmain);
BlendFileReadReport bf_reports{};
@@ -1535,12 +1529,13 @@ static int foreach_libblock_link_finalize_cb(LibraryIDLinkCallbackData *cb_data)
return IDWALK_RET_NOP;
}
static void blendfile_link_finalize(BlendfileLinkAppendContext *lapp_context, ReportList *reports)
void BKE_blendfile_link_append_instantiate_loose(BlendfileLinkAppendContext *lapp_context,
ReportList *reports)
{
BLI_assert((lapp_context->params->flag & FILE_LINK) != 0);
/* Instantiate newly linked IDs as needed. */
if (lapp_context->params->context.scene != nullptr) {
if (!lapp_context->params->context.scene) {
return;
}
if (lapp_context->params->flag & FILE_LINK) {
new_id_to_item_mapping_create(lapp_context);
/* Add items for all not yet known IDs (i.e. implicitly linked indirect dependencies) to the
* list.
@@ -1564,16 +1559,12 @@ static void blendfile_link_finalize(BlendfileLinkAppendContext *lapp_context, Re
&cb_data,
IDWALK_NOP);
}
LooseDataInstantiateContext instantiate_context{};
instantiate_context.lapp_context = lapp_context;
instantiate_context.active_collection = nullptr;
loose_data_instantiate(&instantiate_context);
}
BlendFileReadReport bf_reports{};
bf_reports.reports = reports;
BLO_read_do_version_after_setup(lapp_context->params->bmain, &bf_reports);
LooseDataInstantiateContext instantiate_context{};
instantiate_context.lapp_context = lapp_context;
instantiate_context.active_collection = nullptr;
loose_data_instantiate(&instantiate_context);
}
void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *reports)
@@ -1646,8 +1637,10 @@ void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *re
*
* In append case, the finalizing process is much more complex and requires and additional call
* to #BKE_blendfile_append for caller code. */
if ((lapp_context->params->flag & FILE_LINK) != 0) {
blendfile_link_finalize(lapp_context, reports);
if (lapp_context->params->flag & FILE_LINK) {
BlendFileReadReport bf_reports{};
bf_reports.reports = reports;
BLO_read_do_version_after_setup(lapp_context->params->bmain, &bf_reports);
}
}

View File

@@ -780,26 +780,38 @@ static void view3d_ob_drop_copy_external_asset(bContext *C, wmDrag *drag, wmDrop
* can use the context setup here to place the objects. */
BLI_assert(drag->type == WM_DRAG_ASSET);
Main *bmain = CTX_data_main(C);
wmDragAsset *asset_drag = WM_drag_get_asset_data(drag, 0);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
BKE_view_layer_base_deselect_all(scene, view_layer);
ID *id = WM_drag_asset_id_import(C, asset_drag, FILE_AUTOSELECT);
Object *object = reinterpret_cast<Object *>(
WM_drag_asset_id_import(C, asset_drag, FILE_AUTOSELECT));
LayerCollection *lc = BKE_layer_collection_get_active(view_layer);
Collection *collection = BKE_collection_parent_editable_find_recursive(view_layer,
lc->collection);
object->visibility_flag &= ~(OB_HIDE_VIEWPORT | OB_HIDE_SELECT);
BKE_collection_object_add(bmain, collection, object);
BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, object);
base->local_view_bits |= v3d->local_view_uid;
base->flag |= BASE_SELECTED;
BKE_scene_object_base_flag_sync_from_base(base);
/* TODO(sergey): Only update relations for the current scene. */
DEG_relations_tag_update(CTX_data_main(C));
WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
RNA_int_set(drop->ptr, "session_uid", id->session_uid);
RNA_int_set(drop->ptr, "session_uid", object->id.session_uid);
BKE_view_layer_synced_ensure(scene, view_layer);
Base *base = BKE_view_layer_base_find(view_layer, (Object *)id);
if (base != nullptr) {
BKE_view_layer_base_select_and_set_active(view_layer, base);
WM_main_add_notifier(NC_SCENE | ND_OB_ACTIVE, scene);
}
BKE_view_layer_base_select_and_set_active(view_layer, base);
WM_main_add_notifier(NC_SCENE | ND_OB_ACTIVE, scene);
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
ED_outliner_select_sync_from_object_tag(C);
@@ -812,7 +824,7 @@ static void view3d_ob_drop_copy_external_asset(bContext *C, wmDrag *drag, wmDrop
if (snap_state) {
float obmat_final[4][4];
view3d_ob_drop_matrix_from_snap(snap_state, (Object *)id, obmat_final);
view3d_ob_drop_matrix_from_snap(snap_state, object, obmat_final);
RNA_float_set_array(drop->ptr, "matrix", &obmat_final[0][0]);
}

View File

@@ -366,6 +366,9 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
BKE_blendfile_append(lapp_context, op->reports);
}
/* 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_free(lapp_context);
/* Important we unset, otherwise these object won't