diff options
Diffstat (limited to 'source/blender/windowmanager/intern/wm_files_link.c')
-rw-r--r-- | source/blender/windowmanager/intern/wm_files_link.c | 114 |
1 files changed, 85 insertions, 29 deletions
diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c index 05c569cbaac..cd6a38cb9a8 100644 --- a/source/blender/windowmanager/intern/wm_files_link.c +++ b/source/blender/windowmanager/intern/wm_files_link.c @@ -59,7 +59,7 @@ #include "BLO_readfile.h" #include "BKE_context.h" -#include "BKE_depsgraph.h" +#include "BKE_layer.h" #include "BKE_library.h" #include "BKE_library_remap.h" #include "BKE_global.h" @@ -69,6 +69,8 @@ #include "BKE_idcode.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" #include "IMB_colormanagement.h" @@ -131,8 +133,8 @@ static short wm_link_append_flag(wmOperator *op) if (RNA_boolean_get(op->ptr, "autoselect")) flag |= FILE_AUTOSELECT; - if (RNA_boolean_get(op->ptr, "active_layer")) - flag |= FILE_ACTIVELAY; + if (RNA_boolean_get(op->ptr, "active_collection")) + flag |= FILE_ACTIVE_COLLECTION; 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")) @@ -211,7 +213,8 @@ static WMLinkAppendDataItem *wm_link_append_data_item_add( return item; } -static void wm_link_do(WMLinkAppendData *lapp_data, ReportList *reports, Main *bmain, Scene *scene, View3D *v3d) +static void wm_link_do( + WMLinkAppendData *lapp_data, ReportList *reports, Main *bmain, Scene *scene, ViewLayer *view_layer) { Main *mainl; BlendHandle *bh; @@ -258,7 +261,7 @@ static void wm_link_do(WMLinkAppendData *lapp_data, ReportList *reports, Main *b continue; } - new_id = BLO_library_link_named_part_ex(mainl, &bh, item->idcode, item->name, flag, scene, v3d); + new_id = BLO_library_link_named_part_ex(mainl, &bh, item->idcode, item->name, flag, scene, view_layer); if (new_id) { /* If the link is successful, clear item's libs 'todo' flags. @@ -268,21 +271,58 @@ static void wm_link_do(WMLinkAppendData *lapp_data, ReportList *reports, Main *b } } - BLO_library_link_end(mainl, &bh, flag, scene, v3d); + BLO_library_link_end(mainl, &bh, flag, scene, view_layer); BLO_blendhandle_close(bh); } } +/** + * Check if an item defined by \a name and \a group can be appended/linked. + * + * \param reports: Optionally report an error when an item can't be appended/linked. + */ +static bool wm_link_append_item_poll( + ReportList *reports, const char *path, const char *group, const char *name, const bool do_append) +{ + short idcode; + + if (!group || !name) { + printf("skipping %s\n", path); + return false; + } + + idcode = BKE_idcode_from_name(group); + + /* XXX For now, we do a nasty exception for workspace, forbid linking them. + * Not nice, ultimately should be solved! */ + if (!BKE_idcode_is_linkable(idcode) && (do_append || idcode != ID_WS)) { + if (reports) { + if (do_append) { + BKE_reportf(reports, RPT_ERROR_INVALID_INPUT, "Can't append data-block '%s' of type '%s'", name, group); + } + else { + BKE_reportf(reports, RPT_ERROR_INVALID_INPUT, "Can't link data-block '%s' of type '%s'", name, group); + } + } + return false; + } + + return true; +} + static int wm_link_append_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); PropertyRNA *prop; WMLinkAppendData *lapp_data; char path[FILE_MAX_LIBEXTRA], root[FILE_MAXDIR], libname[FILE_MAX_LIBEXTRA], relname[FILE_MAX]; char *group, *name; int totfiles = 0; short flag; + bool has_item = false; + bool do_append; RNA_string_get(op->ptr, "filename", relname); RNA_string_get(op->ptr, "directory", root); @@ -320,6 +360,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) } flag = wm_link_append_flag(op); + do_append = (flag & FILE_LINK) == 0; /* sanity checks for flag */ if (scene && scene->id.lib) { @@ -333,8 +374,8 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) /* from here down, no error returns */ - if (scene && RNA_boolean_get(op->ptr, "autoselect")) { - BKE_scene_base_deselect_all(scene); + if (view_layer && RNA_boolean_get(op->ptr, "autoselect")) { + BKE_view_layer_base_deselect_all(view_layer); } /* tag everything, all untagged data can be made local @@ -357,7 +398,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) BLI_join_dirfile(path, sizeof(path), root, relname); if (BLO_library_path_explode(path, libname, &group, &name)) { - if (!group || !name) { + if (!wm_link_append_item_poll(NULL, path, group, name, do_append)) { continue; } @@ -365,6 +406,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) BLI_ghash_insert(libraries, BLI_strdup(libname), SET_INT_IN_POINTER(lib_idx)); lib_idx++; wm_link_append_data_library_add(lapp_data, libname); + has_item = true; } } } @@ -378,8 +420,8 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) if (BLO_library_path_explode(path, libname, &group, &name)) { WMLinkAppendDataItem *item; - if (!group || !name) { - printf("skipping %s\n", path); + + if (!wm_link_append_item_poll(op->reports, path, group, name, do_append)) { continue; } @@ -387,6 +429,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) item = wm_link_append_data_item_add(lapp_data, name, BKE_idcode_from_name(group), NULL); BLI_BITMAP_ENABLE(item->libraries, lib_idx); + has_item = true; } } RNA_END; @@ -399,12 +442,18 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) wm_link_append_data_library_add(lapp_data, libname); item = wm_link_append_data_item_add(lapp_data, name, BKE_idcode_from_name(group), NULL); BLI_BITMAP_ENABLE(item->libraries, 0); + has_item = true; + } + + if (!has_item) { + wm_link_append_data_free(lapp_data); + return OPERATOR_CANCELLED; } /* XXX We'd need re-entrant locking on Main for this to work... */ /* BKE_main_lock(bmain); */ - wm_link_do(lapp_data, op->reports, bmain, scene, CTX_wm_view3d(C)); + wm_link_do(lapp_data, op->reports, bmain, scene, view_layer); /* BKE_main_unlock(bmain); */ @@ -413,7 +462,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) IMB_colormanagement_check_file_config(bmain); /* append, rather than linking */ - if ((flag & FILE_LINK) == 0) { + if (do_append) { const bool set_fake = RNA_boolean_get(op->ptr, "set_fake"); const bool use_recursive = RNA_boolean_get(op->ptr, "use_recursive"); @@ -444,13 +493,17 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) * link into other scenes from this blend file */ BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false); + /* TODO(sergey): Use proper flag for tagging here. */ + + /* TODO (dalai): Temporary solution! + * Ideally we only need to tag the new objects themselves, not the scene. This way we'll avoid flush of + * collection properties to all objects and limit update to the particular object only. + * But afraid first we need to change collection evaluation in DEG according to depsgraph manifesto. + */ + DEG_id_tag_update(&scene->id, 0); + /* recreate dependency graph to include new objects */ - if (scene) { - DAG_scene_relations_rebuild(bmain, scene); - } - - /* free gpu materials, some materials depend on existing objects, such as lamps so freeing correctly refreshes */ - GPU_materials_free(); + DEG_relations_tag_update(bmain); /* XXX TODO: align G.lib with other directory storage (like last opened image etc...) */ BLI_strncpy(G.lib, root, FILE_MAX); @@ -472,8 +525,8 @@ static void wm_link_append_properties_common(wmOperatorType *ot, bool is_link) prop = RNA_def_boolean(ot->srna, "autoselect", true, "Select", "Select new objects"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); - prop = RNA_def_boolean(ot->srna, "active_layer", true, - "Active Layer", "Put new objects on the active layer"); + prop = RNA_def_boolean(ot->srna, "active_collection", true, + "Active Collection", "Put new objects on the active collection"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); prop = RNA_def_boolean(ot->srna, "instance_groups", is_link, "Instance Groups", "Create Dupli-Group instances for each group"); @@ -553,7 +606,7 @@ static int wm_lib_relocate_invoke(bContext *C, wmOperator *op, const wmEvent *UN } static void lib_relocate_do( - Main *bmain, Scene *scene, + Main *bmain, Library *library, WMLinkAppendData *lapp_data, ReportList *reports, const bool do_reload) { ListBase *lbarray[MAX_LIBARRAY]; @@ -561,6 +614,7 @@ static void lib_relocate_do( LinkNode *itemlink; int item_idx; + bool has_item = false; /* Remove all IDs to be reloaded from Main. */ lba_idx = set_listbasepointers(bmain, lbarray); @@ -582,6 +636,7 @@ static void lib_relocate_do( BLI_remlink(lbarray[lba_idx], id); item = wm_link_append_data_item_add(lapp_data, id->name + 2, idcode, id); BLI_BITMAP_SET_ALL(item->libraries, true, lapp_data->num_libraries); + has_item = true; #ifdef PRINT_DEBUG printf("\tdatablock to seek for: %s\n", id->name); @@ -590,6 +645,11 @@ static void lib_relocate_do( } } + if (!has_item) { + /* nothing to relocate */ + return; + } + BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true); /* We do not want any instanciation here! */ @@ -738,10 +798,7 @@ static void lib_relocate_do( BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false); /* recreate dependency graph to include new objects */ - DAG_scene_relations_rebuild(bmain, scene); - - /* free gpu materials, some materials depend on existing objects, such as lamps so freeing correctly refreshes */ - GPU_materials_free(); + DEG_relations_tag_update(bmain); } void WM_lib_reload(Library *lib, bContext *C, ReportList *reports) @@ -761,7 +818,7 @@ void WM_lib_reload(Library *lib, bContext *C, ReportList *reports) wm_link_append_data_library_add(lapp_data, lib->filepath); - lib_relocate_do(CTX_data_main(C), CTX_data_scene(C), lib, lapp_data, reports, true); + lib_relocate_do(CTX_data_main(C), lib, lapp_data, reports, true); wm_link_append_data_free(lapp_data); @@ -778,7 +835,6 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, bool do_reload) if (lib) { Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); PropertyRNA *prop; WMLinkAppendData *lapp_data; @@ -872,7 +928,7 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, bool do_reload) lapp_data->flag |= BLO_LIBLINK_USE_PLACEHOLDERS | BLO_LIBLINK_FORCE_INDIRECT; } - lib_relocate_do(bmain, scene, lib, lapp_data, op->reports, do_reload); + lib_relocate_do(bmain, lib, lapp_data, op->reports, do_reload); wm_link_append_data_free(lapp_data); |