Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPablo Vazquez <pablo@blender.org>2021-10-04 17:21:26 +0300
committerPablo Vazquez <pablo@blender.org>2021-10-04 17:21:26 +0300
commitf0731bd5ac78856e69f1ee09e4762e7d42dc17c9 (patch)
treeaf1576c25c72517e970fbe07a4a7ad2d1248004f
parent2c5661682b61ac4a8a8f45f77a4eff7b85f6f141 (diff)
parent4a3464050c4e83d446d47c946e17b9540f5a3862 (diff)
Merge branch 'master' into temp-ui-tweakstemp-ui-tweaks
-rw-r--r--intern/cycles/blender/addon/engine.py1
-rw-r--r--intern/cycles/blender/addon/properties.py6
-rw-r--r--intern/cycles/blender/addon/ui.py1
-rw-r--r--intern/cycles/blender/blender_sync.cpp6
-rw-r--r--intern/cycles/integrator/pass_accessor.cpp3
-rw-r--r--intern/cycles/kernel/geom/geom_shader_data.h2
-rw-r--r--intern/cycles/kernel/integrator/integrator_init_from_bake.h25
-rw-r--r--intern/cycles/kernel/integrator/integrator_intersect_closest.h2
-rw-r--r--intern/cycles/kernel/kernel_types.h1
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp13
-rw-r--r--intern/cycles/kernel/osl/osl_services.h1
-rw-r--r--intern/cycles/kernel/shaders/node_normal_map.osl2
-rw-r--r--intern/cycles/render/film.cpp2
-rw-r--r--intern/cycles/render/pass.cpp5
-rw-r--r--source/blender/blenlib/intern/math_color_inline.c2
-rw-r--r--source/blender/editors/object/object_bake_api.c12
-rw-r--r--source/blender/editors/space_file/asset_catalog_tree_view.cc299
-rw-r--r--source/blender/editors/space_file/filelist.c12
18 files changed, 241 insertions, 154 deletions
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index d729cb1ee69..c402df12ba9 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -211,7 +211,6 @@ def list_render_passes(scene, srl):
if crl.use_pass_shadow_catcher: yield ("Shadow Catcher", "RGB", 'COLOR')
# Debug passes.
- if crl.pass_debug_render_time: yield ("Debug Render Time", "X", 'VALUE')
if crl.pass_debug_sample_count: yield ("Debug Sample Count", "X", 'VALUE')
# Cryptomatte passes.
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index cea70033784..8c1f26d7b9f 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -1197,12 +1197,6 @@ class CyclesCurveRenderSettings(bpy.types.PropertyGroup):
class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
- pass_debug_render_time: BoolProperty(
- name="Debug Render Time",
- description="Render time in milliseconds per sample and pixel",
- default=False,
- update=update_render_passes,
- )
pass_debug_sample_count: BoolProperty(
name="Debug Sample Count",
description="Number of samples/camera rays per pixel",
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index c4a1844480c..55782088444 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -792,7 +792,6 @@ class CYCLES_RENDER_PT_passes_data(CyclesButtonsPanel, Panel):
col.prop(view_layer, "use_pass_material_index")
col = layout.column(heading="Debug", align=True)
- col.prop(cycles_view_layer, "pass_debug_render_time", text="Render Time")
col.prop(cycles_view_layer, "pass_debug_sample_count", text="Sample Count")
layout.prop(view_layer, "pass_alpha_threshold")
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 717f301b03e..9f5bbddbe77 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -545,8 +545,6 @@ static PassType get_blender_pass_type(BL::RenderPass &b_pass)
MAP_PASS("Shadow Catcher", PASS_SHADOW_CATCHER);
MAP_PASS("Noisy Shadow Catcher", PASS_SHADOW_CATCHER);
- MAP_PASS("Debug Render Time", PASS_RENDER_TIME);
-
MAP_PASS("AdaptiveAuxBuffer", PASS_ADAPTIVE_AUX_BUFFER);
MAP_PASS("Debug Sample Count", PASS_SAMPLE_COUNT);
@@ -604,10 +602,6 @@ void BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLayer &b_v
PointerRNA crl = RNA_pointer_get(&b_view_layer.ptr, "cycles");
/* Debug passes. */
- if (get_boolean(crl, "pass_debug_render_time")) {
- b_engine.add_pass("Debug Render Time", 1, "X", b_view_layer.name().c_str());
- pass_add(scene, PASS_RENDER_TIME, "Debug Render Time");
- }
if (get_boolean(crl, "pass_debug_sample_count")) {
b_engine.add_pass("Debug Sample Count", 1, "X", b_view_layer.name().c_str());
pass_add(scene, PASS_SAMPLE_COUNT, "Debug Sample Count");
diff --git a/intern/cycles/integrator/pass_accessor.cpp b/intern/cycles/integrator/pass_accessor.cpp
index 87c048b1fa5..4f76f1fa9df 100644
--- a/intern/cycles/integrator/pass_accessor.cpp
+++ b/intern/cycles/integrator/pass_accessor.cpp
@@ -149,9 +149,6 @@ bool PassAccessor::get_render_tile_pixels(const RenderBuffers *render_buffers,
/* Denoised passes store their final pixels, no need in special calculation. */
get_pass_float(render_buffers, buffer_params, destination);
}
- else if (type == PASS_RENDER_TIME) {
- /* TODO(sergey): Needs implementation. */
- }
else if (type == PASS_DEPTH) {
get_pass_depth(render_buffers, buffer_params, destination);
}
diff --git a/intern/cycles/kernel/geom/geom_shader_data.h b/intern/cycles/kernel/geom/geom_shader_data.h
index fb2cb5cb1ea..0e373c10086 100644
--- a/intern/cycles/kernel/geom/geom_shader_data.h
+++ b/intern/cycles/kernel/geom/geom_shader_data.h
@@ -103,7 +103,7 @@ ccl_device_inline void shader_setup_from_ray(const KernelGlobals *ccl_restrict k
sd->flag |= kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
- if (isect->object != OBJECT_NONE) {
+ if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
/* instance transform */
object_normal_transform_auto(kg, sd, &sd->N);
object_normal_transform_auto(kg, sd, &sd->Ng);
diff --git a/intern/cycles/kernel/integrator/integrator_init_from_bake.h b/intern/cycles/kernel/integrator/integrator_init_from_bake.h
index 96db606cee1..6e4e1be55fa 100644
--- a/intern/cycles/kernel/integrator/integrator_init_from_bake.h
+++ b/intern/cycles/kernel/integrator/integrator_init_from_bake.h
@@ -109,9 +109,17 @@ ccl_device bool integrator_init_from_bake(INTEGRATOR_STATE_ARGS,
}
/* Position and normal on triangle. */
+ const int object = kernel_data.bake.object_index;
float3 P, Ng;
int shader;
- triangle_point_normal(kg, kernel_data.bake.object_index, prim, u, v, &P, &Ng, &shader);
+ triangle_point_normal(kg, object, prim, u, v, &P, &Ng, &shader);
+
+ const int object_flag = kernel_tex_fetch(__object_flag, object);
+ if (!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
+ P = transform_point_auto(&tfm, P);
+ }
+
if (kernel_data.film.pass_background != PASS_UNUSED) {
/* Environment baking. */
@@ -130,8 +138,13 @@ ccl_device bool integrator_init_from_bake(INTEGRATOR_STATE_ARGS,
}
else {
/* Surface baking. */
- const float3 N = (shader & SHADER_SMOOTH_NORMAL) ? triangle_smooth_normal(kg, Ng, prim, u, v) :
- Ng;
+ float3 N = (shader & SHADER_SMOOTH_NORMAL) ? triangle_smooth_normal(kg, Ng, prim, u, v) : Ng;
+
+ if (!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
+ Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+ N = normalize(transform_direction_transposed(&itfm, N));
+ Ng = normalize(transform_direction_transposed(&itfm, Ng));
+ }
/* Setup ray. */
Ray ray ccl_optional_struct_init;
@@ -143,6 +156,12 @@ ccl_device bool integrator_init_from_bake(INTEGRATOR_STATE_ARGS,
/* Setup differentials. */
float3 dPdu, dPdv;
triangle_dPdudv(kg, prim, &dPdu, &dPdv);
+ if (!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
+ dPdu = transform_direction(&tfm, dPdu);
+ dPdv = transform_direction(&tfm, dPdv);
+ }
+
differential3 dP;
dP.dx = dPdu * dudx + dPdv * dvdx;
dP.dy = dPdu * dudy + dPdv * dvdy;
diff --git a/intern/cycles/kernel/integrator/integrator_intersect_closest.h b/intern/cycles/kernel/integrator/integrator_intersect_closest.h
index 34ca6814534..4e581df1870 100644
--- a/intern/cycles/kernel/integrator/integrator_intersect_closest.h
+++ b/intern/cycles/kernel/integrator/integrator_intersect_closest.h
@@ -123,7 +123,7 @@ ccl_device_forceinline void integrator_intersect_shader_next_kernel(
#ifdef __SHADOW_CATCHER__
const int object_flags = intersection_get_object_flags(kg, isect);
if (kernel_shadow_catcher_split(INTEGRATOR_STATE_PASS, object_flags)) {
- if (kernel_data.film.use_approximate_shadow_catcher && !kernel_data.background.transparent) {
+ if (kernel_data.film.pass_background != PASS_UNUSED && !kernel_data.background.transparent) {
INTEGRATOR_STATE_WRITE(path, flag) |= PATH_RAY_SHADOW_CATCHER_BACKGROUND;
if (use_raytrace_kernel) {
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 3cc42bf7a85..1a986c58878 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -360,7 +360,6 @@ typedef enum PassType {
PASS_MATERIAL_ID,
PASS_MOTION,
PASS_MOTION_WEIGHT,
- PASS_RENDER_TIME,
PASS_CRYPTOMATTE,
PASS_AOV_COLOR,
PASS_AOV_VALUE,
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index 4fc46a255a8..2c7f5eb4948 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -110,6 +110,7 @@ ustring OSLRenderServices::u_curve_thickness("geom:curve_thickness");
ustring OSLRenderServices::u_curve_length("geom:curve_length");
ustring OSLRenderServices::u_curve_tangent_normal("geom:curve_tangent_normal");
ustring OSLRenderServices::u_curve_random("geom:curve_random");
+ustring OSLRenderServices::u_normal_map_normal("geom:normal_map_normal");
ustring OSLRenderServices::u_path_ray_length("path:ray_length");
ustring OSLRenderServices::u_path_ray_depth("path:ray_depth");
ustring OSLRenderServices::u_path_diffuse_depth("path:diffuse_depth");
@@ -985,8 +986,18 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobals *kg,
float3 f = curve_tangent_normal(kg, sd);
return set_attribute_float3(f, type, derivatives, val);
}
- else
+ else if (name == u_normal_map_normal) {
+ if (sd->type & PRIMITIVE_ALL_TRIANGLE) {
+ float3 f = triangle_smooth_normal_unnormalized(kg, sd, sd->Ng, sd->prim, sd->u, sd->v);
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+ else {
+ return false;
+ }
+ }
+ else {
return false;
+ }
}
bool OSLRenderServices::get_background_attribute(const KernelGlobals *kg,
diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h
index 2a5400282b3..a9671485eda 100644
--- a/intern/cycles/kernel/osl/osl_services.h
+++ b/intern/cycles/kernel/osl/osl_services.h
@@ -297,6 +297,7 @@ class OSLRenderServices : public OSL::RendererServices {
static ustring u_curve_length;
static ustring u_curve_tangent_normal;
static ustring u_curve_random;
+ static ustring u_normal_map_normal;
static ustring u_path_ray_length;
static ustring u_path_ray_depth;
static ustring u_path_diffuse_depth;
diff --git a/intern/cycles/kernel/shaders/node_normal_map.osl b/intern/cycles/kernel/shaders/node_normal_map.osl
index 6d4780f6dae..7a94ad8ad1a 100644
--- a/intern/cycles/kernel/shaders/node_normal_map.osl
+++ b/intern/cycles/kernel/shaders/node_normal_map.osl
@@ -45,7 +45,7 @@ shader node_normal_map(normal NormalIn = N,
// get _unnormalized_ interpolated normal and tangent
if (getattribute(attr_name, tangent) && getattribute(attr_sign_name, tangent_sign) &&
- (!is_smooth || getattribute("geom:N", ninterp))) {
+ (!is_smooth || getattribute("geom:normal_map_normal", ninterp))) {
// apply normal map
vector B = tangent_sign * cross(ninterp, tangent);
Normal = normalize(mcolor[0] * tangent + mcolor[1] * B + mcolor[2] * ninterp);
diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp
index ad3336ca089..48f87ea3bf7 100644
--- a/intern/cycles/render/film.cpp
+++ b/intern/cycles/render/film.cpp
@@ -326,8 +326,6 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
kfilm->pass_bake_differential = kfilm->pass_stride;
break;
- case PASS_RENDER_TIME:
- break;
case PASS_CRYPTOMATTE:
kfilm->pass_cryptomatte = have_cryptomatte ?
min(kfilm->pass_cryptomatte, kfilm->pass_stride) :
diff --git a/intern/cycles/render/pass.cpp b/intern/cycles/render/pass.cpp
index 27ad7c0db97..472c9fc0a82 100644
--- a/intern/cycles/render/pass.cpp
+++ b/intern/cycles/render/pass.cpp
@@ -89,7 +89,6 @@ const NodeEnum *Pass::get_type_enum()
pass_type_enum.insert("material_id", PASS_MATERIAL_ID);
pass_type_enum.insert("motion", PASS_MOTION);
pass_type_enum.insert("motion_weight", PASS_MOTION_WEIGHT);
- pass_type_enum.insert("render_time", PASS_RENDER_TIME);
pass_type_enum.insert("cryptomatte", PASS_CRYPTOMATTE);
pass_type_enum.insert("aov_color", PASS_AOV_COLOR);
pass_type_enum.insert("aov_value", PASS_AOV_VALUE);
@@ -217,10 +216,6 @@ PassInfo Pass::get_info(const PassType type, const bool include_albedo)
pass_info.num_components = 3;
pass_info.use_exposure = false;
break;
- case PASS_RENDER_TIME:
- /* This pass is handled entirely on the host side. */
- pass_info.num_components = 0;
- break;
case PASS_DIFFUSE_COLOR:
case PASS_GLOSSY_COLOR:
diff --git a/source/blender/blenlib/intern/math_color_inline.c b/source/blender/blenlib/intern/math_color_inline.c
index 8b3e3b11cff..24c4143e587 100644
--- a/source/blender/blenlib/intern/math_color_inline.c
+++ b/source/blender/blenlib/intern/math_color_inline.c
@@ -329,7 +329,7 @@ MINLINE float dither_random_value(float s, float t)
hash0 -= floorf(hash0);
hash1 -= floorf(hash1);
/* Convert uniform distribution into triangle-shaped distribution. */
- return hash0 + hash0 - 0.5f;
+ return hash0 + hash1 - 0.5f;
}
MINLINE void float_to_byte_dither_v3(
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index 26f5b21a311..475e0e581fb 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -1532,22 +1532,22 @@ static int bake(const BakeAPIRender *bkr,
if (md) {
mode = md->mode;
md->mode &= ~eModifierMode_Render;
- }
- /* Evaluate modifiers again. */
- me_nores = BKE_mesh_new_from_object(NULL, ob_low_eval, false, false);
- bake_targets_populate_pixels(bkr, &targets, ob_low, me_nores, pixel_array_low);
+ /* Evaluate modifiers again. */
+ me_nores = BKE_mesh_new_from_object(NULL, ob_low_eval, false, false);
+ bake_targets_populate_pixels(bkr, &targets, ob_low, me_nores, pixel_array_low);
+ }
RE_bake_normal_world_to_tangent(pixel_array_low,
targets.num_pixels,
targets.num_channels,
targets.result,
- me_nores,
+ (me_nores) ? me_nores : me_low_eval,
bkr->normal_swizzle,
ob_low_eval->obmat);
- BKE_id_free(NULL, &me_nores->id);
if (md) {
+ BKE_id_free(NULL, &me_nores->id);
md->mode = mode;
}
}
diff --git a/source/blender/editors/space_file/asset_catalog_tree_view.cc b/source/blender/editors/space_file/asset_catalog_tree_view.cc
index 92e4e668885..883bc6d7890 100644
--- a/source/blender/editors/space_file/asset_catalog_tree_view.cc
+++ b/source/blender/editors/space_file/asset_catalog_tree_view.cc
@@ -74,6 +74,7 @@ class AssetCatalogTreeView : public ui::AbstractTreeView {
void add_unassigned_item();
bool is_active_catalog(CatalogID catalog_id) const;
};
+
/* ---------------------------------------------------------------------- */
class AssetCatalogTreeViewItem : public ui::BasicTreeViewItem {
@@ -81,111 +82,23 @@ class AssetCatalogTreeViewItem : public ui::BasicTreeViewItem {
AssetCatalogTreeItem &catalog_item_;
public:
- AssetCatalogTreeViewItem(AssetCatalogTreeItem *catalog_item)
- : BasicTreeViewItem(catalog_item->get_name()), catalog_item_(*catalog_item)
- {
- }
-
- void on_activate() override
- {
- const AssetCatalogTreeView &tree_view = static_cast<const AssetCatalogTreeView &>(
- get_tree_view());
- tree_view.params_->asset_catalog_visibility = FILE_SHOW_ASSETS_FROM_CATALOG;
- tree_view.params_->catalog_id = catalog_item_.get_catalog_id();
- WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, nullptr);
- }
-
- void build_row(uiLayout &row) override
- {
- ui::BasicTreeViewItem::build_row(row);
-
- if (!is_active()) {
- return;
- }
+ AssetCatalogTreeViewItem(AssetCatalogTreeItem *catalog_item);
- PointerRNA *props;
- const CatalogID catalog_id = catalog_item_.get_catalog_id();
+ static bool has_droppable_item(const wmDrag &drag);
+ static bool drop_into_catalog(const AssetCatalogTreeView &tree_view,
+ const wmDrag &drag,
+ CatalogID catalog_id,
+ StringRefNull simple_name = "");
- props = UI_but_extra_operator_icon_add(
- button(), "ASSET_OT_catalog_new", WM_OP_INVOKE_DEFAULT, ICON_ADD);
- RNA_string_set(props, "parent_path", catalog_item_.catalog_path().c_str());
-
- /* Tree items without a catalog ID represent components of catalog paths that are not
- * associated with an actual catalog. They exist merely by the presence of a child catalog, and
- * thus cannot be deleted themselves. */
- if (!BLI_uuid_is_nil(catalog_id)) {
- char catalog_id_str_buffer[UUID_STRING_LEN] = "";
- BLI_uuid_format(catalog_id_str_buffer, catalog_id);
-
- props = UI_but_extra_operator_icon_add(
- button(), "ASSET_OT_catalog_delete", WM_OP_INVOKE_DEFAULT, ICON_X);
- RNA_string_set(props, "catalog_id", catalog_id_str_buffer);
- }
- }
-
- bool has_droppable_item(const wmDrag &drag) const
- {
- const ListBase *asset_drags = WM_drag_asset_list_get(&drag);
-
- /* There needs to be at least one asset from the current file. */
- LISTBASE_FOREACH (const wmDragAssetListItem *, asset_item, asset_drags) {
- if (!asset_item->is_external) {
- return true;
- }
- }
- return false;
- }
+ void on_activate() override;
- bool can_drop(const wmDrag &drag) const override
- {
- if (drag.type != WM_DRAG_ASSET_LIST) {
- return false;
- }
- return has_droppable_item(drag);
- }
+ void build_row(uiLayout &row) override;
- std::string drop_tooltip(const bContext & /*C*/,
+ bool can_drop(const wmDrag &drag) const override;
+ std::string drop_tooltip(const bContext &C,
const wmDrag &drag,
- const wmEvent & /*event*/) const override
- {
- const ListBase *asset_drags = WM_drag_asset_list_get(&drag);
- const bool is_multiple_assets = !BLI_listbase_is_single(asset_drags);
-
- /* Don't try to be smart by dynamically adding the 's' for the plural. Just makes translation
- * harder, so use full literals. */
- std::string basic_tip = is_multiple_assets ? TIP_("Move assets to catalog") :
- TIP_("Move asset to catalog");
-
- return basic_tip + ": " + catalog_item_.get_name() + " (" +
- catalog_item_.catalog_path().str() + ")";
- }
-
- bool on_drop(const wmDrag &drag) override
- {
- const ListBase *asset_drags = WM_drag_asset_list_get(&drag);
- if (!asset_drags) {
- return false;
- }
-
- const AssetCatalogTreeView &tree_view = static_cast<const AssetCatalogTreeView &>(
- get_tree_view());
-
- LISTBASE_FOREACH (wmDragAssetListItem *, asset_item, asset_drags) {
- if (asset_item->is_external) {
- /* Only internal assets can be modified! */
- continue;
- }
- BKE_asset_metadata_catalog_id_set(asset_item->asset_data.local_id->asset_data,
- catalog_item_.get_catalog_id(),
- catalog_item_.get_simple_name().c_str());
-
- /* Trigger re-run of filtering to update visible assets. */
- filelist_tag_needs_filtering(tree_view.space_file_.files);
- file_select_deselect_all(&tree_view.space_file_, FILE_SEL_SELECTED | FILE_SEL_HIGHLIGHTED);
- }
-
- return true;
- }
+ const wmEvent &event) const override;
+ bool on_drop(const wmDrag &drag) override;
};
/** Only reason this isn't just `BasicTreeViewItem` is to add a '+' icon for adding a root level
@@ -193,22 +106,21 @@ class AssetCatalogTreeViewItem : public ui::BasicTreeViewItem {
class AssetCatalogTreeViewAllItem : public ui::BasicTreeViewItem {
using BasicTreeViewItem::BasicTreeViewItem;
- void build_row(uiLayout &row) override
- {
- ui::BasicTreeViewItem::build_row(row);
+ void build_row(uiLayout &row) override;
+};
- if (!is_active()) {
- return;
- }
+class AssetCatalogTreeViewUnassignedItem : public ui::BasicTreeViewItem {
+ using BasicTreeViewItem::BasicTreeViewItem;
- PointerRNA *props;
- props = UI_but_extra_operator_icon_add(
- button(), "ASSET_OT_catalog_new", WM_OP_INVOKE_DEFAULT, ICON_ADD);
- /* No parent path to use the root level. */
- RNA_string_set(props, "parent_path", nullptr);
- }
+ bool can_drop(const wmDrag &drag) const override;
+ std::string drop_tooltip(const bContext &C,
+ const wmDrag &drag,
+ const wmEvent &event) const override;
+ bool on_drop(const wmDrag &drag) override;
};
+/* ---------------------------------------------------------------------- */
+
AssetCatalogTreeView::AssetCatalogTreeView(::AssetLibrary *library,
FileAssetSelectParams *params,
SpaceFile &space_file)
@@ -267,7 +179,7 @@ void AssetCatalogTreeView::add_unassigned_item()
{
FileAssetSelectParams *params = params_;
- ui::AbstractTreeViewItem &item = add_tree_item<ui::BasicTreeViewItem>(
+ AssetCatalogTreeViewUnassignedItem &item = add_tree_item<AssetCatalogTreeViewUnassignedItem>(
IFACE_("Unassigned"), ICON_FILE_HIDDEN, [params](ui::BasicTreeViewItem & /*item*/) {
params->asset_catalog_visibility = FILE_SHOW_ASSETS_WITHOUT_CATALOG;
WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, nullptr);
@@ -283,6 +195,167 @@ bool AssetCatalogTreeView::is_active_catalog(CatalogID catalog_id) const
(params_->catalog_id == catalog_id);
}
+/* ---------------------------------------------------------------------- */
+
+AssetCatalogTreeViewItem::AssetCatalogTreeViewItem(AssetCatalogTreeItem *catalog_item)
+ : BasicTreeViewItem(catalog_item->get_name()), catalog_item_(*catalog_item)
+{
+}
+
+void AssetCatalogTreeViewItem::on_activate()
+{
+ const AssetCatalogTreeView &tree_view = static_cast<const AssetCatalogTreeView &>(
+ get_tree_view());
+ tree_view.params_->asset_catalog_visibility = FILE_SHOW_ASSETS_FROM_CATALOG;
+ tree_view.params_->catalog_id = catalog_item_.get_catalog_id();
+ WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, nullptr);
+}
+
+void AssetCatalogTreeViewItem::build_row(uiLayout &row)
+{
+ ui::BasicTreeViewItem::build_row(row);
+
+ if (!is_active()) {
+ return;
+ }
+
+ PointerRNA *props;
+ const CatalogID catalog_id = catalog_item_.get_catalog_id();
+
+ props = UI_but_extra_operator_icon_add(
+ button(), "ASSET_OT_catalog_new", WM_OP_INVOKE_DEFAULT, ICON_ADD);
+ RNA_string_set(props, "parent_path", catalog_item_.catalog_path().c_str());
+
+ /* Tree items without a catalog ID represent components of catalog paths that are not
+ * associated with an actual catalog. They exist merely by the presence of a child catalog, and
+ * thus cannot be deleted themselves. */
+ if (!BLI_uuid_is_nil(catalog_id)) {
+ char catalog_id_str_buffer[UUID_STRING_LEN] = "";
+ BLI_uuid_format(catalog_id_str_buffer, catalog_id);
+
+ props = UI_but_extra_operator_icon_add(
+ button(), "ASSET_OT_catalog_delete", WM_OP_INVOKE_DEFAULT, ICON_X);
+ RNA_string_set(props, "catalog_id", catalog_id_str_buffer);
+ }
+}
+
+bool AssetCatalogTreeViewItem::has_droppable_item(const wmDrag &drag)
+{
+ const ListBase *asset_drags = WM_drag_asset_list_get(&drag);
+
+ /* There needs to be at least one asset from the current file. */
+ LISTBASE_FOREACH (const wmDragAssetListItem *, asset_item, asset_drags) {
+ if (!asset_item->is_external) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool AssetCatalogTreeViewItem::can_drop(const wmDrag &drag) const
+{
+ if (drag.type != WM_DRAG_ASSET_LIST) {
+ return false;
+ }
+ return has_droppable_item(drag);
+}
+
+std::string AssetCatalogTreeViewItem::drop_tooltip(const bContext & /*C*/,
+ const wmDrag &drag,
+ const wmEvent & /*event*/) const
+{
+ const ListBase *asset_drags = WM_drag_asset_list_get(&drag);
+ const bool is_multiple_assets = !BLI_listbase_is_single(asset_drags);
+
+ /* Don't try to be smart by dynamically adding the 's' for the plural. Just makes translation
+ * harder, so use full literals. */
+ std::string basic_tip = is_multiple_assets ? TIP_("Move assets to catalog") :
+ TIP_("Move asset to catalog");
+
+ return basic_tip + ": " + catalog_item_.get_name() + " (" + catalog_item_.catalog_path().str() +
+ ")";
+}
+
+bool AssetCatalogTreeViewItem::drop_into_catalog(const AssetCatalogTreeView &tree_view,
+ const wmDrag &drag,
+ CatalogID catalog_id,
+ StringRefNull simple_name)
+{
+ const ListBase *asset_drags = WM_drag_asset_list_get(&drag);
+ if (!asset_drags) {
+ return false;
+ }
+
+ LISTBASE_FOREACH (wmDragAssetListItem *, asset_item, asset_drags) {
+ if (asset_item->is_external) {
+ /* Only internal assets can be modified! */
+ continue;
+ }
+ BKE_asset_metadata_catalog_id_set(
+ asset_item->asset_data.local_id->asset_data, catalog_id, simple_name.c_str());
+
+ /* Trigger re-run of filtering to update visible assets. */
+ filelist_tag_needs_filtering(tree_view.space_file_.files);
+ file_select_deselect_all(&tree_view.space_file_, FILE_SEL_SELECTED | FILE_SEL_HIGHLIGHTED);
+ }
+
+ return true;
+}
+
+bool AssetCatalogTreeViewItem::on_drop(const wmDrag &drag)
+{
+ const AssetCatalogTreeView &tree_view = static_cast<const AssetCatalogTreeView &>(
+ get_tree_view());
+ return drop_into_catalog(
+ tree_view, drag, catalog_item_.get_catalog_id(), catalog_item_.get_simple_name());
+}
+
+/* ---------------------------------------------------------------------- */
+
+void AssetCatalogTreeViewAllItem::build_row(uiLayout &row)
+{
+ ui::BasicTreeViewItem::build_row(row);
+
+ if (!is_active()) {
+ return;
+ }
+
+ PointerRNA *props;
+ props = UI_but_extra_operator_icon_add(
+ button(), "ASSET_OT_catalog_new", WM_OP_INVOKE_DEFAULT, ICON_ADD);
+ /* No parent path to use the root level. */
+ RNA_string_set(props, "parent_path", nullptr);
+}
+
+/* ---------------------------------------------------------------------- */
+
+bool AssetCatalogTreeViewUnassignedItem::can_drop(const wmDrag &drag) const
+{
+ if (drag.type != WM_DRAG_ASSET_LIST) {
+ return false;
+ }
+ return AssetCatalogTreeViewItem::has_droppable_item(drag);
+}
+
+std::string AssetCatalogTreeViewUnassignedItem::drop_tooltip(const bContext & /*C*/,
+ const wmDrag &drag,
+ const wmEvent & /*event*/) const
+{
+ const ListBase *asset_drags = WM_drag_asset_list_get(&drag);
+ const bool is_multiple_assets = !BLI_listbase_is_single(asset_drags);
+
+ return is_multiple_assets ? TIP_("Move assets out of any catalog") :
+ TIP_("Move asset out of any catalog");
+}
+
+bool AssetCatalogTreeViewUnassignedItem::on_drop(const wmDrag &drag)
+{
+ const AssetCatalogTreeView &tree_view = static_cast<const AssetCatalogTreeView &>(
+ get_tree_view());
+ /* Assign to nil catalog ID. */
+ return AssetCatalogTreeViewItem::drop_into_catalog(tree_view, drag, CatalogID{});
+}
+
} // namespace blender::ed::asset_browser
/* ---------------------------------------------------------------------- */
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index b58a04d6d4f..a927b62fd6e 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -3295,6 +3295,7 @@ typedef struct FileListReadJob {
} FileListReadJob;
static bool filelist_readjob_should_recurse_into_entry(const int max_recursion,
+ const bool is_lib,
const int current_recursion_level,
FileListInternEntry *entry)
{
@@ -3302,10 +3303,16 @@ static bool filelist_readjob_should_recurse_into_entry(const int max_recursion,
/* Recursive loading is disabled. */
return false;
}
- if (current_recursion_level >= max_recursion) {
+ if (!is_lib && current_recursion_level > max_recursion) {
/* No more levels of recursion left. */
return false;
}
+ /* Show entries when recursion is set to `Blend file` even when `current_recursion_level` exceeds
+ * `max_recursion`. */
+ if (!is_lib && (current_recursion_level >= max_recursion) &&
+ ((entry->typeflag & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) == 0)) {
+ return false;
+ }
if (entry->typeflag & FILE_TYPE_BLENDERLIB) {
/* Libraries are already loaded recursively when recursive loaded is used. No need to add
* them another time. This loading is done with the `LIST_LIB_RECURSIVE` option. */
@@ -3421,7 +3428,8 @@ static void filelist_readjob_do(const bool do_lib,
entry->name = fileentry_uiname(root, entry->relpath, entry->typeflag, dir);
entry->free_name = true;
- if (filelist_readjob_should_recurse_into_entry(max_recursion, recursion_level, entry)) {
+ if (filelist_readjob_should_recurse_into_entry(
+ max_recursion, is_lib, recursion_level, entry)) {
/* We have a directory we want to list, add it to todo list! */
BLI_join_dirfile(dir, sizeof(dir), root, entry->relpath);
BLI_path_normalize_dir(job_params->main_name, dir);