Merge branch 'blender-v3.3-release'
This commit is contained in:
commit
5d4d5a2162
|
@ -1544,7 +1544,7 @@ uiButViewItem *ui_block_view_find_matching_view_item_but_in_old_block(
|
|||
|
||||
struct uiListType *UI_UL_cache_file_layers(void);
|
||||
|
||||
struct ID *ui_template_id_liboverride_hierarchy_create(struct bContext *C,
|
||||
struct ID *ui_template_id_liboverride_hierarchy_make(struct bContext *C,
|
||||
struct Main *bmain,
|
||||
struct ID *owner_id,
|
||||
struct ID *id,
|
||||
|
|
|
@ -801,12 +801,12 @@ static bool override_idtemplate_poll(bContext *C, const bool is_create_op)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool override_idtemplate_create_poll(bContext *C)
|
||||
static bool override_idtemplate_make_poll(bContext *C)
|
||||
{
|
||||
return override_idtemplate_poll(C, true);
|
||||
}
|
||||
|
||||
static int override_idtemplate_create_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
static int override_idtemplate_make_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
ID *owner_id, *id;
|
||||
PointerRNA owner_ptr;
|
||||
|
@ -816,42 +816,49 @@ static int override_idtemplate_create_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
ID *id_override = ui_template_id_liboverride_hierarchy_create(
|
||||
ID *id_override = ui_template_id_liboverride_hierarchy_make(
|
||||
C, CTX_data_main(C), owner_id, id, NULL);
|
||||
|
||||
if (id_override == NULL) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if (ID_IS_OVERRIDE_LIBRARY_REAL(owner_id)) {
|
||||
PointerRNA idptr;
|
||||
/* `idptr` is re-assigned to owner property to ensure proper updates etc. Here we also use it
|
||||
* to ensure remapping of the owner property from the linked data to the newly created
|
||||
* liboverride (note that in theory this remapping has already been done by code above), but
|
||||
* only in case owner ID was already an existing liboverride.
|
||||
*
|
||||
* Otherwise, owner ID will also have been overridden, and remapped already to use it's
|
||||
* override of the data too. */
|
||||
PointerRNA idptr;
|
||||
/* `idptr` is re-assigned to owner property to ensure proper updates etc. Here we also use it
|
||||
* to ensure remapping of the owner property from the linked data to the newly created
|
||||
* liboverride (note that in theory this remapping has already been done by code above), but
|
||||
* only in case owner ID was already local ID (override or pure local data).
|
||||
*
|
||||
* Otherwise, owner ID will also have been overridden, and remapped already to use it's
|
||||
* override of the data too. */
|
||||
if (!ID_IS_LINKED(owner_id)) {
|
||||
RNA_id_pointer_create(id_override, &idptr);
|
||||
RNA_property_pointer_set(&owner_ptr, prop, idptr, NULL);
|
||||
RNA_property_update(C, &owner_ptr, prop);
|
||||
}
|
||||
RNA_property_update(C, &owner_ptr, prop);
|
||||
|
||||
/* 'Security' extra tagging, since this process may also affect the owner ID and not only the
|
||||
* used ID, relying on the property update code only is not always enough. */
|
||||
DEG_id_tag_update(&CTX_data_scene(C)->id, ID_RECALC_BASE_FLAGS | ID_RECALC_COPY_ON_WRITE);
|
||||
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
||||
WM_event_add_notifier(C, NC_WM | ND_LIB_OVERRIDE_CHANGED, NULL);
|
||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void UI_OT_override_idtemplate_create(wmOperatorType *ot)
|
||||
static void UI_OT_override_idtemplate_make(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Create Library Override";
|
||||
ot->idname = "UI_OT_override_idtemplate_create";
|
||||
ot->name = "Make Library Override";
|
||||
ot->idname = "UI_OT_override_idtemplate_make";
|
||||
ot->description =
|
||||
"Create a local override of the selected linked data-block, and its hierarchy of "
|
||||
"dependencies";
|
||||
|
||||
/* callbacks */
|
||||
ot->poll = override_idtemplate_create_poll;
|
||||
ot->exec = override_idtemplate_create_exec;
|
||||
ot->poll = override_idtemplate_make_poll;
|
||||
ot->exec = override_idtemplate_make_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_UNDO;
|
||||
|
@ -884,6 +891,9 @@ static int override_idtemplate_reset_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
RNA_property_pointer_set(&owner_ptr, prop, idptr, NULL);
|
||||
RNA_property_update(C, &owner_ptr, prop);
|
||||
|
||||
/* No need for 'security' extra tagging here, since this process will never affect the owner ID.
|
||||
*/
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
|
@ -922,24 +932,45 @@ static int override_idtemplate_clear_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
}
|
||||
|
||||
Main *bmain = CTX_data_main(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ID *id_new = id;
|
||||
|
||||
if (BKE_lib_override_library_is_hierarchy_leaf(bmain, id)) {
|
||||
id_new = id->override_library->reference;
|
||||
bool do_remap_active = false;
|
||||
if (OBACT(view_layer) == (Object *)id) {
|
||||
BLI_assert(GS(id->name) == ID_OB);
|
||||
BLI_assert(GS(id_new->name) == ID_OB);
|
||||
do_remap_active = true;
|
||||
}
|
||||
BKE_libblock_remap(bmain, id, id_new, ID_REMAP_SKIP_INDIRECT_USAGE);
|
||||
if (do_remap_active) {
|
||||
Object *ref_object = (Object *)id_new;
|
||||
Base *basact = BKE_view_layer_base_find(view_layer, ref_object);
|
||||
if (basact != NULL) {
|
||||
view_layer->basact = basact;
|
||||
}
|
||||
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
|
||||
}
|
||||
BKE_id_delete(bmain, id);
|
||||
}
|
||||
else {
|
||||
BKE_lib_override_library_id_reset(bmain, id, true);
|
||||
}
|
||||
|
||||
PointerRNA idptr;
|
||||
/* `idptr` is re-assigned to owner property to ensure proper updates etc. Here we also use it to
|
||||
* ensure remapping of the owner property from the linked data to the newly created liboverride
|
||||
* (note that in theory this remapping has already been done by code above). */
|
||||
RNA_id_pointer_create(id_new, &idptr);
|
||||
RNA_property_pointer_set(&owner_ptr, prop, idptr, NULL);
|
||||
/* Here the affected ID may remain the same, or be replaced by its linked reference. In either
|
||||
* case, the owner ID remains unchanged, and remapping is already handled by internal code, so
|
||||
* calling `RNA_property_update` on it is enough to ensure proper notifiers are sent. */
|
||||
RNA_property_update(C, &owner_ptr, prop);
|
||||
|
||||
/* 'Security' extra tagging, since this process may also affect the owner ID and not only the
|
||||
* used ID, relying on the property update code only is not always enough. */
|
||||
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS | ID_RECALC_COPY_ON_WRITE);
|
||||
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
||||
WM_event_add_notifier(C, NC_WM | ND_LIB_OVERRIDE_CHANGED, NULL);
|
||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
|
@ -979,7 +1010,7 @@ static bool override_idtemplate_menu_poll(const bContext *C_const, MenuType *UNU
|
|||
static void override_idtemplate_menu_draw(const bContext *UNUSED(C), Menu *menu)
|
||||
{
|
||||
uiLayout *layout = menu->layout;
|
||||
uiItemO(layout, IFACE_("Make"), ICON_NONE, "UI_OT_override_idtemplate_create");
|
||||
uiItemO(layout, IFACE_("Make"), ICON_NONE, "UI_OT_override_idtemplate_make");
|
||||
uiItemO(layout, IFACE_("Reset"), ICON_NONE, "UI_OT_override_idtemplate_reset");
|
||||
uiItemO(layout, IFACE_("Clear"), ICON_NONE, "UI_OT_override_idtemplate_clear");
|
||||
}
|
||||
|
@ -2501,7 +2532,7 @@ void ED_operatortypes_ui(void)
|
|||
|
||||
WM_operatortype_append(UI_OT_override_type_set_button);
|
||||
WM_operatortype_append(UI_OT_override_remove_button);
|
||||
WM_operatortype_append(UI_OT_override_idtemplate_create);
|
||||
WM_operatortype_append(UI_OT_override_idtemplate_make);
|
||||
WM_operatortype_append(UI_OT_override_idtemplate_reset);
|
||||
WM_operatortype_append(UI_OT_override_idtemplate_clear);
|
||||
override_idtemplate_menu();
|
||||
|
|
|
@ -653,7 +653,7 @@ static void template_id_liboverride_hierarchy_collections_tag_recursive(
|
|||
}
|
||||
}
|
||||
|
||||
ID *ui_template_id_liboverride_hierarchy_create(
|
||||
ID *ui_template_id_liboverride_hierarchy_make(
|
||||
bContext *C, Main *bmain, ID *owner_id, ID *id, const char **r_undo_push_label)
|
||||
{
|
||||
const char *undo_push_label;
|
||||
|
@ -872,27 +872,27 @@ ID *ui_template_id_liboverride_hierarchy_create(
|
|||
return id_override;
|
||||
}
|
||||
|
||||
static void template_id_liboverride_hierarchy_create(bContext *C,
|
||||
Main *bmain,
|
||||
TemplateID *template_ui,
|
||||
PointerRNA *idptr,
|
||||
const char **r_undo_push_label)
|
||||
static void template_id_liboverride_hierarchy_make(bContext *C,
|
||||
Main *bmain,
|
||||
TemplateID *template_ui,
|
||||
PointerRNA *idptr,
|
||||
const char **r_undo_push_label)
|
||||
{
|
||||
ID *id = idptr->data;
|
||||
ID *owner_id = template_ui->ptr.owner_id;
|
||||
|
||||
ID *id_override = ui_template_id_liboverride_hierarchy_create(
|
||||
ID *id_override = ui_template_id_liboverride_hierarchy_make(
|
||||
C, bmain, owner_id, id, r_undo_push_label);
|
||||
|
||||
if (id_override != NULL) {
|
||||
/* Given `idptr` is re-assigned to owner property by caller to ensure proper updates etc. Here
|
||||
* we also use it to ensure remapping of the owner property from the linked data to the newly
|
||||
* created liboverride (note that in theory this remapping has already been done by code
|
||||
* above), but only in case owner ID was already an existing liboverride.
|
||||
/* `idptr` is re-assigned to owner property to ensure proper updates etc. Here we also use it
|
||||
* to ensure remapping of the owner property from the linked data to the newly created
|
||||
* liboverride (note that in theory this remapping has already been done by code above), but
|
||||
* only in case owner ID was already local ID (override or pure local data).
|
||||
*
|
||||
* Otherwise, owner ID will also have been overridden, and remapped already to use
|
||||
* it's override of the data too. */
|
||||
if (ID_IS_OVERRIDE_LIBRARY_REAL(owner_id)) {
|
||||
* Otherwise, owner ID will also have been overridden, and remapped already to use it's
|
||||
* override of the data too. */
|
||||
if (!ID_IS_LINKED(owner_id)) {
|
||||
RNA_id_pointer_create(id_override, idptr);
|
||||
}
|
||||
}
|
||||
|
@ -950,8 +950,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
|
|||
if (id) {
|
||||
Main *bmain = CTX_data_main(C);
|
||||
if (CTX_wm_window(C)->eventstate->modifier & KM_SHIFT) {
|
||||
template_id_liboverride_hierarchy_create(
|
||||
C, bmain, template_ui, &idptr, &undo_push_label);
|
||||
template_id_liboverride_hierarchy_make(C, bmain, template_ui, &idptr, &undo_push_label);
|
||||
}
|
||||
else {
|
||||
if (BKE_lib_id_make_local(bmain, id, 0)) {
|
||||
|
@ -972,8 +971,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
|
|||
if (id && ID_IS_OVERRIDE_LIBRARY(id)) {
|
||||
Main *bmain = CTX_data_main(C);
|
||||
if (CTX_wm_window(C)->eventstate->modifier & KM_SHIFT) {
|
||||
template_id_liboverride_hierarchy_create(
|
||||
C, bmain, template_ui, &idptr, &undo_push_label);
|
||||
template_id_liboverride_hierarchy_make(C, bmain, template_ui, &idptr, &undo_push_label);
|
||||
}
|
||||
else {
|
||||
BKE_lib_override_library_make_local(id);
|
||||
|
|
|
@ -2420,6 +2420,8 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
|
|||
|
||||
DEG_id_tag_update(&CTX_data_scene(C)->id, ID_RECALC_BASE_FLAGS | ID_RECALC_COPY_ON_WRITE);
|
||||
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
||||
WM_event_add_notifier(C, NC_WM | ND_LIB_OVERRIDE_CHANGED, NULL);
|
||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
|
||||
|
||||
return success ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
|
||||
}
|
||||
|
@ -2552,7 +2554,8 @@ static int reset_override_library_exec(bContext *C, wmOperator *UNUSED(op))
|
|||
}
|
||||
FOREACH_SELECTED_OBJECT_END;
|
||||
|
||||
WM_event_add_notifier(C, NC_WM | ND_DATACHANGED, NULL);
|
||||
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
||||
WM_event_add_notifier(C, NC_WM | ND_LIB_OVERRIDE_CHANGED, NULL);
|
||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -2582,26 +2585,49 @@ void OBJECT_OT_reset_override_library(wmOperatorType *ot)
|
|||
static int clear_override_library_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
LinkNode *todo_objects = NULL, *todo_object_iter;
|
||||
|
||||
/* Make already existing selected liboverrides editable. */
|
||||
FOREACH_SELECTED_OBJECT_BEGIN (CTX_data_view_layer(C), CTX_wm_view3d(C), ob_iter) {
|
||||
FOREACH_SELECTED_OBJECT_BEGIN (view_layer, CTX_wm_view3d(C), ob_iter) {
|
||||
if (ID_IS_LINKED(ob_iter)) {
|
||||
continue;
|
||||
}
|
||||
BLI_linklist_prepend_alloca(&todo_objects, ob_iter);
|
||||
}
|
||||
FOREACH_SELECTED_OBJECT_END;
|
||||
|
||||
for (todo_object_iter = todo_objects; todo_object_iter != NULL;
|
||||
todo_object_iter = todo_object_iter->next) {
|
||||
Object *ob_iter = todo_object_iter->link;
|
||||
if (BKE_lib_override_library_is_hierarchy_leaf(bmain, &ob_iter->id)) {
|
||||
bool do_remap_active = false;
|
||||
if (OBACT(view_layer) == ob_iter) {
|
||||
do_remap_active = true;
|
||||
}
|
||||
BKE_libblock_remap(bmain,
|
||||
&ob_iter->id,
|
||||
ob_iter->id.override_library->reference,
|
||||
ID_REMAP_SKIP_INDIRECT_USAGE);
|
||||
if (do_remap_active) {
|
||||
Object *ref_object = ob_iter->id.override_library->reference;
|
||||
Base *basact = BKE_view_layer_base_find(view_layer, ref_object);
|
||||
if (basact != NULL) {
|
||||
view_layer->basact = basact;
|
||||
}
|
||||
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
|
||||
}
|
||||
BKE_id_delete(bmain, &ob_iter->id);
|
||||
}
|
||||
else {
|
||||
BKE_lib_override_library_id_reset(bmain, &ob_iter->id, true);
|
||||
}
|
||||
}
|
||||
FOREACH_SELECTED_OBJECT_END;
|
||||
|
||||
WM_event_add_notifier(C, NC_WM | ND_DATACHANGED, NULL);
|
||||
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS | ID_RECALC_COPY_ON_WRITE);
|
||||
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
||||
WM_event_add_notifier(C, NC_WM | ND_LIB_OVERRIDE_CHANGED, NULL);
|
||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
|
|
|
@ -1274,24 +1274,70 @@ static void id_override_library_reset_fn(bContext *C,
|
|||
OutlinerLibOverrideData *data = static_cast<OutlinerLibOverrideData *>(user_data);
|
||||
const bool do_hierarchy = data->do_hierarchy;
|
||||
|
||||
if (ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) {
|
||||
Main *bmain = CTX_data_main(C);
|
||||
if (!ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) {
|
||||
CLOG_WARN(&LOG, "Could not reset library override of data block '%s'", id_root->name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (do_hierarchy) {
|
||||
BKE_lib_override_library_id_hierarchy_reset(bmain, id_root, false);
|
||||
}
|
||||
else {
|
||||
BKE_lib_override_library_id_reset(bmain, id_root, false);
|
||||
}
|
||||
Main *bmain = CTX_data_main(C);
|
||||
|
||||
WM_event_add_notifier(C, NC_WM | ND_DATACHANGED, nullptr);
|
||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, nullptr);
|
||||
if (do_hierarchy) {
|
||||
BKE_lib_override_library_id_hierarchy_reset(bmain, id_root, false);
|
||||
}
|
||||
else {
|
||||
CLOG_WARN(&LOG, "Could not reset library override of data block '%s'", id_root->name);
|
||||
BKE_lib_override_library_id_reset(bmain, id_root, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void id_override_library_clear_single_fn(bContext *C,
|
||||
ReportList *reports,
|
||||
Scene *scene,
|
||||
TreeElement *UNUSED(te),
|
||||
TreeStoreElem *UNUSED(tsep),
|
||||
TreeStoreElem *tselem,
|
||||
void *UNUSED(user_data))
|
||||
{
|
||||
BLI_assert(TSE_IS_REAL_ID(tselem));
|
||||
Main *bmain = CTX_data_main(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
ID *id = tselem->id;
|
||||
|
||||
if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
|
||||
BKE_reportf(reports,
|
||||
RPT_WARNING,
|
||||
"Cannot clear embedded library override id '%s', only overrides of real "
|
||||
"data-blocks can be directly deleted",
|
||||
id->name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If given ID is not using any other override (it's a 'leaf' in the override hierarchy),
|
||||
* delete it and remap its usages to its linked reference. Otherwise, keep it as a reset system
|
||||
* override. */
|
||||
if (BKE_lib_override_library_is_hierarchy_leaf(bmain, id)) {
|
||||
bool do_remap_active = false;
|
||||
if (OBACT(view_layer) == reinterpret_cast<Object *>(id)) {
|
||||
BLI_assert(GS(id->name) == ID_OB);
|
||||
do_remap_active = true;
|
||||
}
|
||||
BKE_libblock_remap(bmain, id, id->override_library->reference, ID_REMAP_SKIP_INDIRECT_USAGE);
|
||||
if (do_remap_active) {
|
||||
Object *ref_object = reinterpret_cast<Object *>(id->override_library->reference);
|
||||
Base *basact = BKE_view_layer_base_find(view_layer, ref_object);
|
||||
if (basact != nullptr) {
|
||||
view_layer->basact = basact;
|
||||
}
|
||||
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
|
||||
}
|
||||
BKE_id_delete(bmain, id);
|
||||
}
|
||||
else {
|
||||
BKE_lib_override_library_id_reset(bmain, id, true);
|
||||
}
|
||||
|
||||
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS | ID_RECALC_COPY_ON_WRITE);
|
||||
}
|
||||
|
||||
static void id_override_library_resync_fn(bContext *UNUSED(C),
|
||||
ReportList *UNUSED(reports),
|
||||
Scene *UNUSED(scene),
|
||||
|
@ -1340,13 +1386,13 @@ static void id_override_library_resync_hierarchy_process(bContext *C,
|
|||
WM_event_add_notifier(C, NC_WINDOW, nullptr);
|
||||
}
|
||||
|
||||
static void id_override_library_clear_hierarchy_fn(bContext *UNUSED(C),
|
||||
ReportList *UNUSED(reports),
|
||||
Scene *UNUSED(scene),
|
||||
TreeElement *UNUSED(te),
|
||||
TreeStoreElem *UNUSED(tsep),
|
||||
TreeStoreElem *tselem,
|
||||
void *user_data)
|
||||
static void id_override_library_delete_hierarchy_fn(bContext *UNUSED(C),
|
||||
ReportList *UNUSED(reports),
|
||||
Scene *UNUSED(scene),
|
||||
TreeElement *UNUSED(te),
|
||||
TreeStoreElem *UNUSED(tsep),
|
||||
TreeStoreElem *tselem,
|
||||
void *user_data)
|
||||
{
|
||||
OutlinerLibOverrideData *data = reinterpret_cast<OutlinerLibOverrideData *>(user_data);
|
||||
|
||||
|
@ -1366,52 +1412,15 @@ static void id_override_library_clear_hierarchy_fn(bContext *UNUSED(C),
|
|||
}
|
||||
|
||||
/* Clear (delete) a hierarchy of library overrides. */
|
||||
static void id_override_library_clear_hierarchy_process(bContext *C,
|
||||
ReportList *UNUSED(reports),
|
||||
OutlinerLibOverrideData &data)
|
||||
static void id_override_library_delete_hierarchy_process(bContext *C,
|
||||
ReportList *UNUSED(reports),
|
||||
OutlinerLibOverrideData &data)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
|
||||
for (auto &&id_hierarchy_root : data.id_hierarchy_roots.keys()) {
|
||||
BKE_lib_override_library_delete(bmain, id_hierarchy_root);
|
||||
}
|
||||
|
||||
WM_event_add_notifier(C, NC_WINDOW, nullptr);
|
||||
}
|
||||
|
||||
static void id_override_library_clear_single_fn(bContext *C,
|
||||
ReportList *reports,
|
||||
Scene *UNUSED(scene),
|
||||
TreeElement *UNUSED(te),
|
||||
TreeStoreElem *UNUSED(tsep),
|
||||
TreeStoreElem *tselem,
|
||||
void *UNUSED(user_data))
|
||||
{
|
||||
BLI_assert(TSE_IS_REAL_ID(tselem));
|
||||
Main *bmain = CTX_data_main(C);
|
||||
ID *id = tselem->id;
|
||||
|
||||
if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
|
||||
BKE_reportf(reports,
|
||||
RPT_WARNING,
|
||||
"Cannot clear embedded library override id '%s', only overrides of real "
|
||||
"data-blocks can be directly deleted",
|
||||
id->name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If given ID is not using any other override (it's a 'leaf' in the override hierarchy),
|
||||
* delete it and remap its usages to its linked reference. Otherwise, keep it as a reset system
|
||||
* override. */
|
||||
if (BKE_lib_override_library_is_hierarchy_leaf(bmain, id)) {
|
||||
BKE_libblock_remap(bmain, id, id->override_library->reference, ID_REMAP_SKIP_INDIRECT_USAGE);
|
||||
BKE_id_delete(bmain, id);
|
||||
}
|
||||
else {
|
||||
BKE_lib_override_library_id_reset(bmain, id, true);
|
||||
}
|
||||
|
||||
WM_event_add_notifier(C, NC_WINDOW, nullptr);
|
||||
}
|
||||
|
||||
static void id_fake_user_set_fn(bContext *UNUSED(C),
|
||||
|
@ -1785,11 +1794,11 @@ static int outliner_liboverride_operation_exec(bContext *C, wmOperator *op)
|
|||
op->reports,
|
||||
scene,
|
||||
space_outliner,
|
||||
id_override_library_clear_hierarchy_fn,
|
||||
id_override_library_delete_hierarchy_fn,
|
||||
OUTLINER_LIB_SELECTIONSET_SELECTED,
|
||||
nullptr);
|
||||
|
||||
id_override_library_clear_hierarchy_process(C, op->reports, override_data);
|
||||
id_override_library_delete_hierarchy_process(C, op->reports, override_data);
|
||||
|
||||
ED_undo_push(C, "Delete Overridden Data Hierarchy");
|
||||
break;
|
||||
|
@ -1799,11 +1808,9 @@ static int outliner_liboverride_operation_exec(bContext *C, wmOperator *op)
|
|||
break;
|
||||
}
|
||||
|
||||
/* wrong notifier still... */
|
||||
WM_event_add_notifier(C, NC_ID | NA_EDITED, nullptr);
|
||||
|
||||
/* XXX: this is just so that outliner is always up to date. */
|
||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_OUTLINER, nullptr);
|
||||
WM_event_add_notifier(C, NC_WINDOW, nullptr);
|
||||
WM_event_add_notifier(C, NC_WM | ND_LIB_OVERRIDE_CHANGED, nullptr);
|
||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, nullptr);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue