diff options
author | Pablo Vazquez <pablo@blender.org> | 2021-10-04 17:21:26 +0300 |
---|---|---|
committer | Pablo Vazquez <pablo@blender.org> | 2021-10-04 17:21:26 +0300 |
commit | f0731bd5ac78856e69f1ee09e4762e7d42dc17c9 (patch) | |
tree | af1576c25c72517e970fbe07a4a7ad2d1248004f | |
parent | 2c5661682b61ac4a8a8f45f77a4eff7b85f6f141 (diff) | |
parent | 4a3464050c4e83d446d47c946e17b9540f5a3862 (diff) |
Merge branch 'master' into temp-ui-tweakstemp-ui-tweaks
-rw-r--r-- | intern/cycles/blender/addon/engine.py | 1 | ||||
-rw-r--r-- | intern/cycles/blender/addon/properties.py | 6 | ||||
-rw-r--r-- | intern/cycles/blender/addon/ui.py | 1 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.cpp | 6 | ||||
-rw-r--r-- | intern/cycles/integrator/pass_accessor.cpp | 3 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_shader_data.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/integrator/integrator_init_from_bake.h | 25 | ||||
-rw-r--r-- | intern/cycles/kernel/integrator/integrator_intersect_closest.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 1 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_services.cpp | 13 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_services.h | 1 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/node_normal_map.osl | 2 | ||||
-rw-r--r-- | intern/cycles/render/film.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/render/pass.cpp | 5 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_color_inline.c | 2 | ||||
-rw-r--r-- | source/blender/editors/object/object_bake_api.c | 12 | ||||
-rw-r--r-- | source/blender/editors/space_file/asset_catalog_tree_view.cc | 299 | ||||
-rw-r--r-- | source/blender/editors/space_file/filelist.c | 12 |
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); |