Asset Browser: Show "orphaned" assets in "Unassigned" catalog

Show assets that have an unknown catalog ID assigned in the "Unassigned"
catalog.

Another catalog named "Orphans" was considered as well, but that would
clash with the usual handling of Blender (discarding orphan data on
save) and thus that idea was discarded.

Manifest Task: T91949
This commit is contained in:
Sybren A. Stüvel 2021-10-22 16:32:05 +02:00
parent 70aad5f498
commit 85312f2236
3 changed files with 35 additions and 12 deletions

View File

@ -118,6 +118,11 @@ class AssetCatalogService {
* none marked as "first loaded", return the one with the lowest UUID. */
AssetCatalog *find_catalog_by_path(const AssetCatalogPath &path) const;
/**
* Return true only if this catalog is known.
* This treats deleted catalogs as "unknown". */
bool is_catalog_known(CatalogID catalog_id) const;
/**
* Create a filter object that can be used to determine whether an asset belongs to the given
* catalog, or any of the catalogs in the sub-tree rooted at the given catalog.
@ -488,17 +493,22 @@ using MutableAssetCatalogOrderedSet = std::set<AssetCatalog *, AssetCatalogLessT
/**
* Filter that can determine whether an asset should be visible or not, based on its catalog ID.
*
* \see AssetCatalogService::create_filter()
* \see AssetCatalogService::create_catalog_filter()
*/
class AssetCatalogFilter {
public:
bool contains(CatalogID asset_catalog_id) const;
/* So that all unknown catalogs can be shown under "Unassigned". */
bool is_known(CatalogID asset_catalog_id) const;
protected:
friend AssetCatalogService;
const Set<CatalogID> matching_catalog_ids;
const Set<CatalogID> known_catalog_ids;
explicit AssetCatalogFilter(Set<CatalogID> &&matching_catalog_ids);
explicit AssetCatalogFilter(Set<CatalogID> &&matching_catalog_ids,
Set<CatalogID> &&known_catalog_ids);
};
} // namespace blender::bke

View File

@ -154,18 +154,20 @@ AssetCatalog *AssetCatalogService::find_catalog_by_path(const AssetCatalogPath &
return *best_choice_it;
}
bool AssetCatalogService::is_catalog_known(CatalogID catalog_id) const
{
BLI_assert(catalog_collection_);
return catalog_collection_->catalogs_.contains(catalog_id);
}
AssetCatalogFilter AssetCatalogService::create_catalog_filter(
const CatalogID active_catalog_id) const
{
Set<CatalogID> matching_catalog_ids;
Set<CatalogID> known_catalog_ids;
matching_catalog_ids.add(active_catalog_id);
const AssetCatalog *active_catalog = find_catalog(active_catalog_id);
if (!active_catalog) {
/* If the UUID is unknown (i.e. not mapped to an actual Catalog), it is impossible to determine
* its children. The filter can still work on the given UUID. */
return AssetCatalogFilter(std::move(matching_catalog_ids));
}
/* This cannot just iterate over tree items to get all the required data, because tree items only
* represent single UUIDs. It could be used to get the main UUIDs of the children, though, and
@ -173,12 +175,13 @@ AssetCatalogFilter AssetCatalogService::create_catalog_filter(
* call). Without an extra indexed-by-path acceleration structure, this is still going to require
* a linear search, though. */
for (const auto &catalog_uptr : catalog_collection_->catalogs_.values()) {
if (catalog_uptr->path.is_contained_in(active_catalog->path)) {
if (active_catalog && catalog_uptr->path.is_contained_in(active_catalog->path)) {
matching_catalog_ids.add(catalog_uptr->catalog_id);
}
known_catalog_ids.add(catalog_uptr->catalog_id);
}
return AssetCatalogFilter(std::move(matching_catalog_ids));
return AssetCatalogFilter(std::move(matching_catalog_ids), std::move(known_catalog_ids));
}
void AssetCatalogService::delete_catalog_by_id_soft(const CatalogID catalog_id)
@ -1063,8 +1066,10 @@ std::string AssetCatalog::sensible_simple_name_for_path(const AssetCatalogPath &
return "..." + name.substr(name.length() - 60);
}
AssetCatalogFilter::AssetCatalogFilter(Set<CatalogID> &&matching_catalog_ids)
: matching_catalog_ids(std::move(matching_catalog_ids))
AssetCatalogFilter::AssetCatalogFilter(Set<CatalogID> &&matching_catalog_ids,
Set<CatalogID> &&known_catalog_ids)
: matching_catalog_ids(std::move(matching_catalog_ids)),
known_catalog_ids(std::move(known_catalog_ids))
{
}
@ -1073,4 +1078,12 @@ bool AssetCatalogFilter::contains(const CatalogID asset_catalog_id) const
return matching_catalog_ids.contains(asset_catalog_id);
}
bool AssetCatalogFilter::is_known(const CatalogID asset_catalog_id) const
{
if (BLI_uuid_is_nil(asset_catalog_id)) {
return false;
}
return known_catalog_ids.contains(asset_catalog_id);
}
} // namespace blender::bke

View File

@ -490,7 +490,7 @@ bool file_is_asset_visible_in_catalog_filter_settings(
switch (filter_settings->asset_catalog_visibility) {
case FILE_SHOW_ASSETS_WITHOUT_CATALOG:
return BLI_uuid_is_nil(asset_data->catalog_id);
return !filter_settings->catalog_filter->is_known(asset_data->catalog_id);
case FILE_SHOW_ASSETS_FROM_CATALOG:
return filter_settings->catalog_filter->contains(asset_data->catalog_id);
case FILE_SHOW_ASSETS_ALL_CATALOGS: