Cleanup: naming & reduce declaration scope in the PyAPI for lib loading

Use terms source/destination instead of from/to.
This commit is contained in:
Campbell Barton
2025-08-02 02:10:59 +00:00
parent 58c7bb3fc7
commit 6d899a6726
2 changed files with 42 additions and 49 deletions

View File

@@ -3,32 +3,32 @@ import bpy
filepath = "//link_library.blend"
# Load a single scene we know the name of.
with bpy.data.libraries.load(filepath) as (data_from, data_to):
data_to.scenes = ["Scene"]
with bpy.data.libraries.load(filepath) as (data_src, data_dst):
data_dst.scenes = ["Scene"]
# Load all meshes.
with bpy.data.libraries.load(filepath) as (data_from, data_to):
data_to.meshes = data_from.meshes
with bpy.data.libraries.load(filepath) as (data_src, data_dst):
data_dst.meshes = data_src.meshes
# Link all objects starting with "A".
with bpy.data.libraries.load(filepath, link=True) as (data_from, data_to):
data_to.objects = [name for name in data_from.objects if name.startswith("A")]
with bpy.data.libraries.load(filepath, link=True) as (data_src, data_dst):
data_dst.objects = [name for name in data_src.objects if name.startswith("A")]
# Append everything.
with bpy.data.libraries.load(filepath) as (data_from, data_to):
for attr in dir(data_to):
setattr(data_to, attr, getattr(data_from, attr))
with bpy.data.libraries.load(filepath) as (data_src, data_dst):
for attr in dir(data_dst):
setattr(data_dst, attr, getattr(data_src, attr))
# The loaded objects can be accessed from 'data_to' outside of the context
# The loaded objects can be accessed from `data_dst` outside of the context
# since loading the data replaces the strings for the data-blocks or None
# if the data-block could not be loaded.
with bpy.data.libraries.load(filepath) as (data_from, data_to):
data_to.meshes = data_from.meshes
with bpy.data.libraries.load(filepath) as (data_src, data_dst):
data_dst.meshes = data_src.meshes
# Now operate directly on the loaded data.
for mesh in data_to.meshes:
for mesh in data_dst.meshes:
if mesh is not None:
print(mesh.name)

View File

@@ -434,19 +434,15 @@ static PyObject *bpy_lib_load(BPy_PropertyRNA *self, PyObject *args, PyObject *k
static PyObject *_bpy_names(BPy_Library *self, int blocktype)
{
PyObject *list;
LinkNode *l, *names;
int totnames;
names = BLO_blendhandle_get_datablock_names(
self->blo_handle, blocktype, (self->flag & FILE_ASSETS_ONLY) != 0, &totnames);
list = PyList_New(totnames);
int names_num;
LinkNode *names = BLO_blendhandle_get_datablock_names(
self->blo_handle, blocktype, (self->flag & FILE_ASSETS_ONLY) != 0, &names_num);
PyObject *list = PyList_New(names_num);
if (names) {
int counter = 0;
for (l = names; l; l = l->next) {
PyList_SET_ITEM(list, counter, PyUnicode_FromString((char *)l->link));
counter++;
int i = 0;
for (LinkNode *l = names; l; l = l->next, i++) {
PyList_SET_ITEM(list, i, PyUnicode_FromString((char *)l->link));
}
BLI_linklist_freeN(names); /* free linklist *and* each node's data */
}
@@ -456,8 +452,6 @@ static PyObject *_bpy_names(BPy_Library *self, int blocktype)
static PyObject *bpy_lib_enter(BPy_Library *self)
{
PyObject *ret;
BPy_Library *self_from;
ReportList *reports = &self->reports;
BlendFileReadReport *bf_reports = &self->bf_reports;
@@ -474,7 +468,8 @@ static PyObject *bpy_lib_enter(BPy_Library *self)
return nullptr;
}
PyObject *from_dict = _PyDict_NewPresized(bpy_library_dict_num);
PyObject *dict_src = _PyDict_NewPresized(bpy_library_dict_num);
PyObject *dict_dst = self->dict; /* Only for convenience (always `self->dict`). */
int dict_num_offset = 0;
int i = 0, code;
@@ -487,60 +482,58 @@ static PyObject *bpy_lib_enter(BPy_Library *self)
PyObject *str = PyUnicode_FromString(name_plural);
PyObject *item;
PyDict_SetItem(self->dict, str, item = PyList_New(0));
PyDict_SetItem(dict_dst, str, item = PyList_New(0));
Py_DECREF(item);
PyDict_SetItem(from_dict, str, item = _bpy_names(self, code));
PyDict_SetItem(dict_src, str, item = _bpy_names(self, code));
Py_DECREF(item);
Py_DECREF(str);
}
/* create a dummy */
self_from = PyObject_New(BPy_Library, &bpy_lib_Type);
STRNCPY(self_from->relpath, self->relpath);
STRNCPY(self_from->abspath, self->abspath);
/* Create a dummy. */
BPy_Library *self_src = PyObject_New(BPy_Library, &bpy_lib_Type);
STRNCPY(self_src->relpath, self->relpath);
STRNCPY(self_src->abspath, self->abspath);
/* Library blendfile version. */
/* Library blend-file version. */
{
PyObject *version;
PyObject *identifier = PyUnicode_FromString("version");
blender::int3 blendfile_version;
/* From. */
/* Source. */
blendfile_version = BLO_blendhandle_get_version(self->blo_handle);
version = PyC_Tuple_PackArray_I32(&blendfile_version[0], 3);
PyDict_SetItem(from_dict, identifier, version);
PyDict_SetItem(dict_src, identifier, version);
Py_DECREF(version);
/* To. */
/* Destination. */
blendfile_version = blender::int3(
BLENDER_FILE_VERSION / 100, BLENDER_FILE_VERSION % 100, BLENDER_FILE_SUBVERSION);
version = PyC_Tuple_PackArray_I32(&blendfile_version[0], 3);
PyDict_SetItem(self->dict, identifier, version);
PyDict_SetItem(dict_dst, identifier, version);
Py_DECREF(version);
Py_DECREF(identifier);
}
self_from->blo_handle = nullptr;
self_from->flag = 0;
self_from->create_liboverrides = false;
self_from->liboverride_flags = BKE_LIBLINK_OVERRIDE_INIT;
self_from->dict = from_dict; /* owns the dict */
self_src->blo_handle = nullptr;
self_src->flag = 0;
self_src->create_liboverrides = false;
self_src->liboverride_flags = BKE_LIBLINK_OVERRIDE_INIT;
self_src->dict = dict_src; /* owns the dict */
/* While it's not a bug if the sizes differ, the size is expected to match.
* Ensure `bpy_library_dict_num` gets updated when members are added. */
BLI_assert(PyDict_GET_SIZE(self_from->dict) + dict_num_offset == bpy_library_dict_num);
BLI_assert(PyDict_GET_SIZE(self_src->dict) + dict_num_offset == bpy_library_dict_num);
BLI_assert(PyDict_GET_SIZE(self->dict) + dict_num_offset == bpy_library_dict_num);
UNUSED_VARS_NDEBUG(dict_num_offset);
/* return pair */
ret = PyTuple_New(2);
PyTuple_SET_ITEMS(ret, (PyObject *)self_from, (PyObject *)self);
Py_INCREF(self);
BKE_reports_clear(reports);
/* Return a pair. */
PyObject *ret = PyTuple_New(2);
PyTuple_SET_ITEMS(ret, (PyObject *)self_src, Py_NewRef((PyObject *)self));
return ret;
}