43#define USE_RNA_DATABLOCKS
45#ifdef USE_RNA_DATABLOCKS
79# pragma clang diagnostic push
80# pragma clang diagnostic ignored "-Wcast-function-type"
82# pragma GCC diagnostic push
83# pragma GCC diagnostic ignored "-Wcast-function-type"
96# pragma clang diagnostic pop
98# pragma GCC diagnostic pop
104 Py_XDECREF(
self->dict);
109 PyVarObject_HEAD_INIT(
nullptr, 0)
125 PyObject_GenericGetAttr,
167 "assets_only=False, "
168 "create_liboverrides=False, "
169 "reuse_liboverrides=False, "
170 "create_liboverrides_runtime=False)\n"
172 " Returns a context manager which exposes 2 library objects on entering.\n"
173 " Each object has attributes matching bpy.data which are lists of strings to be linked.\n"
175 " :arg filepath: The path to a blend file.\n"
176 " :type filepath: str | bytes\n"
177 " :arg link: When False reference to the original file is lost.\n"
178 " :type link: bool\n"
179 " :arg relative: When True the path is stored relative to the open blend file.\n"
180 " :type relative: bool\n"
181 " :arg assets_only: If True, only list data-blocks marked as assets.\n"
182 " :type assets_only: bool\n"
183 " :arg create_liboverrides: If True and ``link`` is True, liboverrides will\n"
184 " be created for linked data.\n"
185 " :type create_liboverrides: bool\n"
186 " :arg reuse_liboverrides: If True and ``create_liboverride`` is True,\n"
187 " search for existing liboverride first.\n"
188 " :type reuse_liboverrides: bool\n"
189 " :arg create_liboverrides_runtime: If True and ``create_liboverride`` is True,\n"
190 " create (or search for existing) runtime liboverride.\n"
191 " :type create_liboverrides_runtime: bool\n");
198 bool is_rel =
false, is_link =
false, use_assets_only =
false;
199 bool create_liboverrides =
false, reuse_liboverrides =
false,
200 create_liboverrides_runtime =
false;
202 static const char *_keywords[] = {
207 "create_liboverrides",
208 "reuse_liboverrides",
209 "create_liboverrides_runtime",
212 static _PyArg_Parser _parser = {
227 if (!_PyArg_ParseTupleAndKeywordsFast(args,
239 &create_liboverrides,
243 &create_liboverrides_runtime))
253 STRNCPY(filepath_abs, filepath_rel);
257 if (blendfile_path[0]) {
265 char filepath_abs_normalized[
FILE_MAX];
266 STRNCPY(filepath_abs_normalized, filepath_abs);
268 if (
BLI_path_cmp(filepath_abs_normalized, blendfile_path) == 0) {
269 PyErr_SetString(PyExc_ValueError,
"Cannot load from the current blend file.");
274 if (!is_link && create_liboverrides) {
275 PyErr_SetString(PyExc_ValueError,
"`link` is False but `create_liboverrides` is True");
278 if (!create_liboverrides && reuse_liboverrides) {
279 PyErr_SetString(PyExc_ValueError,
280 "`create_liboverrides` is False but `reuse_liboverrides` is True");
283 if (!create_liboverrides && create_liboverrides_runtime) {
284 PyErr_SetString(PyExc_ValueError,
285 "`create_liboverrides` is False but `create_liboverrides_runtime` is True");
295 ret->bmain_is_temp = (bmain != bmain_base);
297 ret->blo_handle =
nullptr;
300 ret->create_liboverrides = create_liboverrides;
302 create_liboverrides ?
309 return (PyObject *)
ret;
320 list = PyList_New(totnames);
324 for (
l = names;
l;
l =
l->next) {
325 PyList_SET_ITEM(list, counter, PyUnicode_FromString((
char *)
l->link));
342 memset(bf_reports, 0,
sizeof(*bf_reports));
347 if (
self->blo_handle ==
nullptr) {
349 PyErr_Format(PyExc_IOError,
"load: %s failed to open blend file",
self->abspath);
354 PyObject *from_dict = _PyDict_NewPresized(
INDEX_ID_MAX);
360 PyObject *
str = PyUnicode_FromString(name_plural);
363 PyDict_SetItem(
self->dict,
str, item = PyList_New(0));
381 self_from->
dict = from_dict;
384 ret = PyTuple_New(2);
394 const char *name_plural,
397 PyObject *exc, *val, *tb;
398 PyErr_Fetch(&exc, &val, &tb);
399 if (PyErr_WarnFormat(PyExc_UserWarning,
401 "load: '%s' does not contain %s[\"%s\"]",
407 if (PyErr_ExceptionMatches(PyExc_Warning)) {
408 PyErr_WriteUnraisable((PyObject *)
self);
411 PyErr_Restore(exc, val, tb);
416 PyObject *exc, *val, *tb;
417 PyErr_Fetch(&exc, &val, &tb);
418 if (PyErr_WarnFormat(PyExc_UserWarning,
420 "load: '%s' expected a string type, not a %.200s",
422 Py_TYPE(item)->tp_name))
425 if (PyErr_ExceptionMatches(PyExc_Warning)) {
426 PyErr_WriteUnraisable((PyObject *)
self);
429 PyErr_Restore(exc, val, tb);
453 ID *liboverride_id =
data.py_library->create_liboverrides ?
463 PyObject *item_src = PyList_GET_ITEM(
data.py_list, py_list_index);
467 if (liboverride_id !=
nullptr) {
471 else if (new_id !=
nullptr) {
476 const char *item_idname = PyUnicode_AsUTF8(item_src);
481 py_item = Py_NewRef(Py_None);
484 PyList_SET_ITEM(
data.py_list, py_list_index, py_item);
495 const bool create_liboverrides =
self->create_liboverrides;
498 BLI_assert(!do_append || !create_liboverrides);
511 self->blo_handle =
nullptr;
521 PyObject *ls = PyDict_GetItemString(
self->dict, name_plural);
523 if (ls ==
nullptr || !PyList_Check(ls)) {
527 const Py_ssize_t
size = PyList_GET_SIZE(ls);
533 for (Py_ssize_t
i = 0;
i <
size;
i++) {
534 PyObject *item_src = PyList_GET_ITEM(ls,
i);
535 const char *item_idname = PyUnicode_AsUTF8(item_src);
541 if (item_idname !=
nullptr) {
551#ifdef USE_RNA_DATABLOCKS
553 PyObject *py_item = Py_NewRef(Py_None);
554 PyList_SET_ITEM(ls,
i, py_item);
567 else if (create_liboverrides) {
574#ifdef USE_RNA_DATABLOCKS
581 PyObject *ls = PyDict_GetItemString(
self->dict, name_plural);
583 if (ls ==
nullptr || !PyList_Check(ls)) {
587 const Py_ssize_t
size = PyList_GET_SIZE(ls);
595 iter_data.
idcode = idcode;
619 return PyDict_Keys(
self->dict);
624# pragma clang diagnostic push
625# pragma clang diagnostic ignored "-Wcast-function-type"
627# pragma GCC diagnostic push
628# pragma GCC diagnostic ignored "-Wcast-function-type"
635 METH_VARARGS | METH_KEYWORDS,
641# pragma clang diagnostic pop
643# pragma GCC diagnostic pop
void BKE_blendfile_link_append_context_finalize(BlendfileLinkAppendContext *lapp_context)
void BKE_blendfile_link_append_context_item_foreach(BlendfileLinkAppendContext *lapp_context, blender::FunctionRef< bool(BlendfileLinkAppendContext *lapp_context, BlendfileLinkAppendContextItem *item)> callback_function, eBlendfileLinkAppendForeachItemFlag flag)
@ BKE_LIBLINK_OVERRIDE_USE_EXISTING_LIBOVERRIDES
@ BKE_LIBLINK_OVERRIDE_CREATE_RUNTIME
@ BKE_LIBLINK_OVERRIDE_INIT
void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *reports)
void BKE_blendfile_link_append_context_library_add(BlendfileLinkAppendContext *lapp_context, const char *libname, BlendHandle *blo_handle)
BlendfileLinkAppendContextItem * BKE_blendfile_link_append_context_item_add(BlendfileLinkAppendContext *lapp_context, const char *idname, short idcode, void *userdata)
void BKE_blendfile_link_append_context_free(BlendfileLinkAppendContext *lapp_context)
void BKE_blendfile_append(BlendfileLinkAppendContext *lapp_context, ReportList *reports)
void BKE_blendfile_override(BlendfileLinkAppendContext *lapp_context, const eBKELibLinkOverride flags, ReportList *reports)
void BKE_blendfile_link_append_context_item_library_index_enable(BlendfileLinkAppendContext *lapp_context, BlendfileLinkAppendContextItem *item, int library_index)
BlendfileLinkAppendContext * BKE_blendfile_link_append_context_new(LibraryLink_Params *params)
short BKE_blendfile_link_append_context_item_idcode_get(BlendfileLinkAppendContext *lapp_context, BlendfileLinkAppendContextItem *item)
ID * BKE_blendfile_link_append_context_item_liboverrideid_get(BlendfileLinkAppendContext *lapp_context, BlendfileLinkAppendContextItem *item)
@ BKE_BLENDFILE_LINK_APPEND_FOREACH_ITEM_FLAG_DO_DIRECT
void * BKE_blendfile_link_append_context_item_userdata_get(BlendfileLinkAppendContext *lapp_context, BlendfileLinkAppendContextItem *item)
void BKE_blendfile_link_append_context_init_done(BlendfileLinkAppendContext *lapp_context)
ID * BKE_blendfile_link_append_context_item_newid_get(BlendfileLinkAppendContext *lapp_context, BlendfileLinkAppendContextItem *item)
Main * CTX_data_main(const bContext *C)
bool BKE_idtype_idcode_is_linkable(short idcode)
short BKE_idtype_idcode_iter_step(int *idtype_index)
const char * BKE_idtype_idcode_to_name_plural(short idcode)
void BKE_main_id_tag_all(Main *mainvar, int tag, bool value)
const char * BKE_main_blendfile_path(const Main *bmain) ATTR_NONNULL()
void BKE_reports_free(ReportList *reports)
void BKE_reports_clear(ReportList *reports)
void BKE_reports_init(ReportList *reports, int flag)
void BLI_linklist_freeN(LinkNode *list)
bool BLI_path_abs(char path[FILE_MAX], const char *basepath) ATTR_NONNULL(1
int BLI_path_normalize(char *path) ATTR_NONNULL(1)
char * STRNCPY(char(&dst)[N], const char *src)
#define POINTER_FROM_INT(i)
#define POINTER_AS_INT(i)
external readfile function prototypes.
void BLO_library_link_params_init(LibraryLink_Params *params, Main *bmain, int flag, int id_tag_extra)
BlendHandle * BLO_blendhandle_from_file(const char *filepath, BlendFileReadReport *reports)
LinkNode * BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype, bool use_assets_only, int *r_tot_names)
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMLoop * l
short BPy_reports_to_error(ReportList *reports, PyObject *exception, const bool clear)
struct bContext * BPY_context_get()
PyMethodDef BPY_library_load_method_def
static void bpy_lib_dealloc(BPy_Library *self)
static PyObject * bpy_lib_exit(BPy_Library *self, PyObject *args)
static PyMethodDef bpy_lib_methods[]
PyDoc_STRVAR(bpy_lib_load_doc, ".. method:: load(" "filepath, " "link=False, " "relative=False, " "assets_only=False, " "create_liboverrides=False, " "reuse_liboverrides=False, " "create_liboverrides_runtime=False)\n" "\n" " Returns a context manager which exposes 2 library objects on entering.\n" " Each object has attributes matching bpy.data which are lists of strings to be linked.\n" "\n" " :arg filepath: The path to a blend file.\n" " :type filepath: str | bytes\n" " :arg link: When False reference to the original file is lost.\n" " :type link: bool\n" " :arg relative: When True the path is stored relative to the open blend file.\n" " :type relative: bool\n" " :arg assets_only: If True, only list data-blocks marked as assets.\n" " :type assets_only: bool\n" " :arg create_liboverrides: If True and ``link`` is True, liboverrides will\n" " be created for linked data.\n" " :type create_liboverrides: bool\n" " :arg reuse_liboverrides: If True and ``create_liboverride`` is True,\n" " search for existing liboverride first.\n" " :type reuse_liboverrides: bool\n" " :arg create_liboverrides_runtime: If True and ``create_liboverride`` is True,\n" " create (or search for existing) runtime liboverride.\n" " :type create_liboverrides_runtime: bool\n")
static PyObject * bpy_lib_enter(BPy_Library *self)
static PyObject * _bpy_names(BPy_Library *self, int blocktype)
static PyObject * bpy_lib_dir(BPy_Library *self)
static bool bpy_lib_exit_lapp_context_items_cb(BlendfileLinkAppendContext *lapp_context, BlendfileLinkAppendContextItem *item, LibExitLappContextItemsIterData &data)
static PyObject * bpy_lib_load(BPy_PropertyRNA *self, PyObject *args, PyObject *kw)
int BPY_library_load_type_ready()
static void bpy_lib_exit_warn_type(BPy_Library *self, PyObject *item)
static PyTypeObject bpy_lib_Type
static void bpy_lib_exit_warn_idname(BPy_Library *self, const char *name_plural, const char *idname)
PyObject * pyrna_struct_CreatePyObject(PointerRNA *ptr)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
int PyC_ParseUnicodeAsBytesAndSize(PyObject *o, void *p)
int PyC_ParseBool(PyObject *o, void *p)
header-only compatibility defines.
#define PY_ARG_PARSER_HEAD_COMPAT()
#define PyTuple_SET_ITEMS(op_arg,...)
PointerRNA RNA_id_pointer_create(ID *id)
eBKELibLinkOverride liboverride_flags
BlendFileReadReport bf_reports
PyObject_HEAD char relpath[FILE_MAX]