[Bf-blender-cvs] [591f454] master: WM linking code rework.
Bastien Montagne
noreply at git.blender.org
Mon Oct 12 15:25:27 CEST 2015
Commit: 591f4549c958bc65fb02ef0011ec1d5ed475dc9a
Author: Bastien Montagne
Date: Mon Oct 12 15:20:51 2015 +0200
Branches: master
https://developer.blender.org/rB591f4549c958bc65fb02ef0011ec1d5ed475dc9a
WM linking code rework.
New code loops much less, does re-open & close .blend files for each data type,
and is much much more flexible - it is also ready for id-remap & co work being done in branches.
Main idea is to store libraries & datablocks to link in a dedicated struct, in a way
that avoids too much looping, and also allows to search for a single datablock in several libraries.
Here again, no change is expected in current behavior of link/append tool, please report
if anything goes different!
===================================================================
M source/blender/windowmanager/intern/wm_operators.c
===================================================================
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index aed1473..ac77b88 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -59,10 +59,13 @@
#include "PIL_time.h"
#include "BLI_blenlib.h"
+#include "BLI_bitmap.h"
#include "BLI_dial.h"
#include "BLI_dynstr.h" /*for WM_operator_pystring */
+#include "BLI_linklist.h"
#include "BLI_linklist_stack.h"
#include "BLI_math.h"
+#include "BLI_memarena.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
@@ -2604,106 +2607,150 @@ static int wm_link_append_invoke(bContext *C, wmOperator *op, const wmEvent *UNU
static short wm_link_append_flag(wmOperator *op)
{
+ PropertyRNA *prop;
short flag = 0;
- if (RNA_boolean_get(op->ptr, "autoselect")) flag |= FILE_AUTOSELECT;
- if (RNA_boolean_get(op->ptr, "active_layer")) flag |= FILE_ACTIVELAY;
- if (RNA_struct_find_property(op->ptr, "relative_path") && RNA_boolean_get(op->ptr, "relative_path")) flag |= FILE_RELPATH;
- if (RNA_boolean_get(op->ptr, "link")) flag |= FILE_LINK;
- if (RNA_boolean_get(op->ptr, "instance_groups")) flag |= FILE_GROUP_INSTANCE;
+ if (RNA_boolean_get(op->ptr, "autoselect"))
+ flag |= FILE_AUTOSELECT;
+ if (RNA_boolean_get(op->ptr, "active_layer"))
+ flag |= FILE_ACTIVELAY;
+ if ((prop = RNA_struct_find_property(op->ptr, "relative_path")) && RNA_property_boolean_get(op->ptr, prop))
+ flag |= FILE_RELPATH;
+ if (RNA_boolean_get(op->ptr, "link"))
+ flag |= FILE_LINK;
+ if (RNA_boolean_get(op->ptr, "instance_groups"))
+ flag |= FILE_GROUP_INSTANCE;
return flag;
}
-/* Helper.
- * if `name` is non-NULL, we assume a single-item link/append.
- * else if `*todo_libraries` is NULL we assume first-run.
- */
-static void wm_link_append_do_libgroup(
- bContext *C, wmOperator *op, const char *root, const char *libname, char *group, char *name,
- const short flag, GSet **todo_libraries)
+typedef struct WMLinkAppendDataItem {
+ char *name;
+ BLI_bitmap *libraries; /* All libs (from WMLinkAppendData.libraries) to try to load this ID from. */
+ int idcode;
+
+ ID *new_id;
+ void *customdata;
+} WMLinkAppendDataItem;
+
+typedef struct WMLinkAppendData {
+ LinkNodePair libraries;
+ LinkNodePair items;
+ int num_libraries;
+ int num_items;
+ short flag;
+
+ /* Internal 'private' data */
+ MemArena *memarena;
+} WMLinkAppendData;
+
+static WMLinkAppendData *wm_link_append_data_new(const int flag)
{
- Main *bmain = CTX_data_main(C);
- Main *mainl;
- BlendHandle *bh;
- Library *lib;
+ MemArena *ma = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+ WMLinkAppendData *lapp_data = BLI_memarena_calloc(ma, sizeof(*lapp_data));
- char path[FILE_MAX_LIBEXTRA], relname[FILE_MAX];
- int idcode;
- const bool is_first_run = (*todo_libraries == NULL);
+ lapp_data->flag = flag;
+ lapp_data->memarena = ma;
- BLI_assert(group);
- idcode = BKE_idcode_from_name(group);
+ return lapp_data;
+}
- bh = BLO_blendhandle_from_file(libname, op->reports);
+static void wm_link_append_data_free(WMLinkAppendData *lapp_data)
+{
+ BLI_memarena_free(lapp_data->memarena);
+}
- if (bh == NULL) {
- /* unlikely since we just browsed it, but possible
- * error reports will have been made by BLO_blendhandle_from_file() */
- return;
- }
+/* WARNING! *Never* call wm_link_append_data_library_add() after having added some items! */
- /* here appending/linking starts */
- mainl = BLO_library_link_begin(bmain, &bh, libname);
- lib = mainl->curlib;
- BLI_assert(lib);
+static void wm_link_append_data_library_add(WMLinkAppendData *lapp_data, const char *libname)
+{
+ size_t len = strlen(libname) + 1;
+ char *libpath = BLI_memarena_alloc(lapp_data->memarena, len);
- if (mainl->versionfile < 250) {
- BKE_reportf(op->reports, RPT_WARNING,
- "Linking or appending from a very old .blend file format (%d.%d), no animation conversion will "
- "be done! You may want to re-save your lib file with current Blender",
- mainl->versionfile, mainl->subversionfile);
- }
+ BLI_strncpy(libpath, libname, len);
+ BLI_linklist_append_arena(&lapp_data->libraries, libpath, lapp_data->memarena);
+ lapp_data->num_libraries++;
+}
- if (name) {
- BLO_library_link_named_part_ex(mainl, &bh, name, idcode, flag, CTX_data_scene(C), CTX_wm_view3d(C));
- }
- else {
- if (is_first_run) {
- *todo_libraries = BLI_gset_new(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, __func__);
- }
+static WMLinkAppendDataItem *wm_link_append_data_item_add(
+ WMLinkAppendData *lapp_data, const char *idname, const int idcode, void *customdata)
+{
+ WMLinkAppendDataItem *item = BLI_memarena_alloc(lapp_data->memarena, sizeof(*item));
+ size_t len = strlen(idname) + 1;
- RNA_BEGIN (op->ptr, itemptr, "files")
- {
- char curr_libname[FILE_MAX];
- int curr_idcode;
+ item->name = BLI_memarena_alloc(lapp_data->memarena, len);
+ BLI_strncpy(item->name, idname, len);
+ item->idcode = idcode;
+ item->libraries = BLI_BITMAP_NEW_MEMARENA(lapp_data->memarena, lapp_data->num_libraries);
- RNA_string_get(&itemptr, "name", relname);
+ item->new_id = NULL;
+ item->customdata = customdata;
- BLI_join_dirfile(path, sizeof(path), root, relname);
+ BLI_linklist_append_arena(&lapp_data->items, item, lapp_data->memarena);
+ lapp_data->num_items++;
- if (BLO_library_path_explode(path, curr_libname, &group, &name)) {
- if (!group || !name) {
- continue;
- }
+ return item;
+}
- curr_idcode = BKE_idcode_from_name(group);
+static void wm_link_do(
+ WMLinkAppendData *lapp_data, ReportList *reports, Main *bmain, Scene *scene, View3D *v3d)
+{
+ Main *mainl;
+ BlendHandle *bh;
+ Library *lib;
- if ((idcode == curr_idcode) && (BLI_path_cmp(curr_libname, libname) == 0)) {
- BLO_library_link_named_part_ex(mainl, &bh, name, idcode, flag, CTX_data_scene(C), CTX_wm_view3d(C));
- }
- else if (is_first_run) {
- BLI_join_dirfile(path, sizeof(path), curr_libname, group);
- if (!BLI_gset_haskey(*todo_libraries, path)) {
- BLI_gset_insert(*todo_libraries, BLI_strdup(path));
- }
- }
- }
+ const int flag = lapp_data->flag;
+
+ LinkNode *liblink, *itemlink;
+ int lib_idx, item_idx;
+
+ BLI_assert(lapp_data->num_items && lapp_data->num_libraries);
+
+ for (lib_idx = 0, liblink = lapp_data->libraries.list; liblink; lib_idx++, liblink = liblink->next) {
+ char *libname = liblink->link;
+
+ bh = BLO_blendhandle_from_file(libname, reports);
+
+ if (bh == NULL) {
+ /* Unlikely since we just browsed it, but possible
+ * Error reports will have been made by BLO_blendhandle_from_file() */
+ continue;
}
- RNA_END;
- }
- BLO_library_link_end(mainl, &bh, flag, CTX_data_scene(C), CTX_wm_view3d(C));
- BLO_blendhandle_close(bh);
+ /* here appending/linking starts */
+ mainl = BLO_library_link_begin(bmain, &bh, libname);
+ lib = mainl->curlib;
+ BLI_assert(lib);
+ UNUSED_VARS_NDEBUG(lib);
+
+ if (mainl->versionfile < 250) {
+ BKE_reportf(reports, RPT_WARNING,
+ "Linking or appending from a very old .blend file format (%d.%d), no animation conversion will "
+ "be done! You may want to re-save your lib file with current Blender",
+ mainl->versionfile, mainl->subversionfile);
+ }
- /* mark all library linked objects to be updated */
- BKE_main_lib_objects_recalc_all(bmain);
- IMB_colormanagement_check_file_config(bmain);
+ /* For each lib file, we try to link all items belonging to that lib,
+ * and tag those successful to not try to load them again with the other libs. */
+ for (item_idx = 0, itemlink = lapp_data->items.list; itemlink; item_idx++, itemlink = itemlink->next) {
+ WMLinkAppendDataItem *item = itemlink->link;
+ ID *new_id;
- /* append, rather than linking */
- if ((flag & FILE_LINK) == 0) {
- BLI_assert(BLI_findindex(&bmain->library, lib) != -1);
- BKE_library_make_local(bmain, lib, true);
+ if (!BLI_BITMAP_TEST(item->libraries, lib_idx)) {
+ continue;
+ }
+
+ new_id = BLO_library_link_named_part_ex(mainl, &bh, item->name, item->idcode, flag, scene, v3d);
+ if (new_id) {
+ /* If the link is sucessful, clear item's libs 'todo' flags.
+ * This avoids trying to link same item with other libraries to come. */
+ BLI_BITMAP_SET_ALL(item->libraries, false, lapp_data->num_libraries);
+ item->new_id = new_id;
+ }
+ }
+
+ BLO_library_link_end(mainl, &bh, flag, scene, v3d);
+ BLO_blendhandle_close(bh);
}
}
@@ -2712,13 +2759,12 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
PropertyRNA *prop;
+ WMLinkAppendData *lapp_data;
char path[FILE_MAX_LIBEXTRA], root[FILE_MAXDIR], libname[FILE_MAX], relname[FILE_MAX];
char *group, *name;
int totfiles = 0;
short flag;
- GSet *todo_libraries = NULL;
-
RNA_string_get(op->ptr, "filename", relname);
RNA_string_get(op->ptr, "directory", root);
@@ -2726,15 +2772,15 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
/* test if we have a valid data */
if (!BLO_library_path_explode(path, libname, &group, &name)) {
- BKE_report(op->reports, RPT_ERROR, "Not a library");
+ BKE_reportf(op->reports, RPT_ERROR, "'%s': not a library", path);
return OPERATOR_CANCELLED;
}
else if (!group) {
- BKE_report(op->reports, RPT_ERROR, "Nothing indicated");
+ BKE_reportf(op->reports, RPT_ERROR, "'%s': nothing indicated", path);
return OPERATOR_CANCELLED;
}
else if (BLI_path_cmp(bmain->name, libname) == 0) {
- BKE_report(op->reports, RPT_ERROR, "Cannot use current file as library");
+ BKE_reportf(op->reports, RPT_ERROR, "'%s': cannot use current file as library", path);
return OPERATOR_CANCELLED;
}
@@ -2744,55 +2790,112 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
totfiles = RNA_property_collection_length(op->ptr, prop);
if (totfiles == 0) {
if (!name) {
- BKE_report(op->reports, RPT_ERROR, "Nothing indicated");
+ BKE_reportf(op->reports, RPT_ERROR, "'%s': nothing indicated", path);
return OPERATOR_CANCELLED;
}
}
}
else if (!name) {
- BKE_report(op->reports, RP
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list