LibOverride: Outliner: Add an operation to override the selected ID and its parents.
This will override all linked data-blocks in the tree branch leading to the selected one.
This commit is contained in:
parent
140b26909e
commit
e3fd60b182
|
@ -54,6 +54,7 @@
|
|||
#include "BKE_context.h"
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_idtype.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_lib_override.h"
|
||||
|
@ -739,22 +740,63 @@ static void id_local_cb(bContext *C,
|
|||
}
|
||||
}
|
||||
|
||||
typedef struct OutlinerLibOverrideData {
|
||||
bool do_hierarchy;
|
||||
} OutlinerLibOverrideData;
|
||||
|
||||
static void id_override_library_cb(bContext *C,
|
||||
ReportList *UNUSED(reports),
|
||||
Scene *UNUSED(scene),
|
||||
TreeElement *UNUSED(te),
|
||||
TreeElement *te,
|
||||
TreeStoreElem *UNUSED(tsep),
|
||||
TreeStoreElem *tselem,
|
||||
void *UNUSED(user_data))
|
||||
void *user_data)
|
||||
{
|
||||
if (ID_IS_OVERRIDABLE_LIBRARY(tselem->id)) {
|
||||
BLI_assert(TSE_IS_REAL_ID(tselem));
|
||||
ID *id_root = tselem->id;
|
||||
|
||||
if (ID_IS_LINKED(id_root) &&
|
||||
(BKE_idtype_get_info_from_id(id_root)->flags & IDTYPE_FLAGS_NO_LIBLINKING) == 0) {
|
||||
Main *bmain = CTX_data_main(C);
|
||||
OutlinerLibOverrideData *data = user_data;
|
||||
const bool do_hierarchy = data->do_hierarchy;
|
||||
|
||||
id_root->tag |= LIB_TAG_DOIT;
|
||||
|
||||
printf("%s: Tagging root id %s\n", __func__, id_root->name);
|
||||
|
||||
/* For now, remapp all local usages of linked ID to local override one here. */
|
||||
BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, true);
|
||||
ID *override_id = BKE_lib_override_library_create_from_id(bmain, tselem->id, true);
|
||||
if (override_id != NULL) {
|
||||
BKE_main_id_clear_newpoins(bmain);
|
||||
ID *id_iter;
|
||||
FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
|
||||
if (ID_IS_LINKED(id_iter)) {
|
||||
id_iter->tag &= ~LIB_TAG_DOIT;
|
||||
}
|
||||
else {
|
||||
id_iter->tag |= LIB_TAG_DOIT;
|
||||
}
|
||||
}
|
||||
FOREACH_MAIN_ID_END;
|
||||
|
||||
if (do_hierarchy) {
|
||||
/* Tag all linked parents in tree hierarchy to be also overridden. */
|
||||
while ((te = te->parent) != NULL) {
|
||||
if (!TSE_IS_REAL_ID(te->store_elem)) {
|
||||
continue;
|
||||
}
|
||||
if (!ID_IS_LINKED(te->store_elem->id)) {
|
||||
break;
|
||||
}
|
||||
te->store_elem->id->tag |= LIB_TAG_DOIT;
|
||||
printf("%s: Tagging parent id %s\n", __func__, te->store_elem->id->name);
|
||||
}
|
||||
BKE_lib_override_dependencies_tag(bmain, id_root, LIB_TAG_DOIT, true);
|
||||
BKE_lib_override_library_create_from_tag(bmain);
|
||||
}
|
||||
else if (ID_IS_OVERRIDABLE_LIBRARY(id_root)) {
|
||||
BKE_lib_override_library_create_from_id(bmain, id_root, true);
|
||||
}
|
||||
|
||||
BKE_main_id_clear_newpoins(bmain);
|
||||
BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
|
||||
}
|
||||
}
|
||||
|
@ -1326,8 +1368,8 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
else if (event == OL_OP_REMAP) {
|
||||
outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_remap_cb, NULL);
|
||||
/* No undo push here, operator does it itself (since it's a modal one, the op_undo_depth trick
|
||||
* does not work here). */
|
||||
/* No undo push here, operator does it itself (since it's a modal one, the op_undo_depth
|
||||
* trick does not work here). */
|
||||
}
|
||||
else if (event == OL_OP_LOCALIZED) { /* disabled, see above enum (ton) */
|
||||
outliner_do_object_operation(C, op->reports, scene, soops, &soops->tree, id_local_cb);
|
||||
|
@ -1508,6 +1550,7 @@ typedef enum eOutlinerIdOpTypes {
|
|||
OUTLINER_IDOP_UNLINK,
|
||||
OUTLINER_IDOP_LOCAL,
|
||||
OUTLINER_IDOP_OVERRIDE_LIBRARY,
|
||||
OUTLINER_IDOP_OVERRIDE_LIBRARY_HIERARCHY,
|
||||
OUTLINER_IDOP_SINGLE,
|
||||
OUTLINER_IDOP_DELETE,
|
||||
OUTLINER_IDOP_REMAP,
|
||||
|
@ -1531,6 +1574,11 @@ static const EnumPropertyItem prop_id_op_types[] = {
|
|||
0,
|
||||
"Add Library Override",
|
||||
"Add a local override of this linked data-block"},
|
||||
{OUTLINER_IDOP_OVERRIDE_LIBRARY_HIERARCHY,
|
||||
"OVERRIDE_LIBRARY_HIERARCHY",
|
||||
0,
|
||||
"Add Library Override Hierarchy",
|
||||
"Add a local override of this linked data-block, and its hierarchy of dependencies"},
|
||||
{OUTLINER_IDOP_SINGLE, "SINGLE", 0, "Make Single User", ""},
|
||||
{OUTLINER_IDOP_DELETE, "DELETE", ICON_X, "Delete", ""},
|
||||
{OUTLINER_IDOP_REMAP,
|
||||
|
@ -1678,8 +1726,25 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
case OUTLINER_IDOP_OVERRIDE_LIBRARY: {
|
||||
/* make local */
|
||||
outliner_do_libdata_operation(
|
||||
C, op->reports, scene, soops, &soops->tree, id_override_library_cb, NULL);
|
||||
outliner_do_libdata_operation(C,
|
||||
op->reports,
|
||||
scene,
|
||||
soops,
|
||||
&soops->tree,
|
||||
id_override_library_cb,
|
||||
&(OutlinerLibOverrideData){.do_hierarchy = false});
|
||||
ED_undo_push(C, "Overridden Data");
|
||||
break;
|
||||
}
|
||||
case OUTLINER_IDOP_OVERRIDE_LIBRARY_HIERARCHY: {
|
||||
/* make local */
|
||||
outliner_do_libdata_operation(C,
|
||||
op->reports,
|
||||
scene,
|
||||
soops,
|
||||
&soops->tree,
|
||||
id_override_library_cb,
|
||||
&(OutlinerLibOverrideData){.do_hierarchy = true});
|
||||
ED_undo_push(C, "Overridden Data");
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue