LibOverride: Add option to Hierarchy Creation to get all data user-editable by default.
Avoids having to manually enable data-blocks for user-edition when you do not care about what should be edited by whom. Similar to default behavior before introduction of system overrides (aka non-user-editable overrides).
This commit is contained in:
parent
019681b984
commit
a89f829f12
Notes:
blender-bot
2023-02-14 04:07:50 +01:00
Referenced by issue #99256, Regression: Meta balls segfaulting copy-to-selected
|
@ -2295,6 +2295,8 @@ class VIEW3D_MT_object_relations(Menu):
|
|||
layout = self.layout
|
||||
|
||||
layout.operator("object.make_override_library", text="Make Library Override...")
|
||||
layout.operator("object.make_override_library",
|
||||
text="Make Library Override - Fully Editable...").do_fully_editable=True
|
||||
|
||||
layout.operator("object.make_dupli_face")
|
||||
|
||||
|
|
|
@ -116,6 +116,8 @@ struct ID *BKE_lib_override_library_create_from_id(struct Main *bmain,
|
|||
* \param do_no_main: Create the new override data outside of Main database.
|
||||
* Used for resyncing of linked overrides.
|
||||
*
|
||||
* \param do_fully_editable: if true, tag all created overrides as user-editable by default.
|
||||
*
|
||||
* \return \a true on success, \a false otherwise.
|
||||
*/
|
||||
bool BKE_lib_override_library_create_from_tag(struct Main *bmain,
|
||||
|
@ -123,7 +125,8 @@ bool BKE_lib_override_library_create_from_tag(struct Main *bmain,
|
|||
const struct ID *id_root_reference,
|
||||
struct ID *id_hierarchy_root,
|
||||
const struct ID *id_hierarchy_root_reference,
|
||||
bool do_no_main);
|
||||
bool do_no_main,
|
||||
const bool do_fully_editable);
|
||||
/**
|
||||
* Advanced 'smart' function to create fully functional overrides.
|
||||
*
|
||||
|
@ -154,6 +157,8 @@ bool BKE_lib_override_library_create_from_tag(struct Main *bmain,
|
|||
*
|
||||
* \param r_id_root_override: if not NULL, the override generated for the given \a id_root.
|
||||
*
|
||||
* \param do_fully_editable: if true, tag all created overrides as user-editable by default.
|
||||
*
|
||||
* \return true if override was successfully created.
|
||||
*/
|
||||
bool BKE_lib_override_library_create(struct Main *bmain,
|
||||
|
@ -163,7 +168,8 @@ bool BKE_lib_override_library_create(struct Main *bmain,
|
|||
struct ID *id_root_reference,
|
||||
struct ID *id_hierarchy_root_reference,
|
||||
struct ID *id_instance_hint,
|
||||
struct ID **r_id_root_override);
|
||||
struct ID **r_id_root_override,
|
||||
const bool do_fully_editable);
|
||||
/**
|
||||
* Create a library override template.
|
||||
*/
|
||||
|
|
|
@ -398,7 +398,8 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain,
|
|||
const ID *id_root_reference,
|
||||
ID *id_hierarchy_root,
|
||||
const ID *id_hierarchy_root_reference,
|
||||
const bool do_no_main)
|
||||
const bool do_no_main,
|
||||
const bool do_fully_editable)
|
||||
{
|
||||
BLI_assert(id_root_reference != NULL && ID_IS_LINKED(id_root_reference));
|
||||
/* If we do not have any hierarchy root given, then the root reference must be tagged for
|
||||
|
@ -464,6 +465,9 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain,
|
|||
success = false;
|
||||
break;
|
||||
}
|
||||
if (do_fully_editable) {
|
||||
reference_id->newid->override_library->flag &= ~IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED;
|
||||
}
|
||||
}
|
||||
/* We also tag the new IDs so that in next step we can remap their pointers too. */
|
||||
reference_id->newid->tag |= LIB_TAG_DOIT;
|
||||
|
@ -993,7 +997,8 @@ static bool lib_override_library_create_do(Main *bmain,
|
|||
Scene *scene,
|
||||
Library *owner_library,
|
||||
ID *id_root_reference,
|
||||
ID *id_hierarchy_root_reference)
|
||||
ID *id_hierarchy_root_reference,
|
||||
const bool do_fully_editable)
|
||||
{
|
||||
BKE_main_relations_create(bmain, 0);
|
||||
LibOverrideGroupTagData data = {.bmain = bmain,
|
||||
|
@ -1017,12 +1022,22 @@ static bool lib_override_library_create_do(Main *bmain,
|
|||
BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_hierarchy_root_reference));
|
||||
BLI_assert(id_hierarchy_root_reference->override_library->reference->lib ==
|
||||
id_root_reference->lib);
|
||||
success = BKE_lib_override_library_create_from_tag(
|
||||
bmain, owner_library, id_root_reference, id_hierarchy_root_reference, NULL, false);
|
||||
success = BKE_lib_override_library_create_from_tag(bmain,
|
||||
owner_library,
|
||||
id_root_reference,
|
||||
id_hierarchy_root_reference,
|
||||
NULL,
|
||||
false,
|
||||
do_fully_editable);
|
||||
}
|
||||
else {
|
||||
success = BKE_lib_override_library_create_from_tag(
|
||||
bmain, owner_library, id_root_reference, NULL, id_hierarchy_root_reference, false);
|
||||
success = BKE_lib_override_library_create_from_tag(bmain,
|
||||
owner_library,
|
||||
id_root_reference,
|
||||
NULL,
|
||||
id_hierarchy_root_reference,
|
||||
false,
|
||||
do_fully_editable);
|
||||
}
|
||||
|
||||
return success;
|
||||
|
@ -1180,7 +1195,8 @@ bool BKE_lib_override_library_create(Main *bmain,
|
|||
ID *id_root_reference,
|
||||
ID *id_hierarchy_root_reference,
|
||||
ID *id_instance_hint,
|
||||
ID **r_id_root_override)
|
||||
ID **r_id_root_override,
|
||||
const bool do_fully_editable)
|
||||
{
|
||||
if (r_id_root_override != NULL) {
|
||||
*r_id_root_override = NULL;
|
||||
|
@ -1190,8 +1206,12 @@ bool BKE_lib_override_library_create(Main *bmain,
|
|||
id_hierarchy_root_reference = id_root_reference;
|
||||
}
|
||||
|
||||
const bool success = lib_override_library_create_do(
|
||||
bmain, scene, owner_library, id_root_reference, id_hierarchy_root_reference);
|
||||
const bool success = lib_override_library_create_do(bmain,
|
||||
scene,
|
||||
owner_library,
|
||||
id_root_reference,
|
||||
id_hierarchy_root_reference,
|
||||
do_fully_editable);
|
||||
|
||||
if (!success) {
|
||||
return success;
|
||||
|
@ -1680,7 +1700,13 @@ static bool lib_override_library_resync(Main *bmain,
|
|||
* override IDs (including within the old overrides themselves, since those are tagged too
|
||||
* above). */
|
||||
const bool success = BKE_lib_override_library_create_from_tag(
|
||||
bmain, NULL, id_root_reference, id_root->override_library->hierarchy_root, NULL, true);
|
||||
bmain,
|
||||
NULL,
|
||||
id_root_reference,
|
||||
id_root->override_library->hierarchy_root,
|
||||
NULL,
|
||||
true,
|
||||
false);
|
||||
|
||||
if (!success) {
|
||||
BLI_ghash_free(linkedref_to_old_override, NULL, NULL);
|
||||
|
|
|
@ -82,7 +82,7 @@ bool BKE_lib_override_library_proxy_convert(Main *bmain,
|
|||
FOREACH_MAIN_ID_END;
|
||||
|
||||
return BKE_lib_override_library_create(
|
||||
bmain, scene, view_layer, ob_proxy->id.lib, id_root, id_root, id_instance_hint, NULL);
|
||||
bmain, scene, view_layer, ob_proxy->id.lib, id_root, id_root, id_instance_hint, NULL, false);
|
||||
}
|
||||
|
||||
static void lib_override_library_proxy_convert_do(Main *bmain,
|
||||
|
|
|
@ -742,7 +742,7 @@ static void template_id_liboverride_hierarchy_create(bContext *C,
|
|||
object_active->id.tag |= LIB_TAG_DOIT;
|
||||
}
|
||||
BKE_lib_override_library_create(
|
||||
bmain, scene, view_layer, NULL, id, &collection_active->id, NULL, &id_override);
|
||||
bmain, scene, view_layer, NULL, id, &collection_active->id, NULL, &id_override, false);
|
||||
}
|
||||
else if (object_active != NULL && !ID_IS_LINKED(object_active) &&
|
||||
&object_active->instance_collection->id == id) {
|
||||
|
@ -754,7 +754,8 @@ static void template_id_liboverride_hierarchy_create(bContext *C,
|
|||
id,
|
||||
&object_active->id,
|
||||
&object_active->id,
|
||||
&id_override);
|
||||
&id_override,
|
||||
false);
|
||||
}
|
||||
break;
|
||||
case ID_OB:
|
||||
|
@ -765,7 +766,7 @@ static void template_id_liboverride_hierarchy_create(bContext *C,
|
|||
object_active->id.tag |= LIB_TAG_DOIT;
|
||||
}
|
||||
BKE_lib_override_library_create(
|
||||
bmain, scene, view_layer, NULL, id, &collection_active->id, NULL, &id_override);
|
||||
bmain, scene, view_layer, NULL, id, &collection_active->id, NULL, &id_override, false);
|
||||
}
|
||||
break;
|
||||
case ID_ME:
|
||||
|
@ -787,13 +788,20 @@ static void template_id_liboverride_hierarchy_create(bContext *C,
|
|||
if (object_active != NULL) {
|
||||
object_active->id.tag |= LIB_TAG_DOIT;
|
||||
}
|
||||
BKE_lib_override_library_create(
|
||||
bmain, scene, view_layer, NULL, id, &collection_active->id, NULL, &id_override);
|
||||
BKE_lib_override_library_create(bmain,
|
||||
scene,
|
||||
view_layer,
|
||||
NULL,
|
||||
id,
|
||||
&collection_active->id,
|
||||
NULL,
|
||||
&id_override,
|
||||
false);
|
||||
}
|
||||
else {
|
||||
object_active->id.tag |= LIB_TAG_DOIT;
|
||||
BKE_lib_override_library_create(
|
||||
bmain, scene, view_layer, NULL, id, &object_active->id, NULL, &id_override);
|
||||
bmain, scene, view_layer, NULL, id, &object_active->id, NULL, &id_override, false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -2267,8 +2267,12 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
|
|||
ID *id_root = NULL;
|
||||
bool is_override_instancing_object = false;
|
||||
|
||||
GSet *user_overrides_objects_uids = BLI_gset_new(
|
||||
BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, __func__);
|
||||
const bool do_fully_editable = RNA_boolean_get(op->ptr, "do_fully_editable");
|
||||
|
||||
GSet *user_overrides_objects_uids = do_fully_editable ? NULL :
|
||||
BLI_gset_new(BLI_ghashutil_inthash_p,
|
||||
BLI_ghashutil_intcmp,
|
||||
__func__);
|
||||
bool user_overrides_from_selected_objects = false;
|
||||
|
||||
if (!ID_IS_LINKED(obact) && obact->instance_collection != NULL &&
|
||||
|
@ -2316,7 +2320,10 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
|
|||
user_overrides_from_selected_objects = true;
|
||||
}
|
||||
|
||||
if (user_overrides_from_selected_objects) {
|
||||
if (do_fully_editable) {
|
||||
/* Pass. */
|
||||
}
|
||||
else if (user_overrides_from_selected_objects) {
|
||||
/* Only selected objects can be 'user overrides'. */
|
||||
FOREACH_SELECTED_OBJECT_BEGIN (view_layer, CTX_wm_view3d(C), ob_iter) {
|
||||
BLI_gset_add(user_overrides_objects_uids, POINTER_FROM_UINT(ob_iter->id.session_uuid));
|
||||
|
@ -2336,25 +2343,34 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
|
|||
BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
|
||||
|
||||
ID *id_root_override;
|
||||
const bool success = BKE_lib_override_library_create(
|
||||
bmain, scene, view_layer, NULL, id_root, id_root, &obact->id, &id_root_override);
|
||||
const bool success = BKE_lib_override_library_create(bmain,
|
||||
scene,
|
||||
view_layer,
|
||||
NULL,
|
||||
id_root,
|
||||
id_root,
|
||||
&obact->id,
|
||||
&id_root_override,
|
||||
do_fully_editable);
|
||||
|
||||
/* Define liboverrides from selected/validated objects as user defined. */
|
||||
ID *id_hierarchy_root_override = id_root_override->override_library->hierarchy_root;
|
||||
ID *id_iter;
|
||||
FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
|
||||
if (ID_IS_LINKED(id_iter) || !ID_IS_OVERRIDE_LIBRARY_REAL(id_iter) ||
|
||||
id_iter->override_library->hierarchy_root != id_hierarchy_root_override) {
|
||||
continue;
|
||||
}
|
||||
if (BLI_gset_haskey(user_overrides_objects_uids,
|
||||
POINTER_FROM_UINT(id_iter->override_library->reference->session_uuid))) {
|
||||
id_iter->override_library->flag &= ~IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED;
|
||||
if (!do_fully_editable) {
|
||||
/* Define liboverrides from selected/validated objects as user defined. */
|
||||
ID *id_hierarchy_root_override = id_root_override->override_library->hierarchy_root;
|
||||
ID *id_iter;
|
||||
FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
|
||||
if (ID_IS_LINKED(id_iter) || !ID_IS_OVERRIDE_LIBRARY_REAL(id_iter) ||
|
||||
id_iter->override_library->hierarchy_root != id_hierarchy_root_override) {
|
||||
continue;
|
||||
}
|
||||
if (BLI_gset_haskey(user_overrides_objects_uids,
|
||||
POINTER_FROM_UINT(id_iter->override_library->reference->session_uuid))) {
|
||||
id_iter->override_library->flag &= ~IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED;
|
||||
}
|
||||
}
|
||||
FOREACH_MAIN_ID_END;
|
||||
|
||||
BLI_gset_free(user_overrides_objects_uids, NULL);
|
||||
}
|
||||
FOREACH_MAIN_ID_END;
|
||||
|
||||
BLI_gset_free(user_overrides_objects_uids, NULL);
|
||||
|
||||
/* Remove the instance empty from this scene, the items now have an overridden collection
|
||||
* instead. */
|
||||
|
@ -2468,6 +2484,13 @@ void OBJECT_OT_make_override_library(wmOperatorType *ot)
|
|||
RNA_def_enum_funcs(prop, make_override_collections_of_linked_object_itemf);
|
||||
RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
|
||||
ot->prop = prop;
|
||||
|
||||
prop = RNA_def_boolean(ot->srna,
|
||||
"do_fully_editable",
|
||||
false,
|
||||
"Create Fully Editable",
|
||||
"Make all created override data-blocks fully editable");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -763,6 +763,10 @@ static void id_local_fn(bContext *C,
|
|||
|
||||
struct OutlinerLibOverrideData {
|
||||
bool do_hierarchy;
|
||||
|
||||
/** When creating new overrides, make them all user-editable. */
|
||||
bool do_fully_editable;
|
||||
|
||||
/**
|
||||
* For resync operation, force keeping newly created override IDs (or original linked IDs)
|
||||
* instead of re-applying relevant existing ID pointer property override operations. Helps
|
||||
|
@ -957,7 +961,8 @@ static void id_override_library_create_fn(bContext *C,
|
|||
id_root_reference,
|
||||
id_hierarchy_root_reference,
|
||||
id_instance_hint,
|
||||
&id_root_override);
|
||||
&id_root_override,
|
||||
data->do_fully_editable);
|
||||
|
||||
BLI_assert(id_root_override != nullptr);
|
||||
BLI_assert(!ID_IS_LINKED(id_root_override));
|
||||
|
@ -1979,6 +1984,7 @@ enum eOutlinerIdOpTypes {
|
|||
OUTLINER_IDOP_LOCAL,
|
||||
OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE,
|
||||
OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY,
|
||||
OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY_FULLY_EDITABLE,
|
||||
OUTLINER_IDOP_OVERRIDE_LIBRARY_MAKE_EDITABLE,
|
||||
OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET,
|
||||
OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET_HIERARCHY,
|
||||
|
@ -2024,6 +2030,12 @@ static const EnumPropertyItem prop_id_op_types[] = {
|
|||
"Make Library Override Hierarchy",
|
||||
"Make a local override of this linked data-block, and its hierarchy of dependencies - only "
|
||||
"applies to active Outliner item"},
|
||||
{OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY_FULLY_EDITABLE,
|
||||
"OVERRIDE_LIBRARY_CREATE_HIERARCHY_FULLY_EDITABLE",
|
||||
0,
|
||||
"Make Library Override Hierarchy Fully Editable",
|
||||
"Make a local override of this linked data-block, and its hierarchy of dependencies, making "
|
||||
"them all fully user-editable - only applies to active Outliner item"},
|
||||
{OUTLINER_IDOP_OVERRIDE_LIBRARY_MAKE_EDITABLE,
|
||||
"OVERRIDE_LIBRARY_MAKE_EDITABLE",
|
||||
0,
|
||||
|
@ -2103,6 +2115,7 @@ static bool outliner_id_operation_item_poll(bContext *C,
|
|||
}
|
||||
return false;
|
||||
case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY:
|
||||
case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY_FULLY_EDITABLE:
|
||||
if (ID_IS_OVERRIDABLE_LIBRARY(tselem->id) || (ID_IS_LINKED(tselem->id))) {
|
||||
return true;
|
||||
}
|
||||
|
@ -2300,6 +2313,29 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
|
|||
ED_undo_push(C, "Overridden Data Hierarchy");
|
||||
break;
|
||||
}
|
||||
case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY_FULLY_EDITABLE: {
|
||||
OutlinerLibOverrideData override_data{};
|
||||
override_data.do_hierarchy = true;
|
||||
override_data.do_fully_editable = true;
|
||||
outliner_do_libdata_operation(C,
|
||||
op->reports,
|
||||
scene,
|
||||
space_outliner,
|
||||
&space_outliner->tree,
|
||||
id_override_library_create_hierarchy_pre_process_fn,
|
||||
&override_data);
|
||||
outliner_do_libdata_operation(C,
|
||||
op->reports,
|
||||
scene,
|
||||
space_outliner,
|
||||
&space_outliner->tree,
|
||||
id_override_library_create_fn,
|
||||
&override_data);
|
||||
id_override_library_create_hierarchy_post_process(C, &override_data);
|
||||
|
||||
ED_undo_push(C, "Overridden Data Hierarchy Fully Editable");
|
||||
break;
|
||||
}
|
||||
case OUTLINER_IDOP_OVERRIDE_LIBRARY_MAKE_EDITABLE: {
|
||||
outliner_do_libdata_operation(C,
|
||||
op->reports,
|
||||
|
|
|
@ -722,7 +722,7 @@ static ID *rna_ID_override_hierarchy_create(
|
|||
|
||||
ID *id_root_override = NULL;
|
||||
BKE_lib_override_library_create(
|
||||
bmain, scene, view_layer, NULL, id, id, id_instance_hint, &id_root_override);
|
||||
bmain, scene, view_layer, NULL, id, id, id_instance_hint, &id_root_override, false);
|
||||
|
||||
WM_main_add_notifier(NC_ID | NA_ADDED, NULL);
|
||||
WM_main_add_notifier(NC_WM | ND_LIB_OVERRIDE_CHANGED, NULL);
|
||||
|
|
Loading…
Reference in New Issue