2023-08-16 00:20:26 +10:00
|
|
|
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
2023-05-31 16:19:06 +02:00
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
2016-04-24 22:42:41 +10:00
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup bke
|
2016-04-24 22:42:41 +10:00
|
|
|
*
|
|
|
|
|
* Used for copy/paste operator, (using a temporary file).
|
|
|
|
|
*/
|
|
|
|
|
|
2023-07-22 11:27:25 +10:00
|
|
|
#include <cstdlib>
|
2016-04-24 22:42:41 +10:00
|
|
|
|
2024-01-21 19:34:20 +01:00
|
|
|
#include "BKE_blender_copybuffer.hh" /* own include */
|
2023-12-13 12:36:45 +01:00
|
|
|
#include "BKE_blendfile_link_append.hh"
|
2023-11-16 11:41:55 +01:00
|
|
|
#include "BKE_context.hh"
|
2024-01-23 15:18:09 -05:00
|
|
|
#include "BKE_layer.hh"
|
2024-01-15 12:44:04 -05:00
|
|
|
#include "BKE_lib_id.hh"
|
2016-04-24 22:42:41 +10:00
|
|
|
|
2023-09-22 03:18:17 +02:00
|
|
|
#include "DEG_depsgraph_build.hh"
|
2017-04-06 16:11:50 +02:00
|
|
|
|
2024-02-09 13:41:30 +01:00
|
|
|
#include "BLO_readfile.hh"
|
2023-08-28 15:01:05 +02:00
|
|
|
#include "BLO_writefile.hh"
|
2016-04-24 22:42:41 +10:00
|
|
|
|
2024-01-18 22:50:23 +02:00
|
|
|
#include "IMB_colormanagement.hh"
|
2016-04-24 22:42:41 +10:00
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
2024-08-04 13:45:06 +10:00
|
|
|
/** \name Paste API based on 'partial' blend-files.
|
2016-04-24 22:42:41 +10:00
|
|
|
* \{ */
|
|
|
|
|
|
2021-11-30 17:11:25 +01:00
|
|
|
/* Common helper for paste functions. */
|
|
|
|
|
static void copybuffer_append(BlendfileLinkAppendContext *lapp_context,
|
|
|
|
|
Main *bmain,
|
|
|
|
|
ReportList *reports)
|
|
|
|
|
{
|
|
|
|
|
/* Tag existing IDs in given `bmain_dst` as already existing. */
|
2024-08-07 12:12:17 +02:00
|
|
|
BKE_main_id_tag_all(bmain, ID_TAG_PRE_EXISTING, true);
|
2021-11-30 17:11:25 +01:00
|
|
|
|
Python API: Add link/append pre/post handlers.
The `pre` handler is called after blender internal code is done populating
the link/append context with data to be processed, and before this data
starts being linked from library files.
The `post` handler is called after blender is done linking, and
potentailly appending and/or instantiating, the requested data and all
of their dependencies.
Both handlers are called with a single argument, the link/append
context.
An new RNA sets of wrappers have been added to expose relevant info from
these internal C++ structures.
NOTE: !113658 is very similar (but tied to asset drag & drop), whereas
this PR is more general (these could probably live hand-in-hand / side-
by-side).
Implements #122357
Pull Request: https://projects.blender.org/blender/blender/pulls/128279
-----------------
Some quick py example code:
```python
import bpy
def my_handler_pre(lapp_context):
print("About to {}:\n\t".format("link" if "LINK" in lapp_context.options else "append"),
"\n\t".join("{} '{}', from libs ['{}']".format(item.id_type, item.name,
"', '".join([l.filepath for l in item.source_libraries]))
for item in lapp_context.import_items))
def my_handler_post(lapp_context):
print("{}:\n\t".format("Linked" if "LINK" in lapp_context.options else "Appended"),
"\n\t".join("{} '{}', from lib '{}'".format(item.id.id_type, item.id.name, item.source_library.filepath)
for item in lapp_context.import_items))
bpy.app.handlers.link_append_pre.append(my_handler_pre)
bpy.app.handlers.link_append_post.append(my_handler_post)
```
2024-10-02 16:44:38 +02:00
|
|
|
BKE_blendfile_link_append_context_init_done(lapp_context);
|
|
|
|
|
|
2021-11-30 17:11:25 +01:00
|
|
|
BKE_blendfile_link(lapp_context, reports);
|
|
|
|
|
|
|
|
|
|
/* Mark all library linked objects to be updated. */
|
|
|
|
|
BKE_main_lib_objects_recalc_all(bmain);
|
|
|
|
|
IMB_colormanagement_check_file_config(bmain);
|
|
|
|
|
|
|
|
|
|
/* Append, rather than linking */
|
|
|
|
|
BKE_blendfile_append(lapp_context, reports);
|
|
|
|
|
|
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
2024-08-07 09:35:10 +02:00
|
|
|
/* Instantiate loose data in the scene (e.g. add object to the active collection). */
|
|
|
|
|
BKE_blendfile_link_append_instantiate_loose(lapp_context, reports);
|
|
|
|
|
|
Python API: Add link/append pre/post handlers.
The `pre` handler is called after blender internal code is done populating
the link/append context with data to be processed, and before this data
starts being linked from library files.
The `post` handler is called after blender is done linking, and
potentailly appending and/or instantiating, the requested data and all
of their dependencies.
Both handlers are called with a single argument, the link/append
context.
An new RNA sets of wrappers have been added to expose relevant info from
these internal C++ structures.
NOTE: !113658 is very similar (but tied to asset drag & drop), whereas
this PR is more general (these could probably live hand-in-hand / side-
by-side).
Implements #122357
Pull Request: https://projects.blender.org/blender/blender/pulls/128279
-----------------
Some quick py example code:
```python
import bpy
def my_handler_pre(lapp_context):
print("About to {}:\n\t".format("link" if "LINK" in lapp_context.options else "append"),
"\n\t".join("{} '{}', from libs ['{}']".format(item.id_type, item.name,
"', '".join([l.filepath for l in item.source_libraries]))
for item in lapp_context.import_items))
def my_handler_post(lapp_context):
print("{}:\n\t".format("Linked" if "LINK" in lapp_context.options else "Appended"),
"\n\t".join("{} '{}', from lib '{}'".format(item.id.id_type, item.id.name, item.source_library.filepath)
for item in lapp_context.import_items))
bpy.app.handlers.link_append_pre.append(my_handler_pre)
bpy.app.handlers.link_append_post.append(my_handler_post)
```
2024-10-02 16:44:38 +02:00
|
|
|
BKE_blendfile_link_append_context_finalize(lapp_context);
|
|
|
|
|
|
2021-11-30 17:11:25 +01:00
|
|
|
/* This must be unset, otherwise these object won't link into other scenes from this blend
|
|
|
|
|
* file. */
|
2024-08-07 12:12:17 +02:00
|
|
|
BKE_main_id_tag_all(bmain, ID_TAG_PRE_EXISTING, false);
|
2021-11-30 17:11:25 +01:00
|
|
|
|
|
|
|
|
/* Recreate dependency graph to include new objects. */
|
|
|
|
|
DEG_relations_tag_update(bmain);
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-25 09:55:36 +01:00
|
|
|
bool BKE_copybuffer_read(Main *bmain_dst,
|
|
|
|
|
const char *libname,
|
|
|
|
|
ReportList *reports,
|
2020-03-03 17:21:28 +01:00
|
|
|
const uint64_t id_types_mask)
|
2016-09-14 17:50:11 +02:00
|
|
|
{
|
2022-05-13 09:24:28 +10:00
|
|
|
/* NOTE: No recursive append here (no `BLO_LIBLINK_APPEND_RECURSIVE`), external linked data
|
2021-11-30 17:11:25 +01:00
|
|
|
* should remain linked. */
|
2020-09-08 15:32:43 +10:00
|
|
|
const int flag = 0;
|
2021-03-09 00:53:13 +11:00
|
|
|
const int id_tag_extra = 0;
|
2023-06-03 08:36:28 +10:00
|
|
|
LibraryLink_Params liblink_params;
|
2021-03-09 00:53:13 +11:00
|
|
|
BLO_library_link_params_init(&liblink_params, bmain_dst, flag, id_tag_extra);
|
2021-11-30 17:11:25 +01:00
|
|
|
|
|
|
|
|
BlendfileLinkAppendContext *lapp_context = BKE_blendfile_link_append_context_new(
|
|
|
|
|
&liblink_params);
|
2023-07-17 10:46:26 +02:00
|
|
|
BKE_blendfile_link_append_context_library_add(lapp_context, libname, nullptr);
|
2021-11-30 17:11:25 +01:00
|
|
|
|
|
|
|
|
const int num_pasted = BKE_blendfile_link_append_context_item_idtypes_from_library_add(
|
|
|
|
|
lapp_context, reports, id_types_mask, 0);
|
|
|
|
|
if (num_pasted == BLENDFILE_LINK_APPEND_INVALID) {
|
|
|
|
|
BKE_blendfile_link_append_context_free(lapp_context);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
copybuffer_append(lapp_context, bmain_dst, reports);
|
|
|
|
|
|
|
|
|
|
BKE_blendfile_link_append_context_free(lapp_context);
|
2016-09-14 17:50:11 +02:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-25 09:55:36 +01:00
|
|
|
int BKE_copybuffer_paste(bContext *C,
|
|
|
|
|
const char *libname,
|
2021-11-12 10:17:15 +01:00
|
|
|
const int flag,
|
2019-03-25 09:55:36 +01:00
|
|
|
ReportList *reports,
|
2020-03-03 17:21:28 +01:00
|
|
|
const uint64_t id_types_mask)
|
2016-04-24 22:42:41 +10:00
|
|
|
{
|
|
|
|
|
Main *bmain = CTX_data_main(C);
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
2017-11-22 10:52:39 -02:00
|
|
|
ViewLayer *view_layer = CTX_data_view_layer(C);
|
2023-07-17 10:46:26 +02:00
|
|
|
View3D *v3d = CTX_wm_view3d(C); /* may be nullptr. */
|
2021-03-09 00:53:13 +11:00
|
|
|
const int id_tag_extra = 0;
|
2016-04-24 22:42:41 +10:00
|
|
|
|
2022-05-13 09:24:28 +10:00
|
|
|
/* NOTE: No recursive append here, external linked data should remain linked. */
|
2021-11-30 17:11:25 +01:00
|
|
|
BLI_assert((flag & BLO_LIBLINK_APPEND_RECURSIVE) == 0);
|
2016-04-24 22:42:41 +10:00
|
|
|
|
2023-06-03 08:36:28 +10:00
|
|
|
LibraryLink_Params liblink_params;
|
2021-03-09 00:53:13 +11:00
|
|
|
BLO_library_link_params_init_with_context(
|
|
|
|
|
&liblink_params, bmain, flag, id_tag_extra, scene, view_layer, v3d);
|
2016-04-24 22:42:41 +10:00
|
|
|
|
2021-11-30 17:11:25 +01:00
|
|
|
BlendfileLinkAppendContext *lapp_context = BKE_blendfile_link_append_context_new(
|
|
|
|
|
&liblink_params);
|
2023-07-17 10:46:26 +02:00
|
|
|
BKE_blendfile_link_append_context_library_add(lapp_context, libname, nullptr);
|
2016-04-24 22:42:41 +10:00
|
|
|
|
2021-11-30 17:11:25 +01:00
|
|
|
const int num_pasted = BKE_blendfile_link_append_context_item_idtypes_from_library_add(
|
|
|
|
|
lapp_context, reports, id_types_mask, 0);
|
|
|
|
|
if (num_pasted == BLENDFILE_LINK_APPEND_INVALID) {
|
|
|
|
|
BKE_blendfile_link_append_context_free(lapp_context);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2016-04-24 22:42:41 +10:00
|
|
|
|
2022-09-14 21:30:20 +02:00
|
|
|
BKE_view_layer_base_deselect_all(scene, view_layer);
|
2017-08-16 12:14:31 +02:00
|
|
|
|
2021-11-30 17:11:25 +01:00
|
|
|
copybuffer_append(lapp_context, bmain, reports);
|
2016-04-24 22:42:41 +10:00
|
|
|
|
2021-11-30 17:11:25 +01:00
|
|
|
BKE_blendfile_link_append_context_free(lapp_context);
|
2019-03-25 09:55:36 +01:00
|
|
|
return num_pasted;
|
2016-04-24 22:42:41 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|