Fix 'Make LibOverride' from 3DView failing in some trivial cases.
Slightly non-trivial linked collections hierarchy could cause 'Make LibOverride' operation from 3DView fail, reporting that more than one potential root collections were found. Logic here was way to simple, now this error should only happen when there are effectively more than one potential 'good' root collection (i.e. when two unrelated collections both contain (directly or not) the selected objects(s).
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_vector_set.hh"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
@@ -2568,33 +2569,68 @@ static int make_override_library_invoke(bContext *C, wmOperator *op, const wmEve
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
int potential_root_collections_num = 0;
|
||||
uint collection_session_uuid = MAIN_ID_SESSION_UUID_UNSET;
|
||||
blender::VectorSet<Collection *> potential_root_collections;
|
||||
LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
|
||||
/* Only check for directly linked collections. */
|
||||
if (!ID_IS_LINKED(&collection->id) || (collection->id.tag & LIB_TAG_INDIRECT) != 0 ||
|
||||
/* Only check for linked collections from the same library, in the current viewlayer. */
|
||||
if (!ID_IS_LINKED(&collection->id) || collection->id.lib != obact->id.lib ||
|
||||
!BKE_view_layer_has_collection(view_layer, collection))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (BKE_collection_has_object_recursive(collection, obact)) {
|
||||
if (potential_root_collections_num == 0) {
|
||||
collection_session_uuid = collection->id.session_uuid;
|
||||
if (!BKE_collection_has_object_recursive(collection, obact)) {
|
||||
continue;
|
||||
}
|
||||
if (potential_root_collections.is_empty()) {
|
||||
potential_root_collections.add_new(collection);
|
||||
}
|
||||
else {
|
||||
bool has_parents_in_potential_roots = false;
|
||||
bool is_potential_root = false;
|
||||
for (auto collection_root_iter : potential_root_collections) {
|
||||
if (BKE_collection_has_collection(collection_root_iter, collection)) {
|
||||
BLI_assert_msg(!BKE_collection_has_collection(collection, collection_root_iter),
|
||||
"Invalid loop in collection hierarchy");
|
||||
/* Current potential root is already 'better' (higher up in the collection hierarchy)
|
||||
* than current collection, nothing else to do. */
|
||||
has_parents_in_potential_roots = true;
|
||||
}
|
||||
else if (BKE_collection_has_collection(collection, collection_root_iter)) {
|
||||
BLI_assert_msg(!BKE_collection_has_collection(collection_root_iter, collection),
|
||||
"Invalid loop in collection hierarchy");
|
||||
/* Current potential root is in the current collection's hierarchy, so the later is a
|
||||
* better candidate as root collection. */
|
||||
is_potential_root = true;
|
||||
potential_root_collections.remove(collection_root_iter);
|
||||
}
|
||||
else {
|
||||
/* Current potential root is not found in current collection's hierarchy, so the later is
|
||||
* a potential candidate as root collection. */
|
||||
is_potential_root = true;
|
||||
}
|
||||
}
|
||||
/* Only add the current collection as potential root if it is not a descendant of any already
|
||||
* known potential root collections. */
|
||||
if (is_potential_root && !has_parents_in_potential_roots) {
|
||||
potential_root_collections.add_new(collection);
|
||||
}
|
||||
potential_root_collections_num++;
|
||||
}
|
||||
}
|
||||
|
||||
if (potential_root_collections_num <= 1) {
|
||||
RNA_property_int_set(op->ptr, op->type->prop, *((int *)&collection_session_uuid));
|
||||
if (potential_root_collections.is_empty()) {
|
||||
RNA_property_int_set(op->ptr, op->type->prop, MAIN_ID_SESSION_UUID_UNSET);
|
||||
return make_override_library_exec(C, op);
|
||||
}
|
||||
if (potential_root_collections.size() == 1) {
|
||||
Collection *collection_root = potential_root_collections.pop();
|
||||
RNA_property_int_set(op->ptr, op->type->prop, *((int *)&collection_root->id.session_uuid));
|
||||
return make_override_library_exec(C, op);
|
||||
}
|
||||
|
||||
BKE_reportf(op->reports,
|
||||
RPT_ERROR,
|
||||
"Too many potential root collections (%d) for the override hierarchy, "
|
||||
"Too many potential root collections (%ld) for the override hierarchy, "
|
||||
"please use the Outliner instead",
|
||||
potential_root_collections_num);
|
||||
potential_root_collections.size());
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user