From 5258b17ef60a72048a65d2e26a730407c8405057 Mon Sep 17 00:00:00 2001 From: Omar Emara Date: Mon, 6 Nov 2023 15:15:22 +0100 Subject: [PATCH 01/62] Fix #114260: Compositor sometimes produces straight alpha The compositor sometimes produces straight alpha even though premultiplied alpha is expected. Moreover, there is an inconsistency between the CPU and GPU compositors. For the GPU compositor, this is because GPU textures sometimes store straight alpha, while the compositor always expects premultiplied alpha, so we need to premultiply the alpha in those cases. For the CPU compositor, this is because the image operation didn't premultiply the alpha of byte textures, so we need to ensure premultiplied alpha in those cases. There is a data loss issue in case of byte images, since the IMB module unpremultiplies premultiplied images then the compositor premultiplies it again. But this will be handled in a different patch since it require some design and refactoring first. Pull Request: https://projects.blender.org/blender/blender/pulls/114305 --- .../compositor/intern/COM_MemoryBuffer.cc | 22 +++++++++++++-- .../compositor/intern/COM_MemoryBuffer.h | 7 ++++- .../operations/COM_ImageOperation.cc | 22 +++++++++++---- .../infos/compositor_read_input_info.hh | 4 ++- .../composite/nodes/node_composite_image.cc | 28 +++++++++++++++++++ 5 files changed, 74 insertions(+), 9 deletions(-) diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cc b/source/blender/compositor/intern/COM_MemoryBuffer.cc index e3daf21bc57..6454f6315fc 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.cc +++ b/source/blender/compositor/intern/COM_MemoryBuffer.cc @@ -312,9 +312,21 @@ static void colorspace_to_scene_linear(MemoryBuffer *buf, const rcti &area, Colo } } -void MemoryBuffer::copy_from(const ImBuf *src, const rcti &area, const bool ensure_linear_space) +static void premultiply_alpha(MemoryBuffer *buf, const rcti &area) { - copy_from(src, area, 0, this->get_num_channels(), 0, ensure_linear_space); + for (int y = area.ymin; y < area.ymax; y++) { + for (int x = area.xmin; x < area.xmax; x++) { + straight_to_premul_v4(buf->get_elem(x, y)); + } + } +} + +void MemoryBuffer::copy_from(const ImBuf *src, + const rcti &area, + const bool ensure_premultiplied, + const bool ensure_linear_space) +{ + copy_from(src, area, 0, this->get_num_channels(), 0, ensure_premultiplied, ensure_linear_space); } void MemoryBuffer::copy_from(const ImBuf *src, @@ -322,6 +334,7 @@ void MemoryBuffer::copy_from(const ImBuf *src, const int channel_offset, const int elem_size, const int to_channel_offset, + const bool ensure_premultiplied, const bool ensure_linear_space) { copy_from(src, @@ -331,6 +344,7 @@ void MemoryBuffer::copy_from(const ImBuf *src, area.xmin, area.ymin, to_channel_offset, + ensure_premultiplied, ensure_linear_space); } @@ -341,6 +355,7 @@ void MemoryBuffer::copy_from(const ImBuf *src, const int to_x, const int to_y, const int to_channel_offset, + const bool ensure_premultiplied, const bool ensure_linear_space) { if (src->float_buffer.data) { @@ -363,6 +378,9 @@ void MemoryBuffer::copy_from(const ImBuf *src, if (ensure_linear_space) { colorspace_to_scene_linear(this, area, src->byte_buffer.colorspace); } + if (ensure_premultiplied) { + premultiply_alpha(this, area); + } } else { /* Empty ImBuf source. Fill destination with empty values. */ diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.h b/source/blender/compositor/intern/COM_MemoryBuffer.h index 4738428a22c..d64c6609dc4 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.h +++ b/source/blender/compositor/intern/COM_MemoryBuffer.h @@ -603,12 +603,16 @@ class MemoryBuffer { int to_x, int to_y, int to_channel_offset); - void copy_from(const struct ImBuf *src, const rcti &area, bool ensure_linear_space = false); + void copy_from(const struct ImBuf *src, + const rcti &area, + bool ensure_premultiplied = false, + bool ensure_linear_space = false); void copy_from(const struct ImBuf *src, const rcti &area, int channel_offset, int elem_size, int to_channel_offset, + bool ensure_premultiplied = false, bool ensure_linear_space = false); void copy_from(const struct ImBuf *src, const rcti &src_area, @@ -617,6 +621,7 @@ class MemoryBuffer { int to_x, int to_y, int to_channel_offset, + bool ensure_premultiplied = false, bool ensure_linear_space = false); void fill(const rcti &area, const float *value); diff --git a/source/blender/compositor/operations/COM_ImageOperation.cc b/source/blender/compositor/operations/COM_ImageOperation.cc index b246fdff916..7eb0a4ed238 100644 --- a/source/blender/compositor/operations/COM_ImageOperation.cc +++ b/source/blender/compositor/operations/COM_ImageOperation.cc @@ -91,8 +91,13 @@ void BaseImageOperation::determine_canvas(const rcti & /*preferred_area*/, rcti BKE_image_release_ibuf(image_, stackbuf, nullptr); } -static void sample_image_at_location( - ImBuf *ibuf, float x, float y, PixelSampler sampler, bool make_linear_rgb, float color[4]) +static void sample_image_at_location(ImBuf *ibuf, + float x, + float y, + PixelSampler sampler, + bool make_linear_rgb, + bool ensure_premultiplied, + float color[4]) { if (ibuf->float_buffer.data) { switch (sampler) { @@ -125,6 +130,9 @@ static void sample_image_at_location( IMB_colormanagement_colorspace_to_scene_linear_v4( color, false, ibuf->byte_buffer.colorspace); } + if (ensure_premultiplied) { + straight_to_premul_v4(color); + } } } @@ -138,7 +146,9 @@ void ImageOperation::execute_pixel_sampled(float output[4], float x, float y, Pi zero_v4(output); } else { - sample_image_at_location(buffer_, x, y, sampler, true, output); + const bool ensure_premultiplied = !ELEM( + image_->alpha_mode, IMA_ALPHA_CHANNEL_PACKED, IMA_ALPHA_IGNORE); + sample_image_at_location(buffer_, x, y, sampler, true, ensure_premultiplied, output); } } @@ -146,7 +156,9 @@ void ImageOperation::update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, Span /*inputs*/) { - output->copy_from(buffer_, area, true); + const bool ensure_premultiplied = !ELEM( + image_->alpha_mode, IMA_ALPHA_CHANNEL_PACKED, IMA_ALPHA_IGNORE); + output->copy_from(buffer_, area, ensure_premultiplied, true); } void ImageAlphaOperation::execute_pixel_sampled(float output[4], @@ -161,7 +173,7 @@ void ImageAlphaOperation::execute_pixel_sampled(float output[4], } else { tempcolor[3] = 1.0f; - sample_image_at_location(buffer_, x, y, sampler, false, tempcolor); + sample_image_at_location(buffer_, x, y, sampler, false, false, tempcolor); output[0] = tempcolor[3]; } } diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_read_input_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_read_input_info.hh index a8e80ebb948..d1dee6b8a56 100644 --- a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_read_input_info.hh +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_read_input_info.hh @@ -24,8 +24,10 @@ GPU_SHADER_CREATE_INFO(compositor_read_input_vector) GPU_SHADER_CREATE_INFO(compositor_read_input_color) .additional_info("compositor_read_input_shared") + .push_constant(Type::BOOL, "premultiply_alpha") .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") - .define("READ_EXPRESSION(input_color)", "input_color") + .define("READ_EXPRESSION(input_color)", + "input_color * vec4(vec3(premultiply_alpha ? input_color.a : 1.0), 1.0)") .do_static_compilation(true); GPU_SHADER_CREATE_INFO(compositor_read_input_alpha) diff --git a/source/blender/nodes/composite/nodes/node_composite_image.cc b/source/blender/nodes/composite/nodes/node_composite_image.cc index 73ebe92e1bd..f8226311d26 100644 --- a/source/blender/nodes/composite/nodes/node_composite_image.cc +++ b/source/blender/nodes/composite/nodes/node_composite_image.cc @@ -23,6 +23,7 @@ #include "DEG_depsgraph_query.hh" +#include "DNA_image_types.h" #include "DNA_scene_types.h" #include "DNA_vec_types.h" @@ -519,6 +520,10 @@ class ImageOperation : public NodeOperation { const int2 lower_bound = int2(0); GPU_shader_uniform_2iv(shader, "lower_bound", lower_bound); + if (result.type() == ResultType::Color) { + GPU_shader_uniform_1b(shader, "premultiply_alpha", should_premultiply_alpha(image_user)); + } + const int input_unit = GPU_shader_get_sampler_binding(shader, "input_tx"); GPU_texture_bind(image_texture, input_unit); @@ -570,6 +575,29 @@ class ImageOperation : public NodeOperation { } } + /* Compositor image inputs are expected to be always premultiplied, so identify if the GPU + * texture returned by the image module is straight and needs to be premultiplied. An exception + * is when the image has an alpha mode of channel packed or alpha ignore, in which case, we + * always ignore premultiplication. */ + bool should_premultiply_alpha(ImageUser &image_user) + { + Image *image = get_image(); + if (ELEM(image->alpha_mode, IMA_ALPHA_CHANNEL_PACKED, IMA_ALPHA_IGNORE)) { + return false; + } + + ImBuf *image_buffer = BKE_image_acquire_ibuf(image, &image_user, nullptr); + if (!image_buffer) { + return false; + } + + const bool has_premultiplied_alpha = BKE_image_has_gpu_texture_premultiplied_alpha( + image, image_buffer); + BKE_image_release_ibuf(image, image_buffer, nullptr); + + return !has_premultiplied_alpha; + } + Image *get_image() { return (Image *)bnode().id; From 6d0b5e2ace9830eace00fb2eeee080116b8c2e6d Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Mon, 6 Nov 2023 15:45:00 +0100 Subject: [PATCH 02/62] EEVEE-Next: New shadow settings Remove `Material > Shadow Mode` and use `Object > Shadow Ray Visibility` and `Material > Transparent Shadows` instead. The versioning system auto-updates objects/materials in EEVEE scenes so their behavior is as close as possible to the previous one. Update Cycles to use the native `use_transparent_shadow` property. Note: Material changes don't set any `recalc` flag on the objects that use them, so the EEVEE Next shadow maps don't update when changing settings/nodes. Fixing this issue is required for 4.1, but it's out of the scope of this PR. Pull Request: https://projects.blender.org/blender/blender/pulls/113980 --- intern/cycles/blender/addon/properties.py | 6 -- intern/cycles/blender/addon/ui.py | 2 +- intern/cycles/blender/shader.cpp | 2 +- scripts/startup/bl_ui/properties_material.py | 2 +- scripts/startup/bl_ui/properties_object.py | 5 ++ .../blender/blenkernel/BKE_blender_version.h | 2 +- .../blenloader/intern/versioning_400.cc | 59 +++++++++++++++++++ .../draw/engines/eevee_next/eevee_material.hh | 13 ++-- .../draw/engines/eevee_next/eevee_shader.cc | 14 +++-- .../draw/engines/eevee_next/eevee_shadow.cc | 5 +- .../draw/engines/eevee_next/eevee_shadow.hh | 4 +- .../draw/engines/eevee_next/eevee_sync.cc | 17 ++---- .../blender/makesdna/DNA_material_defaults.h | 2 + source/blender/makesdna/DNA_material_types.h | 1 + .../blender/makesrna/intern/rna_material.cc | 9 +++ 15 files changed, 108 insertions(+), 35 deletions(-) diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 7ddbb90b35a..8cbfc0a98b9 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -1013,12 +1013,6 @@ class CyclesMaterialSettings(bpy.types.PropertyGroup): default="AUTO", ) - use_transparent_shadow: BoolProperty( - name="Transparent Shadows", - description="Use transparent shadows for this material if it contains a Transparent BSDF, " - "disabling will render faster but not give accurate shadows", - default=True, - ) use_bump_map_correction: BoolProperty( name="Bump Map Correction", description="Apply corrections to solve shadow terminator artifacts caused by bump mapping", diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 749d32cc52a..01c88272944 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -1966,7 +1966,7 @@ class CYCLES_MATERIAL_PT_settings_surface(CyclesButtonsPanel, Panel): col = layout.column() col.prop(cmat, "displacement_method", text="Displacement") col.prop(cmat, "emission_sampling") - col.prop(cmat, "use_transparent_shadow") + col.prop(mat, "use_transparent_shadow") col.prop(cmat, "use_bump_map_correction") def draw(self, context): diff --git a/intern/cycles/blender/shader.cpp b/intern/cycles/blender/shader.cpp index 7e131ea9749..7c8c63299a5 100644 --- a/intern/cycles/blender/shader.cpp +++ b/intern/cycles/blender/shader.cpp @@ -1550,7 +1550,7 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all) /* settings */ PointerRNA cmat = RNA_pointer_get(&b_mat.ptr, "cycles"); shader->set_emission_sampling_method(get_emission_sampling(cmat)); - shader->set_use_transparent_shadow(get_boolean(cmat, "use_transparent_shadow")); + shader->set_use_transparent_shadow(b_mat.use_transparent_shadow()); shader->set_use_bump_map_correction(get_boolean(cmat, "use_bump_map_correction")); shader->set_heterogeneous_volume(!get_boolean(cmat, "homogeneous_volume")); shader->set_volume_sampling_method(get_volume_sampling(cmat)); diff --git a/scripts/startup/bl_ui/properties_material.py b/scripts/startup/bl_ui/properties_material.py index fb6957b2e37..74f7b3d0407 100644 --- a/scripts/startup/bl_ui/properties_material.py +++ b/scripts/startup/bl_ui/properties_material.py @@ -300,7 +300,7 @@ class EEVEE_NEXT_MATERIAL_PT_settings_surface(MaterialButtonsPanel, Panel): col.prop(mat, "use_backface_culling_shadow", text="Shadow") # TODO(fclem): Displacement option - # TODO(fclem): Transparent shadow option + layout.prop(mat, "use_transparent_shadow") col = layout.column() col.prop(mat, "surface_render_method", text="Render Method") diff --git a/scripts/startup/bl_ui/properties_object.py b/scripts/startup/bl_ui/properties_object.py index 900543c5585..095f0285ab6 100644 --- a/scripts/startup/bl_ui/properties_object.py +++ b/scripts/startup/bl_ui/properties_object.py @@ -390,6 +390,11 @@ class OBJECT_PT_visibility(ObjectButtonsPanel, Panel): col.prop(ob, "hide_render", text="Renders", toggle=False, invert_checkbox=True) if context.engine == 'BLENDER_EEVEE_NEXT': + if ob.type in {'MESH', 'CURVE', 'SURFACE', 'META', 'FONT', 'CURVES', 'POINTCLOUD', 'VOLUME'}: + layout.separator() + col = layout.column(heading="Ray Visibility") + col.prop(ob, "visible_shadow", text="Shadow", toggle=False) + if ob.type in {'MESH', 'CURVE', 'SURFACE', 'META', 'FONT', 'CURVES', 'POINTCLOUD', 'VOLUME', 'LIGHT'}: layout.separator() col = layout.column(heading="Light Probes") diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 238f9e57d08..8fbe1acd022 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -29,7 +29,7 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 4 +#define BLENDER_FILE_SUBVERSION 5 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and cancel loading the file, showing a warning to diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index d39a370b112..eed551712d5 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -47,11 +47,13 @@ #include "BKE_animsys.h" #include "BKE_armature.h" #include "BKE_attribute.h" +#include "BKE_collection.h" #include "BKE_curve.h" #include "BKE_effect.h" #include "BKE_grease_pencil.hh" #include "BKE_idprop.hh" #include "BKE_main.h" +#include "BKE_material.h" #include "BKE_mesh_legacy_convert.hh" #include "BKE_node.hh" #include "BKE_node_runtime.hh" @@ -298,6 +300,30 @@ static void version_principled_bsdf_update_animdata(ID *owner_id, bNodeTree *ntr } } +static void versioning_eevee_shadow_settings(Object *object) +{ + /** EEVEE no longer uses the Material::blend_shadow property. + * Instead, it uses Object::visibility_flag for disabling shadow casting + */ + + short *material_len = BKE_object_material_len_p(object); + if (!material_len) { + return; + } + + using namespace blender; + bool hide_shadows = *material_len > 0; + for (int i : IndexRange(*material_len)) { + Material *material = BKE_object_material_get(object, i + 1); + if (!material || material->blend_shadow != MA_BS_NONE) { + hide_shadows = false; + } + } + + /* Enable the hide_shadow flag only if there's not any shadow casting material. */ + SET_FLAG_FROM_TEST(object->visibility_flag, hide_shadows, OB_HIDE_SHADOW); +} + void do_versions_after_linking_400(FileData *fd, Main *bmain) { if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 9)) { @@ -382,6 +408,16 @@ void do_versions_after_linking_400(FileData *fd, Main *bmain) BKE_mesh_legacy_face_map_to_generic(bmain); } + if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 5)) { + Scene *scene = static_cast(bmain->scenes.first); + bool is_cycles = scene && STREQ(scene->r.engine, RE_engine_id_CYCLES); + if (!is_cycles) { + LISTBASE_FOREACH (Object *, object, &bmain->objects) { + versioning_eevee_shadow_settings(object); + } + } + } + /** * Versioning code until next subversion bump goes here. * @@ -1783,6 +1819,29 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain) } } + if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 5)) { + /* Unify Material::blend_shadow and Cycles.use_transparent_shadows into the + * Material::blend_flag. */ + Scene *scene = static_cast(bmain->scenes.first); + bool is_cycles = scene && STREQ(scene->r.engine, RE_engine_id_CYCLES); + if (is_cycles) { + LISTBASE_FOREACH (Material *, material, &bmain->materials) { + bool transparent_shadows = true; + if (IDProperty *cmat = version_cycles_properties_from_ID(&material->id)) { + transparent_shadows = version_cycles_property_boolean( + cmat, "use_transparent_shadow", true); + } + SET_FLAG_FROM_TEST(material->blend_flag, transparent_shadows, MA_BL_TRANSPARENT_SHADOW); + } + } + else { + LISTBASE_FOREACH (Material *, material, &bmain->materials) { + bool transparent_shadow = material->blend_shadow != MA_BS_SOLID; + SET_FLAG_FROM_TEST(material->blend_flag, transparent_shadow, MA_BL_TRANSPARENT_SHADOW); + } + } + } + /** * Versioning code until next subversion bump goes here. * diff --git a/source/blender/draw/engines/eevee_next/eevee_material.hh b/source/blender/draw/engines/eevee_next/eevee_material.hh index 439d8cb31a8..27c0c189fc9 100644 --- a/source/blender/draw/engines/eevee_next/eevee_material.hh +++ b/source/blender/draw/engines/eevee_next/eevee_material.hh @@ -69,19 +69,24 @@ enum eMaterialProbe { static inline void material_type_from_shader_uuid(uint64_t shader_uuid, eMaterialPipeline &pipeline_type, - eMaterialGeometry &geometry_type) + eMaterialGeometry &geometry_type, + bool &transparent_shadows) { const uint64_t geometry_mask = ((1u << 4u) - 1u); const uint64_t pipeline_mask = ((1u << 4u) - 1u); geometry_type = static_cast(shader_uuid & geometry_mask); pipeline_type = static_cast((shader_uuid >> 4u) & pipeline_mask); + transparent_shadows = (shader_uuid >> 8u) & 1u; } static inline uint64_t shader_uuid_from_material_type(eMaterialPipeline pipeline_type, - eMaterialGeometry geometry_type) + eMaterialGeometry geometry_type, + char blend_flags) { BLI_assert(geometry_type < (1 << 4)); - return geometry_type | (pipeline_type << 4); + BLI_assert(pipeline_type < (1 << 4)); + uchar transparent_shadows = blend_flags & MA_BL_TRANSPARENT_SHADOW ? 1 : 0; + return geometry_type | (pipeline_type << 4) | (transparent_shadows << 8); } ENUM_OPERATORS(eClosureBits, CLOSURE_AMBIENT_OCCLUSION) @@ -142,7 +147,7 @@ struct MaterialKey { MaterialKey(::Material *mat_, eMaterialGeometry geometry, eMaterialPipeline pipeline) : mat(mat_) { - options = shader_uuid_from_material_type(pipeline, geometry); + options = shader_uuid_from_material_type(pipeline, geometry, mat_->blend_flag); } uint64_t hash() const diff --git a/source/blender/draw/engines/eevee_next/eevee_shader.cc b/source/blender/draw/engines/eevee_next/eevee_shader.cc index d44e97fd485..4f8d9c3dca4 100644 --- a/source/blender/draw/engines/eevee_next/eevee_shader.cc +++ b/source/blender/draw/engines/eevee_next/eevee_shader.cc @@ -311,7 +311,8 @@ void ShaderModule::material_create_info_ammend(GPUMaterial *gpumat, GPUCodegenOu eMaterialPipeline pipeline_type; eMaterialGeometry geometry_type; - material_type_from_shader_uuid(shader_uuid, pipeline_type, geometry_type); + bool transparent_shadows; + material_type_from_shader_uuid(shader_uuid, pipeline_type, geometry_type, transparent_shadows); GPUCodegenOutput &codegen = *codegen_; ShaderCreateInfo &info = *reinterpret_cast(codegen.create_info); @@ -356,7 +357,9 @@ void ShaderModule::material_create_info_ammend(GPUMaterial *gpumat, GPUCodegenOu } if (GPU_material_flag_get(gpumat, GPU_MATFLAG_TRANSPARENT)) { - info.define("MAT_TRANSPARENT"); + if (pipeline_type != MAT_PIPE_SHADOW || transparent_shadows) { + info.define("MAT_TRANSPARENT"); + } /* Transparent material do not have any velocity specific pipeline. */ if (pipeline_type == MAT_PIPE_PREPASS_FORWARD_VELOCITY) { pipeline_type = MAT_PIPE_PREPASS_FORWARD; @@ -641,7 +644,8 @@ GPUMaterial *ShaderModule::material_shader_get(::Material *blender_mat, { bool is_volume = ELEM(pipeline_type, MAT_PIPE_VOLUME_MATERIAL, MAT_PIPE_VOLUME_OCCUPANCY); - uint64_t shader_uuid = shader_uuid_from_material_type(pipeline_type, geometry_type); + uint64_t shader_uuid = shader_uuid_from_material_type( + pipeline_type, geometry_type, blender_mat->blend_flag); return DRW_shader_from_material( blender_mat, nodetree, shader_uuid, is_volume, deferred_compilation, codegen_callback, this); @@ -656,7 +660,7 @@ GPUMaterial *ShaderModule::world_shader_get(::World *blender_world, eMaterialGeometry geometry_type = is_volume ? MAT_GEOM_VOLUME_WORLD : MAT_GEOM_WORLD; - uint64_t shader_uuid = shader_uuid_from_material_type(pipeline_type, geometry_type); + uint64_t shader_uuid = shader_uuid_from_material_type(pipeline_type, geometry_type, 0); return DRW_shader_from_world( blender_world, nodetree, shader_uuid, is_volume, defer_compilation, codegen_callback, this); @@ -671,7 +675,7 @@ GPUMaterial *ShaderModule::material_shader_get(const char *name, eMaterialGeometry geometry_type, bool is_lookdev) { - uint64_t shader_uuid = shader_uuid_from_material_type(pipeline_type, geometry_type); + uint64_t shader_uuid = shader_uuid_from_material_type(pipeline_type, geometry_type, 0); bool is_volume = ELEM(pipeline_type, MAT_PIPE_VOLUME_MATERIAL, MAT_PIPE_VOLUME_OCCUPANCY); diff --git a/source/blender/draw/engines/eevee_next/eevee_shadow.cc b/source/blender/draw/engines/eevee_next/eevee_shadow.cc index 66df398a22b..60639f7878b 100644 --- a/source/blender/draw/engines/eevee_next/eevee_shadow.cc +++ b/source/blender/draw/engines/eevee_next/eevee_shadow.cc @@ -893,11 +893,12 @@ void ShadowModule::begin_sync() } } -void ShadowModule::sync_object(const ObjectHandle &handle, +void ShadowModule::sync_object(const Object *ob, + const ObjectHandle &handle, const ResourceHandle &resource_handle, - bool is_shadow_caster, bool is_alpha_blend) { + bool is_shadow_caster = !(ob->visibility_flag & OB_HIDE_SHADOW); if (!is_shadow_caster && !is_alpha_blend) { return; } diff --git a/source/blender/draw/engines/eevee_next/eevee_shadow.hh b/source/blender/draw/engines/eevee_next/eevee_shadow.hh index 81a88e54975..4808df6d01e 100644 --- a/source/blender/draw/engines/eevee_next/eevee_shadow.hh +++ b/source/blender/draw/engines/eevee_next/eevee_shadow.hh @@ -328,9 +328,9 @@ class ShadowModule { void begin_sync(); /** Register a shadow caster or receiver. */ - void sync_object(const ObjectHandle &handle, + void sync_object(const Object *ob, + const ObjectHandle &handle, const ResourceHandle &resource_handle, - bool is_shadow_caster, bool is_alpha_blend); void end_sync(); diff --git a/source/blender/draw/engines/eevee_next/eevee_sync.cc b/source/blender/draw/engines/eevee_next/eevee_sync.cc index 5b179c963c4..4184c99b4bf 100644 --- a/source/blender/draw/engines/eevee_next/eevee_sync.cc +++ b/source/blender/draw/engines/eevee_next/eevee_sync.cc @@ -140,7 +140,6 @@ void SyncModule::sync_mesh(Object *ob, return; } - bool is_shadow_caster = false; bool is_alpha_blend = false; for (auto i : material_array.gpu_materials.index_range()) { GPUBatch *geom = mat_geom[i]; @@ -173,7 +172,6 @@ void SyncModule::sync_mesh(Object *ob, geometry_call(material.reflection_probe_prepass.sub_pass, geom, res_handle); geometry_call(material.reflection_probe_shading.sub_pass, geom, res_handle); - is_shadow_caster = is_shadow_caster || material.shadow.sub_pass != nullptr; is_alpha_blend = is_alpha_blend || material.is_alpha_blend_transparent; ::Material *mat = GPU_material_get_material(gpu_material); @@ -182,7 +180,7 @@ void SyncModule::sync_mesh(Object *ob, inst_.manager->extract_object_attributes(res_handle, ob_ref, material_array.gpu_materials); - inst_.shadows.sync_object(ob_handle, res_handle, is_shadow_caster, is_alpha_blend); + inst_.shadows.sync_object(ob, ob_handle, res_handle, is_alpha_blend); inst_.cryptomatte.sync_object(ob, res_handle); } @@ -215,7 +213,6 @@ bool SyncModule::sync_sculpt(Object *ob, bool has_motion = false; MaterialArray &material_array = inst_.materials.material_array_get(ob, has_motion); - bool is_shadow_caster = false; bool is_alpha_blend = false; for (SculptBatch &batch : sculpt_batches_per_material_get(ob_ref.object, material_array.gpu_materials)) @@ -249,7 +246,6 @@ bool SyncModule::sync_sculpt(Object *ob, geometry_call(material.reflection_probe_prepass.sub_pass, geom, res_handle); geometry_call(material.reflection_probe_shading.sub_pass, geom, res_handle); - is_shadow_caster = is_shadow_caster || material.shadow.sub_pass != nullptr; is_alpha_blend = is_alpha_blend || material.is_alpha_blend_transparent; GPUMaterial *gpu_material = material_array.gpu_materials[batch.material_slot]; @@ -259,7 +255,7 @@ bool SyncModule::sync_sculpt(Object *ob, inst_.manager->extract_object_attributes(res_handle, ob_ref, material_array.gpu_materials); - inst_.shadows.sync_object(ob_handle, res_handle, is_shadow_caster, is_alpha_blend); + inst_.shadows.sync_object(ob, ob_handle, res_handle, is_alpha_blend); inst_.cryptomatte.sync_object(ob, res_handle); return true; @@ -322,9 +318,8 @@ void SyncModule::sync_point_cloud(Object *ob, ::Material *mat = GPU_material_get_material(gpu_material); inst_.cryptomatte.sync_material(mat); - bool is_caster = material.shadow.sub_pass != nullptr; bool is_alpha_blend = material.is_alpha_blend_transparent; - inst_.shadows.sync_object(ob_handle, res_handle, is_caster, is_alpha_blend); + inst_.shadows.sync_object(ob, ob_handle, res_handle, is_alpha_blend); } /** \} */ @@ -486,9 +481,8 @@ void SyncModule::sync_gpencil(Object *ob, ObjectHandle &ob_handle, ResourceHandl gpencil_drawcall_flush(iter); - bool is_caster = true; /* TODO material.shadow.sub_pass. */ bool is_alpha_blend = true; /* TODO material.is_alpha_blend. */ - inst_.shadows.sync_object(ob_handle, res_handle, is_caster, is_alpha_blend); + inst_.shadows.sync_object(ob, ob_handle, res_handle, is_alpha_blend); } /** \} */ @@ -557,9 +551,8 @@ void SyncModule::sync_curves(Object *ob, ::Material *mat = GPU_material_get_material(gpu_material); inst_.cryptomatte.sync_material(mat); - bool is_caster = material.shadow.sub_pass != nullptr; bool is_alpha_blend = material.is_alpha_blend_transparent; - inst_.shadows.sync_object(ob_handle, res_handle, is_caster, is_alpha_blend); + inst_.shadows.sync_object(ob, ob_handle, res_handle, is_alpha_blend); } /** \} */ diff --git a/source/blender/makesdna/DNA_material_defaults.h b/source/blender/makesdna/DNA_material_defaults.h index 1681d732d60..83dcff68efb 100644 --- a/source/blender/makesdna/DNA_material_defaults.h +++ b/source/blender/makesdna/DNA_material_defaults.h @@ -33,6 +33,8 @@ .alpha_threshold = 0.5f, \ \ .blend_shadow = MA_BS_SOLID, \ + \ + .blend_flag = MA_BL_TRANSPARENT_SHADOW,\ \ .lineart.mat_occlusion = 1, \ } diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index 57b3c5e0324..159c34335ea 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -360,6 +360,7 @@ enum { MA_BL_TRANSLUCENCY = (1 << 3), MA_BL_LIGHTPROBE_VOLUME_DOUBLE_SIDED = (1 << 4), MA_BL_CULL_BACKFACE_SHADOW = (1 << 5), + MA_BL_TRANSPARENT_SHADOW = (1 << 6), }; /** #Material::blend_shadow */ diff --git a/source/blender/makesrna/intern/rna_material.cc b/source/blender/makesrna/intern/rna_material.cc index a41401cabfc..c11d0ea30d8 100644 --- a/source/blender/makesrna/intern/rna_material.cc +++ b/source/blender/makesrna/intern/rna_material.cc @@ -909,6 +909,15 @@ void RNA_def_material(BlenderRNA *brna) prop, "Shadow Backface Culling", "Use back face culling when casting shadows"); RNA_def_property_update(prop, 0, "rna_Material_draw_update"); + prop = RNA_def_property(srna, "use_transparent_shadow", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, nullptr, "blend_flag", MA_BL_TRANSPARENT_SHADOW); + RNA_def_property_ui_text( + prop, + "Transparent Shadows", + "Use transparent shadows for this material if it contains a Transparent BSDF, " + "disabling will render faster but not give accurate shadows"); + RNA_def_property_update(prop, 0, "rna_Material_draw_update"); + prop = RNA_def_property(srna, "lightprobe_volume_single_sided", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna( prop, nullptr, "blend_flag", MA_BL_LIGHTPROBE_VOLUME_DOUBLE_SIDED); From 9956ef4622d991695a9e1570ceff223ecfd22720 Mon Sep 17 00:00:00 2001 From: Thomas Barlow Date: Mon, 6 Nov 2023 15:51:07 +0100 Subject: [PATCH 03/62] PyAPI: Allow prop collection raw array read access for non-editable props Non-editable prop collection items would always fall back to the slower loop in `rna_raw_access`. This patch changes `RNA_property_collection_raw_array` to only fail with non-editable items when intending to set values, allowing for the faster raw array access to occur when reading values in `rna_raw_access`. This brings the Python API `bpy_prop_collection.foreach_get` performance of `Mesh.vertex_normals`/`polygon_normals`/`corner_normals` up to the same speed as generic `FLOAT_VECTOR` attributes with the same domains. Given a mesh with 393216 corners: Using `foreach_get` with the "vector" prop and a compatible buffer object: - Corner vector attribute: ~0.9ms - Corner normals (before): ~7.9ms - Corner normals (after): ~0.9ms Using `foreach_get` with the "vector" prop and a Python list: - Corner vector attribute: ~11.0ms - Corner normals (before): ~18.0ms - Corner normals (after): ~11.0ms Pull Request: https://projects.blender.org/blender/blender/pulls/114063 --- source/blender/makesrna/RNA_access.hh | 6 ++---- source/blender/makesrna/intern/rna_access.cc | 10 ++++------ 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/source/blender/makesrna/RNA_access.hh b/source/blender/makesrna/RNA_access.hh index 9939af9c949..a6ffdd8d401 100644 --- a/source/blender/makesrna/RNA_access.hh +++ b/source/blender/makesrna/RNA_access.hh @@ -451,10 +451,8 @@ int RNA_property_collection_assign_int(PointerRNA *ptr, bool RNA_property_collection_type_get(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr); /* efficient functions to set properties for arrays */ -int RNA_property_collection_raw_array(PointerRNA *ptr, - PropertyRNA *prop, - PropertyRNA *itemprop, - RawArray *array); +int RNA_property_collection_raw_array( + PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, bool set, RawArray *array); int RNA_property_collection_raw_get(struct ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, diff --git a/source/blender/makesrna/intern/rna_access.cc b/source/blender/makesrna/intern/rna_access.cc index 4b5c644f8c9..68dcde90226 100644 --- a/source/blender/makesrna/intern/rna_access.cc +++ b/source/blender/makesrna/intern/rna_access.cc @@ -4405,10 +4405,8 @@ bool RNA_property_collection_type_get(PointerRNA *ptr, PropertyRNA *prop, Pointe return ((r_ptr->type = rna_ensure_property(prop)->srna) ? 1 : 0); } -int RNA_property_collection_raw_array(PointerRNA *ptr, - PropertyRNA *prop, - PropertyRNA *itemprop, - RawArray *array) +int RNA_property_collection_raw_array( + PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, bool set, RawArray *array) { CollectionPropertyIterator iter; ArrayIterator *internal; @@ -4429,7 +4427,7 @@ int RNA_property_collection_raw_array(PointerRNA *ptr, internal = &iter.internal.array; arrayp = (iter.valid) ? static_cast(iter.ptr.data) : nullptr; - if (internal->skip || !RNA_property_editable(&iter.ptr, itemprop)) { + if (internal->skip || (set && !RNA_property_editable(&iter.ptr, itemprop))) { /* we might skip some items, so it's not a proper array */ RNA_property_collection_end(&iter); return 0; @@ -4587,7 +4585,7 @@ static int rna_raw_access(ReportList *reports, itemprop = nullptr; } /* try to access as raw array */ - else if (RNA_property_collection_raw_array(ptr, prop, itemprop, &out)) { + else if (RNA_property_collection_raw_array(ptr, prop, itemprop, set, &out)) { int arraylen = (itemlen == 0) ? 1 : itemlen; if (in.len != arraylen * out.len) { BKE_reportf(reports, From f1116f64bdd0b4ad9e33e5a3b5e8a5332c36b35a Mon Sep 17 00:00:00 2001 From: Alaska Date: Mon, 6 Nov 2023 17:25:14 +0100 Subject: [PATCH 04/62] Fix #114435: Harsh Principled BSDF Subsurface transition in EEVEE Fixes a harsh transistion between diffuse and subsurface scattering materials in the Principled BSDF as a user increases the Subsurface Scattering Weight from 0 to 1. Pull Request: https://projects.blender.org/blender/blender/pulls/114500 --- .../gpu/shaders/material/gpu_shader_material_principled.glsl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl index 3af6ba4cdca..7a5f2ac9ac9 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl @@ -221,7 +221,8 @@ void node_bsdf_principled(vec4 base_color, /* Diffuse component */ if (true) { - diffuse_data.sss_radius = max(subsurface_radius * subsurface_scale, vec3(0.0)); + diffuse_data.sss_radius = subsurface_weight * + max(subsurface_radius * subsurface_scale, vec3(0.0)); diffuse_data.sss_id = uint(do_sss); diffuse_data.color += weight * diffuse_sss_base_color.rgb * coat_tint.rgb; } From 4f52ab0b49a9e50fccc3a9f54fd7ea5652a82413 Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Mon, 6 Nov 2023 17:30:48 +0100 Subject: [PATCH 05/62] Cycles: Workaround MetalRT TLAS build hanging in some motion blur scenes This PR works around an issue where zero-filled motion TLAS instance descriptors can cause unexpected hangs during downstream TLAS builds on M3. Instead of zeroing the descriptor we insert an explicit "null" BLAS, achieving the same result. Pull Request: https://projects.blender.org/blender/blender/pulls/114544 --- intern/cycles/device/metal/bvh.h | 3 ++ intern/cycles/device/metal/bvh.mm | 86 +++++++++++++++++++++++++------ 2 files changed, 74 insertions(+), 15 deletions(-) diff --git a/intern/cycles/device/metal/bvh.h b/intern/cycles/device/metal/bvh.h index 75d8e326941..46c810c9b72 100644 --- a/intern/cycles/device/metal/bvh.h +++ b/intern/cycles/device/metal/bvh.h @@ -19,6 +19,9 @@ class BVHMetal : public BVH { API_AVAILABLE(macos(11.0)) id accel_struct = nil; + API_AVAILABLE(macos(11.0)) + id null_BLAS = nil; + API_AVAILABLE(macos(11.0)) vector> blas_array; diff --git a/intern/cycles/device/metal/bvh.mm b/intern/cycles/device/metal/bvh.mm index a4de673a0f5..ba86e80f587 100644 --- a/intern/cycles/device/metal/bvh.mm +++ b/intern/cycles/device/metal/bvh.mm @@ -124,6 +124,66 @@ BVHMetal::~BVHMetal() stats.mem_free(accel_struct.allocatedSize); [accel_struct release]; } + + if (null_BLAS) { + [null_BLAS release]; + } + } +} + +id make_null_BLAS(id device, id queue) +{ + if (@available(macos 12.0, *)) { + MTLResourceOptions storage_mode = MTLResourceStorageModeManaged; + if (device.hasUnifiedMemory) { + storage_mode = MTLResourceStorageModeShared; + } + + id nullBuf = [device newBufferWithLength:0 options:storage_mode]; + + /* Create an acceleration structure. */ + MTLAccelerationStructureTriangleGeometryDescriptor *geomDesc = + [MTLAccelerationStructureTriangleGeometryDescriptor descriptor]; + geomDesc.vertexBuffer = nullBuf; + geomDesc.vertexBufferOffset = 0; + geomDesc.vertexStride = sizeof(float3); + geomDesc.indexBuffer = nullBuf; + geomDesc.indexBufferOffset = 0; + geomDesc.indexType = MTLIndexTypeUInt32; + geomDesc.triangleCount = 0; + geomDesc.intersectionFunctionTableOffset = 0; + geomDesc.opaque = true; + geomDesc.allowDuplicateIntersectionFunctionInvocation = false; + + MTLPrimitiveAccelerationStructureDescriptor *accelDesc = + [MTLPrimitiveAccelerationStructureDescriptor descriptor]; + accelDesc.geometryDescriptors = @[ geomDesc ]; + accelDesc.usage |= MTLAccelerationStructureUsageExtendedLimits; + + MTLAccelerationStructureSizes accelSizes = [device + accelerationStructureSizesWithDescriptor:accelDesc]; + id accel_struct = [device + newAccelerationStructureWithSize:accelSizes.accelerationStructureSize]; + id scratchBuf = [device newBufferWithLength:accelSizes.buildScratchBufferSize + options:MTLResourceStorageModePrivate]; + id sizeBuf = [device newBufferWithLength:8 options:MTLResourceStorageModeShared]; + id accelCommands = [queue commandBuffer]; + id accelEnc = + [accelCommands accelerationStructureCommandEncoder]; + [accelEnc buildAccelerationStructure:accel_struct + descriptor:accelDesc + scratchBuffer:scratchBuf + scratchBufferOffset:0]; + [accelEnc endEncoding]; + [accelCommands commit]; + [accelCommands waitUntilCompleted]; + + /* free temp resources */ + [scratchBuf release]; + [nullBuf release]; + [sizeBuf release]; + + return accel_struct; } } @@ -1005,7 +1065,7 @@ bool BVHMetal::build_TLAS(Progress &progress, int blas_index = (int)[all_blas count]; instance_mapping[blas] = blas_index; if (@available(macos 12.0, *)) { - [all_blas addObject:blas->accel_struct]; + [all_blas addObject:(blas ? blas->accel_struct : null_BLAS)]; } return blas_index; } @@ -1052,22 +1112,18 @@ bool BVHMetal::build_TLAS(Progress &progress, if (!blas || !blas->accel_struct) { /* Place a degenerate instance, to ensure [[instance_id]] equals ob->get_device_index() * in our intersection functions */ - if (motion_blur) { - MTLAccelerationStructureMotionInstanceDescriptor *instances = - (MTLAccelerationStructureMotionInstanceDescriptor *)[instanceBuf contents]; - MTLAccelerationStructureMotionInstanceDescriptor &desc = instances[instance_index++]; - memset(&desc, 0x00, sizeof(desc)); + blas = nullptr; + + /* Workaround for issue in macOS <= 14.1: Insert degenerate BLAS instead of zero-filling + * the descriptor. */ + if (!null_BLAS) { + null_BLAS = make_null_BLAS(device, queue); } - else { - MTLAccelerationStructureUserIDInstanceDescriptor *instances = - (MTLAccelerationStructureUserIDInstanceDescriptor *)[instanceBuf contents]; - MTLAccelerationStructureUserIDInstanceDescriptor &desc = instances[instance_index++]; - memset(&desc, 0x00, sizeof(desc)); - } - blas_array.push_back(nil); - continue; + blas_array.push_back(null_BLAS); + } + else { + blas_array.push_back(blas->accel_struct); } - blas_array.push_back(blas->accel_struct); uint32_t accel_struct_index = get_blas_index(blas); From 10848b9774c5030fd36b7672c5880160f3595ce2 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Mon, 6 Nov 2023 18:11:38 +0100 Subject: [PATCH 06/62] Fix #114229: Hydra MaterialX crash when node name starts with digit Pull Request: https://projects.blender.org/blender/blender/pulls/114471 --- source/blender/nodes/shader/CMakeLists.txt | 4 +++ .../nodes/shader/materialx/node_parser.cc | 34 ++++++++++++++----- .../nodes/shader/materialx/node_parser.h | 2 +- .../shader/nodes/node_shader_tex_image.cc | 3 +- 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/source/blender/nodes/shader/CMakeLists.txt b/source/blender/nodes/shader/CMakeLists.txt index 0caf0e164c5..f0c226c316e 100644 --- a/source/blender/nodes/shader/CMakeLists.txt +++ b/source/blender/nodes/shader/CMakeLists.txt @@ -139,6 +139,10 @@ set(LIB if(WITH_MATERIALX) add_definitions(-DWITH_MATERIALX) + list(APPEND INC + ${USD_INCLUDE_DIRS} + ${BOOST_INCLUDE_DIR} + ) list(APPEND SRC materialx/material.cc materialx/node_item.cc diff --git a/source/blender/nodes/shader/materialx/node_parser.cc b/source/blender/nodes/shader/materialx/node_parser.cc index eeb7ae88320..c0f3ec1064a 100644 --- a/source/blender/nodes/shader/materialx/node_parser.cc +++ b/source/blender/nodes/shader/materialx/node_parser.cc @@ -2,6 +2,8 @@ * * SPDX-License-Identifier: GPL-2.0-or-later */ +#include + #include "node_parser.h" #include "group_nodes.h" @@ -58,26 +60,40 @@ NodeItem NodeParser::compute_full() return res; } -std::string NodeParser::node_name() const +std::string NodeParser::node_name(bool with_out_socket) const { + auto valid_name = [](const std::string &name) { + /* Node name should suite to MatX and USD valid names. + * It shouldn't start from '_', due to error occured in Storm delegate. */ + std::string res = MaterialX::createValidName(pxr::TfMakeValidIdentifier(name)); + if (res[0] == '_') { + res = "node" + res; + } + return res; + }; + std::string name = node_->name; - if (node_->output_sockets().size() > 1) { - name += std::string("_") + socket_out_->name; - } - if (ELEM(to_type_, NodeItem::Type::BSDF, NodeItem::Type::EDF, NodeItem::Type::SurfaceOpacity)) { - name += "_" + NodeItem::type(to_type_); + if (with_out_socket) { + if (node_->output_sockets().size() > 1) { + name += std::string("_") + socket_out_->name; + } + if (ELEM(to_type_, NodeItem::Type::BSDF, NodeItem::Type::EDF, NodeItem::Type::SurfaceOpacity)) + { + name += "_" + NodeItem::type(to_type_); + } } #ifdef USE_MATERIALX_NODEGRAPH - return MaterialX::createValidName(name); + return valid_name(name); #else + std::string prefix; GroupNodeParser *gr = group_parser_; while (gr) { const bNodeTree *ngroup = reinterpret_cast(gr->node_->id); - prefix = MaterialX::createValidName(ngroup->id.name) + "_" + prefix; + prefix = valid_name(ngroup->id.name) + "_" + prefix; gr = gr->group_parser_; } - return prefix + MaterialX::createValidName(name); + return prefix + valid_name(name); #endif } diff --git a/source/blender/nodes/shader/materialx/node_parser.h b/source/blender/nodes/shader/materialx/node_parser.h index 6fca45a02af..87d860fe9d8 100644 --- a/source/blender/nodes/shader/materialx/node_parser.h +++ b/source/blender/nodes/shader/materialx/node_parser.h @@ -50,7 +50,7 @@ class NodeParser { virtual NodeItem compute_full(); protected: - std::string node_name() const; + std::string node_name(bool with_out_socket = true) const; NodeItem create_node(const std::string &category, NodeItem::Type type); NodeItem create_node(const std::string &category, NodeItem::Type type, diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.cc b/source/blender/nodes/shader/nodes/node_shader_tex_image.cc index bc84d5aa917..75f3da75f67 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_image.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.cc @@ -178,8 +178,7 @@ NODE_SHADER_MATERIALX_BEGIN #ifdef WITH_MATERIALX { /* Getting node name for Color output. This name will be used for node. */ - std::string image_node_name = node_name(); - image_node_name = image_node_name.substr(0, image_node_name.rfind('_')) + "_Color"; + std::string image_node_name = node_name(false) + "_Color"; NodeItem res = empty(); res.node = graph_->getNode(image_node_name); From 0dad1645050b6e03db91023348f86d9e76fa420d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 6 Nov 2023 18:34:54 +0100 Subject: [PATCH 07/62] Fix #114540: macOS crash on startup after recent changes in c2b755a3c00 Thanks to Michael Parkin-White for finding the cause. Ref #114513 --- source/blender/gpu/metal/mtl_shader_generator.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/gpu/metal/mtl_shader_generator.mm b/source/blender/gpu/metal/mtl_shader_generator.mm index 3e99a6d9cb8..cfdbfc3566a 100644 --- a/source/blender/gpu/metal/mtl_shader_generator.mm +++ b/source/blender/gpu/metal/mtl_shader_generator.mm @@ -622,7 +622,7 @@ void extract_shared_memory_blocks(MSLGeneratorInterface &msl_iface, } int len = c_next_space - c; BLI_assert(len < 256); - BLI_strncpy(buf, c, len); + BLI_strncpy(buf, c, len + 1); new_shared_block.type_name = std::string(buf); /* Read var-name. @@ -662,13 +662,13 @@ void extract_shared_memory_blocks(MSLGeneratorInterface &msl_iface, } len = varname_end - c; BLI_assert(len < 256); - BLI_strncpy(buf, c, len); + BLI_strncpy(buf, c, len + 1); new_shared_block.varname = std::string(buf); /* Determine if array. */ if (new_shared_block.is_array) { int len = c_expr_end - c_array_begin; - BLI_strncpy(buf, c_array_begin, len); + BLI_strncpy(buf, c_array_begin, len + 1); new_shared_block.array_decl = std::string(buf); } From fe9e28c0860e7a8195d291d0a47b40440e1e3947 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 6 Nov 2023 18:50:25 +0100 Subject: [PATCH 08/62] Fix build error on macOS x86, after Metal motion blur workaround Ref #114544 --- intern/cycles/device/metal/bvh.mm | 110 +++++++++++++++--------------- 1 file changed, 54 insertions(+), 56 deletions(-) diff --git a/intern/cycles/device/metal/bvh.mm b/intern/cycles/device/metal/bvh.mm index ba86e80f587..45780b4f166 100644 --- a/intern/cycles/device/metal/bvh.mm +++ b/intern/cycles/device/metal/bvh.mm @@ -131,62 +131,6 @@ BVHMetal::~BVHMetal() } } -id make_null_BLAS(id device, id queue) -{ - if (@available(macos 12.0, *)) { - MTLResourceOptions storage_mode = MTLResourceStorageModeManaged; - if (device.hasUnifiedMemory) { - storage_mode = MTLResourceStorageModeShared; - } - - id nullBuf = [device newBufferWithLength:0 options:storage_mode]; - - /* Create an acceleration structure. */ - MTLAccelerationStructureTriangleGeometryDescriptor *geomDesc = - [MTLAccelerationStructureTriangleGeometryDescriptor descriptor]; - geomDesc.vertexBuffer = nullBuf; - geomDesc.vertexBufferOffset = 0; - geomDesc.vertexStride = sizeof(float3); - geomDesc.indexBuffer = nullBuf; - geomDesc.indexBufferOffset = 0; - geomDesc.indexType = MTLIndexTypeUInt32; - geomDesc.triangleCount = 0; - geomDesc.intersectionFunctionTableOffset = 0; - geomDesc.opaque = true; - geomDesc.allowDuplicateIntersectionFunctionInvocation = false; - - MTLPrimitiveAccelerationStructureDescriptor *accelDesc = - [MTLPrimitiveAccelerationStructureDescriptor descriptor]; - accelDesc.geometryDescriptors = @[ geomDesc ]; - accelDesc.usage |= MTLAccelerationStructureUsageExtendedLimits; - - MTLAccelerationStructureSizes accelSizes = [device - accelerationStructureSizesWithDescriptor:accelDesc]; - id accel_struct = [device - newAccelerationStructureWithSize:accelSizes.accelerationStructureSize]; - id scratchBuf = [device newBufferWithLength:accelSizes.buildScratchBufferSize - options:MTLResourceStorageModePrivate]; - id sizeBuf = [device newBufferWithLength:8 options:MTLResourceStorageModeShared]; - id accelCommands = [queue commandBuffer]; - id accelEnc = - [accelCommands accelerationStructureCommandEncoder]; - [accelEnc buildAccelerationStructure:accel_struct - descriptor:accelDesc - scratchBuffer:scratchBuf - scratchBufferOffset:0]; - [accelEnc endEncoding]; - [accelCommands commit]; - [accelCommands waitUntilCompleted]; - - /* free temp resources */ - [scratchBuf release]; - [nullBuf release]; - [sizeBuf release]; - - return accel_struct; - } -} - bool BVHMetal::build_BLAS_mesh(Progress &progress, id device, id queue, @@ -1024,6 +968,60 @@ bool BVHMetal::build_TLAS(Progress &progress, g_bvh_build_throttler.wait_for_all(); if (@available(macos 12.0, *)) { + /* Defined inside available check, for return type to be available. */ + auto make_null_BLAS = [](id device, + id queue) -> id { + MTLResourceOptions storage_mode = MTLResourceStorageModeManaged; + if (device.hasUnifiedMemory) { + storage_mode = MTLResourceStorageModeShared; + } + + id nullBuf = [device newBufferWithLength:0 options:storage_mode]; + + /* Create an acceleration structure. */ + MTLAccelerationStructureTriangleGeometryDescriptor *geomDesc = + [MTLAccelerationStructureTriangleGeometryDescriptor descriptor]; + geomDesc.vertexBuffer = nullBuf; + geomDesc.vertexBufferOffset = 0; + geomDesc.vertexStride = sizeof(float3); + geomDesc.indexBuffer = nullBuf; + geomDesc.indexBufferOffset = 0; + geomDesc.indexType = MTLIndexTypeUInt32; + geomDesc.triangleCount = 0; + geomDesc.intersectionFunctionTableOffset = 0; + geomDesc.opaque = true; + geomDesc.allowDuplicateIntersectionFunctionInvocation = false; + + MTLPrimitiveAccelerationStructureDescriptor *accelDesc = + [MTLPrimitiveAccelerationStructureDescriptor descriptor]; + accelDesc.geometryDescriptors = @[ geomDesc ]; + accelDesc.usage |= MTLAccelerationStructureUsageExtendedLimits; + + MTLAccelerationStructureSizes accelSizes = [device + accelerationStructureSizesWithDescriptor:accelDesc]; + id accel_struct = [device + newAccelerationStructureWithSize:accelSizes.accelerationStructureSize]; + id scratchBuf = [device newBufferWithLength:accelSizes.buildScratchBufferSize + options:MTLResourceStorageModePrivate]; + id sizeBuf = [device newBufferWithLength:8 options:MTLResourceStorageModeShared]; + id accelCommands = [queue commandBuffer]; + id accelEnc = + [accelCommands accelerationStructureCommandEncoder]; + [accelEnc buildAccelerationStructure:accel_struct + descriptor:accelDesc + scratchBuffer:scratchBuf + scratchBufferOffset:0]; + [accelEnc endEncoding]; + [accelCommands commit]; + [accelCommands waitUntilCompleted]; + + /* free temp resources */ + [scratchBuf release]; + [nullBuf release]; + [sizeBuf release]; + + return accel_struct; + }; uint32_t num_instances = 0; uint32_t num_motion_transforms = 0; From 03bbdd804c161648a9603ccb2b561afa09e0f2e1 Mon Sep 17 00:00:00 2001 From: Aras Pranckevicius Date: Mon, 6 Nov 2023 13:33:52 +0200 Subject: [PATCH 09/62] Cleanup: move math_geom.c to c++ --- source/blender/blenlib/CMakeLists.txt | 2 +- .../intern/{math_geom.c => math_geom.cc} | 21 +++++++------------ 2 files changed, 8 insertions(+), 15 deletions(-) rename source/blender/blenlib/intern/{math_geom.c => math_geom.cc} (99%) diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 594ff99e515..cf087d4f68f 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -101,7 +101,7 @@ set(SRC intern/math_color.c intern/math_color_blend_inline.c intern/math_color_inline.c - intern/math_geom.c + intern/math_geom.cc intern/math_geom_inline.c intern/math_interp.c intern/math_matrix.c diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.cc similarity index 99% rename from source/blender/blenlib/intern/math_geom.c rename to source/blender/blenlib/intern/math_geom.cc index 93839a6b65b..984f1ef5276 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.cc @@ -6,11 +6,10 @@ * \ingroup bli */ +#include "BLI_array.hh" #include "BLI_math_base.h" #include "BLI_math_geom.h" -#include "MEM_guardedalloc.h" - #include "BLI_math_bits.h" #include "BLI_math_matrix.h" #include "BLI_math_rotation.h" @@ -1466,7 +1465,7 @@ int isect_line_sphere_v2(const float l1[2], bool isect_point_poly_v2(const float pt[2], const float verts[][2], const uint nr, - const bool UNUSED(use_holes)) + [[maybe_unused]] const bool use_holes) { /* Keep in sync with #isect_point_poly_v2_int. */ @@ -1486,7 +1485,7 @@ bool isect_point_poly_v2(const float pt[2], bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const uint nr, - const bool UNUSED(use_holes)) + [[maybe_unused]] const bool use_holes) { /* Keep in sync with #isect_point_poly_v2. */ @@ -3953,11 +3952,11 @@ int interp_sparse_array(float *array, const int list_size, const float skipval) float valid_last = skipval; int valid_ofs = 0; - float *array_up = MEM_callocN(sizeof(float) * (size_t)list_size, "interp_sparse_array up"); - float *array_down = MEM_callocN(sizeof(float) * (size_t)list_size, "interp_sparse_array up"); + blender::Array array_up(list_size); + blender::Array array_down(list_size); - int *ofs_tot_up = MEM_callocN(sizeof(int) * (size_t)list_size, "interp_sparse_array tup"); - int *ofs_tot_down = MEM_callocN(sizeof(int) * (size_t)list_size, "interp_sparse_array tdown"); + blender::Array ofs_tot_up(list_size); + blender::Array ofs_tot_down(list_size); for (i = 0; i < list_size; i++) { if (array[i] == skipval) { @@ -4001,12 +4000,6 @@ int interp_sparse_array(float *array, const int list_size, const float skipval) } } - MEM_freeN(array_up); - MEM_freeN(array_down); - - MEM_freeN(ofs_tot_up); - MEM_freeN(ofs_tot_down); - return 1; } From 6e4adbe694b8cf2ac49874af72afb1615485b488 Mon Sep 17 00:00:00 2001 From: Aras Pranckevicius Date: Mon, 6 Nov 2023 13:39:29 +0200 Subject: [PATCH 10/62] Cleanup: use_holes arg to isect_point_poly_v2 has been ignored since 2013 07851dd8df23 made the use_holes argument be no longer used. --- source/blender/blenlib/BLI_math_geom.h | 6 ++---- source/blender/blenlib/intern/lasso_2d.c | 2 +- source/blender/blenlib/intern/math_geom.cc | 10 ++-------- source/blender/bmesh/intern/bmesh_polygon.cc | 2 +- source/blender/bmesh/intern/bmesh_query_uv.cc | 3 +-- source/blender/editors/mesh/editmesh_knife.cc | 2 +- source/blender/modifiers/intern/MOD_surfacedeform.cc | 2 +- 7 files changed, 9 insertions(+), 18 deletions(-) diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index f14a3776f7a..7239e2ab723 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -790,12 +790,10 @@ bool isect_ray_line_v3(const float ray_origin[3], bool isect_point_poly_v2(const float pt[2], const float verts[][2], - unsigned int nr, - bool use_holes); + unsigned int nr); bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], - unsigned int nr, - bool use_holes); + unsigned int nr); /** * Point in quad - only convex quads. diff --git a/source/blender/blenlib/intern/lasso_2d.c b/source/blender/blenlib/intern/lasso_2d.c index 18b0d141743..8a20dbe2c25 100644 --- a/source/blender/blenlib/intern/lasso_2d.c +++ b/source/blender/blenlib/intern/lasso_2d.c @@ -48,7 +48,7 @@ bool BLI_lasso_is_point_inside(const int mcoords[][2], } const int pt[2] = {sx, sy}; - return isect_point_poly_v2_int(pt, mcoords, mcoords_len, true); + return isect_point_poly_v2_int(pt, mcoords, mcoords_len); } bool BLI_lasso_is_edge_inside(const int mcoords[][2], diff --git a/source/blender/blenlib/intern/math_geom.cc b/source/blender/blenlib/intern/math_geom.cc index 984f1ef5276..7051acc711f 100644 --- a/source/blender/blenlib/intern/math_geom.cc +++ b/source/blender/blenlib/intern/math_geom.cc @@ -1462,10 +1462,7 @@ int isect_line_sphere_v2(const float l1[2], return -1; } -bool isect_point_poly_v2(const float pt[2], - const float verts[][2], - const uint nr, - [[maybe_unused]] const bool use_holes) +bool isect_point_poly_v2(const float pt[2], const float verts[][2], const uint nr) { /* Keep in sync with #isect_point_poly_v2_int. */ @@ -1482,10 +1479,7 @@ bool isect_point_poly_v2(const float pt[2], } return isect; } -bool isect_point_poly_v2_int(const int pt[2], - const int verts[][2], - const uint nr, - [[maybe_unused]] const bool use_holes) +bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const uint nr) { /* Keep in sync with #isect_point_poly_v2. */ diff --git a/source/blender/bmesh/intern/bmesh_polygon.cc b/source/blender/bmesh/intern/bmesh_polygon.cc index 1b5a95907c5..983bf6144f7 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.cc +++ b/source/blender/bmesh/intern/bmesh_polygon.cc @@ -944,7 +944,7 @@ bool BM_face_point_inside_test(const BMFace *f, const float co[3]) mul_v2_m3v3(projverts[i], axis_mat, l_iter->v->co); } - return isect_point_poly_v2(co_2d, projverts, f->len, false); + return isect_point_poly_v2(co_2d, projverts, f->len); } void BM_face_triangulate(BMesh *bm, diff --git a/source/blender/bmesh/intern/bmesh_query_uv.cc b/source/blender/bmesh/intern/bmesh_query_uv.cc index 9e872cbba32..0722fdf5228 100644 --- a/source/blender/bmesh/intern/bmesh_query_uv.cc +++ b/source/blender/bmesh/intern/bmesh_query_uv.cc @@ -208,6 +208,5 @@ bool BM_face_uv_point_inside_test(const BMFace *f, const float co[2], const int projverts[i] = BM_ELEM_CD_GET_FLOAT2_P(l_iter, cd_loop_uv_offset); } - return isect_point_poly_v2( - co, reinterpret_cast(projverts.data()), f->len, false); + return isect_point_poly_v2(co, reinterpret_cast(projverts.data()), f->len); } diff --git a/source/blender/editors/mesh/editmesh_knife.cc b/source/blender/editors/mesh/editmesh_knife.cc index dc755a97bbc..8cc1bc0e142 100644 --- a/source/blender/editors/mesh/editmesh_knife.cc +++ b/source/blender/editors/mesh/editmesh_knife.cc @@ -4965,7 +4965,7 @@ static bool edbm_mesh_knife_point_isect(LinkNode *polys, const float cent_ss[2]) while (p) { const float(*mval_fl)[2] = static_cast(p->link); const int mval_tot = MEM_allocN_len(mval_fl) / sizeof(*mval_fl); - isect += int(isect_point_poly_v2(cent_ss, mval_fl, mval_tot - 1, false)); + isect += int(isect_point_poly_v2(cent_ss, mval_fl, mval_tot - 1)); p = p->next; } diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.cc b/source/blender/modifiers/intern/MOD_surfacedeform.cc index d73e09a3a9b..6a48ecde160 100644 --- a/source/blender/modifiers/intern/MOD_surfacedeform.cc +++ b/source/blender/modifiers/intern/MOD_surfacedeform.cc @@ -606,7 +606,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, return nullptr; } - bpoly->inside = isect_point_poly_v2(bpoly->point_v2, bpoly->coords_v2, face.size(), false); + bpoly->inside = isect_point_poly_v2(bpoly->point_v2, bpoly->coords_v2, face.size()); /* Initialize weight components */ bpoly->weight_angular = 1.0f; From 0db6d8a5fca86f52830a7f3d1b857b022264f4e2 Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Mon, 6 Nov 2023 20:35:14 +0100 Subject: [PATCH 11/62] EEVEE-Next: Fix shadow tests Fix an issue in `find_first_valid` where Nvidia would incorrectly increment `src` after return. This should fix the issue where some tiles would stay corrupted until resetting EEVEE. Initialize tiles_data in `TestAlloc` so it doesn't fail in debug builds. Pull Request: https://projects.blender.org/blender/blender/pulls/114550 --- .../eevee_next/shaders/eevee_shadow_page_defrag_comp.glsl | 7 +++++-- source/blender/draw/tests/eevee_test.cc | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_page_defrag_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_page_defrag_comp.glsl index 4e8e448e596..3a1d292bfc2 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_page_defrag_comp.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_shadow_page_defrag_comp.glsl @@ -24,11 +24,14 @@ const uint max_page = SHADOW_MAX_PAGE; void find_first_valid(inout uint src, uint dst) { - for (; src < dst; src++) { - if (pages_cached_buf[src % max_page].x != uint(-1)) { + for (uint i = src; i < dst; i++) { + if (pages_cached_buf[i % max_page].x != uint(-1)) { + src = i; return; } } + + src = dst; } void page_cached_free(uint page_index) diff --git a/source/blender/draw/tests/eevee_test.cc b/source/blender/draw/tests/eevee_test.cc index ecfb94740c1..40f7584fd84 100644 --- a/source/blender/draw/tests/eevee_test.cc +++ b/source/blender/draw/tests/eevee_test.cc @@ -648,6 +648,10 @@ class TestAlloc { GPU_render_begin(); int tiles_index = 1; + for (int i : IndexRange(SHADOW_MAX_TILE)) { + tiles_data[i] = 0; + } + for (uint i : IndexRange(0, page_free_count)) { uint2 page = {i % SHADOW_PAGE_PER_ROW, i / SHADOW_PAGE_PER_ROW}; pages_free_data[i] = page.x | (page.y << 16u); From abe925d0c67151ee1ecdae96a3d591ccc48381e9 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Mon, 6 Nov 2023 21:51:43 +0100 Subject: [PATCH 12/62] Fix #114436: Crash when right clicking certain, nested, popup dialogs `CTX_wm_region()` isn't reliable with popups. Handling should use `uiHandleButtonData.region` instead, which respects popup regions. --- source/blender/editors/interface/interface_handlers.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/interface/interface_handlers.cc b/source/blender/editors/interface/interface_handlers.cc index 0284ef5b700..9d35506430c 100644 --- a/source/blender/editors/interface/interface_handlers.cc +++ b/source/blender/editors/interface/interface_handlers.cc @@ -8047,16 +8047,15 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * (event->modifier & (KM_SHIFT | KM_CTRL | KM_ALT | KM_OSKEY)) == 0 && (event->val == KM_PRESS)) { - ARegion *region = CTX_wm_region(C); /* For some button types that are typically representing entire sets of data, right-clicking * to spawn the context menu should also activate the item. This makes it clear which item * will be operated on. * Apply the button immediately, so context menu polls get the right active item. */ uiBut *clicked_view_item_but = but->type == UI_BTYPE_VIEW_ITEM ? but : - ui_view_item_find_mouse_over(region, event->xy); + ui_view_item_find_mouse_over(data->region, event->xy); if (clicked_view_item_but) { - UI_but_execute(C, region, clicked_view_item_but); + UI_but_execute(C, data->region, clicked_view_item_but); } /* RMB has two options now */ From 480dceab1202062a7e022c55308fe08bc42757ae Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Mon, 6 Nov 2023 22:22:54 +0100 Subject: [PATCH 13/62] Asset shelf: Drag over checkboxes to enable/disable catalogs in selector Makes it possible to swipe over the checkboxes used to enable or disable catalogs in the asset catalog selector popup, to batch enable or disable the ones dragged over. Might also enable this feature for other cases where checkboxes are displayed. --- source/blender/editors/interface/interface.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc index 8fc9166190f..2d24d22e10f 100644 --- a/source/blender/editors/interface/interface.cc +++ b/source/blender/editors/interface/interface.cc @@ -2452,6 +2452,8 @@ bool ui_but_is_bool(const uiBut *but) UI_BTYPE_TOGGLE_N, UI_BTYPE_ICON_TOGGLE, UI_BTYPE_ICON_TOGGLE_N, + UI_BTYPE_CHECKBOX, + UI_BTYPE_CHECKBOX_N, UI_BTYPE_TAB)) { return true; From 79840a9ec6a0ac9c5457c82c97b17f0c42db6217 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Nov 2023 11:31:01 +1100 Subject: [PATCH 14/62] Cleanup: early returns in BLF, use full scentences --- source/blender/blenfont/intern/blf_font.cc | 83 ++++++++++++---------- 1 file changed, 46 insertions(+), 37 deletions(-) diff --git a/source/blender/blenfont/intern/blf_font.cc b/source/blender/blenfont/intern/blf_font.cc index cc7d76b70f9..650ab11b304 100644 --- a/source/blender/blenfont/intern/blf_font.cc +++ b/source/blender/blenfont/intern/blf_font.cc @@ -56,7 +56,7 @@ BatchBLF g_batch; -/* freetype2 handle ONLY for this file! */ +/* `freetype2` handle ONLY for this file! */ static FT_Library ft_lib = nullptr; static FTC_Manager ftc_manager = nullptr; static FTC_CMapCache ftc_charmap_cache = nullptr; @@ -163,8 +163,8 @@ static ft_pix blf_unscaled_F26Dot6_to_pixels(FontBLF *font, FT_Pos value) /* Scale value by font size using integer-optimized multiplication. */ FT_Long scaled = FT_MulFix(value, font->ft_size->metrics.x_scale); - /* Copied from FreeType's FT_Get_Kerning (with FT_KERNING_DEFAULT), scaling down */ - /* kerning distances at small PPEM values so that they don't become too big. */ + /* Copied from FreeType's FT_Get_Kerning (with FT_KERNING_DEFAULT), scaling down. */ + /* Kerning distances at small PPEM values so that they don't become too big. */ if (font->ft_size->metrics.x_ppem < 25) { scaled = FT_MulDiv(scaled, font->ft_size->metrics.x_ppem, 25); } @@ -270,7 +270,7 @@ void blf_batch_draw_begin(FontBLF *font) } } else { - /* flush cache */ + /* Flush cache. */ blf_batch_draw(); g_batch.font = font; g_batch.simple_shader = simple_shader; @@ -332,7 +332,7 @@ void blf_batch_draw() GPUTexture *texture = blf_batch_cache_texture_load(); GPU_vertbuf_data_len_set(g_batch.verts, g_batch.glyph_len); - GPU_vertbuf_use(g_batch.verts); /* send data */ + GPU_vertbuf_use(g_batch.verts); /* Send data. */ GPU_batch_program_set_builtin(g_batch.batch, GPU_SHADER_TEXT); GPU_batch_texture_bind(g_batch.batch, "glyph", texture); @@ -342,7 +342,7 @@ void blf_batch_draw() GPU_texture_unbind(texture); - /* restart to 1st vertex data pointers */ + /* Restart to 1st vertex data pointers. */ GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.pos_loc, &g_batch.pos_step); GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.col_loc, &g_batch.col_step); GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.offset_loc, &g_batch.offset_step); @@ -442,15 +442,15 @@ static void blf_font_draw_ex(FontBLF *font, ResultBLF *r_info, const ft_pix pen_y) { + if (str_len == 0) { + /* Early exit, don't do any immediate-mode GPU operations. */ + return; + } + GlyphBLF *g = nullptr; ft_pix pen_x = 0; size_t i = 0; - if (str_len == 0) { - /* early output, don't do any IMM OpenGL. */ - return; - } - blf_batch_draw_begin(font); while ((i < str_len) && str[i]) { @@ -458,7 +458,7 @@ static void blf_font_draw_ex(FontBLF *font, if (UNLIKELY(g == nullptr)) { continue; } - /* do not return this loop if clipped, we want every character tested */ + /* Do not return this loop if clipped, we want every character tested. */ blf_glyph_draw(font, gc, g, ft_pix_to_int_floor(pen_x), ft_pix_to_int_floor(pen_y)); pen_x += g->advance_x; } @@ -497,7 +497,7 @@ int blf_font_draw_mono( if (UNLIKELY(g == nullptr)) { continue; } - /* do not return this loop if clipped, we want every character tested */ + /* Do not return this loop if clipped, we want every character tested. */ blf_glyph_draw(font, gc, g, ft_pix_to_int_floor(pen_x), ft_pix_to_int_floor(pen_y)); const int col = UNLIKELY(g->c == '\t') ? (tab_columns - (columns % tab_columns)) : @@ -641,10 +641,10 @@ static void blf_font_draw_buffer_ex(FontBLF *font, ft_pix pen_y_basis = ft_pix_from_int(font->pos[1]) + pen_y; size_t i = 0; - /* buffer specific vars */ + /* Buffer specific variables. */ FontBufInfoBLF *buf_info = &font->buf_info; - /* another buffer specific call for color conversion */ + /* Another buffer specific call for color conversion. */ while ((i < str_len) && str[i]) { g = blf_glyph_from_utf8_and_step(font, gc, g, str, str_len, &i, &pen_x); @@ -687,7 +687,8 @@ static bool blf_font_width_to_strlen_glyph_process(FontBLF *font, const int width_i) { if (UNLIKELY(g == nullptr)) { - return false; /* continue the calling loop. */ + /* Continue the calling loop. */ + return false; } if (g && pen_x && !(font->flags & BLF_MONOSPACED)) { @@ -946,19 +947,19 @@ void blf_font_boundbox_foreach_glyph(FontBLF *font, BLF_GlyphBoundsFn user_fn, void *user_data) { - GlyphBLF *g = nullptr; - ft_pix pen_x = 0; - size_t i = 0, i_curr; - if (str_len == 0 || str[0] == 0) { - /* early output. */ + /* Early exit. */ return; } + GlyphBLF *g = nullptr; + ft_pix pen_x = 0; + size_t i = 0; + GlyphCacheBLF *gc = blf_glyph_cache_acquire(font); while ((i < str_len) && str[i]) { - i_curr = i; + const size_t i_curr = i; g = blf_glyph_from_utf8_and_step(font, gc, g, str, str_len, &i, &pen_x); if (UNLIKELY(g == nullptr)) { @@ -1103,8 +1104,8 @@ static void blf_font_wrap_apply(FontBLF *font, // printf("%s wrapping (%d, %d) `%s`:\n", __func__, str_len, strlen(str), str); while ((i < str_len) && str[i]) { - /* wrap vars */ - size_t i_curr = i; + /* Wrap variables. */ + const size_t i_curr = i; bool do_draw = false; g = blf_glyph_from_utf8_and_step(font, gc, g_prev, str, str_len, &i, &pen_x); @@ -1126,7 +1127,7 @@ static void blf_font_wrap_apply(FontBLF *font, do_draw = true; } else if (UNLIKELY(((i < str_len) && str[i]) == 0)) { - /* need check here for trailing newline, else we draw it */ + /* Need check here for trailing newline, else we draw it. */ wrap.last[0] = i + ((g->c != '\n') ? 1 : 0); wrap.last[1] = i; do_draw = true; @@ -1142,8 +1143,13 @@ static void blf_font_wrap_apply(FontBLF *font, } if (UNLIKELY(do_draw)) { - // printf("(%03d..%03d) `%.*s`\n", - // wrap.start, wrap.last[0], (wrap.last[0] - wrap.start) - 1, &str[wrap.start]); +#if 0 + printf("(%03d..%03d) `%.*s`\n", + wrap.start, + wrap.last[0], + (wrap.last[0] - wrap.start) - 1, + &str[wrap.start]); +#endif callback(font, gc, &str[wrap.start], (wrap.last[0] - wrap.start) - 1, pen_y, userdata); wrap.start = wrap.last[0]; @@ -1163,14 +1169,14 @@ static void blf_font_wrap_apply(FontBLF *font, if (r_info) { r_info->lines = lines; - /* width of last line only (with wrapped lines) */ + /* Width of last line only (with wrapped lines). */ r_info->width = ft_pix_to_int(pen_x_next); } blf_glyph_cache_release(font); } -/* blf_font_draw__wrap */ +/** Utility for #blf_font_draw__wrap. */ static void blf_font_draw__wrap_cb(FontBLF *font, GlyphCacheBLF *gc, const char *str, @@ -1185,7 +1191,7 @@ void blf_font_draw__wrap(FontBLF *font, const char *str, const size_t str_len, R blf_font_wrap_apply(font, str, str_len, r_info, blf_font_draw__wrap_cb, nullptr); } -/* blf_font_boundbox__wrap */ +/** Utility for #blf_font_boundbox__wrap. */ static void blf_font_boundbox_wrap_cb(FontBLF *font, GlyphCacheBLF *gc, const char *str, @@ -1210,7 +1216,7 @@ void blf_font_boundbox__wrap( blf_font_wrap_apply(font, str, str_len, r_info, blf_font_boundbox_wrap_cb, box); } -/* blf_font_draw_buffer__wrap */ +/** Utility for #blf_font_draw_buffer__wrap. */ static void blf_font_draw_buffer__wrap_cb(FontBLF *font, GlyphCacheBLF *gc, const char *str, @@ -1237,7 +1243,7 @@ void blf_font_draw_buffer__wrap(FontBLF *font, static ft_pix blf_font_height_max_ft_pix(FontBLF *font) { blf_ensure_size(font); - /* Metrics.height is rounded to pixel. Force minimum of one pixel. */ + /* #Metrics::height is rounded to pixel. Force minimum of one pixel. */ return MAX2((ft_pix)font->ft_size->metrics.height, ft_pix_from_int(1)); } @@ -1249,7 +1255,7 @@ int blf_font_height_max(FontBLF *font) static ft_pix blf_font_width_max_ft_pix(FontBLF *font) { blf_ensure_size(font); - /* Metrics.max_advance is rounded to pixel. Force minimum of one pixel. */ + /* #Metrics::max_advance is rounded to pixel. Force minimum of one pixel. */ return MAX2((ft_pix)font->ft_size->metrics.max_advance, ft_pix_from_int(1)); } @@ -1299,7 +1305,7 @@ int blf_font_init() nullptr, &ftc_manager); if (err == FT_Err_Ok) { - /* Create a charmap cache to speed up glyph index lookups. */ + /* Create a character-map cache to speed up glyph index lookups. */ err = FTC_CMapCache_New(ftc_manager, &ftc_charmap_cache); } } @@ -1342,7 +1348,8 @@ static void blf_font_fill(FontBLF *font) font->m[i] = 0; } - /* annoying bright color so we can see where to add BLF_color calls */ + /* Use an easily identifiable bright color (yellow) + * so its clear when #BLF_color calls are missing. */ font->color[0] = 255; font->color[1] = 255; font->color[2] = 0; @@ -1377,8 +1384,10 @@ static void blf_font_fill(FontBLF *font) font->buf_info.col_init[3] = 0; } -/* Note that the data the following function creates is not yet used. - * But do not remove it as it will be used in the near future - Harley */ +/** + * NOTE(@Harley): that the data the following function creates is not yet used. + * But do not remove it as it will be used in the near future. + */ static void blf_font_metrics(FT_Face face, FontMetrics *metrics) { /* Members with non-zero defaults. */ From c450b5f2b84b7e5abc224099197c8cb409ae7a0a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Nov 2023 11:31:02 +1100 Subject: [PATCH 15/62] Cleanup: use full sentences in writefile.cc, minor clarifications Also correct doxy-sections. --- source/blender/blenloader/intern/writefile.cc | 77 +++++++++++-------- 1 file changed, 45 insertions(+), 32 deletions(-) diff --git a/source/blender/blenloader/intern/writefile.cc b/source/blender/blenloader/intern/writefile.cc index ae2274d2276..552572a1e0c 100644 --- a/source/blender/blenloader/intern/writefile.cc +++ b/source/blender/blenloader/intern/writefile.cc @@ -78,7 +78,7 @@ #include "CLG_log.h" -/* allow writefile to use deprecated functionality (for forward compatibility code) */ +/* Allow writefile to use deprecated functionality (for forward compatibility code). */ #define DNA_DEPRECATED_ALLOW #include "DNA_collection_types.h" @@ -101,7 +101,7 @@ #include "BKE_blender_version.h" #include "BKE_bpath.h" -#include "BKE_global.h" /* for G */ +#include "BKE_global.h" /* For #Global `G`. */ #include "BKE_idprop.h" #include "BKE_idtype.h" #include "BKE_layer.h" @@ -471,7 +471,7 @@ static void writedata_do_write(WriteData *wd, const void *mem, size_t memlen) return; } - /* memory based save */ + /* Memory based save. */ if (wd->use_memfile) { BLO_memfile_chunk_add(&wd->mem, static_cast(mem), memlen); } @@ -532,8 +532,8 @@ static void mywrite(WriteData *wd, const void *adr, size_t len) writedata_do_write(wd, adr, len); } else { - /* if we have a single big chunk, write existing data in - * buffer and write out big chunk in smaller pieces */ + /* If we have a single big chunk, write existing data in + * buffer and write out big chunk in smaller pieces. */ if (len > wd->buffer.chunk_size) { if (wd->buffer.used_len != 0) { writedata_do_write(wd, wd->buffer.buf, wd->buffer.used_len); @@ -550,13 +550,13 @@ static void mywrite(WriteData *wd, const void *adr, size_t len) return; } - /* if data would overflow buffer, write out the buffer */ + /* If data would overflow buffer, write out the buffer. */ if (len + wd->buffer.used_len > wd->buffer.max_size - 1) { writedata_do_write(wd, wd->buffer.buf, wd->buffer.used_len); wd->buffer.used_len = 0; } - /* append data at end of buffer */ + /* Append data at end of buffer. */ memcpy(&wd->buffer.buf[wd->buffer.used_len], adr, len); wd->buffer.used_len += len; } @@ -669,7 +669,7 @@ static void writestruct_at_address_nr( return; } - /* init BHead */ + /* Initialize #BHead. */ bh.code = filecode; bh.old = adr; bh.nr = nr; @@ -693,7 +693,9 @@ static void writestruct_nr( writestruct_at_address_nr(wd, filecode, struct_nr, nr, adr, adr); } -/* do not use for structs */ +/** + * \warning Do not use for structs. + */ static void writedata(WriteData *wd, int filecode, size_t len, const void *adr) { BHead bh; @@ -707,10 +709,10 @@ static void writedata(WriteData *wd, int filecode, size_t len, const void *adr) return; } - /* align to 4 (writes uninitialized bytes in some cases) */ + /* Align to 4 (writes uninitialized bytes in some cases). */ len = (len + 3) & ~size_t(3); - /* init BHead */ + /* Initialize #BHead. */ bh.code = filecode; bh.old = adr; bh.nr = 1; @@ -721,7 +723,9 @@ static void writedata(WriteData *wd, int filecode, size_t len, const void *adr) mywrite(wd, adr, len); } -/* use this to force writing of lists in same order as reading (using link_list) */ +/** + * Use this to force writing of lists in same order as reading (using link_list). + */ static void writelist_nr(WriteData *wd, int filecode, const int struct_nr, const ListBase *lb) { const Link *link = static_cast(lb->first); @@ -782,20 +786,20 @@ static void current_screen_compat(Main *mainvar, wmWindowManager *wm; wmWindow *window = nullptr; - /* find a global current screen in the first open window, to have - * a reasonable default for reading in older versions */ + /* Find a global current screen in the first open window, to have + * a reasonable default for reading in older versions. */ wm = static_cast(mainvar->wm.first); if (wm) { if (use_active_win) { - /* write the active window into the file, needed for multi-window undo #43424 */ + /* Write the active window into the file, needed for multi-window undo #43424. */ for (window = static_cast(wm->windows.first); window; window = window->next) { if (window->active) { break; } } - /* fallback */ + /* Fallback. */ if (window == nullptr) { window = static_cast(wm->windows.first); } @@ -829,7 +833,7 @@ static void write_renderinfo(WriteData *wd, Main *mainvar) Scene *curscene = nullptr; ViewLayer *view_layer; - /* XXX in future, handle multiple windows with multiple screens? */ + /* XXX: in future, handle multiple windows with multiple screens? */ current_screen_compat(mainvar, false, &curscreen, &curscene, &view_layer); LISTBASE_FOREACH (Scene *, sce, &mainvar->scenes) { @@ -939,7 +943,7 @@ static void write_userdef(BlendWriter *writer, const UserDef *userdef) } } -/* Keep it last of write_foodata functions. */ +/** Keep it last of `write_*_data` functions. */ static void write_libraries(WriteData *wd, Main *main) { ListBase *lbarray[INDEX_ID_MAX]; @@ -950,7 +954,7 @@ static void write_libraries(WriteData *wd, Main *main) for (; main; main = main->next) { a = tot = set_listbasepointers(main, lbarray); - /* test: is lib being used */ + /* Test: is lib being used. */ if (main->curlib && main->curlib->packedfile) { found_one = true; } @@ -1024,9 +1028,11 @@ extern "C" ulong build_commit_timestamp; extern "C" char build_hash[]; #endif -/* context is usually defined by WM, two cases where no WM is available: - * - for forward compatibility, curscreen has to be saved - * - for undofile, curscene needs to be saved */ +/** + * Context is usually defined by WM, two cases where no WM is available: + * - for forward compatibility, `curscreen` has to be saved + * - for undo-file, `curscene` needs to be saved. + */ static void write_global(WriteData *wd, int fileflags, Main *mainvar) { const bool is_undo = wd->use_memfile; @@ -1036,7 +1042,7 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar) ViewLayer *view_layer; char subvstr[8]; - /* prevent mem checkers from complaining */ + /* Prevent memory checkers from complaining. */ memset(fg._pad, 0, sizeof(fg._pad)); memset(fg.filepath, 0, sizeof(fg.filepath)); memset(fg.build_hash, 0, sizeof(fg.build_hash)); @@ -1044,12 +1050,12 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar) current_screen_compat(mainvar, is_undo, &screen, &scene, &view_layer); - /* XXX still remap G */ + /* XXX: still remap `G`. */ fg.curscreen = screen; fg.curscene = scene; fg.cur_view_layer = view_layer; - /* prevent to save this, is not good convention, and feature with concerns... */ + /* Prevent to save this, is not good convention, and feature with concerns. */ fg.fileflags = (fileflags & ~G_FILE_FLAG_ALL_RUNTIME); fg.globalf = G.f; @@ -1192,7 +1198,12 @@ static int write_id_direct_linked_data_process_cb(LibraryIDLinkCallbackData *cb_ return IDWALK_RET_NOP; } -/* if MemFile * there's filesave to memory */ +/** + * When #MemFile arguments are non-null, this is a file-safe to memory. + * + * \param compare: Previous memory file (can be nullptr). + * \param current: The current memory file (can be nullptr). + */ static bool write_file_handle(Main *mainvar, WriteWrap *ww, MemFile *compare, @@ -1364,7 +1375,7 @@ static bool write_file_handle(Main *mainvar, * so writing each time uses the same address and doesn't cause unnecessary undo overhead. */ writedata(wd, BLO_CODE_DNA1, size_t(wd->sdna->data_len), wd->sdna->data); - /* end of file */ + /* End of file. */ memset(&bhead, 0, sizeof(BHead)); bhead.code = BLO_CODE_ENDB; mywrite(wd, &bhead, sizeof(BHead)); @@ -1475,14 +1486,14 @@ static bool BLO_write_file_impl(Main *mainvar, const BlendThumbnail *thumb = params->thumb; const bool relbase_valid = (mainvar->filepath[0] != '\0'); - /* path backup/restore */ + /* Path backup/restore. */ void *path_list_backup = nullptr; const eBPathForeachFlag path_list_flag = (BKE_BPATH_FOREACH_PATH_SKIP_LINKED | BKE_BPATH_FOREACH_PATH_SKIP_MULTIFILE); write_file_main_validate_pre(mainvar, reports); - /* open temporary file, so we preserve the original in case we crash */ + /* Open temporary file, so we preserve the original in case we crash. */ SNPRINTF(tempname, "%s@", filepath); if (ww.open(tempname) == false) { @@ -1574,7 +1585,7 @@ static bool BLO_write_file_impl(Main *mainvar, } } - /* actual file writing */ + /* Actual file writing. */ const bool err = write_file_handle( mainvar, &ww, nullptr, nullptr, write_flags, use_userdef, thumb); @@ -1592,8 +1603,8 @@ static bool BLO_write_file_impl(Main *mainvar, return false; } - /* file save to temporary file was successful */ - /* now do reverse file history (move .blend1 -> .blend2, .blend -> .blend1) */ + /* File save to temporary file was successful, now do reverse file history + * (move `.blend1` -> `.blend2`, `.blend` -> `.blend1` .. etc). */ if (use_save_versions) { if (!do_history(filepath, reports)) { BKE_report(reports, RPT_ERROR, "Version backup failed (file saved with @)"); @@ -1611,6 +1622,8 @@ static bool BLO_write_file_impl(Main *mainvar, return true; } +/** \} */ + /* -------------------------------------------------------------------- */ /** \name File Writing (Public) * \{ */ From 1e66938d7a3b22ece58eb4d1af4ac7611448a7ff Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Nov 2023 11:31:04 +1100 Subject: [PATCH 16/62] Cleanup: spelling in comments, format --- scripts/startup/bl_ui/properties_object.py | 2 +- source/blender/blenlib/BLI_math_geom.h | 8 ++------ source/blender/blenlib/intern/math_geom.cc | 8 +++----- .../blender/nodes/composite/nodes/node_composite_image.cc | 6 +++--- source/blender/nodes/shader/materialx/node_parser.cc | 2 +- 5 files changed, 10 insertions(+), 16 deletions(-) diff --git a/scripts/startup/bl_ui/properties_object.py b/scripts/startup/bl_ui/properties_object.py index 095f0285ab6..1dddc9e229a 100644 --- a/scripts/startup/bl_ui/properties_object.py +++ b/scripts/startup/bl_ui/properties_object.py @@ -394,7 +394,7 @@ class OBJECT_PT_visibility(ObjectButtonsPanel, Panel): layout.separator() col = layout.column(heading="Ray Visibility") col.prop(ob, "visible_shadow", text="Shadow", toggle=False) - + if ob.type in {'MESH', 'CURVE', 'SURFACE', 'META', 'FONT', 'CURVES', 'POINTCLOUD', 'VOLUME', 'LIGHT'}: layout.separator() col = layout.column(heading="Light Probes") diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index 7239e2ab723..f23c49d23ea 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -788,12 +788,8 @@ bool isect_ray_line_v3(const float ray_origin[3], /* Point in polygon. */ -bool isect_point_poly_v2(const float pt[2], - const float verts[][2], - unsigned int nr); -bool isect_point_poly_v2_int(const int pt[2], - const int verts[][2], - unsigned int nr); +bool isect_point_poly_v2(const float pt[2], const float verts[][2], unsigned int nr); +bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], unsigned int nr); /** * Point in quad - only convex quads. diff --git a/source/blender/blenlib/intern/math_geom.cc b/source/blender/blenlib/intern/math_geom.cc index 7051acc711f..01df242508c 100644 --- a/source/blender/blenlib/intern/math_geom.cc +++ b/source/blender/blenlib/intern/math_geom.cc @@ -1359,16 +1359,14 @@ int isect_line_sphere_v3(const float l1[3], float r_p1[3], float r_p2[3]) { - /* adapted for use in blender by Campbell Barton - 2011 + /* Adapted for use in blender by Campbell Barton, 2011. * - * atelier iebele abel - 2001 - * * http://www.iebele.nl + * `Atelier Iebele Abel ` - 2001. * * sphere_line_intersection function adapted from: * http://astronomy.swin.edu.au/pbourke/geometry/sphereline - * Paul Bourke - */ + * `Paul Bourke `. */ const float ldir[3] = { l2[0] - l1[0], diff --git a/source/blender/nodes/composite/nodes/node_composite_image.cc b/source/blender/nodes/composite/nodes/node_composite_image.cc index f8226311d26..239fe265317 100644 --- a/source/blender/nodes/composite/nodes/node_composite_image.cc +++ b/source/blender/nodes/composite/nodes/node_composite_image.cc @@ -575,10 +575,10 @@ class ImageOperation : public NodeOperation { } } - /* Compositor image inputs are expected to be always premultiplied, so identify if the GPU - * texture returned by the image module is straight and needs to be premultiplied. An exception + /* Compositor image inputs are expected to be always pre-multiplied, so identify if the GPU + * texture returned by the image module is straight and needs to be pre-multiplied. An exception * is when the image has an alpha mode of channel packed or alpha ignore, in which case, we - * always ignore premultiplication. */ + * always ignore pre-multiplication. */ bool should_premultiply_alpha(ImageUser &image_user) { Image *image = get_image(); diff --git a/source/blender/nodes/shader/materialx/node_parser.cc b/source/blender/nodes/shader/materialx/node_parser.cc index c0f3ec1064a..e1313b770d6 100644 --- a/source/blender/nodes/shader/materialx/node_parser.cc +++ b/source/blender/nodes/shader/materialx/node_parser.cc @@ -64,7 +64,7 @@ std::string NodeParser::node_name(bool with_out_socket) const { auto valid_name = [](const std::string &name) { /* Node name should suite to MatX and USD valid names. - * It shouldn't start from '_', due to error occured in Storm delegate. */ + * It shouldn't start from '_', due to error occurred in Storm delegate. */ std::string res = MaterialX::createValidName(pxr::TfMakeValidIdentifier(name)); if (res[0] == '_') { res = "node" + res; From aaf05c2497433502c34df51e590b4af4ce34b702 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Nov 2023 11:31:07 +1100 Subject: [PATCH 17/62] Cleanup: various C++ changes (use nullptr, function style casts) --- intern/ghost/intern/GHOST_SystemWayland.cc | 14 +- .../blender/blenkernel/intern/customdata.cc | 2 +- .../blenkernel/intern/grease_pencil.cc | 2 +- .../blenkernel/intern/subdiv_modifier.cc | 2 +- source/blender/blenlib/intern/BLI_filelist.cc | 46 ++--- source/blender/blenlib/intern/fileops_c.cc | 12 +- source/blender/blenlib/intern/math_geom.cc | 185 +++++++++--------- source/blender/blenlib/intern/path_util.cc | 6 +- source/blender/blenlib/intern/storage.cc | 4 +- source/blender/blenlib/intern/string_utf8.cc | 42 ++-- source/blender/blenlib/intern/string_utils.cc | 16 +- .../blenloader/intern/versioning_defaults.cc | 3 +- .../compositor/nodes/COM_SceneTimeNode.cc | 2 +- .../COM_SummedAreaTableOperation.cc | 4 +- .../draw/engines/eevee_next/eevee_shadow.cc | 4 +- .../engines/workbench/workbench_volume.cc | 2 +- source/blender/draw/intern/draw_curves.cc | 2 +- .../blender/editors/animation/anim_filter.cc | 2 +- .../blender/editors/animation/keyingsets.cc | 4 +- .../gizmo_library/gizmo_types/snap3d_gizmo.cc | 2 +- .../editors/sculpt_paint/paint_cursor.cc | 2 +- source/blender/editors/sound/sound_ops.cc | 2 +- .../editors/space_action/action_edit.cc | 2 +- .../blender/editors/space_info/info_stats.cc | 2 +- .../blender/editors/space_node/node_edit.cc | 2 +- .../editors/space_node/node_shader_preview.cc | 2 +- .../transform/transform_convert_action.cc | 2 +- .../intern/lineart/lineart_cpu.cc | 2 +- .../imbuf/intern/openexr/openexr_api.cpp | 2 +- .../nodes/node_geo_input_scene_time.cc | 2 +- .../shader/nodes/node_shader_tex_gradient.cc | 2 +- .../sequencer/intern/strip_retiming.cc | 2 +- .../windowmanager/intern/wm_event_query.cc | 2 +- .../blender/windowmanager/intern/wm_window.cc | 2 +- 34 files changed, 189 insertions(+), 195 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemWayland.cc b/intern/ghost/intern/GHOST_SystemWayland.cc index 819862d240f..cee553a46e8 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cc +++ b/intern/ghost/intern/GHOST_SystemWayland.cc @@ -726,7 +726,7 @@ static void gwl_primary_selection_discard_source(GWL_PrimarySelection *primary) #ifdef WITH_INPUT_IME struct GWL_SeatIME { - struct wl_surface *surface_window = nullptr; + wl_surface *surface_window = nullptr; GHOST_TEventImeData event_ime_data = { /*result_len*/ nullptr, /*composite_len*/ nullptr, @@ -806,7 +806,7 @@ struct GWL_Seat { std::unordered_set tablet_tools; #ifdef WITH_INPUT_IME - struct zwp_text_input_v3 *text_input = nullptr; + zwp_text_input_v3 *text_input = nullptr; #endif } wp; @@ -1063,7 +1063,7 @@ struct GWL_Display { zwp_pointer_constraints_v1 *pointer_constraints = nullptr; zwp_pointer_gestures_v1 *pointer_gestures = nullptr; #ifdef WITH_INPUT_IME - struct zwp_text_input_manager_v3 *text_input_manager = nullptr; + zwp_text_input_manager_v3 *text_input_manager = nullptr; #endif } wp; @@ -4566,7 +4566,7 @@ static CLG_LogRef LOG_WL_TEXT_INPUT = {"ghost.wl.handle.text_input"}; static void text_input_handle_enter(void *data, zwp_text_input_v3 * /*zwp_text_input_v3*/, - struct wl_surface *surface) + wl_surface *surface) { if (!ghost_wl_surface_own(surface)) { return; @@ -4578,7 +4578,7 @@ static void text_input_handle_enter(void *data, static void text_input_handle_leave(void *data, zwp_text_input_v3 * /*zwp_text_input_v3*/, - struct wl_surface *surface) + wl_surface *surface) { /* Can be null when closing a window. */ if (!ghost_wl_surface_own_with_null_check(surface)) { @@ -4747,7 +4747,7 @@ static void text_input_handle_done(void *data, seat->ime.has_commit_string_callback = false; } -static struct zwp_text_input_v3_listener text_input_listener = { +static zwp_text_input_v3_listener text_input_listener = { /*enter*/ text_input_handle_enter, /*leave*/ text_input_handle_leave, /*preedit_string*/ text_input_handle_preedit_string, @@ -5773,7 +5773,7 @@ static void gwl_registry_wp_text_input_manager_remove(GWL_Display *display, void * /*user_data*/, const bool /*on_exit*/) { - struct zwp_text_input_manager_v3 **value_p = &display->wp.text_input_manager; + zwp_text_input_manager_v3 **value_p = &display->wp.text_input_manager; zwp_text_input_manager_v3_destroy(*value_p); *value_p = nullptr; } diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index 0788076332a..534ff4a8b99 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -2427,7 +2427,7 @@ void CustomData_ensure_data_is_mutable(CustomDataLayer *layer, const int totelem ensure_layer_data_is_mutable(*layer, totelem); } -void CustomData_ensure_layers_are_mutable(struct CustomData *data, int totelem) +void CustomData_ensure_layers_are_mutable(CustomData *data, int totelem) { for (const int i : IndexRange(data->totlayer)) { ensure_layer_data_is_mutable(data->layers[i], totelem); diff --git a/source/blender/blenkernel/intern/grease_pencil.cc b/source/blender/blenkernel/intern/grease_pencil.cc index 4757f136717..4c3faa0b81d 100644 --- a/source/blender/blenkernel/intern/grease_pencil.cc +++ b/source/blender/blenkernel/intern/grease_pencil.cc @@ -1939,7 +1939,7 @@ static std::string unique_node_name(const GreasePencil &grease_pencil, { using namespace blender; char unique_name[MAX_NAME]; - BLI_strncpy(unique_name, name.c_str(), MAX_NAME); + STRNCPY(unique_name, name.c_str()); VectorSet names = get_node_names(grease_pencil); unique_node_name_ex(names, default_name, unique_name); return unique_name; diff --git a/source/blender/blenkernel/intern/subdiv_modifier.cc b/source/blender/blenkernel/intern/subdiv_modifier.cc index 795dbe6bb80..c6a559340ee 100644 --- a/source/blender/blenkernel/intern/subdiv_modifier.cc +++ b/source/blender/blenkernel/intern/subdiv_modifier.cc @@ -97,7 +97,7 @@ static bool is_subdivision_evaluation_possible_on_gpu() return false; } - if (!(GPU_compute_shader_support())) { + if (!GPU_compute_shader_support()) { return false; } diff --git a/source/blender/blenlib/intern/BLI_filelist.cc b/source/blender/blenlib/intern/BLI_filelist.cc index 407223311a2..c3da3ae9353 100644 --- a/source/blender/blenlib/intern/BLI_filelist.cc +++ b/source/blender/blenlib/intern/BLI_filelist.cc @@ -48,7 +48,7 @@ * Ordering function for sorting lists of files/directories. Returns -1 if * entry1 belongs before entry2, 0 if they are equal, 1 if they should be swapped. */ -static int direntry_cmp(struct direntry *entry1, struct direntry *entry2) +static int direntry_cmp(direntry *entry1, direntry *entry2) { /* type is equal to stat.st_mode */ @@ -101,14 +101,14 @@ static int direntry_cmp(struct direntry *entry1, struct direntry *entry2) } struct BuildDirCtx { - struct direntry *files; /* array[files_num] */ + direntry *files; /* array[files_num] */ int files_num; }; /** * Scans the directory named *dirname and appends entries for its contents to files. */ -static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) +static void bli_builddir(BuildDirCtx *dir_ctx, const char *dirname) { DIR *dir = opendir(dirname); if (UNLIKELY(dir == nullptr)) { @@ -121,7 +121,7 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) ListBase dirbase = {nullptr, nullptr}; int newnum = 0; - const struct dirent *fname; + const dirent *fname; bool has_current = false, has_parent = false; char dirname_with_slash[FILE_MAXDIR + 1]; @@ -136,7 +136,7 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) } while ((fname = readdir(dir)) != nullptr) { - struct dirlink *const dlink = (struct dirlink *)malloc(sizeof(dirlink)); + dirlink *const dlink = (dirlink *)malloc(sizeof(dirlink)); if (dlink != nullptr) { dlink->name = BLI_strdup(fname->d_name); if (FILENAME_IS_PARENT(dlink->name)) { @@ -155,7 +155,7 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) STRNCPY(pardir, dirname); if (BLI_path_parent_dir(pardir) && (BLI_access(pardir, R_OK) == 0)) { - struct dirlink *const dlink = (struct dirlink *)malloc(sizeof(dirlink)); + dirlink *const dlink = (dirlink *)malloc(sizeof(dirlink)); if (dlink != nullptr) { dlink->name = BLI_strdup(FILENAME_PARENT); BLI_addhead(&dirbase, dlink); @@ -164,7 +164,7 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) } } if (!has_current) { - struct dirlink *const dlink = (struct dirlink *)malloc(sizeof(dirlink)); + dirlink *const dlink = (dirlink *)malloc(sizeof(dirlink)); if (dlink != nullptr) { dlink->name = BLI_strdup(FILENAME_CURRENT); BLI_addhead(&dirbase, dlink); @@ -186,7 +186,7 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) } if (dir_ctx->files == nullptr) { - dir_ctx->files = (struct direntry *)MEM_mallocN(newnum * sizeof(direntry), __func__); + dir_ctx->files = (direntry *)MEM_mallocN(newnum * sizeof(direntry), __func__); } if (UNLIKELY(dir_ctx->files == nullptr)) { @@ -194,8 +194,8 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) dir_ctx->files_num = 0; } else { - struct dirlink *dlink = (dirlink *)dirbase.first; - struct direntry *file = &dir_ctx->files[dir_ctx->files_num]; + dirlink *dlink = (dirlink *)dirbase.first; + direntry *file = &dir_ctx->files[dir_ctx->files_num]; while (dlink) { memset(file, 0, sizeof(direntry)); @@ -226,9 +226,9 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) closedir(dir); } -uint BLI_filelist_dir_contents(const char *dirname, struct direntry **r_filelist) +uint BLI_filelist_dir_contents(const char *dirname, direntry **r_filelist) { - struct BuildDirCtx dir_ctx; + BuildDirCtx dir_ctx; dir_ctx.files_num = 0; dir_ctx.files = nullptr; @@ -322,7 +322,7 @@ void BLI_filelist_entry_owner_to_string(const struct stat *st, UNUSED_VARS(st); BLI_strncpy(r_owner, "unknown", FILELIST_DIRENTRY_OWNER_LEN); #else - struct passwd *pwuser = getpwuid(st->st_uid); + passwd *pwuser = getpwuid(st->st_uid); if (pwuser) { BLI_strncpy(r_owner, pwuser->pw_name, sizeof(*r_owner) * FILELIST_DIRENTRY_OWNER_LEN); @@ -348,8 +348,8 @@ void BLI_filelist_entry_datetime_to_string(const struct stat *st, if (r_is_today || r_is_yesterday) { /* `localtime()` has only one buffer so need to get data out before called again. */ - const time_t ts_now = time(NULL); - struct tm *today = localtime(&ts_now); + const time_t ts_now = time(nullptr); + tm *today = localtime(&ts_now); today_year = today->tm_year; today_yday = today->tm_yday; @@ -368,7 +368,7 @@ void BLI_filelist_entry_datetime_to_string(const struct stat *st, } const time_t ts_mtime = ts; - const struct tm *tm = localtime(st ? &st->st_mtime : &ts_mtime); + const tm *tm = localtime(st ? &st->st_mtime : &ts_mtime); const time_t zero = 0; /* Prevent impossible dates in windows. */ @@ -395,7 +395,7 @@ void BLI_filelist_entry_datetime_to_string(const struct stat *st, } } -void BLI_filelist_entry_duplicate(struct direntry *dst, const struct direntry *src) +void BLI_filelist_entry_duplicate(direntry *dst, const direntry *src) { *dst = *src; if (dst->relname) { @@ -406,8 +406,8 @@ void BLI_filelist_entry_duplicate(struct direntry *dst, const struct direntry *s } } -void BLI_filelist_duplicate(struct direntry **dest_filelist, - struct direntry *const src_filelist, +void BLI_filelist_duplicate(direntry **dest_filelist, + direntry *const src_filelist, const uint nrentries) { uint i; @@ -415,13 +415,13 @@ void BLI_filelist_duplicate(struct direntry **dest_filelist, *dest_filelist = static_cast( MEM_mallocN(sizeof(**dest_filelist) * size_t(nrentries), __func__)); for (i = 0; i < nrentries; i++) { - struct direntry *const src = &src_filelist[i]; - struct direntry *dst = &(*dest_filelist)[i]; + direntry *const src = &src_filelist[i]; + direntry *dst = &(*dest_filelist)[i]; BLI_filelist_entry_duplicate(dst, src); } } -void BLI_filelist_entry_free(struct direntry *entry) +void BLI_filelist_entry_free(direntry *entry) { if (entry->relname) { MEM_freeN((void *)entry->relname); @@ -431,7 +431,7 @@ void BLI_filelist_entry_free(struct direntry *entry) } } -void BLI_filelist_free(struct direntry *filelist, const uint nrentries) +void BLI_filelist_free(direntry *filelist, const uint nrentries) { uint i; for (i = 0; i < nrentries; i++) { diff --git a/source/blender/blenlib/intern/fileops_c.cc b/source/blender/blenlib/intern/fileops_c.cc index d0cda1617ca..c51f2b2a74c 100644 --- a/source/blender/blenlib/intern/fileops_c.cc +++ b/source/blender/blenlib/intern/fileops_c.cc @@ -862,9 +862,9 @@ static int recursive_operation(const char *startfrom, RecursiveOp_Callback callback_dir_post) { struct stat st; - char *from = NULL, *to = nullptr; - char *from_path = NULL, *to_path = nullptr; - struct dirent **dirlist = nullptr; + char *from = nullptr, *to = nullptr; + char *from_path = nullptr, *to_path = nullptr; + dirent **dirlist = nullptr; size_t from_alloc_len = -1, to_alloc_len = -1; int i, n = 0, ret = 0; @@ -916,7 +916,7 @@ static int recursive_operation(const char *startfrom, } for (i = 0; i < n; i++) { - const struct dirent *const dirent = dirlist[i]; + const dirent *const dirent = dirlist[i]; if (FILENAME_IS_CURRPAR(dirent->d_name)) { continue; @@ -1062,8 +1062,8 @@ static int delete_soft(const char *file, const char **error_message) char *xdg_current_desktop = getenv("XDG_CURRENT_DESKTOP"); char *xdg_session_desktop = getenv("XDG_SESSION_DESKTOP"); - if ((xdg_current_desktop != NULL && STREQ(xdg_current_desktop, "KDE")) || - (xdg_session_desktop != NULL && STREQ(xdg_session_desktop, "KDE"))) + if ((xdg_current_desktop != nullptr && STREQ(xdg_current_desktop, "KDE")) || + (xdg_session_desktop != nullptr && STREQ(xdg_session_desktop, "KDE"))) { args[0] = "kioclient5"; args[1] = "move"; diff --git a/source/blender/blenlib/intern/math_geom.cc b/source/blender/blenlib/intern/math_geom.cc index 01df242508c..2f247f429d1 100644 --- a/source/blender/blenlib/intern/math_geom.cc +++ b/source/blender/blenlib/intern/math_geom.cc @@ -653,7 +653,7 @@ void aabb_get_near_far_from_plane(const float plane_no[3], /** \name dist_squared_to_ray_to_aabb and helpers * \{ */ -void dist_squared_ray_to_aabb_v3_precalc(struct DistRayAABB_Precalc *neasrest_precalc, +void dist_squared_ray_to_aabb_v3_precalc(DistRayAABB_Precalc *neasrest_precalc, const float ray_origin[3], const float ray_direction[3]) { @@ -667,7 +667,7 @@ void dist_squared_ray_to_aabb_v3_precalc(struct DistRayAABB_Precalc *neasrest_pr } } -float dist_squared_ray_to_aabb_v3(const struct DistRayAABB_Precalc *data, +float dist_squared_ray_to_aabb_v3(const DistRayAABB_Precalc *data, const float bb_min[3], const float bb_max[3], float r_point[3], @@ -763,7 +763,7 @@ float dist_squared_ray_to_aabb_v3_simple(const float ray_origin[3], float r_point[3], float *r_depth) { - struct DistRayAABB_Precalc data; + DistRayAABB_Precalc data; dist_squared_ray_to_aabb_v3_precalc(&data, ray_origin, ray_direction); return dist_squared_ray_to_aabb_v3(&data, bb_min, bb_max, r_point, r_depth); } @@ -774,7 +774,7 @@ float dist_squared_ray_to_aabb_v3_simple(const float ray_origin[3], /** \name dist_squared_to_projected_aabb and helpers * \{ */ -void dist_squared_to_projected_aabb_precalc(struct DistProjectedAABBPrecalc *precalc, +void dist_squared_to_projected_aabb_precalc(DistProjectedAABBPrecalc *precalc, const float projmat[4][4], const float winsize[2], const float mval[2]) @@ -826,7 +826,7 @@ void dist_squared_to_projected_aabb_precalc(struct DistProjectedAABBPrecalc *pre } } -float dist_squared_to_projected_aabb(struct DistProjectedAABBPrecalc *data, +float dist_squared_to_projected_aabb(DistProjectedAABBPrecalc *data, const float bbmin[3], const float bbmax[3], bool r_axis_closest[3]) @@ -962,7 +962,7 @@ float dist_squared_to_projected_aabb_simple(const float projmat[4][4], const float bbmin[3], const float bbmax[3]) { - struct DistProjectedAABBPrecalc data; + DistProjectedAABBPrecalc data; dist_squared_to_projected_aabb_precalc(&data, projmat, winsize, mval); bool dummy[3] = {true, true, true}; @@ -1070,14 +1070,14 @@ int isect_seg_seg_v2_int(const int v1[2], const int v2[2], const int v3[2], cons { float div, lambda, mu; - div = (float)((v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0])); + div = float((v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0])); if (div == 0.0f) { return ISECT_LINE_LINE_COLINEAR; } - lambda = (float)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; + lambda = float((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; - mu = (float)((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div; + mu = float((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div; if (lambda >= 0.0f && lambda <= 1.0f && mu >= 0.0f && mu <= 1.0f) { if (lambda == 0.0f || lambda == 1.0f || mu == 0.0f || mu == 1.0f) { @@ -1120,9 +1120,9 @@ int isect_seg_seg_v2(const float v1[2], const float v2[2], const float v3[2], co return ISECT_LINE_LINE_COLINEAR; } - lambda = ((float)(v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; + lambda = (float(v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; - mu = ((float)(v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div; + mu = (float(v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div; if (lambda >= 0.0f && lambda <= 1.0f && mu >= 0.0f && mu <= 1.0f) { if (lambda == 0.0f || lambda == 1.0f || mu == 0.0f || mu == 1.0f) { @@ -1781,7 +1781,7 @@ bool isect_ray_tri_epsilon_v3(const float ray_origin[3], return true; } -void isect_ray_tri_watertight_v3_precalc(struct IsectRayPrecalc *isect_precalc, +void isect_ray_tri_watertight_v3_precalc(IsectRayPrecalc *isect_precalc, const float ray_direction[3]) { float inv_dir_z; @@ -1809,7 +1809,7 @@ void isect_ray_tri_watertight_v3_precalc(struct IsectRayPrecalc *isect_precalc, } bool isect_ray_tri_watertight_v3(const float ray_origin[3], - const struct IsectRayPrecalc *isect_precalc, + const IsectRayPrecalc *isect_precalc, const float v0[3], const float v1[3], const float v2[3], @@ -1859,7 +1859,7 @@ bool isect_ray_tri_watertight_v3(const float ray_origin[3], /* Calculate scaled z-coordinates of vertices and use them to calculate * the hit distance. */ - const int sign_det = (float_as_int(det) & (int)0x80000000); + const int sign_det = (float_as_int(det) & int(0x80000000)); const float t = (u * a_kz + v * b_kz + w * c_kz) * sz; const float sign_t = xor_fl(t, sign_det); if ((sign_t < 0.0f) @@ -1892,7 +1892,7 @@ bool isect_ray_tri_watertight_v3_simple(const float ray_origin[3], float *r_lambda, float r_uv[2]) { - struct IsectRayPrecalc isect_precalc; + IsectRayPrecalc isect_precalc; isect_ray_tri_watertight_v3_precalc(&isect_precalc, ray_direction); return isect_ray_tri_watertight_v3(ray_origin, &isect_precalc, v0, v1, v2, r_lambda, r_uv); } @@ -2250,9 +2250,9 @@ bool isect_tri_tri_v3_ex(const float tri_a[3][3], sub_v3db_v3fl_v3fl(bc, tri_a[2], tri_a[1]); cross_v3_v3v3_db(plane_a, ba, bc); plane_a[3] = -dot_v3db_v3fl(plane_a, tri_a[1]); - side[1][0] = (float)(dot_v3db_v3fl(plane_a, tri_b[0]) + plane_a[3]); - side[1][1] = (float)(dot_v3db_v3fl(plane_a, tri_b[1]) + plane_a[3]); - side[1][2] = (float)(dot_v3db_v3fl(plane_a, tri_b[2]) + plane_a[3]); + side[1][0] = float(dot_v3db_v3fl(plane_a, tri_b[0]) + plane_a[3]); + side[1][1] = float(dot_v3db_v3fl(plane_a, tri_b[1]) + plane_a[3]); + side[1][2] = float(dot_v3db_v3fl(plane_a, tri_b[2]) + plane_a[3]); if (!side[1][0] && !side[1][1] && !side[1][2]) { /* Coplanar case is not supported. */ @@ -2271,9 +2271,9 @@ bool isect_tri_tri_v3_ex(const float tri_a[3][3], sub_v3db_v3fl_v3fl(bc, tri_b[2], tri_b[1]); cross_v3_v3v3_db(plane_b, ba, bc); plane_b[3] = -dot_v3db_v3fl(plane_b, tri_b[1]); - side[0][0] = (float)(dot_v3db_v3fl(plane_b, tri_a[0]) + plane_b[3]); - side[0][1] = (float)(dot_v3db_v3fl(plane_b, tri_a[1]) + plane_b[3]); - side[0][2] = (float)(dot_v3db_v3fl(plane_b, tri_a[2]) + plane_b[3]); + side[0][0] = float(dot_v3db_v3fl(plane_b, tri_a[0]) + plane_b[3]); + side[0][1] = float(dot_v3db_v3fl(plane_b, tri_a[1]) + plane_b[3]); + side[0][2] = float(dot_v3db_v3fl(plane_b, tri_a[2]) + plane_b[3]); if ((side[0][0] && side[0][1] && side[0][2]) && (side[0][0] < 0.0f) == (side[0][1] < 0.0f) && (side[0][0] < 0.0f) == (side[0][2] < 0.0f)) @@ -2323,13 +2323,13 @@ bool isect_tri_tri_v3_ex(const float tri_a[3][3], SWAP(int, tri_i[0], tri_i[2]); } - range[i].min = (float)(dot_b + offset0); - range[i].max = (float)(dot_b + offset1); + range[i].min = float(dot_b + offset0); + range[i].max = float(dot_b + offset1); interp_v3_v3v3(range[i].loc[0], tri[tri_i[1]], tri[tri_i[0]], fac0); interp_v3_v3v3(range[i].loc[1], tri[tri_i[1]], tri[tri_i[2]], fac1); } else { - range[i].min = range[i].max = (float)dot_b; + range[i].min = range[i].max = float(dot_b); copy_v3_v3(range[i].loc[0], tri[tri_i[1]]); copy_v3_v3(range[i].loc[1], tri[tri_i[1]]); } @@ -3019,12 +3019,12 @@ bool isect_ray_ray_epsilon_v3(const float ray_origin_a[3], sub_v3_v3v3(t, ray_origin_b, ray_origin_a); sub_v3_v3v3(c, n, t); - if (r_lambda_a != NULL) { + if (r_lambda_a != nullptr) { cross_v3_v3v3(cray, c, ray_direction_b); *r_lambda_a = dot_v3v3(cray, n) / nlen; } - if (r_lambda_b != NULL) { + if (r_lambda_b != nullptr) { cross_v3_v3v3(cray, c, ray_direction_a); *r_lambda_b = dot_v3v3(cray, n) / nlen; } @@ -3057,7 +3057,7 @@ bool isect_aabb_aabb_v3(const float min1[3], min2[1] < max1[1] && min2[2] < max1[2]); } -void isect_ray_aabb_v3_precalc(struct IsectRayAABB_Precalc *data, +void isect_ray_aabb_v3_precalc(IsectRayAABB_Precalc *data, const float ray_origin[3], const float ray_direction[3]) { @@ -3072,7 +3072,7 @@ void isect_ray_aabb_v3_precalc(struct IsectRayAABB_Precalc *data, data->sign[2] = data->ray_inv_dir[2] < 0.0f; } -bool isect_ray_aabb_v3(const struct IsectRayAABB_Precalc *data, +bool isect_ray_aabb_v3(const IsectRayAABB_Precalc *data, const float bb_min[3], const float bb_max[3], float *tmin_out) @@ -3133,17 +3133,17 @@ bool isect_ray_aabb_v3_simple(const float orig[3], { double t[6]; float hit_dist[2]; - const double invdirx = (dir[0] > 1e-35f || dir[0] < -1e-35f) ? 1.0 / (double)dir[0] : DBL_MAX; - const double invdiry = (dir[1] > 1e-35f || dir[1] < -1e-35f) ? 1.0 / (double)dir[1] : DBL_MAX; - const double invdirz = (dir[2] > 1e-35f || dir[2] < -1e-35f) ? 1.0 / (double)dir[2] : DBL_MAX; - t[0] = (double)(bb_min[0] - orig[0]) * invdirx; - t[1] = (double)(bb_max[0] - orig[0]) * invdirx; - t[2] = (double)(bb_min[1] - orig[1]) * invdiry; - t[3] = (double)(bb_max[1] - orig[1]) * invdiry; - t[4] = (double)(bb_min[2] - orig[2]) * invdirz; - t[5] = (double)(bb_max[2] - orig[2]) * invdirz; - hit_dist[0] = (float)fmax(fmax(fmin(t[0], t[1]), fmin(t[2], t[3])), fmin(t[4], t[5])); - hit_dist[1] = (float)fmin(fmin(fmax(t[0], t[1]), fmax(t[2], t[3])), fmax(t[4], t[5])); + const double invdirx = (dir[0] > 1e-35f || dir[0] < -1e-35f) ? 1.0 / double(dir[0]) : DBL_MAX; + const double invdiry = (dir[1] > 1e-35f || dir[1] < -1e-35f) ? 1.0 / double(dir[1]) : DBL_MAX; + const double invdirz = (dir[2] > 1e-35f || dir[2] < -1e-35f) ? 1.0 / double(dir[2]) : DBL_MAX; + t[0] = double(bb_min[0] - orig[0]) * invdirx; + t[1] = double(bb_max[0] - orig[0]) * invdirx; + t[2] = double(bb_min[1] - orig[1]) * invdiry; + t[3] = double(bb_max[1] - orig[1]) * invdiry; + t[4] = double(bb_min[2] - orig[2]) * invdirz; + t[5] = double(bb_max[2] - orig[2]) * invdirz; + hit_dist[0] = float(fmax(fmax(fmin(t[0], t[1]), fmin(t[2], t[3])), fmin(t[4], t[5]))); + hit_dist[1] = float(fmin(fmin(fmax(t[0], t[1]), fmax(t[2], t[3])), fmax(t[4], t[5]))); if ((hit_dist[1] < 0.0f) || (hit_dist[0] > hit_dist[1])) { return false; } @@ -3314,17 +3314,17 @@ int isect_point_tri_v2_int( { float v1[2], v2[2], v3[2], p[2]; - v1[0] = (float)x1; - v1[1] = (float)y1; + v1[0] = float(x1); + v1[1] = float(y1); - v2[0] = (float)x1; - v2[1] = (float)y2; + v2[0] = float(x1); + v2[1] = float(y2); - v3[0] = (float)x2; - v3[1] = (float)y1; + v3[0] = float(x2); + v3[1] = float(y1); - p[0] = (float)a; - p[1] = (float)b; + p[0] = float(a); + p[1] = float(b); return isect_point_tri_v2(p, v1, v2, v3); } @@ -3979,9 +3979,9 @@ int interp_sparse_array(float *array, const int list_size, const float skipval) for (i = 0; i < list_size; i++) { if (array[i] == skipval) { if (array_up[i] != skipval && array_down[i] != skipval) { - array[i] = ((array_up[i] * (float)ofs_tot_down[i]) + - (array_down[i] * (float)ofs_tot_up[i])) / - (float)(ofs_tot_down[i] + ofs_tot_up[i]); + array[i] = ((array_up[i] * float(ofs_tot_down[i])) + + (array_down[i] * float(ofs_tot_up[i]))) / + float(ofs_tot_down[i] + ofs_tot_up[i]); } else if (array_up[i] != skipval) { array[i] = array_up[i]; @@ -4026,8 +4026,7 @@ struct Double2_Len { /* Mean value weights - smooth interpolation weights for polygons with * more than 3 vertices */ -static float mean_value_half_tan_v3(const struct Float3_Len *d_curr, - const struct Float3_Len *d_next) +static float mean_value_half_tan_v3(const Float3_Len *d_curr, const Float3_Len *d_next) { float cross[3]; cross_v3_v3v3(cross, d_curr->dir, d_next->dir); @@ -4053,8 +4052,7 @@ static float mean_value_half_tan_v3(const struct Float3_Len *d_curr, * do not indicate a point "inside" the polygon. * To resolve this, doubles are used. */ -static double mean_value_half_tan_v2_db(const struct Double2_Len *d_curr, - const struct Double2_Len *d_next) +static double mean_value_half_tan_v2_db(const Double2_Len *d_curr, const Double2_Len *d_next) { /* Different from the 3d version but still correct. */ const double area = cross_v2v2_db(d_curr->dir, d_next->dir); @@ -4091,7 +4089,7 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[ float totweight = 0.0f; int i_curr, i_next; char ix_flag = 0; - struct Float3_Len d_curr, d_next; + Float3_Len d_curr, d_next; /* loop over 'i_next' */ i_curr = n - 1; @@ -4134,7 +4132,7 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[ } if (ix_flag) { - memset(w, 0, sizeof(*w) * (size_t)n); + memset(w, 0, sizeof(*w) * size_t(n)); if (ix_flag & IS_POINT_IX) { w[i_curr] = 1.0f; @@ -4176,7 +4174,7 @@ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[ float totweight = 0.0f; int i_curr, i_next; char ix_flag = 0; - struct Double2_Len d_curr, d_next; + Double2_Len d_curr, d_next; /* loop over 'i_next' */ i_curr = n - 1; @@ -4207,7 +4205,7 @@ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[ d_curr = d_next; DIR_V2_SET(&d_next, v_next, co); ht = mean_value_half_tan_v2_db(&d_curr, &d_next); - w[i_curr] = (d_curr.len == 0.0) ? 0.0f : (float)((ht_prev + ht) / d_curr.len); + w[i_curr] = (d_curr.len == 0.0) ? 0.0f : float((ht_prev + ht) / d_curr.len); totweight += w[i_curr]; /* step */ @@ -4219,7 +4217,7 @@ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[ } if (ix_flag) { - memset(w, 0, sizeof(*w) * (size_t)n); + memset(w, 0, sizeof(*w) * size_t(n)); if (ix_flag & IS_POINT_IX) { w[i_curr] = 1.0f; @@ -4297,8 +4295,8 @@ void resolve_tri_uv_v2( if (IS_ZERO(det) == 0) { const double x[2] = {st[0] - st2[0], st[1] - st2[1]}; - r_uv[0] = (float)((d * x[0] - b * x[1]) / det); - r_uv[1] = (float)(((-c) * x[0] + a * x[1]) / det); + r_uv[0] = float((d * x[0] - b * x[1]) / det); + r_uv[1] = float(((-c) * x[0] + a * x[1]) / det); } else { zero_v2(r_uv); @@ -4327,8 +4325,8 @@ void resolve_tri_uv_v3( if (IS_ZERO(det) == 0) { float w; - w = (float)((d00 * d21 - d01 * d20) / det); - r_uv[1] = (float)((d11 * d20 - d01 * d21) / det); + w = float((d00 * d21 - d01 * d20) / det); + r_uv[1] = float((d11 * d20 - d01 * d21) / det); r_uv[0] = 1.0f - r_uv[1] - w; } else { @@ -4343,7 +4341,7 @@ void resolve_quad_uv_v2(float r_uv[2], const float st2[2], const float st3[2]) { - resolve_quad_uv_v2_deriv(r_uv, NULL, st, st0, st1, st2, st3); + resolve_quad_uv_v2_deriv(r_uv, nullptr, st, st0, st1, st2, st3); } void resolve_quad_uv_v2_deriv(float r_uv[2], @@ -4364,10 +4362,9 @@ void resolve_quad_uv_v2_deriv(float r_uv[2], const double a = (st0[0] - st[0]) * (st0[1] - st3[1]) - (st0[1] - st[1]) * (st0[0] - st3[0]); /* B = ( (p0 - p) X (p1 - p2) + (p1 - p) X (p0 - p3) ) / 2 */ - const double b = 0.5 * (double)(((st0[0] - st[0]) * (st1[1] - st2[1]) - - (st0[1] - st[1]) * (st1[0] - st2[0])) + - ((st1[0] - st[0]) * (st0[1] - st3[1]) - - (st1[1] - st[1]) * (st0[0] - st3[0]))); + const double b = + 0.5 * double(((st0[0] - st[0]) * (st1[1] - st2[1]) - (st0[1] - st[1]) * (st1[0] - st2[0])) + + ((st1[0] - st[0]) * (st0[1] - st3[1]) - (st1[1] - st[1]) * (st0[0] - st3[0]))); /* C = (p1-p) X (p1-p2) */ const double fC = (st1[0] - st[0]) * (st1[1] - st2[1]) - (st1[1] - st[1]) * (st1[0] - st2[0]); @@ -4379,7 +4376,7 @@ void resolve_quad_uv_v2_deriv(float r_uv[2], if (IS_ZERO(denom) != 0) { const double fDen = a - fC; if (IS_ZERO(fDen) == 0) { - r_uv[0] = (float)(a / fDen); + r_uv[0] = float(a / fDen); } } else { @@ -4387,7 +4384,7 @@ void resolve_quad_uv_v2_deriv(float r_uv[2], const double desc = sqrt(desc_sq < 0.0 ? 0.0 : desc_sq); const double s = signed_area > 0 ? (-1.0) : 1.0; - r_uv[0] = (float)(((a - b) + s * desc) / denom); + r_uv[0] = float(((a - b) + s * desc) / denom); } /* find UV such that @@ -4404,9 +4401,8 @@ void resolve_quad_uv_v2_deriv(float r_uv[2], } if (IS_ZERO(denom) == 0) { - r_uv[1] = (float)((double)((1.0f - r_uv[0]) * (st0[i] - st[i]) + - r_uv[0] * (st1[i] - st[i])) / - denom); + r_uv[1] = float(double((1.0f - r_uv[0]) * (st0[i] - st[i]) + r_uv[0] * (st1[i] - st[i])) / + denom); } } @@ -4428,10 +4424,10 @@ void resolve_quad_uv_v2_deriv(float r_uv[2], if (!IS_ZERO(denom)) { double inv_denom = 1.0 / denom; - r_deriv[0][0] = (float)((double)-t[1] * inv_denom); - r_deriv[0][1] = (float)((double)t[0] * inv_denom); - r_deriv[1][0] = (float)((double)s[1] * inv_denom); - r_deriv[1][1] = (float)((double)-s[0] * inv_denom); + r_deriv[0][0] = float(double(-t[1]) * inv_denom); + r_deriv[0][1] = float(double(t[0]) * inv_denom); + r_deriv[1][0] = float(double(s[1]) * inv_denom); + r_deriv[1][1] = float(double(-s[0]) * inv_denom); } } } @@ -4452,10 +4448,9 @@ float resolve_quad_u_v2(const float st[2], const double a = (st0[0] - st[0]) * (st0[1] - st3[1]) - (st0[1] - st[1]) * (st0[0] - st3[0]); /* B = ( (p0 - p) X (p1 - p2) + (p1 - p) X (p0 - p3) ) / 2 */ - const double b = 0.5 * (double)(((st0[0] - st[0]) * (st1[1] - st2[1]) - - (st0[1] - st[1]) * (st1[0] - st2[0])) + - ((st1[0] - st[0]) * (st0[1] - st3[1]) - - (st1[1] - st[1]) * (st0[0] - st3[0]))); + const double b = + 0.5 * double(((st0[0] - st[0]) * (st1[1] - st2[1]) - (st0[1] - st[1]) * (st1[0] - st2[0])) + + ((st1[0] - st[0]) * (st0[1] - st3[1]) - (st1[1] - st[1]) * (st0[0] - st3[0]))); /* C = (p1-p) X (p1-p2) */ const double fC = (st1[0] - st[0]) * (st1[1] - st2[1]) - (st1[1] - st[1]) * (st1[0] - st2[0]); @@ -4464,7 +4459,7 @@ float resolve_quad_u_v2(const float st[2], if (IS_ZERO(denom) != 0) { const double fDen = a - fC; if (IS_ZERO(fDen) == 0) { - return (float)(a / fDen); + return float(a / fDen); } return 0.0f; @@ -4474,7 +4469,7 @@ float resolve_quad_u_v2(const float st[2], const double desc = sqrt(desc_sq < 0.0 ? 0.0 : desc_sq); const double s = signed_area > 0 ? (-1.0) : 1.0; - return (float)(((a - b) + s * desc) / denom); + return float(((a - b) + s * desc) / denom); } #undef IS_ZERO @@ -4730,14 +4725,14 @@ void projmat_from_subregion(const float projmat[4][4], const int y_max, float r_projmat[4][4]) { - float rect_width = (float)(x_max - x_min); - float rect_height = (float)(y_max - y_min); + float rect_width = float(x_max - x_min); + float rect_height = float(y_max - y_min); - float x_sca = (float)win_size[0] / rect_width; - float y_sca = (float)win_size[1] / rect_height; + float x_sca = float(win_size[0]) / rect_width; + float y_sca = float(win_size[1]) / rect_height; - float x_fac = (float)((x_min + x_max) - win_size[0]) / rect_width; - float y_fac = (float)((y_min + y_max) - win_size[1]) / rect_height; + float x_fac = float((x_min + x_max) - win_size[0]) / rect_width; + float y_fac = float((y_min + y_max) - win_size[1]) / rect_height; copy_m4_m4(r_projmat, projmat); r_projmat[0][0] *= x_sca; @@ -4944,7 +4939,7 @@ bool map_to_tube(float *r_u, float *r_v, const float x, const float y, const flo } else { /* The "Regular" case, just compute the coordinate. */ - *r_u = snap_coordinate(atan2f(x, -y) / (float)(2.0f * M_PI)); + *r_u = snap_coordinate(atan2f(x, -y) / float(2.0f * M_PI)); } *r_v = (z + 1.0f) / 2.0f; return regular; @@ -4961,9 +4956,9 @@ bool map_to_sphere(float *r_u, float *r_v, const float x, const float y, const f } else { /* The "Regular" case, just compute the coordinate. */ - *r_u = snap_coordinate(atan2f(x, -y) / (float)(2.0f * M_PI)); + *r_u = snap_coordinate(atan2f(x, -y) / float(2.0f * M_PI)); } - *r_v = snap_coordinate(atan2f(len_xy, -z) / (float)M_PI); + *r_v = snap_coordinate(atan2f(len_xy, -z) / float(M_PI)); return regular; } @@ -5040,7 +5035,7 @@ void accumulate_vertex_normals_v3(float n1[3], const float co4[3]) { float vdiffs[4][3]; - const int nverts = (n4 != NULL && co4 != NULL) ? 4 : 3; + const int nverts = (n4 != nullptr && co4 != nullptr) ? 4 : 3; /* compute normalized edge vectors */ sub_v3_v3v3(vdiffs[0], co2, co1); @@ -5211,7 +5206,7 @@ void vcloud_estimate_transform_v3(const int list_size, } } if (!weight || !rweight) { - accu_weight = accu_rweight = (float)list_size; + accu_weight = accu_rweight = float(list_size); } mul_v3_fl(accu_com, 1.0f / accu_weight); @@ -5725,7 +5720,7 @@ float form_factor_quad(const float p[3], dot3 = dot_v3v3(n, g2); dot4 = dot_v3v3(n, g3); - result = (a1 * dot1 + a2 * dot2 + a3 * dot3 + a4 * dot4) * 0.5f / (float)M_PI; + result = (a1 * dot1 + a2 * dot2 + a3 * dot3 + a4 * dot4) * 0.5f / float(M_PI); result = MAX2(result, 0.0f); return result; diff --git a/source/blender/blenlib/intern/path_util.cc b/source/blender/blenlib/intern/path_util.cc index bb6e0deee23..95cd7c6dbd7 100644 --- a/source/blender/blenlib/intern/path_util.cc +++ b/source/blender/blenlib/intern/path_util.cc @@ -76,7 +76,7 @@ int BLI_path_sequence_decode(const char *path, const char *const lslash = BLI_path_slash_rfind(path); const char *const extension = BLI_path_extension_or_end(lslash ? lslash : path); const uint lslash_len = lslash != nullptr ? int(lslash - path) : 0; - const uint name_end = (uint)(extension - path); + const uint name_end = uint(extension - path); for (i = name_end - 1; i >= int(lslash_len); i--) { if (isdigit(path[i])) { @@ -108,7 +108,7 @@ int BLI_path_sequence_decode(const char *path, if (r_digits_len) { *r_digits_len = nume - nums + 1; } - return (int)ret; + return int(ret); } } @@ -1166,7 +1166,7 @@ bool BLI_path_abs(char path[FILE_MAX], const char *basepath) if (lslash) { /* Length up to and including last `/`. */ - const int baselen = (int)(lslash - base) + 1; + const int baselen = int(lslash - base) + 1; /* Use path for temp storage here, we copy back over it right away. */ BLI_strncpy(path, tmp + 2, FILE_MAX); /* Strip `//` prefix. */ diff --git a/source/blender/blenlib/intern/storage.cc b/source/blender/blenlib/intern/storage.cc index 2c9a3aabd7c..7b90e0d23ce 100644 --- a/source/blender/blenlib/intern/storage.cc +++ b/source/blender/blenlib/intern/storage.cc @@ -172,7 +172,7 @@ double BLI_dir_free_space(const char *dir) } # endif - return ((double(disk.f_bsize)) * (double(disk.f_bfree))); + return double(disk.f_bsize) * double(disk.f_bfree); #endif } @@ -563,7 +563,7 @@ LinkNode *BLI_file_read_as_lines(const char *filepath) } BLI_fseek(fp, 0, SEEK_END); - size = (size_t)BLI_ftell(fp); + size = size_t(BLI_ftell(fp)); BLI_fseek(fp, 0, SEEK_SET); if (UNLIKELY(size == size_t(-1))) { diff --git a/source/blender/blenlib/intern/string_utf8.cc b/source/blender/blenlib/intern/string_utf8.cc index 097103289ac..b06cc85d9b5 100644 --- a/source/blender/blenlib/intern/string_utf8.cc +++ b/source/blender/blenlib/intern/string_utf8.cc @@ -319,7 +319,7 @@ BLI_INLINE char *str_utf8_copy_max_bytes_impl(char *dst, const char *src, size_t /* Cast to `uint8_t` is a no-op, quiets array subscript of type `char` warning. * No need to check `src` points to a nil byte as this will return from the switch statement. */ size_t utf8_size; - while ((utf8_size = (size_t)utf8_char_compute_skip(*src)) < dst_maxncpy) { + while ((utf8_size = size_t(utf8_char_compute_skip(*src))) < dst_maxncpy) { dst_maxncpy -= utf8_size; /* Prefer more compact block. */ /* NOLINTBEGIN: bugprone-assignment-in-if-condition */ @@ -356,7 +356,7 @@ size_t BLI_strncpy_utf8_rlen(char *__restrict dst, const char *__restrict src, s char *r_dst = dst; dst = str_utf8_copy_max_bytes_impl(dst, src, dst_maxncpy); - return (size_t)(dst - r_dst); + return size_t(dst - r_dst); } /* -------------------------------------------------------------------- */ @@ -371,7 +371,7 @@ size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, size_t len = 0; while (*src && len < dst_maxncpy) { - len += BLI_str_utf8_from_unicode((uint)*src++, dst + len, dst_maxncpy - len); + len += BLI_str_utf8_from_unicode(uint(*src++), dst + len, dst_maxncpy - len); } dst[len] = '\0'; /* Return the correct length when part of the final byte did not fit into the string. */ @@ -386,7 +386,7 @@ size_t BLI_wstrlen_utf8(const wchar_t *src) size_t len = 0; while (*src) { - len += BLI_str_utf8_from_unicode_len((uint)*src++); + len += BLI_str_utf8_from_unicode_len(uint(*src++)); } return len; @@ -401,7 +401,7 @@ size_t BLI_strlen_utf8_ex(const char *strc, size_t *r_len_bytes) strc += BLI_str_utf8_size_safe(strc); } - *r_len_bytes = (size_t)(strc - strc_orig); + *r_len_bytes = size_t(strc - strc_orig); return len; } @@ -418,7 +418,7 @@ size_t BLI_strnlen_utf8_ex(const char *strc, const size_t strc_maxlen, size_t *r const char *strc_end = strc + strc_maxlen; while (true) { - size_t step = (size_t)BLI_str_utf8_size_safe(strc); + size_t step = size_t(BLI_str_utf8_size_safe(strc)); if (!*strc || strc + step > strc_end) { break; } @@ -426,7 +426,7 @@ size_t BLI_strnlen_utf8_ex(const char *strc, const size_t strc_maxlen, size_t *r len++; } - *r_len_bytes = (size_t)(strc - strc_orig); + *r_len_bytes = size_t(strc - strc_orig); return len; } @@ -762,7 +762,7 @@ uint BLI_str_utf8_as_unicode_step_or_error(const char *__restrict p, const size_t p_len, size_t *__restrict index) { - const uchar c = (uchar) * (p += *index); + const uchar c = uchar(*(p += *index)); BLI_assert(*index < p_len); BLI_assert(c != '\0'); @@ -788,7 +788,7 @@ uint BLI_str_utf8_as_unicode_step_safe(const char *__restrict p, { uint result = BLI_str_utf8_as_unicode_step_or_error(p, p_len, index); if (UNLIKELY(result == BLI_UTF8_ERR)) { - result = (uint)p[*index]; + result = uint(p[*index]); *index += 1; } BLI_assert(*index <= p_len); @@ -854,10 +854,10 @@ size_t BLI_str_utf8_from_unicode(uint c, char *dst, const size_t dst_maxncpy) } for (uint i = len - 1; i > 0; i--) { - dst[i] = (char)((c & 0x3f) | 0x80); + dst[i] = char((c & 0x3f) | 0x80); c >>= 6; } - dst[0] = (char)(c | first); + dst[0] = char(c | first); return len; } @@ -883,7 +883,7 @@ size_t BLI_str_utf8_as_utf32(char32_t *__restrict dst_w, else { *dst_w = '?'; const char *src_c_next = BLI_str_find_next_char_utf8(src_c + index, src_c_end); - index = (size_t)(src_c_next - src_c); + index = size_t(src_c_next - src_c); } dst_w++; len++; @@ -903,7 +903,7 @@ size_t BLI_str_utf32_as_utf8(char *__restrict dst, size_t len = 0; while (*src && len < dst_maxncpy) { - len += BLI_str_utf8_from_unicode((uint)*src++, dst + len, dst_maxncpy - len); + len += BLI_str_utf8_from_unicode(uint(*src++), dst + len, dst_maxncpy - len); } dst[len] = '\0'; /* Return the correct length when part of the final byte did not fit into the string. */ @@ -919,7 +919,7 @@ size_t BLI_str_utf32_as_utf8_len_ex(const char32_t *src, const size_t src_maxlen const char32_t *src_end = src + src_maxlen; while ((src < src_end) && *src) { - len += BLI_str_utf8_from_unicode_len((uint)*src++); + len += BLI_str_utf8_from_unicode_len(uint(*src++)); } return len; @@ -930,7 +930,7 @@ size_t BLI_str_utf32_as_utf8_len(const char32_t *src) size_t len = 0; while (*src) { - len += BLI_str_utf8_from_unicode_len((uint)*src++); + len += BLI_str_utf8_from_unicode_len(uint(*src++)); } return len; @@ -987,7 +987,7 @@ size_t BLI_str_partition_ex_utf8(const char *str, const char **r_suf, const bool from_right) { - const size_t str_len = end ? (size_t)(end - str) : strlen(str); + const size_t str_len = end ? size_t(end - str) : strlen(str); if (end == nullptr) { end = str + str_len; } @@ -1003,7 +1003,7 @@ size_t BLI_str_partition_ex_utf8(const char *str, str + index)) { size_t index_ofs = 0; - const uint c = BLI_str_utf8_as_unicode_step_or_error(sep, (size_t)(end - sep), &index_ofs); + const uint c = BLI_str_utf8_as_unicode_step_or_error(sep, size_t(end - sep), &index_ofs); if (UNLIKELY(c == BLI_UTF8_ERR)) { break; } @@ -1014,7 +1014,7 @@ size_t BLI_str_partition_ex_utf8(const char *str, /* `suf` is already correct in case from_right is true. */ *r_sep = sep; *r_suf = from_right ? suf : (char *)(str + index); - return (size_t)(sep - str); + return size_t(sep - str); } } @@ -1063,7 +1063,7 @@ int BLI_str_utf8_offset_from_index(const char *str, const size_t str_len, const UNUSED_VARS(code); index++; } - return (int)offset; + return int(offset); } int BLI_str_utf8_offset_to_column(const char *str, const size_t str_len, const int offset_target) @@ -1092,7 +1092,7 @@ int BLI_str_utf8_offset_from_column(const char *str, const size_t str_len, const } offset = offset_next; } - return (int)offset; + return int(offset); } int BLI_str_utf8_offset_to_column_with_tabs(const char *str, @@ -1129,7 +1129,7 @@ int BLI_str_utf8_offset_from_column_with_tabs(const char *str, } offset = offset_next; } - return (int)offset; + return int(offset); } /** \} */ diff --git a/source/blender/blenlib/intern/string_utils.cc b/source/blender/blenlib/intern/string_utils.cc index 9dee1a128d9..2841c39a369 100644 --- a/source/blender/blenlib/intern/string_utils.cc +++ b/source/blender/blenlib/intern/string_utils.cc @@ -114,11 +114,11 @@ bool BLI_string_replace_table_exact(char *string, size_t BLI_string_replace_range( char *string, size_t string_maxncpy, int src_beg, int src_end, const char *dst) { - int string_len = (int)strlen(string); + int string_len = int(strlen(string)); BLI_assert(src_beg <= src_end); BLI_assert(src_end <= string_len); const int src_len = src_end - src_beg; - int dst_len = (int)strlen(dst); + int dst_len = int(strlen(dst)); if (src_len < dst_len) { /* Grow, first handle special cases. */ @@ -140,13 +140,13 @@ size_t BLI_string_replace_range( } /* Grow. */ - memmove(string + (src_end + ofs), string + src_end, (size_t)(string_len - src_end) + 1); + memmove(string + (src_end + ofs), string + src_end, size_t(string_len - src_end) + 1); string_len += ofs; } else if (src_len > dst_len) { /* Shrink. */ const int ofs = src_len - dst_len; - memmove(string + (src_end - ofs), string + src_end, (size_t)(string_len - src_end) + 1); + memmove(string + (src_end - ofs), string + src_end, size_t(string_len - src_end) + 1); string_len -= ofs; } else { /* Simple case, no resizing. */ @@ -157,7 +157,7 @@ size_t BLI_string_replace_range( memcpy(string + src_beg, dst, size_t(dst_len)); } BLI_assert(string[string_len] == '\0'); - return (size_t)string_len; + return size_t(string_len); } /** \} */ @@ -178,7 +178,7 @@ size_t BLI_string_split_name_number(const char *name, while (a--) { if (name[a] == delim) { r_name_left[a] = '\0'; /* truncate left part here */ - *r_number = (int)atol(name + a + 1); + *r_number = int(atol(name + a + 1)); /* casting down to an int, can overflow for large numbers */ if (*r_number < 0) { *r_number = 0; @@ -562,7 +562,7 @@ size_t BLI_string_join_array(char *result, } } *c = '\0'; - return (size_t)(c - result); + return size_t(c - result); } size_t BLI_string_join_array_by_sep_char( @@ -589,7 +589,7 @@ size_t BLI_string_join_array_by_sep_char( } } *c = '\0'; - return (size_t)(c - result); + return size_t(c - result); } char *BLI_string_join_arrayN(const char *strings[], uint strings_num) diff --git a/source/blender/blenloader/intern/versioning_defaults.cc b/source/blender/blenloader/intern/versioning_defaults.cc index cafaac62034..6717966cc7e 100644 --- a/source/blender/blenloader/intern/versioning_defaults.cc +++ b/source/blender/blenloader/intern/versioning_defaults.cc @@ -547,8 +547,7 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template) LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { blo_update_defaults_scene(bmain, scene); - if (app_template && - (STREQ(app_template, "Video_Editing") || STREQ(app_template, "2D_Animation"))) { + if (app_template && STR_ELEM(app_template, "Video_Editing", "2D_Animation")) { /* Filmic is too slow, use standard until it is optimized. */ STRNCPY(scene->view_settings.view_transform, "Standard"); STRNCPY(scene->view_settings.look, "None"); diff --git a/source/blender/compositor/nodes/COM_SceneTimeNode.cc b/source/blender/compositor/nodes/COM_SceneTimeNode.cc index f4cd849f874..c1543874d35 100644 --- a/source/blender/compositor/nodes/COM_SceneTimeNode.cc +++ b/source/blender/compositor/nodes/COM_SceneTimeNode.cc @@ -21,7 +21,7 @@ void SceneTimeNode::convert_to_operations(NodeConverter &converter, const int frameNumber = context.get_framenumber(); const Scene *scene = context.get_scene(); - const double frameRate = (double(scene->r.frs_sec) / double(scene->r.frs_sec_base)); + const double frameRate = double(scene->r.frs_sec) / double(scene->r.frs_sec_base); SecondOperation->set_value(float(frameNumber / frameRate)); converter.add_operation(SecondOperation); diff --git a/source/blender/compositor/operations/COM_SummedAreaTableOperation.cc b/source/blender/compositor/operations/COM_SummedAreaTableOperation.cc index 258f0e12e1e..8dca4e293bb 100644 --- a/source/blender/compositor/operations/COM_SummedAreaTableOperation.cc +++ b/source/blender/compositor/operations/COM_SummedAreaTableOperation.cc @@ -155,8 +155,8 @@ float4 summed_area_table_sum_tiled(SocketReader *buffer, const rcti &area) int2 corrected_lower_bound = lower_bound - int2(1, 1); int2 corrected_upper_bound; - corrected_upper_bound[0] = math::min((int)buffer->get_width() - 1, upper_bound[0]); - corrected_upper_bound[1] = math::min((int)buffer->get_height() - 1, upper_bound[1]); + corrected_upper_bound[0] = math::min(int(buffer->get_width()) - 1, upper_bound[0]); + corrected_upper_bound[1] = math::min(int(buffer->get_height()) - 1, upper_bound[1]); float4 a, b, c, d, addend, substrahend; buffer->read_sampled( diff --git a/source/blender/draw/engines/eevee_next/eevee_shadow.cc b/source/blender/draw/engines/eevee_next/eevee_shadow.cc index 60639f7878b..1244b091656 100644 --- a/source/blender/draw/engines/eevee_next/eevee_shadow.cc +++ b/source/blender/draw/engines/eevee_next/eevee_shadow.cc @@ -321,7 +321,7 @@ void ShadowPunctual::compute_projection_boundaries(float light_radius, * TODO(fclem): Explain derivation. */ float cos_alpha = shadow_radius / max_lit_distance; - float sin_alpha = sqrt((1.0f - math::square(cos_alpha))); + float sin_alpha = sqrt(1.0f - math::square(cos_alpha)); float near_shift = M_SQRT2 * shadow_radius * 0.5f * (sin_alpha - cos_alpha); float side_shift = M_SQRT2 * shadow_radius * 0.5f * (sin_alpha + cos_alpha); float origin_shift = M_SQRT2 * shadow_radius / (sin_alpha - cos_alpha); @@ -345,7 +345,7 @@ void ShadowPunctual::end_sync(Light &light, float lod_bias) light_radius_, light_radius_ * softness_factor_, max_distance_, near, far, side); /* Shift shadow map origin for area light to avoid clipping nearby geometry. */ - float shift = (is_area_light(light.type)) ? near : 0.0f; + float shift = is_area_light(light.type) ? near : 0.0f; float4x4 obmat_tmp = light.object_mat; diff --git a/source/blender/draw/engines/workbench/workbench_volume.cc b/source/blender/draw/engines/workbench/workbench_volume.cc index 0376c006682..e3f09c66bc3 100644 --- a/source/blender/draw/engines/workbench/workbench_volume.cc +++ b/source/blender/draw/engines/workbench/workbench_volume.cc @@ -15,7 +15,7 @@ namespace blender::workbench { VolumePass::~VolumePass() { GPUShader **sh_p = &shaders_[0][0][0][0]; - const int n = sizeof(shaders_) / sizeof(*shaders_); + const int n = ARRAY_SIZE(shaders_); for (int i = 0; i < n; i++, sh_p++) { GPUShader *sh = *sh_p; if (sh) { diff --git a/source/blender/draw/intern/draw_curves.cc b/source/blender/draw/intern/draw_curves.cc index 507254a0624..3a59b3d5898 100644 --- a/source/blender/draw/intern/draw_curves.cc +++ b/source/blender/draw/intern/draw_curves.cc @@ -509,7 +509,7 @@ void DRW_curves_update() GPUFrameBuffer *temp_fb = nullptr; GPUFrameBuffer *prev_fb = nullptr; if (GPU_type_matches_ex(GPU_DEVICE_ANY, GPU_OS_MAC, GPU_DRIVER_ANY, GPU_BACKEND_METAL)) { - if (!(GPU_compute_shader_support())) { + if (!GPU_compute_shader_support()) { prev_fb = GPU_framebuffer_active_get(); char errorOut[256]; /* if the frame-buffer is invalid we need a dummy frame-buffer to be bound. */ diff --git a/source/blender/editors/animation/anim_filter.cc b/source/blender/editors/animation/anim_filter.cc index 2657932b4f3..60379903719 100644 --- a/source/blender/editors/animation/anim_filter.cc +++ b/source/blender/editors/animation/anim_filter.cc @@ -1822,7 +1822,7 @@ static size_t animdata_filter_grease_pencil_layer_node_recursive( size_t tmp_items = 0; /* Add grease pencil layer channels. */ - BEGIN_ANIMFILTER_SUBCHANNELS ((layer_group.base.flag & GP_LAYER_TREE_NODE_EXPANDED)) { + BEGIN_ANIMFILTER_SUBCHANNELS (layer_group.base.flag &GP_LAYER_TREE_NODE_EXPANDED) { LISTBASE_FOREACH_BACKWARD (GreasePencilLayerTreeNode *, node_, &layer_group.children) { tmp_items += animdata_filter_grease_pencil_layer_node_recursive( &tmp_data, ads, grease_pencil, node_->wrap(), filter_mode); diff --git a/source/blender/editors/animation/keyingsets.cc b/source/blender/editors/animation/keyingsets.cc index e63aa354c1e..f90a435a69b 100644 --- a/source/blender/editors/animation/keyingsets.cc +++ b/source/blender/editors/animation/keyingsets.cc @@ -876,7 +876,7 @@ KeyingSet *ANIM_keyingset_get_from_idname(Scene *scene, const char *idname) bool ANIM_keyingset_context_ok_poll(bContext *C, KeyingSet *ks) { - if ((ks->flag & KEYINGSET_ABSOLUTE)) { + if (ks->flag & KEYINGSET_ABSOLUTE) { return true; } @@ -940,7 +940,7 @@ eModifyKey_Returns ANIM_validate_keyingset(bContext *C, } /* if relative Keying Sets, poll and build up the paths */ - if ((ks->flag & KEYINGSET_ABSOLUTE)) { + if (ks->flag & KEYINGSET_ABSOLUTE) { return MODIFYKEY_SUCCESS; } diff --git a/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.cc b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.cc index 7e204d0ac3d..590b4d08fbb 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.cc +++ b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.cc @@ -174,7 +174,7 @@ static void gizmo_snap_rna_snap_elem_index_get_fn(PointerRNA * /*ptr*/, static int gizmo_snap_rna_snap_srouce_type_get_fn(PointerRNA * /*ptr*/, PropertyRNA * /*prop*/) { V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get(); - return (int)snap_data->type_source; + return int(snap_data->type_source); } static void gizmo_snap_rna_snap_srouce_type_set_fn(PointerRNA * /*ptr*/, diff --git a/source/blender/editors/sculpt_paint/paint_cursor.cc b/source/blender/editors/sculpt_paint/paint_cursor.cc index ee588755dbc..4b9a9f6e26e 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.cc +++ b/source/blender/editors/sculpt_paint/paint_cursor.cc @@ -1472,7 +1472,7 @@ static void paint_draw_2D_view_brush_cursor_default(PaintCursorContext *pcontext static void grease_pencil_eraser_draw(PaintCursorContext *pcontext) { - float radius = static_cast(BKE_brush_size_get(pcontext->scene, pcontext->brush)); + float radius = float(BKE_brush_size_get(pcontext->scene, pcontext->brush)); /* Red-ish color with alpha. */ immUniformColor4ub(255, 100, 100, 20); diff --git a/source/blender/editors/sound/sound_ops.cc b/source/blender/editors/sound/sound_ops.cc index b9cc586b64c..05341a7b409 100644 --- a/source/blender/editors/sound/sound_ops.cc +++ b/source/blender/editors/sound/sound_ops.cc @@ -357,7 +357,7 @@ static int sound_mixdown_exec(bContext *C, wmOperator *op) BLI_path_abs(filepath, BKE_main_blendfile_path(bmain)); - const double fps = (double(scene_eval->r.frs_sec) / double(scene_eval->r.frs_sec_base)); + const double fps = double(scene_eval->r.frs_sec) / double(scene_eval->r.frs_sec_base); const int start_frame = scene_eval->r.sfra; const int end_frame = scene_eval->r.efra; diff --git a/source/blender/editors/space_action/action_edit.cc b/source/blender/editors/space_action/action_edit.cc index 92a6fe790e4..263538a7e54 100644 --- a/source/blender/editors/space_action/action_edit.cc +++ b/source/blender/editors/space_action/action_edit.cc @@ -794,7 +794,7 @@ static void insert_grease_pencil_key(bAnimContext *ac, bool changed = false; if (hold_previous) { const FramesMapKey active_frame_number = layer->frame_key_at(current_frame_number); - if ((active_frame_number == -1) || (layer->frames().lookup(active_frame_number).is_null())) { + if ((active_frame_number == -1) || layer->frames().lookup(active_frame_number).is_null()) { /* There is no active frame to hold to, or it's a null frame. Therefore just insert a blank * frame. */ changed = grease_pencil->insert_blank_frame( diff --git a/source/blender/editors/space_info/info_stats.cc b/source/blender/editors/space_info/info_stats.cc index 74024f75da8..49a27d62c4f 100644 --- a/source/blender/editors/space_info/info_stats.cc +++ b/source/blender/editors/space_info/info_stats.cc @@ -870,7 +870,7 @@ void ED_info_draw_stats( else if ((ob) && (ob->type == OB_LAMP)) { stats_row(col1, labels[LIGHTS], col2, stats_fmt.totlampsel, stats_fmt.totlamp, y, height); } - else if ((object_mode == OB_MODE_OBJECT) && ob && (ELEM(ob->type, OB_MESH, OB_FONT))) { + else if ((object_mode == OB_MODE_OBJECT) && ob && ELEM(ob->type, OB_MESH, OB_FONT)) { /* Object mode with the active object a mesh or text object. */ stats_row(col1, labels[VERTS], col2, stats_fmt.totvertsel, stats_fmt.totvert, y, height); stats_row(col1, labels[EDGES], col2, stats_fmt.totedgesel, stats_fmt.totedge, y, height); diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index 1c818c1b7bc..a107531d01c 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -1133,7 +1133,7 @@ bool node_is_previewable(const SpaceNode &snode, const bNodeTree &ntree, const b return false; } if (ntree.type == NTREE_SHADER) { - return U.experimental.use_shader_node_previews && !(node.is_frame()); + return U.experimental.use_shader_node_previews && !node.is_frame(); } return node.typeinfo->flag & NODE_PREVIEW; } diff --git a/source/blender/editors/space_node/node_shader_preview.cc b/source/blender/editors/space_node/node_shader_preview.cc index 5de59f3d948..9735881d895 100644 --- a/source/blender/editors/space_node/node_shader_preview.cc +++ b/source/blender/editors/space_node/node_shader_preview.cc @@ -261,7 +261,7 @@ static bNodeSocket *node_find_preview_socket(bNodeTree &ntree, bNode &node) if (socket == nullptr) { socket = get_main_socket(ntree, node, SOCK_IN); if (socket != nullptr && socket->link == nullptr) { - if (!(ELEM(socket->type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA))) { + if (!ELEM(socket->type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA)) { /* We can not preview a socket with no link and no manual value. */ return nullptr; } diff --git a/source/blender/editors/transform/transform_convert_action.cc b/source/blender/editors/transform/transform_convert_action.cc index 69d2c647858..e5ceb3cec8e 100644 --- a/source/blender/editors/transform/transform_convert_action.cc +++ b/source/blender/editors/transform/transform_convert_action.cc @@ -498,7 +498,7 @@ static int GreasePencilLayerToTransData(TransData *td, }; const blender::Map &frame_map = - duplicate ? (layer->runtime->trans_data_.temp_frames_buffer) : (layer->frames()); + duplicate ? (layer->runtime->trans_data_.temp_frames_buffer) : layer->frames(); for (const auto [frame_number, frame] : frame_map.items()) { grease_pencil_frame_to_trans_data(frame_number, frame.is_selected()); diff --git a/source/blender/gpencil_modifiers_legacy/intern/lineart/lineart_cpu.cc b/source/blender/gpencil_modifiers_legacy/intern/lineart/lineart_cpu.cc index 37423c2e60d..903e654630a 100644 --- a/source/blender/gpencil_modifiers_legacy/intern/lineart/lineart_cpu.cc +++ b/source/blender/gpencil_modifiers_legacy/intern/lineart/lineart_cpu.cc @@ -3616,7 +3616,7 @@ static LineartData *lineart_create_render_buffer(Scene *scene, ld->qtree.recursive_level = LRT_TILE_RECURSIVE_ORTHO; } - double asp = (double(ld->w) / double(ld->h)); + double asp = double(ld->w) / double(ld->h); int fit = BKE_camera_sensor_fit(c->sensor_fit, ld->w, ld->h); ld->conf.shift_x = fit == CAMERA_SENSOR_FIT_HOR ? c->shiftx : c->shiftx / asp; ld->conf.shift_y = fit == CAMERA_SENSOR_FIT_VERT ? c->shifty : c->shifty * asp; diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index 397676e17d8..7feada82d49 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -1793,7 +1793,7 @@ static int exr_has_rgb(MultiPartInputFile &file, const char *rgb_channels[3]) std::transform(lower_case_name.begin(), lower_case_name.end(), lower_case_name.begin(), - [](unsigned char c) { return std::tolower(c); }); + [](uchar c) { return std::tolower(c); }); if (header.channels().findChannel(channel_names[i]) || header.channels().findChannel(lower_case_name)) diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_scene_time.cc b/source/blender/nodes/geometry/nodes/node_geo_input_scene_time.cc index 28313bd40a2..e7a9fda657a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_scene_time.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_scene_time.cc @@ -20,7 +20,7 @@ static void node_exec(GeoNodeExecParams params) { const Scene *scene = DEG_get_input_scene(params.depsgraph()); const float scene_ctime = BKE_scene_ctime_get(scene); - const double frame_rate = (double(scene->r.frs_sec) / double(scene->r.frs_sec_base)); + const double frame_rate = double(scene->r.frs_sec) / double(scene->r.frs_sec_base); params.set_output("Seconds", float(scene_ctime / frame_rate)); params.set_output("Frame", scene_ctime); } diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc index 7dd9ad194bb..f322fc0d41c 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc @@ -174,7 +174,7 @@ NODE_SHADER_MATERIALX_BEGIN res = (vector[0] + vector[1]) * val(0.5f); break; case SHD_BLEND_RADIAL: - res = vector[1].atan2(vector[0]) / (val(float(M_PI * 2.0f))) + val(0.5f); + res = vector[1].atan2(vector[0]) / val(float(M_PI * 2.0f)) + val(0.5f); break; case SHD_BLEND_QUADRATIC_SPHERE: res = (val(1.0f) - vector.dotproduct(vector).sqrt()).max(val(0.0f)); diff --git a/source/blender/sequencer/intern/strip_retiming.cc b/source/blender/sequencer/intern/strip_retiming.cc index 27805dabe2b..abff619694a 100644 --- a/source/blender/sequencer/intern/strip_retiming.cc +++ b/source/blender/sequencer/intern/strip_retiming.cc @@ -215,7 +215,7 @@ bool SEQ_retiming_key_is_transition_start(const SeqRetimingKey *key) SeqRetimingKey *SEQ_retiming_transition_start_get(SeqRetimingKey *key) { - if ((key->flag & SEQ_SPEED_TRANSITION_OUT)) { + if (key->flag & SEQ_SPEED_TRANSITION_OUT) { return key - 1; } if (key->flag & SEQ_SPEED_TRANSITION_IN) { diff --git a/source/blender/windowmanager/intern/wm_event_query.cc b/source/blender/windowmanager/intern/wm_event_query.cc index 023a5e1c72c..8b15163bbae 100644 --- a/source/blender/windowmanager/intern/wm_event_query.cc +++ b/source/blender/windowmanager/intern/wm_event_query.cc @@ -624,7 +624,7 @@ int WM_event_absolute_delta_y(const wmEvent *event) * * \note Shift is excluded from this check since it prevented typing `Shift+Space`, see: #85517. */ -bool WM_event_is_ime_switch(const struct wmEvent *event) +bool WM_event_is_ime_switch(const wmEvent *event) { return (event->val == KM_PRESS) && (event->type == EVT_SPACEKEY) && (event->modifier & (KM_CTRL | KM_OSKEY | KM_ALT)); diff --git a/source/blender/windowmanager/intern/wm_window.cc b/source/blender/windowmanager/intern/wm_window.cc index 70599343582..6eda9cc4147 100644 --- a/source/blender/windowmanager/intern/wm_window.cc +++ b/source/blender/windowmanager/intern/wm_window.cc @@ -1704,7 +1704,7 @@ static bool wm_window_timers_process(const bContext *C, int *sleep_us_p) * Even though using `floor` or `round` is more responsive, * it causes CPU intensive loops that may run until the timer is reached, see: #111579. */ const double microseconds = 1000000.0; - const double sleep_sec = (double(sleep_us) / microseconds); + const double sleep_sec = double(sleep_us) / microseconds; const double sleep_sec_next = ntime_min - time; if (sleep_sec_next < sleep_sec) { From afd5faceec72d9f40aaaf5191da7086d2393f05d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Nov 2023 11:36:52 +1100 Subject: [PATCH 18/62] Tools: add edit to use std min/max instead of MIN2/MAX2 macros --- tools/utils_maintenance/code_clean.py | 35 +++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tools/utils_maintenance/code_clean.py b/tools/utils_maintenance/code_clean.py index 79083346b56..42b486e5f1d 100755 --- a/tools/utils_maintenance/code_clean.py +++ b/tools/utils_maintenance/code_clean.py @@ -1076,6 +1076,41 @@ class edit_generators: return edits + class use_std_min_max(EditGenerator): + """ + Use `std::min` & `std::max` instead of `MIN2`, `MAX2` macros: + + Replace: + MAX2(a, b) + With: + std::max(a, b) + """ + is_default = True + + @staticmethod + def edit_list_from_file(source: str, data: str, _shared_edit_data: Any) -> List[Edit]: + edits: List[Edit] = [] + + # The user might include C & C++, if they forget, it is better not to operate on C. + if source.lower().endswith((".h", ".c")): + return edits + + for src, dst in ( + ("MIN2", "std::min"), + ("MAX2", "std::max"), + ): + for match in re.finditer( + (r"\b(" + src + r")\("), + data, + ): + edits.append(Edit( + span=match.span(1), + content=dst, + content_fail='__ALWAYS_FAIL__', + )) + + return edits + class use_str_sizeof_macros(EditGenerator): """ Use `STRNCPY` & `SNPRINTF` macros: From 126f3bcfc15d0ef3d4cffdb418e22d6921435d55 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 26 Oct 2023 15:19:33 +1100 Subject: [PATCH 19/62] Tests: support running graphical tests as part of CTests User a Blender wrapper `tests/utils/blender_headless.py` to runs a graphical instance of Blender within a headless weston compositor. Currently only WAYLAND is supported as a back-end, support for other platforms is possible. The tests can run from X11 since the tests don't depend on existing instances of X11 or WAYLAND. - Each test runs a separate headless instance of WESTON since the overhead is minimal, this allows tests to run in parallel without interfering with each other. - There is a CMake option WESTON_BIN, when left empty the weston from LIBDIR is used. Otherwise this can point to the weston binary installed on the users system. - In most cases simulated events are needed to implement these tests (running blender with `--enable-event-simulate`). - This commit adds 14 undo tests - simulating user interaction as well as undo/redo actions, ensuring the desired result is reached. Other kinds of UI tests could be added in the future. Ref !114164 --- CMakeLists.txt | 16 ++++++ tests/python/CMakeLists.txt | 102 +++++++++++++++++++++++++++++++++++- 2 files changed, 116 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 84d4424ec42..a35d267513e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -761,6 +761,18 @@ option(WITH_GTESTS "Enable GTest unit testing" OFF) option(WITH_OPENGL_RENDER_TESTS "Enable OpenGL render related unit testing (Experimental)" OFF) option(WITH_OPENGL_DRAW_TESTS "Enable OpenGL UI drawing related unit testing (Experimental)" OFF) option(WITH_COMPOSITOR_REALTIME_TESTS "Enable regression testing for realtime compositor" OFF) +if(UNIX AND NOT (APPLE OR HAIKU)) + option(WITH_UI_TESTS "\ +Enable user-interface tests using a headless display server. \ +Currently this depends on WITH_GHOST_WAYLAND and the weston compositor \ +(Experimental)" + OFF + ) +else() + # TODO: support running GUI tests on other platforms. + set(WITH_UI_TESTS OFF) +endif() + # NOTE: All callers of this must add `TEST_PYTHON_EXE_EXTRA_ARGS` before any other arguments. set(TEST_PYTHON_EXE "" CACHE PATH "Python executable to run unit tests") mark_as_advanced(TEST_PYTHON_EXE) @@ -1156,6 +1168,10 @@ endif() set_and_warn_incompatible(WITH_HEADLESS WITH_XR_OPENXR OFF) set_and_warn_incompatible(WITH_GHOST_SDL WITH_XR_OPENXR OFF) +if(WITH_UI_TESTS) + set_and_warn_dependency(WITH_GHOST_WAYLAND WITH_UI_TESTS OFF) +endif() + if(WITH_BUILDINFO) find_package(Git) set_and_warn_library_found("Git" GIT_FOUND WITH_BUILDINFO) diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index c0aaf587396..94030d144bf 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -22,10 +22,10 @@ file(MAKE_DIRECTORY ${TEST_OUT_DIR}/blendfile_io) # endif() # Run Blender command with parameters. -function(add_blender_test testname) +function(add_blender_test_impl testname exe) add_test( NAME ${testname} - COMMAND "${TEST_BLENDER_EXE}" ${TEST_BLENDER_EXE_PARAMS} ${ARGN} + COMMAND ${exe} ${ARGN} ) # Don't fail tests on leaks since these often happen in external libraries that we can't fix. @@ -41,6 +41,68 @@ function(add_blender_test testname) endif() endfunction() +function(add_blender_test testname) + add_blender_test_impl( + "${testname}" + "${TEST_BLENDER_EXE}" + ${TEST_BLENDER_EXE_PARAMS} + ${ARGN} + ) +endfunction() + +if(WITH_UI_TESTS) + set(_blender_headless_env_vars "BLENDER_BIN=${TEST_BLENDER_EXE}") + + # Currently only WAYLAND is supported, support for others may be added later. + # In this case none of the WESTON environment variables will be used. + if(WITH_GHOST_WAYLAND) + set(_weston_bin_in_libdir OFF) + if(DEFINED LIBDIR) + set(_weston_bin_default "${LIBDIR}/wayland_weston/bin/weston") + else() + set(_weston_bin_default "weston") + endif() + set(WESTON_BIN "${_weston_bin_default}" CACHE STRING "\ +The location of weston, leave blank for the default location." + ) + mark_as_advanced(WESTON_BIN) + if((DEFINED LIBDIR) AND ("${WESTON_BIN}" STREQUAL "${_weston_bin_default}")) + set(_weston_bin_in_libdir ON) + endif() + + list(APPEND _blender_headless_env_vars + "WESTON_BIN=${WESTON_BIN}" + ) + + if(_weston_bin_in_libdir) + list(APPEND _blender_headless_env_vars + "WAYLAND_ROOT_DIR=${LIBDIR}/wayland" + "WESTON_ROOT_DIR=${LIBDIR}/wayland_weston" + ) + endif() + endif() + + function(add_blender_test_headless testname) + # Remove `--background` so headless execution uses a GUI + # (within a headless graphical environment). + set(EXE_PARAMS ${TEST_BLENDER_EXE_PARAMS}) + list(REMOVE_ITEM EXE_PARAMS --background) + add_blender_test_impl( + "${testname}" + "${TEST_PYTHON_EXE}" + "${CMAKE_SOURCE_DIR}/tests/utils/blender_headless.py" + # NOTE: attempting to maximize the window causes problems with a headless `weston`, + # while this could be investigated, use windowed mode instead. + # Use a window size that balances software GPU rendering with enough room to use the UI. + --factory-startup + -p 0 0 800 600 + "${EXE_PARAMS}" + "${ARGN}" + ) + set_tests_properties(${testname} PROPERTIES ENVIRONMENT "${_blender_headless_env_vars}") + endfunction() +endif() + # Run Python script outside Blender. function(add_python_test testname testscript) if(NOT TEST_PYTHON_EXE) @@ -1000,6 +1062,42 @@ else() endif() +# ------------------------------------------------------------------------------ +# Headless GUI Tests + +if(WITH_UI_TESTS) + # This could be generated with: + # `"${TEST_PYTHON_EXE}" "${TEST_SRC_DIR}/ui_simulate/run.py" --list-tests` + # list explicitly so changes bisecting/updated are sure to re-run CMake. + set(_undo_tests + test_undo.text_editor_edit_mode_mix + test_undo.text_editor_simple + test_undo.view3d_edit_mode_multi_window + test_undo.view3d_font_edit_mode_simple + test_undo.view3d_mesh_edit_separate + test_undo.view3d_mesh_particle_edit_mode_simple + test_undo.view3d_multi_mode_multi_window + test_undo.view3d_multi_mode_select + test_undo.view3d_sculpt_dyntopo_and_edit + test_undo.view3d_sculpt_dyntopo_simple + test_undo.view3d_sculpt_with_memfile_step + test_undo.view3d_simple + test_undo.view3d_texture_paint_complex + test_undo.view3d_texture_paint_simple + ) + foreach(ui_test ${_undo_tests}) + add_blender_test_headless( + "bf_ui_${ui_test}" + --enable-event-simulate + --python "${TEST_SRC_DIR}/ui_simulate/run_blender_setup.py" + -- + --tests "${ui_test}" + ) + endforeach() + unset(_undo_tests) +endif() + + add_subdirectory(collada) # TODO: disabled for now after collection unification From 865944734fcfe6a8857367b98ff680016613addd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Nov 2023 12:57:45 +1100 Subject: [PATCH 20/62] Build: add the WESTON compositor for Linux WESTON is used when WITH_UI_TESTS is enabled. Note that the system WESTON installation can be used by setting WESTON_BIN to a path on the users system. Ref !114164. --- build_files/build_environment/CMakeLists.txt | 1 + .../build_environment/cmake/download.cmake | 1 + .../build_environment/cmake/harvest.cmake | 8 +++ .../build_environment/cmake/versions.cmake | 7 +++ .../cmake/wayland_weston.cmake | 56 +++++++++++++++++++ .../linux/linux_rocky8_setup.sh | 14 +++++ 6 files changed, 87 insertions(+) create mode 100644 build_files/build_environment/cmake/wayland_weston.cmake diff --git a/build_files/build_environment/CMakeLists.txt b/build_files/build_environment/CMakeLists.txt index 0f705d7f501..4e3875be070 100644 --- a/build_files/build_environment/CMakeLists.txt +++ b/build_files/build_environment/CMakeLists.txt @@ -168,6 +168,7 @@ if(UNIX AND NOT APPLE) # Can be removed when the build-bot upgrades to v1.20.x or newer. include(cmake/wayland.cmake) include(cmake/wayland_libdecor.cmake) + include(cmake/wayland_weston.cmake) endif() include(cmake/shaderc_deps.cmake) include(cmake/shaderc.cmake) diff --git a/build_files/build_environment/cmake/download.cmake b/build_files/build_environment/cmake/download.cmake index 58058b60a19..f1c04ba6ef8 100644 --- a/build_files/build_environment/cmake/download.cmake +++ b/build_files/build_environment/cmake/download.cmake @@ -137,6 +137,7 @@ download_source(XR_OPENXR_SDK) download_source(WL_PROTOCOLS) download_source(WAYLAND) download_source(WAYLAND_LIBDECOR) +download_source(WAYLAND_WESTON) download_source(ISPC) download_source(GMP) download_source(POTRACE) diff --git a/build_files/build_environment/cmake/harvest.cmake b/build_files/build_environment/cmake/harvest.cmake index ebfbe9b4223..61a8745892e 100644 --- a/build_files/build_environment/cmake/harvest.cmake +++ b/build_files/build_environment/cmake/harvest.cmake @@ -191,6 +191,14 @@ else() harvest(wayland/bin wayland/bin "wayland-scanner") harvest(wayland/include wayland/include "*.h") harvest(wayland_libdecor/include wayland_libdecor/include "*.h") + # Only needed for running the WESTON compositor. + harvest(wayland/lib64 wayland/lib64 "*") + + harvest( + wayland_weston/ + wayland_weston/ + "*" + ) else() harvest(blosc/lib openvdb/lib "*.a") harvest(xml2/lib opencollada/lib "*.a") diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake index e5ce66e7acb..893c398cac1 100644 --- a/build_files/build_environment/cmake/versions.cmake +++ b/build_files/build_environment/cmake/versions.cmake @@ -574,6 +574,13 @@ set(WAYLAND_LIBDECOR_HASH 47b59eba76faa3787f0878bf8700e912) set(WAYLAND_LIBDECOR_HASH_TYPE MD5) set(WAYLAND_LIBDECOR_HOMEPAGE https://gitlab.freedesktop.org/libdecor/libdecor) +set(WAYLAND_WESTON_VERSION 12.0.92) +set(WAYLAND_WESTON_FILE weston-${WAYLAND_WESTON_VERSION}.tar.xz) +set(WAYLAND_WESTON_URI https://gitlab.freedesktop.org/wayland/weston/-/releases/${WAYLAND_WESTON_VERSION}/downloads/weston-${WAYLAND_WESTON_VERSION}.tar.xz) +set(WAYLAND_WESTON_HASH 44542b60bf9b9fe3add904af11bbad98) +set(WAYLAND_WESTON_HASH_TYPE MD5) +set(WAYLAND_WESTON_HOMEPAGE https://wayland.freedesktop.org) + set(ISPC_VERSION v1.17.0) set(ISPC_URI https://github.com/ispc/ispc/archive/${ISPC_VERSION}.tar.gz) set(ISPC_HASH 4f476a3109332a77fe839a9014c60ca9) diff --git a/build_files/build_environment/cmake/wayland_weston.cmake b/build_files/build_environment/cmake/wayland_weston.cmake new file mode 100644 index 00000000000..2211e98c6cb --- /dev/null +++ b/build_files/build_environment/cmake/wayland_weston.cmake @@ -0,0 +1,56 @@ +# SPDX-FileCopyrightText: 2023 Blender Authors +# +# SPDX-License-Identifier: GPL-2.0-or-later + +set(WAYLAND_WESTON_CONFIGURE_ENV ${CONFIGURE_ENV}) +set(WAYLAND_WESTON_PKG_ENV "PKG_CONFIG_PATH=\ +${LIBDIR}/wayland/lib64/pkgconfig:\ +${LIBDIR}/wayland-protocols/share/pkgconfig:\ +$PKG_CONFIG_PATH" +) + +ExternalProject_Add(external_wayland_weston + URL file://${PACKAGE_DIR}/${WAYLAND_WESTON_FILE} + URL_HASH ${WAYLAND_WESTON_HASH_TYPE}=${WAYLAND_WESTON_HASH} + DOWNLOAD_DIR ${DOWNLOAD_DIR} + PREFIX ${BUILD_DIR}/wayland_weston + + CONFIGURE_COMMAND ${WAYLAND_WESTON_CONFIGURE_ENV} && + ${CMAKE_COMMAND} -E env ${WAYLAND_WESTON_PKG_ENV} + ${MESON} setup + ${MESON_BUILD_TYPE} + --prefix ${LIBDIR}/wayland_weston + --libdir lib + -Dbackend-default=headless # For tests. + -Dbackend-drm-screencast-vaapi=false + -Dbackend-drm=false + -Dbackend-pipewire=false + -Dbackend-rdp=false + -Dcolor-management-lcms=false + -Ddemo-clients=false + -Dimage-jpeg=false + -Dimage-webp=false + -Dpipewire=false + -Dremoting=false + -Dshell-fullscreen=false + -Dshell-kiosk=false + -Dsimple-clients= + -Dsystemd=false + -Dtest-junit-xml=false + -Dwcap-decode=false + -Dxwayland=false + ${BUILD_DIR}/wayland_weston/src/external_wayland_weston-build + ${BUILD_DIR}/wayland_weston/src/external_wayland_weston + + BUILD_COMMAND ninja + INSTALL_COMMAND ninja install + INSTALL_DIR ${LIBDIR}/wayland_weston +) + +add_dependencies( + external_wayland_weston + external_wayland_protocols + external_wayland + # Needed for `MESON`. + external_python_site_packages +) diff --git a/build_files/build_environment/linux/linux_rocky8_setup.sh b/build_files/build_environment/linux/linux_rocky8_setup.sh index 51dbe814157..b89d5726804 100644 --- a/build_files/build_environment/linux/linux_rocky8_setup.sh +++ b/build_files/build_environment/linux/linux_rocky8_setup.sh @@ -109,6 +109,20 @@ PACKAGES_FOR_LIBS=( # Required by: `external_ssl` (build dependencies). perl-IPC-Cmd perl-Pod-Html + + # Required by: `external_wayland_weston` + cairo-devel + libdrm-devel + pixman-devel + libffi-devel + libinput-devel + libevdev-devel + mesa-libEGL-devel + systemd-dev # for `libudev` (not so obvious!). + # Required by: `weston --headless` (run-time requirement for off screen rendering). + mesa-dri-drivers + mesa-libEGL + mesa-libGL ) # Additional packages needed for building Blender. From b771ce8ce413d3b75e9a9ba00570cf0c53b0a1f9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Nov 2023 14:14:54 +1100 Subject: [PATCH 21/62] Build: disable some unnecessary tools & options for WESTON --- build_files/build_environment/cmake/wayland_weston.cmake | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/build_files/build_environment/cmake/wayland_weston.cmake b/build_files/build_environment/cmake/wayland_weston.cmake index 2211e98c6cb..ff97f4222b9 100644 --- a/build_files/build_environment/cmake/wayland_weston.cmake +++ b/build_files/build_environment/cmake/wayland_weston.cmake @@ -15,6 +15,10 @@ ExternalProject_Add(external_wayland_weston DOWNLOAD_DIR ${DOWNLOAD_DIR} PREFIX ${BUILD_DIR}/wayland_weston + # Notes: + # - Disable nearly everything as only a simple headless server is needed for testing. + # - Keep X11 and WAYLAND back-ends enabled so it's possible + # to run the instance inside existing X11/WAYLAND sessions (for debugging). CONFIGURE_COMMAND ${WAYLAND_WESTON_CONFIGURE_ENV} && ${CMAKE_COMMAND} -E env ${WAYLAND_WESTON_PKG_ENV} ${MESON} setup @@ -26,17 +30,22 @@ ExternalProject_Add(external_wayland_weston -Dbackend-drm=false -Dbackend-pipewire=false -Dbackend-rdp=false + -Dbackend-vnc=false -Dcolor-management-lcms=false -Ddemo-clients=false + -Ddoc=false -Dimage-jpeg=false -Dimage-webp=false -Dpipewire=false -Dremoting=false + -Dscreenshare=false -Dshell-fullscreen=false + -Dshell-ivi=false -Dshell-kiosk=false -Dsimple-clients= -Dsystemd=false -Dtest-junit-xml=false + -Dtools= -Dwcap-decode=false -Dxwayland=false ${BUILD_DIR}/wayland_weston/src/external_wayland_weston-build From 1496aa9d3eb0b96118341f9191e3f010cd95fad5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Nov 2023 14:15:12 +1100 Subject: [PATCH 22/62] Tests: support running Blender with pre-compiled WAYLAND libraries --- tests/utils/blender_headless.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/utils/blender_headless.py b/tests/utils/blender_headless.py index 06e140149a1..1c45c572ac3 100644 --- a/tests/utils/blender_headless.py +++ b/tests/utils/blender_headless.py @@ -287,7 +287,12 @@ class backend_wayland(backend_base): blender_env = {**os.environ, "WAYLAND_DISPLAY": socket} + # Needed so Blender can find WAYLAND libraries such as `libwayland-cursor.so`. + if weston_env is not None and "LD_LIBRARY_PATH" in weston_env: + blender_env["LD_LIBRARY_PATH"] = weston_env["LD_LIBRARY_PATH"] + cmd = [ + # "strace", # Can be useful for debugging any startup issues. BLENDER_BIN, *blender_args, ] From f2fcfc8730e06e0e3e04c44060b3f8236c73e674 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Nov 2023 14:50:22 +1100 Subject: [PATCH 23/62] Tests: move undo tests from SVN into tests/python/ui_simulate --- tests/python/CMakeLists.txt | 4 +- tests/python/ui_simulate/modules/__init__.py | 0 tests/python/ui_simulate/modules/easy_keys.py | 357 +++++++ tests/python/ui_simulate/run.py | 193 ++++ tests/python/ui_simulate/run_blender_setup.py | 113 +++ tests/python/ui_simulate/test_undo.py | 894 ++++++++++++++++++ 6 files changed, 1559 insertions(+), 2 deletions(-) create mode 100644 tests/python/ui_simulate/modules/__init__.py create mode 100644 tests/python/ui_simulate/modules/easy_keys.py create mode 100755 tests/python/ui_simulate/run.py create mode 100644 tests/python/ui_simulate/run_blender_setup.py create mode 100644 tests/python/ui_simulate/test_undo.py diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index 94030d144bf..55721fa4913 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -1067,7 +1067,7 @@ endif() if(WITH_UI_TESTS) # This could be generated with: - # `"${TEST_PYTHON_EXE}" "${TEST_SRC_DIR}/ui_simulate/run.py" --list-tests` + # `"${TEST_PYTHON_EXE}" "${CMAKE_CURRENT_LIST_DIR}/ui_simulate/run.py" --list-tests` # list explicitly so changes bisecting/updated are sure to re-run CMake. set(_undo_tests test_undo.text_editor_edit_mode_mix @@ -1089,7 +1089,7 @@ if(WITH_UI_TESTS) add_blender_test_headless( "bf_ui_${ui_test}" --enable-event-simulate - --python "${TEST_SRC_DIR}/ui_simulate/run_blender_setup.py" + --python "${CMAKE_CURRENT_LIST_DIR}/ui_simulate/run_blender_setup.py" -- --tests "${ui_test}" ) diff --git a/tests/python/ui_simulate/modules/__init__.py b/tests/python/ui_simulate/modules/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/python/ui_simulate/modules/easy_keys.py b/tests/python/ui_simulate/modules/easy_keys.py new file mode 100644 index 00000000000..3d8f08e3176 --- /dev/null +++ b/tests/python/ui_simulate/modules/easy_keys.py @@ -0,0 +1,357 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +import string +import bpy +event_types = tuple( + e.identifier.lower() + for e in bpy.types.Event.bl_rna.properties["type"].enum_items_static +) +del bpy + +# We don't normally care about which one. +event_types_alias = { + "ctrl": "left_ctrl", + "shift": "left_shift", + "alt": "left_alt", + + # Collides with Python keywords. + "delete": "del", +} + + +# Note, we could add support for other keys using control characters, +# for example: `\xF12` could be used for the F12 key. +# +# Besides this, we could encode symbols into a regular string using our own syntax +# which can mix regular text and key symbols. +# +# At the moment this doesn't seem necessary, no need to add it. +event_types_text = ( + ('ZERO', "0", False), + ('ONE', "1", False), + ('TWO', "2", False), + ('THREE', "3", False), + ('FOUR', "4", False), + ('FIVE', "5", False), + ('SIX', "6", False), + ('SEVEN', "7", False), + ('EIGHT', "8", False), + ('NINE', "9", False), + + ('ONE', "!", True), + ('TWO', "@", True), + ('THREE', "#", True), + ('FOUR', "$", True), + ('FIVE', "%", True), + ('SIX', "^", True), + ('SEVEN', "&", True), + ('EIGHT', "*", True), + ('NINE', "(", True), + ('ZERO', ")", True), + + ('MINUS', "-", False), + ('MINUS', "_", True), + + ('EQUAL', "=", False), + ('EQUAL', "+", True), + + ('ACCENT_GRAVE', "`", False), + ('ACCENT_GRAVE', "~", True), + + ('LEFT_BRACKET', "[", False), + ('LEFT_BRACKET', "{", True), + + ('RIGHT_BRACKET', "]", False), + ('RIGHT_BRACKET', "}", True), + + ('SEMI_COLON', ";", False), + ('SEMI_COLON', ":", True), + + ('PERIOD', ".", False), + ('PERIOD', ">", True), + + ('COMMA', ",", False), + ('COMMA', "<", True), + + ('QUOTE', "'", False), + ('QUOTE', '"', True), + + ('SLASH', "/", False), + ('SLASH', "?", True), + + ('BACK_SLASH', "\\", False), + ('BACK_SLASH', "|", True), + + + *((ch_upper, ch, False) for (ch_upper, ch) in zip(string.ascii_uppercase, string.ascii_lowercase)), + *((ch, ch, True) for ch in string.ascii_uppercase), + + ('SPACE', " ", False), + ('RET', "\n", False), + ('TAB', "\t", False), +) + +event_types_text_from_char = {ch: (ty, is_shift) for (ty, ch, is_shift) in event_types_text} +event_types_text_from_event = {(ty, is_shift): ch for (ty, ch, is_shift) in event_types_text} + + +class _EventBuilder: + __slots__ = ( + "_shared_event_gen", + "_event_type", + "_parent", + ) + + def __init__(self, event_gen, ty): + self._shared_event_gen = event_gen + self._event_type = ty + self._parent = None + + def __call__(self, count=1): + assert count >= 0 + for _ in range(count): + self.tap() + return self._shared_event_gen + + def _key_press_release(self, do_press=False, do_release=False, unicode_override=None): + assert (do_press or do_release) + keys_held = self._shared_event_gen._event_types_held + build_keys = [] + e = self + while e is not None: + build_keys.append(e._event_type.upper()) + e = e._parent + build_keys.reverse() + + events = [None, None] + for i, value in enumerate(('PRESS', 'RELEASE')): + if value == 'RELEASE': + build_keys.reverse() + for event_type in build_keys: + if value == 'PRESS': + keys_held.add(event_type) + else: + keys_held.remove(event_type) + + if (not do_press) and value == 'PRESS': + continue + if (not do_release) and value == 'RELEASE': + continue + + shift = 'LEFT_SHIFT' in keys_held or 'RIGHT_SHIFT' in keys_held + ctrl = 'LEFT_CTRL' in keys_held or 'RIGHT_CTRL' in keys_held + shift = 'LEFT_SHIFT' in keys_held or 'RIGHT_SHIFT' in keys_held + alt = 'LEFT_ALT' in keys_held or 'RIGHT_ALT' in keys_held + oskey = 'OSKEY' in keys_held + + unicode = None + if value == 'PRESS': + if ctrl is False and alt is False and oskey is False: + if unicode_override is not None: + unicode = unicode_override + else: + unicode = event_types_text_from_event.get((event_type, shift)) + if unicode is None and shift: + # Some keys don't care about shift + unicode = event_types_text_from_event.get((event_type, False)) + + event = self._shared_event_gen.window.event_simulate( + type=event_type, + value=value, + unicode=unicode, + shift=shift, + ctrl=ctrl, + alt=alt, + oskey=oskey, + x=self._shared_event_gen._mouse_co[0], + y=self._shared_event_gen._mouse_co[1], + ) + events[i] = event + return tuple(events) + + def tap(self): + return self._key_press_release(do_press=True, do_release=True) + + def press(self): + return self._key_press_release(do_press=True)[0] + + def release(self): + return self._key_press_release(do_release=True)[1] + + def cursor_motion(self, coords): + coords = list(coords) + self._shared_event_gen.cursor_position_set(*coords[0], move=True) + yield + + event = self.press() + shift = event.shift + ctrl = event.ctrl + shift = event.shift + alt = event.alt + oskey = event.oskey + yield + + for x, y in coords: + self._shared_event_gen.window.event_simulate( + type='MOUSEMOVE', + value='NOTHING', + unicode=None, + shift=shift, + ctrl=ctrl, + alt=alt, + oskey=oskey, + x=x, + y=y + ) + yield + self._shared_event_gen.cursor_position_set(x, y, move=False) + self.release() + yield + + def __getattr__(self, attr): + attr = event_types_alias.get(attr, attr) + if attr in event_types: + e = _EventBuilder(self._shared_event_gen, attr) + e._parent = self + return e + raise Exception(f"{attr!r} not found in {event_types!r}") + + +class EventGenerate: + __slots__ = ( + "window", + + "_mouse_co", + "_event_types_held", + ) + + def __init__(self, window): + self.window = window + self._mouse_co = [0, 0] + self._event_types_held = set() + + self.cursor_position_set(window.width // 2, window.height // 2) + + def cursor_position_set(self, x, y, move=False): + self._mouse_co[:] = x, y + if move: + self.window.event_simulate( + type='MOUSEMOVE', + value='NOTHING', + x=x, + y=y, + ) + + def text(self, text): + """ Type in entire phrases. """ + for ch in text: + ty, shift = event_types_text_from_char[ch] + ty = ty.lower() + if shift: + eb = getattr(_EventBuilder(self, 'left_shift'), ty) + else: + eb = _EventBuilder(self, ty) + eb.tap() + return self + + def text_unicode(self, text): + # Since the only purpose of this key-press is to enter text + # the key can be almost anything, use a key which isn't likely to be assigned ot any other action. + # + # If it were possible `EVT_UNKNOWNKEY` would be most correct + # as dead keys map to this and still enter text. + ty_dummy = 'F24' + for ch in text: + eb = _EventBuilder(self, ty_dummy) + eb._key_press_release(do_press=True, do_release=True, unicode_override=ch) + return self + + def __getattr__(self, attr): + attr = event_types_alias.get(attr, attr) + if attr in event_types: + return _EventBuilder(self, attr) + raise Exception(f"{attr!r} not found in {event_types!r}") + + def __del__(self): + if self._event_types_held: + print("'__del__' with keys held:", repr(self._event_types_held)) + + +def run( + event_iter, *, + on_error=None, + on_exit=None, + on_step_command_pre=None, + on_step_command_post=None, +): + import bpy + + TICKS = 4 # 3 works, 4 to be on the safe side. + + def event_step(): + # Run once 'TICKS' is reached. + if event_step._ticks < TICKS: + event_step._ticks += 1 + return 0.0 + event_step._ticks = 0 + + if on_step_command_pre: + if event_step.run_events.gi_frame is not None: + import shlex + import subprocess + subprocess.call( + shlex.split( + on_step_command_pre.replace( + "{file}", event_step.run_events.gi_frame.f_code.co_filename, + ).replace( + "{line}", str(event_step.run_events.gi_frame.f_lineno), + ) + ) + ) + try: + val = next(event_step.run_events, Ellipsis) + except Exception: + import traceback + traceback.print_exc() + if on_error is not None: + on_error() + if on_exit is not None: + on_exit() + return None + + if on_step_command_post: + if event_step.run_events.gi_frame is not None: + import shlex + import subprocess + subprocess.call( + shlex.split( + on_step_command_post.replace( + "{file}", event_step.run_events.gi_frame.f_code.co_filename, + ).replace( + "{line}", str(event_step.run_events.gi_frame.f_lineno), + ) + ) + ) + + if isinstance(val, EventGenerate) or val is None: + return 0.0 + elif val is Ellipsis: + if on_exit is not None: + on_exit() + return None + else: + raise Exception(f"{val!r} of type {type(val)!r} not supported") + + event_step.run_events = iter(event_iter) + event_step._ticks = 0 + + bpy.app.timers.register(event_step, first_interval=0.0) + + +def setup_default_preferences(preferences): + """ Set preferences useful for automation. + """ + preferences.view.show_splash = False + preferences.view.smooth_view = 0 + preferences.view.use_save_prompt = False + preferences.filepaths.use_auto_save_temporary_files = False diff --git a/tests/python/ui_simulate/run.py b/tests/python/ui_simulate/run.py new file mode 100755 index 00000000000..a25ccddc098 --- /dev/null +++ b/tests/python/ui_simulate/run.py @@ -0,0 +1,193 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-or-later + +""" +Run interaction tests using event simulation. + +Example usage from Blender's source dir: + + ./tests/python/ui_simulate/run.py --blender=./blender.bin --tests test_undo.text_editor_simple + +This uses ``test_undo.py``, running the ``text_editor_simple`` function. + +To run all tests: + + ./tests/python/ui_simulate/run.py --blender=blender.bin --tests '*' + +For an editor to follow the tests: + + ./lib/python/tests/ui_simulate/run.py --blender=blender.bin --tests '*' \ + --step-command-pre='gvim --remote-silent +{line} "{file}"' + +""" + +import os +import sys + + +def create_parser(): + import argparse + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawTextHelpFormatter, + ) + parser.add_argument( + "--blender", + dest="blender", + required=True, + metavar="BLENDER_COMMAND", + help="Location of the blender command to run (when quoted, may include arguments).", + ) + + parser.add_argument( + "--tests", + dest="tests", + nargs='+', + required=True, + metavar="TEST_ID", + help="Names of tests to run, use '*' to run all tests.", + ) + + parser.add_argument( + "--jobs", "-j", + dest="jobs", + default=1, + type=int, + help="Number of tests (and instances of Blender) to run in parallel.", + ) + + parser.add_argument( + "--keep-open", + dest="keep_open", + default=False, + action='store_true', + required=False, + help="Keep the Blender window open after running the test.", + ) + + parser.add_argument( + "--list-tests", + dest="list_tests", + default=False, + action='store_true', + required=False, + help="Show a list of available TEST_ID.", + ) + + parser.add_argument( + "--step-command-pre", + dest="step_command_pre", + required=False, + metavar="STEP_COMMAND_PRE", + help=( + "Command to run that takes the test file and line as arguments. " + "Literals {file} and {line} will be replaced with the file and line." + "Called for every event." + "Called for every event, allows an editor to track which commands run." + ) + ) + parser.add_argument( + "--step-command-post", + dest="step_command_post", + required=False, + metavar="STEP_COMMAND_POST", + help=( + "Command to run that takes the test file and line as arguments. " + "Literals {file} and {line} will be replaced with the file and line." + "Called for every event, allows an editor to track which commands run." + ) + ) + + return parser + + +def all_test_ids(directory): + from types import FunctionType + for f in sorted(os.listdir(directory)): + if f.startswith("test_") and f.endswith(".py"): + mod = __import__(f[:-3]) + for k, v in sorted(vars(mod).items()): + if not k.startswith("_") and isinstance(v, FunctionType): + yield f.rpartition(".")[0] + "." + k + + +def list_tests(directory): + for test_id in all_test_ids(directory): + print(test_id) + sys.exit(0) + + +def _process_test_id_fn(env, args, test_id): + import subprocess + import shlex + + directory = os.path.dirname(__file__) + cmd = ( + *shlex.split(args.blender), + "--enable-event-simulate", + "--factory-startup", + "--python", os.path.join(directory, "run_blender_setup.py"), + "--", + "--tests", test_id, + *(("--keep-open",) if args.keep_open else ()), + *(("--step-command-pre", args.step_command_pre) if args.step_command_pre else ()), + *(("--step-command-post", args.step_command_post) if args.step_command_post else ()), + ) + callproc = subprocess.run(cmd, env=env) + return test_id, callproc.returncode == 0 + + +def main(): + directory = os.path.dirname(__file__) + if "--list-tests" in sys.argv: + list_tests(directory) + sys.exit(0) + + if "bpy" in sys.modules: + raise Exception("Cannot run inside Blender") + + parser = create_parser() + args = parser.parse_args() + + tests = args.tests + + # Validate tests exist + test_ids = list(all_test_ids(directory)) + if tests[0] == "*": + tests = test_ids + else: + for test_id in tests: + if test_id not in test_ids: + print(test_id, "not found in", test_ids) + return + + env = os.environ.copy() + env.update({ + "LSAN_OPTIONS": "exitcode=0", + }) + + # We could support multiple tests per Blender session. + results = [] + results_fail = 0 + if args.jobs <= 1: + for test_id in tests: + _, success = _process_test_id_fn(env, args, test_id) + results.append((test_id, success)) + if not success: + results_fail += 1 + else: + from concurrent.futures import ProcessPoolExecutor + executor = ProcessPoolExecutor(max_workers=args.jobs) + num_tests = len(tests) + for test_id, success in executor.map(_process_test_id_fn, (env,) * num_tests, (args,) * num_tests, tests): + results.append((test_id, success)) + if not success: + results_fail += 1 + + print(len(results), "tests,", results_fail, "failed") + for test_id, ok in results: + print("OK: " if ok else "FAIL:", test_id) + + +if __name__ == "__main__": + main() diff --git a/tests/python/ui_simulate/run_blender_setup.py b/tests/python/ui_simulate/run_blender_setup.py new file mode 100644 index 00000000000..cd206a3e1ad --- /dev/null +++ b/tests/python/ui_simulate/run_blender_setup.py @@ -0,0 +1,113 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +""" +Utility script, called by ``run.py`` to run inside Blender, +to avoid boiler plate code having to be added into each test. +""" + +import os +import sys + + +def create_parser(): + import argparse + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawTextHelpFormatter, + ) + + parser.add_argument( + "--keep-open", + dest="keep_open", + default=False, + action='store_true', + required=False, + help="Keep the Blender window open after running the test.", + ) + + parser.add_argument( + "--step-command-pre", + dest="step_command_pre", + default=None, + required=False, + help="See 'run.py'", + ) + parser.add_argument( + "--step-command-post", + dest="step_command_post", + default=None, + required=False, + help="See 'run.py'", + ) + + parser.add_argument( + "--tests", + dest="tests", + nargs='+', + required=True, + metavar="TEST_ID", + help="Names of tests to run.", + ) + + return parser + + +def main(): + directory = os.path.dirname(__file__) + sys.path.insert(0, directory) + if "bpy" not in sys.modules: + raise Exception("This must run inside Blender") + import bpy + + parser = create_parser() + args = parser.parse_args(sys.argv[sys.argv.index("--") + 1:]) + + # Check if `bpy.app.use_event_simulate` has been enabled by the test it's self. + # When writing tests, it's useful if the test can temporarily be set to keep the window open. + + def on_error(): + if not bpy.app.use_event_simulate: + args.keep_open = True + + if not args.keep_open: + sys.exit(1) + + def on_exit(): + if not bpy.app.use_event_simulate: + args.keep_open = True + + if not args.keep_open: + sys.exit(0) + else: + bpy.app.use_event_simulate = False + + is_first = True + for test_id in args.tests: + if not is_first: + bpy.ops.wm.read_homefile() + is_first = False + + mod_name, fn_name = test_id.partition(".")[0::2] + mod = __import__(mod_name) + test_fn = getattr(mod, fn_name) + + from modules import easy_keys + + # So we can get the operator ID's. + bpy.context.preferences.view.show_developer_ui = True + + # Hack back in operator search. + + easy_keys.setup_default_preferences(bpy.context.preferences) + easy_keys.run( + test_fn(), + on_error=on_error, + on_exit=on_exit, + # Optional. + on_step_command_pre=args.step_command_pre, + on_step_command_post=args.step_command_post, + ) + + +if __name__ == "__main__": + main() diff --git a/tests/python/ui_simulate/test_undo.py b/tests/python/ui_simulate/test_undo.py new file mode 100644 index 00000000000..1203bd74316 --- /dev/null +++ b/tests/python/ui_simulate/test_undo.py @@ -0,0 +1,894 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# Only access for it's methods. + + +# FIXME: Since 2.8 or so, there is a problem with simulated events +# where a popup needs the main-loop to cycle once before new events +# are handled. This isn't great but seems not to be a problem for users? +_MENU_CONFIRM_HACK = True + + +# ----------------------------------------------------------------------------- +# Utilities + +def _keep_open(): + """ + Only for development, handy so we can quickly keep the window open while testing. + """ + import bpy + bpy.app.use_event_simulate = False + + +def _test_window(windows_exclude=None): + import bpy + wm = bpy.data.window_managers[0] + # Use -1 so the last added window is always used. + if windows_exclude is None: + return wm.windows[0] + for window in wm.windows: + if window not in windows_exclude: + return window + return None + + +def _test_vars(window): + import unittest + from modules.easy_keys import EventGenerate + return ( + EventGenerate(window), + unittest.TestCase(), + ) + + +def _call_by_name(e, text: str): + yield e.f3() + yield e.text(text) + yield e.ret() + + +def _call_menu(e, text: str): + yield e.f3() + yield e.text_unicode(text.replace(" -> ", " \u25b8 ")) + yield e.ret() + + +def _cursor_motion_data_x(window): + size = window.width, window.height + return [ + (x, size[1] // 2) for x in + range(int(size[0] * 0.2), int(size[0] * 0.8), 80) + ] + + +def _cursor_motion_data_y(window): + size = window.width, window.height + return [ + (size[0] // 2, y) for y in + range(int(size[1] * 0.2), int(size[1] * 0.8), 80) + ] + + +def _window_area_get_by_type(window, space_type): + for area in window.screen.areas: + if area.type == space_type: + return area + + +def _cursor_position_from_area(area): + return ( + area.x + area.width // 2, + area.y + area.height // 2, + ) + + +def _cursor_position_from_spacetype(window, space_type): + area = _window_area_get_by_type(window, space_type) + if area is None: + raise Exception("Space Type %r not found" % space_type) + return _cursor_position_from_area(area) + + +def _view3d_object_calc_screen_space_location(window, name: str): + from bpy_extras.view3d_utils import location_3d_to_region_2d + + area = _window_area_get_by_type(window, 'VIEW_3D') + region = next((region for region in area.regions if region.type == 'WINDOW')) + rv3d = region.data + + ob = window.view_layer.objects[name] + co = location_3d_to_region_2d(region, rv3d, ob.matrix_world.translation) + return int(co[0]), int(co[1]) + + +def _view3d_object_select_by_name(e, name: str): + location = _view3d_object_calc_screen_space_location(e.window, name) + e.cursor_position_set(*location, move=True) + # e.shift.rightmouse.tap() # Set the cursor so it's possible to see what was selected. + yield + e.ctrl.leftmouse.tap() + yield + + +def _setup_window_areas_from_ui_types(e, ui_types): + assert len(e.window.screen.areas) == 1 + total_areas = len(ui_types) + i = 0 + while len(e.window.screen.areas) < total_areas: + areas = list(e.window.screen.areas) + for area in areas: + event_xy = _cursor_position_from_area(area) + e.cursor_position_set(x=event_xy[0], y=event_xy[1], move=True) + # areas_len_prev = len(e.window.screen.areas) + if (i % 2) == 0: + yield from _call_menu(e, "View -> Area -> Horizontal Split") + else: + yield from _call_menu(e, "View -> Area -> Vertical Split") + e.leftmouse.tap() + yield + # areas_len_curr = len(e.window.screen.areas) + # assert areas_len_curr != areas_len_prev + if len(e.window.screen.areas) >= total_areas: + break + i += 1 + + # Use direct assignment, it's possible to use shortcuts for most area types, it's tedious. + for ty, area in zip(ui_types, e.window.screen.areas, strict=True): + area.ui_type = ty + yield + + +def _print_undo_steps_and_line(): + """ + Keep even when unused, handy for tracking down problems. + """ + from inspect import currentframe + cf = currentframe() + line = cf.f_back.f_lineno + + import bpy + wm = bpy.data.window_managers[0] + print(__file__ + ":" + str(line)) + wm.print_undo_steps() + + +def _bmesh_from_object(ob): + import bmesh + return bmesh.from_edit_mesh(ob.data) + + +# ----------------------------------------------------------------------------- +# Text Editor + +def _text_editor_startup(e): + yield e.shift.f11() # Text editor. + yield e.ctrl.alt.space() # Full-screen. + yield e.alt.n() # New text. + + +def _text_editor_and_3dview_startup(e, window): + # Add text block in properties editors. + pos_text = _cursor_position_from_spacetype(window, 'PROPERTIES') + e.cursor_position_set(*pos_text, move=True) + yield e.shift.f11() # Text editor. + yield e.alt.n() # New text. + + +def text_editor_simple(): + e, t = _test_vars(_test_window()) + + import bpy + yield from _text_editor_startup(e) + text = bpy.data.texts[0] + + yield e.text("Hello\nWorld") + t.assertEqual(text.as_string(), "Hello\nWorld") + yield e.shift.home().ctrl.x().back_space() + yield e.home().ctrl.v().ret() + t.assertEqual(text.as_string(), "World\nHello") + yield e.ctrl.a().tab() + t.assertEqual(text.as_string(), " World\n Hello") + yield e.ctrl.z(5) + t.assertEqual(text.as_string(), "Hello\nWorld") + + +def text_editor_edit_mode_mix(): + # Ensure text edits and mesh edits can co-exist properly (see: T66658). + e, t = _test_vars(window := _test_window()) + + import bpy + yield from _text_editor_and_3dview_startup(e, window) + text = bpy.data.texts[0] + + pos_text = _cursor_position_from_spacetype(window, 'TEXT_EDITOR') + pos_v3d = _cursor_position_from_spacetype(window, 'VIEW_3D') + + # View 3D: edit-mode + e.cursor_position_set(*pos_v3d, move=True) + yield from _call_menu(e, "Add -> Mesh -> Cube") + + yield e.numpad_period() # View all. + yield e.tab() # Edit mode. + yield e.a() # Select all. + + # Text: add text 'AA'. + e.cursor_position_set(*pos_text, move=True) + yield e.text("AA") + t.assertEqual(text.as_string(), "AA") + + # View 3D: duplicate & move. + e.cursor_position_set(*pos_v3d, move=True) + yield e.shift.d().x().text("3").ret() + yield e.g().z().text("1").ret() + t.assertEqual(len(_bmesh_from_object(window.view_layer.objects.active).verts), 8 * 2) + e.home() + + # Text: add text 'BB' + e.cursor_position_set(*pos_text, move=True) + yield e.text("BB") + t.assertEqual(text.as_string(), "AABB") + + # View 3D: duplicate & move. + e.cursor_position_set(*pos_v3d, move=True) + yield e.shift.d().x().text("3").ret() + yield e.g().z().text("1").ret() + e.home() + t.assertEqual(len(_bmesh_from_object(window.view_layer.objects.active).verts), 8 * 3) + + # Text: add text 'CC' + e.cursor_position_set(*pos_text, move=True) + yield e.text("CC") + t.assertEqual(text.as_string(), "AABBCC") + + # View 3D: duplicate & move. + e.cursor_position_set(*pos_v3d, move=True) + yield e.shift.d().x().text("3").ret() + yield e.g().z().text("1").ret() + e.home() + t.assertEqual(len(_bmesh_from_object(window.view_layer.objects.active).verts), 8 * 4) + + # Undo and check the state is valid. + yield e.ctrl.z(4) + t.assertEqual(len(_bmesh_from_object(window.view_layer.objects.active).verts), 8 * 3) + t.assertEqual(text.as_string(), "AABB") + + yield e.ctrl.z(4) + t.assertEqual(len(_bmesh_from_object(window.view_layer.objects.active).verts), 8 * 2) + t.assertEqual(text.as_string(), "AA") + + yield e.ctrl.z(4) + t.assertEqual(len(_bmesh_from_object(window.view_layer.objects.active).verts), 8) + t.assertEqual(text.as_string(), "") + + # Finally redo all. + yield e.ctrl.shift.z(4 * 3) + t.assertEqual(len(_bmesh_from_object(window.view_layer.objects.active).verts), 8 * 4) + t.assertEqual(text.as_string(), "AABBCC") + + +# ----------------------------------------------------------------------------- +# 3D View + +def _view3d_startup_area_maximized(e): + yield e.shift.f5() # 3D Viewport. + yield e.ctrl.alt.space() # Full-screen. + yield e.a() # Select all. + yield e.delete().ret() # Delete all. + + +def _view3d_startup_area_single(e): + yield e.shift.f5() # 3D Viewport. + yield e.a() # Select all. + yield e.delete().ret() # Delete all. + + for _ in range(len(e.window.screen.areas)): + # 3D Viewport. + event_xy = _cursor_position_from_spacetype(e.window, e.window.screen.areas[0].type) + e.cursor_position_set(x=event_xy[0], y=event_xy[1], move=True) + yield e.shift.f5() + yield from _call_menu(e, "View -> Area -> Close Area") + assert len(e.window.screen.areas) == 1 + + +def view3d_simple(): + e, t = _test_vars(window := _test_window()) + yield from _view3d_startup_area_maximized(e) + + yield from _call_menu(e, "Add -> Mesh -> Plane") + # Duplicate and rotate. + for _ in range(3): + yield e.shift.d().x().text("3").ret() + yield e.r.z().text("15").ret() + t.assertEqual(len(window.view_layer.objects), 4) + yield e.a() # Select all. + yield e.numpad_7().numpad_period() # View top. + yield e.ctrl.j() # Join. + t.assertEqual(len(window.view_layer.objects), 1) + yield e.tab() # Edit mode. + yield from _call_menu(e, "Edge -> Subdivide") + yield e.tab() # Object mode. + t.assertEqual(len(window.view_layer.objects.active.data.polygons), 16) + yield e.ctrl.z(12) # Undo until start. + t.assertEqual(len(window.view_layer.objects), 0) + yield e.ctrl.shift.z(12) # Redo until end. + t.assertEqual(len(window.view_layer.objects.active.data.polygons), 16) + + +def view3d_sculpt_with_memfile_step(): + e, t = _test_vars(window := _test_window()) + yield from _view3d_startup_area_maximized(e) + + yield from _call_menu(e, "Add -> Mesh -> Torus") + + # Note: this could also be replaced by adding the multires modifier (see comment below). + yield e.tab() # Enter Edit mode. + yield e.ctrl.e().d() # Subdivide. + yield e.ctrl.e().d() # Subdivide. + yield e.tab() # Leave Edit mode. + + yield e.numpad_period() # View all. + yield e.ctrl.tab().s() # Sculpt via pie menu. + + # Add a 'memfile' undo step without leaving Sculpt mode. + yield e.f3().text("add const").ret().d() # Add 'Limit Distance' constraint. + # Note: Multires modifier exhibits even more issues with undo/redo in sculpt mode, but unfortunately geometry is not + # available from python anymore while in sculpt mode, so we cannot test/check if undo/redo steps apply properly. + # yield e.ctrl.two() # Add multires modifier. + + # Utility to extract current mesh coordinates (used to ensure undo/redo steps are applied properly). + def extract_mesh_cos(window): + # TODO: Find/add a way to get that info when there is a multires active in Sculpt mode. + window.view_layer.update() + tmp_mesh = window.view_layer.objects.active.to_mesh(preserve_all_data_layers=True) + tmp_cos = [0.0] * len(tmp_mesh.vertices) * 3 + tmp_mesh.vertices.foreach_get("co", tmp_cos) + window.view_layer.objects.active.to_mesh_clear() + return tmp_cos + + mesh_verts_cos_before_sculpt = extract_mesh_cos(window) + + # Add a first sculpt stroke. + yield from e.leftmouse.cursor_motion(_cursor_motion_data_x(window)) + mesh_verts_cos_sculpt_stroke1 = extract_mesh_cos(window) + t.assertNotEqual(mesh_verts_cos_before_sculpt, mesh_verts_cos_sculpt_stroke1) + + # Add a second sculpt stroke. + yield from e.leftmouse.cursor_motion(_cursor_motion_data_y(window)) + mesh_verts_cos_sculpt_stroke2 = extract_mesh_cos(window) + t.assertNotEqual(mesh_verts_cos_sculpt_stroke1, mesh_verts_cos_sculpt_stroke2) + + # Undo to first sculpt stroke. + yield e.ctrl.z() + mesh_verts_cos = extract_mesh_cos(window) + t.assertEqual(mesh_verts_cos, mesh_verts_cos_sculpt_stroke1) + + # Undo to memfile step (add constraint), fine here (T82532), + # but would fail if we had added a Multires modifier instead (T82851). + yield e.ctrl.z() + mesh_verts_cos = extract_mesh_cos(window) + t.assertEqual(mesh_verts_cos, mesh_verts_cos_before_sculpt) + + # Redo first sculpt stroke, would now be undone (in Multires case, T82851), + # or not redone (in constraint case, T82532). + yield e.ctrl.shift.z() + mesh_verts_cos = extract_mesh_cos(window) + t.assertEqual(mesh_verts_cos, mesh_verts_cos_sculpt_stroke1) + + # Redo second sculpt stroke, would redo properly, + # as well as part of the first one that affects the same nodes (T82851, T82532). + yield e.ctrl.shift.z() + mesh_verts_cos = extract_mesh_cos(window) + t.assertEqual(mesh_verts_cos, mesh_verts_cos_sculpt_stroke2) + + +def view3d_sculpt_dyntopo_simple(): + e, t = _test_vars(window := _test_window()) + yield from _view3d_startup_area_maximized(e) + + yield from _call_menu(e, "Add -> Mesh -> Torus") + # Avoid dynamic topology prompt. + yield from _call_by_name(e, "Remove UV Map") + if _MENU_CONFIRM_HACK: + yield + yield e.r().y().text("45").ret() # Rotate Y 45. + yield e.ctrl.a().r() # Apply rotation. + yield e.numpad_period() # View all. + yield e.ctrl.tab().s() # Sculpt via pie menu. + yield from _call_menu(e, "Sculpt -> Dynamic Topology Toggle") + # TODO: should be accessible from menu. + yield from _call_by_name(e, "Symmetrize") + yield e.ctrl.tab().o() # Object mode. + t.assertEqual(len(window.view_layer.objects.active.data.polygons), 1258) + yield e.delete() # Delete the object. + yield e.ctrl.z() # Undo... + yield e.ctrl.z() # Undo used to crash here: T60974 + t.assertEqual(len(window.view_layer.objects.active.data.polygons), 1258) + t.assertEqual(window.view_layer.objects.active.mode, 'SCULPT') + + +def view3d_sculpt_dyntopo_and_edit(): + e, t = _test_vars(window := _test_window()) + yield from _view3d_startup_area_maximized(e) + + yield from _call_menu(e, "Add -> Mesh -> Torus") + yield e.numpad_period() # View all. + yield from _call_by_name(e, "Remove UV Map") + yield e.ctrl.tab().s() # Sculpt via pie menu. + yield e.ctrl.d().ret() # Dynamic topology. + # TODO: should be accessible from menu. + yield from _call_by_name(e, "Symmetrize") + # Some painting (demo it works, not needed for the crash) + yield from e.leftmouse.cursor_motion(_cursor_motion_data_x(window)) + yield e.tab() # Edit mode. + yield e.tab() # Object mode. + yield e.ctrl.z(3) # Undo + # yield e.ctrl.z() # Undo asserts (nested undo call from dyntopo) + + +def view3d_texture_paint_simple(): + e, t = _test_vars(window := _test_window()) + yield from _view3d_startup_area_maximized(e) + + yield from _call_menu(e, "Add -> Mesh -> Monkey") + yield e.numpad_period() # View monkey + yield e.ctrl.tab().t() # Paint via pie menu. + yield from _call_by_name(e, "Add Texture Paint Slot") + yield e.ret() # Accept popup. + + yield from e.leftmouse.cursor_motion(_cursor_motion_data_x(window)) + yield e.ctrl.z(2) # Undo: initial texture paint. + t.assertEqual(window.view_layer.objects.active.mode, 'TEXTURE_PAINT') + yield e.ctrl.z() # Undo: object mode. + t.assertEqual(window.view_layer.objects.active.mode, 'OBJECT') + yield e.ctrl.shift.z(2) # Redo: initial blank canvas. + t.assertEqual(window.view_layer.objects.active.mode, 'TEXTURE_PAINT') + yield from e.leftmouse.cursor_motion(_cursor_motion_data_x(window)) + yield e.ctrl.z() # Used to crash T61172. + # test_undo.view3d_sculpt_dyntopo_simple + # test_undo.view3d_texture_paint_simple + + +def view3d_texture_paint_complex(): + # More complex test than `view3d_texture_paint_simple`, + # including interleaved memfile steps, + # and a call to history to undo several steps at once. + e, t = _test_vars(window := _test_window()) + yield from _view3d_startup_area_maximized(e) + + yield from _call_menu(e, "Add -> Mesh -> Monkey") + yield e.numpad_period() # View monkey + yield e.ctrl.tab().t() # Paint via pie menu. + + yield from _call_by_name(e, "Add Texture Paint Slot") + yield e.ret() # Accept popup. + + yield from e.leftmouse.cursor_motion(_cursor_motion_data_x(window)) + yield from e.leftmouse.cursor_motion(_cursor_motion_data_y(window)) + + yield from _call_by_name(e, "Add Texture Paint Slot") + yield e.ret() # Accept popup. + + yield from e.leftmouse.cursor_motion(_cursor_motion_data_x(window)) + yield from e.leftmouse.cursor_motion(_cursor_motion_data_y(window)) + + yield e.ctrl.z(6) # Undo: initial texture paint. + t.assertEqual(window.view_layer.objects.active.mode, 'TEXTURE_PAINT') + yield e.ctrl.z() # Undo: object mode. + t.assertEqual(window.view_layer.objects.active.mode, 'OBJECT') + + yield e.ctrl.shift.z(2) # Redo: initial blank canvas. + t.assertEqual(window.view_layer.objects.active.mode, 'TEXTURE_PAINT') + + yield from e.leftmouse.cursor_motion(_cursor_motion_data_x(window)) + yield from e.leftmouse.cursor_motion(_cursor_motion_data_y(window)) + + yield from _call_by_name(e, "Undo History") + yield e.o() # Undo everything to Original step. + t.assertEqual(window.view_layer.objects.active.mode, 'OBJECT') + + +def view3d_mesh_edit_separate(): + e, t = _test_vars(window := _test_window()) + yield from _view3d_startup_area_maximized(e) + + yield from _call_menu(e, "Add -> Mesh -> Cube") + yield e.numpad_period() # View all. + yield e.tab() # Edit mode. + yield e.shift.d() # Duplicate... + yield e.x().text("3").ret() # Move X-3. + yield e.p().s() # Separate selection. + t.assertEqual(len(window.view_layer.objects), 2) + yield e.ctrl.z() # Undo. + t.assertEqual(len(window.view_layer.objects), 1) + yield e.tab() # Object mode. + t.assertEqual(len(window.view_layer.objects.active.data.polygons), 12) + yield e.tab() # Edit mode. + yield e.ctrl.i() # Invert selection. + yield e.p().s() # Separate selection. + yield e.tab() # Object mode. + t.assertEqual([len(ob.data.polygons) for ob in window.view_layer.objects], [6, 6]) + yield e.ctrl.z(8) # Undo until start. + t.assertEqual(len(window.view_layer.objects), 0) + yield e.ctrl.shift.z(8) # Redo until end. + t.assertEqual([len(ob.data.polygons) for ob in window.view_layer.objects], [6, 6]) + + +def view3d_mesh_particle_edit_mode_simple(): + e, t = _test_vars(window := _test_window()) + yield from _view3d_startup_area_maximized(e) + + yield from _call_menu(e, "Add -> Mesh -> Cube") + yield e.r.z().text("15").ret() # Single object-mode action (to test mixing different kinds of undo steps). + yield from _call_menu(e, "Object -> Quick Effects -> Quick Fur") + + yield e.ctrl.tab().s() # Particle sculpt mode. + t.assertEqual(window.view_layer.objects.active.mode, 'SCULPT_CURVES') + + # Brush strokes. + yield from e.leftmouse.cursor_motion(_cursor_motion_data_y(window)) + yield from e.leftmouse.cursor_motion(_cursor_motion_data_x(window)) + + # Undo and redo. + yield e.ctrl.z(5) + t.assertEqual(window.view_layer.objects.active.mode, 'OBJECT') + yield e.shift.ctrl.z(5) + + t.assertEqual(window.view_layer.objects.active.mode, 'SCULPT_CURVES') + + # Brush strokes. + yield from e.leftmouse.cursor_motion(_cursor_motion_data_y(window)) + yield from e.leftmouse.cursor_motion(_cursor_motion_data_x(window)) + + yield e.ctrl.z(7) + t.assertEqual(window.view_layer.objects.active.mode, 'OBJECT') + yield e.shift.ctrl.z(7) + + +def view3d_font_edit_mode_simple(): + e, t = _test_vars(window := _test_window()) + yield from _view3d_startup_area_maximized(e) + + yield from _call_menu(e, "Add -> Text") + yield e.numpad_period() # View all. + yield e.tab() # Edit mode. + yield e.ctrl.back_space() + yield e.text("Hello\nWorld") + yield e.tab() # Object mode. + t.assertEqual(window.view_layer.objects.active.data.body, 'Hello\nWorld') + yield e.r.x().text("90").ret() # Rotate 90, face the view. + yield e.tab() # Edit mode. + yield e.end() # Edit mode. + yield e.ctrl.back_space() + yield e.back_space() + yield e.tab() # Object mode. + t.assertEqual(window.view_layer.objects.active.data.body, 'Hello') + + yield e.ctrl.z(3) + t.assertEqual(window.view_layer.objects.active.data.body, 'Hello\nWorld') + yield e.shift.ctrl.z(3) + t.assertEqual(window.view_layer.objects.active.data.body, 'Hello') + + +def view3d_multi_mode_select(): + # Note, this test should be extended to change modes for each object type. + e, t = _test_vars(window := _test_window()) + yield from _view3d_startup_area_maximized(e) + + object_names = [] + + for i, (menu_search, ob_name) in enumerate(( + ("Add -> Armature", "Armature"), + ("Add -> Text", "Text"), + ("Add -> Mesh -> Cube", "Cube"), + ("Add -> Curve -> Bezier", "Curve"), + ("Add -> Volume -> Empty", "Volume Empty"), + ("Add -> Metaball -> Ball", "Metaball"), + ("Add -> Lattice", "Lattice"), + ("Add -> Light -> Point", "Point Light"), + ("Add -> Camera", "Camera"), + ("Add -> Empty -> Plain Axis", "Empty"), + )): + yield from _call_menu(e, menu_search) + # Single object-mode action (to test mixing different kinds of undo steps). + yield e.g.z().text(str(i * 2)).ret() + # Rename. + yield e.f2().text(ob_name).ret() + + object_names.append(window.view_layer.objects.active.name) + + yield from _call_menu(e, "View -> Frame All") + print(object_names) + + for ob_name in object_names: + yield from _view3d_object_select_by_name(e, ob_name) + yield + print() + print('=' * 40) + print(window.view_layer.objects.active.name, ob_name) + + for ob_name in reversed(object_names): + t.assertEqual(ob_name, window.view_layer.objects.active.name) + yield e.ctrl.z() + + +def view3d_multi_mode_multi_window(): + e_a, t = _test_vars(window_a := _test_window()) + yield from _call_menu(e_a, "Window -> New Main Window") + + e_b, _ = _test_vars(window_b := _test_window(windows_exclude={window_a})) + del _ + yield from _call_menu(e_b, "New Scene") + yield e_b.ret() + if _MENU_CONFIRM_HACK: + yield + + for e in (e_a, e_b): + pos_v3d = _cursor_position_from_spacetype(e.window, 'VIEW_3D') + e.cursor_position_set(x=pos_v3d[0], y=pos_v3d[1], move=True) + del pos_v3d + + yield from _view3d_startup_area_maximized(e_a) + yield from _view3d_startup_area_maximized(e_b) + + undo_current = 0 + undo_state_empty = undo_current + + yield from _call_menu(e_a, "Add -> Torus") + yield from _call_menu(e_b, "Add -> Monkey") + undo_current += 2 + + # Weight paint via pie menu. + yield e_a.ctrl.tab().w() + yield e_b.ctrl.tab().w() + undo_current += 2 + undo_state_wpaint = undo_current + + t.assertEqual(window_a.view_layer.objects.active.mode, 'WEIGHT_PAINT') + t.assertEqual(window_b.view_layer.objects.active.mode, 'WEIGHT_PAINT') + + # Object mode via pie menu. + yield e_a.ctrl.tab().o() + yield e_b.ctrl.tab().o() + undo_current += 2 + + undo_state_non_empty_start = undo_current + + # Edit mode. + yield e_a.tab() + yield e_b.tab() + undo_current += 2 + + vert_count_a_start = len(_bmesh_from_object(window_a.view_layer.objects.active).verts) + vert_count_b_start = len(_bmesh_from_object(window_b.view_layer.objects.active).verts) + + yield from _call_menu(e_a, "Edge -> Subdivide") + yield from _call_menu(e_b, "Edge -> Subdivide") + undo_current += 2 + + yield e_a.r().y().text("45").ret() # Rotate Y 45. + yield e_b.r().z().text("45").ret() # Rotate Z 45. + undo_current += 2 + + # Object mode. + yield e_a.tab() + yield e_b.tab() + undo_current += 2 + + # Object mode via pie menu. + yield e_a.ctrl.tab().s() + yield e_b.ctrl.tab().s() + undo_current += 2 + + t.assertEqual(window_a.view_layer.objects.active.mode, 'SCULPT') + t.assertEqual(window_b.view_layer.objects.active.mode, 'SCULPT') + + # Rotate 90. + yield from _call_menu(e_a, "Sculpt -> Rotate") + yield e_a.text("90").ret() + yield from _call_menu(e_b, "Sculpt -> Rotate") + yield e_b.text("90").ret() + undo_current += 2 + + # Object mode. + yield e_a.ctrl.tab().o() + yield e_b.ctrl.tab().o() + undo_current += 2 + + # Edit mode. + yield e_a.tab() + yield e_b.tab() + undo_current += 2 + + yield from _call_menu(e_a, "Edge -> Subdivide") + yield from _call_menu(e_b, "Edge -> Subdivide") + undo_current += 2 + + vert_count_a_end = len(_bmesh_from_object(window_a.view_layer.objects.active).verts) + vert_count_b_end = len(_bmesh_from_object(window_b.view_layer.objects.active).verts) + + t.assertEqual(vert_count_a_end, 9216) + t.assertEqual(vert_count_b_end, 7830) + + yield e_a.r().y().text("45").ret() # Rotate Y 45. + yield e_b.r().z().text("45").ret() # Rotate Z 45. + undo_current += 2 + + yield e_a.tab() + yield e_b.tab() + undo_current += 2 + + undo_state_final = undo_current + + undo_delta = undo_state_final - undo_state_empty + + yield e_a.ctrl.z(undo_delta) + undo_current -= undo_delta + + # Ensure scene is empty. + t.assertEqual(len(window_a.view_layer.objects), 0) + t.assertEqual(len(window_b.view_layer.objects), 0) + + undo_delta = undo_state_final - undo_state_empty + yield e_a.ctrl.shift.z(undo_delta) + undo_current += undo_delta + + t.assertEqual(window_a.view_layer.objects.active.mode, 'OBJECT') + t.assertEqual(window_b.view_layer.objects.active.mode, 'OBJECT') + + t.assertEqual(len(window_a.view_layer.objects.active.data.vertices), vert_count_a_end) + t.assertEqual(len(window_b.view_layer.objects.active.data.vertices), vert_count_b_end) + + undo_delta = undo_state_final - undo_state_wpaint + yield e_a.ctrl.z(undo_delta) + undo_current -= undo_delta + + t.assertEqual(window_a.view_layer.objects.active.mode, 'WEIGHT_PAINT') + t.assertEqual(window_b.view_layer.objects.active.mode, 'WEIGHT_PAINT') + + undo_delta = undo_state_non_empty_start - undo_state_wpaint + yield e_a.ctrl.shift.z(undo_delta) + undo_current += undo_delta + + t.assertEqual(len(window_a.view_layer.objects.active.data.vertices), vert_count_a_start) + t.assertEqual(len(window_b.view_layer.objects.active.data.vertices), vert_count_b_start) + + # Further checks could be added but this seems enough. + + +def view3d_edit_mode_multi_window(): + """ + Use undo and redo with multiple windows in edit-mode, + this test caused a crash with #110022. + """ + e_a, t = _test_vars(window_a := _test_window()) + + # Nice but slower. + use_all_area_ui_types = False + + # Use a large, single area so the window can be duplicated & split. + yield from _view3d_startup_area_single(e_a) + + yield from _call_menu(e_a, "Window -> New Main Window") + + e_b, _ = _test_vars(window_b := _test_window(windows_exclude={window_a})) + del _ + + yield from _call_menu(e_b, "New Scene") + yield e_b.ret() + if _MENU_CONFIRM_HACK: + yield + + for e in (e_a, e_b): + pos_v3d = _cursor_position_from_spacetype(e.window, 'VIEW_3D') + e.cursor_position_set(x=pos_v3d[0], y=pos_v3d[1], move=True) + del pos_v3d + + undo_current = 0 + + yield from _call_menu(e_a, "Add -> Cone") + yield from _call_menu(e_b, "Add -> Cylinder") + undo_current += 2 + + # Edit mode. + yield e_a.tab() + yield e_b.tab() + undo_current += 2 + + undo_state_edit_mode = undo_current + + vert_count_a_start = len(_bmesh_from_object(window_a.view_layer.objects.active).verts) + vert_count_b_start = len(_bmesh_from_object(window_b.view_layer.objects.active).verts) + + yield e_a.r().y().text("45").ret() # Rotate Y 45. + yield e_b.r().z().text("45").ret() # Rotate Z 45. + undo_current += 2 + + yield from _call_menu(e_a, "Face -> Poke Faces") + yield from _call_menu(e_b, "Face -> Poke Faces") + undo_current += 2 + + yield from _call_menu(e_a, "Face -> Beautify Faces") + yield from _call_menu(e_b, "Face -> Beautify Faces") + undo_current += 2 + + yield from _call_menu(e_a, "Face -> Wireframe") + yield from _call_menu(e_b, "Face -> Wireframe") + undo_current += 2 + + vert_count_a_end = len(_bmesh_from_object(window_a.view_layer.objects.active).verts) + vert_count_b_end = len(_bmesh_from_object(window_b.view_layer.objects.active).verts) + + # Object mode. + yield e_a.tab() + yield e_b.tab() + undo_current += 2 + + # Finished with edits, assert undo is working as expected. + + yield e_a.ctrl.z(undo_current - undo_state_edit_mode) + + t.assertEqual(len(_bmesh_from_object(window_a.view_layer.objects.active).verts), vert_count_a_start) + t.assertEqual(len(_bmesh_from_object(window_b.view_layer.objects.active).verts), vert_count_b_start) + t.assertEqual(window_a.view_layer.objects.active.mode, 'EDIT') + t.assertEqual(window_b.view_layer.objects.active.mode, 'EDIT') + + yield e_a.ctrl.shift.z(undo_current - undo_state_edit_mode) + + t.assertEqual(len(window_a.view_layer.objects.active.data.vertices), vert_count_a_end) + t.assertEqual(len(window_b.view_layer.objects.active.data.vertices), vert_count_b_end) + t.assertEqual(window_a.view_layer.objects.active.mode, 'OBJECT') + t.assertEqual(window_b.view_layer.objects.active.mode, 'OBJECT') + + # Delete objects. + yield e_a.delete() + yield e_b.delete() + undo_current += 2 + + yield e_b.ctrl.z(undo_current) + + # Ensure scene is empty. + t.assertEqual(len(window_a.view_layer.objects), 0) + t.assertEqual(len(window_b.view_layer.objects), 0) + + yield e_b.ctrl.shift.z(undo_current - 2) + undo_current -= 2 + + t.assertEqual(len(window_a.view_layer.objects.active.data.vertices), vert_count_a_end) + t.assertEqual(len(window_b.view_layer.objects.active.data.vertices), vert_count_b_end) + t.assertEqual(window_a.view_layer.objects.active.mode, 'OBJECT') + t.assertEqual(window_b.view_layer.objects.active.mode, 'OBJECT') + + # Second phase! + # Split windows & show space types (could be a utility function). + # Test undo / redo doesn't cause issues when showing different space types. + if use_all_area_ui_types: + # TODO: extracting the enum from an exception is not good. + # As it's a dynamic enum it can't be accessed from `bl_rna.properties`. + try: + e_a.window.screen.areas[0].ui_type = '__INVALID__' + except TypeError as ex: + ui_types = ex.args[0] + ui_types = eval(ui_types[ui_types.rfind("("):]) + else: + ui_types = ('VIEW_3D', 'PROPERTIES') + + for e in (e_a, e_b): + yield from _setup_window_areas_from_ui_types(e, ui_types) + + # Ensure each undo step redraws. + for _ in range(undo_current - undo_state_edit_mode): + yield e_b.ctrl.z() + + t.assertEqual(len(_bmesh_from_object(window_a.view_layer.objects.active).verts), vert_count_a_start) + t.assertEqual(len(_bmesh_from_object(window_b.view_layer.objects.active).verts), vert_count_b_start) + t.assertEqual(window_a.view_layer.objects.active.mode, 'EDIT') + t.assertEqual(window_b.view_layer.objects.active.mode, 'EDIT') + + # Ensure each undo step redraws. + for _ in range(undo_current - undo_state_edit_mode): + yield e_b.ctrl.shift.z() + + t.assertEqual(len(window_a.view_layer.objects.active.data.vertices), vert_count_a_end) + t.assertEqual(len(window_b.view_layer.objects.active.data.vertices), vert_count_b_end) + t.assertEqual(window_a.view_layer.objects.active.mode, 'OBJECT') + t.assertEqual(window_b.view_layer.objects.active.mode, 'OBJECT') From 570799374f1197d1ef720ce70515e30454a8fe8f Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Tue, 7 Nov 2023 04:43:10 +0100 Subject: [PATCH 24/62] Fix #114542: VSE overlap not handled correctly Caused bu mistake in refactoring - tested `seq` instead of `seq_other`. --- source/blender/sequencer/intern/strip_transform.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/sequencer/intern/strip_transform.cc b/source/blender/sequencer/intern/strip_transform.cc index 3ece25f9844..68eb89b600a 100644 --- a/source/blender/sequencer/intern/strip_transform.cc +++ b/source/blender/sequencer/intern/strip_transform.cc @@ -220,7 +220,7 @@ static int shuffle_seq_time_offset_get(const Scene *scene, if (SEQ_relation_is_effect_of_strip(seq_other, seq)) { continue; } - if (UNLIKELY(strips_to_shuffle.contains(seq))) { + if (UNLIKELY(strips_to_shuffle.contains(seq_other))) { CLOG_WARN(&LOG, "Strip overlaps with itself or another strip, that is to be shuffled. " "This should never happen."); From 9463135fed29c5f54e43d2b5803ae665bb083572 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Tue, 7 Nov 2023 04:54:55 +0100 Subject: [PATCH 25/62] Fix incorrect assumption when handling overlap In `shuffle_seq_time_offset_get()` code tried to check whether `strips_to_shuffle` would overlap with each other, but this was done incorrectly. This check relied on result of `shuffle_seq_test_overlap()` but that function assumes, that only 1 strip of its input is transformed by `offset`. This means, that if 2 strips are moved by same offset and overlap is checked against each other it could result in true return value. However this is checked in the code already by `strips_to_shuffle.contains(seq_other)`, in which case loop continues. This resulted in emmision of warning which was incorrect. The issue is fixed by continuing loop if `strips_to_shuffle` contains `seq_other` as first precondition to signify, that this is expected and in fact inevitable case. `shuffle_seq_test_overlap()` does not check whether 2 passed strips are equal, rather `BLI_assert` is used to signify, that this is not valid use-case. Since the warning can not happen, the logging was removed. --- source/blender/sequencer/intern/strip_transform.cc | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/source/blender/sequencer/intern/strip_transform.cc b/source/blender/sequencer/intern/strip_transform.cc index 68eb89b600a..ea10474494b 100644 --- a/source/blender/sequencer/intern/strip_transform.cc +++ b/source/blender/sequencer/intern/strip_transform.cc @@ -36,8 +36,6 @@ #include "CLG_log.h" -static CLG_LogRef LOG = {"seq.strip_transform"}; - bool SEQ_transform_single_image_check(Sequence *seq) { return (seq->flag & SEQ_SINGLE_FRAME_CONTENT) != 0; @@ -195,7 +193,8 @@ static bool shuffle_seq_test_overlap(const Scene *scene, const Sequence *seq2, const int offset) { - return (seq1 != seq2 && seq1->machine == seq2->machine && + BLI_assert(seq1 != seq2); + return (seq1->machine == seq2->machine && ((SEQ_time_right_handle_frame_get(scene, seq1) + offset <= SEQ_time_left_handle_frame_get(scene, seq2)) || (SEQ_time_left_handle_frame_get(scene, seq1) + offset >= @@ -214,16 +213,13 @@ static int shuffle_seq_time_offset_get(const Scene *scene, all_conflicts_resolved = true; for (Sequence *seq : strips_to_shuffle) { LISTBASE_FOREACH (Sequence *, seq_other, seqbasep) { - if (!shuffle_seq_test_overlap(scene, seq, seq_other, offset)) { + if (strips_to_shuffle.contains(seq_other)) { continue; } if (SEQ_relation_is_effect_of_strip(seq_other, seq)) { continue; } - if (UNLIKELY(strips_to_shuffle.contains(seq_other))) { - CLOG_WARN(&LOG, - "Strip overlaps with itself or another strip, that is to be shuffled. " - "This should never happen."); + if (!shuffle_seq_test_overlap(scene, seq, seq_other, offset)) { continue; } From 79917e7bb32ac9f66bfba33a1e67670775c63eff Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Nov 2023 15:16:48 +1100 Subject: [PATCH 26/62] Cleanup: minor corrections & clarifications for undo tests --- tests/python/ui_simulate/run.py | 4 +--- tests/python/ui_simulate/test_undo.py | 22 ++++++++++++++-------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/tests/python/ui_simulate/run.py b/tests/python/ui_simulate/run.py index a25ccddc098..64537cce971 100755 --- a/tests/python/ui_simulate/run.py +++ b/tests/python/ui_simulate/run.py @@ -6,8 +6,6 @@ Run interaction tests using event simulation. Example usage from Blender's source dir: - ./tests/python/ui_simulate/run.py --blender=./blender.bin --tests test_undo.text_editor_simple - This uses ``test_undo.py``, running the ``text_editor_simple`` function. To run all tests: @@ -16,7 +14,7 @@ To run all tests: For an editor to follow the tests: - ./lib/python/tests/ui_simulate/run.py --blender=blender.bin --tests '*' \ + ./tests/python/ui_simulate/run.py --blender=blender.bin --tests '*' \ --step-command-pre='gvim --remote-silent +{line} "{file}"' """ diff --git a/tests/python/ui_simulate/test_undo.py b/tests/python/ui_simulate/test_undo.py index 1203bd74316..e6519263bcc 100644 --- a/tests/python/ui_simulate/test_undo.py +++ b/tests/python/ui_simulate/test_undo.py @@ -1,7 +1,8 @@ # SPDX-License-Identifier: GPL-2.0-or-later -# Only access for it's methods. - +""" +This file does not run anything, it's methods are accessed for tests by: ``run.py``. +""" # FIXME: Since 2.8 or so, there is a problem with simulated events # where a popup needs the main-loop to cycle once before new events @@ -270,6 +271,9 @@ def text_editor_edit_mode_mix(): # 3D View def _view3d_startup_area_maximized(e): + """ + Set the 3D viewport and set the area full-screen so no other regions. + """ yield e.shift.f5() # 3D Viewport. yield e.ctrl.alt.space() # Full-screen. yield e.a() # Select all. @@ -277,6 +281,10 @@ def _view3d_startup_area_maximized(e): def _view3d_startup_area_single(e): + """ + Create a single area (not full screen) + this has the advantage that the window can be duplicated (not the case with a full-screened area). + """ yield e.shift.f5() # 3D Viewport. yield e.a() # Select all. yield e.delete().ret() # Delete all. @@ -444,8 +452,6 @@ def view3d_texture_paint_simple(): t.assertEqual(window.view_layer.objects.active.mode, 'TEXTURE_PAINT') yield from e.leftmouse.cursor_motion(_cursor_motion_data_x(window)) yield e.ctrl.z() # Used to crash T61172. - # test_undo.view3d_sculpt_dyntopo_simple - # test_undo.view3d_texture_paint_simple def view3d_texture_paint_complex(): @@ -597,14 +603,14 @@ def view3d_multi_mode_select(): object_names.append(window.view_layer.objects.active.name) yield from _call_menu(e, "View -> Frame All") - print(object_names) + # print(object_names) for ob_name in object_names: yield from _view3d_object_select_by_name(e, ob_name) yield - print() - print('=' * 40) - print(window.view_layer.objects.active.name, ob_name) + # print() + # print('=' * 40) + # print(window.view_layer.objects.active.name, ob_name) for ob_name in reversed(object_names): t.assertEqual(ob_name, window.view_layer.objects.active.name) From dfd363edbd5c30d1c64f2b1cc13bb24c884a6ada Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Nov 2023 15:37:47 +1100 Subject: [PATCH 27/62] Cleanup: add SPDX-FileCopyrightText --- tests/python/ui_simulate/modules/easy_keys.py | 2 ++ tests/python/ui_simulate/run.py | 2 ++ tests/python/ui_simulate/run_blender_setup.py | 2 ++ tests/python/ui_simulate/test_undo.py | 2 ++ 4 files changed, 8 insertions(+) diff --git a/tests/python/ui_simulate/modules/easy_keys.py b/tests/python/ui_simulate/modules/easy_keys.py index 3d8f08e3176..dbeffae1110 100644 --- a/tests/python/ui_simulate/modules/easy_keys.py +++ b/tests/python/ui_simulate/modules/easy_keys.py @@ -1,3 +1,5 @@ +# SPDX-FileCopyrightText: 2019-2023 Blender Authors +# # SPDX-License-Identifier: GPL-2.0-or-later import string diff --git a/tests/python/ui_simulate/run.py b/tests/python/ui_simulate/run.py index 64537cce971..e6eb031d755 100755 --- a/tests/python/ui_simulate/run.py +++ b/tests/python/ui_simulate/run.py @@ -1,4 +1,6 @@ #!/usr/bin/env python3 +# SPDX-FileCopyrightText: 2019-2023 Blender Authors +# # SPDX-License-Identifier: GPL-2.0-or-later """ diff --git a/tests/python/ui_simulate/run_blender_setup.py b/tests/python/ui_simulate/run_blender_setup.py index cd206a3e1ad..49d3e65e6e7 100644 --- a/tests/python/ui_simulate/run_blender_setup.py +++ b/tests/python/ui_simulate/run_blender_setup.py @@ -1,3 +1,5 @@ +# SPDX-FileCopyrightText: 2019-2023 Blender Authors +# # SPDX-License-Identifier: GPL-2.0-or-later """ diff --git a/tests/python/ui_simulate/test_undo.py b/tests/python/ui_simulate/test_undo.py index e6519263bcc..c88362de377 100644 --- a/tests/python/ui_simulate/test_undo.py +++ b/tests/python/ui_simulate/test_undo.py @@ -1,3 +1,5 @@ +# SPDX-FileCopyrightText: 2019-2023 Blender Authors +# # SPDX-License-Identifier: GPL-2.0-or-later """ From 6297bbe931b6be271b67d6cd84ed575002652cb0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Nov 2023 15:42:52 +1100 Subject: [PATCH 28/62] License headers: attribute copyright to "Blender Authors" See #110784, it seems that merging functionality reintroduced the old convention. --- source/blender/animrig/ANIM_armature_iter.hh | 2 +- source/blender/animrig/ANIM_bone_collections.hh | 2 +- source/blender/animrig/ANIM_bonecolor.hh | 2 +- source/blender/animrig/ANIM_fcurve.hh | 2 +- source/blender/animrig/ANIM_keyframing.hh | 2 +- source/blender/animrig/ANIM_rna.hh | 2 +- source/blender/animrig/ANIM_visualkey.hh | 2 +- source/blender/animrig/intern/anim_rna.cc | 2 +- source/blender/animrig/intern/bonecolor.cc | 2 +- source/blender/animrig/intern/fcurve.cc | 2 +- source/blender/animrig/intern/keyframing.cc | 2 +- source/blender/animrig/intern/keyframing_auto.cc | 2 +- source/blender/animrig/intern/visualkey.cc | 2 +- source/blender/blenkernel/intern/bake_items_paths.cc | 2 +- source/blender/blenlib/intern/bit_ref.cc | 2 +- source/blender/blenlib/intern/cpp_type.cc | 2 +- source/blender/blenlib/intern/hash_tables.cc | 2 +- source/blender/blenlib/intern/index_range.cc | 2 +- source/blender/blenlib/intern/math_basis_types.cc | 2 +- source/blender/blenlib/intern/string_ref.cc | 2 +- source/blender/blenlib/intern/vector.cc | 2 +- source/blender/blenlib/intern/virtual_array.cc | 2 +- .../COM_KuwaharaAnisotropicStructureTensorOperation.cc | 2 +- .../COM_KuwaharaAnisotropicStructureTensorOperation.h | 2 +- .../compositor/operations/COM_SummedAreaTableOperation.cc | 2 +- .../compositor/operations/COM_SummedAreaTableOperation.h | 2 +- .../tests/COM_ComputeSummedAreaTableOperation_test.cc | 2 +- .../blender/editors/grease_pencil/intern/grease_pencil_geom.cc | 2 +- .../blender/editors/grease_pencil/intern/grease_pencil_utils.cc | 2 +- .../editors/interface/interface_template_node_tree_interface.cc | 2 +- .../editors/space_outliner/tree/tree_element_linked_object.cc | 2 +- .../editors/space_outliner/tree/tree_element_linked_object.hh | 2 +- .../editors/space_outliner/tree/tree_element_modifier.cc | 2 +- .../editors/space_outliner/tree/tree_element_modifier.hh | 2 +- source/blender/makesrna/intern/rna_node_tree_interface.cc | 2 +- .../nodes/function/nodes/node_fn_axis_angle_to_rotation.cc | 2 +- .../blender/nodes/function/nodes/node_fn_euler_to_rotation.cc | 2 +- source/blender/nodes/function/nodes/node_fn_invert_rotation.cc | 2 +- .../nodes/function/nodes/node_fn_quaternion_to_rotation.cc | 2 +- source/blender/nodes/function/nodes/node_fn_rotate_vector.cc | 2 +- .../nodes/function/nodes/node_fn_rotation_to_axis_angle.cc | 2 +- .../blender/nodes/function/nodes/node_fn_rotation_to_euler.cc | 2 +- .../nodes/function/nodes/node_fn_rotation_to_quaternion.cc | 2 +- .../blender/nodes/geometry/nodes/node_geo_points_to_curves.cc | 2 +- source/blender/nodes/shader/materialx/group_nodes.cc | 2 +- source/blender/nodes/shader/materialx/group_nodes.h | 2 +- source/blender/nodes/shader/materialx/material.cc | 2 +- source/blender/nodes/shader/materialx/material.h | 2 +- source/blender/nodes/shader/materialx/node_item.cc | 2 +- source/blender/nodes/shader/materialx/node_item.h | 2 +- source/blender/nodes/shader/materialx/node_parser.cc | 2 +- source/blender/nodes/shader/materialx/node_parser.h | 2 +- tests/python/bl_node_group_compat.py | 2 +- tests/python/bl_node_group_interface.py | 2 +- tests/python/compositor_realtime_render_tests.py | 2 +- 55 files changed, 55 insertions(+), 55 deletions(-) diff --git a/source/blender/animrig/ANIM_armature_iter.hh b/source/blender/animrig/ANIM_armature_iter.hh index 48030f872f2..53288c11388 100644 --- a/source/blender/animrig/ANIM_armature_iter.hh +++ b/source/blender/animrig/ANIM_armature_iter.hh @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/animrig/ANIM_bone_collections.hh b/source/blender/animrig/ANIM_bone_collections.hh index 57bae41aa58..144670240fc 100644 --- a/source/blender/animrig/ANIM_bone_collections.hh +++ b/source/blender/animrig/ANIM_bone_collections.hh @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/animrig/ANIM_bonecolor.hh b/source/blender/animrig/ANIM_bonecolor.hh index ba3ddf9140a..c440196e5f5 100644 --- a/source/blender/animrig/ANIM_bonecolor.hh +++ b/source/blender/animrig/ANIM_bonecolor.hh @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/animrig/ANIM_fcurve.hh b/source/blender/animrig/ANIM_fcurve.hh index 057702c1de2..0122fc959db 100644 --- a/source/blender/animrig/ANIM_fcurve.hh +++ b/source/blender/animrig/ANIM_fcurve.hh @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/animrig/ANIM_keyframing.hh b/source/blender/animrig/ANIM_keyframing.hh index b38b2f85f2d..10f003f5204 100644 --- a/source/blender/animrig/ANIM_keyframing.hh +++ b/source/blender/animrig/ANIM_keyframing.hh @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/animrig/ANIM_rna.hh b/source/blender/animrig/ANIM_rna.hh index 335d14b19ff..831b2bad1ba 100644 --- a/source/blender/animrig/ANIM_rna.hh +++ b/source/blender/animrig/ANIM_rna.hh @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/animrig/ANIM_visualkey.hh b/source/blender/animrig/ANIM_visualkey.hh index 5332a4fa7a6..cd3083441ce 100644 --- a/source/blender/animrig/ANIM_visualkey.hh +++ b/source/blender/animrig/ANIM_visualkey.hh @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/animrig/intern/anim_rna.cc b/source/blender/animrig/intern/anim_rna.cc index 8214a2cfe16..2b0b8176550 100644 --- a/source/blender/animrig/intern/anim_rna.cc +++ b/source/blender/animrig/intern/anim_rna.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/animrig/intern/bonecolor.cc b/source/blender/animrig/intern/bonecolor.cc index 196d7e6ba40..d0e29b39681 100644 --- a/source/blender/animrig/intern/bonecolor.cc +++ b/source/blender/animrig/intern/bonecolor.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/animrig/intern/fcurve.cc b/source/blender/animrig/intern/fcurve.cc index b1c1131fd0a..04c7e579907 100644 --- a/source/blender/animrig/intern/fcurve.cc +++ b/source/blender/animrig/intern/fcurve.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/animrig/intern/keyframing.cc b/source/blender/animrig/intern/keyframing.cc index 8cc3ad36710..c5352861e62 100644 --- a/source/blender/animrig/intern/keyframing.cc +++ b/source/blender/animrig/intern/keyframing.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/animrig/intern/keyframing_auto.cc b/source/blender/animrig/intern/keyframing_auto.cc index 9382ad3260f..12b0e0e34d8 100644 --- a/source/blender/animrig/intern/keyframing_auto.cc +++ b/source/blender/animrig/intern/keyframing_auto.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/animrig/intern/visualkey.cc b/source/blender/animrig/intern/visualkey.cc index ffa62af292e..13a7823a679 100644 --- a/source/blender/animrig/intern/visualkey.cc +++ b/source/blender/animrig/intern/visualkey.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/blenkernel/intern/bake_items_paths.cc b/source/blender/blenkernel/intern/bake_items_paths.cc index 6945dacebfc..4f7d38dd752 100644 --- a/source/blender/blenkernel/intern/bake_items_paths.cc +++ b/source/blender/blenkernel/intern/bake_items_paths.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/blenlib/intern/bit_ref.cc b/source/blender/blenlib/intern/bit_ref.cc index b6bc02dfd7d..c9572477a68 100644 --- a/source/blender/blenlib/intern/bit_ref.cc +++ b/source/blender/blenlib/intern/bit_ref.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/blenlib/intern/cpp_type.cc b/source/blender/blenlib/intern/cpp_type.cc index ee17924bc05..7d590a8a663 100644 --- a/source/blender/blenlib/intern/cpp_type.cc +++ b/source/blender/blenlib/intern/cpp_type.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/blenlib/intern/hash_tables.cc b/source/blender/blenlib/intern/hash_tables.cc index f0c36eab60e..a0760c42e3f 100644 --- a/source/blender/blenlib/intern/hash_tables.cc +++ b/source/blender/blenlib/intern/hash_tables.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/blenlib/intern/index_range.cc b/source/blender/blenlib/intern/index_range.cc index 559f4fd6797..315a14e2790 100644 --- a/source/blender/blenlib/intern/index_range.cc +++ b/source/blender/blenlib/intern/index_range.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/blenlib/intern/math_basis_types.cc b/source/blender/blenlib/intern/math_basis_types.cc index a3e6422d1c4..d99e4aba2a6 100644 --- a/source/blender/blenlib/intern/math_basis_types.cc +++ b/source/blender/blenlib/intern/math_basis_types.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/blenlib/intern/string_ref.cc b/source/blender/blenlib/intern/string_ref.cc index 1e466753c68..5c26361d0e0 100644 --- a/source/blender/blenlib/intern/string_ref.cc +++ b/source/blender/blenlib/intern/string_ref.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/blenlib/intern/vector.cc b/source/blender/blenlib/intern/vector.cc index e17dcb5c77a..47c2667a8d0 100644 --- a/source/blender/blenlib/intern/vector.cc +++ b/source/blender/blenlib/intern/vector.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/blenlib/intern/virtual_array.cc b/source/blender/blenlib/intern/virtual_array.cc index 75bc5d71664..c935a7a1b67 100644 --- a/source/blender/blenlib/intern/virtual_array.cc +++ b/source/blender/blenlib/intern/virtual_array.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/compositor/operations/COM_KuwaharaAnisotropicStructureTensorOperation.cc b/source/blender/compositor/operations/COM_KuwaharaAnisotropicStructureTensorOperation.cc index bd54a2b062d..66be7a256b3 100644 --- a/source/blender/compositor/operations/COM_KuwaharaAnisotropicStructureTensorOperation.cc +++ b/source/blender/compositor/operations/COM_KuwaharaAnisotropicStructureTensorOperation.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/compositor/operations/COM_KuwaharaAnisotropicStructureTensorOperation.h b/source/blender/compositor/operations/COM_KuwaharaAnisotropicStructureTensorOperation.h index 5e35c06b8ac..2a76cfd3e7e 100644 --- a/source/blender/compositor/operations/COM_KuwaharaAnisotropicStructureTensorOperation.h +++ b/source/blender/compositor/operations/COM_KuwaharaAnisotropicStructureTensorOperation.h @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/compositor/operations/COM_SummedAreaTableOperation.cc b/source/blender/compositor/operations/COM_SummedAreaTableOperation.cc index 8dca4e293bb..4b7b03cbe84 100644 --- a/source/blender/compositor/operations/COM_SummedAreaTableOperation.cc +++ b/source/blender/compositor/operations/COM_SummedAreaTableOperation.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/compositor/operations/COM_SummedAreaTableOperation.h b/source/blender/compositor/operations/COM_SummedAreaTableOperation.h index 05d1bba0461..e4766a56740 100644 --- a/source/blender/compositor/operations/COM_SummedAreaTableOperation.h +++ b/source/blender/compositor/operations/COM_SummedAreaTableOperation.h @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/compositor/tests/COM_ComputeSummedAreaTableOperation_test.cc b/source/blender/compositor/tests/COM_ComputeSummedAreaTableOperation_test.cc index 415fb908fb4..986a340e240 100644 --- a/source/blender/compositor/tests/COM_ComputeSummedAreaTableOperation_test.cc +++ b/source/blender/compositor/tests/COM_ComputeSummedAreaTableOperation_test.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/editors/grease_pencil/intern/grease_pencil_geom.cc b/source/blender/editors/grease_pencil/intern/grease_pencil_geom.cc index 6e219be13bb..2e1ee0f2c8f 100644 --- a/source/blender/editors/grease_pencil/intern/grease_pencil_geom.cc +++ b/source/blender/editors/grease_pencil/intern/grease_pencil_geom.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/editors/grease_pencil/intern/grease_pencil_utils.cc b/source/blender/editors/grease_pencil/intern/grease_pencil_utils.cc index c599d329742..fc96a5b83ad 100644 --- a/source/blender/editors/grease_pencil/intern/grease_pencil_utils.cc +++ b/source/blender/editors/grease_pencil/intern/grease_pencil_utils.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/editors/interface/interface_template_node_tree_interface.cc b/source/blender/editors/interface/interface_template_node_tree_interface.cc index 32551388f5d..d5ef7d3fc5f 100644 --- a/source/blender/editors/interface/interface_template_node_tree_interface.cc +++ b/source/blender/editors/interface/interface_template_node_tree_interface.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/editors/space_outliner/tree/tree_element_linked_object.cc b/source/blender/editors/space_outliner/tree/tree_element_linked_object.cc index 83b51b82356..036f7b62b83 100644 --- a/source/blender/editors/space_outliner/tree/tree_element_linked_object.cc +++ b/source/blender/editors/space_outliner/tree/tree_element_linked_object.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/editors/space_outliner/tree/tree_element_linked_object.hh b/source/blender/editors/space_outliner/tree/tree_element_linked_object.hh index 6128aa1f32f..0eac37d1ade 100644 --- a/source/blender/editors/space_outliner/tree/tree_element_linked_object.hh +++ b/source/blender/editors/space_outliner/tree/tree_element_linked_object.hh @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/editors/space_outliner/tree/tree_element_modifier.cc b/source/blender/editors/space_outliner/tree/tree_element_modifier.cc index 6f4b74ec953..234aa98df29 100644 --- a/source/blender/editors/space_outliner/tree/tree_element_modifier.cc +++ b/source/blender/editors/space_outliner/tree/tree_element_modifier.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/editors/space_outliner/tree/tree_element_modifier.hh b/source/blender/editors/space_outliner/tree/tree_element_modifier.hh index 4183b7bf921..1b2be7206e8 100644 --- a/source/blender/editors/space_outliner/tree/tree_element_modifier.hh +++ b/source/blender/editors/space_outliner/tree/tree_element_modifier.hh @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/makesrna/intern/rna_node_tree_interface.cc b/source/blender/makesrna/intern/rna_node_tree_interface.cc index a124f475292..18fedf45d80 100644 --- a/source/blender/makesrna/intern/rna_node_tree_interface.cc +++ b/source/blender/makesrna/intern/rna_node_tree_interface.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/nodes/function/nodes/node_fn_axis_angle_to_rotation.cc b/source/blender/nodes/function/nodes/node_fn_axis_angle_to_rotation.cc index 08bc7aa270c..fd56f847f2d 100644 --- a/source/blender/nodes/function/nodes/node_fn_axis_angle_to_rotation.cc +++ b/source/blender/nodes/function/nodes/node_fn_axis_angle_to_rotation.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/nodes/function/nodes/node_fn_euler_to_rotation.cc b/source/blender/nodes/function/nodes/node_fn_euler_to_rotation.cc index ff6768342d3..8636b079bff 100644 --- a/source/blender/nodes/function/nodes/node_fn_euler_to_rotation.cc +++ b/source/blender/nodes/function/nodes/node_fn_euler_to_rotation.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/nodes/function/nodes/node_fn_invert_rotation.cc b/source/blender/nodes/function/nodes/node_fn_invert_rotation.cc index bdcd236146e..36b8e3ac700 100644 --- a/source/blender/nodes/function/nodes/node_fn_invert_rotation.cc +++ b/source/blender/nodes/function/nodes/node_fn_invert_rotation.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/nodes/function/nodes/node_fn_quaternion_to_rotation.cc b/source/blender/nodes/function/nodes/node_fn_quaternion_to_rotation.cc index 15c492de796..113180d646c 100644 --- a/source/blender/nodes/function/nodes/node_fn_quaternion_to_rotation.cc +++ b/source/blender/nodes/function/nodes/node_fn_quaternion_to_rotation.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/nodes/function/nodes/node_fn_rotate_vector.cc b/source/blender/nodes/function/nodes/node_fn_rotate_vector.cc index d86bbbaf73a..15d6b47f0fa 100644 --- a/source/blender/nodes/function/nodes/node_fn_rotate_vector.cc +++ b/source/blender/nodes/function/nodes/node_fn_rotate_vector.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/nodes/function/nodes/node_fn_rotation_to_axis_angle.cc b/source/blender/nodes/function/nodes/node_fn_rotation_to_axis_angle.cc index adffb7f2154..529130785ab 100644 --- a/source/blender/nodes/function/nodes/node_fn_rotation_to_axis_angle.cc +++ b/source/blender/nodes/function/nodes/node_fn_rotation_to_axis_angle.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/nodes/function/nodes/node_fn_rotation_to_euler.cc b/source/blender/nodes/function/nodes/node_fn_rotation_to_euler.cc index d47230ddaf9..7c6938f3db9 100644 --- a/source/blender/nodes/function/nodes/node_fn_rotation_to_euler.cc +++ b/source/blender/nodes/function/nodes/node_fn_rotation_to_euler.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/nodes/function/nodes/node_fn_rotation_to_quaternion.cc b/source/blender/nodes/function/nodes/node_fn_rotation_to_quaternion.cc index be381f6b40a..399d773ca1e 100644 --- a/source/blender/nodes/function/nodes/node_fn_rotation_to_quaternion.cc +++ b/source/blender/nodes/function/nodes/node_fn_rotation_to_quaternion.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/nodes/geometry/nodes/node_geo_points_to_curves.cc b/source/blender/nodes/geometry/nodes/node_geo_points_to_curves.cc index b422db14a29..97fe596f92b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_points_to_curves.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_points_to_curves.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2023 Blender Foundation +/* SPDX-FileCopyrightText: 2023 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/nodes/shader/materialx/group_nodes.cc b/source/blender/nodes/shader/materialx/group_nodes.cc index 4fbeefc4ce5..81ba769001e 100644 --- a/source/blender/nodes/shader/materialx/group_nodes.cc +++ b/source/blender/nodes/shader/materialx/group_nodes.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation +/* SPDX-FileCopyrightText: 2011-2022 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/nodes/shader/materialx/group_nodes.h b/source/blender/nodes/shader/materialx/group_nodes.h index 983ab5f1062..56e747464b3 100644 --- a/source/blender/nodes/shader/materialx/group_nodes.h +++ b/source/blender/nodes/shader/materialx/group_nodes.h @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation +/* SPDX-FileCopyrightText: 2011-2022 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/nodes/shader/materialx/material.cc b/source/blender/nodes/shader/materialx/material.cc index 5339289e21b..4f4358ed137 100644 --- a/source/blender/nodes/shader/materialx/material.cc +++ b/source/blender/nodes/shader/materialx/material.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation +/* SPDX-FileCopyrightText: 2011-2022 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/nodes/shader/materialx/material.h b/source/blender/nodes/shader/materialx/material.h index d0a4a7e6a31..7c62d4fe361 100644 --- a/source/blender/nodes/shader/materialx/material.h +++ b/source/blender/nodes/shader/materialx/material.h @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation +/* SPDX-FileCopyrightText: 2011-2022 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/nodes/shader/materialx/node_item.cc b/source/blender/nodes/shader/materialx/node_item.cc index d2468cff770..959fae20a04 100644 --- a/source/blender/nodes/shader/materialx/node_item.cc +++ b/source/blender/nodes/shader/materialx/node_item.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation +/* SPDX-FileCopyrightText: 2011-2022 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/nodes/shader/materialx/node_item.h b/source/blender/nodes/shader/materialx/node_item.h index f392a42666d..f6a98366d73 100644 --- a/source/blender/nodes/shader/materialx/node_item.h +++ b/source/blender/nodes/shader/materialx/node_item.h @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation +/* SPDX-FileCopyrightText: 2011-2022 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/nodes/shader/materialx/node_parser.cc b/source/blender/nodes/shader/materialx/node_parser.cc index e1313b770d6..2f8628270da 100644 --- a/source/blender/nodes/shader/materialx/node_parser.cc +++ b/source/blender/nodes/shader/materialx/node_parser.cc @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation +/* SPDX-FileCopyrightText: 2011-2022 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/source/blender/nodes/shader/materialx/node_parser.h b/source/blender/nodes/shader/materialx/node_parser.h index 87d860fe9d8..5f76b8caaf2 100644 --- a/source/blender/nodes/shader/materialx/node_parser.h +++ b/source/blender/nodes/shader/materialx/node_parser.h @@ -1,4 +1,4 @@ -/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation +/* SPDX-FileCopyrightText: 2011-2022 Blender Authors * * SPDX-License-Identifier: GPL-2.0-or-later */ diff --git a/tests/python/bl_node_group_compat.py b/tests/python/bl_node_group_compat.py index 7138ac621f5..3e3002618e8 100644 --- a/tests/python/bl_node_group_compat.py +++ b/tests/python/bl_node_group_compat.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2021-2023 Blender Foundation +# SPDX-FileCopyrightText: 2021-2023 Blender Authors # # SPDX-License-Identifier: GPL-2.0-or-later diff --git a/tests/python/bl_node_group_interface.py b/tests/python/bl_node_group_interface.py index 61beed4b444..7f5582507c8 100644 --- a/tests/python/bl_node_group_interface.py +++ b/tests/python/bl_node_group_interface.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2021-2023 Blender Foundation +# SPDX-FileCopyrightText: 2021-2023 Blender Authors # # SPDX-License-Identifier: GPL-2.0-or-later diff --git a/tests/python/compositor_realtime_render_tests.py b/tests/python/compositor_realtime_render_tests.py index 946cac753ac..11d92e6bd84 100644 --- a/tests/python/compositor_realtime_render_tests.py +++ b/tests/python/compositor_realtime_render_tests.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# SPDX-FileCopyrightText: 2015-2023 Blender Foundation +# SPDX-FileCopyrightText: 2015-2023 Blender Authors # # SPDX-License-Identifier: Apache-2.0 From 611930e5a8f2f0e2efc1035f54625331219f0294 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Nov 2023 16:33:19 +1100 Subject: [PATCH 29/62] Cleanup: use std::min/max instead of MIN2/MAX2 macros --- source/blender/blenfont/intern/blf_font.cc | 4 +- source/blender/blenfont/intern/blf_glyph.cc | 6 +- source/blender/blenfont/intern/blf_thumbs.cc | 4 +- source/blender/blenkernel/intern/anim_sys.cc | 2 +- source/blender/blenkernel/intern/boids.cc | 8 +- source/blender/blenkernel/intern/collision.cc | 2 +- source/blender/blenkernel/intern/fluid.cc | 18 +-- source/blender/blenkernel/intern/fmodifier.cc | 3 +- .../blenkernel/intern/gpencil_geom_legacy.cc | 6 +- .../blenkernel/intern/mask_evaluate.cc | 3 +- .../blenkernel/intern/mask_rasterize.cc | 4 +- source/blender/blenkernel/intern/multires.cc | 6 +- source/blender/blenkernel/intern/particle.cc | 14 +- .../blenkernel/intern/particle_child.cc | 2 +- .../blenkernel/intern/particle_distribute.cc | 8 +- .../blenkernel/intern/particle_system.cc | 8 +- .../blender/blenkernel/intern/pointcache.cc | 20 +-- source/blender/blenkernel/intern/rigidbody.cc | 2 +- .../blender/blenkernel/intern/subsurf_ccg.cc | 2 +- source/blender/blenkernel/intern/text.cc | 4 +- source/blender/blenkernel/intern/unit.cc | 9 +- source/blender/blenlib/intern/math_geom.cc | 2 +- source/blender/blenlib/intern/path_util.cc | 11 +- source/blender/blenlib/intern/task_range.cc | 2 +- source/blender/blenloader/intern/readfile.cc | 4 +- .../blenloader/intern/versioning_250.cc | 4 +- .../blenloader/intern/versioning_260.cc | 2 +- .../blenloader/intern/versioning_300.cc | 8 +- .../blenloader/intern/versioning_legacy.cc | 6 +- source/blender/blenloader/intern/writefile.cc | 2 +- .../bmesh/tools/bmesh_decimate_collapse.cc | 4 +- .../blender/bmesh/tools/bmesh_region_match.cc | 6 +- .../compositor/intern/COM_ExecutionGroup.cc | 10 +- .../compositor/intern/COM_ExecutionSystem.cc | 2 +- .../compositor/intern/COM_MemoryBuffer.cc | 4 +- .../compositor/intern/COM_NodeOperation.cc | 8 +- .../compositor/nodes/COM_SwitchViewNode.cc | 2 +- .../operations/COM_BokehBlurOperation.cc | 8 +- .../operations/COM_BoxMaskOperation.cc | 4 +- .../operations/COM_ChannelMatteOperation.cc | 4 +- .../COM_ColorBalanceLGGOperation.cc | 2 +- .../operations/COM_ColorSpillOperation.cc | 4 +- .../COM_ConvertDepthToRadiusOperation.cc | 2 +- .../operations/COM_CropOperation.cc | 6 +- .../operations/COM_DespeckleOperation.cc | 8 +- .../operations/COM_DilateErodeOperation.cc | 126 +++++++++--------- .../operations/COM_EllipseMaskOperation.cc | 4 +- .../COM_FastGaussianBlurOperation.cc | 6 +- .../COM_GaussianBokehBlurOperation.cc | 4 +- .../operations/COM_KeyingBlurOperation.cc | 10 +- .../operations/COM_KeyingClipOperation.cc | 8 +- .../operations/COM_KeyingDespillOperation.cc | 8 +- .../operations/COM_KeyingOperation.cc | 4 +- .../operations/COM_MathBaseOperation.cc | 2 +- .../operations/COM_RotateOperation.cc | 14 +- .../operations/COM_ScaleOperation.cc | 4 +- .../operations/COM_TonemapOperation.cc | 10 +- .../COM_VariableSizeBokehBlurOperation.cc | 49 +++---- .../operations/COM_ZCombineOperation.cc | 8 +- .../realtime_compositor/intern/scheduler.cc | 4 +- .../depsgraph/intern/depsgraph_query_iter.cc | 2 +- .../blender/draw/engines/eevee/eevee_bloom.cc | 10 +- .../draw/engines/eevee/eevee_engine.cc | 2 +- .../draw/engines/eevee/eevee_lightcache.cc | 2 +- source/blender/draw/intern/draw_curves.cc | 2 +- source/blender/draw/intern/draw_hair.cc | 2 +- .../draw/intern/draw_manager_profiling.cc | 4 +- .../animation/anim_channels_defines.cc | 2 +- source/blender/editors/animation/drivers.cc | 2 +- .../editors/animation/keyframes_keylist.cc | 2 +- .../editors/animation/time_scrub_ui.cc | 2 +- .../editors/gpencil_legacy/gpencil_merge.cc | 2 +- .../editors/gpencil_legacy/gpencil_paint.cc | 8 +- .../editors/gpencil_legacy/gpencil_utils.cc | 2 +- source/blender/editors/interface/interface.cc | 8 +- .../editors/interface/interface_draw.cc | 4 +- .../editors/interface/interface_icons.cc | 6 +- .../editors/interface/interface_layout.cc | 22 +-- .../interface/interface_region_popover.cc | 2 +- .../editors/interface/interface_style.cc | 4 +- .../editors/interface/interface_templates.cc | 6 +- .../editors/interface/interface_widgets.cc | 4 +- .../editors/object/object_gpencil_modifier.cc | 4 +- source/blender/editors/screen/screen_draw.cc | 32 ++--- source/blender/editors/screen/screen_edit.cc | 14 +- .../blender/editors/screen/screen_geometry.cc | 4 +- .../editors/sculpt_paint/paint_weight.cc | 4 +- .../editors/sculpt_paint/sculpt_pose.cc | 2 +- .../editors/space_action/action_draw.cc | 4 +- .../editors/space_clip/tracking_ops_track.cc | 4 +- .../blender/editors/space_file/file_draw.cc | 2 +- source/blender/editors/space_file/filelist.cc | 2 +- source/blender/editors/space_file/filesel.cc | 2 +- source/blender/editors/space_info/textview.cc | 6 +- .../editors/space_outliner/outliner_draw.cc | 2 +- .../blender/editors/space_text/text_draw.cc | 6 +- .../editors/space_view3d/view3d_draw.cc | 2 +- .../space_view3d/view3d_gizmo_ruler.cc | 2 +- source/blender/editors/transform/transform.cc | 2 +- .../transform/transform_convert_mesh.cc | 8 +- .../editors/uvedit/uvedit_smart_stitch.cc | 2 +- .../intern/MOD_gpencil_legacy_build.cc | 8 +- .../intern/MOD_gpencil_legacy_lineart.cc | 2 +- .../intern/lineart/lineart_chain.cc | 3 +- .../intern/lineart/lineart_cpu.cc | 17 ++- source/blender/gpu/intern/gpu_index_buffer.cc | 21 +-- source/blender/gpu/intern/gpu_material.cc | 2 +- source/blender/imbuf/intern/format_svg.cc | 6 +- source/blender/imbuf/intern/jpeg.cc | 2 +- .../imbuf/intern/openexr/openexr_api.cpp | 6 +- source/blender/imbuf/intern/stereoimbuf.cc | 2 +- source/blender/imbuf/intern/webp.cc | 6 +- .../io/gpencil/intern/gpencil_io_base.cc | 2 +- .../gpencil/intern/gpencil_io_export_pdf.cc | 2 +- .../gpencil/intern/gpencil_io_export_svg.cc | 2 +- source/blender/makesrna/intern/rna_access.cc | 18 +-- source/blender/makesrna/intern/rna_define.cc | 12 +- .../blender/modifiers/intern/MOD_subsurf.cc | 4 +- .../blender/modifiers/intern/MOD_wireframe.cc | 2 +- .../nodes/texture/nodes/node_texture_math.cc | 2 +- .../python/generic/idprop_py_ui_api.cc | 28 ++-- source/blender/python/intern/bpy_props.cc | 4 +- .../python/mathutils/mathutils_Matrix.cc | 2 +- .../python/mathutils/mathutils_Vector.cc | 6 +- source/blender/render/intern/texture_image.cc | 2 +- .../render/intern/texture_pointdensity.cc | 2 +- source/blender/sequencer/intern/effects.cc | 16 +-- source/blender/sequencer/intern/strip_add.cc | 2 +- .../windowmanager/intern/wm_playanim.cc | 2 +- .../windowmanager/intern/wm_splash_screen.cc | 2 +- 130 files changed, 458 insertions(+), 442 deletions(-) diff --git a/source/blender/blenfont/intern/blf_font.cc b/source/blender/blenfont/intern/blf_font.cc index 650ab11b304..563de55e242 100644 --- a/source/blender/blenfont/intern/blf_font.cc +++ b/source/blender/blenfont/intern/blf_font.cc @@ -1244,7 +1244,7 @@ static ft_pix blf_font_height_max_ft_pix(FontBLF *font) { blf_ensure_size(font); /* #Metrics::height is rounded to pixel. Force minimum of one pixel. */ - return MAX2((ft_pix)font->ft_size->metrics.height, ft_pix_from_int(1)); + return std::max((ft_pix)font->ft_size->metrics.height, ft_pix_from_int(1)); } int blf_font_height_max(FontBLF *font) @@ -1256,7 +1256,7 @@ static ft_pix blf_font_width_max_ft_pix(FontBLF *font) { blf_ensure_size(font); /* #Metrics::max_advance is rounded to pixel. Force minimum of one pixel. */ - return MAX2((ft_pix)font->ft_size->metrics.max_advance, ft_pix_from_int(1)); + return std::max((ft_pix)font->ft_size->metrics.max_advance, ft_pix_from_int(1)); } int blf_font_width_max(FontBLF *font) diff --git a/source/blender/blenfont/intern/blf_glyph.cc b/source/blender/blenfont/intern/blf_glyph.cc index d5fba595516..f03fd9e3f2e 100644 --- a/source/blender/blenfont/intern/blf_glyph.cc +++ b/source/blender/blenfont/intern/blf_glyph.cc @@ -1134,11 +1134,11 @@ static FT_GlyphSlot blf_glyph_render(FontBLF *settings_font, /* Style targets are on the settings_font. */ float weight_target = float(settings_font->char_weight); if (settings_font->flags & BLF_BOLD) { - weight_target = MIN2(weight_target + 300.0f, 900.0f); + weight_target = std::min(weight_target + 300.0f, 900.0f); } float slant_target = settings_font->char_slant; if (settings_font->flags & BLF_ITALIC) { - slant_target = MIN2(slant_target + 8.0f, 15.0f); + slant_target = std::min(slant_target + 8.0f, 15.0f); } float width_target = settings_font->char_width; float spacing_target = settings_font->char_spacing; @@ -1281,7 +1281,7 @@ static void blf_glyph_calc_rect_test(rcti *rect, GlyphBLF *g, const int x, const * width used by BLF_width. This allows that the text slightly * overlaps the clipping border to achieve better alignment. */ rect->xmin = x + g->pos[0] + 1; - rect->xmax = x + MIN2(ft_pix_to_int(g->advance_x), g->dims[0]); + rect->xmax = x + std::min(ft_pix_to_int(g->advance_x), g->dims[0]); rect->ymin = y; rect->ymax = rect->ymin - g->dims[1]; } diff --git a/source/blender/blenfont/intern/blf_thumbs.cc b/source/blender/blenfont/intern/blf_thumbs.cc index 31ca0d33f3e..de7534a557e 100644 --- a/source/blender/blenfont/intern/blf_thumbs.cc +++ b/source/blender/blenfont/intern/blf_thumbs.cc @@ -365,7 +365,7 @@ bool BLF_thumb_preview(const char *filename, uchar *buf, int w, int h, int /*cha int height = ft_pix_to_int((ft_pix)face->size->metrics.ascender - (ft_pix)face->size->metrics.descender); - width = MAX2(width, height); + width = std::max(width, height); /* Fill up to 96% horizontally or vertically. */ float font_size = MIN3(float(w), @@ -410,7 +410,7 @@ bool BLF_thumb_preview(const char *filename, uchar *buf, int w, int h, int /*cha if (dest_col >= 0 && dest_col < w) { uchar *source = &face->glyph->bitmap.buffer[y * int(face->glyph->bitmap.width) + x]; uchar *dest = &buf[dest_row * w * 4 + (dest_col * 4 + 3)]; - *dest = uchar(MIN2((uint(*dest) + uint(*source)), 255u)); + *dest = uchar(std::min((uint(*dest) + uint(*source)), 255u)); } } } diff --git a/source/blender/blenkernel/intern/anim_sys.cc b/source/blender/blenkernel/intern/anim_sys.cc index 782b999b1f9..7ca0d43eb69 100644 --- a/source/blender/blenkernel/intern/anim_sys.cc +++ b/source/blender/blenkernel/intern/anim_sys.cc @@ -1197,7 +1197,7 @@ static void nlaeval_snapshot_init(NlaEvalSnapshot *snapshot, NlaEvalSnapshot *base) { snapshot->base = base; - snapshot->size = MAX2(16, nlaeval->num_channels); + snapshot->size = std::max(16, nlaeval->num_channels); snapshot->channels = static_cast( MEM_callocN(sizeof(*snapshot->channels) * snapshot->size, "NlaEvalSnapshot::channels")); } diff --git a/source/blender/blenkernel/intern/boids.cc b/source/blender/blenkernel/intern/boids.cc index d0a37d6da9f..889e143e0ee 100644 --- a/source/blender/blenkernel/intern/boids.cc +++ b/source/blender/blenkernel/intern/boids.cc @@ -275,7 +275,7 @@ static bool rule_avoid_collision(BoidRule *rule, mul_v3_fl(bbd->wanted_co, (1.0f - t) * val->personal_space * pa->size); bbd->wanted_speed = sqrtf(t) * len_v3(pa->prev_state.vel); - bbd->wanted_speed = MAX2(bbd->wanted_speed, val->min_speed); + bbd->wanted_speed = std::max(bbd->wanted_speed, val->min_speed); return true; } @@ -1321,7 +1321,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) new_speed = MAX2(bbd->wanted_speed, old_speed - val.max_acc); } else { - new_speed = MIN2(bbd->wanted_speed, old_speed + val.max_acc); + new_speed = std::min(bbd->wanted_speed, old_speed + val.max_acc); } /* combine direction and speed */ @@ -1333,7 +1333,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) float len2 = dot_v2v2(new_vel, new_vel); float root; - len2 = MAX2(len2, val.min_speed * val.min_speed); + len2 = std::max(len2, val.min_speed * val.min_speed); root = sasqrt(new_speed * new_speed - len2); new_vel[2] = new_vel[2] < 0.0f ? -root : root; @@ -1367,7 +1367,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) if (ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)) { float length = normalize_v3(force); - length = MAX2(0.0f, length - boids->land_stick_force); + length = std::max(0.0f, length - boids->land_stick_force); mul_v3_fl(force, length); } diff --git a/source/blender/blenkernel/intern/collision.cc b/source/blender/blenkernel/intern/collision.cc index bf633e784e0..3a60bb81efa 100644 --- a/source/blender/blenkernel/intern/collision.cc +++ b/source/blender/blenkernel/intern/collision.cc @@ -757,7 +757,7 @@ static int cloth_collision_response_static(ClothModifierData *clmd, } if ((magrelVel < 0.1f * d * time_multiplier) && (d > ALMOST_ZERO)) { - repulse = MIN2(d / time_multiplier, 0.1f * d * time_multiplier - magrelVel); + repulse = std::min(d / time_multiplier, 0.1f * d * time_multiplier - magrelVel); /* Stay on the safe side and clamp repulse. */ if (impulse > ALMOST_ZERO) { diff --git a/source/blender/blenkernel/intern/fluid.cc b/source/blender/blenkernel/intern/fluid.cc index 793e43613b9..b9ac1c4023e 100644 --- a/source/blender/blenkernel/intern/fluid.cc +++ b/source/blender/blenkernel/intern/fluid.cc @@ -450,7 +450,7 @@ static void manta_set_domain_from_mesh(FluidDomainSettings *fds, fds->base_res[1] = max_ii(int(size[1] * scale + 0.5f), 4); fds->base_res[2] = max_ii(int(size[2] * scale + 0.5f), 4); } - else if (size[1] >= MAX2(size[0], size[2])) { + else if (size[1] >= std::max(size[0], size[2])) { scale = res / size[1]; fds->scale = size[1] / fabsf(ob->scale[1]); fds->base_res[0] = max_ii(int(size[0] * scale + 0.5f), 4); @@ -736,8 +736,8 @@ static void bb_combineMaps(FluidObjectBB *output, for (i = 0; i < 3; i++) { if (bb1.valid) { - output->min[i] = MIN2(bb1.min[i], bb2->min[i]); - output->max[i] = MAX2(bb1.max[i], bb2->max[i]); + output->min[i] = std::min(bb1.min[i], bb2->min[i]); + output->max[i] = std::max(bb1.max[i], bb2->max[i]); } else { output->min[i] = bb2->min[i]; @@ -783,13 +783,13 @@ static void bb_combineMaps(FluidObjectBB *output, x - bb2->min[0], bb2->res[0], y - bb2->min[1], bb2->res[1], z - bb2->min[2]); /* Values. */ - output->numobjs[index_out] = MAX2(bb2->numobjs[index_in], output->numobjs[index_out]); + output->numobjs[index_out] = std::max(bb2->numobjs[index_in], output->numobjs[index_out]); if (output->influence && bb2->influence) { if (additive) { output->influence[index_out] += bb2->influence[index_in] * sample_size; } else { - output->influence[index_out] = MAX2(bb2->influence[index_in], + output->influence[index_out] = std::max(bb2->influence[index_in], output->influence[index_out]); } } @@ -2481,7 +2481,7 @@ BLI_INLINE void apply_inflow_fields(FluidFlowSettings *ffs, /* Set emission value for smoke inflow. * Ensure that emission value is "maximized". */ if (emission_in) { - emission_in[index] = MAX2(emission_value, emission_in[index]); + emission_in[index] = std::max(emission_value, emission_in[index]); } /* Set inflow for smoke from here on. */ @@ -2502,13 +2502,13 @@ BLI_INLINE void apply_inflow_fields(FluidFlowSettings *ffs, if (density && density_in) { if (ffs->type != FLUID_FLOW_TYPE_FIRE && dens_flow > density[index]) { /* Use MAX2 to preserve values from other emitters at this cell. */ - density_in[index] = MAX2(dens_flow, density_in[index]); + density_in[index] = std::max(dens_flow, density_in[index]); } } if (fuel && fuel_in) { if (ffs->type != FLUID_FLOW_TYPE_SMOKE && fuel_flow && fuel_flow > fuel[index]) { /* Use MAX2 to preserve values from other emitters at this cell. */ - fuel_in[index] = MAX2(fuel_flow, fuel_in[index]); + fuel_in[index] = std::max(fuel_flow, fuel_in[index]); } } } @@ -4414,7 +4414,7 @@ float BKE_fluid_get_velocity_at(Object *ob, float position[3], float velocity[3] if (manta_smoke_has_fuel(fds->fluid)) { fuel = BLI_voxel_sample_trilinear(manta_smoke_get_fuel(fds->fluid), fds->res, pos); } - return MAX2(density, fuel); + return std::max(density, fuel); } return -1.0f; } diff --git a/source/blender/blenkernel/intern/fmodifier.cc b/source/blender/blenkernel/intern/fmodifier.cc index 8fba3cb446f..af53dadd214 100644 --- a/source/blender/blenkernel/intern/fmodifier.cc +++ b/source/blender/blenkernel/intern/fmodifier.cc @@ -6,6 +6,7 @@ * \ingroup bke */ +#include /* For `min/max`. */ #include #include #include @@ -1327,7 +1328,7 @@ uint evaluate_fmodifiers_storage_size_per_modifier(ListBase *modifiers) continue; } - max_size = MAX2(max_size, fmi->storage_size); + max_size = std::max(max_size, fmi->storage_size); } return max_size; diff --git a/source/blender/blenkernel/intern/gpencil_geom_legacy.cc b/source/blender/blenkernel/intern/gpencil_geom_legacy.cc index cfe499a3a63..c815f067037 100644 --- a/source/blender/blenkernel/intern/gpencil_geom_legacy.cc +++ b/source/blender/blenkernel/intern/gpencil_geom_legacy.cc @@ -1717,7 +1717,7 @@ float BKE_gpencil_stroke_segment_length(const bGPDstroke *gps, } int index = MAX2(start_index, 0) + 1; - int last_index = MIN2(end_index, gps->totpoints - 1) + 1; + int last_index = std::min(end_index, gps->totpoints - 1) + 1; float *last_pt = &gps->points[index - 1].x; float total_length = 0.0f; @@ -3560,8 +3560,8 @@ void BKE_gpencil_stroke_join(bGPDstroke *gps_a, if (smooth) { const int sample_points = 8; /* Get the segment to smooth using n points on each side of the join. */ - int start = MAX2(0, totpoints_a - sample_points); - int end = MIN2(gps_a->totpoints - 1, start + (sample_points * 2)); + int start = std::max(0, totpoints_a - sample_points); + int end = std::min(gps_a->totpoints - 1, start + (sample_points * 2)); const int len = (end - start); float step = 1.0f / ((len / 2) + 1); diff --git a/source/blender/blenkernel/intern/mask_evaluate.cc b/source/blender/blenkernel/intern/mask_evaluate.cc index dcdcfc9aa36..5d7789ffed2 100644 --- a/source/blender/blenkernel/intern/mask_evaluate.cc +++ b/source/blender/blenkernel/intern/mask_evaluate.cc @@ -8,6 +8,7 @@ * Functions for evaluating the mask beziers into points for the outline and feather. */ +#include /* For `min/max`. */ #include #include @@ -57,7 +58,7 @@ uint BKE_mask_spline_resolution(MaskSpline *spline, int width, int height) len = a + b + c; cur_resol = len / max_segment; - resol = MAX2(resol, cur_resol); + resol = std::max(resol, cur_resol); if (resol >= MASK_RESOL_MAX) { break; diff --git a/source/blender/blenkernel/intern/mask_rasterize.cc b/source/blender/blenkernel/intern/mask_rasterize.cc index a9eb71d5872..438ccdb23b9 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.cc +++ b/source/blender/blenkernel/intern/mask_rasterize.cc @@ -50,6 +50,8 @@ * - Campbell */ +#include /* For `min/max`. */ + #include "CLG_log.h" #include "MEM_guardedalloc.h" @@ -630,7 +632,7 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, const uint resol_a = BKE_mask_spline_resolution(spline, width, height) / 4; const uint resol_b = BKE_mask_spline_feather_resolution(spline, width, height) / 4; - const uint resol = CLAMPIS(MAX2(resol_a, resol_b), 4, 512); + const uint resol = CLAMPIS(std::max(resol_a, resol_b), 4, 512); diff_points = BKE_mask_spline_differentiate_with_resolution(spline, resol, &tot_diff_point); diff --git a/source/blender/blenkernel/intern/multires.cc b/source/blender/blenkernel/intern/multires.cc index 93ebab4d521..768487085c5 100644 --- a/source/blender/blenkernel/intern/multires.cc +++ b/source/blender/blenkernel/intern/multires.cc @@ -532,9 +532,9 @@ void multiresModifier_set_levels_from_disps(MultiresModifierData *mmd, Object *o if (mdisp) { mmd->totlvl = get_levels_from_disps(ob); - mmd->lvl = MIN2(mmd->sculptlvl, mmd->totlvl); - mmd->sculptlvl = MIN2(mmd->sculptlvl, mmd->totlvl); - mmd->renderlvl = MIN2(mmd->renderlvl, mmd->totlvl); + mmd->lvl = std::min(mmd->sculptlvl, mmd->totlvl); + mmd->sculptlvl = std::min(mmd->sculptlvl, mmd->totlvl); + mmd->renderlvl = std::min(mmd->renderlvl, mmd->totlvl); } } diff --git a/source/blender/blenkernel/intern/particle.cc b/source/blender/blenkernel/intern/particle.cc index 3ae5a490d5e..8c389cfb7fa 100644 --- a/source/blender/blenkernel/intern/particle.cc +++ b/source/blender/blenkernel/intern/particle.cc @@ -492,12 +492,12 @@ static ParticleCacheKey **psys_alloc_path_cache_buffers(ListBase *bufs, int tot, ParticleCacheKey **cache; int i, totkey, totbufkey; - tot = MAX2(tot, 1); + tot = std::max(tot, 1); totkey = 0; cache = static_cast(MEM_callocN(tot * sizeof(void *), "PathCacheArray")); while (totkey < tot) { - totbufkey = MIN2(tot - totkey, PATH_CACHE_BUF_SIZE); + totbufkey = std::min(tot - totkey, PATH_CACHE_BUF_SIZE); buf = static_cast(MEM_callocN(sizeof(LinkData), "PathCacheLinkData")); buf->data = MEM_callocN(sizeof(ParticleCacheKey) * totbufkey * totkeys, "ParticleCacheKey"); @@ -1309,8 +1309,8 @@ static void init_particle_interpolation(Object *ob, pind->dietime = pa ? pa->dietime : (pind->cache->endframe + 1); if (get_pointcache_times_for_particle(pind->cache, pa - psys->particles, &start, &dietime)) { - pind->birthtime = MAX2(pind->birthtime, start); - pind->dietime = MIN2(pind->dietime, dietime); + pind->birthtime = std::max(pind->birthtime, start); + pind->dietime = std::min(pind->dietime, dietime); } } else { @@ -3352,7 +3352,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re if (part->draw & PART_ABS_PATH_TIME) { birthtime = MAX2(pind.birthtime, part->path_start); - dietime = MIN2(pind.dietime, part->path_end); + dietime = std::min(pind.dietime, part->path_end); } else { float tb = pind.birthtime; @@ -3674,7 +3674,7 @@ void psys_cache_edit_paths(Depsgraph *depsgraph, return; } - segments = MAX2(segments, 4); + segments = std::max(segments, 4); if (!cache || edit->totpoint != edit->totcached) { /* Clear out old and create new empty path cache. */ @@ -4934,7 +4934,7 @@ bool psys_get_particle_state(ParticleSimulationData *sim, } } - cfra = MIN2(cfra, pa->dietime); + cfra = std::min(cfra, pa->dietime); } if (sim->psys->flag & PSYS_KEYED) { diff --git a/source/blender/blenkernel/intern/particle_child.cc b/source/blender/blenkernel/intern/particle_child.cc index e4a9b5f2b72..82562ce7d9b 100644 --- a/source/blender/blenkernel/intern/particle_child.cc +++ b/source/blender/blenkernel/intern/particle_child.cc @@ -526,7 +526,7 @@ void do_kink(ParticleKey *state, sub_v3_v3v3(par_vec, state->co, state_co); length = normalize_v3(par_vec); - mul_v3_fl(par_vec, MIN2(length, amplitude / 2.0f)); + mul_v3_fl(par_vec, std::min(length, amplitude / 2.0f)); add_v3_v3v3(state_co, par_co, y_vec); add_v3_v3(state_co, z_vec); diff --git a/source/blender/blenkernel/intern/particle_distribute.cc b/source/blender/blenkernel/intern/particle_distribute.cc index 17064548bd6..bba5890c739 100644 --- a/source/blender/blenkernel/intern/particle_distribute.cc +++ b/source/blender/blenkernel/intern/particle_distribute.cc @@ -128,11 +128,11 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys) /* float errors grrr. */ size[(axis + 1) % 3] = MIN2(size[(axis + 1) % 3], res); - size[(axis + 2) % 3] = MIN2(size[(axis + 2) % 3], res); + size[(axis + 2) % 3] = std::min(size[(axis + 2) % 3], res); - size[0] = MAX2(size[0], 1); - size[1] = MAX2(size[1], 1); - size[2] = MAX2(size[2], 1); + size[0] = std::max(size[0], 1); + size[1] = std::max(size[1], 1); + size[2] = std::max(size[2], 1); /* no full offset for flat/thin objects */ min[0] += d < delta[0] ? d / 2.0f : delta[0] / 2.0f; diff --git a/source/blender/blenkernel/intern/particle_system.cc b/source/blender/blenkernel/intern/particle_system.cc index 5b323abddec..821021b49d1 100644 --- a/source/blender/blenkernel/intern/particle_system.cc +++ b/source/blender/blenkernel/intern/particle_system.cc @@ -1132,7 +1132,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, (sim->psys->pointcache->mem_cache.first)) { float dietime = psys_get_dietime_from_cache(sim->psys->pointcache, p); - pa->dietime = MIN2(pa->dietime, dietime); + pa->dietime = std::min(pa->dietime, dietime); } if (pa->time > cfra) { @@ -3003,7 +3003,7 @@ static int collision_response(ParticleSimulationData *sim, /* Convert to angular velocity. */ cross_v3_v3v3(ave, vr_tan, pce->nor); - mul_v3_fl(ave, 1.0f / MAX2(pa->size, 0.001f)); + mul_v3_fl(ave, 1.0f / std::max(pa->size, 0.001f)); /* only friction will cause change in linear & angular velocity */ interp_v3_v3v3(pa->state.ave, pa->state.ave, ave, frict); @@ -4688,8 +4688,8 @@ void psys_changed_type(Object *ob, ParticleSystem *psys) else { free_hair(ob, psys, 1); - CLAMP(part->path_start, 0.0f, MAX2(100.0f, part->end + part->lifetime)); - CLAMP(part->path_end, 0.0f, MAX2(100.0f, part->end + part->lifetime)); + CLAMP(part->path_start, 0.0f, std::max(100.0f, part->end + part->lifetime)); + CLAMP(part->path_end, 0.0f, std::max(100.0f, part->end + part->lifetime)); } psys_reset(psys, PSYS_RESET_ALL); diff --git a/source/blender/blenkernel/intern/pointcache.cc b/source/blender/blenkernel/intern/pointcache.cc index 3c5d43dd621..f98fe50b8fc 100644 --- a/source/blender/blenkernel/intern/pointcache.cc +++ b/source/blender/blenkernel/intern/pointcache.cc @@ -410,8 +410,8 @@ static void ptcache_particle_interpolate(int index, } cfra = MIN2(cfra, pa->dietime); - cfra1 = MIN2(cfra1, pa->dietime); - cfra2 = MIN2(cfra2, pa->dietime); + cfra1 = std::min(cfra1, pa->dietime); + cfra2 = std::min(cfra2, pa->dietime); if (cfra1 == cfra2) { return; @@ -2372,7 +2372,7 @@ int BKE_ptcache_read(PTCacheID *pid, float cfra, bool no_extrapolate_old) pid->cache->flag &= ~PTCACHE_FRAMES_SKIPPED; } - BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, MAX2(cfrai, pid->cache->last_exact)); + BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, std::max(cfrai, pid->cache->last_exact)); } return ret; @@ -2653,7 +2653,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, uint cfra) if (strstr(de->d_name, ext)) { /* Do we have the right extension? */ if (STREQLEN(filepath, de->d_name, len)) { /* Do we have the right prefix. */ if (mode == PTCACHE_CLEAR_ALL) { - pid->cache->last_exact = MIN2(pid->cache->startframe, 0); + pid->cache->last_exact = std::min(pid->cache->startframe, 0); BLI_path_join(path_full, sizeof(path_full), path, de->d_name); BLI_delete(path_full, false, false); } @@ -2688,7 +2688,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, uint cfra) if (mode == PTCACHE_CLEAR_ALL) { /* We want startframe if the cache starts before zero. */ - pid->cache->last_exact = MIN2(pid->cache->startframe, 0); + pid->cache->last_exact = std::min(pid->cache->startframe, 0); for (; pm; pm = pm->next) { ptcache_mem_clear(pm); } @@ -2803,7 +2803,7 @@ void BKE_ptcache_id_time( time = BKE_scene_ctime_get(scene); nexttime = BKE_scene_frame_to_ctime(scene, scene->r.cfra + 1); - *timescale = MAX2(nexttime - time, 0.0f); + *timescale = std::max(nexttime - time, 0.0f); } if (startframe && endframe) { @@ -3219,7 +3219,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker) BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0); } - startframe = MAX2(cache->last_exact, cache->startframe); + startframe = std::max(cache->last_exact, cache->startframe); if (bake) { endframe = cache->endframe; @@ -3603,8 +3603,8 @@ void BKE_ptcache_load_external(PTCacheID *pid) if (frame != -1) { if (frame) { - start = MIN2(start, frame); - end = MAX2(end, frame); + start = std::min(start, frame); + end = std::max(end, frame); } else { info = 1; @@ -3774,7 +3774,7 @@ void BKE_ptcache_invalidate(PointCache *cache) if (cache) { cache->flag &= ~PTCACHE_SIMULATION_VALID; cache->simframe = 0; - cache->last_exact = MIN2(cache->startframe, 0); + cache->last_exact = std::min(cache->startframe, 0); } } diff --git a/source/blender/blenkernel/intern/rigidbody.cc b/source/blender/blenkernel/intern/rigidbody.cc index 0aa861b5790..0300de863ef 100644 --- a/source/blender/blenkernel/intern/rigidbody.cc +++ b/source/blender/blenkernel/intern/rigidbody.cc @@ -501,7 +501,7 @@ static rbCollisionShape *rigidbody_validate_sim_shape_helper(RigidBodyWorld *rbw if (ELEM(rbo->shape, RB_SHAPE_CAPSULE, RB_SHAPE_CYLINDER, RB_SHAPE_CONE)) { /* take radius as largest x/y dimension, and height as z-dimension */ - radius = MAX2(size[0], size[1]); + radius = std::max(size[0], size[1]); height = size[2]; } else if (rbo->shape == RB_SHAPE_SPHERE) { diff --git a/source/blender/blenkernel/intern/subsurf_ccg.cc b/source/blender/blenkernel/intern/subsurf_ccg.cc index 6443890a3e6..94cbdb83924 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.cc +++ b/source/blender/blenkernel/intern/subsurf_ccg.cc @@ -94,7 +94,7 @@ static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int numLaye int normalOffset = 0; /* (subdivLevels == 0) is not allowed */ - subdivLevels = MAX2(subdivLevels, 1); + subdivLevels = std::max(subdivLevels, 1); if (prevSS) { int oldUseAging; diff --git a/source/blender/blenkernel/intern/text.cc b/source/blender/blenkernel/intern/text.cc index 9eac59c470e..e7d7b93fb20 100644 --- a/source/blender/blenkernel/intern/text.cc +++ b/source/blender/blenkernel/intern/text.cc @@ -2113,7 +2113,7 @@ static bool txt_select_unprefix(Text *text, const char *remove, const bool requi if (text->curl == text->sell) { if (changed) { - text->selc = MAX2(text->selc - indentlen, 0); + text->selc = std::max(text->selc - indentlen, 0); } break; } @@ -2123,7 +2123,7 @@ static bool txt_select_unprefix(Text *text, const char *remove, const bool requi } if (unindented_first) { - text->curc = MAX2(text->curc - indentlen, 0); + text->curc = std::max(text->curc - indentlen, 0); } while (num > 0) { diff --git a/source/blender/blenkernel/intern/unit.cc b/source/blender/blenkernel/intern/unit.cc index d69e0c83d78..71854bdf646 100644 --- a/source/blender/blenkernel/intern/unit.cc +++ b/source/blender/blenkernel/intern/unit.cc @@ -6,6 +6,7 @@ * \ingroup bke */ +#include /* For `min/max`. */ #include #include #include @@ -1673,17 +1674,17 @@ static const bUnitDef *get_preferred_display_unit_if_used(int type, PreferredUni if (units.length == USER_UNIT_ADAPTIVE) { return nullptr; } - return usys->units + MIN2(units.length, max_offset); + return usys->units + std::min(units.length, max_offset); case B_UNIT_MASS: if (units.mass == USER_UNIT_ADAPTIVE) { return nullptr; } - return usys->units + MIN2(units.mass, max_offset); + return usys->units + std::min(units.mass, max_offset); case B_UNIT_TIME: if (units.time == USER_UNIT_ADAPTIVE) { return nullptr; } - return usys->units + MIN2(units.time, max_offset); + return usys->units + std::min(units.time, max_offset); case B_UNIT_ROTATION: if (units.rotation == 0) { return usys->units + 0; @@ -1696,7 +1697,7 @@ static const bUnitDef *get_preferred_display_unit_if_used(int type, PreferredUni if (units.temperature == USER_UNIT_ADAPTIVE) { return nullptr; } - return usys->units + MIN2(units.temperature, max_offset); + return usys->units + std::min(units.temperature, max_offset); default: break; } diff --git a/source/blender/blenlib/intern/math_geom.cc b/source/blender/blenlib/intern/math_geom.cc index 2f247f429d1..d45d3f385e2 100644 --- a/source/blender/blenlib/intern/math_geom.cc +++ b/source/blender/blenlib/intern/math_geom.cc @@ -5721,7 +5721,7 @@ float form_factor_quad(const float p[3], dot4 = dot_v3v3(n, g3); result = (a1 * dot1 + a2 * dot2 + a3 * dot3 + a4 * dot4) * 0.5f / float(M_PI); - result = MAX2(result, 0.0f); + result = std::max(result, 0.0f); return result; } diff --git a/source/blender/blenlib/intern/path_util.cc b/source/blender/blenlib/intern/path_util.cc index 95cd7c6dbd7..3fadfbb895a 100644 --- a/source/blender/blenlib/intern/path_util.cc +++ b/source/blender/blenlib/intern/path_util.cc @@ -7,6 +7,7 @@ * Various string, file, list operations. */ +#include /* For `min/max`. */ #include #include #include @@ -135,7 +136,7 @@ void BLI_path_sequence_encode(char *path, { BLI_string_debug_size(path, path_maxncpy); - BLI_snprintf(path, path_maxncpy, "%s%.*d%s", head, numlen, MAX2(0, pic), tail); + BLI_snprintf(path, path_maxncpy, "%s%.*d%s", head, numlen, std::max(0, pic), tail); } /** @@ -963,7 +964,7 @@ bool BLI_path_frame(char *path, size_t path_maxncpy, int frame, int digits) if (path_frame_chars_find_range(path, &ch_sta, &ch_end)) { char frame_str[FILENAME_FRAME_CHARS_MAX + 1]; /* One for null. */ - const int ch_span = MIN2(ch_end - ch_sta, FILENAME_FRAME_CHARS_MAX); + const int ch_span = std::min(ch_end - ch_sta, FILENAME_FRAME_CHARS_MAX); SNPRINTF(frame_str, "%.*d", ch_span, frame); BLI_string_replace_range(path, path_maxncpy, ch_sta, ch_end, frame_str); return true; @@ -983,7 +984,7 @@ bool BLI_path_frame_range(char *path, size_t path_maxncpy, int sta, int end, int if (path_frame_chars_find_range(path, &ch_sta, &ch_end)) { char frame_str[(FILENAME_FRAME_CHARS_MAX * 2) + 1 + 1]; /* One for null, one for the '-' */ - const int ch_span = MIN2(ch_end - ch_sta, FILENAME_FRAME_CHARS_MAX); + const int ch_span = std::min(ch_end - ch_sta, FILENAME_FRAME_CHARS_MAX); SNPRINTF(frame_str, "%.*d-%.*d", ch_span, sta, ch_span, end); BLI_string_replace_range(path, path_maxncpy, ch_sta, ch_end, frame_str); return true; @@ -1581,7 +1582,7 @@ void BLI_path_split_dir_file(const char *filepath, const char *basename = BLI_path_basename(filepath); if (basename != filepath) { const size_t dir_size = (basename - filepath) + 1; - BLI_strncpy(dir, filepath, MIN2(dir_maxncpy, dir_size)); + BLI_strncpy(dir, filepath, std::min(dir_maxncpy, dir_size)); } else { dir[0] = '\0'; @@ -1595,7 +1596,7 @@ void BLI_path_split_dir_part(const char *filepath, char *dir, const size_t dir_m const char *basename = BLI_path_basename(filepath); if (basename != filepath) { const size_t dir_size = (basename - filepath) + 1; - BLI_strncpy(dir, filepath, MIN2(dir_maxncpy, dir_size)); + BLI_strncpy(dir, filepath, std::min(dir_maxncpy, dir_size)); } else { dir[0] = '\0'; diff --git a/source/blender/blenlib/intern/task_range.cc b/source/blender/blenlib/intern/task_range.cc index 1bc856292a0..0ff589d929c 100644 --- a/source/blender/blenlib/intern/task_range.cc +++ b/source/blender/blenlib/intern/task_range.cc @@ -105,7 +105,7 @@ void BLI_task_parallel_range(const int start, /* Multithreading. */ if (settings->use_threading && BLI_task_scheduler_num_threads() > 1) { RangeTask task(func, userdata, settings); - const size_t grainsize = MAX2(settings->min_iter_per_thread, 1); + const size_t grainsize = std::max(settings->min_iter_per_thread, 1); const tbb::blocked_range range(start, stop, grainsize); blender::lazy_threading::send_hint(); diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index 33182d74dd2..9a86ae3bdb2 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -702,7 +702,7 @@ static BHeadN *get_bhead(FileData *fd) else { /* MIN2 is only to quiet '-Warray-bounds' compiler warning. */ BLI_assert(sizeof(bhead) == sizeof(bhead4)); - memcpy(&bhead, &bhead4, MIN2(sizeof(bhead), sizeof(bhead4))); + memcpy(&bhead, &bhead4, std::min(sizeof(bhead), sizeof(bhead4))); } } else { @@ -725,7 +725,7 @@ static BHeadN *get_bhead(FileData *fd) else { /* MIN2 is only to quiet `-Warray-bounds` compiler warning. */ BLI_assert(sizeof(bhead) == sizeof(bhead8)); - memcpy(&bhead, &bhead8, MIN2(sizeof(bhead), sizeof(bhead8))); + memcpy(&bhead, &bhead8, std::min(sizeof(bhead), sizeof(bhead8))); } } else { diff --git a/source/blender/blenloader/intern/versioning_250.cc b/source/blender/blenloader/intern/versioning_250.cc index 271091c4299..98a1bc574a2 100644 --- a/source/blender/blenloader/intern/versioning_250.cc +++ b/source/blender/blenloader/intern/versioning_250.cc @@ -961,7 +961,7 @@ void blo_do_versions_250(FileData *fd, Library * /*lib*/, Main *bmain) key->refkey) { data = static_cast(key->refkey->data); - tot = MIN2(me->totvert, key->refkey->totelem); + tot = std::min(me->totvert, key->refkey->totelem); MVert *verts = (MVert *)CustomData_get_layer_for_write( &me->vert_data, CD_MVERT, me->totvert); for (a = 0; a < tot; a++, data += 3) { @@ -976,7 +976,7 @@ void blo_do_versions_250(FileData *fd, Library * /*lib*/, Main *bmain) key->refkey) { data = static_cast(key->refkey->data); - tot = MIN2(lt->pntsu * lt->pntsv * lt->pntsw, key->refkey->totelem); + tot = std::min(lt->pntsu * lt->pntsv * lt->pntsw, key->refkey->totelem); for (a = 0; a < tot; a++, data += 3) { copy_v3_v3(lt->def[a].vec, data); diff --git a/source/blender/blenloader/intern/versioning_260.cc b/source/blender/blenloader/intern/versioning_260.cc index f980070f304..53bac42b943 100644 --- a/source/blender/blenloader/intern/versioning_260.cc +++ b/source/blender/blenloader/intern/versioning_260.cc @@ -2557,7 +2557,7 @@ void blo_do_versions_260(FileData *fd, Library * /*lib*/, Main *bmain) if (!MAIN_VERSION_FILE_ATLEAST(bmain, 268, 1)) { LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) { - brush->spacing = MAX2(1, brush->spacing); + brush->spacing = std::max(1, brush->spacing); } } diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 815f91a9691..70f178ac59a 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -122,12 +122,12 @@ static void version_idproperty_move_data_int(IDPropertyUIDataInt *ui_data, IDProperty *soft_min = IDP_GetPropertyFromGroup(prop_ui_data, "soft_min"); if (soft_min != nullptr) { ui_data->soft_min = IDP_coerce_to_int_or_zero(soft_min); - ui_data->soft_min = MIN2(ui_data->soft_min, ui_data->min); + ui_data->soft_min = std::min(ui_data->soft_min, ui_data->min); } IDProperty *soft_max = IDP_GetPropertyFromGroup(prop_ui_data, "soft_max"); if (soft_max != nullptr) { ui_data->soft_max = IDP_coerce_to_int_or_zero(soft_max); - ui_data->soft_max = MAX2(ui_data->soft_max, ui_data->max); + ui_data->soft_max = std::max(ui_data->soft_max, ui_data->max); } IDProperty *step = IDP_GetPropertyFromGroup(prop_ui_data, "step"); if (step != nullptr) { @@ -163,12 +163,12 @@ static void version_idproperty_move_data_float(IDPropertyUIDataFloat *ui_data, IDProperty *soft_min = IDP_GetPropertyFromGroup(prop_ui_data, "soft_min"); if (soft_min != nullptr) { ui_data->soft_min = IDP_coerce_to_double_or_zero(soft_min); - ui_data->soft_min = MAX2(ui_data->soft_min, ui_data->min); + ui_data->soft_min = std::max(ui_data->soft_min, ui_data->min); } IDProperty *soft_max = IDP_GetPropertyFromGroup(prop_ui_data, "soft_max"); if (soft_max != nullptr) { ui_data->soft_max = IDP_coerce_to_double_or_zero(soft_max); - ui_data->soft_max = MIN2(ui_data->soft_max, ui_data->max); + ui_data->soft_max = std::min(ui_data->soft_max, ui_data->max); } IDProperty *step = IDP_GetPropertyFromGroup(prop_ui_data, "step"); if (step != nullptr) { diff --git a/source/blender/blenloader/intern/versioning_legacy.cc b/source/blender/blenloader/intern/versioning_legacy.cc index 41582ca6339..5edf95c03ea 100644 --- a/source/blender/blenloader/intern/versioning_legacy.cc +++ b/source/blender/blenloader/intern/versioning_legacy.cc @@ -2259,7 +2259,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) /* convert settings from old particle system */ /* general settings */ - part->totpart = MIN2(paf->totpart, 100000); + part->totpart = std::min(paf->totpart, 100000); part->sta = paf->sta; part->end = paf->end; part->lifetime = paf->lifetime; @@ -2503,8 +2503,8 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) * use it for the number of divisions per segment */ if (nu->pntsv > 1) { - nu->resolu = MAX2(1, int((float(nu->resolu) / float(nu->pntsu)) + 0.5f)); - nu->resolv = MAX2(1, int((float(nu->resolv) / float(nu->pntsv)) + 0.5f)); + nu->resolu = std::max(1, int((float(nu->resolu) / float(nu->pntsu)) + 0.5f)); + nu->resolv = std::max(1, int((float(nu->resolv) / float(nu->pntsv)) + 0.5f)); } } } diff --git a/source/blender/blenloader/intern/writefile.cc b/source/blender/blenloader/intern/writefile.cc index 552572a1e0c..cb54da01cb7 100644 --- a/source/blender/blenloader/intern/writefile.cc +++ b/source/blender/blenloader/intern/writefile.cc @@ -541,7 +541,7 @@ static void mywrite(WriteData *wd, const void *adr, size_t len) } do { - size_t writelen = MIN2(len, wd->buffer.chunk_size); + size_t writelen = std::min(len, wd->buffer.chunk_size); writedata_do_write(wd, adr, writelen); adr = (const char *)adr + writelen; len -= writelen; diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.cc b/source/blender/bmesh/tools/bmesh_decimate_collapse.cc index 107a2e221fd..a2538b8f6a4 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_collapse.cc +++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.cc @@ -608,10 +608,10 @@ static void bm_decim_triangulate_end(BMesh *bm, const int edges_tri_tot) /* we need to collect before merging for ngons since the loops indices will be lost */ BMEdge **edges_tri = static_cast( - MEM_mallocN(MIN2(edges_tri_tot, bm->totedge) * sizeof(*edges_tri), __func__)); + MEM_mallocN(std::min(edges_tri_tot, bm->totedge) * sizeof(*edges_tri), __func__)); STACK_DECLARE(edges_tri); - STACK_INIT(edges_tri, MIN2(edges_tri_tot, bm->totedge)); + STACK_INIT(edges_tri, std::min(edges_tri_tot, bm->totedge)); /* boundary edges */ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { diff --git a/source/blender/bmesh/tools/bmesh_region_match.cc b/source/blender/bmesh/tools/bmesh_region_match.cc index 9256d658bc1..b2b1538469b 100644 --- a/source/blender/bmesh/tools/bmesh_region_match.cc +++ b/source/blender/bmesh/tools/bmesh_region_match.cc @@ -382,7 +382,7 @@ static void bm_uuidwalk_rehash(UUIDWalk *uuidwalk) UUID_Int *uuid_store; uint i; - uint rehash_store_len_new = MAX2(BLI_ghash_len(uuidwalk->verts_uuid), + uint rehash_store_len_new = std::max(BLI_ghash_len(uuidwalk->verts_uuid), BLI_ghash_len(uuidwalk->faces_uuid)); bm_uuidwalk_rehash_reserve(uuidwalk, rehash_store_len_new); @@ -740,8 +740,8 @@ static BMFace **bm_mesh_region_match_pair( goto finally; } - bm_uuidwalk_rehash_reserve(w_src, MAX2(faces_src_region_len, verts_src_region_len)); - bm_uuidwalk_rehash_reserve(w_dst, MAX2(faces_src_region_len, verts_src_region_len)); + bm_uuidwalk_rehash_reserve(w_src, std::max(faces_src_region_len, verts_src_region_len)); + bm_uuidwalk_rehash_reserve(w_dst, std::max(faces_src_region_len, verts_src_region_len)); while (true) { bool ok = false; diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cc b/source/blender/compositor/intern/COM_ExecutionGroup.cc index 955d6f25abb..484d78949bb 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.cc +++ b/source/blender/compositor/intern/COM_ExecutionGroup.cc @@ -146,7 +146,7 @@ void ExecutionGroup::init_read_buffer_operations() if (operation->get_flags().is_read_buffer_operation) { ReadBufferOperation *read_operation = static_cast(operation); read_operations_.append(read_operation); - max_offset = MAX2(max_offset, read_operation->get_offset()); + max_offset = std::max(max_offset, read_operation->get_offset()); } } max_offset++; @@ -442,10 +442,10 @@ inline void ExecutionGroup::determine_chunk_rect(rcti *r_rect, const uint width = MIN2(uint(viewer_border_.xmax), width_); const uint height = MIN2(uint(viewer_border_.ymax), height_); BLI_rcti_init(r_rect, - MIN2(minx, width_), - MIN2(minx + chunk_size_, width), - MIN2(miny, height_), - MIN2(miny + chunk_size_, height)); + std::min(minx, width_), + std::min(minx + chunk_size_, width), + std::min(miny, height_), + std::min(miny + chunk_size_, height)); } } diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cc b/source/blender/compositor/intern/COM_ExecutionSystem.cc index e6fcb6f1a07..d2bd9b52a8a 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cc +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cc @@ -109,7 +109,7 @@ void ExecutionSystem::execute_work(const rcti &work_rect, /* Split work vertically to maximize continuous memory. */ const int work_height = BLI_rcti_size_y(&work_rect); - const int num_sub_works = MIN2(num_work_threads_, work_height); + const int num_sub_works = std::min(num_work_threads_, work_height); const int split_height = num_sub_works == 0 ? 0 : work_height / num_sub_works; int remaining_height = work_height - split_height * num_sub_works; diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cc b/source/blender/compositor/intern/COM_MemoryBuffer.cc index 6454f6315fc..54cd893ebc9 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.cc +++ b/source/blender/compositor/intern/COM_MemoryBuffer.cc @@ -409,8 +409,8 @@ void MemoryBuffer::fill_from(const MemoryBuffer &src) rcti overlap; overlap.xmin = MAX2(rect_.xmin, src.rect_.xmin); overlap.xmax = MIN2(rect_.xmax, src.rect_.xmax); - overlap.ymin = MAX2(rect_.ymin, src.rect_.ymin); - overlap.ymax = MIN2(rect_.ymax, src.rect_.ymax); + overlap.ymin = std::max(rect_.ymin, src.rect_.ymin); + overlap.ymax = std::min(rect_.ymax, src.rect_.ymax); copy_from(&src, overlap); } diff --git a/source/blender/compositor/intern/COM_NodeOperation.cc b/source/blender/compositor/intern/COM_NodeOperation.cc index 0c0543d473a..2f10cd91236 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.cc +++ b/source/blender/compositor/intern/COM_NodeOperation.cc @@ -237,10 +237,10 @@ bool NodeOperation::determine_depending_area_of_interest(rcti *input, first = false; } else { - output->xmin = MIN2(output->xmin, temp_output.xmin); - output->ymin = MIN2(output->ymin, temp_output.ymin); - output->xmax = MAX2(output->xmax, temp_output.xmax); - output->ymax = MAX2(output->ymax, temp_output.ymax); + output->xmin = std::min(output->xmin, temp_output.xmin); + output->ymin = std::min(output->ymin, temp_output.ymin); + output->xmax = std::max(output->xmax, temp_output.xmax); + output->ymax = std::max(output->ymax, temp_output.ymax); } } } diff --git a/source/blender/compositor/nodes/COM_SwitchViewNode.cc b/source/blender/compositor/nodes/COM_SwitchViewNode.cc index fe5be5ae15a..f953e76dce9 100644 --- a/source/blender/compositor/nodes/COM_SwitchViewNode.cc +++ b/source/blender/compositor/nodes/COM_SwitchViewNode.cc @@ -20,7 +20,7 @@ void SwitchViewNode::convert_to_operations(NodeConverter &converter, /* get the internal index of the socket with a matching name */ int nr = BLI_findstringindex(&bnode->inputs, view_name, offsetof(bNodeSocket, name)); - nr = MAX2(nr, 0); + nr = std::max(nr, 0); result = converter.add_input_proxy(get_input_socket(nr), false); converter.map_output_socket(get_output_socket(0), result); diff --git a/source/blender/compositor/operations/COM_BokehBlurOperation.cc b/source/blender/compositor/operations/COM_BokehBlurOperation.cc index 1df610689d9..81a960c7130 100644 --- a/source/blender/compositor/operations/COM_BokehBlurOperation.cc +++ b/source/blender/compositor/operations/COM_BokehBlurOperation.cc @@ -44,7 +44,7 @@ void BokehBlurOperation::init_data() const int width = bokeh->get_width(); const int height = bokeh->get_height(); - const float dimension = MIN2(width, height); + const float dimension = std::min(width, height); bokeh_mid_x_ = width / 2.0f; bokeh_mid_y_ = height / 2.0f; @@ -103,8 +103,8 @@ void BokehBlurOperation::execute_pixel(float output[4], int x, int y, void *data int maxy = y + pixel_size; int minx = x - pixel_size; int maxx = x + pixel_size; - miny = MAX2(miny, input_rect.ymin); - minx = MAX2(minx, input_rect.xmin); + miny = std::max(miny, input_rect.ymin); + minx = std::max(minx, input_rect.xmin); maxy = MIN2(maxy, input_rect.ymax); maxx = MIN2(maxx, input_rect.xmax); @@ -338,7 +338,7 @@ void BokehBlurOperation::update_memory_buffer_partial(MemoryBuffer *output, multiplier_accum[2] = 1.0f; multiplier_accum[3] = 1.0f; } - const int miny = MAX2(y - pixel_size, image_rect.ymin); + const int miny = std::max(y - pixel_size, image_rect.ymin); const int maxy = MIN2(y + pixel_size, image_rect.ymax); const int minx = MAX2(x - pixel_size, image_rect.xmin); const int maxx = MIN2(x + pixel_size, image_rect.xmax); diff --git a/source/blender/compositor/operations/COM_BoxMaskOperation.cc b/source/blender/compositor/operations/COM_BoxMaskOperation.cc index 5c7252c1239..d6f873bd7dc 100644 --- a/source/blender/compositor/operations/COM_BoxMaskOperation.cc +++ b/source/blender/compositor/operations/COM_BoxMaskOperation.cc @@ -53,7 +53,7 @@ void BoxMaskOperation::execute_pixel_sampled(float output[4], switch (mask_type_) { case CMP_NODE_MASKTYPE_ADD: if (inside) { - output[0] = MAX2(input_mask[0], input_value[0]); + output[0] = std::max(input_mask[0], input_value[0]); } else { output[0] = input_mask[0]; @@ -100,7 +100,7 @@ void BoxMaskOperation::update_memory_buffer_partial(MemoryBuffer *output, switch (mask_type_) { case CMP_NODE_MASKTYPE_ADD: mask_func = [](const bool is_inside, const float *mask, const float *value) { - return is_inside ? MAX2(mask[0], value[0]) : mask[0]; + return is_inside ? std::max(mask[0], value[0]) : mask[0]; }; break; case CMP_NODE_MASKTYPE_SUBTRACT: diff --git a/source/blender/compositor/operations/COM_ChannelMatteOperation.cc b/source/blender/compositor/operations/COM_ChannelMatteOperation.cc index e789cb58d9f..e6d100ffb56 100644 --- a/source/blender/compositor/operations/COM_ChannelMatteOperation.cc +++ b/source/blender/compositor/operations/COM_ChannelMatteOperation.cc @@ -83,7 +83,7 @@ void ChannelMatteOperation::execute_pixel_sampled(float output[4], input_image_program_->read_sampled(in_color, x, y, sampler); /* matte operation */ - alpha = in_color[ids_[0]] - MAX2(in_color[ids_[1]], in_color[ids_[2]]); + alpha = in_color[ids_[0]] - std::max(in_color[ids_[1]], in_color[ids_[2]]); /* flip because 0.0 is transparent, not 1.0 */ alpha = 1.0f - alpha; @@ -104,7 +104,7 @@ void ChannelMatteOperation::execute_pixel_sampled(float output[4], */ /* Don't make something that was more transparent less transparent. */ - output[0] = MIN2(alpha, in_color[3]); + output[0] = std::min(alpha, in_color[3]); } void ChannelMatteOperation::update_memory_buffer_partial(MemoryBuffer *output, diff --git a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cc b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cc index 1dbfb0e966e..29ffbff7195 100644 --- a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cc +++ b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cc @@ -54,7 +54,7 @@ void ColorBalanceLGGOperation::execute_pixel_sampled(float output[4], input_color_operation_->read_sampled(input_color, x, y, sampler); float fac = value[0]; - fac = MIN2(1.0f, fac); + fac = std::min(1.0f, fac); const float mfac = 1.0f - fac; output[0] = mfac * input_color[0] + diff --git a/source/blender/compositor/operations/COM_ColorSpillOperation.cc b/source/blender/compositor/operations/COM_ColorSpillOperation.cc index 50b5e00fbc9..d6b7fcba26e 100644 --- a/source/blender/compositor/operations/COM_ColorSpillOperation.cc +++ b/source/blender/compositor/operations/COM_ColorSpillOperation.cc @@ -78,7 +78,7 @@ void ColorSpillOperation::execute_pixel_sampled(float output[4], float input[4]; input_fac_reader_->read_sampled(fac, x, y, sampler); input_image_reader_->read_sampled(input, x, y, sampler); - float rfac = MIN2(1.0f, fac[0]); + float rfac = std::min(1.0f, fac[0]); float map; switch (spill_method_) { @@ -108,7 +108,7 @@ void ColorSpillOperation::update_memory_buffer_partial(MemoryBuffer *output, { for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { const float *color = it.in(0); - const float factor = MIN2(1.0f, *it.in(1)); + const float factor = std::min(1.0f, *it.in(1)); float map; switch (spill_method_) { diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc index fd95522db68..d6a8c4f50c6 100644 --- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc +++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cc @@ -55,7 +55,7 @@ void ConvertDepthToRadiusOperation::init_execution() dof_sp_ = minsz / ((cam_sensor / 2.0f) / cam_lens_); if (blur_post_operation_) { - blur_post_operation_->set_sigma(MIN2(aperture_ * 128.0f, max_radius_)); + blur_post_operation_->set_sigma(std::min(aperture_ * 128.0f, max_radius_)); } } diff --git a/source/blender/compositor/operations/COM_CropOperation.cc b/source/blender/compositor/operations/COM_CropOperation.cc index 18befcbb2fd..a3c7d784608 100644 --- a/source/blender/compositor/operations/COM_CropOperation.cc +++ b/source/blender/compositor/operations/COM_CropOperation.cc @@ -42,9 +42,9 @@ void CropBaseOperation::update_area() } xmax_ = MAX2(local_settings.x1, local_settings.x2); - xmin_ = MIN2(local_settings.x1, local_settings.x2); - ymax_ = MAX2(local_settings.y1, local_settings.y2); - ymin_ = MIN2(local_settings.y1, local_settings.y2); + xmin_ = std::min(local_settings.x1, local_settings.x2); + ymax_ = std::max(local_settings.y1, local_settings.y2); + ymin_ = std::min(local_settings.y1, local_settings.y2); } else { xmax_ = 0; diff --git a/source/blender/compositor/operations/COM_DespeckleOperation.cc b/source/blender/compositor/operations/COM_DespeckleOperation.cc index 13b9f8a6a6b..efe43306006 100644 --- a/source/blender/compositor/operations/COM_DespeckleOperation.cc +++ b/source/blender/compositor/operations/COM_DespeckleOperation.cc @@ -163,12 +163,12 @@ void DespeckleOperation::update_memory_buffer_partial(MemoryBuffer *output, const int last_x = get_width() - 1; const int last_y = get_height() - 1; for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { - const int x1 = MAX2(it.x - 1, 0); + const int x1 = std::max(it.x - 1, 0); const int x2 = it.x; - const int x3 = MIN2(it.x + 1, last_x); - const int y1 = MAX2(it.y - 1, 0); + const int x3 = std::min(it.x + 1, last_x); + const int y1 = std::max(it.y - 1, 0); const int y2 = it.y; - const int y3 = MIN2(it.y + 1, last_y); + const int y3 = std::min(it.y + 1, last_y); float w = 0.0f; const float *color_org = it.in(IMAGE_INPUT_INDEX); diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.cc b/source/blender/compositor/operations/COM_DilateErodeOperation.cc index fe032628651..b8a341fe068 100644 --- a/source/blender/compositor/operations/COM_DilateErodeOperation.cc +++ b/source/blender/compositor/operations/COM_DilateErodeOperation.cc @@ -25,7 +25,7 @@ void DilateErodeThresholdOperation::init_data() } else { if (inset_ * 2 > distance_) { - scope_ = MAX2(inset_ * 2 - distance_, distance_); + scope_ = std::max(inset_ * 2 - distance_, distance_); } else { scope_ = distance_; @@ -60,10 +60,10 @@ void DilateErodeThresholdOperation::execute_pixel(float output[4], int x, int y, MemoryBuffer *input_buffer = (MemoryBuffer *)data; float *buffer = input_buffer->get_buffer(); const rcti &input_rect = input_buffer->get_rect(); - const int minx = MAX2(x - scope_, input_rect.xmin); - const int miny = MAX2(y - scope_, input_rect.ymin); - const int maxx = MIN2(x + scope_, input_rect.xmax); - const int maxy = MIN2(y + scope_, input_rect.ymax); + const int minx = std::max(x - scope_, input_rect.xmin); + const int miny = std::max(y - scope_, input_rect.ymin); + const int maxx = std::min(x + scope_, input_rect.xmax); + const int maxy = std::min(y + scope_, input_rect.ymax); const int buffer_width = input_buffer->get_width(); int offset; @@ -76,7 +76,7 @@ void DilateErodeThresholdOperation::execute_pixel(float output[4], int x, int y, if (buffer[offset] < sw) { const float dx = xi - x; const float dis = dx * dx + dy * dy; - mindist = MIN2(mindist, dis); + mindist = std::min(mindist, dis); } offset++; } @@ -91,7 +91,7 @@ void DilateErodeThresholdOperation::execute_pixel(float output[4], int x, int y, if (buffer[offset] > sw) { const float dx = xi - x; const float dis = dx * dx + dy * dy; - mindist = MIN2(mindist, dis); + mindist = std::min(mindist, dis); } offset++; } @@ -192,7 +192,7 @@ static float get_min_distance(DilateErodeThresholdOperation::PixelData &p) if (compare(*elem, p.sw)) { const float dx = xi - p.x; const float dist = dx * dx + dist_y; - min_dist = MIN2(min_dist, dist); + min_dist = std::min(min_dist, dist); } elem += p.elem_stride; } @@ -218,10 +218,10 @@ void DilateErodeThresholdOperation::update_memory_buffer_partial(MemoryBuffer *o for (BuffersIterator it = output->iterate_with(inputs, area); !it.is_end(); ++it) { p.x = it.x; p.y = it.y; - p.xmin = MAX2(p.x - scope_, input_rect.xmin); - p.ymin = MAX2(p.y - scope_, input_rect.ymin); - p.xmax = MIN2(p.x + scope_, input_rect.xmax); - p.ymax = MIN2(p.y + scope_, input_rect.ymax); + p.xmin = std::max(p.x - scope_, input_rect.xmin); + p.ymin = std::max(p.y - scope_, input_rect.ymin); + p.xmax = std::min(p.x + scope_, input_rect.xmax); + p.ymax = std::min(p.y + scope_, input_rect.ymax); p.elem = it.in(0); float pixel_value; @@ -290,10 +290,10 @@ void DilateDistanceOperation::execute_pixel(float output[4], int x, int y, void MemoryBuffer *input_buffer = (MemoryBuffer *)data; float *buffer = input_buffer->get_buffer(); const rcti &input_rect = input_buffer->get_rect(); - const int minx = MAX2(x - scope_, input_rect.xmin); - const int miny = MAX2(y - scope_, input_rect.ymin); - const int maxx = MIN2(x + scope_, input_rect.xmax); - const int maxy = MIN2(y + scope_, input_rect.ymax); + const int minx = std::max(x - scope_, input_rect.xmin); + const int miny = std::max(y - scope_, input_rect.ymin); + const int maxx = std::min(x + scope_, input_rect.xmax); + const int maxy = std::min(y + scope_, input_rect.ymax); const int buffer_width = input_buffer->get_width(); int offset; @@ -306,7 +306,7 @@ void DilateDistanceOperation::execute_pixel(float output[4], int x, int y, void const float dx = xi - x; const float dis = dx * dx + dy * dy; if (dis <= mindist) { - value = MAX2(buffer[offset], value); + value = std::max(buffer[offset], value); } offset++; } @@ -395,10 +395,10 @@ struct DilateDistanceOperation::PixelData { { x = it.x; y = it.y; - xmin = MAX2(x - scope, input_rect.xmin); - ymin = MAX2(y - scope, input_rect.ymin); - xmax = MIN2(x + scope, input_rect.xmax); - ymax = MIN2(y + scope, input_rect.ymax); + xmin = std::max(x - scope, input_rect.xmin); + ymin = std::max(y - scope, input_rect.ymin); + xmax = std::min(x + scope, input_rect.xmax); + ymax = std::min(y + scope, input_rect.ymax); elem = it.in(0); } }; @@ -455,10 +455,10 @@ void ErodeDistanceOperation::execute_pixel(float output[4], int x, int y, void * MemoryBuffer *input_buffer = (MemoryBuffer *)data; float *buffer = input_buffer->get_buffer(); const rcti &input_rect = input_buffer->get_rect(); - const int minx = MAX2(x - scope_, input_rect.xmin); - const int miny = MAX2(y - scope_, input_rect.ymin); - const int maxx = MIN2(x + scope_, input_rect.xmax); - const int maxy = MIN2(y + scope_, input_rect.ymax); + const int minx = std::max(x - scope_, input_rect.xmin); + const int miny = std::max(y - scope_, input_rect.ymin); + const int maxx = std::min(x + scope_, input_rect.xmax); + const int maxy = std::min(y + scope_, input_rect.ymax); const int buffer_width = input_buffer->get_width(); int offset; @@ -471,7 +471,7 @@ void ErodeDistanceOperation::execute_pixel(float output[4], int x, int y, void * const float dx = xi - x; const float dis = dx * dx + dy * dy; if (dis <= mindist) { - value = MIN2(buffer[offset], value); + value = std::min(buffer[offset], value); } offset++; } @@ -557,10 +557,10 @@ void *DilateStepOperation::initialize_tile_data(rcti *rect) int half_window = iterations_; int window = half_window * 2 + 1; - int xmin = MAX2(0, rect->xmin - half_window); - int ymin = MAX2(0, rect->ymin - half_window); - int xmax = MIN2(width, rect->xmax + half_window); - int ymax = MIN2(height, rect->ymax + half_window); + int xmin = std::max(0, rect->xmin - half_window); + int ymin = std::max(0, rect->ymin - half_window); + int xmax = std::min(width, rect->xmax + half_window); + int ymax = std::min(height, rect->ymax + half_window); int bwidth = rect->xmax - rect->xmin; int bheight = rect->ymax - rect->ymin; @@ -575,7 +575,7 @@ void *DilateStepOperation::initialize_tile_data(rcti *rect) * single row or column of input values, padded with FLT_MAX's to * simplify the logic. */ float *temp = (float *)MEM_mallocN(sizeof(float) * (2 * window - 1), "dilate erode temp"); - float *buf = (float *)MEM_mallocN(sizeof(float) * (MAX2(bwidth, bheight) + 5 * half_window), + float *buf = (float *)MEM_mallocN(sizeof(float) * (std::max(bwidth, bheight) + 5 * half_window), "dilate erode buf"); /* The following is based on the van Herk/Gil-Werman algorithm for morphology operations. @@ -593,13 +593,13 @@ void *DilateStepOperation::initialize_tile_data(rcti *rect) temp[window - 1] = buf[start]; for (x = 1; x < window; x++) { - temp[window - 1 - x] = MAX2(temp[window - x], buf[start - x]); - temp[window - 1 + x] = MAX2(temp[window + x - 2], buf[start + x]); + temp[window - 1 - x] = std::max(temp[window - x], buf[start - x]); + temp[window - 1 + x] = std::max(temp[window + x - 2], buf[start + x]); } start = half_window + (i - 1) * window + 1; - for (x = -MIN2(0, start); x < window - MAX2(0, start + window - bwidth); x++) { - rectf[bwidth * (y - ymin) + (start + x)] = MAX2(temp[x], temp[x + window - 1]); + for (x = -std::min(0, start); x < window - std::max(0, start + window - bwidth); x++) { + rectf[bwidth * (y - ymin) + (start + x)] = std::max(temp[x], temp[x + window - 1]); } } } @@ -618,14 +618,14 @@ void *DilateStepOperation::initialize_tile_data(rcti *rect) temp[window - 1] = buf[start]; for (y = 1; y < window; y++) { - temp[window - 1 - y] = MAX2(temp[window - y], buf[start - y]); - temp[window - 1 + y] = MAX2(temp[window + y - 2], buf[start + y]); + temp[window - 1 - y] = std::max(temp[window - y], buf[start - y]); + temp[window - 1 + y] = std::max(temp[window + y - 2], buf[start + y]); } start = half_window + (i - 1) * window + 1; - for (y = -MIN2(0, start); y < window - MAX2(0, start + window - bheight); y++) { - rectf[bwidth * (y + start + (rect->ymin - ymin)) + x] = MAX2(temp[y], - temp[y + window - 1]); + for (y = -std::min(0, start); y < window - std::max(0, start + window - bheight); y++) { + rectf[bwidth * (y + start + (rect->ymin - ymin)) + x] = std::max(temp[y], + temp[y + window - 1]); } } } @@ -697,10 +697,10 @@ static void step_update_memory_buffer(MemoryBuffer *output, const int half_window = num_iterations; const int window = half_window * 2 + 1; - const int xmin = MAX2(0, area.xmin - half_window); - const int ymin = MAX2(0, area.ymin - half_window); - const int xmax = MIN2(width, area.xmax + half_window); - const int ymax = MIN2(height, area.ymax + half_window); + const int xmin = std::max(0, area.xmin - half_window); + const int ymin = std::max(0, area.ymin - half_window); + const int xmax = std::min(width, area.xmax + half_window); + const int ymax = std::min(height, area.ymax + half_window); const int bwidth = area.xmax - area.xmin; const int bheight = area.ymax - area.ymin; @@ -716,7 +716,7 @@ static void step_update_memory_buffer(MemoryBuffer *output, * single row or column of input values, padded with #limit values to * simplify the logic. */ float *temp = (float *)MEM_mallocN(sizeof(float) * (2 * window - 1), "dilate erode temp"); - float *buf = (float *)MEM_mallocN(sizeof(float) * (MAX2(bwidth, bheight) + 5 * half_window), + float *buf = (float *)MEM_mallocN(sizeof(float) * (std::max(bwidth, bheight) + 5 * half_window), "dilate erode buf"); /* The following is based on the van Herk/Gil-Werman algorithm for morphology operations. */ @@ -739,7 +739,7 @@ static void step_update_memory_buffer(MemoryBuffer *output, } start = half_window + (i - 1) * window + 1; - for (int x = -MIN2(0, start); x < window - MAX2(0, start + window - bwidth); x++) { + for (int x = -std::min(0, start); x < window - std::max(0, start + window - bwidth); x++) { result.get_value(start + x + area.xmin, y, 0) = selector(temp[x], temp[x + window - 1]); } } @@ -764,7 +764,7 @@ static void step_update_memory_buffer(MemoryBuffer *output, } start = half_window + (i - 1) * window + 1; - for (int y = -MIN2(0, start); y < window - MAX2(0, start + window - bheight); y++) { + for (int y = -std::min(0, start); y < window - std::max(0, start + window - bheight); y++) { result.get_value(x + area.xmin, y + start + area.ymin, 0) = selector(temp[y], temp[y + window - 1]); } @@ -780,7 +780,7 @@ static void step_update_memory_buffer(MemoryBuffer *output, struct Max2Selector { float operator()(float f1, float f2) const { - return MAX2(f1, f2); + return std::max(f1, f2); } }; @@ -807,10 +807,10 @@ void *ErodeStepOperation::initialize_tile_data(rcti *rect) int half_window = iterations_; int window = half_window * 2 + 1; - int xmin = MAX2(0, rect->xmin - half_window); - int ymin = MAX2(0, rect->ymin - half_window); - int xmax = MIN2(width, rect->xmax + half_window); - int ymax = MIN2(height, rect->ymax + half_window); + int xmin = std::max(0, rect->xmin - half_window); + int ymin = std::max(0, rect->ymin - half_window); + int xmax = std::min(width, rect->xmax + half_window); + int ymax = std::min(height, rect->ymax + half_window); int bwidth = rect->xmax - rect->xmin; int bheight = rect->ymax - rect->ymin; @@ -825,7 +825,7 @@ void *ErodeStepOperation::initialize_tile_data(rcti *rect) * single row or column of input values, padded with FLT_MAX's to * simplify the logic. */ float *temp = (float *)MEM_mallocN(sizeof(float) * (2 * window - 1), "dilate erode temp"); - float *buf = (float *)MEM_mallocN(sizeof(float) * (MAX2(bwidth, bheight) + 5 * half_window), + float *buf = (float *)MEM_mallocN(sizeof(float) * (std::max(bwidth, bheight) + 5 * half_window), "dilate erode buf"); /* The following is based on the van Herk/Gil-Werman algorithm for morphology operations. @@ -843,13 +843,13 @@ void *ErodeStepOperation::initialize_tile_data(rcti *rect) temp[window - 1] = buf[start]; for (x = 1; x < window; x++) { - temp[window - 1 - x] = MIN2(temp[window - x], buf[start - x]); - temp[window - 1 + x] = MIN2(temp[window + x - 2], buf[start + x]); + temp[window - 1 - x] = std::min(temp[window - x], buf[start - x]); + temp[window - 1 + x] = std::min(temp[window + x - 2], buf[start + x]); } start = half_window + (i - 1) * window + 1; - for (x = -MIN2(0, start); x < window - MAX2(0, start + window - bwidth); x++) { - rectf[bwidth * (y - ymin) + (start + x)] = MIN2(temp[x], temp[x + window - 1]); + for (x = -std::min(0, start); x < window - std::max(0, start + window - bwidth); x++) { + rectf[bwidth * (y - ymin) + (start + x)] = std::min(temp[x], temp[x + window - 1]); } } } @@ -868,14 +868,14 @@ void *ErodeStepOperation::initialize_tile_data(rcti *rect) temp[window - 1] = buf[start]; for (y = 1; y < window; y++) { - temp[window - 1 - y] = MIN2(temp[window - y], buf[start - y]); - temp[window - 1 + y] = MIN2(temp[window + y - 2], buf[start + y]); + temp[window - 1 - y] = std::min(temp[window - y], buf[start - y]); + temp[window - 1 + y] = std::min(temp[window + y - 2], buf[start + y]); } start = half_window + (i - 1) * window + 1; - for (y = -MIN2(0, start); y < window - MAX2(0, start + window - bheight); y++) { - rectf[bwidth * (y + start + (rect->ymin - ymin)) + x] = MIN2(temp[y], - temp[y + window - 1]); + for (y = -std::min(0, start); y < window - std::max(0, start + window - bheight); y++) { + rectf[bwidth * (y + start + (rect->ymin - ymin)) + x] = std::min(temp[y], + temp[y + window - 1]); } } } @@ -889,7 +889,7 @@ void *ErodeStepOperation::initialize_tile_data(rcti *rect) struct Min2Selector { float operator()(float f1, float f2) const { - return MIN2(f1, f2); + return std::min(f1, f2); } }; diff --git a/source/blender/compositor/operations/COM_EllipseMaskOperation.cc b/source/blender/compositor/operations/COM_EllipseMaskOperation.cc index 252efc50909..f11c9a69386 100644 --- a/source/blender/compositor/operations/COM_EllipseMaskOperation.cc +++ b/source/blender/compositor/operations/COM_EllipseMaskOperation.cc @@ -59,7 +59,7 @@ void EllipseMaskOperation::execute_pixel_sampled(float output[4], switch (mask_type_) { case CMP_NODE_MASKTYPE_ADD: if (inside) { - output[0] = MAX2(input_mask[0], input_value[0]); + output[0] = std::max(input_mask[0], input_value[0]); } else { output[0] = input_mask[0]; @@ -106,7 +106,7 @@ void EllipseMaskOperation::update_memory_buffer_partial(MemoryBuffer *output, switch (mask_type_) { case CMP_NODE_MASKTYPE_ADD: mask_func = [](const bool is_inside, const float *mask, const float *value) { - return is_inside ? MAX2(mask[0], value[0]) : mask[0]; + return is_inside ? std::max(mask[0], value[0]) : mask[0]; }; break; case CMP_NODE_MASKTYPE_SUBTRACT: diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cc b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cc index ed9ba75f8dc..ec87e31d5d2 100644 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cc +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cc @@ -210,7 +210,7 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, uint c (void)0 /* Intermediate buffers. */ - src_dim_max = MAX2(src_width, src_height); + src_dim_max = std::max(src_width, src_height); X = (double *)MEM_callocN(src_dim_max * sizeof(double), "IIR_gauss X buf"); Y = (double *)MEM_callocN(src_dim_max * sizeof(double), "IIR_gauss Y buf"); W = (double *)MEM_callocN(src_dim_max * sizeof(double), "IIR_gauss W buf"); @@ -424,12 +424,12 @@ void FastGaussianBlurValueOperation::update_memory_buffer_partial(MemoryBuffer * BuffersIterator it = output->iterate_with({image, iirgaus_}, area); if (overlay_ == FAST_GAUSS_OVERLAY_MIN) { for (; !it.is_end(); ++it) { - *it.out = MIN2(*it.in(0), *it.in(1)); + *it.out = std::min(*it.in(0), *it.in(1)); } } else if (overlay_ == FAST_GAUSS_OVERLAY_MAX) { for (; !it.is_end(); ++it) { - *it.out = MAX2(*it.in(0), *it.in(1)); + *it.out = std::max(*it.in(0), *it.in(1)); } } } diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cc b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cc index 995e624a2e9..3f514f69d11 100644 --- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cc +++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cc @@ -319,7 +319,7 @@ void GaussianBlurReferenceOperation::init_execution() void GaussianBlurReferenceOperation::update_gauss() { int i; - int x = MAX2(filtersizex_, filtersizey_); + int x = std::max(filtersizex_, filtersizey_); maintabs_ = (float **)MEM_mallocN(x * sizeof(float *), "gauss array"); for (i = 0; i < x; i++) { maintabs_[i] = make_gausstab(i + 1, i + 1); @@ -396,7 +396,7 @@ void GaussianBlurReferenceOperation::execute_pixel(float output[4], int x, int y void GaussianBlurReferenceOperation::deinit_execution() { int x, i; - x = MAX2(filtersizex_, filtersizey_); + x = std::max(filtersizex_, filtersizey_); for (i = 0; i < x; i++) { MEM_freeN(maintabs_[i]); } diff --git a/source/blender/compositor/operations/COM_KeyingBlurOperation.cc b/source/blender/compositor/operations/COM_KeyingBlurOperation.cc index 0314d766f6c..4f95176d3f6 100644 --- a/source/blender/compositor/operations/COM_KeyingBlurOperation.cc +++ b/source/blender/compositor/operations/COM_KeyingBlurOperation.cc @@ -33,7 +33,8 @@ void KeyingBlurOperation::execute_pixel(float output[4], int x, int y, void *dat float average = 0.0f; if (axis_ == 0) { - const int start = MAX2(0, x - size_ + 1), end = MIN2(buffer_width, x + size_); + const int start = MAX2(0, x - size_ + 1); + const int end = std::min(buffer_width, x + size_); for (int cx = start; cx < end; cx++) { int buffer_index = (y * buffer_width + cx); average += buffer[buffer_index]; @@ -41,7 +42,8 @@ void KeyingBlurOperation::execute_pixel(float output[4], int x, int y, void *dat } } else { - const int start = MAX2(0, y - size_ + 1), end = MIN2(input_buffer->get_height(), y + size_); + const int start = std::max(0, y - size_ + 1); + const int end = std::min(input_buffer->get_height(), y + size_); for (int cy = start; cy < end; cy++) { int buffer_index = (cy * buffer_width + x); average += buffer[buffer_index]; @@ -124,8 +126,8 @@ void KeyingBlurOperation::update_memory_buffer_partial(MemoryBuffer *output, for (; !it.is_end(); ++it) { const int coord = get_current_coord(); - const int start_coord = MAX2(0, coord - size_ + 1); - const int end_coord = MIN2(coord_max, coord + size_); + const int start_coord = std::max(0, coord - size_ + 1); + const int end_coord = std::min(coord_max, coord + size_); const int count = end_coord - start_coord; float sum = 0.0f; diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.cc b/source/blender/compositor/operations/COM_KeyingClipOperation.cc index b70c1b03d56..4a1b2835936 100644 --- a/source/blender/compositor/operations/COM_KeyingClipOperation.cc +++ b/source/blender/compositor/operations/COM_KeyingClipOperation.cc @@ -140,10 +140,10 @@ void KeyingClipOperation::update_memory_buffer_partial(MemoryBuffer *output, const int x = it.x; const int y = it.y; - const int start_x = MAX2(0, x - delta + 1); - const int start_y = MAX2(0, y - delta + 1); - const int end_x = MIN2(x + delta, width); - const int end_y = MIN2(y + delta, height); + const int start_x = std::max(0, x - delta + 1); + const int start_y = std::max(0, y - delta + 1); + const int end_x = std::min(x + delta, width); + const int end_y = std::min(y + delta, height); const int x_len = end_x - start_x; const int y_len = end_y - start_y; diff --git a/source/blender/compositor/operations/COM_KeyingDespillOperation.cc b/source/blender/compositor/operations/COM_KeyingDespillOperation.cc index 2e44f5d50a4..a3bc7726212 100644 --- a/source/blender/compositor/operations/COM_KeyingDespillOperation.cc +++ b/source/blender/compositor/operations/COM_KeyingDespillOperation.cc @@ -49,8 +49,8 @@ void KeyingDespillOperation::execute_pixel_sampled(float output[4], const int other_1 = (screen_primary_channel + 1) % 3; const int other_2 = (screen_primary_channel + 2) % 3; - const int min_channel = MIN2(other_1, other_2); - const int max_channel = MAX2(other_1, other_2); + const int min_channel = std::min(other_1, other_2); + const int max_channel = std::max(other_1, other_2); float average_value, amount; @@ -78,8 +78,8 @@ void KeyingDespillOperation::update_memory_buffer_partial(MemoryBuffer *output, const int other_1 = (screen_primary_channel + 1) % 3; const int other_2 = (screen_primary_channel + 2) % 3; - const int min_channel = MIN2(other_1, other_2); - const int max_channel = MAX2(other_1, other_2); + const int min_channel = std::min(other_1, other_2); + const int max_channel = std::max(other_1, other_2); const float average_value = color_balance_ * pixel_color[min_channel] + (1.0f - color_balance_) * pixel_color[max_channel]; diff --git a/source/blender/compositor/operations/COM_KeyingOperation.cc b/source/blender/compositor/operations/COM_KeyingOperation.cc index 19d099fc32c..e9eedf0cb13 100644 --- a/source/blender/compositor/operations/COM_KeyingOperation.cc +++ b/source/blender/compositor/operations/COM_KeyingOperation.cc @@ -15,8 +15,8 @@ static float get_pixel_saturation(const float pixel_color[4], const int other_1 = (primary_channel + 1) % 3; const int other_2 = (primary_channel + 2) % 3; - const int min_channel = MIN2(other_1, other_2); - const int max_channel = MAX2(other_1, other_2); + const int min_channel = std::min(other_1, other_2); + const int max_channel = std::max(other_1, other_2); const float val = screen_balance * pixel_color[min_channel] + (1.0f - screen_balance) * pixel_color[max_channel]; diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.cc b/source/blender/compositor/operations/COM_MathBaseOperation.cc index 46f989dc323..53f386dee4e 100644 --- a/source/blender/compositor/operations/COM_MathBaseOperation.cc +++ b/source/blender/compositor/operations/COM_MathBaseOperation.cc @@ -997,7 +997,7 @@ void MathCompareOperation::execute_pixel_sampled(float output[4], input_value2_operation_->read_sampled(input_value2, x, y, sampler); input_value3_operation_->read_sampled(input_value3, x, y, sampler); - output[0] = (fabsf(input_value1[0] - input_value2[0]) <= MAX2(input_value3[0], 1e-5f)) ? 1.0f : + output[0] = (fabsf(input_value1[0] - input_value2[0]) <= std::max(input_value3[0], 1e-5f)) ? 1.0f : 0.0f; clamp_if_needed(output); diff --git a/source/blender/compositor/operations/COM_RotateOperation.cc b/source/blender/compositor/operations/COM_RotateOperation.cc index 2b189fea492..aea2198da57 100644 --- a/source/blender/compositor/operations/COM_RotateOperation.cc +++ b/source/blender/compositor/operations/COM_RotateOperation.cc @@ -57,9 +57,9 @@ void RotateOperation::get_area_rotation_bounds(const rcti &area, const float y3 = center_y + (sine * dxmin + cosine * dymax); const float y4 = center_y + (sine * dxmax + cosine * dymax); const float minx = MIN2(x1, MIN2(x2, MIN2(x3, x4))); - const float maxx = MAX2(x1, MAX2(x2, MAX2(x3, x4))); - const float miny = MIN2(y1, MIN2(y2, MIN2(y3, y4))); - const float maxy = MAX2(y1, MAX2(y2, MAX2(y3, y4))); + const float maxx = std::max(x1, MAX2(x2, std::max(x3, x4))); + const float miny = MIN2(y1, std::min(y2, MIN2(y3, y4))); + const float maxy = std::max(y1, MAX2(y2, std::max(y3, y4))); r_bounds.xmin = floor(minx); r_bounds.xmax = ceil(maxx); @@ -191,10 +191,10 @@ bool RotateOperation::determine_depending_area_of_interest(rcti *input, const float y2 = center_y_ + (-sine_ * dxmax + cosine_ * dymin); const float y3 = center_y_ + (-sine_ * dxmin + cosine_ * dymax); const float y4 = center_y_ + (-sine_ * dxmax + cosine_ * dymax); - const float minx = MIN2(x1, MIN2(x2, MIN2(x3, x4))); - const float maxx = MAX2(x1, MAX2(x2, MAX2(x3, x4))); - const float miny = MIN2(y1, MIN2(y2, MIN2(y3, y4))); - const float maxy = MAX2(y1, MAX2(y2, MAX2(y3, y4))); + const float minx = std::min(x1, std::min(x2, std::min(x3, x4))); + const float maxx = std::max(x1, std::max(x2, std::max(x3, x4))); + const float miny = std::min(y1, std::min(y2, std::min(y3, y4))); + const float maxy = std::max(y1, std::max(y2, std::max(y3, y4))); new_input.xmax = ceil(maxx) + 1; new_input.xmin = floor(minx) - 1; diff --git a/source/blender/compositor/operations/COM_ScaleOperation.cc b/source/blender/compositor/operations/COM_ScaleOperation.cc index 4b24e1b4f5c..a8a5421b3ba 100644 --- a/source/blender/compositor/operations/COM_ScaleOperation.cc +++ b/source/blender/compositor/operations/COM_ScaleOperation.cc @@ -223,8 +223,8 @@ void ScaleOperation::determine_canvas(const rcti &preferred_area, rcti &r_area) const float scale_x = get_constant_scale_x(input_width); const float scale_y = get_constant_scale_y(input_height); scale_area(r_area, scale_x, scale_y); - const Size2f max_scale_size = {MAX2(input_width, max_scale_canvas_size_.x), - MAX2(input_height, max_scale_canvas_size_.y)}; + const Size2f max_scale_size = {std::max(input_width, max_scale_canvas_size_.x), + std::max(input_height, max_scale_canvas_size_.y)}; clamp_area_size_max(r_area, max_scale_size); /* Re-determine canvases of x and y constant inputs with scaled canvas as preferred. */ diff --git a/source/blender/compositor/operations/COM_TonemapOperation.cc b/source/blender/compositor/operations/COM_TonemapOperation.cc index cfeb88ab1ac..51dce9cc4d1 100644 --- a/source/blender/compositor/operations/COM_TonemapOperation.cc +++ b/source/blender/compositor/operations/COM_TonemapOperation.cc @@ -39,9 +39,9 @@ void TonemapOperation::execute_pixel(float output[4], int x, int y, void *data) output[2] /= ((db == 0.0f) ? 1.0f : db); const float igm = avg->igm; if (igm != 0.0f) { - output[0] = powf(MAX2(output[0], 0.0f), igm); + output[0] = powf(std::max(output[0], 0.0f), igm); output[1] = powf(MAX2(output[1], 0.0f), igm); - output[2] = powf(MAX2(output[2], 0.0f), igm); + output[2] = powf(std::max(output[2], 0.0f), igm); } } void PhotoreceptorTonemapOperation::execute_pixel(float output[4], int x, int y, void *data) @@ -186,8 +186,8 @@ void TonemapOperation::update_memory_buffer_started(MemoryBuffer * /*output*/, join.sum += chunk.sum; add_v3_v3(join.color_sum, chunk.color_sum); join.log_sum += chunk.log_sum; - join.max = MAX2(join.max, chunk.max); - join.min = MIN2(join.min, chunk.min); + join.max = std::max(join.max, chunk.max); + join.min = std::min(join.min, chunk.min); join.num_pixels += chunk.num_pixels; }); @@ -224,7 +224,7 @@ void TonemapOperation::update_memory_buffer_partial(MemoryBuffer *output, if (igm != 0.0f) { it.out[0] = powf(MAX2(it.out[0], 0.0f), igm); it.out[1] = powf(MAX2(it.out[1], 0.0f), igm); - it.out[2] = powf(MAX2(it.out[2], 0.0f), igm); + it.out[2] = powf(std::max(it.out[2], 0.0f), igm); } } } diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc index 7f93f529833..fbc0def4109 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc @@ -59,7 +59,7 @@ void *VariableSizeBokehBlurOperation::initialize_tile_data(rcti *rect) this->determine_depending_area_of_interest( rect, (ReadBufferOperation *)input_size_program_, &rect2); - const float max_dim = MAX2(this->get_width(), this->get_height()); + const float max_dim = std::max(this->get_width(), this->get_height()); const float scalar = do_size_scale_ ? (max_dim / 100.0f) : 1.0f; data->max_blur_scalar = int(data->size->get_max_value(rect2) * scalar); @@ -87,7 +87,7 @@ void VariableSizeBokehBlurOperation::execute_pixel(float output[4], int x, int y float multiplier_accum[4]; float color_accum[4]; - const float max_dim = MAX2(get_width(), get_height()); + const float max_dim = std::max(get_width(), get_height()); const float scalar = do_size_scale_ ? (max_dim / 100.0f) : 1.0f; int max_blur_scalar = tile_data->max_blur_scalar; @@ -105,10 +105,10 @@ void VariableSizeBokehBlurOperation::execute_pixel(float output[4], int x, int y int maxx = search[2]; int maxy = search[3]; #else - int minx = MAX2(x - max_blur_scalar, 0); - int miny = MAX2(y - max_blur_scalar, 0); - int maxx = MIN2(x + max_blur_scalar, int(get_width())); - int maxy = MIN2(y + max_blur_scalar, int(get_height())); + int minx = std::max(x - max_blur_scalar, 0); + int miny = std::max(y - max_blur_scalar, 0); + int maxx = std::min(x + max_blur_scalar, int(get_width())); + int maxy = std::min(y + max_blur_scalar, int(get_height())); #endif { input_size_buffer->read_no_check(temp_size, x, y); @@ -130,7 +130,8 @@ void VariableSizeBokehBlurOperation::execute_pixel(float output[4], int x, int y int offset_color_nx_ny = offset_value_nx_ny * COM_DATA_TYPE_COLOR_CHANNELS; for (int nx = minx; nx < maxx; nx += add_xstep_value) { if (nx != x || ny != y) { - float size = MIN2(input_size_float_buffer[offset_value_nx_ny] * scalar, size_center); + float size = std::min(input_size_float_buffer[offset_value_nx_ny] * scalar, + size_center); if (size > threshold_) { float dx = nx - x; if (size > fabsf(dx) && size > fabsf(dy)) { @@ -183,7 +184,7 @@ void VariableSizeBokehBlurOperation::execute_opencl( MemoryBuffer *size_memory_buffer = input_size_program_->get_input_memory_buffer( input_memory_buffers); - const float max_dim = MAX2(get_width(), get_height()); + const float max_dim = std::max(get_width(), get_height()); cl_float scalar = do_size_scale_ ? (max_dim / 100.0f) : 1.0f; max_blur = (cl_int)min_ff(size_memory_buffer->get_max_value() * scalar, float(max_blur_)); @@ -223,7 +224,7 @@ bool VariableSizeBokehBlurOperation::determine_depending_area_of_interest( rcti new_input; rcti bokeh_input; - const float max_dim = MAX2(get_width(), get_height()); + const float max_dim = std::max(get_width(), get_height()); const float scalar = do_size_scale_ ? (max_dim / 100.0f) : 1.0f; int max_blur_scalar = max_blur_ * scalar; @@ -269,7 +270,7 @@ void VariableSizeBokehBlurOperation::get_area_of_interest(const int input_idx, switch (input_idx) { case IMAGE_INPUT_INDEX: case SIZE_INPUT_INDEX: { - const float max_dim = MAX2(get_width(), get_height()); + const float max_dim = std::max(get_width(), get_height()); const float scalar = do_size_scale_ ? (max_dim / 100.0f) : 1.0f; const int max_blur_scalar = max_blur_ * scalar; r_input_area.xmax = output_area.xmax + max_blur_scalar + 2; @@ -326,10 +327,10 @@ static void blur_pixel(int x, int y, PixelData &p) const int maxx = search[2]; const int maxy = search[3]; #else - const int minx = MAX2(x - p.max_blur_scalar, 0); - const int miny = MAX2(y - p.max_blur_scalar, 0); - const int maxx = MIN2(x + p.max_blur_scalar, p.image_width); - const int maxy = MIN2(y + p.max_blur_scalar, p.image_height); + const int minx = std::max(x - p.max_blur_scalar, 0); + const int miny = std::max(y - p.max_blur_scalar, 0); + const int maxx = std::min(x + p.max_blur_scalar, p.image_width); + const int maxy = std::min(y + p.max_blur_scalar, p.image_height); #endif const int color_row_stride = p.image_input->row_stride * p.step; @@ -350,7 +351,7 @@ static void blur_pixel(int x, int y, PixelData &p) if (nx == x && ny == y) { continue; } - const float size = MIN2(size_elem[0] * p.scalar, p.size_center); + const float size = std::min(size_elem[0] * p.scalar, p.size_center); if (size <= p.threshold) { continue; } @@ -391,7 +392,7 @@ void VariableSizeBokehBlurOperation::update_memory_buffer_partial(MemoryBuffer * BLI_rcti_isect(&scalar_area, &p.size_input->get_rect(), &scalar_area); const float max_size = p.size_input->get_max_value(scalar_area); - const float max_dim = MAX2(this->get_width(), this->get_height()); + const float max_dim = std::max(this->get_width(), this->get_height()); p.scalar = do_size_scale_ ? (max_dim / 100.0f) : 1.0f; p.max_blur_scalar = int(max_size * p.scalar); CLAMP(p.max_blur_scalar, 1, max_blur_); @@ -452,10 +453,10 @@ void *InverseSearchRadiusOperation::initialize_tile_data(rcti *rect) for (x = rect->xmin; x < rect->xmax; x++) { int rx = x * DIVIDER; int ry = y * DIVIDER; - buffer[offset] = MAX2(rx - max_blur_, 0); - buffer[offset + 1] = MAX2(ry - max_blur_, 0); - buffer[offset + 2] = MIN2(rx + DIVIDER + max_blur_, width); - buffer[offset + 3] = MIN2(ry + DIVIDER + max_blur_, height); + buffer[offset] = std::max(rx - max_blur_, 0); + buffer[offset + 1] = std::max(ry - max_blur_, 0); + buffer[offset + 2] = std::min(rx + DIVIDER + max_blur_, width); + buffer[offset + 3] = std::min(ry + DIVIDER + max_blur_, height); offset += 4; } } @@ -482,10 +483,10 @@ void *InverseSearchRadiusOperation::initialize_tile_data(rcti *rect) for (int x2 = x - impact_radius; x2 < x + impact_radius; x2++) { for (int y2 = y - impact_radius; y2 < y + impact_radius; y2++) { data->read(temp, x2, y2); - temp[0] = MIN2(temp[0], maxx); - temp[1] = MIN2(temp[1], maxy); - temp[2] = MAX2(temp[2], maxx); - temp[3] = MAX2(temp[3], maxy); + temp[0] = std::min(temp[0], maxx); + temp[1] = std::min(temp[1], maxy); + temp[2] = std::max(temp[2], maxx); + temp[3] = std::max(temp[3], maxy); data->write_pixel(x2, y2, temp); } } diff --git a/source/blender/compositor/operations/COM_ZCombineOperation.cc b/source/blender/compositor/operations/COM_ZCombineOperation.cc index d926d919a75..4ccd178407a 100644 --- a/source/blender/compositor/operations/COM_ZCombineOperation.cc +++ b/source/blender/compositor/operations/COM_ZCombineOperation.cc @@ -84,7 +84,7 @@ void ZCombineAlphaOperation::execute_pixel_sampled(float output[4], output[0] = fac * color1[0] + ifac * color2[0]; output[1] = fac * color1[1] + ifac * color2[1]; output[2] = fac * color1[2] + ifac * color2[2]; - output[3] = MAX2(color1[3], color2[3]); + output[3] = std::max(color1[3], color2[3]); } void ZCombineAlphaOperation::update_memory_buffer_partial(MemoryBuffer *output, @@ -109,7 +109,7 @@ void ZCombineAlphaOperation::update_memory_buffer_partial(MemoryBuffer *output, it.out[0] = fac * color1[0] + ifac * color2[0]; it.out[1] = fac * color1[1] + ifac * color2[1]; it.out[2] = fac * color1[2] + ifac * color2[2]; - it.out[3] = MAX2(color1[3], color2[3]); + it.out[3] = std::max(color1[3], color2[3]); } } @@ -188,7 +188,7 @@ void ZCombineMaskAlphaOperation::execute_pixel_sampled(float output[4], output[0] = color1[0] * mfac + color2[0] * fac; output[1] = color1[1] * mfac + color2[1] * fac; output[2] = color1[2] * mfac + color2[2] * fac; - output[3] = MAX2(color1[3], color2[3]); + output[3] = std::max(color1[3], color2[3]); } void ZCombineMaskAlphaOperation::update_memory_buffer_partial(MemoryBuffer *output, @@ -205,7 +205,7 @@ void ZCombineMaskAlphaOperation::update_memory_buffer_partial(MemoryBuffer *outp it.out[0] = color1[0] * mfac + color2[0] * fac; it.out[1] = color1[1] * mfac + color2[1] * fac; it.out[2] = color1[2] * mfac + color2[2] * fac; - it.out[3] = MAX2(color1[3], color2[3]); + it.out[3] = std::max(color1[3], color2[3]); } } diff --git a/source/blender/compositor/realtime_compositor/intern/scheduler.cc b/source/blender/compositor/realtime_compositor/intern/scheduler.cc index 1138f47c9a5..759a9f5c023 100644 --- a/source/blender/compositor/realtime_compositor/intern/scheduler.cc +++ b/source/blender/compositor/realtime_compositor/intern/scheduler.cc @@ -263,8 +263,8 @@ static NeededBuffers compute_number_of_needed_buffers(Stack &output_nodes /* Compute the heuristic estimation of the number of needed intermediate buffers to compute * this node and all of its dependencies. This is computing the aforementioned equation * "max(n + m, d)". */ - const int total_buffers = MAX2(number_of_input_buffers + number_of_output_buffers, - buffers_needed_by_dependencies); + const int total_buffers = std::max(number_of_input_buffers + number_of_output_buffers, + buffers_needed_by_dependencies); needed_buffers.add(node, total_buffers); } diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc index 5b26381babc..86f42dfb379 100644 --- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc +++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc @@ -171,7 +171,7 @@ bool deg_iterator_duplis_step(DEGObjectIterData *data) temp_dupli_object->base_local_view_bits = dupli_parent->base_local_view_bits; temp_dupli_object->runtime.local_collections_bits = dupli_parent->runtime.local_collections_bits; - temp_dupli_object->dt = MIN2(temp_dupli_object->dt, dupli_parent->dt); + temp_dupli_object->dt = std::min(temp_dupli_object->dt, dupli_parent->dt); copy_v4_v4(temp_dupli_object->color, dupli_parent->color); temp_dupli_object->runtime.select_id = dupli_parent->runtime.select_id; if (dob->ob->data != dob->ob_data) { diff --git a/source/blender/draw/engines/eevee/eevee_bloom.cc b/source/blender/draw/engines/eevee/eevee_bloom.cc index 8e3026de8c7..6c50879f2ad 100644 --- a/source/blender/draw/engines/eevee/eevee_bloom.cc +++ b/source/blender/draw/engines/eevee/eevee_bloom.cc @@ -59,7 +59,7 @@ int EEVEE_bloom_init(EEVEE_ViewLayerData * /*sldata*/, EEVEE_Data *vedata) effects->bloom_clamp = scene_eval->eevee.bloom_clamp; /* determine the iteration count */ - const float minDim = float(MIN2(blitsize[0], blitsize[1])); + const float minDim = float(std::min(blitsize[0], blitsize[1])); const float maxIter = (radius - 8.0f) + log(minDim) / log(2); const int maxIterInt = effects->bloom_iteration_len = int(maxIter); @@ -79,8 +79,8 @@ int EEVEE_bloom_init(EEVEE_ViewLayerData * /*sldata*/, EEVEE_Data *vedata) texsize[0] /= 2; texsize[1] /= 2; - texsize[0] = MAX2(texsize[0], 2); - texsize[1] = MAX2(texsize[1], 2); + texsize[0] = std::max(texsize[0], 2); + texsize[1] = std::max(texsize[1], 2); effects->downsamp_texel_size[i][0] = 1.0f / float(texsize[0]); effects->downsamp_texel_size[i][1] = 1.0f / float(texsize[1]); @@ -101,8 +101,8 @@ int EEVEE_bloom_init(EEVEE_ViewLayerData * /*sldata*/, EEVEE_Data *vedata) texsize[0] /= 2; texsize[1] /= 2; - texsize[0] = MAX2(texsize[0], 2); - texsize[1] = MAX2(texsize[1], 2); + texsize[0] = std::max(texsize[0], 2); + texsize[1] = std::max(texsize[1], 2); eGPUTextureUsage upsample_usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT | diff --git a/source/blender/draw/engines/eevee/eevee_engine.cc b/source/blender/draw/engines/eevee/eevee_engine.cc index 3e80a5d9a56..a53f18681e4 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.cc +++ b/source/blender/draw/engines/eevee/eevee_engine.cc @@ -216,7 +216,7 @@ static void eevee_draw_scene(void *vedata) if (DRW_state_is_image_render()) { const DRWContextState *draw_ctx = DRW_context_state_get(); const Scene *scene = draw_ctx->scene; - loop_len = MAX2(1, scene->eevee.taa_samples); + loop_len = std::max(1, scene->eevee.taa_samples); } if (stl->effects->bypass_drawing) { diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.cc b/source/blender/draw/engines/eevee/eevee_lightcache.cc index 94942f165fa..1ff2ef4a686 100644 --- a/source/blender/draw/engines/eevee/eevee_lightcache.cc +++ b/source/blender/draw/engines/eevee/eevee_lightcache.cc @@ -276,7 +276,7 @@ static void irradiance_pool_size_get(int visibility_size, int total_samples, int (visibility_size / IRRADIANCE_SAMPLE_SIZE_Y); /* The irradiance itself take one layer, hence the +1 */ - int layer_count = MIN2(irr_per_vis + 1, IRRADIANCE_MAX_POOL_LAYER); + int layer_count = std::min(irr_per_vis + 1, IRRADIANCE_MAX_POOL_LAYER); int texel_count = int(ceilf(float(total_samples) / float(layer_count - 1))); r_size[0] = visibility_size * diff --git a/source/blender/draw/intern/draw_curves.cc b/source/blender/draw/intern/draw_curves.cc index 3a59b3d5898..3af02fb3982 100644 --- a/source/blender/draw/intern/draw_curves.cc +++ b/source/blender/draw/intern/draw_curves.cc @@ -158,7 +158,7 @@ static void drw_curves_cache_update_compute(CurvesEvalCache *cache, const int max_strands_per_call = GPU_max_work_group_count(0); int strands_start = 0; while (strands_start < strands_len) { - int batch_strands_len = MIN2(strands_len - strands_start, max_strands_per_call); + int batch_strands_len = std::min(strands_len - strands_start, max_strands_per_call); DRWShadingGroup *subgroup = DRW_shgroup_create_sub(shgrp); DRW_shgroup_uniform_int_copy(subgroup, "hairStrandOffset", strands_start); DRW_shgroup_call_compute(subgroup, batch_strands_len, cache->final[subdiv].strands_res, 1); diff --git a/source/blender/draw/intern/draw_hair.cc b/source/blender/draw/intern/draw_hair.cc index 729dfb97931..1c4c6ff0e90 100644 --- a/source/blender/draw/intern/draw_hair.cc +++ b/source/blender/draw/intern/draw_hair.cc @@ -130,7 +130,7 @@ static void drw_hair_particle_cache_update_compute(ParticleHairCache *cache, con const int max_strands_per_call = GPU_max_work_group_count(0); int strands_start = 0; while (strands_start < strands_len) { - int batch_strands_len = MIN2(strands_len - strands_start, max_strands_per_call); + int batch_strands_len = std::min(strands_len - strands_start, max_strands_per_call); DRWShadingGroup *subgroup = DRW_shgroup_create_sub(shgrp); DRW_shgroup_uniform_int_copy(subgroup, "hairStrandOffset", strands_start); DRW_shgroup_call_compute(subgroup, batch_strands_len, cache->final[subdiv].strands_res, 1); diff --git a/source/blender/draw/intern/draw_manager_profiling.cc b/source/blender/draw/intern/draw_manager_profiling.cc index fbed558e0e1..cb4cc3bdce9 100644 --- a/source/blender/draw/intern/draw_manager_profiling.cc +++ b/source/blender/draw/intern/draw_manager_profiling.cc @@ -337,8 +337,8 @@ void DRW_stats_draw(const rcti *rect) } /* avoid very long number */ - time_ms = MIN2(time_ms, 999.0); - time_percent = MIN2(time_percent, 100.0); + time_ms = std::min(time_ms, 999.0); + time_percent = std::min(time_percent, 100.0); SNPRINTF(stat_string, "%s", timer->name); draw_stat(rect, 0 + timer->lvl, v, stat_string, sizeof(stat_string)); diff --git a/source/blender/editors/animation/anim_channels_defines.cc b/source/blender/editors/animation/anim_channels_defines.cc index 632551e9158..1cda66c76c6 100644 --- a/source/blender/editors/animation/anim_channels_defines.cc +++ b/source/blender/editors/animation/anim_channels_defines.cc @@ -5593,7 +5593,7 @@ void ANIM_channel_draw_widgets(const bContext *C, "", offset + margin_x, rect->ymin, - MAX2(width, RENAME_TEXT_MIN_WIDTH), + std::max(width, RENAME_TEXT_MIN_WIDTH), channel_height, &ptr, RNA_property_identifier(prop), diff --git a/source/blender/editors/animation/drivers.cc b/source/blender/editors/animation/drivers.cc index 5712c7ebaaf..7e733025d10 100644 --- a/source/blender/editors/animation/drivers.cc +++ b/source/blender/editors/animation/drivers.cc @@ -330,7 +330,7 @@ int ANIM_add_driver_with_target(ReportList *reports, int dst_len = RNA_property_array_check(prop) ? RNA_property_array_length(&ptr, prop) : 1; int src_len = RNA_property_array_check(prop) ? RNA_property_array_length(&ptr2, prop2) : 1; - int len = MIN2(dst_len, src_len); + int len = std::min(dst_len, src_len); for (int i = 0; i < len; i++) { done_tot += add_driver_with_target(reports, diff --git a/source/blender/editors/animation/keyframes_keylist.cc b/source/blender/editors/animation/keyframes_keylist.cc index 001b2ad2cd7..4d2d13cd159 100644 --- a/source/blender/editors/animation/keyframes_keylist.cc +++ b/source/blender/editors/animation/keyframes_keylist.cc @@ -493,7 +493,7 @@ static void nupdate_ak_bezt(ActKeyColumn *ak, void *data) } /* For interpolation type, select the highest value (enum is sorted). */ - ak->handle_type = MAX2((eKeyframeHandleDrawOpts)ak->handle_type, bezt_handle_type(bezt)); + ak->handle_type = std::max((eKeyframeHandleDrawOpts)ak->handle_type, bezt_handle_type(bezt)); /* For extremes, detect when combining different states. */ const char new_extreme = bezt_extreme_type(chain); diff --git a/source/blender/editors/animation/time_scrub_ui.cc b/source/blender/editors/animation/time_scrub_ui.cc index f50ca97a1ba..d151d0d34ce 100644 --- a/source/blender/editors/animation/time_scrub_ui.cc +++ b/source/blender/editors/animation/time_scrub_ui.cc @@ -84,7 +84,7 @@ static void draw_current_frame(const Scene *scene, char frame_str[64]; get_current_time_str(scene, display_seconds, current_frame, frame_str, sizeof(frame_str)); float text_width = UI_fontstyle_string_width(fstyle, frame_str); - float box_width = MAX2(text_width + 8 * UI_SCALE_FAC, 24 * UI_SCALE_FAC); + float box_width = std::max(text_width + 8 * UI_SCALE_FAC, 24 * UI_SCALE_FAC); float box_padding = 3 * UI_SCALE_FAC; const int line_outline = max_ii(1, round_fl_to_int(1 * UI_SCALE_FAC)); diff --git a/source/blender/editors/gpencil_legacy/gpencil_merge.cc b/source/blender/editors/gpencil_legacy/gpencil_merge.cc index 16ac2029c8e..61654bfd217 100644 --- a/source/blender/editors/gpencil_legacy/gpencil_merge.cc +++ b/source/blender/editors/gpencil_legacy/gpencil_merge.cc @@ -119,7 +119,7 @@ static bGPDstroke *gpencil_prepare_stroke(bContext *C, wmOperator *op, int totpo gpl, scene->r.cfra, eGP_GetFrame_Mode(add_frame_mode)); /* stroke */ - bGPDstroke *gps = BKE_gpencil_stroke_new(MAX2(ob->actcol - 1, 0), totpoints, brush->size); + bGPDstroke *gps = BKE_gpencil_stroke_new(std::max(ob->actcol - 1, 0), totpoints, brush->size); gps->flag |= GP_STROKE_SELECT; BKE_gpencil_stroke_select_index_set(gpd, gps); diff --git a/source/blender/editors/gpencil_legacy/gpencil_paint.cc b/source/blender/editors/gpencil_legacy/gpencil_paint.cc index 5bbb9fc8068..53e15293165 100644 --- a/source/blender/editors/gpencil_legacy/gpencil_paint.cc +++ b/source/blender/editors/gpencil_legacy/gpencil_paint.cc @@ -828,7 +828,7 @@ static short gpencil_stroke_addpoint(tGPsdata *p, /* color strength */ if (brush_settings->flag & GP_BRUSH_USE_STRENGTH_PRESSURE) { pt->strength *= BKE_curvemapping_evaluateF(brush_settings->curve_strength, 0, pressure); - CLAMP(pt->strength, MIN2(GPENCIL_STRENGTH_MIN, brush_settings->draw_strength), 1.0f); + CLAMP(pt->strength, std::min(GPENCIL_STRENGTH_MIN, brush_settings->draw_strength), 1.0f); } /* Set vertex colors for buffer. */ @@ -1090,7 +1090,7 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p) /* copy pressure and time */ pt->pressure = ptc->pressure; pt->strength = ptc->strength; - CLAMP(pt->strength, MIN2(GPENCIL_STRENGTH_MIN, brush_settings->draw_strength), 1.0f); + CLAMP(pt->strength, std::min(GPENCIL_STRENGTH_MIN, brush_settings->draw_strength), 1.0f); copy_v4_v4(pt->vert_color, ptc->vert_color); pt->time = ptc->time; /* Apply the vertex color to point. */ @@ -1124,7 +1124,7 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p) /* copy pressure and time */ pt->pressure = ptc->pressure; pt->strength = ptc->strength; - CLAMP(pt->strength, MIN2(GPENCIL_STRENGTH_MIN, brush_settings->draw_strength), 1.0f); + CLAMP(pt->strength, std::min(GPENCIL_STRENGTH_MIN, brush_settings->draw_strength), 1.0f); pt->time = ptc->time; /* Apply the vertex color to point. */ ED_gpencil_point_vertex_color_set(ts, brush, pt, ptc); @@ -1256,7 +1256,7 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p) /* copy pressure and time */ pt->pressure = ptc->pressure; pt->strength = ptc->strength; - CLAMP(pt->strength, MIN2(GPENCIL_STRENGTH_MIN, brush_settings->draw_strength), 1.0f); + CLAMP(pt->strength, std::min(GPENCIL_STRENGTH_MIN, brush_settings->draw_strength), 1.0f); copy_v4_v4(pt->vert_color, ptc->vert_color); pt->time = ptc->time; pt->uv_fac = ptc->uv_fac; diff --git a/source/blender/editors/gpencil_legacy/gpencil_utils.cc b/source/blender/editors/gpencil_legacy/gpencil_utils.cc index 26bb1e261fa..94328d66699 100644 --- a/source/blender/editors/gpencil_legacy/gpencil_utils.cc +++ b/source/blender/editors/gpencil_legacy/gpencil_utils.cc @@ -1774,7 +1774,7 @@ float ED_gpencil_cursor_radius(bContext *C, int x, int y) float brush_size = float(brush->size); bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd); if (gpl != nullptr) { - brush_size = MAX2(1.0f, brush_size + gpl->line_change); + brush_size = std::max(1.0f, brush_size + gpl->line_change); } /* Convert the 3D offset distance to a brush radius. */ diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc index 2d24d22e10f..95c974e300f 100644 --- a/source/blender/editors/interface/interface.cc +++ b/source/blender/editors/interface/interface.cc @@ -540,8 +540,8 @@ static void ui_block_bounds_calc_popup( const int height = BLI_rctf_size_y(&block->rect); /* avoid divide by zero below, caused by calling with no UI, but better not crash */ - oldwidth = oldwidth > 0 ? oldwidth : MAX2(1, width); - oldheight = oldheight > 0 ? oldheight : MAX2(1, height); + oldwidth = oldwidth > 0 ? oldwidth : std::max(1, width); + oldheight = oldheight > 0 ? oldheight : std::max(1, height); /* offset block based on mouse position, user offset is scaled * along in case we resized the block in ui_block_bounds_calc_text */ @@ -2934,7 +2934,7 @@ void ui_but_string_get_ex(uiBut *but, BLI_snprintf(str, str_maxncpy, "%.*f", prec, value); } else { - BLI_snprintf(str, str_maxncpy, "%.*f", MAX2(0, prec - 2), value * 100); + BLI_snprintf(str, str_maxncpy, "%.*f", std::max(0, prec - 2), value * 100); } } else { @@ -3758,7 +3758,7 @@ static void ui_but_build_drawstr_float(uiBut *but, double value) STR_CONCATF(but->drawstr, slen, "%.*f", precision, value); } else { - STR_CONCATF(but->drawstr, slen, "%.*f%%", MAX2(0, precision - 2), value * 100); + STR_CONCATF(but->drawstr, slen, "%.*f%%", std::max(0, precision - 2), value * 100); } } else if (ui_but_is_unit(but)) { diff --git a/source/blender/editors/interface/interface_draw.cc b/source/blender/editors/interface/interface_draw.cc index c470f47c61a..5ac023b8125 100644 --- a/source/blender/editors/interface/interface_draw.cc +++ b/source/blender/editors/interface/interface_draw.cc @@ -1121,10 +1121,10 @@ static void ui_draw_colorband_handle(uint shdr_pos, GPU_blend(GPU_BLEND_ALPHA); /* Allow the lines to decrease as we get really small. */ - float line_width = MAX2(MIN2(U.pixelsize / 5.0f * fabs(half_width - 4.0f), U.pixelsize), 0.5f); + float line_width = std::max(std::min(U.pixelsize / 5.0f * fabs(half_width - 4.0f), U.pixelsize), 0.5f); /* Make things transparent as we get tiny. */ - uchar alpha = MIN2(int(fabs(half_width - 2.0f) * 50.0f), 255); + uchar alpha = std::min(int(fabs(half_width - 2.0f) * 50.0f), 255); immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR); diff --git a/source/blender/editors/interface/interface_icons.cc b/source/blender/editors/interface/interface_icons.cc index 4c8f63eaed8..fed3a8f0d91 100644 --- a/source/blender/editors/interface/interface_icons.cc +++ b/source/blender/editors/interface/interface_icons.cc @@ -797,10 +797,10 @@ static ImBuf *create_mono_icon_with_border(ImBuf *buf, /* blur the alpha channel and store it in blurred_alpha_buffer */ const int blur_size = 2 / resolution_divider; for (int bx = 0; bx < icon_width; bx++) { - const int asx = MAX2(bx - blur_size, 0); + const int asx = std::max(bx - blur_size, 0); const int aex = MIN2(bx + blur_size + 1, icon_width); for (int by = 0; by < icon_height; by++) { - const int asy = MAX2(by - blur_size, 0); + const int asy = std::max(by - blur_size, 0); const int aey = MIN2(by + blur_size + 1, icon_height); /* blur alpha channel */ @@ -827,7 +827,7 @@ static ImBuf *create_mono_icon_with_border(ImBuf *buf, const int offset_write = (sy + by) * buf->x + (sx + bx); const float blurred_alpha = blurred_alpha_buffer[blurred_alpha_offset]; const float border_srgb[4] = { - 0, 0, 0, MIN2(1.0f, blurred_alpha * border_sharpness) * border_intensity}; + 0, 0, 0, std::min(1.0f, blurred_alpha * border_sharpness) * border_intensity}; const uint color_read = buf_rect[offset_write]; const uchar *orig_color = (uchar *)&color_read; diff --git a/source/blender/editors/interface/interface_layout.cc b/source/blender/editors/interface/interface_layout.cc index c7e11106fbb..3a1c38c4fb9 100644 --- a/source/blender/editors/interface/interface_layout.cc +++ b/source/blender/editors/interface/interface_layout.cc @@ -2818,7 +2818,7 @@ uiBut *ui_but_add_search(uiBut *but, search_but->rnasearchprop = searchprop; } - but->hardmax = MAX2(but->hardmax, 256.0f); + but->hardmax = std::max(but->hardmax, 256.0f); but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT; if (RNA_property_is_unlink(prop)) { but->flag |= UI_BUT_VALUE_CLEAR; @@ -3773,7 +3773,7 @@ static void ui_litem_estimate_row(uiLayout *litem) min_size_flag = min_size_flag && (item->flag & UI_ITEM_FIXED_SIZE); litem->w += itemw; - litem->h = MAX2(itemh, litem->h); + litem->h = std::max(itemh, litem->h); if (item->next) { litem->w += litem->space; @@ -3787,7 +3787,7 @@ static void ui_litem_estimate_row(uiLayout *litem) static int ui_litem_min_width(int itemw) { - return MIN2(2 * UI_UNIT_X, itemw); + return std::min(2 * UI_UNIT_X, itemw); } static void ui_litem_layout_row(uiLayout *litem) @@ -3954,7 +3954,7 @@ static void ui_litem_estimate_column(uiLayout *litem, bool is_box) min_size_flag = min_size_flag && (item->flag & UI_ITEM_FIXED_SIZE); - litem->w = MAX2(litem->w, itemw); + litem->w = std::max(litem->w, itemw); litem->h += itemh; if (item->next && (!is_box || item != litem->items.first)) { @@ -4692,8 +4692,8 @@ static void ui_litem_estimate_absolute(uiLayout *litem) minx = min_ii(minx, itemx); miny = min_ii(miny, itemy); - litem->w = MAX2(litem->w, itemx + itemw); - litem->h = MAX2(litem->h, itemy + itemh); + litem->w = std::max(litem->w, itemx + itemw); + litem->h = std::max(litem->h, itemy + itemh); } litem->w -= minx; @@ -4783,7 +4783,7 @@ static void ui_litem_layout_split(uiLayout *litem) const int w = (litem->w - (tot - 1) * litem->space); int colw = w * percentage; - colw = MAX2(colw, 0); + colw = std::max(colw, 0); LISTBASE_FOREACH (uiItem *, item, &litem->items) { int itemh; @@ -4796,7 +4796,7 @@ static void ui_litem_layout_split(uiLayout *litem) const float width = extra_pixel + (w - int(w * percentage)) / (float(tot) - 1); extra_pixel = width - int(width); colw = int(width); - colw = MAX2(colw, 0); + colw = std::max(colw, 0); x += litem->space; } @@ -4818,8 +4818,8 @@ static void ui_litem_estimate_overlap(uiLayout *litem) int itemw, itemh; ui_item_size(item, &itemw, &itemh); - litem->w = MAX2(itemw, litem->w); - litem->h = MAX2(itemh, litem->h); + litem->w = std::max(itemw, litem->w); + litem->h = std::max(itemh, litem->h); } } @@ -4834,7 +4834,7 @@ static void ui_litem_layout_overlap(uiLayout *litem) ui_item_size(item, &itemw, &itemh); ui_item_position(item, x, y - itemh, litem->w, itemh); - litem->h = MAX2(litem->h, itemh); + litem->h = std::max(litem->h, itemh); } litem->x = x; diff --git a/source/blender/editors/interface/interface_region_popover.cc b/source/blender/editors/interface/interface_region_popover.cc index 98625513e3d..00edbde2fb9 100644 --- a/source/blender/editors/interface/interface_region_popover.cc +++ b/source/blender/editors/interface/interface_region_popover.cc @@ -255,7 +255,7 @@ uiPopupBlockHandle *ui_popover_panel_create( const int ui_units_x = (panel_type->ui_units_x == 0) ? UI_POPOVER_WIDTH_UNITS : panel_type->ui_units_x; /* Scale width by changes to Text Style point size. */ - const int text_points_max = MAX2(style->widget.points, style->widgetlabel.points); + const int text_points_max = std::max(style->widget.points, style->widgetlabel.points); pup->ui_size_x = ui_units_x * U.widget_unit * (text_points_max / float(UI_DEFAULT_TEXT_POINTS)); } diff --git a/source/blender/editors/interface/interface_style.cc b/source/blender/editors/interface/interface_style.cc index c7a602e7380..5b0be9f2abc 100644 --- a/source/blender/editors/interface/interface_style.cc +++ b/source/blender/editors/interface/interface_style.cc @@ -179,8 +179,8 @@ void UI_fontstyle_draw_ex(const uiFontStyle *fs, xofs = BLI_rcti_size_x(rect) - BLF_width(fs->uifont_id, str, str_len); } - yofs = MAX2(0, yofs); - xofs = MAX2(0, xofs); + yofs = std::max(0, yofs); + xofs = std::max(0, xofs); BLF_clipping(fs->uifont_id, rect->xmin, rect->ymin, rect->xmax, rect->ymax); BLF_position(fs->uifont_id, rect->xmin + xofs, rect->ymin + yofs, 0.0f); diff --git a/source/blender/editors/interface/interface_templates.cc b/source/blender/editors/interface/interface_templates.cc index 16717b611eb..1144df8028a 100644 --- a/source/blender/editors/interface/interface_templates.cc +++ b/source/blender/editors/interface/interface_templates.cc @@ -3713,7 +3713,7 @@ static void colorband_buttons_layout(uiLayout *layout, UI_UNIT_Y, &coba->cur, 0.0, - float(MAX2(0, coba->tot - 1)), + float(std::max(0, coba->tot - 1)), 0, 0, TIP_("Choose active color stop")); @@ -3740,7 +3740,7 @@ static void colorband_buttons_layout(uiLayout *layout, UI_UNIT_Y, &coba->cur, 0.0, - float(MAX2(0, coba->tot - 1)), + float(std::max(0, coba->tot - 1)), 0, 0, TIP_("Choose active color stop")); @@ -5840,7 +5840,7 @@ void uiTemplatePalette(uiLayout *layout, PointerRNA *ptr, const char *propname, PropertyRNA *prop = RNA_struct_find_property(ptr, propname); uiBut *but = nullptr; - const int cols_per_row = MAX2(uiLayoutGetWidth(layout) / UI_UNIT_X, 1); + const int cols_per_row = std::max(uiLayoutGetWidth(layout) / UI_UNIT_X, 1); if (!prop) { RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); diff --git a/source/blender/editors/interface/interface_widgets.cc b/source/blender/editors/interface/interface_widgets.cc index 99640f5cf14..334cfcad7dc 100644 --- a/source/blender/editors/interface/interface_widgets.cc +++ b/source/blender/editors/interface/interface_widgets.cc @@ -1327,7 +1327,7 @@ static void widget_draw_preview(BIFIconID icon, float alpha, const rcti *rect) const int w = BLI_rcti_size_x(rect); const int h = BLI_rcti_size_y(rect); - const int size = MIN2(w, h) - PREVIEW_PAD * 2; + const int size = std::min(w, h) - PREVIEW_PAD * 2; if (size > 0) { const int x = rect->xmin + w / 2 - size / 2; @@ -3741,7 +3741,7 @@ static void widget_progress_type_bar(uiButProgress *but_progress, float w = factor * BLI_rcti_size_x(&rect_prog); /* Ensure minimum size. */ - w = MAX2(w, ofs); + w = std::max(w, ofs); rect_bar.xmax = rect_bar.xmin + w; diff --git a/source/blender/editors/object/object_gpencil_modifier.cc b/source/blender/editors/object/object_gpencil_modifier.cc index 244beea8983..6b648cc9fb5 100644 --- a/source/blender/editors/object/object_gpencil_modifier.cc +++ b/source/blender/editors/object/object_gpencil_modifier.cc @@ -1056,7 +1056,7 @@ static int time_segment_remove_exec(bContext *C, wmOperator *op) MEM_freeN(gpmd->segments); gpmd->segments = new_segments; - gpmd->segment_active_index = MAX2(gpmd->segment_active_index - 1, 0); + gpmd->segment_active_index = std::max(gpmd->segment_active_index - 1, 0); } gpmd->segments_len--; @@ -1300,7 +1300,7 @@ static int dash_segment_remove_exec(bContext *C, wmOperator *op) MEM_freeN(dmd->segments); dmd->segments = new_segments; - dmd->segment_active_index = MAX2(dmd->segment_active_index - 1, 0); + dmd->segment_active_index = std::max(dmd->segment_active_index - 1, 0); } dmd->segments_len--; diff --git a/source/blender/editors/screen/screen_draw.cc b/source/blender/editors/screen/screen_draw.cc index af9fc9b4be6..e0d13a3a8a7 100644 --- a/source/blender/editors/screen/screen_draw.cc +++ b/source/blender/editors/screen/screen_draw.cc @@ -226,14 +226,14 @@ void screen_draw_join_highlight(ScrArea *sa1, ScrArea *sa2) /* Rect of the combined areas. */ const bool vertical = SCREEN_DIR_IS_VERTICAL(dir); rctf combined{}; - combined.xmin = vertical ? MAX2(sa1->totrct.xmin, sa2->totrct.xmin) : - MIN2(sa1->totrct.xmin, sa2->totrct.xmin); - combined.xmax = vertical ? MIN2(sa1->totrct.xmax, sa2->totrct.xmax) : - MAX2(sa1->totrct.xmax, sa2->totrct.xmax); - combined.ymin = vertical ? MIN2(sa1->totrct.ymin, sa2->totrct.ymin) : - MAX2(sa1->totrct.ymin, sa2->totrct.ymin); - combined.ymax = vertical ? MAX2(sa1->totrct.ymax, sa2->totrct.ymax) : - MIN2(sa1->totrct.ymax, sa2->totrct.ymax); + combined.xmin = vertical ? std::max(sa1->totrct.xmin, sa2->totrct.xmin) : + std::min(sa1->totrct.xmin, sa2->totrct.xmin); + combined.xmax = vertical ? std::min(sa1->totrct.xmax, sa2->totrct.xmax) : + std::max(sa1->totrct.xmax, sa2->totrct.xmax); + combined.ymin = vertical ? std::min(sa1->totrct.ymin, sa2->totrct.ymin) : + std::max(sa1->totrct.ymin, sa2->totrct.ymin); + combined.ymax = vertical ? std::max(sa1->totrct.ymax, sa2->totrct.ymax) : + std::min(sa1->totrct.ymax, sa2->totrct.ymax); uint pos_id = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -243,18 +243,18 @@ void screen_draw_join_highlight(ScrArea *sa1, ScrArea *sa2) /* Highlight source (sa1) within combined area. */ immUniformColor4fv(blender::float4{1.0f, 1.0f, 1.0f, 0.10f}); immRectf(pos_id, - MAX2(sa1->totrct.xmin, combined.xmin), - MAX2(sa1->totrct.ymin, combined.ymin), - MIN2(sa1->totrct.xmax, combined.xmax), - MIN2(sa1->totrct.ymax, combined.ymax)); + std::max(float(sa1->totrct.xmin), combined.xmin), + std::max(float(sa1->totrct.ymin), combined.ymin), + std::min(float(sa1->totrct.xmax), combined.xmax), + std::min(float(sa1->totrct.ymax), combined.ymax)); /* Highlight destination (sa2) within combined area. */ immUniformColor4fv(blender::float4{0.0f, 0.0f, 0.0f, 0.25f}); immRectf(pos_id, - MAX2(sa2->totrct.xmin, combined.xmin), - MAX2(sa2->totrct.ymin, combined.ymin), - MIN2(sa2->totrct.xmax, combined.xmax), - MIN2(sa2->totrct.ymax, combined.ymax)); + std::max(float(sa2->totrct.xmin), combined.xmin), + std::max(float(sa2->totrct.ymin), combined.ymin), + std::min(float(sa2->totrct.xmax), combined.xmax), + std::min(float(sa2->totrct.ymax), combined.ymax)); int offset1; int offset2; diff --git a/source/blender/editors/screen/screen_edit.cc b/source/blender/editors/screen/screen_edit.cc index fab0ca57336..9c71265b0a4 100644 --- a/source/blender/editors/screen/screen_edit.cc +++ b/source/blender/editors/screen/screen_edit.cc @@ -281,8 +281,8 @@ eScreenDir area_getorientation(ScrArea *sa_a, ScrArea *sa_b) short bottom_b = sa_b->v1->vec.y; /* How much these areas share a common edge. */ - short overlapx = MIN2(right_a, right_b) - MAX2(left_a, left_b); - short overlapy = MIN2(top_a, top_b) - MAX2(bottom_a, bottom_b); + short overlapx = std::min(right_a, right_b) - std::max(left_a, left_b); + short overlapy = std::min(top_a, top_b) - std::max(bottom_a, bottom_b); /* Minimum overlap required. */ const short minx = MIN3(AREAJOINTOLERANCEX, right_a - left_a, right_b - left_b); @@ -381,8 +381,8 @@ static bool screen_areas_can_align(bScreen *screen, ScrArea *sa1, ScrArea *sa2, /* Areas that are _smaller_ than minimum sizes, sharing an edge to be moved. See #100772. */ if (SCREEN_DIR_IS_VERTICAL(dir)) { - const short xmin = MIN2(sa1->v1->vec.x, sa2->v1->vec.x); - const short xmax = MAX2(sa1->v3->vec.x, sa2->v3->vec.x); + const short xmin = std::min(sa1->v1->vec.x, sa2->v1->vec.x); + const short xmax = std::max(sa1->v3->vec.x, sa2->v3->vec.x); LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { if (ELEM(area, sa1, sa2)) { continue; @@ -396,8 +396,8 @@ static bool screen_areas_can_align(bScreen *screen, ScrArea *sa1, ScrArea *sa2, } } else { - const short ymin = MIN2(sa1->v1->vec.y, sa2->v1->vec.y); - const short ymax = MAX2(sa1->v3->vec.y, sa2->v3->vec.y); + const short ymin = std::min(sa1->v1->vec.y, sa2->v1->vec.y); + const short ymax = std::max(sa1->v3->vec.y, sa2->v3->vec.y); LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { if (ELEM(area, sa1, sa2)) { continue; @@ -581,7 +581,7 @@ bool screen_area_close(bContext *C, bScreen *screen, ScrArea *area) const int ar_length = vertical ? (neighbor->v3->vec.x - neighbor->v1->vec.x) : (neighbor->v3->vec.y - neighbor->v1->vec.y); /* Calculate the ratio of the lengths of the shared edges. */ - float alignment = MIN2(area_length, ar_length) / float(MAX2(area_length, ar_length)); + float alignment = std::min(area_length, ar_length) / float(std::max(area_length, ar_length)); if (alignment > best_alignment) { best_alignment = alignment; sa2 = neighbor; diff --git a/source/blender/editors/screen/screen_geometry.cc b/source/blender/editors/screen/screen_geometry.cc index cdef6ec1a5c..712d9efa671 100644 --- a/source/blender/editors/screen/screen_geometry.cc +++ b/source/blender/editors/screen/screen_geometry.cc @@ -85,7 +85,7 @@ ScrEdge *screen_geom_area_map_find_active_scredge(const ScrAreaMap *area_map, if ((se->v1->vec.y > bounds_rect->ymin) && (se->v1->vec.y < (bounds_rect->ymax - 1))) { short min, max; min = MIN2(se->v1->vec.x, se->v2->vec.x); - max = MAX2(se->v1->vec.x, se->v2->vec.x); + max = std::max(se->v1->vec.x, se->v2->vec.x); if (abs(my - se->v1->vec.y) <= safety && mx >= min && mx <= max) { return se; @@ -96,7 +96,7 @@ ScrEdge *screen_geom_area_map_find_active_scredge(const ScrAreaMap *area_map, if ((se->v1->vec.x > bounds_rect->xmin) && (se->v1->vec.x < (bounds_rect->xmax - 1))) { short min, max; min = MIN2(se->v1->vec.y, se->v2->vec.y); - max = MAX2(se->v1->vec.y, se->v2->vec.y); + max = std::max(se->v1->vec.y, se->v2->vec.y); if (abs(mx - se->v1->vec.x) <= safety && my >= min && my <= max) { return se; diff --git a/source/blender/editors/sculpt_paint/paint_weight.cc b/source/blender/editors/sculpt_paint/paint_weight.cc index 9c8cc8e3a97..4445af648f1 100644 --- a/source/blender/editors/sculpt_paint/paint_weight.cc +++ b/source/blender/editors/sculpt_paint/paint_weight.cc @@ -220,10 +220,10 @@ static float wpaint_blend(const VPaint *wp, static float wpaint_clamp_monotonic(float oldval, float curval, float newval) { if (newval < oldval) { - return MIN2(newval, curval); + return std::min(newval, curval); } if (newval > oldval) { - return MAX2(newval, curval); + return std::max(newval, curval); } return newval; } diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.cc b/source/blender/editors/sculpt_paint/sculpt_pose.cc index f5266fc5037..892d54f5dc5 100644 --- a/source/blender/editors/sculpt_paint/sculpt_pose.cc +++ b/source/blender/editors/sculpt_paint/sculpt_pose.cc @@ -220,7 +220,7 @@ static void pose_brush_grow_factor_task(Object *ob, /* Grow the factor. */ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.vertex, ni) { float vmask_f = prev_mask[ni.index]; - max = MAX2(vmask_f, max); + max = std::max(vmask_f, max); } SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); diff --git a/source/blender/editors/space_action/action_draw.cc b/source/blender/editors/space_action/action_draw.cc index 124d5facc36..90a9627d5c6 100644 --- a/source/blender/editors/space_action/action_draw.cc +++ b/source/blender/editors/space_action/action_draw.cc @@ -280,7 +280,7 @@ static void draw_backdrops(bAnimContext *ac, ListBase &anim_data, View2D *v2d, u immRectf(pos, ac->scene->r.sfra, ymin, ac->scene->r.efra, ymax); /* Color overlay outside the start/end frame range get a more transparent overlay. */ - immUniformColor3ubvAlpha(color, MIN2(255, color[3] / 2)); + immUniformColor3ubvAlpha(color, std::min(255, color[3] / 2)); immRectf(pos, v2d->cur.xmin, ymin, ac->scene->r.sfra, ymax); immRectf(pos, ac->scene->r.efra, ymin, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymax); } @@ -299,7 +299,7 @@ static void draw_backdrops(bAnimContext *ac, ListBase &anim_data, View2D *v2d, u immRectf(pos, ac->scene->r.sfra, ymin, ac->scene->r.efra, ymax); /* Color overlay outside the start/end frame range get a more transparent overlay. */ - immUniformColor3ubvAlpha(color, MIN2(255, color[3] / 2)); + immUniformColor3ubvAlpha(color, std::min(255, color[3] / 2)); immRectf(pos, v2d->cur.xmin, ymin, ac->scene->r.sfra, ymax); immRectf(pos, ac->scene->r.efra, ymin, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymax); } diff --git a/source/blender/editors/space_clip/tracking_ops_track.cc b/source/blender/editors/space_clip/tracking_ops_track.cc index 75f57f57de7..29b78c253a6 100644 --- a/source/blender/editors/space_clip/tracking_ops_track.cc +++ b/source/blender/editors/space_clip/tracking_ops_track.cc @@ -153,10 +153,10 @@ static bool track_markers_initjob(bContext *C, TrackMarkersJob *tmj, bool backwa /* Limit frames to be tracked by user setting. */ if (frames_limit) { if (backwards) { - tmj->efra = MAX2(tmj->efra, tmj->sfra - frames_limit); + tmj->efra = std::max(tmj->efra, tmj->sfra - frames_limit); } else { - tmj->efra = MIN2(tmj->efra, tmj->sfra + frames_limit); + tmj->efra = std::min(tmj->efra, tmj->sfra + frames_limit); } } diff --git a/source/blender/editors/space_file/file_draw.cc b/source/blender/editors/space_file/file_draw.cc index 3d93b535245..ff350b48602 100644 --- a/source/blender/editors/space_file/file_draw.cc +++ b/source/blender/editors/space_file/file_draw.cc @@ -925,7 +925,7 @@ void file_draw_list(const bContext *C, ARegion *region) bool do_drag; uchar text_col[4]; const bool draw_columnheader = (params->display == FILE_VERTICALDISPLAY); - const float thumb_icon_aspect = MIN2(64.0f / float(params->thumbnail_size), 1.0f); + const float thumb_icon_aspect = std::min(64.0f / float(params->thumbnail_size), 1.0f); numfiles = filelist_files_ensure(files); diff --git a/source/blender/editors/space_file/filelist.cc b/source/blender/editors/space_file/filelist.cc index 3d2d471dd5a..21de331c44b 100644 --- a/source/blender/editors/space_file/filelist.cc +++ b/source/blender/editors/space_file/filelist.cc @@ -4131,7 +4131,7 @@ static void filelist_readjob_update(void *flrjv) /* if no new_entries_num, this is NOP */ BLI_movelisttolist(&fl_intern->entries, &new_entries); - flrj->filelist->filelist.entries_num = MAX2(entries_num, 0) + new_entries_num; + flrj->filelist->filelist.entries_num = std::max(entries_num, 0) + new_entries_num; } static void filelist_readjob_endjob(void *flrjv) diff --git a/source/blender/editors/space_file/filesel.cc b/source/blender/editors/space_file/filesel.cc index 8ddd88c5af0..7f96f4dd4aa 100644 --- a/source/blender/editors/space_file/filesel.cc +++ b/source/blender/editors/space_file/filesel.cc @@ -1086,7 +1086,7 @@ void ED_fileselect_init_layout(SpaceFile *sfile, ARegion *region) (layout->tile_h + 2 * layout->tile_border_y); file_attribute_columns_init(params, layout); - layout->rows = MAX2(rowcount, numfiles); + layout->rows = std::max(rowcount, numfiles); BLI_assert(layout->rows != 0); layout->height = sfile->layout->rows * (layout->tile_h + 2 * layout->tile_border_y) + layout->tile_border_y * 2 + layout->offset_top; diff --git a/source/blender/editors/space_info/textview.cc b/source/blender/editors/space_info/textview.cc index 5680b36aec1..34e3b09fcb9 100644 --- a/source/blender/editors/space_info/textview.cc +++ b/source/blender/editors/space_info/textview.cc @@ -99,13 +99,13 @@ static int textview_wrap_offsets( int i, end; /* Offset as unicode code-point. */ int j; /* Offset as bytes. */ const int tab_columns = TVC_TAB_COLUMNS; - const int column_width_max = MAX2(tab_columns, BLI_UTF8_WIDTH_MAX); + const int column_width_max = std::max(tab_columns, BLI_UTF8_WIDTH_MAX); *r_lines = 1; *r_offsets = static_cast( MEM_callocN(sizeof(**r_offsets) * - (str_len * column_width_max / MAX2(1, width - (column_width_max - 1)) + 1), + (str_len * column_width_max / std::max(1, width - (column_width_max - 1)) + 1), __func__)); (*r_offsets)[0] = 0; @@ -158,7 +158,7 @@ static bool textview_draw_string(TextViewDrawState *tds, /* Wrap. */ if (tot_lines > 1) { int iofs = int(float(y_next - tds->mval[1]) / tds->lheight); - ofs += offsets[MIN2(iofs, tot_lines - 1)]; + ofs += offsets[std::min(iofs, tot_lines - 1)]; } /* Last part. */ diff --git a/source/blender/editors/space_outliner/outliner_draw.cc b/source/blender/editors/space_outliner/outliner_draw.cc index 458b0d3d831..57b6a21dbc4 100644 --- a/source/blender/editors/space_outliner/outliner_draw.cc +++ b/source/blender/editors/space_outliner/outliner_draw.cc @@ -3214,7 +3214,7 @@ static void outliner_draw_iconrow(bContext *C, if ((merged->tree_element[index] == nullptr) || (active > merged->active[index])) { merged->tree_element[index] = te; } - merged->active[index] = MAX2(active, merged->active[index]); + merged->active[index] = std::max(active, merged->active[index]); } } diff --git a/source/blender/editors/space_text/text_draw.cc b/source/blender/editors/space_text/text_draw.cc index d0353e6ba69..0c9cc2dab29 100644 --- a/source/blender/editors/space_text/text_draw.cc +++ b/source/blender/editors/space_text/text_draw.cc @@ -821,7 +821,7 @@ int text_get_visible_lines(const SpaceText *st, ARegion *region, const char *str while (chars--) { if (i + columns - start > max) { lines++; - start = MIN2(end, i); + start = std::min(end, i); end += max; } else if (ELEM(ch, ' ', '-')) { @@ -927,7 +927,7 @@ static void calc_text_rcts(SpaceText *st, ARegion *region, rcti *scroll, rcti *b sell_off = text_get_span_wrap( st, region, static_cast(st->text->lines.first), st->text->sell); lhlstart = MIN2(curl_off, sell_off); - lhlend = MAX2(curl_off, sell_off); + lhlend = std::max(curl_off, sell_off); if (ltexth > 0) { hlstart = (lhlstart * pix_available) / ltexth; @@ -1085,7 +1085,7 @@ static void draw_suggestion_list(const SpaceText *st, const TextDrawContext *tdc boxh = SUGG_LIST_SIZE * lheight + 8; if (x + boxw > region->winx) { - x = MAX2(0, region->winx - boxw); + x = std::max(0, region->winx - boxw); } /* not needed but stands out nicer */ diff --git a/source/blender/editors/space_view3d/view3d_draw.cc b/source/blender/editors/space_view3d/view3d_draw.cc index a379a113ab7..d82cb16c13b 100644 --- a/source/blender/editors/space_view3d/view3d_draw.cc +++ b/source/blender/editors/space_view3d/view3d_draw.cc @@ -177,7 +177,7 @@ void ED_view3d_update_viewmat(Depsgraph *depsgraph, len_sc = float(max_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect))); } else { - len_sc = float(MAX2(region->winx, region->winy)); + len_sc = float(std::max(region->winx, region->winy)); } rv3d->pixsize = len_px / len_sc; diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.cc b/source/blender/editors/space_view3d/view3d_gizmo_ruler.cc index b37045a46d8..c8c6321933e 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.cc +++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.cc @@ -963,7 +963,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) ((len < (numstr_size[0] + bg_margin + bg_margin)) && (fabs(rot_90_vec[0]) < 0.5f))) { /* Super short, or quite short and also shallow angle. Position below line. */ - posit[1] = MIN2(co_ss[0][1], co_ss[2][1]) - numstr_size[1] - bg_margin - bg_margin; + posit[1] = std::min(co_ss[0][1], co_ss[2][1]) - numstr_size[1] - bg_margin - bg_margin; } else if (fabs(rot_90_vec[0]) < 0.2f) { /* Very shallow angle. Shift down by text height. */ diff --git a/source/blender/editors/transform/transform.cc b/source/blender/editors/transform/transform.cc index afaa51c98ab..d1aa543f64c 100644 --- a/source/blender/editors/transform/transform.cc +++ b/source/blender/editors/transform/transform.cc @@ -1533,7 +1533,7 @@ static void drawAutoKeyWarning(TransInfo *t, ARegion *region) offset = U.gizmo_size_navigate_v3d; break; case USER_MINI_AXIS_TYPE_MINIMAL: - offset = U.rvisize * MIN2((U.pixelsize / U.scale_factor), 1.0f) * 2.5f; + offset = U.rvisize * std::min((U.pixelsize / U.scale_factor), 1.0f) * 2.5f; break; case USER_MINI_AXIS_TYPE_NONE: offset = U.rvisize; diff --git a/source/blender/editors/transform/transform_convert_mesh.cc b/source/blender/editors/transform/transform_convert_mesh.cc index 4f356774dd1..aecefe6938e 100644 --- a/source/blender/editors/transform/transform_convert_mesh.cc +++ b/source/blender/editors/transform/transform_convert_mesh.cc @@ -1964,10 +1964,10 @@ static void mesh_partial_update(TransInfo *t, /* Promote the partial update types based on the previous state * so the values that no longer modified are reset before being left as-is. * Needed for translation which can toggle snap-to-normal during transform. */ - const enum ePartialType partial_for_looptri = MAX2(partial_state->for_looptri, - partial_state_prev->for_looptri); - const enum ePartialType partial_for_normals = MAX2(partial_state->for_normals, - partial_state_prev->for_normals); + const enum ePartialType partial_for_looptri = std::max(partial_state->for_looptri, + partial_state_prev->for_looptri); + const enum ePartialType partial_for_normals = std::max(partial_state->for_normals, + partial_state_prev->for_normals); if ((partial_for_looptri == PARTIAL_TYPE_ALL) && (partial_for_normals == PARTIAL_TYPE_ALL) && (em->bm->totvert == em->bm->totvertsel)) diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.cc b/source/blender/editors/uvedit/uvedit_smart_stitch.cc index 9e38cb3f5b7..756b8207832 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.cc +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.cc @@ -2580,7 +2580,7 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event) case WHEELDOWNMOUSE: if ((event->val == KM_PRESS) && (event->modifier & KM_ALT)) { ssc->limit_dist -= 0.01f; - ssc->limit_dist = MAX2(0.01f, ssc->limit_dist); + ssc->limit_dist = std::max(0.01f, ssc->limit_dist); if (!stitch_process_data(ssc, active_state, scene, false)) { stitch_cancel(C, op); return OPERATOR_CANCELLED; diff --git a/source/blender/gpencil_modifiers_legacy/intern/MOD_gpencil_legacy_build.cc b/source/blender/gpencil_modifiers_legacy/intern/MOD_gpencil_legacy_build.cc index 16988f0a31b..31f4f5dc983 100644 --- a/source/blender/gpencil_modifiers_legacy/intern/MOD_gpencil_legacy_build.cc +++ b/source/blender/gpencil_modifiers_legacy/intern/MOD_gpencil_legacy_build.cc @@ -6,6 +6,7 @@ * \ingroup modifiers */ +#include /* For `min/max`. */ #include #include #include @@ -358,7 +359,7 @@ static void build_sequential(Object *ob, float curgps_delay = fabs(cell->gps->inittime - (cell - 1)->gps->inittime) - last_pointtime; if (0 < curgps_delay) { - sumtime += MIN2(curgps_delay, GP_BUILD_MAXGAP); + sumtime += std::min(curgps_delay, GP_BUILD_MAXGAP); } } } @@ -634,7 +635,7 @@ static void build_concurrent(BuildGpencilModifierData *mmd, case GP_BUILD_TIMEALIGN_START: /* all start on frame 1 */ { /* Scale fac to fit relative_len */ - const float scaled_fac = use_fac / MAX2(relative_len, PSEUDOINVERSE_EPSILON); + const float scaled_fac = use_fac / std::max(relative_len, PSEUDOINVERSE_EPSILON); if (reverse) { points_num = int(roundf((1.0f - scaled_fac) * gps->totpoints)); @@ -651,7 +652,8 @@ static void build_concurrent(BuildGpencilModifierData *mmd, */ const float start_fac = 1.0f - relative_len; - const float scaled_fac = (use_fac - start_fac) / MAX2(relative_len, PSEUDOINVERSE_EPSILON); + const float scaled_fac = (use_fac - start_fac) / + std::max(relative_len, PSEUDOINVERSE_EPSILON); if (reverse) { points_num = int(roundf((1.0f - scaled_fac) * gps->totpoints)); diff --git a/source/blender/gpencil_modifiers_legacy/intern/MOD_gpencil_legacy_lineart.cc b/source/blender/gpencil_modifiers_legacy/intern/MOD_gpencil_legacy_lineart.cc index a57283cf6f6..25620d44fda 100644 --- a/source/blender/gpencil_modifiers_legacy/intern/MOD_gpencil_legacy_lineart.cc +++ b/source/blender/gpencil_modifiers_legacy/intern/MOD_gpencil_legacy_lineart.cc @@ -545,7 +545,7 @@ static bool anything_showing_through(PointerRNA *ptr) const int level_start = RNA_int_get(ptr, "level_start"); const int level_end = RNA_int_get(ptr, "level_end"); if (use_multiple_levels) { - return (MAX2(level_start, level_end) > 0); + return (std::max(level_start, level_end) > 0); } return (level_start > 0); } diff --git a/source/blender/gpencil_modifiers_legacy/intern/lineart/lineart_chain.cc b/source/blender/gpencil_modifiers_legacy/intern/lineart/lineart_chain.cc index 8b224ad0a0e..a631e2b03f5 100644 --- a/source/blender/gpencil_modifiers_legacy/intern/lineart/lineart_chain.cc +++ b/source/blender/gpencil_modifiers_legacy/intern/lineart/lineart_chain.cc @@ -14,6 +14,7 @@ #include "lineart_intern.h" +#include /* For `min/max`. */ #include #define LRT_OTHER_VERT(e, vt) ((vt) == (e)->v1 ? (e)->v2 : ((vt) == (e)->v2 ? (e)->v1 : nullptr)) @@ -1380,7 +1381,7 @@ void MOD_lineart_chain_offset_towards_camera(LineartData *ld, float dist, bool u sub_v3_v3v3(dir, cam, eci->gpos); float len_lim = dot_v3v3(view, dir) - ld->conf.near_clip; normalize_v3_v3(view_clamp, view); - mul_v3_fl(view_clamp, MIN2(dist, len_lim)); + mul_v3_fl(view_clamp, std::min(dist, len_lim)); add_v3_v3(eci->gpos, view_clamp); } } diff --git a/source/blender/gpencil_modifiers_legacy/intern/lineart/lineart_cpu.cc b/source/blender/gpencil_modifiers_legacy/intern/lineart/lineart_cpu.cc index 903e654630a..fb4bb3936c4 100644 --- a/source/blender/gpencil_modifiers_legacy/intern/lineart/lineart_cpu.cc +++ b/source/blender/gpencil_modifiers_legacy/intern/lineart/lineart_cpu.cc @@ -57,6 +57,8 @@ #include "lineart_intern.h" +#include /* For `min/max`. */ + struct LineartIsecSingle { double v1[3], v2[3]; LineartTriangle *tri1, *tri2; @@ -443,7 +445,7 @@ static int lineart_occlusion_make_task_info(LineartData *ld, LineartRenderTaskIn else { rti->pending_edges.array = &ld->pending_edges.array[starting_index]; int remaining = ld->pending_edges.next - starting_index; - rti->pending_edges.max = MIN2(remaining, LRT_THREAD_EDGE_COUNT); + rti->pending_edges.max = std::min(remaining, LRT_THREAD_EDGE_COUNT); res = 1; } @@ -3070,7 +3072,7 @@ static bool lineart_triangle_edge_image_space_occlusion(const LineartTriangle *t return true; } if (dot_1f >= 0 && dot_2f <= 0 && (dot_v1 || dot_v2)) { - *from = MAX2(cut, cross_ratios[cross_v1]); + *from = std::max(cut, cross_ratios[cross_v1]); *to = MIN2(1, cross_ratios[cross_v2]); if (*from >= *to) { return false; @@ -3079,7 +3081,7 @@ static bool lineart_triangle_edge_image_space_occlusion(const LineartTriangle *t } if (dot_1f <= 0 && dot_2f >= 0 && (dot_v1 || dot_v2)) { *from = MAX2(0, cross_ratios[cross_v1]); - *to = MIN2(cut, cross_ratios[cross_v2]); + *to = std::min(cut, cross_ratios[cross_v2]); if (*from >= *to) { return false; } @@ -4064,7 +4066,8 @@ static bool lineart_bounding_area_edge_intersect(LineartData * /*fb*/, double c1, c; if (((converted[0] = ba->l) > MAX2(l[0], r[0])) || ((converted[1] = ba->r) < MIN2(l[0], r[0])) || - ((converted[2] = ba->b) > MAX2(l[1], r[1])) || ((converted[3] = ba->u) < MIN2(l[1], r[1]))) + ((converted[2] = ba->b) > MAX2(l[1], r[1])) || + ((converted[3] = ba->u) < std::min(l[1], r[1]))) { return false; } @@ -4444,9 +4447,9 @@ static bool lineart_get_edge_bounding_areas( } b[0] = MIN2(e->v1->fbcoord[0], e->v2->fbcoord[0]); - b[1] = MAX2(e->v1->fbcoord[0], e->v2->fbcoord[0]); + b[1] = std::max(e->v1->fbcoord[0], e->v2->fbcoord[0]); b[2] = MIN2(e->v1->fbcoord[1], e->v2->fbcoord[1]); - b[3] = MAX2(e->v1->fbcoord[1], e->v2->fbcoord[1]); + b[3] = std::max(e->v1->fbcoord[1], e->v2->fbcoord[1]); if (b[0] > 1 || b[1] < -1 || b[2] > 1 || b[3] < -1) { return false; @@ -5382,7 +5385,7 @@ static void lineart_gpencil_generate(LineartCache *cache, if (invert_input) { use_weight = 1 - use_weight; } - gdw->weight = MAX2(use_weight, gdw->weight); + gdw->weight = std::max(use_weight, gdw->weight); sindex++; } diff --git a/source/blender/gpu/intern/gpu_index_buffer.cc b/source/blender/gpu/intern/gpu_index_buffer.cc index 05e23033eb1..4b3103dbbe1 100644 --- a/source/blender/gpu/intern/gpu_index_buffer.cc +++ b/source/blender/gpu/intern/gpu_index_buffer.cc @@ -19,6 +19,7 @@ #include "GPU_platform.h" +#include /* For `min/max`. */ #include #define KEEP_SINGLE_COPY 1 @@ -109,8 +110,8 @@ void GPU_indexbuf_add_generic_vert(GPUIndexBufBuilder *builder, uint v) assert(v <= builder->max_allowed_index); #endif builder->data[builder->index_len++] = v; - builder->index_min = MIN2(builder->index_min, v); - builder->index_max = MAX2(builder->index_max, v); + builder->index_min = std::min(builder->index_min, v); + builder->index_max = std::max(builder->index_max, v); } void GPU_indexbuf_add_primitive_restart(GPUIndexBufBuilder *builder) @@ -170,9 +171,9 @@ void GPU_indexbuf_set_point_vert(GPUIndexBufBuilder *builder, uint elem, uint v1 BLI_assert(builder->prim_type == GPU_PRIM_POINTS); BLI_assert(elem < builder->max_index_len); builder->data[elem++] = v1; - builder->index_min = MIN2(builder->index_min, v1); - builder->index_max = MAX2(builder->index_max, v1); - builder->index_len = MAX2(builder->index_len, elem); + builder->index_min = std::min(builder->index_min, v1); + builder->index_max = std::max(builder->index_max, v1); + builder->index_len = std::max(builder->index_len, elem); } void GPU_indexbuf_set_line_verts(GPUIndexBufBuilder *builder, uint elem, uint v1, uint v2) @@ -187,7 +188,7 @@ void GPU_indexbuf_set_line_verts(GPUIndexBufBuilder *builder, uint elem, uint v1 builder->data[idx++] = v2; builder->index_min = MIN3(builder->index_min, v1, v2); builder->index_max = MAX3(builder->index_max, v1, v2); - builder->index_len = MAX2(builder->index_len, idx); + builder->index_len = std::max(builder->index_len, idx); } void GPU_indexbuf_set_tri_verts(GPUIndexBufBuilder *builder, uint elem, uint v1, uint v2, uint v3) @@ -205,7 +206,7 @@ void GPU_indexbuf_set_tri_verts(GPUIndexBufBuilder *builder, uint elem, uint v1, builder->index_min = MIN4(builder->index_min, v1, v2, v3); builder->index_max = MAX4(builder->index_max, v1, v2, v3); - builder->index_len = MAX2(builder->index_len, idx); + builder->index_len = std::max(builder->index_len, idx); } void GPU_indexbuf_set_point_restart(GPUIndexBufBuilder *builder, uint elem) @@ -213,7 +214,7 @@ void GPU_indexbuf_set_point_restart(GPUIndexBufBuilder *builder, uint elem) BLI_assert(builder->prim_type == GPU_PRIM_POINTS); BLI_assert(elem < builder->max_index_len); builder->data[elem++] = builder->restart_index_value; - builder->index_len = MAX2(builder->index_len, elem); + builder->index_len = std::max(builder->index_len, elem); builder->uses_restart_indices = true; } @@ -224,7 +225,7 @@ void GPU_indexbuf_set_line_restart(GPUIndexBufBuilder *builder, uint elem) uint idx = elem * 2; builder->data[idx++] = builder->restart_index_value; builder->data[idx++] = builder->restart_index_value; - builder->index_len = MAX2(builder->index_len, idx); + builder->index_len = std::max(builder->index_len, idx); builder->uses_restart_indices = true; } @@ -236,7 +237,7 @@ void GPU_indexbuf_set_tri_restart(GPUIndexBufBuilder *builder, uint elem) builder->data[idx++] = builder->restart_index_value; builder->data[idx++] = builder->restart_index_value; builder->data[idx++] = builder->restart_index_value; - builder->index_len = MAX2(builder->index_len, idx); + builder->index_len = std::max(builder->index_len, idx); builder->uses_restart_indices = true; } diff --git a/source/blender/gpu/intern/gpu_material.cc b/source/blender/gpu/intern/gpu_material.cc index 6c1a608affc..c75169e1db5 100644 --- a/source/blender/gpu/intern/gpu_material.cc +++ b/source/blender/gpu/intern/gpu_material.cc @@ -433,7 +433,7 @@ static void compute_sss_kernel(GPUSssKernelData *kd, const float radii[3], int s /* Minimum radius */ rad[0] = MAX2(radii[0], 1e-15f); rad[1] = MAX2(radii[1], 1e-15f); - rad[2] = MAX2(radii[2], 1e-15f); + rad[2] = std::max(radii[2], 1e-15f); kd->avg_inv_radius = 3.0f / (rad[0] + rad[1] + rad[2]); diff --git a/source/blender/imbuf/intern/format_svg.cc b/source/blender/imbuf/intern/format_svg.cc index c14cdfe7ce9..eb51ca5de6f 100644 --- a/source/blender/imbuf/intern/format_svg.cc +++ b/source/blender/imbuf/intern/format_svg.cc @@ -50,9 +50,9 @@ ImBuf *imb_load_filepath_thumbnail_svg(const char *filepath, colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE); - const float scale = float(max_thumb_size) / MAX2(w, h); - const int dest_w = MAX2(int(w * scale), 1); - const int dest_h = MAX2(int(h * scale), 1); + const float scale = float(max_thumb_size) / std::max(w, h); + const int dest_w = std::max(int(w * scale), 1); + const int dest_h = std::max(int(h * scale), 1); ImBuf *ibuf = IMB_allocImBuf(dest_w, dest_h, 32, IB_rect); if (ibuf != nullptr) { diff --git a/source/blender/imbuf/intern/jpeg.cc b/source/blender/imbuf/intern/jpeg.cc index b266a98b44b..3d6503d920f 100644 --- a/source/blender/imbuf/intern/jpeg.cc +++ b/source/blender/imbuf/intern/jpeg.cc @@ -278,7 +278,7 @@ static ImBuf *ibJpegImageFromCinfo( if (max_size > 0) { /* `libjpeg` can more quickly decompress while scaling down to 1/2, 1/4, 1/8, * while `libjpeg-turbo` can also do 3/8, 5/8, etc. But max is 1/8. */ - float scale = float(max_size) / MAX2(cinfo->image_width, cinfo->image_height); + float scale = float(max_size) / std::max(cinfo->image_width, cinfo->image_height); cinfo->scale_denom = 8; cinfo->scale_num = max_uu(1, min_uu(8, ceill(scale * float(cinfo->scale_denom)))); cinfo->dct_method = JDCT_FASTEST; diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index 7feada82d49..7df76471804 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -2202,10 +2202,10 @@ ImBuf *imb_load_filepath_thumbnail_openexr(const char *filepath, colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_FLOAT); } - float scale_factor = MIN2(float(max_thumb_size) / float(source_w), + float scale_factor = std::min(float(max_thumb_size) / float(source_w), float(max_thumb_size) / float(source_h)); - int dest_w = MAX2(int(source_w * scale_factor), 1); - int dest_h = MAX2(int(source_h * scale_factor), 1); + int dest_w = std::max(int(source_w * scale_factor), 1); + int dest_h = std::max(int(source_h * scale_factor), 1); ImBuf *ibuf = IMB_allocImBuf(dest_w, dest_h, 32, IB_rectfloat); diff --git a/source/blender/imbuf/intern/stereoimbuf.cc b/source/blender/imbuf/intern/stereoimbuf.cc index ac50bec7987..69110102656 100644 --- a/source/blender/imbuf/intern/stereoimbuf.cc +++ b/source/blender/imbuf/intern/stereoimbuf.cc @@ -137,7 +137,7 @@ static void imb_stereo3d_write_anaglyph(const Stereo3DData *s3d, enum eStereo3dA to[0] = from[r][0]; to[1] = from[g][1]; to[2] = from[b][2]; - to[3] = MAX2(from[0][3], from[1][3]); + to[3] = std::max(from[0][3], from[1][3]); } } } diff --git a/source/blender/imbuf/intern/webp.cc b/source/blender/imbuf/intern/webp.cc index 8fbe95b32c0..56c164a2b8f 100644 --- a/source/blender/imbuf/intern/webp.cc +++ b/source/blender/imbuf/intern/webp.cc @@ -114,9 +114,9 @@ ImBuf *imb_load_filepath_thumbnail_webp(const char *filepath, *r_width = size_t(config.input.width); *r_height = size_t(config.input.height); - const float scale = float(max_thumb_size) / MAX2(config.input.width, config.input.height); - const int dest_w = MAX2(int(config.input.width * scale), 1); - const int dest_h = MAX2(int(config.input.height * scale), 1); + const float scale = float(max_thumb_size) / std::max(config.input.width, config.input.height); + const int dest_w = std::max(int(config.input.width * scale), 1); + const int dest_h = std::max(int(config.input.height * scale), 1); colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE); ImBuf *ibuf = IMB_allocImBuf(dest_w, dest_h, 32, IB_rect); diff --git a/source/blender/io/gpencil/intern/gpencil_io_base.cc b/source/blender/io/gpencil/intern/gpencil_io_base.cc index 791947bf058..ea1716a5096 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_base.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_base.cc @@ -268,7 +268,7 @@ float GpencilIO::stroke_point_radius_get(bGPDlayer *gpl, bGPDstroke *gps) float radius = math::length(v1); BKE_gpencil_free_stroke(gps_perimeter); - return MAX2(radius, 1.0f); + return std::max(radius, 1.0f); } void GpencilIO::prepare_layer_export_matrix(Object *ob, bGPDlayer *gpl) diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc index daa602097c3..c8afb6d031e 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc @@ -247,7 +247,7 @@ void GpencilExporterPDF::export_stroke_to_polyline(bGPDlayer *gpl, const float estimated_width = (radius * 2.0f) + gpl->line_change; const float final_width = (avg_pressure == 1.0f) ? MAX2(defined_width, estimated_width) : estimated_width; - HPDF_Page_SetLineWidth(page_, MAX2(final_width, 1.0f)); + HPDF_Page_SetLineWidth(page_, std::max(final_width, 1.0f)); } /* Loop all points. */ diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc b/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc index c9146d26a56..c7471f4bd97 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc @@ -315,7 +315,7 @@ void GpencilExporterSVG::export_stroke_to_polyline(bGPDlayer *gpl, const float estimated_width = (radius * 2.0f) + gpl->line_change; const float final_width = (avg_pressure == 1.0f) ? MAX2(defined_width, estimated_width) : estimated_width; - node_gps.append_attribute("stroke-width").set_value(MAX2(final_width, 1.0f)); + node_gps.append_attribute("stroke-width").set_value(std::max(final_width, 1.0f)); } std::string txt; diff --git a/source/blender/makesrna/intern/rna_access.cc b/source/blender/makesrna/intern/rna_access.cc index 68dcde90226..0d83c973dbb 100644 --- a/source/blender/makesrna/intern/rna_access.cc +++ b/source/blender/makesrna/intern/rna_access.cc @@ -2281,7 +2281,7 @@ static void rna_property_boolean_fill_default_array_values( const bool *defarr, int defarr_length, bool defvalue, int out_length, bool *r_values) { if (defarr && defarr_length > 0) { - defarr_length = MIN2(defarr_length, out_length); + defarr_length = std::min(defarr_length, out_length); memcpy(r_values, defarr, sizeof(bool) * defarr_length); } else { @@ -2297,7 +2297,7 @@ static void rna_property_boolean_fill_default_array_values_from_ints( const int *defarr, int defarr_length, bool defvalue, int out_length, bool *r_values) { if (defarr && defarr_length > 0) { - defarr_length = MIN2(defarr_length, out_length); + defarr_length = std::min(defarr_length, out_length); for (int i = 0; i < defarr_length; i++) { r_values[i] = defarr[i] != 0; } @@ -2650,7 +2650,7 @@ static void rna_property_int_fill_default_array_values( const int *defarr, int defarr_length, int defvalue, int out_length, int *r_values) { if (defarr && defarr_length > 0) { - defarr_length = MIN2(defarr_length, out_length); + defarr_length = std::min(defarr_length, out_length); memcpy(r_values, defarr, sizeof(int) * defarr_length); } else { @@ -2732,8 +2732,8 @@ void RNA_property_int_get_array_range(PointerRNA *ptr, PropertyRNA *prop, int va RNA_property_int_get_array(ptr, prop, arr); values[0] = values[1] = arr[0]; for (i = 1; i < array_len; i++) { - values[0] = MIN2(values[0], arr[i]); - values[1] = MAX2(values[1], arr[i]); + values[0] = std::min(values[0], arr[i]); + values[1] = std::max(values[1], arr[i]); } if (arr != arr_stack) { @@ -2997,7 +2997,7 @@ static void rna_property_float_fill_default_array_values( const float *defarr, int defarr_length, float defvalue, int out_length, float *r_values) { if (defarr && defarr_length > 0) { - defarr_length = MIN2(defarr_length, out_length); + defarr_length = std::min(defarr_length, out_length); memcpy(r_values, defarr, sizeof(float) * defarr_length); } else { @@ -3018,7 +3018,7 @@ static void rna_property_float_fill_default_array_values_double(const double *de const int out_length, float *r_values) { - const int array_copy_len = MIN2(out_length, default_array_len); + const int array_copy_len = std::min(out_length, default_array_len); for (int i = 0; i < array_copy_len; i++) { r_values[i] = float(default_array[i]); @@ -3105,8 +3105,8 @@ void RNA_property_float_get_array_range(PointerRNA *ptr, PropertyRNA *prop, floa RNA_property_float_get_array(ptr, prop, arr); values[0] = values[1] = arr[0]; for (i = 1; i < array_len; i++) { - values[0] = MIN2(values[0], arr[i]); - values[1] = MAX2(values[1], arr[i]); + values[0] = std::min(values[0], arr[i]); + values[1] = std::max(values[1], arr[i]); } if (arr != arr_stack) { diff --git a/source/blender/makesrna/intern/rna_define.cc b/source/blender/makesrna/intern/rna_define.cc index 4acf47801c7..ee7bc3274a0 100644 --- a/source/blender/makesrna/intern/rna_define.cc +++ b/source/blender/makesrna/intern/rna_define.cc @@ -1784,16 +1784,16 @@ void RNA_def_property_range(PropertyRNA *prop, double min, double max) IntPropertyRNA *iprop = (IntPropertyRNA *)prop; iprop->hardmin = int(min); iprop->hardmax = int(max); - iprop->softmin = MAX2(int(min), iprop->hardmin); - iprop->softmax = MIN2(int(max), iprop->hardmax); + iprop->softmin = std::max(int(min), iprop->hardmin); + iprop->softmax = std::min(int(max), iprop->hardmax); break; } case PROP_FLOAT: { FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop; fprop->hardmin = float(min); fprop->hardmax = float(max); - fprop->softmin = MAX2(float(min), fprop->hardmin); - fprop->softmax = MIN2(float(max), fprop->hardmax); + fprop->softmin = std::max(float(min), fprop->hardmin); + fprop->softmax = std::min(float(max), fprop->hardmax); break; } default: @@ -2539,7 +2539,7 @@ void RNA_def_property_int_sdna(PropertyRNA *prop, const char *structname, const } else if (STREQ(dp->dnatype, "int")) { int *defaultarray = static_cast(rna_calloc(size_final)); - memcpy(defaultarray, default_data, MIN2(size_final, dp->dnasize)); + memcpy(defaultarray, default_data, std::min(size_final, dp->dnasize)); iprop->defaultarray = defaultarray; } else { @@ -2650,7 +2650,7 @@ void RNA_def_property_float_sdna(PropertyRNA *prop, const char *structname, cons if (STREQ(dp->dnatype, "float")) { const int size_final = sizeof(float) * prop->totarraylength; float *defaultarray = static_cast(rna_calloc(size_final)); - memcpy(defaultarray, default_data, MIN2(size_final, dp->dnasize)); + memcpy(defaultarray, default_data, std::min(size_final, dp->dnasize)); fprop->defaultarray = defaultarray; } else { diff --git a/source/blender/modifiers/intern/MOD_subsurf.cc b/source/blender/modifiers/intern/MOD_subsurf.cc index 0e99ea09560..3618340eaca 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.cc +++ b/source/blender/modifiers/intern/MOD_subsurf.cc @@ -386,10 +386,10 @@ static void panel_draw(const bContext *C, Panel *panel) } if (ob_use_adaptive_subdivision && show_adaptive_options) { uiItemR(layout, &ob_cycles_ptr, "dicing_rate", UI_ITEM_NONE, nullptr, ICON_NONE); - float render = MAX2(RNA_float_get(&cycles_ptr, "dicing_rate") * + float render = std::max(RNA_float_get(&cycles_ptr, "dicing_rate") * RNA_float_get(&ob_cycles_ptr, "dicing_rate"), 0.1f); - float preview = MAX2(RNA_float_get(&cycles_ptr, "preview_dicing_rate") * + float preview = std::max(RNA_float_get(&cycles_ptr, "preview_dicing_rate") * RNA_float_get(&ob_cycles_ptr, "dicing_rate"), 0.1f); char output[256]; diff --git a/source/blender/modifiers/intern/MOD_wireframe.cc b/source/blender/modifiers/intern/MOD_wireframe.cc index e9df4da1e3f..52fab6f3f68 100644 --- a/source/blender/modifiers/intern/MOD_wireframe.cc +++ b/source/blender/modifiers/intern/MOD_wireframe.cc @@ -91,7 +91,7 @@ static Mesh *WireframeModifier_do(WireframeModifierData *wmd, Object *ob, Mesh * defgrp_index, (wmd->flag & MOD_WIREFRAME_INVERT_VGROUP) != 0, wmd->mat_ofs, - MAX2(ob->totcol - 1, 0), + std::max(ob->totcol - 1, 0), false); result = BKE_mesh_from_bmesh_for_eval_nomain(bm, nullptr, mesh); diff --git a/source/blender/nodes/texture/nodes/node_texture_math.cc b/source/blender/nodes/texture/nodes/node_texture_math.cc index 9ee5393babc..3a9992254a6 100644 --- a/source/blender/nodes/texture/nodes/node_texture_math.cc +++ b/source/blender/nodes/texture/nodes/node_texture_math.cc @@ -285,7 +285,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor case NODE_MATH_COMPARE: { float in2 = tex_input_value(in[2], p, thread); - *out = (fabsf(in0 - in1) <= MAX2(in2, 1e-5f)) ? 1.0f : 0.0f; + *out = (fabsf(in0 - in1) <= std::max(in2, 1e-5f)) ? 1.0f : 0.0f; break; } diff --git a/source/blender/python/generic/idprop_py_ui_api.cc b/source/blender/python/generic/idprop_py_ui_api.cc index 5c88f9e5be4..8f873ef9572 100644 --- a/source/blender/python/generic/idprop_py_ui_api.cc +++ b/source/blender/python/generic/idprop_py_ui_api.cc @@ -143,23 +143,23 @@ static bool idprop_ui_data_update_int(IDProperty *idprop, PyObject *args, PyObje if (args_contain_key(kwargs, "min")) { ui_data.min = min; - ui_data.soft_min = MAX2(ui_data.soft_min, ui_data.min); - ui_data.max = MAX2(ui_data.min, ui_data.max); + ui_data.soft_min = std::max(ui_data.soft_min, ui_data.min); + ui_data.max = std::max(ui_data.min, ui_data.max); } if (args_contain_key(kwargs, "max")) { ui_data.max = max; - ui_data.soft_max = MIN2(ui_data.soft_max, ui_data.max); - ui_data.min = MIN2(ui_data.min, ui_data.max); + ui_data.soft_max = std::min(ui_data.soft_max, ui_data.max); + ui_data.min = std::min(ui_data.min, ui_data.max); } if (args_contain_key(kwargs, "soft_min")) { ui_data.soft_min = soft_min; - ui_data.soft_min = MAX2(ui_data.soft_min, ui_data.min); - ui_data.soft_max = MAX2(ui_data.soft_min, ui_data.soft_max); + ui_data.soft_min = std::max(ui_data.soft_min, ui_data.min); + ui_data.soft_max = std::max(ui_data.soft_min, ui_data.soft_max); } if (args_contain_key(kwargs, "soft_max")) { ui_data.soft_max = soft_max; - ui_data.soft_max = MIN2(ui_data.soft_max, ui_data.max); - ui_data.soft_min = MIN2(ui_data.soft_min, ui_data.soft_max); + ui_data.soft_max = std::min(ui_data.soft_max, ui_data.max); + ui_data.soft_min = std::min(ui_data.soft_min, ui_data.soft_max); } if (args_contain_key(kwargs, "step")) { ui_data.step = step; @@ -354,23 +354,23 @@ static bool idprop_ui_data_update_float(IDProperty *idprop, PyObject *args, PyOb if (args_contain_key(kwargs, "min")) { ui_data.min = min; - ui_data.soft_min = MAX2(ui_data.soft_min, ui_data.min); - ui_data.max = MAX2(ui_data.min, ui_data.max); + ui_data.soft_min = std::max(ui_data.soft_min, ui_data.min); + ui_data.max = std::max(ui_data.min, ui_data.max); } if (args_contain_key(kwargs, "max")) { ui_data.max = max; - ui_data.soft_max = MIN2(ui_data.soft_max, ui_data.max); - ui_data.min = MIN2(ui_data.min, ui_data.max); + ui_data.soft_max = std::min(ui_data.soft_max, ui_data.max); + ui_data.min = std::min(ui_data.min, ui_data.max); } if (args_contain_key(kwargs, "soft_min")) { ui_data.soft_min = soft_min; ui_data.soft_min = MAX2(ui_data.soft_min, ui_data.min); - ui_data.soft_max = MAX2(ui_data.soft_min, ui_data.soft_max); + ui_data.soft_max = std::max(ui_data.soft_min, ui_data.soft_max); } if (args_contain_key(kwargs, "soft_max")) { ui_data.soft_max = soft_max; ui_data.soft_max = MIN2(ui_data.soft_max, ui_data.max); - ui_data.soft_min = MIN2(ui_data.soft_min, ui_data.soft_max); + ui_data.soft_min = std::min(ui_data.soft_min, ui_data.soft_max); } if (args_contain_key(kwargs, "step")) { ui_data.step = float(step); diff --git a/source/blender/python/intern/bpy_props.cc b/source/blender/python/intern/bpy_props.cc index ca63fbbb71e..668b7f18846 100644 --- a/source/blender/python/intern/bpy_props.cc +++ b/source/blender/python/intern/bpy_props.cc @@ -3262,7 +3262,7 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) RNA_def_property_translation_context(prop, translation_context); } RNA_def_property_range(prop, min, max); - RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3); + RNA_def_property_ui_range(prop, std::max(soft_min, min), MIN2(soft_max, max), step, 3); if (tags_enum.base.is_set) { RNA_def_property_tags(prop, tags_enum.base.value); @@ -3460,7 +3460,7 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject if (translation_context) { RNA_def_property_translation_context(prop, translation_context); } - RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3); + RNA_def_property_ui_range(prop, std::max(soft_min, min), MIN2(soft_max, max), step, 3); if (tags_enum.base.is_set) { RNA_def_property_tags(prop, tags_enum.base.value); diff --git a/source/blender/python/mathutils/mathutils_Matrix.cc b/source/blender/python/mathutils/mathutils_Matrix.cc index f50f8816ce2..4d7a9c93250 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.cc +++ b/source/blender/python/mathutils/mathutils_Matrix.cc @@ -3698,7 +3698,7 @@ static PyObject *MatrixAccess_slice(MatrixAccessObject *self, Py_ssize_t begin, end = (matrix_access_len + 1) + end; } CLAMP(end, 0, matrix_access_len); - begin = MIN2(begin, end); + begin = std::min(begin, end); tuple = PyTuple_New(end - begin); for (count = begin; count < end; count++) { diff --git a/source/blender/python/mathutils/mathutils_Vector.cc b/source/blender/python/mathutils/mathutils_Vector.cc index 83151139f8d..f20e232b815 100644 --- a/source/blender/python/mathutils/mathutils_Vector.cc +++ b/source/blender/python/mathutils/mathutils_Vector.cc @@ -694,7 +694,7 @@ static PyObject *Vector_to_3d(VectorObject *self) return nullptr; } - memcpy(tvec, self->vec, sizeof(float) * MIN2(self->vec_num, 3)); + memcpy(tvec, self->vec, sizeof(float) * std::min(self->vec_num, 3)); return Vector_CreatePyObject(tvec, 3, Py_TYPE(self)); } PyDoc_STRVAR(Vector_to_4d_doc, @@ -712,7 +712,7 @@ static PyObject *Vector_to_4d(VectorObject *self) return nullptr; } - memcpy(tvec, self->vec, sizeof(float) * MIN2(self->vec_num, 4)); + memcpy(tvec, self->vec, sizeof(float) * std::min(self->vec_num, 4)); return Vector_CreatePyObject(tvec, 4, Py_TYPE(self)); } @@ -1082,7 +1082,7 @@ PyDoc_STRVAR( " :rtype: float\n"); static PyObject *Vector_angle(VectorObject *self, PyObject *args) { - const int vec_num = MIN2(self->vec_num, 3); /* 4D angle makes no sense */ + const int vec_num = std::min(self->vec_num, 3); /* 4D angle makes no sense */ float tvec[MAX_DIMENSIONS]; PyObject *value; double dot = 0.0f, dot_self = 0.0f, dot_other = 0.0f; diff --git a/source/blender/render/intern/texture_image.cc b/source/blender/render/intern/texture_image.cc index e47774abfc0..5b3283f2a10 100644 --- a/source/blender/render/intern/texture_image.cc +++ b/source/blender/render/intern/texture_image.cc @@ -1219,7 +1219,7 @@ static int imagewraposa_aniso(Tex *tex, b = max_ff(b, 1.0f); fProbes = 2.0f * (a / b) - 1.0f; AFD.iProbes = round_fl_to_int(fProbes); - AFD.iProbes = MIN2(AFD.iProbes, tex->afmax); + AFD.iProbes = std::min(AFD.iProbes, tex->afmax); if (AFD.iProbes < fProbes) { b = 2.0f * a / float(AFD.iProbes + 1); } diff --git a/source/blender/render/intern/texture_pointdensity.cc b/source/blender/render/intern/texture_pointdensity.cc index c7ad337b81a..bebf34a13d9 100644 --- a/source/blender/render/intern/texture_pointdensity.cc +++ b/source/blender/render/intern/texture_pointdensity.cc @@ -525,7 +525,7 @@ static float density_falloff(PointDensityRangeData *pdr, int index, float square break; case TEX_PD_FALLOFF_PARTICLE_AGE: if (pdr->point_data_life) { - density = dist * MIN2(pdr->point_data_life[index], 1.0f); + density = dist * std::min(pdr->point_data_life[index], 1.0f); } else { density = dist; diff --git a/source/blender/sequencer/intern/effects.cc b/source/blender/sequencer/intern/effects.cc index 8bffd997ddf..b96e116d80b 100644 --- a/source/blender/sequencer/intern/effects.cc +++ b/source/blender/sequencer/intern/effects.cc @@ -938,13 +938,13 @@ static void do_drop_effect_byte(float fac, int x, int y, uchar *rect2i, uchar *r for (int j = xoff; j < x; j++) { int temp_fac2 = ((temp_fac * rt2[3]) >> 8); - *(out++) = MAX2(0, *rt1 - temp_fac2); + *(out++) = std::max(0, *rt1 - temp_fac2); rt1++; - *(out++) = MAX2(0, *rt1 - temp_fac2); + *(out++) = std::max(0, *rt1 - temp_fac2); rt1++; - *(out++) = MAX2(0, *rt1 - temp_fac2); + *(out++) = std::max(0, *rt1 - temp_fac2); rt1++; - *(out++) = MAX2(0, *rt1 - temp_fac2); + *(out++) = std::max(0, *rt1 - temp_fac2); rt1++; rt2 += 4; } @@ -972,13 +972,13 @@ static void do_drop_effect_float( for (int j = xoff; j < x; j++) { float temp_fac2 = temp_fac * rt2[3]; - *(out++) = MAX2(0.0f, *rt1 - temp_fac2); + *(out++) = std::max(0.0f, *rt1 - temp_fac2); rt1++; - *(out++) = MAX2(0.0f, *rt1 - temp_fac2); + *(out++) = std::max(0.0f, *rt1 - temp_fac2); rt1++; - *(out++) = MAX2(0.0f, *rt1 - temp_fac2); + *(out++) = std::max(0.0f, *rt1 - temp_fac2); rt1++; - *(out++) = MAX2(0.0f, *rt1 - temp_fac2); + *(out++) = std::max(0.0f, *rt1 - temp_fac2); rt1++; rt2 += 4; } diff --git a/source/blender/sequencer/intern/strip_add.cc b/source/blender/sequencer/intern/strip_add.cc index f890963fec0..0df221f1301 100644 --- a/source/blender/sequencer/intern/strip_add.cc +++ b/source/blender/sequencer/intern/strip_add.cc @@ -490,7 +490,7 @@ Sequence *SEQ_add_movie_strip(Main *bmain, Scene *scene, ListBase *seqbase, SeqL } } - seq->len = MAX2(1, seq->len); + seq->len = std::max(1, seq->len); if (load_data->adjust_playback_rate) { seq->flag |= SEQ_AUTO_PLAYBACK_RATE; } diff --git a/source/blender/windowmanager/intern/wm_playanim.cc b/source/blender/windowmanager/intern/wm_playanim.cc index 2e32ee3fe3b..cfac309b91f 100644 --- a/source/blender/windowmanager/intern/wm_playanim.cc +++ b/source/blender/windowmanager/intern/wm_playanim.cc @@ -1521,7 +1521,7 @@ static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) zoomy = float(ps->display_ctx.size[1]) / ps->ibuf_size[1]; /* Zoom always show entire image. */ - ps->zoom = MIN2(zoomx, zoomy); + ps->zoom = std::min(zoomx, zoomy); GPU_viewport(0, 0, ps->display_ctx.size[0], ps->display_ctx.size[1]); GPU_scissor(0, 0, ps->display_ctx.size[0], ps->display_ctx.size[1]); diff --git a/source/blender/windowmanager/intern/wm_splash_screen.cc b/source/blender/windowmanager/intern/wm_splash_screen.cc index 96eda527605..f3d80299898 100644 --- a/source/blender/windowmanager/intern/wm_splash_screen.cc +++ b/source/blender/windowmanager/intern/wm_splash_screen.cc @@ -262,7 +262,7 @@ void WM_OT_splash(wmOperatorType *ot) static uiBlock *wm_block_create_about(bContext *C, ARegion *region, void * /*arg*/) { const uiStyle *style = UI_style_get_dpi(); - const int text_points_max = MAX2(style->widget.points, style->widgetlabel.points); + const int text_points_max = std::max(style->widget.points, style->widgetlabel.points); const int dialog_width = text_points_max * 42 * UI_SCALE_FAC; uiBlock *block = UI_block_begin(C, region, "about", UI_EMBOSS); From d6cafda3bbd428966b1d74c8798698e5a6ca1ebd Mon Sep 17 00:00:00 2001 From: Alaska Date: Tue, 7 Nov 2023 07:45:36 +0100 Subject: [PATCH 30/62] Fix #114491: Incorrect HDR tooltip Mention that AgX also doesn't produce HDR information for the HDR display feature on macOS. Pull Request: https://projects.blender.org/blender/blender/pulls/114502 --- source/blender/makesrna/intern/rna_color.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_color.cc b/source/blender/makesrna/intern/rna_color.cc index c769668912e..3257e2dc2c3 100644 --- a/source/blender/makesrna/intern/rna_color.cc +++ b/source/blender/makesrna/intern/rna_color.cc @@ -1285,7 +1285,7 @@ static void rna_def_colormanage(BlenderRNA *brna) "High Dynamic Range", "Enable high dynamic range display in rendered viewport, uncapping display brightness. This " "requires a monitor with HDR support and a view transform designed for HDR. " - "'Filmic' does not generate HDR colors"); + "'Filmic' and 'AgX' do not generate HDR colors"); RNA_def_property_update(prop, NC_WINDOW, "rna_ColorManagedColorspaceSettings_reload_update"); /* ** Color-space ** */ From 967e36cf6853bd454d6c9e5ccdadbdcdafaa003a Mon Sep 17 00:00:00 2001 From: Alaska Date: Tue, 7 Nov 2023 07:48:54 +0100 Subject: [PATCH 31/62] UI: Don't show HDR setting when using False Color view transform False Color view transforms doesn't show HDR values. Pull Request: https://projects.blender.org/blender/blender/pulls/114503 --- scripts/startup/bl_ui/properties_render.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/startup/bl_ui/properties_render.py b/scripts/startup/bl_ui/properties_render.py index 74ef1792188..087dd0163dc 100644 --- a/scripts/startup/bl_ui/properties_render.py +++ b/scripts/startup/bl_ui/properties_render.py @@ -111,8 +111,8 @@ class RENDER_PT_color_management_display_settings(RenderButtonsPanel, Panel): # Only display HDR toggle for non-Filmic display transforms. col = layout.column(align=True) sub = col.row() - sub.active = (not view.view_transform.startswith("Filmic") and - not view.view_transform.startswith("AgX")) + sub.active = (not view.view_transform.startswith("Filmic") and not view.view_transform.startswith("AgX") and not + view.view_transform.startswith("False Color")) sub.prop(view, "use_hdr_view") From bbb71f0859e1109779db25638f12c0f37de95443 Mon Sep 17 00:00:00 2001 From: Jason Fielder Date: Tue, 7 Nov 2023 07:53:20 +0100 Subject: [PATCH 32/62] Metal: Ensure pending MTLSafeFreeList is released on shutdown Ensure that on closing of the application, all pending SafeFreeLists are released. A new change to ensure release of SafeFreeLists was always deferred until full completion of GPU buffers meant that a pending MTLSafeFreeList container may not be released on shutdown. This change ensures that the container is fully destructed on final shutdown. Authored by Apple: Michael Parkin-White Pull Request: https://projects.blender.org/blender/blender/pulls/114532 --- source/blender/gpu/metal/mtl_memory.mm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/blender/gpu/metal/mtl_memory.mm b/source/blender/gpu/metal/mtl_memory.mm index b2ddefe13fa..c95c6a6f113 100644 --- a/source/blender/gpu/metal/mtl_memory.mm +++ b/source/blender/gpu/metal/mtl_memory.mm @@ -70,10 +70,17 @@ void MTLBufferPool::free() delete completed_safelist_queue_[safe_pool_free_index]; } completed_safelist_queue_.clear(); + + safelist_lock_.lock(); if (current_free_list_ != nullptr) { delete current_free_list_; current_free_list_ = nullptr; } + if (prev_free_buffer_list_ != nullptr) { + delete prev_free_buffer_list_; + prev_free_buffer_list_ = nullptr; + } + safelist_lock_.unlock(); /* Clear and release memory pools. */ for (std::multiset *buffer_pool : From b56382b38acd7203f08e3cbf7dd27ca992b6b9c0 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 7 Nov 2023 08:04:17 +0100 Subject: [PATCH 33/62] Cleanup: Make format --- source/blender/blenkernel/intern/fluid.cc | 5 +++-- source/blender/bmesh/tools/bmesh_region_match.cc | 2 +- .../compositor/operations/COM_MathBaseOperation.cc | 5 +++-- source/blender/editors/interface/interface_draw.cc | 3 ++- source/blender/editors/space_info/textview.cc | 8 ++++---- source/blender/imbuf/intern/openexr/openexr_api.cpp | 2 +- source/blender/modifiers/intern/MOD_subsurf.cc | 8 ++++---- 7 files changed, 18 insertions(+), 15 deletions(-) diff --git a/source/blender/blenkernel/intern/fluid.cc b/source/blender/blenkernel/intern/fluid.cc index b9ac1c4023e..5539a80b62c 100644 --- a/source/blender/blenkernel/intern/fluid.cc +++ b/source/blender/blenkernel/intern/fluid.cc @@ -783,14 +783,15 @@ static void bb_combineMaps(FluidObjectBB *output, x - bb2->min[0], bb2->res[0], y - bb2->min[1], bb2->res[1], z - bb2->min[2]); /* Values. */ - output->numobjs[index_out] = std::max(bb2->numobjs[index_in], output->numobjs[index_out]); + output->numobjs[index_out] = std::max(bb2->numobjs[index_in], + output->numobjs[index_out]); if (output->influence && bb2->influence) { if (additive) { output->influence[index_out] += bb2->influence[index_in] * sample_size; } else { output->influence[index_out] = std::max(bb2->influence[index_in], - output->influence[index_out]); + output->influence[index_out]); } } output->distances[index_out] = MIN2(bb2->distances[index_in], diff --git a/source/blender/bmesh/tools/bmesh_region_match.cc b/source/blender/bmesh/tools/bmesh_region_match.cc index b2b1538469b..dc71fc2f47e 100644 --- a/source/blender/bmesh/tools/bmesh_region_match.cc +++ b/source/blender/bmesh/tools/bmesh_region_match.cc @@ -383,7 +383,7 @@ static void bm_uuidwalk_rehash(UUIDWalk *uuidwalk) uint i; uint rehash_store_len_new = std::max(BLI_ghash_len(uuidwalk->verts_uuid), - BLI_ghash_len(uuidwalk->faces_uuid)); + BLI_ghash_len(uuidwalk->faces_uuid)); bm_uuidwalk_rehash_reserve(uuidwalk, rehash_store_len_new); uuid_store = uuidwalk->cache.rehash_store; diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.cc b/source/blender/compositor/operations/COM_MathBaseOperation.cc index 53f386dee4e..5d65014f888 100644 --- a/source/blender/compositor/operations/COM_MathBaseOperation.cc +++ b/source/blender/compositor/operations/COM_MathBaseOperation.cc @@ -997,8 +997,9 @@ void MathCompareOperation::execute_pixel_sampled(float output[4], input_value2_operation_->read_sampled(input_value2, x, y, sampler); input_value3_operation_->read_sampled(input_value3, x, y, sampler); - output[0] = (fabsf(input_value1[0] - input_value2[0]) <= std::max(input_value3[0], 1e-5f)) ? 1.0f : - 0.0f; + output[0] = (fabsf(input_value1[0] - input_value2[0]) <= std::max(input_value3[0], 1e-5f)) ? + 1.0f : + 0.0f; clamp_if_needed(output); } diff --git a/source/blender/editors/interface/interface_draw.cc b/source/blender/editors/interface/interface_draw.cc index 5ac023b8125..2ddfdd74a7b 100644 --- a/source/blender/editors/interface/interface_draw.cc +++ b/source/blender/editors/interface/interface_draw.cc @@ -1121,7 +1121,8 @@ static void ui_draw_colorband_handle(uint shdr_pos, GPU_blend(GPU_BLEND_ALPHA); /* Allow the lines to decrease as we get really small. */ - float line_width = std::max(std::min(U.pixelsize / 5.0f * fabs(half_width - 4.0f), U.pixelsize), 0.5f); + float line_width = std::max(std::min(U.pixelsize / 5.0f * fabs(half_width - 4.0f), U.pixelsize), + 0.5f); /* Make things transparent as we get tiny. */ uchar alpha = std::min(int(fabs(half_width - 2.0f) * 50.0f), 255); diff --git a/source/blender/editors/space_info/textview.cc b/source/blender/editors/space_info/textview.cc index 34e3b09fcb9..60171eb6e33 100644 --- a/source/blender/editors/space_info/textview.cc +++ b/source/blender/editors/space_info/textview.cc @@ -103,10 +103,10 @@ static int textview_wrap_offsets( *r_lines = 1; - *r_offsets = static_cast( - MEM_callocN(sizeof(**r_offsets) * - (str_len * column_width_max / std::max(1, width - (column_width_max - 1)) + 1), - __func__)); + *r_offsets = static_cast(MEM_callocN( + sizeof(**r_offsets) * + (str_len * column_width_max / std::max(1, width - (column_width_max - 1)) + 1), + __func__)); (*r_offsets)[0] = 0; for (i = 0, end = width, j = 0; j < str_len && str[j]; j += BLI_str_utf8_size_safe(str + j)) { diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index 7df76471804..01f39b38c47 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -2203,7 +2203,7 @@ ImBuf *imb_load_filepath_thumbnail_openexr(const char *filepath, } float scale_factor = std::min(float(max_thumb_size) / float(source_w), - float(max_thumb_size) / float(source_h)); + float(max_thumb_size) / float(source_h)); int dest_w = std::max(int(source_w * scale_factor), 1); int dest_h = std::max(int(source_h * scale_factor), 1); diff --git a/source/blender/modifiers/intern/MOD_subsurf.cc b/source/blender/modifiers/intern/MOD_subsurf.cc index 3618340eaca..76373451f21 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.cc +++ b/source/blender/modifiers/intern/MOD_subsurf.cc @@ -387,11 +387,11 @@ static void panel_draw(const bContext *C, Panel *panel) if (ob_use_adaptive_subdivision && show_adaptive_options) { uiItemR(layout, &ob_cycles_ptr, "dicing_rate", UI_ITEM_NONE, nullptr, ICON_NONE); float render = std::max(RNA_float_get(&cycles_ptr, "dicing_rate") * - RNA_float_get(&ob_cycles_ptr, "dicing_rate"), - 0.1f); + RNA_float_get(&ob_cycles_ptr, "dicing_rate"), + 0.1f); float preview = std::max(RNA_float_get(&cycles_ptr, "preview_dicing_rate") * - RNA_float_get(&ob_cycles_ptr, "dicing_rate"), - 0.1f); + RNA_float_get(&ob_cycles_ptr, "dicing_rate"), + 0.1f); char output[256]; SNPRINTF(output, TIP_("Final Scale: Render %.2f px, Viewport %.2f px"), render, preview); uiItemL(layout, output, ICON_NONE); From 15f1fe5ddbf05a1f448f4d32dc0be4aed9d1b534 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 7 Nov 2023 09:50:51 +0100 Subject: [PATCH 34/62] Cleanup: Add missing includes to node anonymous attribute header --- .../blender/blenkernel/BKE_node_tree_anonymous_attributes.hh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/blenkernel/BKE_node_tree_anonymous_attributes.hh b/source/blender/blenkernel/BKE_node_tree_anonymous_attributes.hh index 30a0344ef78..f71c6aefbfa 100644 --- a/source/blender/blenkernel/BKE_node_tree_anonymous_attributes.hh +++ b/source/blender/blenkernel/BKE_node_tree_anonymous_attributes.hh @@ -8,8 +8,11 @@ #include "DNA_node_types.h" +#include "BLI_array.hh" #include "BLI_bit_group_vector.hh" +#include "BLI_resource_scope.hh" #include "BLI_vector.hh" +#include "BLI_vector_set.hh" #include "NOD_node_declaration.hh" From ae1b4a6a28373ab5107410d61257e43ddd0f0e0a Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 7 Nov 2023 10:05:13 +0100 Subject: [PATCH 35/62] Cleanup: Consolidate draw attribute extraction Use the same attribute conversion class for PBVH and regular mesh attribute extraction. This makes the GPU formats we use for each attribute type more explicit and centralizes the conversions from the attribute types to the GPU types. It's also a bit more aligned to how we could use implicit sharing for GPU vertex buffer data. Unfortunately it isn't possible to use this same code for curves and point clouds because they use textures for their evaluated data, and 3-wide vectors (e.g. `float3`) aren't supported on GPUs with our current texture abstraction. For generic attributes, the long term approach will probably be to use an SSBO instead. Pull Request: https://projects.blender.org/blender/blender/pulls/114340 --- source/blender/draw/CMakeLists.txt | 2 + .../blender/draw/intern/attribute_convert.cc | 56 ++ .../blender/draw/intern/attribute_convert.hh | 144 ++++++ source/blender/draw/intern/draw_pbvh.cc | 174 +------ .../extract_mesh_vbo_attributes.cc | 485 ++++++++---------- 5 files changed, 429 insertions(+), 432 deletions(-) create mode 100644 source/blender/draw/intern/attribute_convert.cc create mode 100644 source/blender/draw/intern/attribute_convert.hh diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index ab76ae31337..c3343d1de50 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -35,6 +35,7 @@ set(INC_SYS ) set(SRC + intern/attribute_convert.cc intern/draw_cache.cc intern/draw_cache_extract_mesh.cc intern/draw_cache_extract_mesh_render_data.cc @@ -229,6 +230,7 @@ set(SRC DRW_engine.h DRW_pbvh.hh DRW_select_buffer.hh + intern/attribute_convert.hh intern/DRW_gpu_wrapper.hh intern/DRW_render.h intern/draw_attributes.hh diff --git a/source/blender/draw/intern/attribute_convert.cc b/source/blender/draw/intern/attribute_convert.cc new file mode 100644 index 00000000000..19c12766169 --- /dev/null +++ b/source/blender/draw/intern/attribute_convert.cc @@ -0,0 +1,56 @@ +/* SPDX-FileCopyrightText: 2005 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup gpu + */ + +#include "BLI_array_utils.hh" + +#include "BKE_attribute_math.hh" + +#include "GPU_vertex_buffer.h" + +#include "attribute_convert.hh" + +namespace blender::draw { + +GPUVertFormat init_format_for_attribute(const eCustomDataType data_type, + const StringRefNull vbo_name) +{ + GPUVertFormat format{}; + bke::attribute_math::convert_to_static_type(data_type, [&](auto dummy) { + using T = decltype(dummy); + using Converter = AttributeConverter; + GPU_vertformat_attr_add(&format, + vbo_name.c_str(), + Converter::gpu_component_type, + Converter::gpu_component_len, + Converter::gpu_fetch_mode); + }); + return format; +} + +void vertbuf_data_extract_direct(const GSpan attribute, GPUVertBuf &vbo) +{ + bke::attribute_math::convert_to_static_type(attribute.type(), [&](auto dummy) { + using T = decltype(dummy); + using Converter = AttributeConverter; + using VBOType = typename Converter::VBOType; + const Span src = attribute.typed(); + MutableSpan data(static_cast(GPU_vertbuf_get_data(&vbo)), attribute.size()); + if constexpr (std::is_same_v) { + array_utils::copy(src, data); + } + else { + threading::parallel_for(src.index_range(), 8192, [&](const IndexRange range) { + for (const int i : range) { + data[i] = Converter::convert(src[i]); + } + }); + } + }); +} + +} // namespace blender::draw diff --git a/source/blender/draw/intern/attribute_convert.hh b/source/blender/draw/intern/attribute_convert.hh new file mode 100644 index 00000000000..8beb3fb6171 --- /dev/null +++ b/source/blender/draw/intern/attribute_convert.hh @@ -0,0 +1,144 @@ +/* SPDX-FileCopyrightText: 2005 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup gpu + */ + +#include "BLI_color.hh" +#include "BLI_generic_span.hh" +#include "BLI_math_quaternion_types.hh" +#include "BLI_math_vector_types.hh" +#include "BLI_string_ref.hh" + +#include "DNA_customdata_types.h" /* #eCustomDataType. */ + +#include "GPU_vertex_format.h" + +/** + * Component length of 3 is used for scalars because implicit conversion is done by OpenGL from a + * scalar `s` will produce `vec4(s, 0, 0, 1)`. However, following the Blender convention, it should + * be `vec4(s, s, s, 1)`. + */ +constexpr int COMPONENT_LEN_SCALAR = 3; + +namespace blender::draw { + +/** + * Utility to convert from the type used in the attributes to the types for GPU vertex buffers. + */ +template struct AttributeConverter { + using VBOType = void; +}; + +template<> struct AttributeConverter { + using VBOType = VecBase; + static constexpr GPUVertCompType gpu_component_type = GPU_COMP_I32; + static constexpr int gpu_component_len = COMPONENT_LEN_SCALAR; + static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_INT_TO_FLOAT; + static VBOType convert(const bool &value) + { + return VBOType(value); + } +}; +template<> struct AttributeConverter { + using VBOType = VecBase; + static constexpr GPUVertCompType gpu_component_type = GPU_COMP_I32; + static constexpr int gpu_component_len = COMPONENT_LEN_SCALAR; + static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_INT_TO_FLOAT; + static VBOType convert(const int8_t &value) + { + return VecBase(value); + } +}; +template<> struct AttributeConverter { + using VBOType = VecBase; + static constexpr GPUVertCompType gpu_component_type = GPU_COMP_I32; + static constexpr int gpu_component_len = COMPONENT_LEN_SCALAR; + static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_INT_TO_FLOAT; + static VBOType convert(const int &value) + { + return int3(value); + } +}; +template<> struct AttributeConverter { + using VBOType = int2; + static constexpr GPUVertCompType gpu_component_type = GPU_COMP_I32; + static constexpr int gpu_component_len = 2; + static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_INT_TO_FLOAT; + static VBOType convert(const int2 &value) + { + return int2(value.x, value.y); + } +}; +template<> struct AttributeConverter { + using VBOType = VecBase; + static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32; + static constexpr int gpu_component_len = COMPONENT_LEN_SCALAR; + static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT; + static VBOType convert(const float &value) + { + return VBOType(value); + } +}; +template<> struct AttributeConverter { + using VBOType = float2; + static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32; + static constexpr int gpu_component_len = 2; + static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT; + static VBOType convert(const float2 &value) + { + return value; + } +}; +template<> struct AttributeConverter { + using VBOType = float3; + static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32; + static constexpr int gpu_component_len = 3; + static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT; + static VBOType convert(const float3 &value) + { + return value; + } +}; +template<> struct AttributeConverter { + /* 16 bits are required to store the color in linear space without precision loss. */ + using VBOType = ushort4; + static constexpr GPUVertCompType gpu_component_type = GPU_COMP_U16; + static constexpr int gpu_component_len = 4; + static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_INT_TO_FLOAT_UNIT; + static VBOType convert(const ColorGeometry4b &value) + { + return {unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.r]), + unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.g]), + unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.b]), + ushort(value.a * 257)}; + } +}; +template<> struct AttributeConverter { + using VBOType = ColorGeometry4f; + static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32; + static constexpr int gpu_component_len = 4; + static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT; + static VBOType convert(const ColorGeometry4f &value) + { + return value; + } +}; +template<> struct AttributeConverter { + using VBOType = float4; + static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32; + static constexpr int gpu_component_len = 4; + static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT; + static VBOType convert(const math::Quaternion &value) + { + return float4(value.w, value.x, value.y, value.z); + } +}; + +GPUVertFormat init_format_for_attribute(eCustomDataType data_type, StringRefNull vbo_name); + +void vertbuf_data_extract_direct(GSpan attribute, GPUVertBuf &vbo); + +} // namespace blender::draw diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc index f96d5151277..fab5fa31b52 100644 --- a/source/blender/draw/intern/draw_pbvh.cc +++ b/source/blender/draw/intern/draw_pbvh.cc @@ -50,6 +50,7 @@ #include "DRW_engine.h" #include "DRW_pbvh.hh" +#include "attribute_convert.hh" #include "bmesh.h" #include "draw_pbvh.h" #include "gpu_private.h" @@ -57,10 +58,7 @@ #define MAX_PBVH_BATCH_KEY 512 #define MAX_PBVH_VBOS 16 -using blender::char3; -using blender::float2; using blender::float3; -using blender::float4; using blender::FunctionRef; using blender::IndexRange; using blender::Map; @@ -72,131 +70,8 @@ using blender::StringRef; using blender::StringRefNull; using blender::uchar3; using blender::uchar4; -using blender::ushort3; -using blender::ushort4; using blender::Vector; -/** - * Component length of 3 is used for scalars because implicit conversion is done by OpenGL from a - * scalar `s` will produce `vec4(s, 0, 0, 1)`. However, following the Blender convention, it should - * be `vec4(s, s, s, 1)`. - */ -constexpr int COMPONENT_LEN_SCALAR = 3; - -namespace blender::draw { - -/** Similar to #AttributeTypeConverter. */ -template struct AttributeConverter { - using VBOT = void; -}; - -template<> struct AttributeConverter { - using VBOT = VecBase; - static constexpr GPUVertCompType gpu_component_type = GPU_COMP_I32; - static constexpr int gpu_component_len = COMPONENT_LEN_SCALAR; - static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_INT_TO_FLOAT; - static VBOT convert(const bool &value) - { - return VBOT(value); - } -}; -template<> struct AttributeConverter { - using VBOT = VecBase; - static constexpr GPUVertCompType gpu_component_type = GPU_COMP_I32; - static constexpr int gpu_component_len = COMPONENT_LEN_SCALAR; - static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_INT_TO_FLOAT; - static VBOT convert(const int8_t &value) - { - return VecBase(value); - } -}; -template<> struct AttributeConverter { - using VBOT = VecBase; - static constexpr GPUVertCompType gpu_component_type = GPU_COMP_I32; - static constexpr int gpu_component_len = COMPONENT_LEN_SCALAR; - static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_INT_TO_FLOAT; - static VBOT convert(const int &value) - { - return int3(value); - } -}; -template<> struct AttributeConverter { - using VBOT = int2; - static constexpr GPUVertCompType gpu_component_type = GPU_COMP_I32; - static constexpr int gpu_component_len = 2; - static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_INT_TO_FLOAT; - static VBOT convert(const int2 &value) - { - return int2(value.x, value.y); - } -}; -template<> struct AttributeConverter { - using VBOT = VecBase; - static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32; - static constexpr int gpu_component_len = COMPONENT_LEN_SCALAR; - static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT; - static VBOT convert(const float &value) - { - return VBOT(value); - } -}; -template<> struct AttributeConverter { - using VBOT = float2; - static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32; - static constexpr int gpu_component_len = 2; - static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT; - static VBOT convert(const float2 &value) - { - return value; - } -}; -template<> struct AttributeConverter { - using VBOT = float3; - static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32; - static constexpr int gpu_component_len = 3; - static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT; - static VBOT convert(const float3 &value) - { - return value; - } -}; -template<> struct AttributeConverter { - /* 16 bits are required to store the color in linear space without precision loss. */ - using VBOT = ushort4; - static constexpr GPUVertCompType gpu_component_type = GPU_COMP_U16; - static constexpr int gpu_component_len = 4; - static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_INT_TO_FLOAT_UNIT; - static VBOT convert(const ColorGeometry4b &value) - { - return {unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.r]), - unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.g]), - unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.b]), - ushort(value.a * 257)}; - } -}; -template<> struct AttributeConverter { - using VBOT = ColorGeometry4f; - static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32; - static constexpr int gpu_component_len = 4; - static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT; - static VBOT convert(const ColorGeometry4f &value) - { - return value; - } -}; -template<> struct AttributeConverter { - using VBOT = float4; - static constexpr GPUVertCompType gpu_component_type = GPU_COMP_F32; - static constexpr int gpu_component_len = 4; - static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_FLOAT; - static VBOT convert(const blender::math::Quaternion &value) - { - return float4(value.w, value.x, value.y, value.z); - } -}; - -} // namespace blender::draw - static bool pbvh_attr_supported(int type, const eAttrDomain domain) { using namespace blender; @@ -211,8 +86,8 @@ static bool pbvh_attr_supported(int type, const eAttrDomain domain) bke::attribute_math::convert_to_static_type(eCustomDataType(type), [&](auto dummy) { using T = decltype(dummy); using Converter = draw::AttributeConverter; - using VBOT = typename Converter::VBOT; - if constexpr (!std::is_void_v) { + using VBOType = typename Converter::VBOType; + if constexpr (!std::is_void_v) { type_supported = true; } }); @@ -257,13 +132,13 @@ template void extract_data_vert_faces(const PBVH_GPU_Args &args, const Span attribute, GPUVertBuf &vbo) { using Converter = blender::draw::AttributeConverter; - using VBOT = typename Converter::VBOT; + using VBOType = typename Converter::VBOType; const Span corner_verts = args.corner_verts; const Span looptris = args.mlooptri; const Span looptri_faces = args.looptri_faces; const bool *hide_poly = args.hide_poly; - VBOT *data = static_cast(GPU_vertbuf_get_data(&vbo)); + VBOType *data = static_cast(GPU_vertbuf_get_data(&vbo)); for (const int looptri_i : args.prim_indices) { if (hide_poly && hide_poly[looptri_faces[looptri_i]]) { continue; @@ -280,12 +155,12 @@ template void extract_data_face_faces(const PBVH_GPU_Args &args, const Span attribute, GPUVertBuf &vbo) { using Converter = blender::draw::AttributeConverter; - using VBOT = typename Converter::VBOT; + using VBOType = typename Converter::VBOType; const Span looptri_faces = args.looptri_faces; const bool *hide_poly = args.hide_poly; - VBOT *data = static_cast(GPU_vertbuf_get_data(&vbo)); + VBOType *data = static_cast(GPU_vertbuf_get_data(&vbo)); for (const int looptri_i : args.prim_indices) { const int face = looptri_faces[looptri_i]; if (hide_poly && hide_poly[face]) { @@ -300,13 +175,13 @@ template void extract_data_corner_faces(const PBVH_GPU_Args &args, const Span attribute, GPUVertBuf &vbo) { using Converter = blender::draw::AttributeConverter; - using VBOT = typename Converter::VBOT; + using VBOType = typename Converter::VBOType; const Span looptris = args.mlooptri; const Span looptri_faces = args.looptri_faces; const bool *hide_poly = args.hide_poly; - VBOT *data = static_cast(GPU_vertbuf_get_data(&vbo)); + VBOType *data = static_cast(GPU_vertbuf_get_data(&vbo)); for (const int looptri_i : args.prim_indices) { if (hide_poly && hide_poly[looptri_faces[looptri_i]]) { continue; @@ -338,8 +213,8 @@ template void extract_data_vert_bmesh(const PBVH_GPU_Args &args, const int cd_offset, GPUVertBuf &vbo) { using Converter = blender::draw::AttributeConverter; - using VBOT = typename Converter::VBOT; - VBOT *data = static_cast(GPU_vertbuf_get_data(&vbo)); + using VBOType = typename Converter::VBOType; + VBOType *data = static_cast(GPU_vertbuf_get_data(&vbo)); for (const BMFace *f : *args.bm_faces) { if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { @@ -359,8 +234,8 @@ template void extract_data_face_bmesh(const PBVH_GPU_Args &args, const int cd_offset, GPUVertBuf &vbo) { using Converter = blender::draw::AttributeConverter; - using VBOT = typename Converter::VBOT; - VBOT *data = static_cast(GPU_vertbuf_get_data(&vbo)); + using VBOType = typename Converter::VBOType; + VBOType *data = static_cast(GPU_vertbuf_get_data(&vbo)); for (const BMFace *f : *args.bm_faces) { if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { @@ -375,8 +250,8 @@ template void extract_data_corner_bmesh(const PBVH_GPU_Args &args, const int cd_offset, GPUVertBuf &vbo) { using Converter = blender::draw::AttributeConverter; - using VBOT = typename Converter::VBOT; - VBOT *data = static_cast(GPU_vertbuf_get_data(&vbo)); + using VBOType = typename Converter::VBOType; + VBOType *data = static_cast(GPU_vertbuf_get_data(&vbo)); for (const BMFace *f : *args.bm_faces) { if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { @@ -736,10 +611,10 @@ struct PBVHBatches { bke::attribute_math::convert_to_static_type(eCustomDataType(vbo.type), [&](auto dummy) { using T = decltype(dummy); using Converter = draw::AttributeConverter; - using VBOT = typename Converter::VBOT; - std::fill_n(static_cast(GPU_vertbuf_get_data(vbo.vert_buf)), + using VBOType = typename Converter::VBOType; + std::fill_n(static_cast(GPU_vertbuf_get_data(vbo.vert_buf)), GPU_vertbuf_get_vertex_len(vbo.vert_buf), - VBOT()); + VBOType()); }); } } @@ -1094,8 +969,7 @@ struct PBVHBatches { PBVHVbo vbo(domain, type, name); GPUVertFormat format; - bool need_aliases = !ELEM( - type, CD_PBVH_CO_TYPE, CD_PBVH_NO_TYPE, CD_PBVH_FSET_TYPE, CD_PBVH_MASK_TYPE); + bool need_aliases = false; GPU_vertformat_clear(&format); @@ -1112,15 +986,7 @@ struct PBVHBatches { GPU_vertformat_attr_add(&format, "msk", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); } else { - bke::attribute_math::convert_to_static_type(eCustomDataType(type), [&](auto dummy) { - using T = decltype(dummy); - using Converter = draw::AttributeConverter; - GPU_vertformat_attr_add(&format, - "data", - Converter::gpu_component_type, - Converter::gpu_component_len, - Converter::gpu_fetch_mode); - }); + format = draw::init_format_for_attribute(eCustomDataType(type), "data"); need_aliases = true; } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc index 3414636eb7a..9cf503b8e68 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc @@ -8,16 +8,15 @@ #include "MEM_guardedalloc.h" -#include - -#include "BLI_color.hh" +#include "BLI_array_utils.hh" #include "BLI_math_vector_types.hh" #include "BLI_string.h" -#include "BKE_attribute.h" #include "BKE_attribute.hh" +#include "BKE_attribute_math.hh" #include "BKE_mesh.hh" +#include "attribute_convert.hh" #include "draw_attributes.hh" #include "draw_subdivision.h" #include "extract_mesh.hh" @@ -28,142 +27,19 @@ namespace blender::draw { /** \name Extract Attributes * \{ */ -static CustomData *get_custom_data_for_domain(const MeshRenderData &mr, eAttrDomain domain) -{ - switch (domain) { - case ATTR_DOMAIN_POINT: - return (mr.extract_type == MR_EXTRACT_BMESH) ? &mr.bm->vdata : &mr.me->vert_data; - case ATTR_DOMAIN_CORNER: - return (mr.extract_type == MR_EXTRACT_BMESH) ? &mr.bm->ldata : &mr.me->loop_data; - case ATTR_DOMAIN_FACE: - return (mr.extract_type == MR_EXTRACT_BMESH) ? &mr.bm->pdata : &mr.me->face_data; - case ATTR_DOMAIN_EDGE: - return (mr.extract_type == MR_EXTRACT_BMESH) ? &mr.bm->edata : &mr.me->edge_data; - default: - return nullptr; - } -} - -/* Utility to convert from the type used in the attributes to the types for the VBO. - * This is mostly used to promote integers and booleans to floats, as other types (float, float2, - * etc.) directly map to available GPU types. Booleans are still converted as attributes are vec4 - * in the shader. - */ -template struct AttributeTypeConverter { - static VBOType convert_value(AttributeType value) - { - if constexpr (std::is_same_v) { - return value; - } - - /* This should only concern bools which are converted to floats. */ - return static_cast(value); - } -}; - -struct gpuMeshCol { - ushort r, g, b, a; -}; - -template<> struct AttributeTypeConverter { - static gpuMeshCol convert_value(MPropCol value) - { - gpuMeshCol result; - result.r = unit_float_to_ushort_clamp(value.color[0]); - result.g = unit_float_to_ushort_clamp(value.color[1]); - result.b = unit_float_to_ushort_clamp(value.color[2]); - result.a = unit_float_to_ushort_clamp(value.color[3]); - return result; - } -}; - -template<> struct AttributeTypeConverter { - static gpuMeshCol convert_value(ColorGeometry4b value) - { - gpuMeshCol result; - result.r = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.r]); - result.g = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.g]); - result.b = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.b]); - result.a = unit_float_to_ushort_clamp(value.a * (1.0f / 255.0f)); - return result; - } -}; - -/* Return the number of component for the attribute's value type, or 0 if is it unsupported. */ -static uint gpu_component_size_for_attribute_type(eCustomDataType type) -{ - switch (type) { - case CD_PROP_BOOL: - case CD_PROP_INT8: - case CD_PROP_INT32: - case CD_PROP_FLOAT: - /* TODO(@kevindietrich): should be 1 when scalar attributes conversion is handled by us. See - * comment #extract_attr_init. */ - return 3; - case CD_PROP_FLOAT2: - case CD_PROP_INT32_2D: - return 2; - case CD_PROP_FLOAT3: - return 3; - case CD_PROP_COLOR: - case CD_PROP_BYTE_COLOR: - case CD_PROP_QUATERNION: - return 4; - default: - return 0; - } -} - -static GPUVertFetchMode get_fetch_mode_for_type(eCustomDataType type) -{ - switch (type) { - case CD_PROP_INT8: - case CD_PROP_INT32: - case CD_PROP_INT32_2D: - return GPU_FETCH_INT_TO_FLOAT; - case CD_PROP_BYTE_COLOR: - return GPU_FETCH_INT_TO_FLOAT_UNIT; - default: - return GPU_FETCH_FLOAT; - } -} - -static GPUVertCompType get_comp_type_for_type(eCustomDataType type) -{ - switch (type) { - case CD_PROP_INT8: - case CD_PROP_INT32_2D: - case CD_PROP_INT32: - return GPU_COMP_I32; - case CD_PROP_BYTE_COLOR: - /* This should be u8, - * but u16 is required to store the color in linear space without precision loss */ - return GPU_COMP_U16; - default: - return GPU_COMP_F32; - } -} - static void init_vbo_for_attribute(const MeshRenderData &mr, GPUVertBuf *vbo, const DRW_AttributeRequest &request, bool build_on_device, uint32_t len) { - GPUVertCompType comp_type = get_comp_type_for_type(request.cd_type); - GPUVertFetchMode fetch_mode = get_fetch_mode_for_type(request.cd_type); - const uint comp_size = gpu_component_size_for_attribute_type(request.cd_type); - /* We should not be here if the attribute type is not supported. */ - BLI_assert(comp_size != 0); - char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME]; GPU_vertformat_safe_attr_name(request.attribute_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME); /* Attributes use auto-name. */ SNPRINTF(attr_name, "a%s", attr_safe_name); - GPUVertFormat format = {0}; + GPUVertFormat format = init_format_for_attribute(request.cd_type, attr_name); GPU_vertformat_deinterleave(&format); - GPU_vertformat_attr_add(&format, attr_name, comp_type, comp_size, fetch_mode); if (mr.active_color_name && STREQ(request.attribute_name, mr.active_color_name)) { GPU_vertformat_alias_add(&format, "ac"); @@ -181,164 +57,214 @@ static void init_vbo_for_attribute(const MeshRenderData &mr, } } -template -static void fill_vertbuf_with_attribute(const MeshRenderData &mr, - VBOType *vbo_data, - const DRW_AttributeRequest &request) +template +static void extract_data_mesh_mapped_corner(const Span attribute, + const Span indices, + GPUVertBuf &vbo) { - const CustomData *custom_data = get_custom_data_for_domain(mr, request.domain); - BLI_assert(custom_data); - const int layer_index = request.layer_index; + using Converter = AttributeConverter; + using VBOType = typename Converter::VBOType; + MutableSpan data(static_cast(GPU_vertbuf_get_data(&vbo)), indices.size()); - const Span corner_verts = mr.corner_verts; - const Span corner_edges = mr.corner_edges; - - const AttributeType *attr_data = static_cast( - CustomData_get_layer_n(custom_data, request.cd_type, layer_index)); - - using Converter = AttributeTypeConverter; - - switch (request.domain) { - case ATTR_DOMAIN_POINT: - for (int ml_index = 0; ml_index < mr.loop_len; ml_index++, vbo_data++) { - *vbo_data = Converter::convert_value(attr_data[corner_verts[ml_index]]); - } - break; - case ATTR_DOMAIN_CORNER: - for (int ml_index = 0; ml_index < mr.loop_len; ml_index++, vbo_data++) { - *vbo_data = Converter::convert_value(attr_data[ml_index]); - } - break; - case ATTR_DOMAIN_EDGE: - for (int ml_index = 0; ml_index < mr.loop_len; ml_index++, vbo_data++) { - *vbo_data = Converter::convert_value(attr_data[corner_edges[ml_index]]); - } - break; - case ATTR_DOMAIN_FACE: - for (int face_index = 0; face_index < mr.face_len; face_index++) { - const IndexRange face = mr.faces[face_index]; - const VBOType value = Converter::convert_value(attr_data[face_index]); - for (int l = 0; l < face.size(); l++) { - *vbo_data++ = value; - } - } - break; - default: - BLI_assert_unreachable(); - break; - } -} - -template -static void fill_vertbuf_with_attribute_bm(const MeshRenderData &mr, - VBOType *&vbo_data, - const DRW_AttributeRequest &request) -{ - const CustomData *custom_data = get_custom_data_for_domain(mr, request.domain); - BLI_assert(custom_data); - const int layer_index = request.layer_index; - - const int cd_ofs = CustomData_get_n_offset(custom_data, request.cd_type, layer_index); - - using Converter = AttributeTypeConverter; - - BMIter f_iter; - BMFace *efa; - BM_ITER_MESH (efa, &f_iter, mr.bm, BM_FACES_OF_MESH) { - BMLoop *l_iter, *l_first; - l_iter = l_first = BM_FACE_FIRST_LOOP(efa); - do { - const AttributeType *attr_data = nullptr; - if (request.domain == ATTR_DOMAIN_POINT) { - attr_data = static_cast(BM_ELEM_CD_GET_VOID_P(l_iter->v, cd_ofs)); - } - else if (request.domain == ATTR_DOMAIN_CORNER) { - attr_data = static_cast(BM_ELEM_CD_GET_VOID_P(l_iter, cd_ofs)); - } - else if (request.domain == ATTR_DOMAIN_FACE) { - attr_data = static_cast(BM_ELEM_CD_GET_VOID_P(efa, cd_ofs)); - } - else if (request.domain == ATTR_DOMAIN_EDGE) { - attr_data = static_cast(BM_ELEM_CD_GET_VOID_P(l_iter->e, cd_ofs)); - } - else { - BLI_assert_unreachable(); - continue; - } - *vbo_data = Converter::convert_value(*attr_data); - vbo_data++; - } while ((l_iter = l_iter->next) != l_first); - } -} - -template -static void extract_attr_generic(const MeshRenderData &mr, - GPUVertBuf *vbo, - const DRW_AttributeRequest &request) -{ - VBOType *vbo_data = static_cast(GPU_vertbuf_get_data(vbo)); - - if (mr.extract_type == MR_EXTRACT_BMESH) { - fill_vertbuf_with_attribute_bm(mr, vbo_data, request); + if constexpr (std::is_same_v) { + array_utils::gather(attribute, indices, data); } else { - fill_vertbuf_with_attribute(mr, vbo_data, request); + threading::parallel_for(indices.index_range(), 8192, [&](const IndexRange range) { + for (const int i : range) { + data[i] = Converter::convert(attribute[indices[i]]); + } + }); + } +} + +template +static void extract_data_mesh_vert(const MeshRenderData &mr, + const Span attribute, + GPUVertBuf &vbo) +{ +} + +template +static void extract_data_mesh_edge(const MeshRenderData &mr, + const Span attribute, + GPUVertBuf &vbo) +{ + extract_data_mapped_corner(attribute, mr.corner_edges, vbo); +} + +template +static void extract_data_mesh_face(const OffsetIndices faces, + const Span attribute, + GPUVertBuf &vbo) +{ + using Converter = AttributeConverter; + using VBOType = typename Converter::VBOType; + MutableSpan data(static_cast(GPU_vertbuf_get_data(&vbo)), faces.total_size()); + + threading::parallel_for(faces.index_range(), 2048, [&](const IndexRange range) { + for (const int i : range) { + data.slice(faces[i]).fill(Converter::convert(attribute[i])); + } + }); +} + +template +static void extract_data_bmesh_vert(const BMesh &bm, const int cd_offset, GPUVertBuf &vbo) +{ + using Converter = AttributeConverter; + using VBOType = typename Converter::VBOType; + VBOType *data = static_cast(GPU_vertbuf_get_data(&vbo)); + + const BMFace *face; + BMIter f_iter; + BM_ITER_MESH (face, &f_iter, &const_cast(bm), BM_FACES_OF_MESH) { + const BMLoop *loop = BM_FACE_FIRST_LOOP(face); + for ([[maybe_unused]] const int i : IndexRange(face->len)) { + const T *src = static_cast(POINTER_OFFSET(loop->v->head.data, cd_offset)); + *data = Converter::convert(*src); + loop = loop->next; + data++; + } + } +} + +template +static void extract_data_bmesh_edge(const BMesh &bm, const int cd_offset, GPUVertBuf &vbo) +{ + using Converter = AttributeConverter; + using VBOType = typename Converter::VBOType; + VBOType *data = static_cast(GPU_vertbuf_get_data(&vbo)); + + const BMFace *face; + BMIter f_iter; + BM_ITER_MESH (face, &f_iter, &const_cast(bm), BM_FACES_OF_MESH) { + const BMLoop *loop = BM_FACE_FIRST_LOOP(face); + for ([[maybe_unused]] const int i : IndexRange(face->len)) { + const T &src = *static_cast(POINTER_OFFSET(loop->e->head.data, cd_offset)); + *data = Converter::convert(src); + loop = loop->next; + data++; + } + } +} + +template +static void extract_data_bmesh_face(const BMesh &bm, const int cd_offset, GPUVertBuf &vbo) +{ + using Converter = AttributeConverter; + using VBOType = typename Converter::VBOType; + VBOType *data = static_cast(GPU_vertbuf_get_data(&vbo)); + + const BMFace *face; + BMIter f_iter; + BM_ITER_MESH (face, &f_iter, &const_cast(bm), BM_FACES_OF_MESH) { + const T &src = *static_cast(POINTER_OFFSET(face->head.data, cd_offset)); + std::fill_n(data, face->len, Converter::convert(src)); + data += face->len; + } +} + +template +static void extract_data_bmesh_loop(const BMesh &bm, const int cd_offset, GPUVertBuf &vbo) +{ + using Converter = AttributeConverter; + using VBOType = typename Converter::VBOType; + VBOType *data = static_cast(GPU_vertbuf_get_data(&vbo)); + + const BMFace *face; + BMIter f_iter; + BM_ITER_MESH (face, &f_iter, &const_cast(bm), BM_FACES_OF_MESH) { + const BMLoop *loop = BM_FACE_FIRST_LOOP(face); + for ([[maybe_unused]] const int i : IndexRange(face->len)) { + const T &src = *static_cast(POINTER_OFFSET(loop->head.data, cd_offset)); + *data = Converter::convert(src); + loop = loop->next; + data++; + } + } +} + +static const CustomData *get_custom_data_for_domain(const BMesh &bm, eAttrDomain domain) +{ + switch (domain) { + case ATTR_DOMAIN_POINT: + return &bm.vdata; + case ATTR_DOMAIN_CORNER: + return &bm.ldata; + case ATTR_DOMAIN_FACE: + return &bm.pdata; + case ATTR_DOMAIN_EDGE: + return &bm.edata; + default: + return nullptr; } } static void extract_attr(const MeshRenderData &mr, - GPUVertBuf *vbo, - const DRW_AttributeRequest &request) + const DRW_AttributeRequest &request, + GPUVertBuf &vbo) { - /* TODO(@kevindietrich): float3 is used for scalar attributes as the implicit conversion done by - * OpenGL to vec4 for a scalar `s` will produce a `vec4(s, 0, 0, 1)`. However, following the - * Blender convention, it should be `vec4(s, s, s, 1)`. This could be resolved using a similar - * texture as for volume attribute, so we can control the conversion ourselves. */ - switch (request.cd_type) { - case CD_PROP_BOOL: - extract_attr_generic(mr, vbo, request); - break; - case CD_PROP_INT8: - extract_attr_generic(mr, vbo, request); - break; - case CD_PROP_INT32: - extract_attr_generic(mr, vbo, request); - break; - case CD_PROP_INT32_2D: - extract_attr_generic(mr, vbo, request); - break; - case CD_PROP_FLOAT: - extract_attr_generic(mr, vbo, request); - break; - case CD_PROP_FLOAT2: - extract_attr_generic(mr, vbo, request); - break; - case CD_PROP_FLOAT3: - extract_attr_generic(mr, vbo, request); - break; - case CD_PROP_QUATERNION: - case CD_PROP_COLOR: - extract_attr_generic(mr, vbo, request); - break; - case CD_PROP_BYTE_COLOR: - extract_attr_generic(mr, vbo, request); - break; - default: - BLI_assert_unreachable(); + if (mr.extract_type == MR_EXTRACT_BMESH) { + const CustomData &custom_data = *get_custom_data_for_domain(*mr.bm, request.domain); + const char *name = request.attribute_name; + const int cd_offset = CustomData_get_offset_named(&custom_data, request.cd_type, name); + + bke::attribute_math::convert_to_static_type(request.cd_type, [&](auto dummy) { + using T = decltype(dummy); + switch (request.domain) { + case ATTR_DOMAIN_POINT: + extract_data_bmesh_vert(*mr.bm, cd_offset, vbo); + break; + case ATTR_DOMAIN_EDGE: + extract_data_bmesh_edge(*mr.bm, cd_offset, vbo); + break; + case ATTR_DOMAIN_FACE: + extract_data_bmesh_face(*mr.bm, cd_offset, vbo); + break; + case ATTR_DOMAIN_CORNER: + extract_data_bmesh_loop(*mr.bm, cd_offset, vbo); + break; + default: + BLI_assert_unreachable(); + } + }); + } + else { + const bke::AttributeAccessor attributes = mr.me->attributes(); + const StringRef name = request.attribute_name; + const eCustomDataType data_type = request.cd_type; + const GVArraySpan attribute = *attributes.lookup_or_default(name, request.domain, data_type); + + bke::attribute_math::convert_to_static_type(request.cd_type, [&](auto dummy) { + using T = decltype(dummy); + switch (request.domain) { + case ATTR_DOMAIN_POINT: + extract_data_mesh_mapped_corner(attribute.typed(), mr.corner_verts, vbo); + break; + case ATTR_DOMAIN_EDGE: + extract_data_mesh_mapped_corner(attribute.typed(), mr.corner_edges, vbo); + break; + case ATTR_DOMAIN_FACE: + extract_data_mesh_face(mr.faces, attribute.typed(), vbo); + break; + case ATTR_DOMAIN_CORNER: + vertbuf_data_extract_direct(attribute.typed(), vbo); + break; + default: + BLI_assert_unreachable(); + } + }); } } static void extract_attr_init( const MeshRenderData &mr, MeshBatchCache &cache, void *buf, void * /*tls_data*/, int index) { - const DRW_Attributes *attrs_used = &cache.attr_used; - const DRW_AttributeRequest &request = attrs_used->requests[index]; - + const DRW_AttributeRequest &request = cache.attr_used.requests[index]; GPUVertBuf *vbo = static_cast(buf); - init_vbo_for_attribute(mr, vbo, request, false, uint32_t(mr.loop_len)); - - extract_attr(mr, vbo, request); + extract_attr(mr, request, *vbo); } static void extract_attr_init_subdiv(const DRWSubdivCache &subdiv_cache, @@ -353,26 +279,29 @@ static void extract_attr_init_subdiv(const DRWSubdivCache &subdiv_cache, Mesh *coarse_mesh = subdiv_cache.mesh; - GPUVertCompType comp_type = get_comp_type_for_type(request.cd_type); - GPUVertFetchMode fetch_mode = get_fetch_mode_for_type(request.cd_type); - const uint32_t dimensions = gpu_component_size_for_attribute_type(request.cd_type); - /* Prepare VBO for coarse data. The compute shader only expects floats. */ GPUVertBuf *src_data = GPU_vertbuf_calloc(); - GPUVertFormat coarse_format = {0}; - GPU_vertformat_attr_add(&coarse_format, "data", comp_type, dimensions, fetch_mode); + GPUVertFormat coarse_format = draw::init_format_for_attribute(request.cd_type, "data"); GPU_vertbuf_init_with_format_ex(src_data, &coarse_format, GPU_USAGE_STATIC); GPU_vertbuf_data_alloc(src_data, uint32_t(coarse_mesh->totloop)); - extract_attr(mr, src_data, request); + extract_attr(mr, request, *src_data); GPUVertBuf *dst_buffer = static_cast(buffer); init_vbo_for_attribute(mr, dst_buffer, request, true, subdiv_cache.num_subdiv_loops); /* Ensure data is uploaded properly. */ GPU_vertbuf_tag_dirty(src_data); - draw_subdiv_interp_custom_data( - subdiv_cache, src_data, dst_buffer, comp_type, int(dimensions), 0); + bke::attribute_math::convert_to_static_type(request.cd_type, [&](auto dummy) { + using T = decltype(dummy); + using Converter = AttributeConverter; + draw_subdiv_interp_custom_data(subdiv_cache, + src_data, + dst_buffer, + Converter::gpu_component_type, + Converter::gpu_component_len, + 0); + }); GPU_vertbuf_discard(src_data); } From 0eb279de54ffbfe574b9b61c767b17ebbc53b911 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Tue, 7 Nov 2023 10:11:30 +0100 Subject: [PATCH 36/62] Fix #66286: DblClick to rename UIList items within a popover not working Looks like most of `ui_apply_but_XXX` or `ui_do_but_XXX` functions rely on `uiHandleButtonData` (and not necessarily context). Now the problem from a popover in `ui_but_list_row_text_activate` was that the label button to be set in BUTTON_ACTIVATE_TEXT_EDITING for renaming could not be found because it was using the "wrong" region from context (`CTX_wm_region` - which still seem to point to the region the popover was spawned from). The correct region is available in `uiHandleButtonData` though, so now use this instead. Not totally sure if `CTX_wm_region` should actually be correct in all cases - which would hint at an underlying problem of not setting it right - but since other functions rely on `uiHandleButtonData` as well, this fix seems to make sense. Fix should go into LTS I think. Pull Request: https://projects.blender.org/blender/blender/pulls/114363 --- source/blender/editors/interface/interface_handlers.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/interface/interface_handlers.cc b/source/blender/editors/interface/interface_handlers.cc index 9d35506430c..597f9b15160 100644 --- a/source/blender/editors/interface/interface_handlers.cc +++ b/source/blender/editors/interface/interface_handlers.cc @@ -4412,7 +4412,7 @@ static uiBut *ui_but_list_row_text_activate(bContext *C, const wmEvent *event, uiButtonActivateType activate_type) { - ARegion *region = CTX_wm_region(C); + ARegion *region = data->region; uiBut *labelbut = ui_but_find_mouse_over_ex(region, event->xy, true, false, nullptr, nullptr); if (labelbut && labelbut->type == UI_BTYPE_TEXT && !(labelbut->flag & UI_BUT_DISABLED)) { From a338ecb9cbae9408a2f70d157aa4f16b15f62830 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Tue, 7 Nov 2023 10:53:43 +0100 Subject: [PATCH 37/62] Refactor: fcurve.cc No functional changes. Improve the readability of the code by * returning early where possible * moving variables closer to where they are used * renaming variables Pull Request: https://projects.blender.org/blender/blender/pulls/114568 --- source/blender/animrig/intern/fcurve.cc | 105 ++++++++++++------------ 1 file changed, 52 insertions(+), 53 deletions(-) diff --git a/source/blender/animrig/intern/fcurve.cc b/source/blender/animrig/intern/fcurve.cc index 04c7e579907..4f1089312c9 100644 --- a/source/blender/animrig/intern/fcurve.cc +++ b/source/blender/animrig/intern/fcurve.cc @@ -33,9 +33,6 @@ FCurve *action_fcurve_ensure(Main *bmain, const char rna_path[], const int array_index) { - bActionGroup *agrp; - FCurve *fcu; - if (ELEM(nullptr, act, rna_path)) { return nullptr; } @@ -44,66 +41,68 @@ FCurve *action_fcurve_ensure(Main *bmain, * - add if not found and allowed to add one * TODO: add auto-grouping support? how this works will need to be resolved */ - fcu = BKE_fcurve_find(&act->curves, rna_path, array_index); + FCurve *fcu = BKE_fcurve_find(&act->curves, rna_path, array_index); - if (fcu == nullptr) { - fcu = BKE_fcurve_create(); - - fcu->flag = (FCURVE_VISIBLE | FCURVE_SELECTED); - fcu->auto_smoothing = U.auto_smoothing_new; - if (BLI_listbase_is_empty(&act->curves)) { - fcu->flag |= FCURVE_ACTIVE; - } - - fcu->rna_path = BLI_strdup(rna_path); - fcu->array_index = array_index; - - if (group) { - agrp = BKE_action_group_find_name(act, group); - - if (agrp == nullptr) { - agrp = action_groups_add_new(act, group); - - /* sync bone group colors if applicable */ - if (ptr && (ptr->type == &RNA_PoseBone)) { - bPoseChannel *pchan = static_cast(ptr->data); - action_group_colors_set_from_posebone(agrp, pchan); - } - } - - action_groups_add_channel(act, agrp, fcu); - } - else { - BLI_addtail(&act->curves, fcu); - } - - /* New f-curve was added, meaning it's possible that it affects - * dependency graph component which wasn't previously animated. - */ - DEG_relations_tag_update(bmain); + if (fcu != nullptr) { + return fcu; } + fcu = BKE_fcurve_create(); + + fcu->flag = (FCURVE_VISIBLE | FCURVE_SELECTED); + fcu->auto_smoothing = U.auto_smoothing_new; + if (BLI_listbase_is_empty(&act->curves)) { + fcu->flag |= FCURVE_ACTIVE; + } + + fcu->rna_path = BLI_strdup(rna_path); + fcu->array_index = array_index; + + if (group) { + bActionGroup *agrp = BKE_action_group_find_name(act, group); + + if (agrp == nullptr) { + agrp = action_groups_add_new(act, group); + + /* Sync bone group colors if applicable. */ + if (ptr && (ptr->type == &RNA_PoseBone)) { + bPoseChannel *pchan = static_cast(ptr->data); + action_group_colors_set_from_posebone(agrp, pchan); + } + } + + action_groups_add_channel(act, agrp, fcu); + } + else { + BLI_addtail(&act->curves, fcu); + } + + /* New f-curve was added, meaning it's possible that it affects + * dependency graph component which wasn't previously animated. + */ + DEG_relations_tag_update(bmain); + return fcu; } bool delete_keyframe_fcurve(AnimData *adt, FCurve *fcu, float cfra) { bool found; - int i; - i = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, cfra, fcu->totvert, &found); - if (found) { - /* Delete the key at the index (will sanity check + do recalc afterwards). */ - BKE_fcurve_delete_key(fcu, i); - BKE_fcurve_handles_recalc(fcu); - - /* Empty curves get automatically deleted. */ - if (BKE_fcurve_is_empty(fcu)) { - ANIM_fcurve_delete_from_animdata(nullptr, adt, fcu); - } - - return true; + const int index = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, cfra, fcu->totvert, &found); + if (!found) { + return false; } - return false; + + /* Delete the key at the index (will sanity check + do recalc afterwards). */ + BKE_fcurve_delete_key(fcu, index); + BKE_fcurve_handles_recalc(fcu); + + /* Empty curves get automatically deleted. */ + if (BKE_fcurve_is_empty(fcu)) { + ANIM_fcurve_delete_from_animdata(nullptr, adt, fcu); + } + + return true; } } // namespace blender::animrig From ecbb77c5584f7cb9f07eb65c5f4969f930c2070f Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Tue, 7 Nov 2023 10:59:33 +0100 Subject: [PATCH 38/62] UI: Support dragging over node panel headers to batch (un)collapse Makes it possible to swipe over panel header to batch open/collapse all panels the mouse draged over. Normal panels and sub-panels support this too. Two changes were needed: - Support "drag toggle" feature for `UI_BTYPE_BUT_TOGGLE` - all toggle buttons should/can support this. - Allow querying the pushed state from the button used for the collapsing. Multiple ways to do this, in this case simply using the pushed state query callback seemed simplest. Pull Request: https://projects.blender.org/blender/blender/pulls/114560 --- source/blender/editors/interface/interface.cc | 1 + source/blender/editors/space_node/node_draw.cc | 1 + 2 files changed, 2 insertions(+) diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc index 95c974e300f..b2524a48416 100644 --- a/source/blender/editors/interface/interface.cc +++ b/source/blender/editors/interface/interface.cc @@ -2454,6 +2454,7 @@ bool ui_but_is_bool(const uiBut *but) UI_BTYPE_ICON_TOGGLE_N, UI_BTYPE_CHECKBOX, UI_BTYPE_CHECKBOX_N, + UI_BTYPE_BUT_TOGGLE, UI_BTYPE_TAB)) { return true; diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index f8250f2651e..43d1fd29211 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -2228,6 +2228,7 @@ static void node_draw_panels(bNodeTree &ntree, const bNode &node, uiBlock &block 0.0f, 0.0f, ""); + UI_but_func_pushed_state_set(but, [&state](const uiBut &) { return state.is_collapsed(); }); UI_but_func_set( but, node_panel_toggle_button_cb, const_cast(&state), &ntree); From 2f8499415b00a34a528a66e94d1c56cd07f9b859 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 7 Nov 2023 11:04:03 +0100 Subject: [PATCH 39/62] Fix (studio-reported) VSE crash when Text strips use missing fonts. BLF code is not threadsafe, yet font loading gets called over and over by text strips when the font file is missing, including e.g. from depsgraph evaluation code when duplicating the strip for evaluation. WARNING: This is a quick fix for deblocking the Blender studio, proper fix (and report) still needs to be worked on. --- source/blender/sequencer/intern/effects.cc | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/source/blender/sequencer/intern/effects.cc b/source/blender/sequencer/intern/effects.cc index b96e116d80b..b2da0f6f405 100644 --- a/source/blender/sequencer/intern/effects.cc +++ b/source/blender/sequencer/intern/effects.cc @@ -3251,10 +3251,19 @@ void SEQ_effect_text_font_load(TextVars *data, const bool do_id_user) else { char filepath[FILE_MAX]; STRNCPY(filepath, vfont->filepath); - BLI_assert(BLI_thread_is_main()); - BLI_path_abs(filepath, ID_BLEND_PATH_FROM_GLOBAL(&vfont->id)); + if (BLI_thread_is_main()) { + /* FIXME: This is a band-aid fix. A proper solution has to be worked on by the VSE team. + * + * This code can be called from non-main thread, e.g. when copying sequences as part of + * depsgraph CoW copy of the evaluated scene. Just skip font loading in that case, BLF code + * is not thread-safe, and if this happens from threaded context, it almost certainly means + * that a previous atempt to load the font already failed, e.g. because font filepath is + * invalid. Propoer fix would likely be to not attempt to reload a failed-to-load font every + * time. */ + BLI_path_abs(filepath, ID_BLEND_PATH_FROM_GLOBAL(&vfont->id)); - data->text_blf_id = BLF_load(filepath); + data->text_blf_id = BLF_load(filepath); + } } } From 17b875fccf8a7cffce7474864205fa6f1a14ab0f Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 7 Nov 2023 11:19:03 +0100 Subject: [PATCH 40/62] Fix: Windows build error from missing template argument deduction --- source/blender/draw/intern/attribute_convert.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/draw/intern/attribute_convert.cc b/source/blender/draw/intern/attribute_convert.cc index 19c12766169..45e4e2cf4af 100644 --- a/source/blender/draw/intern/attribute_convert.cc +++ b/source/blender/draw/intern/attribute_convert.cc @@ -39,7 +39,8 @@ void vertbuf_data_extract_direct(const GSpan attribute, GPUVertBuf &vbo) using Converter = AttributeConverter; using VBOType = typename Converter::VBOType; const Span src = attribute.typed(); - MutableSpan data(static_cast(GPU_vertbuf_get_data(&vbo)), attribute.size()); + MutableSpan data(static_cast(GPU_vertbuf_get_data(&vbo)), + attribute.size()); if constexpr (std::is_same_v) { array_utils::copy(src, data); } From 051ce95628934e8853f21a4716f24869f545f0d1 Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Tue, 7 Nov 2023 11:20:16 +0100 Subject: [PATCH 41/62] Cycles: Use Metal Program Scope Global Built-ins on macOS >= 14.0 This PR simplifies the kernel entrypoints by using [Metal Program Scope Global Built-ins](https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf) when available (macOS >= 14.0). Pull Request: https://projects.blender.org/blender/blender/pulls/114535 --- intern/cycles/device/metal/device_impl.mm | 5 +++ intern/cycles/kernel/device/metal/compat.h | 38 ++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/intern/cycles/device/metal/device_impl.mm b/intern/cycles/device/metal/device_impl.mm index bf409ed4d33..1da437798da 100644 --- a/intern/cycles/device/metal/device_impl.mm +++ b/intern/cycles/device/metal/device_impl.mm @@ -343,6 +343,11 @@ string MetalDevice::preprocess_source(MetalPipelineType pso_type, } } + if (@available(macos 14.0, *)) { + /* Use Program Scope Global Built-ins, when available. */ + global_defines += "#define __METAL_GLOBAL_BUILTINS__\n"; + } + # ifdef WITH_CYCLES_DEBUG global_defines += "#define __KERNEL_DEBUG__\n"; # endif diff --git a/intern/cycles/kernel/device/metal/compat.h b/intern/cycles/kernel/device/metal/compat.h index 8e2e0e342ee..ccd47455dc3 100644 --- a/intern/cycles/kernel/device/metal/compat.h +++ b/intern/cycles/kernel/device/metal/compat.h @@ -108,6 +108,31 @@ using namespace metal::raytracing; /* Generate a struct containing the entry-point parameters and a "run" * method which can access them implicitly via this-> */ + +#ifdef __METAL_GLOBAL_BUILTINS__ + +#define ccl_gpu_kernel_signature(name, ...) \ +struct kernel_gpu_##name \ +{ \ + PARAMS_MAKER(__VA_ARGS__)(__VA_ARGS__) \ + void run(thread MetalKernelContext& context, \ + threadgroup atomic_int *threadgroup_array) ccl_global const; \ +}; \ +kernel void cycles_metal_##name(device const kernel_gpu_##name *params_struct, \ + constant KernelParamsMetal &ccl_restrict _launch_params_metal, \ + constant MetalAncillaries *_metal_ancillaries, \ + threadgroup atomic_int *threadgroup_array[[ threadgroup(0) ]]) { \ + MetalKernelContext context(_launch_params_metal, _metal_ancillaries); \ + params_struct->run(context, threadgroup_array); \ +} \ +void kernel_gpu_##name::run(thread MetalKernelContext& context, \ + threadgroup atomic_int *threadgroup_array) ccl_global const + +#else + +/* On macOS versions before 14.x, builtin constants (e.g. metal_global_id) must + * be accessed through attributed entrypoint parameters. */ + #define ccl_gpu_kernel_signature(name, ...) \ struct kernel_gpu_##name \ { \ @@ -149,6 +174,8 @@ void kernel_gpu_##name::run(thread MetalKernelContext& context, \ uint simd_group_index, \ uint num_simd_groups) ccl_global const +#endif /* __METAL_GLOBAL_BUILTINS__ */ + #define ccl_gpu_kernel_postfix #define ccl_gpu_kernel_call(x) context.x #define ccl_gpu_kernel_within_bounds(i,n) true @@ -365,3 +392,14 @@ constant constexpr array metal_samplers = { sampler(address::clamp_to_zero, filter::linear), sampler(address::mirrored_repeat, filter::linear), }; + +#ifdef __METAL_GLOBAL_BUILTINS__ +const uint metal_global_id [[thread_position_in_grid]]; +const ushort metal_local_id [[thread_position_in_threadgroup]]; +const ushort metal_local_size [[threads_per_threadgroup]]; +const uint metal_grid_id [[threadgroup_position_in_grid]]; +const uint simdgroup_size [[threads_per_simdgroup]]; +const uint simd_lane_index [[thread_index_in_simdgroup]]; +const uint simd_group_index [[simdgroup_index_in_threadgroup]]; +const uint num_simd_groups [[simdgroups_per_threadgroup]]; +#endif /* __METAL_GLOBAL_BUILTINS__ */ \ No newline at end of file From 9ecd1063070fcfaed387c71e2df11dbe10ab703d Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 7 Nov 2023 11:34:41 +0100 Subject: [PATCH 42/62] Fix (unreported) VSE crash when duplicating 4 or more strips. Regression caused by typo in 3fccfe0bc637... --- source/blender/sequencer/intern/iterator.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/sequencer/intern/iterator.cc b/source/blender/sequencer/intern/iterator.cc index e8549ce0c02..d955d1a5c07 100644 --- a/source/blender/sequencer/intern/iterator.cc +++ b/source/blender/sequencer/intern/iterator.cc @@ -79,7 +79,7 @@ void SEQ_iterator_set_expand(const Scene *scene, } /* Merge all expanded results in provided VectorSet. */ - query_matches.add_multiple(query_matches); + strips.add_multiple(query_matches); } static void query_all_strips_recursive(ListBase *seqbase, VectorSet &strips) From 67dda08deab7a58fff61ac8948be888d0f21c135 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 7 Nov 2023 12:22:11 +0100 Subject: [PATCH 43/62] VSE: Cleanup: Simplify code in iterator by de-duplicating logic. No reason to do the same exact thing in two different functions. --- source/blender/sequencer/intern/iterator.cc | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/source/blender/sequencer/intern/iterator.cc b/source/blender/sequencer/intern/iterator.cc index d955d1a5c07..daae48f4c32 100644 --- a/source/blender/sequencer/intern/iterator.cc +++ b/source/blender/sequencer/intern/iterator.cc @@ -95,13 +95,7 @@ static void query_all_strips_recursive(ListBase *seqbase, VectorSet VectorSet SEQ_query_all_strips_recursive(ListBase *seqbase) { static VectorSet strips; - LISTBASE_FOREACH (Sequence *, seq, seqbase) { - if (seq->type == SEQ_TYPE_META) { - query_all_strips_recursive(&seq->seqbase, strips); - } - strips.add(seq); - } - + query_all_strips_recursive(seqbase, strips); return strips; } From 869372ffc33517a1dcd7a7a72bd899f9a1176d48 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 7 Nov 2023 12:49:09 +0100 Subject: [PATCH 44/62] Fix (studio-reported) VSE crash when deleting strips. Caused by 3fccfe0bc6 again, no idea why these two VertorSet were defined as static variables in the functions generating them... But this was for sure calling for _lots_ of problem. There are almost never good cases for a function to return a static variable, and if it's done, it has to be done extremely carefully. --- source/blender/sequencer/intern/iterator.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/sequencer/intern/iterator.cc b/source/blender/sequencer/intern/iterator.cc index daae48f4c32..e2ec62a4891 100644 --- a/source/blender/sequencer/intern/iterator.cc +++ b/source/blender/sequencer/intern/iterator.cc @@ -94,14 +94,14 @@ static void query_all_strips_recursive(ListBase *seqbase, VectorSet VectorSet SEQ_query_all_strips_recursive(ListBase *seqbase) { - static VectorSet strips; + VectorSet strips; query_all_strips_recursive(seqbase, strips); return strips; } VectorSet SEQ_query_all_strips(ListBase *seqbase) { - static VectorSet strips; + VectorSet strips; LISTBASE_FOREACH (Sequence *, strip, seqbase) { strips.add(strip); } From 02b41a5d235ce1c4767962e492f30d216413da17 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Tue, 7 Nov 2023 13:17:43 +0100 Subject: [PATCH 45/62] Refactor: Move code for actions into its own file No functional changes. Moving the following functions `action_fcurve_ensure` and `action_fcurve_find` from `ANIM_fcurve.hh`/`fcurve.cc` to `ANIM_action.hh`/`action.cc` This is an effort to ensure that the fcurve files don't need to know about the container they are stored in so we can swap out the container more easily. Pull Request: https://projects.blender.org/blender/blender/pulls/114575 --- source/blender/animrig/ANIM_action.hh | 33 +++++++ source/blender/animrig/ANIM_fcurve.hh | 17 ---- source/blender/animrig/CMakeLists.txt | 2 + source/blender/animrig/intern/action.cc | 86 +++++++++++++++++++ source/blender/animrig/intern/fcurve.cc | 72 ---------------- source/blender/animrig/intern/keyframing.cc | 1 + .../animation/anim_channels_defines.cc | 2 +- .../editors/gpencil_legacy/gpencil_convert.cc | 2 +- .../editors/object/object_constraint.cc | 2 +- .../editors/object/object_relations.cc | 2 +- source/blender/makesrna/intern/rna_action.cc | 2 +- 11 files changed, 127 insertions(+), 94 deletions(-) create mode 100644 source/blender/animrig/ANIM_action.hh create mode 100644 source/blender/animrig/intern/action.cc diff --git a/source/blender/animrig/ANIM_action.hh b/source/blender/animrig/ANIM_action.hh new file mode 100644 index 00000000000..365aa11d1ad --- /dev/null +++ b/source/blender/animrig/ANIM_action.hh @@ -0,0 +1,33 @@ +/* SPDX-FileCopyrightText: 2023 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup animrig + * + * \brief Functions to work with Actions. + */ + +#include "RNA_types.hh" + +struct FCurve; +struct bAction; + +namespace blender::animrig { +/** + * Get (or add relevant data to be able to do so) F-Curve from the given Action, + * for the given Animation Data block. This assumes that all the destinations are valid. + */ +FCurve *action_fcurve_ensure(Main *bmain, + bAction *act, + const char group[], + PointerRNA *ptr, + const char rna_path[], + int array_index); + +/** + * Find the F-Curve from the given Action. This assumes that all the destinations are valid. + */ +FCurve *action_fcurve_find(bAction *act, const char rna_path[], int array_index); + +} // namespace blender::animrig \ No newline at end of file diff --git a/source/blender/animrig/ANIM_fcurve.hh b/source/blender/animrig/ANIM_fcurve.hh index 0122fc959db..2a16f672370 100644 --- a/source/blender/animrig/ANIM_fcurve.hh +++ b/source/blender/animrig/ANIM_fcurve.hh @@ -15,23 +15,6 @@ struct FCurve; struct bAction; namespace blender::animrig { - -/** - * Get (or add relevant data to be able to do so) F-Curve from the given Action, - * for the given Animation Data block. This assumes that all the destinations are valid. - */ -FCurve *action_fcurve_ensure(Main *bmain, - bAction *act, - const char group[], - PointerRNA *ptr, - const char rna_path[], - int array_index); - -/** - * Find the F-Curve from the given Action. This assumes that all the destinations are valid. - */ -FCurve *action_fcurve_find(bAction *act, const char rna_path[], int array_index); - /** * \note The caller needs to run #BKE_nla_tweakedit_remap to get NLA relative frame. * The caller should also check #BKE_fcurve_is_protected before keying. diff --git a/source/blender/animrig/CMakeLists.txt b/source/blender/animrig/CMakeLists.txt index b2d69506874..d0bcc381f5d 100644 --- a/source/blender/animrig/CMakeLists.txt +++ b/source/blender/animrig/CMakeLists.txt @@ -20,6 +20,7 @@ set(INC_SYS ) set(SRC + intern/action.cc intern/anim_rna.cc intern/bone_collections.cc intern/bonecolor.cc @@ -28,6 +29,7 @@ set(SRC intern/keyframing_auto.cc intern/visualkey.cc + ANIM_action.hh ANIM_armature_iter.hh ANIM_bone_collections.h ANIM_bone_collections.hh diff --git a/source/blender/animrig/intern/action.cc b/source/blender/animrig/intern/action.cc new file mode 100644 index 00000000000..9ddcf7bb363 --- /dev/null +++ b/source/blender/animrig/intern/action.cc @@ -0,0 +1,86 @@ +/* SPDX-FileCopyrightText: 2023 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup animrig + */ + +#include "ANIM_action.hh" +#include "BKE_action.h" +#include "BKE_fcurve.h" +#include "BLI_listbase.h" +#include "BLI_string.h" +#include "DEG_depsgraph_build.hh" +#include "DNA_anim_types.h" +#include "RNA_prototypes.h" + +namespace blender::animrig { + +FCurve *action_fcurve_find(bAction *act, const char rna_path[], const int array_index) +{ + if (ELEM(nullptr, act, rna_path)) { + return nullptr; + } + return BKE_fcurve_find(&act->curves, rna_path, array_index); +} + +FCurve *action_fcurve_ensure(Main *bmain, + bAction *act, + const char group[], + PointerRNA *ptr, + const char rna_path[], + const int array_index) +{ + if (ELEM(nullptr, act, rna_path)) { + return nullptr; + } + + /* try to find f-curve matching for this setting + * - add if not found and allowed to add one + * TODO: add auto-grouping support? how this works will need to be resolved + */ + FCurve *fcu = BKE_fcurve_find(&act->curves, rna_path, array_index); + + if (fcu != nullptr) { + return fcu; + } + + fcu = BKE_fcurve_create(); + + fcu->flag = (FCURVE_VISIBLE | FCURVE_SELECTED); + fcu->auto_smoothing = U.auto_smoothing_new; + if (BLI_listbase_is_empty(&act->curves)) { + fcu->flag |= FCURVE_ACTIVE; + } + + fcu->rna_path = BLI_strdup(rna_path); + fcu->array_index = array_index; + + if (group) { + bActionGroup *agrp = BKE_action_group_find_name(act, group); + + if (agrp == nullptr) { + agrp = action_groups_add_new(act, group); + + /* Sync bone group colors if applicable. */ + if (ptr && (ptr->type == &RNA_PoseBone)) { + bPoseChannel *pchan = static_cast(ptr->data); + action_group_colors_set_from_posebone(agrp, pchan); + } + } + + action_groups_add_channel(act, agrp, fcu); + } + else { + BLI_addtail(&act->curves, fcu); + } + + /* New f-curve was added, meaning it's possible that it affects + * dependency graph component which wasn't previously animated. + */ + DEG_relations_tag_update(bmain); + + return fcu; +} +} // namespace blender::animrig \ No newline at end of file diff --git a/source/blender/animrig/intern/fcurve.cc b/source/blender/animrig/intern/fcurve.cc index 4f1089312c9..f8f492bcd7b 100644 --- a/source/blender/animrig/intern/fcurve.cc +++ b/source/blender/animrig/intern/fcurve.cc @@ -7,84 +7,12 @@ */ #include "ANIM_fcurve.hh" -#include "BKE_action.h" #include "BKE_fcurve.h" -#include "BLI_listbase.h" -#include "BLI_string.h" -#include "DEG_depsgraph_build.hh" #include "DNA_anim_types.h" #include "ED_anim_api.hh" -#include "RNA_prototypes.h" namespace blender::animrig { -FCurve *action_fcurve_find(bAction *act, const char rna_path[], const int array_index) -{ - if (ELEM(nullptr, act, rna_path)) { - return nullptr; - } - return BKE_fcurve_find(&act->curves, rna_path, array_index); -} - -FCurve *action_fcurve_ensure(Main *bmain, - bAction *act, - const char group[], - PointerRNA *ptr, - const char rna_path[], - const int array_index) -{ - if (ELEM(nullptr, act, rna_path)) { - return nullptr; - } - - /* try to find f-curve matching for this setting - * - add if not found and allowed to add one - * TODO: add auto-grouping support? how this works will need to be resolved - */ - FCurve *fcu = BKE_fcurve_find(&act->curves, rna_path, array_index); - - if (fcu != nullptr) { - return fcu; - } - - fcu = BKE_fcurve_create(); - - fcu->flag = (FCURVE_VISIBLE | FCURVE_SELECTED); - fcu->auto_smoothing = U.auto_smoothing_new; - if (BLI_listbase_is_empty(&act->curves)) { - fcu->flag |= FCURVE_ACTIVE; - } - - fcu->rna_path = BLI_strdup(rna_path); - fcu->array_index = array_index; - - if (group) { - bActionGroup *agrp = BKE_action_group_find_name(act, group); - - if (agrp == nullptr) { - agrp = action_groups_add_new(act, group); - - /* Sync bone group colors if applicable. */ - if (ptr && (ptr->type == &RNA_PoseBone)) { - bPoseChannel *pchan = static_cast(ptr->data); - action_group_colors_set_from_posebone(agrp, pchan); - } - } - - action_groups_add_channel(act, agrp, fcu); - } - else { - BLI_addtail(&act->curves, fcu); - } - - /* New f-curve was added, meaning it's possible that it affects - * dependency graph component which wasn't previously animated. - */ - DEG_relations_tag_update(bmain); - - return fcu; -} - bool delete_keyframe_fcurve(AnimData *adt, FCurve *fcu, float cfra) { bool found; diff --git a/source/blender/animrig/intern/keyframing.cc b/source/blender/animrig/intern/keyframing.cc index c5352861e62..96ebfff525a 100644 --- a/source/blender/animrig/intern/keyframing.cc +++ b/source/blender/animrig/intern/keyframing.cc @@ -9,6 +9,7 @@ #include #include +#include "ANIM_action.hh" #include "ANIM_fcurve.hh" #include "ANIM_keyframing.hh" #include "ANIM_rna.hh" diff --git a/source/blender/editors/animation/anim_channels_defines.cc b/source/blender/editors/animation/anim_channels_defines.cc index 1cda66c76c6..23455350acd 100644 --- a/source/blender/editors/animation/anim_channels_defines.cc +++ b/source/blender/editors/animation/anim_channels_defines.cc @@ -8,7 +8,7 @@ #include -#include "ANIM_fcurve.hh" +#include "ANIM_action.hh" #include "ANIM_keyframing.hh" #include "MEM_guardedalloc.h" diff --git a/source/blender/editors/gpencil_legacy/gpencil_convert.cc b/source/blender/editors/gpencil_legacy/gpencil_convert.cc index 4b69ebd5684..62813c39b86 100644 --- a/source/blender/editors/gpencil_legacy/gpencil_convert.cc +++ b/source/blender/editors/gpencil_legacy/gpencil_convert.cc @@ -66,7 +66,7 @@ #include "UI_resources.hh" #include "UI_view2d.hh" -#include "ANIM_fcurve.hh" +#include "ANIM_action.hh" #include "ANIM_keyframing.hh" #include "ED_clip.hh" diff --git a/source/blender/editors/object/object_constraint.cc b/source/blender/editors/object/object_constraint.cc index ac6c48eac7a..49105286cf1 100644 --- a/source/blender/editors/object/object_constraint.cc +++ b/source/blender/editors/object/object_constraint.cc @@ -60,7 +60,7 @@ #include "ED_object.hh" #include "ED_screen.hh" -#include "ANIM_fcurve.hh" +#include "ANIM_action.hh" #include "UI_interface.hh" #include "UI_resources.hh" diff --git a/source/blender/editors/object/object_relations.cc b/source/blender/editors/object/object_relations.cc index f7acd16c951..968711d0d74 100644 --- a/source/blender/editors/object/object_relations.cc +++ b/source/blender/editors/object/object_relations.cc @@ -103,7 +103,7 @@ #include "ED_screen.hh" #include "ED_view3d.hh" -#include "ANIM_fcurve.hh" +#include "ANIM_action.hh" #include "MOD_nodes.hh" diff --git a/source/blender/makesrna/intern/rna_action.cc b/source/blender/makesrna/intern/rna_action.cc index 7fe8664ab81..fddf3f048eb 100644 --- a/source/blender/makesrna/intern/rna_action.cc +++ b/source/blender/makesrna/intern/rna_action.cc @@ -36,7 +36,7 @@ # include "DEG_depsgraph.hh" -# include "ANIM_fcurve.hh" +# include "ANIM_action.hh" # include "WM_api.hh" From d08582c4d6b6a3af954ecca29f8ab9a185ca00fe Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Tue, 7 Nov 2023 13:20:46 +0100 Subject: [PATCH 46/62] Cleanup: Remove unused declaration and include No functional changes. --- source/blender/animrig/ANIM_fcurve.hh | 3 --- 1 file changed, 3 deletions(-) diff --git a/source/blender/animrig/ANIM_fcurve.hh b/source/blender/animrig/ANIM_fcurve.hh index 2a16f672370..1f1c4fd6c2a 100644 --- a/source/blender/animrig/ANIM_fcurve.hh +++ b/source/blender/animrig/ANIM_fcurve.hh @@ -8,11 +8,8 @@ * \brief Functions to modify FCurves. */ -#include "RNA_types.hh" - struct AnimData; struct FCurve; -struct bAction; namespace blender::animrig { /** From 5c6c71e6e8838c72724bd0ae8f8be5581ce78281 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 7 Nov 2023 23:20:58 +1100 Subject: [PATCH 47/62] Build: prevent OpenSSL using /etc/ssl on macOS & Linux Using /etc/ssl only makes sense when the versions of SSL on the system is compatible with the version Blender uses. Failure to load the configuration for e.g. causes SSL to fail entirely (causing downloading over HTTPS to fail). Recently [0] de facto standard directory `/etc/ssl` was used however we can't guarantee files in this path are compatible with Blender's SSL. Use a known invalid path to resolve #114452. Ref !114569 [0]: 60a8ae7830acd09c3d8e9ab52630d48ecd4d281b --- build_files/build_environment/cmake/ssl.cmake | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/build_files/build_environment/cmake/ssl.cmake b/build_files/build_environment/cmake/ssl.cmake index dff24addf00..12df8ea0e14 100644 --- a/build_files/build_environment/cmake/ssl.cmake +++ b/build_files/build_environment/cmake/ssl.cmake @@ -37,16 +37,14 @@ else() PREFIX ${BUILD_DIR}/ssl CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/ssl/src/external_ssl/ && ${SSL_CONFIGURE_COMMAND} --prefix=${LIBDIR}/ssl --openssldir=${LIBDIR}/ssl - # Without this: Python will use the build directories: - # To see these values in use, check the output of `ssl.get_default_verify_paths()`. - # This definition causes the following values to be set: - # - `capath='/etc/ssl/certs'` - # - `openssl_cafile='/etc/ssl/cert.pem'` - # - `openssl_capath='/etc/ssl/certs'` - # Note that the output from the command `openssl info -configdir` on the users system - # would be ideal but this is more involved. + # Without this: Python will use the build directories. + # using the system directory `/etc/ssl` might seem the obvious choice, + # there is no guarantee the version of SSL used with Blender is compatible with the systems, + # where changes to the SSL configuration format can cause SSL not to load (see #114452). + # So reference a directory known not to exist. Ideally Blender could distribute it's own SSL + # directory, but this isn't compatible with hard coded paths. # See #111132 & https://github.com/openssl/openssl/issues/20185 for details. - -DOPENSSLDIR=\\"/etc/ssl\\" + -DOPENSSLDIR=\\"/dev/null\\" no-shared no-idea no-mdc2 no-rc5 no-zlib no-ssl3 enable-unit-test no-ssl3-method enable-rfc3779 enable-cms --config=${CMAKE_CURRENT_SOURCE_DIR}/cmake/ssl.conf From 93278b55d407aa2f626230287786a26d0827dde0 Mon Sep 17 00:00:00 2001 From: Alexander Wilms Date: Tue, 24 Oct 2023 17:05:30 +0200 Subject: [PATCH 48/62] Linux: Improve metainfo file - Add OARS info, tags and screenshot captions - Change metainfo file extension from the deprecated ".appdata.xml" to. - Update bugtracker and help URL tags in metainfo file. - The metainfo file is now installed. - The file now passes flatpak validation. Ref !114115 --- ...pdata.xml => org.blender.Blender.metainfo.xml} | 15 ++++++++++++--- source/creator/CMakeLists.txt | 4 ++++ 2 files changed, 16 insertions(+), 3 deletions(-) rename release/freedesktop/{org.blender.Blender.appdata.xml => org.blender.Blender.metainfo.xml} (96%) diff --git a/release/freedesktop/org.blender.Blender.appdata.xml b/release/freedesktop/org.blender.Blender.metainfo.xml similarity index 96% rename from release/freedesktop/org.blender.Blender.appdata.xml rename to release/freedesktop/org.blender.Blender.metainfo.xml index bfa2cf49733..dc3833beb06 100644 --- a/release/freedesktop/org.blender.Blender.appdata.xml +++ b/release/freedesktop/org.blender.Blender.metainfo.xml @@ -22,20 +22,28 @@

https://www.blender.org + https://projects.blender.org/blender/blender/issues?q=&labels=296 + https://www.blender.org/support/faq/ https://www.blender.org/support/ - https://developer.blender.org - https://www.blender.org/foundation/donation-payment/ + https://fund.blender.org/ + https://wiki.blender.org/wiki/Process/Translate_Blender + https://projects.blender.org/blender/blender + https://www.blender.org/get-involved/ + Sculpt https://download.blender.org/demo/screenshots/blender_screenshot_1.jpg + Model https://download.blender.org/demo/screenshots/blender_screenshot_2.jpg + Animate https://download.blender.org/demo/screenshots/blender_screenshot_3.jpg + Edit & Grade https://download.blender.org/demo/screenshots/blender_screenshot_4.jpg @@ -377,5 +385,6 @@ - + + diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 8c8c88326b7..76ab4e90f72 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -693,6 +693,10 @@ if(UNIX AND NOT APPLE) FILES ${CMAKE_SOURCE_DIR}/release/freedesktop/blender.desktop DESTINATION "./share/applications" ) + install( + FILES ${CMAKE_SOURCE_DIR}/release/freedesktop/org.blender.Blender.metainfo.xml + DESTINATION "./share/metainfo" + ) install( FILES ${CMAKE_SOURCE_DIR}/release/freedesktop/icons/scalable/apps/blender.svg DESTINATION "./share/icons/hicolor/scalable/apps" From 69a3c5c7fc48633bf8745716caf65ddec615b2ef Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Tue, 7 Nov 2023 14:33:52 +0100 Subject: [PATCH 49/62] Refactor: move code related to fcurve keyframe insertion No functional changes. Move the functions `insert_vert_fcurve` and `insert_bezt_fcurve` from `ED_keyframing.hh` / `keyframing.cc` to `ANIM_fcurve.hh` / `fcurve.cc` in animrig Pull Request: https://projects.blender.org/blender/blender/pulls/114570 --- source/blender/animrig/ANIM_fcurve.hh | 33 +++ source/blender/animrig/intern/fcurve.cc | 270 ++++++++++++++++++ source/blender/editors/animation/drivers.cc | 6 +- .../editors/animation/keyframes_general.cc | 22 +- .../blender/editors/animation/keyframing.cc | 265 ----------------- source/blender/editors/armature/pose_slide.cc | 5 +- .../blender/editors/include/ED_keyframing.hh | 32 --- .../editors/space_action/action_edit.cc | 3 +- .../blender/editors/space_graph/graph_edit.cc | 7 +- .../blender/io/collada/AnimationImporter.cpp | 6 +- .../blender/io/collada/BCAnimationCurve.cpp | 8 +- source/blender/io/collada/BCAnimationCurve.h | 3 +- source/blender/io/usd/CMakeLists.txt | 1 + .../blender/io/usd/intern/usd_skel_convert.cc | 4 +- source/blender/makesrna/intern/rna_fcurve.cc | 14 +- 15 files changed, 352 insertions(+), 327 deletions(-) diff --git a/source/blender/animrig/ANIM_fcurve.hh b/source/blender/animrig/ANIM_fcurve.hh index 1f1c4fd6c2a..9908231f7eb 100644 --- a/source/blender/animrig/ANIM_fcurve.hh +++ b/source/blender/animrig/ANIM_fcurve.hh @@ -8,6 +8,7 @@ * \brief Functions to modify FCurves. */ +#include "DNA_anim_types.h" struct AnimData; struct FCurve; @@ -18,4 +19,36 @@ namespace blender::animrig { */ bool delete_keyframe_fcurve(AnimData *adt, FCurve *fcu, float cfra); +/** + * \brief Lesser Key-framing API call. + * + * Use this when validation of necessary animation data isn't necessary as it already + * exists, and there is a #BezTriple that can be directly copied into the array. + * + * This function adds a given #BezTriple to an F-Curve. It will allocate + * memory for the array if needed, and will insert the #BezTriple into a + * suitable place in chronological order. + * + * \note any recalculate of the F-Curve that needs to be done will need to be done by the caller. + */ +int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag); + +/** + * \brief Main Key-framing API call. + * + * Use this when validation of necessary animation data isn't necessary as it + * already exists. It will insert a keyframe using the current value being keyframed. + * Returns the index at which a keyframe was added (or -1 if failed). + * + * This function is a wrapper for #insert_bezt_fcurve(), and should be used when + * adding a new keyframe to a curve, when the keyframe doesn't exist anywhere else yet. + * It returns the index at which the keyframe was added. + * + * \param keyframe_type: The type of keyframe (#eBezTriple_KeyframeType). + * \param flag: Optional flags (#eInsertKeyFlags) for controlling how keys get added + * and/or whether updates get done. + */ +int insert_vert_fcurve( + FCurve *fcu, float x, float y, eBezTriple_KeyframeType keyframe_type, eInsertKeyFlags flag); + } // namespace blender::animrig diff --git a/source/blender/animrig/intern/fcurve.cc b/source/blender/animrig/intern/fcurve.cc index f8f492bcd7b..fdfdbb5a21f 100644 --- a/source/blender/animrig/intern/fcurve.cc +++ b/source/blender/animrig/intern/fcurve.cc @@ -6,10 +6,14 @@ * \ingroup animrig */ +#include +#include + #include "ANIM_fcurve.hh" #include "BKE_fcurve.h" #include "DNA_anim_types.h" #include "ED_anim_api.hh" +#include "MEM_guardedalloc.h" namespace blender::animrig { @@ -33,4 +37,270 @@ bool delete_keyframe_fcurve(AnimData *adt, FCurve *fcu, float cfra) return true; } + +/* ************************************************** */ +/* KEYFRAME INSERTION */ + +/* -------------- BezTriple Insertion -------------------- */ + +/* Change the Y position of a keyframe to match the input, adjusting handles. */ +static void replace_bezt_keyframe_ypos(BezTriple *dst, const BezTriple *bezt) +{ + /* just change the values when replacing, so as to not overwrite handles */ + float dy = bezt->vec[1][1] - dst->vec[1][1]; + + /* just apply delta value change to the handle values */ + dst->vec[0][1] += dy; + dst->vec[1][1] += dy; + dst->vec[2][1] += dy; + + dst->f1 = bezt->f1; + dst->f2 = bezt->f2; + dst->f3 = bezt->f3; + + /* TODO: perform some other operations? */ +} + +int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag) +{ + int i = 0; + + /* are there already keyframes? */ + if (fcu->bezt) { + bool replace; + i = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, bezt->vec[1][0], fcu->totvert, &replace); + + /* replace an existing keyframe? */ + if (replace) { + /* sanity check: 'i' may in rare cases exceed arraylen */ + if ((i >= 0) && (i < fcu->totvert)) { + if (flag & INSERTKEY_OVERWRITE_FULL) { + fcu->bezt[i] = *bezt; + } + else { + replace_bezt_keyframe_ypos(&fcu->bezt[i], bezt); + } + + if (flag & INSERTKEY_CYCLE_AWARE) { + /* If replacing an end point of a cyclic curve without offset, + * modify the other end too. */ + if (ELEM(i, 0, fcu->totvert - 1) && BKE_fcurve_get_cycle_type(fcu) == FCU_CYCLE_PERFECT) + { + replace_bezt_keyframe_ypos(&fcu->bezt[i == 0 ? fcu->totvert - 1 : 0], bezt); + } + } + } + } + /* Keyframing modes allow not replacing the keyframe. */ + else if ((flag & INSERTKEY_REPLACE) == 0) { + /* insert new - if we're not restricted to replacing keyframes only */ + BezTriple *newb = static_cast( + MEM_callocN((fcu->totvert + 1) * sizeof(BezTriple), "beztriple")); + + /* Add the beztriples that should occur before the beztriple to be pasted + * (originally in fcu). */ + if (i > 0) { + memcpy(newb, fcu->bezt, i * sizeof(BezTriple)); + } + + /* add beztriple to paste at index i */ + *(newb + i) = *bezt; + + /* add the beztriples that occur after the beztriple to be pasted (originally in fcu) */ + if (i < fcu->totvert) { + memcpy(newb + i + 1, fcu->bezt + i, (fcu->totvert - i) * sizeof(BezTriple)); + } + + /* replace (+ free) old with new, only if necessary to do so */ + MEM_freeN(fcu->bezt); + fcu->bezt = newb; + + fcu->totvert++; + } + else { + return -1; + } + } + /* no keyframes already, but can only add if... + * 1) keyframing modes say that keyframes can only be replaced, so adding new ones won't know + * 2) there are no samples on the curve + * NOTE: maybe we may want to allow this later when doing samples -> bezt conversions, + * but for now, having both is asking for trouble + */ + else if ((flag & INSERTKEY_REPLACE) == 0 && (fcu->fpt == nullptr)) { + /* create new keyframes array */ + fcu->bezt = static_cast(MEM_callocN(sizeof(BezTriple), "beztriple")); + *(fcu->bezt) = *bezt; + fcu->totvert = 1; + } + /* cannot add anything */ + else { + /* return error code -1 to prevent any misunderstandings */ + return -1; + } + + /* we need to return the index, so that some tools which do post-processing can + * detect where we added the BezTriple in the array + */ + return i; +} + +/** + * Update the FCurve to allow insertion of `bezt` without modifying the curve shape. + * + * Checks whether it is necessary to apply Bezier subdivision due to involvement of non-auto + * handles. If necessary, changes `bezt` handles from Auto to Aligned. + * + * \param bezt: key being inserted + * \param prev: keyframe before that key + * \param next: keyframe after that key + */ +static void subdivide_nonauto_handles(const FCurve *fcu, + BezTriple *bezt, + BezTriple *prev, + BezTriple *next) +{ + if (prev->ipo != BEZT_IPO_BEZ || bezt->ipo != BEZT_IPO_BEZ) { + return; + } + + /* Don't change Vector handles, or completely auto regions. */ + const bool bezt_auto = BEZT_IS_AUTOH(bezt) || (bezt->h1 == HD_VECT && bezt->h2 == HD_VECT); + const bool prev_auto = BEZT_IS_AUTOH(prev) || (prev->h2 == HD_VECT); + const bool next_auto = BEZT_IS_AUTOH(next) || (next->h1 == HD_VECT); + if (bezt_auto && prev_auto && next_auto) { + return; + } + + /* Subdivide the curve. */ + float delta; + if (!BKE_fcurve_bezt_subdivide_handles(bezt, prev, next, &delta)) { + return; + } + + /* Decide when to force auto to manual. */ + if (!BEZT_IS_AUTOH(bezt)) { + return; + } + if ((prev_auto || next_auto) && fcu->auto_smoothing == FCURVE_SMOOTH_CONT_ACCEL) { + const float hx = bezt->vec[1][0] - bezt->vec[0][0]; + const float dx = bezt->vec[1][0] - prev->vec[1][0]; + + /* This mode always uses 1/3 of key distance for handle x size. */ + const bool auto_works_well = fabsf(hx - dx / 3.0f) < 0.001f; + if (auto_works_well) { + return; + } + } + + /* Turn off auto mode. */ + bezt->h1 = bezt->h2 = HD_ALIGN; +} + +int insert_vert_fcurve( + FCurve *fcu, float x, float y, eBezTriple_KeyframeType keyframe_type, eInsertKeyFlags flag) +{ + BezTriple beztr = {{{0}}}; + uint oldTot = fcu->totvert; + int a; + + /* set all three points, for nicer start position + * NOTE: +/- 1 on vec.x for left and right handles is so that 'free' handles work ok... + */ + beztr.vec[0][0] = x - 1.0f; + beztr.vec[0][1] = y; + beztr.vec[1][0] = x; + beztr.vec[1][1] = y; + beztr.vec[2][0] = x + 1.0f; + beztr.vec[2][1] = y; + beztr.f1 = beztr.f2 = beztr.f3 = SELECT; + + /* set default handle types and interpolation mode */ + if (flag & INSERTKEY_NO_USERPREF) { + /* for Py-API, we want scripts to have predictable behavior, + * hence the option to not depend on the userpref defaults + */ + beztr.h1 = beztr.h2 = HD_AUTO_ANIM; + beztr.ipo = BEZT_IPO_BEZ; + } + else { + /* For UI usage - defaults should come from the user-preferences and/or tool-settings. */ + beztr.h1 = beztr.h2 = U.keyhandles_new; /* use default handle type here */ + + /* use default interpolation mode, with exceptions for int/discrete values */ + beztr.ipo = U.ipo_new; + } + + /* interpolation type used is constrained by the type of values the curve can take */ + if (fcu->flag & FCURVE_DISCRETE_VALUES) { + beztr.ipo = BEZT_IPO_CONST; + } + else if ((beztr.ipo == BEZT_IPO_BEZ) && (fcu->flag & FCURVE_INT_VALUES)) { + beztr.ipo = BEZT_IPO_LIN; + } + + /* set keyframe type value (supplied), which should come from the scene settings in most cases */ + BEZKEYTYPE(&beztr) = keyframe_type; + + /* set default values for "easing" interpolation mode settings + * NOTE: Even if these modes aren't currently used, if users switch + * to these later, we want these to work in a sane way out of + * the box. + */ + + /* "back" easing - this value used to be used when overshoot=0, but that + * introduced discontinuities in how the param worked. */ + beztr.back = 1.70158f; + + /* "elastic" easing - values here were hand-optimized for a default duration of + * ~10 frames (typical mograph motion length) */ + beztr.amplitude = 0.8f; + beztr.period = 4.1f; + + /* add temp beztriple to keyframes */ + a = insert_bezt_fcurve(fcu, &beztr, flag); + BKE_fcurve_active_keyframe_set(fcu, &fcu->bezt[a]); + + /* what if 'a' is a negative index? + * for now, just exit to prevent any segfaults + */ + if (a < 0) { + return -1; + } + + /* Set handle-type and interpolation. */ + if ((fcu->totvert > 2) && (flag & INSERTKEY_REPLACE) == 0) { + BezTriple *bezt = (fcu->bezt + a); + + /* Set interpolation from previous (if available), + * but only if we didn't just replace some keyframe: + * - Replacement is indicated by no-change in number of verts. + * - When replacing, the user may have specified some interpolation that should be kept. + */ + if (fcu->totvert > oldTot) { + if (a > 0) { + bezt->ipo = (bezt - 1)->ipo; + } + else if (a < fcu->totvert - 1) { + bezt->ipo = (bezt + 1)->ipo; + } + + if (0 < a && a < (fcu->totvert - 1) && (flag & INSERTKEY_OVERWRITE_FULL) == 0) { + subdivide_nonauto_handles(fcu, bezt, bezt - 1, bezt + 1); + } + } + } + + /* don't recalculate handles if fast is set + * - this is a hack to make importers faster + * - we may calculate twice (due to auto-handle needing to be calculated twice) + */ + if ((flag & INSERTKEY_FAST) == 0) { + BKE_fcurve_handles_recalc(fcu); + } + + /* return the index at which the keyframe was added */ + return a; +} + } // namespace blender::animrig diff --git a/source/blender/editors/animation/drivers.cc b/source/blender/editors/animation/drivers.cc index 7e733025d10..4ece9a66933 100644 --- a/source/blender/editors/animation/drivers.cc +++ b/source/blender/editors/animation/drivers.cc @@ -43,6 +43,8 @@ #include "RNA_path.hh" #include "RNA_prototypes.h" +#include "ANIM_fcurve.hh" + #include "anim_intern.h" /* ************************************************** */ @@ -122,9 +124,9 @@ FCurve *alloc_driver_fcurve(const char rna_path[], * - These are configured to 0,0 and 1,1 to give a 1-1 mapping * which can be easily tweaked from there. */ - insert_vert_fcurve( + blender::animrig::insert_vert_fcurve( fcu, 0.0f, 0.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST | INSERTKEY_NO_USERPREF); - insert_vert_fcurve( + blender::animrig::insert_vert_fcurve( fcu, 1.0f, 1.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST | INSERTKEY_NO_USERPREF); fcu->extend = FCURVE_EXTRAPOLATE_LINEAR; BKE_fcurve_handles_recalc(fcu); diff --git a/source/blender/editors/animation/keyframes_general.cc b/source/blender/editors/animation/keyframes_general.cc index 9b550859b49..f1c1434bb15 100644 --- a/source/blender/editors/animation/keyframes_general.cc +++ b/source/blender/editors/animation/keyframes_general.cc @@ -38,6 +38,8 @@ #include "ED_keyframes_edit.hh" #include "ED_keyframing.hh" +#include "ANIM_fcurve.hh" + /* This file contains code for various keyframe-editing tools which are 'destructive' * (i.e. they will modify the order of the keyframes, and change the size of the array). * While some of these tools may eventually be moved out into blenkernel, for now, it is @@ -117,7 +119,7 @@ void clean_fcurve(bAnimContext *ac, /* now insert first keyframe, as it should be ok */ bezt = old_bezts; - insert_bezt_fcurve(fcu, bezt, eInsertKeyFlags(0)); + blender::animrig::insert_bezt_fcurve(fcu, bezt, eInsertKeyFlags(0)); if (!(bezt->f2 & SELECT)) { lastb = fcu->bezt; lastb->f1 = lastb->f2 = lastb->f3 = 0; @@ -149,7 +151,7 @@ void clean_fcurve(bAnimContext *ac, cur[1] = bezt->vec[1][1]; if (only_selected_keys && !(bezt->f2 & SELECT)) { - insert_bezt_fcurve(fcu, bezt, eInsertKeyFlags(0)); + blender::animrig::insert_bezt_fcurve(fcu, bezt, eInsertKeyFlags(0)); lastb = (fcu->bezt + (fcu->totvert - 1)); lastb->f1 = lastb->f2 = lastb->f3 = 0; continue; @@ -166,7 +168,7 @@ void clean_fcurve(bAnimContext *ac, if (cur[1] > next[1]) { if (IS_EQT(cur[1], prev[1], thresh) == 0) { /* add new keyframe */ - insert_bezt_fcurve(fcu, bezt, eInsertKeyFlags(0)); + blender::animrig::insert_bezt_fcurve(fcu, bezt, eInsertKeyFlags(0)); } } } @@ -174,7 +176,7 @@ void clean_fcurve(bAnimContext *ac, /* only add if values are a considerable distance apart */ if (IS_EQT(cur[1], prev[1], thresh) == 0) { /* add new keyframe */ - insert_bezt_fcurve(fcu, bezt, eInsertKeyFlags(0)); + blender::animrig::insert_bezt_fcurve(fcu, bezt, eInsertKeyFlags(0)); } } } @@ -184,18 +186,18 @@ void clean_fcurve(bAnimContext *ac, /* does current have same value as previous and next? */ if (IS_EQT(cur[1], prev[1], thresh) == 0) { /* add new keyframe */ - insert_bezt_fcurve(fcu, bezt, eInsertKeyFlags(0)); + blender::animrig::insert_bezt_fcurve(fcu, bezt, eInsertKeyFlags(0)); } else if (IS_EQT(cur[1], next[1], thresh) == 0) { /* add new keyframe */ - insert_bezt_fcurve(fcu, bezt, eInsertKeyFlags(0)); + blender::animrig::insert_bezt_fcurve(fcu, bezt, eInsertKeyFlags(0)); } } else { /* add if value doesn't equal that of previous */ if (IS_EQT(cur[1], prev[1], thresh) == 0) { /* add new keyframe */ - insert_bezt_fcurve(fcu, bezt, eInsertKeyFlags(0)); + blender::animrig::insert_bezt_fcurve(fcu, bezt, eInsertKeyFlags(0)); } } } @@ -1077,7 +1079,7 @@ bool decimate_fcurve(bAnimListElem *ale, float remove_ratio, float error_sq_max) BezTriple *bezt = (old_bezts + i); bezt->f2 &= ~BEZT_FLAG_IGNORE_TAG; if ((bezt->f2 & BEZT_FLAG_TEMP_TAG) == 0) { - insert_bezt_fcurve(fcu, bezt, eInsertKeyFlags(0)); + blender::animrig::insert_bezt_fcurve(fcu, bezt, eInsertKeyFlags(0)); } } /* now free the memory used by the old BezTriples */ @@ -1270,7 +1272,7 @@ void bake_fcurve_segments(FCurve *fcu) /* add keyframes with these, tagging as 'breakdowns' */ for (n = 1, fp = value_cache; n < range && fp; n++, fp++) { - insert_vert_fcurve( + blender::animrig::insert_vert_fcurve( fcu, fp->frame, fp->val, BEZT_KEYTYPE_BREAKDOWN, eInsertKeyFlags(1)); } @@ -1712,7 +1714,7 @@ static void paste_animedit_keys_fcurve( * NOTE: we do not want to inherit handles from existing keyframes in this case! */ - insert_bezt_fcurve(fcu, bezt, INSERTKEY_OVERWRITE_FULL); + blender::animrig::insert_bezt_fcurve(fcu, bezt, INSERTKEY_OVERWRITE_FULL); /* un-apply offset from src beztriple after copying */ sub_v2_v2(bezt->vec[0], offset); diff --git a/source/blender/editors/animation/keyframing.cc b/source/blender/editors/animation/keyframing.cc index 17e06fc825d..41a912ad5cc 100644 --- a/source/blender/editors/animation/keyframing.cc +++ b/source/blender/editors/animation/keyframing.cc @@ -212,271 +212,6 @@ void update_autoflags_fcurve(FCurve *fcu, bContext *C, ReportList *reports, Poin } } -/* ************************************************** */ -/* KEYFRAME INSERTION */ - -/* -------------- BezTriple Insertion -------------------- */ - -/* Change the Y position of a keyframe to match the input, adjusting handles. */ -static void replace_bezt_keyframe_ypos(BezTriple *dst, const BezTriple *bezt) -{ - /* just change the values when replacing, so as to not overwrite handles */ - float dy = bezt->vec[1][1] - dst->vec[1][1]; - - /* just apply delta value change to the handle values */ - dst->vec[0][1] += dy; - dst->vec[1][1] += dy; - dst->vec[2][1] += dy; - - dst->f1 = bezt->f1; - dst->f2 = bezt->f2; - dst->f3 = bezt->f3; - - /* TODO: perform some other operations? */ -} - -int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag) -{ - int i = 0; - - /* are there already keyframes? */ - if (fcu->bezt) { - bool replace; - i = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, bezt->vec[1][0], fcu->totvert, &replace); - - /* replace an existing keyframe? */ - if (replace) { - /* sanity check: 'i' may in rare cases exceed arraylen */ - if ((i >= 0) && (i < fcu->totvert)) { - if (flag & INSERTKEY_OVERWRITE_FULL) { - fcu->bezt[i] = *bezt; - } - else { - replace_bezt_keyframe_ypos(&fcu->bezt[i], bezt); - } - - if (flag & INSERTKEY_CYCLE_AWARE) { - /* If replacing an end point of a cyclic curve without offset, - * modify the other end too. */ - if (ELEM(i, 0, fcu->totvert - 1) && BKE_fcurve_get_cycle_type(fcu) == FCU_CYCLE_PERFECT) - { - replace_bezt_keyframe_ypos(&fcu->bezt[i == 0 ? fcu->totvert - 1 : 0], bezt); - } - } - } - } - /* Keyframing modes allow not replacing the keyframe. */ - else if ((flag & INSERTKEY_REPLACE) == 0) { - /* insert new - if we're not restricted to replacing keyframes only */ - BezTriple *newb = static_cast( - MEM_callocN((fcu->totvert + 1) * sizeof(BezTriple), "beztriple")); - - /* Add the beztriples that should occur before the beztriple to be pasted - * (originally in fcu). */ - if (i > 0) { - memcpy(newb, fcu->bezt, i * sizeof(BezTriple)); - } - - /* add beztriple to paste at index i */ - *(newb + i) = *bezt; - - /* add the beztriples that occur after the beztriple to be pasted (originally in fcu) */ - if (i < fcu->totvert) { - memcpy(newb + i + 1, fcu->bezt + i, (fcu->totvert - i) * sizeof(BezTriple)); - } - - /* replace (+ free) old with new, only if necessary to do so */ - MEM_freeN(fcu->bezt); - fcu->bezt = newb; - - fcu->totvert++; - } - else { - return -1; - } - } - /* no keyframes already, but can only add if... - * 1) keyframing modes say that keyframes can only be replaced, so adding new ones won't know - * 2) there are no samples on the curve - * NOTE: maybe we may want to allow this later when doing samples -> bezt conversions, - * but for now, having both is asking for trouble - */ - else if ((flag & INSERTKEY_REPLACE) == 0 && (fcu->fpt == nullptr)) { - /* create new keyframes array */ - fcu->bezt = static_cast(MEM_callocN(sizeof(BezTriple), "beztriple")); - *(fcu->bezt) = *bezt; - fcu->totvert = 1; - } - /* cannot add anything */ - else { - /* return error code -1 to prevent any misunderstandings */ - return -1; - } - - /* we need to return the index, so that some tools which do post-processing can - * detect where we added the BezTriple in the array - */ - return i; -} - -/** - * Update the FCurve to allow insertion of `bezt` without modifying the curve shape. - * - * Checks whether it is necessary to apply Bezier subdivision due to involvement of non-auto - * handles. If necessary, changes `bezt` handles from Auto to Aligned. - * - * \param bezt: key being inserted - * \param prev: keyframe before that key - * \param next: keyframe after that key - */ -static void subdivide_nonauto_handles(const FCurve *fcu, - BezTriple *bezt, - BezTriple *prev, - BezTriple *next) -{ - if (prev->ipo != BEZT_IPO_BEZ || bezt->ipo != BEZT_IPO_BEZ) { - return; - } - - /* Don't change Vector handles, or completely auto regions. */ - const bool bezt_auto = BEZT_IS_AUTOH(bezt) || (bezt->h1 == HD_VECT && bezt->h2 == HD_VECT); - const bool prev_auto = BEZT_IS_AUTOH(prev) || (prev->h2 == HD_VECT); - const bool next_auto = BEZT_IS_AUTOH(next) || (next->h1 == HD_VECT); - if (bezt_auto && prev_auto && next_auto) { - return; - } - - /* Subdivide the curve. */ - float delta; - if (!BKE_fcurve_bezt_subdivide_handles(bezt, prev, next, &delta)) { - return; - } - - /* Decide when to force auto to manual. */ - if (!BEZT_IS_AUTOH(bezt)) { - return; - } - if ((prev_auto || next_auto) && fcu->auto_smoothing == FCURVE_SMOOTH_CONT_ACCEL) { - const float hx = bezt->vec[1][0] - bezt->vec[0][0]; - const float dx = bezt->vec[1][0] - prev->vec[1][0]; - - /* This mode always uses 1/3 of key distance for handle x size. */ - const bool auto_works_well = fabsf(hx - dx / 3.0f) < 0.001f; - if (auto_works_well) { - return; - } - } - - /* Turn off auto mode. */ - bezt->h1 = bezt->h2 = HD_ALIGN; -} - -int insert_vert_fcurve( - FCurve *fcu, float x, float y, eBezTriple_KeyframeType keyframe_type, eInsertKeyFlags flag) -{ - BezTriple beztr = {{{0}}}; - uint oldTot = fcu->totvert; - int a; - - /* set all three points, for nicer start position - * NOTE: +/- 1 on vec.x for left and right handles is so that 'free' handles work ok... - */ - beztr.vec[0][0] = x - 1.0f; - beztr.vec[0][1] = y; - beztr.vec[1][0] = x; - beztr.vec[1][1] = y; - beztr.vec[2][0] = x + 1.0f; - beztr.vec[2][1] = y; - beztr.f1 = beztr.f2 = beztr.f3 = SELECT; - - /* set default handle types and interpolation mode */ - if (flag & INSERTKEY_NO_USERPREF) { - /* for Py-API, we want scripts to have predictable behavior, - * hence the option to not depend on the userpref defaults - */ - beztr.h1 = beztr.h2 = HD_AUTO_ANIM; - beztr.ipo = BEZT_IPO_BEZ; - } - else { - /* For UI usage - defaults should come from the user-preferences and/or tool-settings. */ - beztr.h1 = beztr.h2 = U.keyhandles_new; /* use default handle type here */ - - /* use default interpolation mode, with exceptions for int/discrete values */ - beztr.ipo = U.ipo_new; - } - - /* interpolation type used is constrained by the type of values the curve can take */ - if (fcu->flag & FCURVE_DISCRETE_VALUES) { - beztr.ipo = BEZT_IPO_CONST; - } - else if ((beztr.ipo == BEZT_IPO_BEZ) && (fcu->flag & FCURVE_INT_VALUES)) { - beztr.ipo = BEZT_IPO_LIN; - } - - /* set keyframe type value (supplied), which should come from the scene settings in most cases */ - BEZKEYTYPE(&beztr) = keyframe_type; - - /* set default values for "easing" interpolation mode settings - * NOTE: Even if these modes aren't currently used, if users switch - * to these later, we want these to work in a sane way out of - * the box. - */ - - /* "back" easing - this value used to be used when overshoot=0, but that - * introduced discontinuities in how the param worked. */ - beztr.back = 1.70158f; - - /* "elastic" easing - values here were hand-optimized for a default duration of - * ~10 frames (typical mograph motion length) */ - beztr.amplitude = 0.8f; - beztr.period = 4.1f; - - /* add temp beztriple to keyframes */ - a = insert_bezt_fcurve(fcu, &beztr, flag); - BKE_fcurve_active_keyframe_set(fcu, &fcu->bezt[a]); - - /* what if 'a' is a negative index? - * for now, just exit to prevent any segfaults - */ - if (a < 0) { - return -1; - } - - /* Set handle-type and interpolation. */ - if ((fcu->totvert > 2) && (flag & INSERTKEY_REPLACE) == 0) { - BezTriple *bezt = (fcu->bezt + a); - - /* Set interpolation from previous (if available), - * but only if we didn't just replace some keyframe: - * - Replacement is indicated by no-change in number of verts. - * - When replacing, the user may have specified some interpolation that should be kept. - */ - if (fcu->totvert > oldTot) { - if (a > 0) { - bezt->ipo = (bezt - 1)->ipo; - } - else if (a < fcu->totvert - 1) { - bezt->ipo = (bezt + 1)->ipo; - } - - if (0 < a && a < (fcu->totvert - 1) && (flag & INSERTKEY_OVERWRITE_FULL) == 0) { - subdivide_nonauto_handles(fcu, bezt, bezt - 1, bezt + 1); - } - } - } - - /* don't recalculate handles if fast is set - * - this is a hack to make importers faster - * - we may calculate twice (due to auto-handle needing to be calculated twice) - */ - if ((flag & INSERTKEY_FAST) == 0) { - BKE_fcurve_handles_recalc(fcu); - } - - /* return the index at which the keyframe was added */ - return a; -} - /* ------------------------- Insert Key API ------------------------- */ void ED_keyframes_add(FCurve *fcu, int num_keys_to_add) diff --git a/source/blender/editors/armature/pose_slide.cc b/source/blender/editors/armature/pose_slide.cc index 038b60acd6b..7d8aba50f47 100644 --- a/source/blender/editors/armature/pose_slide.cc +++ b/source/blender/editors/armature/pose_slide.cc @@ -67,13 +67,14 @@ #include "ED_armature.hh" #include "ED_keyframes_edit.hh" #include "ED_keyframes_keylist.hh" -#include "ED_keyframing.hh" #include "ED_markers.hh" #include "ED_numinput.hh" #include "ED_screen.hh" #include "ED_space_api.hh" #include "ED_util.hh" +#include "ANIM_fcurve.hh" + #include "GPU_immediate.h" #include "GPU_immediate_util.h" #include "GPU_matrix.h" @@ -1740,7 +1741,7 @@ static void propagate_curve_values(ListBase /*tPChanFCurveLink*/ *pflinks, FCurve *fcu = (FCurve *)ld->data; const float current_fcu_value = evaluate_fcurve(fcu, source_frame); LISTBASE_FOREACH (FrameLink *, target_frame, target_frames) { - insert_vert_fcurve( + blender::animrig::insert_vert_fcurve( fcu, target_frame->frame, current_fcu_value, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NEEDED); } } diff --git a/source/blender/editors/include/ED_keyframing.hh b/source/blender/editors/include/ED_keyframing.hh index 5a78a358170..4c3d9b365b9 100644 --- a/source/blender/editors/include/ED_keyframing.hh +++ b/source/blender/editors/include/ED_keyframing.hh @@ -67,38 +67,6 @@ void update_autoflags_fcurve_direct(FCurve *fcu, PropertyRNA *prop); /* -------- */ -/** - * \brief Lesser Key-framing API call. - * - * Use this when validation of necessary animation data isn't necessary as it already - * exists, and there is a #BezTriple that can be directly copied into the array. - * - * This function adds a given #BezTriple to an F-Curve. It will allocate - * memory for the array if needed, and will insert the #BezTriple into a - * suitable place in chronological order. - * - * \note any recalculate of the F-Curve that needs to be done will need to be done by the caller. - */ -int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag); - -/** - * \brief Main Key-framing API call. - * - * Use this when validation of necessary animation data isn't necessary as it - * already exists. It will insert a keyframe using the current value being keyframed. - * Returns the index at which a keyframe was added (or -1 if failed). - * - * This function is a wrapper for #insert_bezt_fcurve(), and should be used when - * adding a new keyframe to a curve, when the keyframe doesn't exist anywhere else yet. - * It returns the index at which the keyframe was added. - * - * \param keyframe_type: The type of keyframe (#eBezTriple_KeyframeType). - * \param flag: Optional flags (#eInsertKeyFlags) for controlling how keys get added - * and/or whether updates get done. - */ -int insert_vert_fcurve( - FCurve *fcu, float x, float y, eBezTriple_KeyframeType keyframe_type, eInsertKeyFlags flag); - /** * Add the given number of keyframes to the FCurve. Their coordinates are * uninitialized, so the curve should not be used without further attention. diff --git a/source/blender/editors/space_action/action_edit.cc b/source/blender/editors/space_action/action_edit.cc index 263538a7e54..00aa1419747 100644 --- a/source/blender/editors/space_action/action_edit.cc +++ b/source/blender/editors/space_action/action_edit.cc @@ -43,6 +43,7 @@ #include "UI_view2d.hh" +#include "ANIM_fcurve.hh" #include "ANIM_keyframing.hh" #include "ED_anim_api.hh" #include "ED_gpencil_legacy.hh" @@ -859,7 +860,7 @@ static void insert_fcurve_key(bAnimContext *ac, } const float curval = evaluate_fcurve(fcu, cfra); - insert_vert_fcurve( + blender::animrig::insert_vert_fcurve( fcu, cfra, curval, eBezTriple_KeyframeType(ts->keyframe_type), eInsertKeyFlags(0)); } diff --git a/source/blender/editors/space_graph/graph_edit.cc b/source/blender/editors/space_graph/graph_edit.cc index a901686b1f2..343b329a0b0 100644 --- a/source/blender/editors/space_graph/graph_edit.cc +++ b/source/blender/editors/space_graph/graph_edit.cc @@ -47,6 +47,7 @@ #include "UI_interface.hh" #include "UI_view2d.hh" +#include "ANIM_fcurve.hh" #include "ANIM_keyframing.hh" #include "ED_anim_api.hh" #include "ED_keyframes_edit.hh" @@ -179,7 +180,7 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode) } /* Insert keyframe directly into the F-Curve. */ - insert_vert_fcurve( + blender::animrig::insert_vert_fcurve( fcu, x, y, eBezTriple_KeyframeType(ts->keyframe_type), eInsertKeyFlags(0)); ale->update |= ANIM_UPDATE_DEFAULT; @@ -228,7 +229,7 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode) } const float curval = evaluate_fcurve_only_curve(fcu, cfra); - insert_vert_fcurve( + blender::animrig::insert_vert_fcurve( fcu, cfra, curval, eBezTriple_KeyframeType(ts->keyframe_type), eInsertKeyFlags(0)); } @@ -345,7 +346,7 @@ static int graphkeys_click_insert_exec(bContext *C, wmOperator *op) val = val * scale - offset; /* Insert keyframe on the specified frame + value. */ - insert_vert_fcurve( + blender::animrig::insert_vert_fcurve( fcu, frame, val, eBezTriple_KeyframeType(ts->keyframe_type), eInsertKeyFlags(0)); ale->update |= ANIM_UPDATE_DEPS; diff --git a/source/blender/io/collada/AnimationImporter.cpp b/source/blender/io/collada/AnimationImporter.cpp index 80a49af58d8..5ed8026c697 100644 --- a/source/blender/io/collada/AnimationImporter.cpp +++ b/source/blender/io/collada/AnimationImporter.cpp @@ -15,6 +15,8 @@ #include "ED_keyframing.hh" +#include "ANIM_fcurve.hh" + #include "BLI_listbase.h" #include "BLI_math_matrix.h" #include "BLI_string.h" @@ -65,7 +67,7 @@ void AnimationImporter::add_bezt(FCurve *fcu, bez.ipo = ipo; /* use default interpolation mode here... */ bez.f1 = bez.f2 = bez.f3 = SELECT; bez.h1 = bez.h2 = HD_AUTO; - insert_bezt_fcurve(fcu, &bez, INSERTKEY_NOFLAGS); + blender::animrig::insert_bezt_fcurve(fcu, &bez, INSERTKEY_NOFLAGS); BKE_fcurve_handles_recalc(fcu); } @@ -132,7 +134,7 @@ void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve) #endif bez.f1 = bez.f2 = bez.f3 = SELECT; - insert_bezt_fcurve(fcu, &bez, INSERTKEY_NOFLAGS); + blender::animrig::insert_bezt_fcurve(fcu, &bez, INSERTKEY_NOFLAGS); } BKE_fcurve_handles_recalc(fcu); diff --git a/source/blender/io/collada/BCAnimationCurve.cpp b/source/blender/io/collada/BCAnimationCurve.cpp index a2cdd5df67f..cebab12a580 100644 --- a/source/blender/io/collada/BCAnimationCurve.cpp +++ b/source/blender/io/collada/BCAnimationCurve.cpp @@ -103,7 +103,7 @@ void BCAnimationCurve::create_bezt(float frame, float output) bez.ipo = U.ipo_new; /* use default interpolation mode here... */ bez.f1 = bez.f2 = bez.f3 = SELECT; bez.h1 = bez.h2 = HD_AUTO; - insert_bezt_fcurve(fcu, &bez, INSERTKEY_NOFLAGS); + blender::animrig::insert_bezt_fcurve(fcu, &bez, INSERTKEY_NOFLAGS); BKE_fcurve_handles_recalc(fcu); } @@ -315,7 +315,8 @@ void BCAnimationCurve::clean_handles() BezTriple *bezt = &old_bezts[i]; float x = bezt->vec[1][0]; float y = bezt->vec[1][1]; - insert_vert_fcurve(fcurve, x, y, (eBezTriple_KeyframeType)BEZKEYTYPE(bezt), INSERTKEY_NOFLAGS); + blender::animrig::insert_vert_fcurve( + fcurve, x, y, (eBezTriple_KeyframeType)BEZKEYTYPE(bezt), INSERTKEY_NOFLAGS); BezTriple *lastb = fcurve->bezt + (fcurve->totvert - 1); lastb->f1 = lastb->f2 = lastb->f3 = 0; } @@ -380,7 +381,8 @@ void BCAnimationCurve::add_value(const float val, const int frame_index) { FCurve *fcu = get_edit_fcurve(); fcu->auto_smoothing = U.auto_smoothing_new; - insert_vert_fcurve(fcu, frame_index, val, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NOFLAGS); + blender::animrig::insert_vert_fcurve( + fcu, frame_index, val, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NOFLAGS); if (fcu->totvert == 1) { init_range(val); diff --git a/source/blender/io/collada/BCAnimationCurve.h b/source/blender/io/collada/BCAnimationCurve.h index 919ba71fc64..0f552b0e954 100644 --- a/source/blender/io/collada/BCAnimationCurve.h +++ b/source/blender/io/collada/BCAnimationCurve.h @@ -15,7 +15,8 @@ #include "ED_anim_api.hh" #include "ED_keyframes_edit.hh" -#include "ED_keyframing.hh" + +#include "ANIM_fcurve.hh" typedef float(TangentPoint)[2]; diff --git a/source/blender/io/usd/CMakeLists.txt b/source/blender/io/usd/CMakeLists.txt index fa20dc94941..172bb37d1d7 100644 --- a/source/blender/io/usd/CMakeLists.txt +++ b/source/blender/io/usd/CMakeLists.txt @@ -186,6 +186,7 @@ set(LIB bf_blenkernel PRIVATE bf::blenlib PRIVATE bf::dna + PRIVATE bf::animrig bf_imbuf PRIVATE bf::intern::guardedalloc bf_io_common diff --git a/source/blender/io/usd/intern/usd_skel_convert.cc b/source/blender/io/usd/intern/usd_skel_convert.cc index de60076a648..6642376cdf0 100644 --- a/source/blender/io/usd/intern/usd_skel_convert.cc +++ b/source/blender/io/usd/intern/usd_skel_convert.cc @@ -41,6 +41,8 @@ #include "ED_keyframing.hh" #include "ED_mesh.hh" +#include "ANIM_fcurve.hh" + #include "WM_api.hh" #include @@ -93,7 +95,7 @@ void add_bezt(FCurve *fcu, bez.ipo = ipo; /* use default interpolation mode here... */ bez.f1 = bez.f2 = bez.f3 = SELECT; bez.h1 = bez.h2 = HD_AUTO; - insert_bezt_fcurve(fcu, &bez, INSERTKEY_NOFLAGS); + blender::animrig::insert_bezt_fcurve(fcu, &bez, INSERTKEY_NOFLAGS); } /** diff --git a/source/blender/makesrna/intern/rna_fcurve.cc b/source/blender/makesrna/intern/rna_fcurve.cc index 372ba22c972..c0588deff63 100644 --- a/source/blender/makesrna/intern/rna_fcurve.cc +++ b/source/blender/makesrna/intern/rna_fcurve.cc @@ -30,6 +30,10 @@ #include "ED_keyframes_edit.hh" #include "ED_keyframing.hh" +#ifdef RNA_RUNTIME +# include "ANIM_fcurve.hh" +#endif + const EnumPropertyItem rna_enum_fmodifier_type_items[] = { {FMODIFIER_TYPE_NULL, "nullptr", 0, "Invalid", ""}, {FMODIFIER_TYPE_GENERATOR, @@ -1051,11 +1055,11 @@ static void rna_FModifierStepped_frame_end_set(PointerRNA *ptr, float value) static BezTriple *rna_FKeyframe_points_insert( ID *id, FCurve *fcu, Main *bmain, float frame, float value, int keyframe_type, int flag) { - int index = insert_vert_fcurve(fcu, - frame, - value, - eBezTriple_KeyframeType(keyframe_type), - eInsertKeyFlags(flag) | INSERTKEY_NO_USERPREF); + int index = blender::animrig::insert_vert_fcurve(fcu, + frame, + value, + eBezTriple_KeyframeType(keyframe_type), + eInsertKeyFlags(flag) | INSERTKEY_NO_USERPREF); if ((fcu->bezt) && (index >= 0)) { rna_tag_animation_update(bmain, id); From adb216419177bd0bf0912d392eac9daf0b4f32af Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 7 Nov 2023 14:53:48 +0100 Subject: [PATCH 50/62] Draw: Add Region Info Debug Group Adding a deug group for draw manager region info so it is easier to find inside tools like renderdoc. Pull Request: https://projects.blender.org/blender/blender/pulls/114578 --- source/blender/draw/intern/draw_view_c.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/draw/intern/draw_view_c.cc b/source/blender/draw/intern/draw_view_c.cc index 05862ccf64f..8200dca4e63 100644 --- a/source/blender/draw/intern/draw_view_c.cc +++ b/source/blender/draw/intern/draw_view_c.cc @@ -17,6 +17,7 @@ #include "ED_util.hh" #include "ED_view3d.hh" +#include "GPU_debug.h" #include "GPU_immediate.h" #include "GPU_matrix.h" #include "GPU_shader.h" @@ -40,12 +41,14 @@ void DRW_draw_region_info() { + GPU_debug_group_begin("RegionInfo"); const DRWContextState *draw_ctx = DRW_context_state_get(); ARegion *region = draw_ctx->region; DRW_draw_cursor(); view3d_draw_region_info(draw_ctx->evil_C, region); + GPU_debug_group_end(); } /* **************************** 3D Cursor ******************************** */ From 73b15f341e06546c12ca572b2f8e68a992db1e3f Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 7 Nov 2023 14:59:28 +0100 Subject: [PATCH 51/62] Fix: Enable Vulkan Workarounds Vulkan workarounds could not be enabled by using the `--debug-gpu-force-workarounds` command line argument. This PR fixes this. Pull Request: https://projects.blender.org/blender/blender/pulls/114579 --- source/blender/gpu/vulkan/vk_backend.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/gpu/vulkan/vk_backend.cc b/source/blender/gpu/vulkan/vk_backend.cc index a354994c7f6..e28f42eebab 100644 --- a/source/blender/gpu/vulkan/vk_backend.cc +++ b/source/blender/gpu/vulkan/vk_backend.cc @@ -92,6 +92,7 @@ void VKBackend::detect_workarounds(VKDevice &device) workarounds.shader_output_layer = true; workarounds.shader_output_viewport_index = true; + device.workarounds_ = workarounds; return; } From b2bdfe946e0a80f58fe36a917f39d88cc8151499 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Tue, 7 Nov 2023 15:08:20 +0100 Subject: [PATCH 52/62] Fix: broken regression test fcurve_test.cc --- source/blender/blenkernel/intern/fcurve_test.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/blenkernel/intern/fcurve_test.cc b/source/blender/blenkernel/intern/fcurve_test.cc index 8c585f36db6..7b93a1ccce0 100644 --- a/source/blender/blenkernel/intern/fcurve_test.cc +++ b/source/blender/blenkernel/intern/fcurve_test.cc @@ -7,6 +7,8 @@ #include "BKE_fcurve.h" +#include "ANIM_fcurve.hh" + #include "ED_keyframing.hh" #include "DNA_anim_types.h" @@ -14,6 +16,7 @@ #include "BLI_math_vector_types.hh" namespace blender::bke::tests { +using namespace blender::animrig; /* Epsilon for floating point comparisons. */ static const float EPSILON = 1e-7f; From b4316445a8cbdbd59148a7a28af57dc9566e7f24 Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Tue, 7 Nov 2023 15:28:07 +0100 Subject: [PATCH 53/62] EEVEE-Next: Add Max Displacement option Add a Max Displacement option to Material settings, so frustum culling can work correctly with vertex displacement. Pull Request: https://projects.blender.org/blender/blender/pulls/114200 --- scripts/startup/bl_ui/properties_material.py | 3 +- .../draw/engines/eevee_next/eevee_instance.cc | 11 +++-- .../draw/engines/eevee_next/eevee_sync.cc | 44 +++++++++++++++---- .../draw/engines/eevee_next/eevee_sync.hh | 1 + source/blender/draw/intern/draw_manager.hh | 29 ++++++++++-- source/blender/draw/intern/draw_resource.hh | 12 ++++- .../blender/draw/intern/draw_shader_shared.h | 2 +- source/blender/gpu/GPU_material.h | 1 + source/blender/gpu/intern/gpu_material.cc | 7 +++ source/blender/makesdna/DNA_material_types.h | 5 +++ .../blender/makesrna/intern/rna_material.cc | 9 ++++ 11 files changed, 105 insertions(+), 19 deletions(-) diff --git a/scripts/startup/bl_ui/properties_material.py b/scripts/startup/bl_ui/properties_material.py index 74f7b3d0407..c48a2b9fde6 100644 --- a/scripts/startup/bl_ui/properties_material.py +++ b/scripts/startup/bl_ui/properties_material.py @@ -299,7 +299,8 @@ class EEVEE_NEXT_MATERIAL_PT_settings_surface(MaterialButtonsPanel, Panel): col.prop(mat, "use_backface_culling", text="Camera") col.prop(mat, "use_backface_culling_shadow", text="Shadow") - # TODO(fclem): Displacement option + layout.prop(mat, "max_vertex_displacement", text="Max Displacement") + layout.prop(mat, "use_transparent_shadow") col = layout.column() diff --git a/source/blender/draw/engines/eevee_next/eevee_instance.cc b/source/blender/draw/engines/eevee_next/eevee_instance.cc index df7a057be55..8dae3eb3ac5 100644 --- a/source/blender/draw/engines/eevee_next/eevee_instance.cc +++ b/source/blender/draw/engines/eevee_next/eevee_instance.cc @@ -196,6 +196,7 @@ void Instance::object_sync(Object *ob) OB_VOLUME, OB_LAMP, OB_LIGHTPROBE); + const bool is_drawable_type = is_renderable_type && !ELEM(ob->type, OB_LAMP, OB_LIGHTPROBE); const int ob_visibility = DRW_object_visibility_in_active_context(ob); const bool partsys_is_visible = (ob_visibility & OB_VISIBLE_PARTICLES) != 0 && (ob->type == OB_MESH); @@ -208,15 +209,17 @@ void Instance::object_sync(Object *ob) /* TODO cleanup. */ ObjectRef ob_ref = DRW_object_ref_get(ob); - ResourceHandle res_handle = manager->resource_handle(ob_ref); - ObjectHandle &ob_handle = sync.sync_object(ob); + ResourceHandle res_handle = {0}; + if (is_drawable_type) { + res_handle = manager->resource_handle(ob_ref); + } if (partsys_is_visible && ob != DRW_context_state_get()->object_edit) { auto sync_hair = [&](ObjectHandle hair_handle, ModifierData &md, ParticleSystem &particle_sys) { ResourceHandle _res_handle = manager->resource_handle(float4x4(ob->object_to_world)); - sync.sync_curves(ob, hair_handle, _res_handle, &md, &particle_sys); + sync.sync_curves(ob, hair_handle, _res_handle, ob_ref, &md, &particle_sys); }; foreach_hair_particle_handle(ob, ob_handle, sync_hair); } @@ -238,7 +241,7 @@ void Instance::object_sync(Object *ob) sync.sync_volume(ob, ob_handle, res_handle); break; case OB_CURVES: - sync.sync_curves(ob, ob_handle, res_handle); + sync.sync_curves(ob, ob_handle, res_handle, ob_ref); break; case OB_GPENCIL_LEGACY: sync.sync_gpencil(ob, ob_handle, res_handle); diff --git a/source/blender/draw/engines/eevee_next/eevee_sync.cc b/source/blender/draw/engines/eevee_next/eevee_sync.cc index 4184c99b4bf..a633a729b04 100644 --- a/source/blender/draw/engines/eevee_next/eevee_sync.cc +++ b/source/blender/draw/engines/eevee_next/eevee_sync.cc @@ -141,6 +141,7 @@ void SyncModule::sync_mesh(Object *ob, } bool is_alpha_blend = false; + float inflate_bounds = 0.0f; for (auto i : material_array.gpu_materials.index_range()) { GPUBatch *geom = mat_geom[i]; if (geom == nullptr) { @@ -176,6 +177,14 @@ void SyncModule::sync_mesh(Object *ob, ::Material *mat = GPU_material_get_material(gpu_material); inst_.cryptomatte.sync_material(mat); + + if (GPU_material_has_displacement_output(gpu_material)) { + inflate_bounds = math::max(inflate_bounds, mat->inflate_bounds); + } + } + + if (inflate_bounds != 0.0f) { + inst_.manager->update_handle_bounds(res_handle, ob_ref, inflate_bounds); } inst_.manager->extract_object_attributes(res_handle, ob_ref, material_array.gpu_materials); @@ -202,18 +211,11 @@ bool SyncModule::sync_sculpt(Object *ob, return false; } - /* Use a valid bounding box. The PBVH module already does its own culling, but a valid */ - /* bounding box is still needed for directional shadow tile-map bounds computation. */ - float3 min, max; - BKE_pbvh_bounding_box(ob_ref.object->sculpt->pbvh, min, max); - float3 center = (min + max) * 0.5; - float3 half_extent = max - center; - res_handle = inst_.manager->resource_handle(ob_ref, nullptr, ¢er, &half_extent); - bool has_motion = false; MaterialArray &material_array = inst_.materials.material_array_get(ob, has_motion); bool is_alpha_blend = false; + float inflate_bounds = 0.0f; for (SculptBatch &batch : sculpt_batches_per_material_get(ob_ref.object, material_array.gpu_materials)) { @@ -251,8 +253,21 @@ bool SyncModule::sync_sculpt(Object *ob, GPUMaterial *gpu_material = material_array.gpu_materials[batch.material_slot]; ::Material *mat = GPU_material_get_material(gpu_material); inst_.cryptomatte.sync_material(mat); + + if (GPU_material_has_displacement_output(gpu_material)) { + inflate_bounds = math::max(inflate_bounds, mat->inflate_bounds); + } } + /* Use a valid bounding box. The PBVH module already does its own culling, but a valid */ + /* bounding box is still needed for directional shadow tile-map bounds computation. */ + float3 min, max; + BKE_pbvh_bounding_box(ob_ref.object->sculpt->pbvh, min, max); + float3 center = (min + max) * 0.5; + float3 half_extent = max - center; + half_extent += inflate_bounds; + inst_.manager->update_handle_bounds(res_handle, center, half_extent); + inst_.manager->extract_object_attributes(res_handle, ob_ref, material_array.gpu_materials); inst_.shadows.sync_object(ob, ob_handle, res_handle, is_alpha_blend); @@ -270,7 +285,7 @@ bool SyncModule::sync_sculpt(Object *ob, void SyncModule::sync_point_cloud(Object *ob, ObjectHandle &ob_handle, ResourceHandle res_handle, - const ObjectRef & /*ob_ref*/) + const ObjectRef &ob_ref) { const int material_slot = POINTCLOUD_MATERIAL_NR; @@ -319,6 +334,11 @@ void SyncModule::sync_point_cloud(Object *ob, inst_.cryptomatte.sync_material(mat); bool is_alpha_blend = material.is_alpha_blend_transparent; + + if (GPU_material_has_displacement_output(gpu_material) && mat->inflate_bounds != 0.0f) { + inst_.manager->update_handle_bounds(res_handle, ob_ref, mat->inflate_bounds); + } + inst_.shadows.sync_object(ob, ob_handle, res_handle, is_alpha_blend); } @@ -494,6 +514,7 @@ void SyncModule::sync_gpencil(Object *ob, ObjectHandle &ob_handle, ResourceHandl void SyncModule::sync_curves(Object *ob, ObjectHandle &ob_handle, ResourceHandle res_handle, + const ObjectRef &ob_ref, ModifierData *modifier_data, ParticleSystem *particle_sys) { @@ -552,6 +573,11 @@ void SyncModule::sync_curves(Object *ob, inst_.cryptomatte.sync_material(mat); bool is_alpha_blend = material.is_alpha_blend_transparent; + + if (GPU_material_has_displacement_output(gpu_material) && mat->inflate_bounds != 0.0f) { + inst_.manager->update_handle_bounds(res_handle, ob_ref, mat->inflate_bounds); + } + inst_.shadows.sync_object(ob, ob_handle, res_handle, is_alpha_blend); } diff --git a/source/blender/draw/engines/eevee_next/eevee_sync.hh b/source/blender/draw/engines/eevee_next/eevee_sync.hh index e455b6b50fc..cdaf46777ab 100644 --- a/source/blender/draw/engines/eevee_next/eevee_sync.hh +++ b/source/blender/draw/engines/eevee_next/eevee_sync.hh @@ -161,6 +161,7 @@ class SyncModule { void sync_curves(Object *ob, ObjectHandle &ob_handle, ResourceHandle res_handle, + const ObjectRef &ob_ref, ModifierData *modifier_data = nullptr, ParticleSystem *particle_sys = nullptr); void sync_light_probe(Object *ob, ObjectHandle &ob_handle); diff --git a/source/blender/draw/intern/draw_manager.hh b/source/blender/draw/intern/draw_manager.hh index efb8732023e..30e871554b8 100644 --- a/source/blender/draw/intern/draw_manager.hh +++ b/source/blender/draw/intern/draw_manager.hh @@ -119,7 +119,7 @@ class Manager { /** * Create a new resource handle for the given object. */ - ResourceHandle resource_handle(const ObjectRef ref); + ResourceHandle resource_handle(const ObjectRef ref, float inflate_bounds = 0.0f); /** * Create a new resource handle for the given object, but optionally override model matrix and * bounds. @@ -142,6 +142,15 @@ class Manager { const float3 &bounds_center, const float3 &bounds_half_extent); + /** Update the bounds of an already created handle. */ + void update_handle_bounds(ResourceHandle handle, + const ObjectRef ref, + float inflate_bounds = 0.0f); + /** Update the bounds of an already created handle. */ + void update_handle_bounds(ResourceHandle handle, + const float3 &bounds_center, + const float3 &bounds_half_extent); + /** * Populate additional per resource data on demand. */ @@ -206,11 +215,11 @@ class Manager { void sync_layer_attributes(); }; -inline ResourceHandle Manager::resource_handle(const ObjectRef ref) +inline ResourceHandle Manager::resource_handle(const ObjectRef ref, float inflate_bounds) { bool is_active_object = (ref.dupli_object ? ref.dupli_parent : ref.object) == object_active; matrix_buf.current().get_or_resize(resource_len_).sync(*ref.object); - bounds_buf.current().get_or_resize(resource_len_).sync(*ref.object); + bounds_buf.current().get_or_resize(resource_len_).sync(*ref.object, inflate_bounds); infos_buf.current().get_or_resize(resource_len_).sync(ref, is_active_object); return ResourceHandle(resource_len_++, (ref.object->transflag & OB_NEG_SCALE) != 0); } @@ -255,6 +264,20 @@ inline ResourceHandle Manager::resource_handle(const float4x4 &model_matrix, return ResourceHandle(resource_len_++, false); } +inline void Manager::update_handle_bounds(ResourceHandle handle, + const ObjectRef ref, + float inflate_bounds) +{ + bounds_buf.current()[handle.resource_index()].sync(*ref.object, inflate_bounds); +} + +inline void Manager::update_handle_bounds(ResourceHandle handle, + const float3 &bounds_center, + const float3 &bounds_half_extent) +{ + bounds_buf.current()[handle.resource_index()].sync(bounds_center, bounds_half_extent); +} + inline void Manager::extract_object_attributes(ResourceHandle handle, const ObjectRef &ref, Span materials) diff --git a/source/blender/draw/intern/draw_resource.hh b/source/blender/draw/intern/draw_resource.hh index b8c5471d92c..5821ef65d6b 100644 --- a/source/blender/draw/intern/draw_resource.hh +++ b/source/blender/draw/intern/draw_resource.hh @@ -159,7 +159,7 @@ inline void ObjectBounds::sync() bounding_sphere.w = -1.0f; /* Disable test. */ } -inline void ObjectBounds::sync(Object &ob) +inline void ObjectBounds::sync(Object &ob, float inflate_bounds) { const std::optional bbox = BKE_object_boundbox_get(&ob); if (!bbox) { @@ -171,6 +171,16 @@ inline void ObjectBounds::sync(Object &ob) *reinterpret_cast(&bounding_corners[2]) = bbox->vec[3]; *reinterpret_cast(&bounding_corners[3]) = bbox->vec[1]; bounding_sphere.w = 0.0f; /* Enable test. */ + + if (inflate_bounds != 0.0f) { + BLI_assert(inflate_bounds >= 0.0f); + float p = inflate_bounds; + float n = -inflate_bounds; + bounding_corners[0] += float4(n, n, n, 0.0f); + bounding_corners[1] += float4(p, n, n, 0.0f); + bounding_corners[2] += float4(n, p, n, 0.0f); + bounding_corners[3] += float4(n, n, p, 0.0f); + } } inline void ObjectBounds::sync(const float3 ¢er, const float3 &size) diff --git a/source/blender/draw/intern/draw_shader_shared.h b/source/blender/draw/intern/draw_shader_shared.h index a4ff34091fc..887d4727212 100644 --- a/source/blender/draw/intern/draw_shader_shared.h +++ b/source/blender/draw/intern/draw_shader_shared.h @@ -204,7 +204,7 @@ struct ObjectBounds { #if !defined(GPU_SHADER) && defined(__cplusplus) void sync(); - void sync(Object &ob); + void sync(Object &ob, float inflate_bounds = 0.0f); void sync(const float3 ¢er, const float3 &size); #endif }; diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 403eb048fcc..e96903a576a 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -320,6 +320,7 @@ struct GPUUniformBuf *GPU_material_create_sss_profile_ubo(void); bool GPU_material_has_surface_output(GPUMaterial *mat); bool GPU_material_has_volume_output(GPUMaterial *mat); +bool GPU_material_has_displacement_output(GPUMaterial *mat); void GPU_material_flag_set(GPUMaterial *mat, eGPUMaterialFlag flag); bool GPU_material_flag_get(const GPUMaterial *mat, eGPUMaterialFlag flag); diff --git a/source/blender/gpu/intern/gpu_material.cc b/source/blender/gpu/intern/gpu_material.cc index c75169e1db5..967ed91acc7 100644 --- a/source/blender/gpu/intern/gpu_material.cc +++ b/source/blender/gpu/intern/gpu_material.cc @@ -130,6 +130,7 @@ struct GPUMaterial { /** DEPRECATED: To remove. */ bool has_surface_output; bool has_volume_output; + bool has_displacement_output; /** DEPRECATED: To remove. */ GPUUniformBuf *sss_profile; /* UBO containing SSS profile. */ GPUTexture *sss_tex_profile; /* Texture containing SSS profile. */ @@ -662,6 +663,7 @@ void GPU_material_output_displacement(GPUMaterial *material, GPUNodeLink *link) { if (!material->graph.outlink_displacement) { material->graph.outlink_displacement = link; + material->has_displacement_output = true; } } @@ -779,6 +781,11 @@ bool GPU_material_has_volume_output(GPUMaterial *mat) return mat->has_volume_output; } +bool GPU_material_has_displacement_output(GPUMaterial *mat) +{ + return mat->has_displacement_output; +} + void GPU_material_flag_set(GPUMaterial *mat, eGPUMaterialFlag flag) { mat->flag |= flag; diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index 159c34335ea..a1fa9a35ae1 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -221,6 +221,11 @@ typedef struct Material { /* Volume. */ char volume_intersection_method; + /* Displacement*/ + float inflate_bounds; + + char _pad3[4]; + /** * Cached slots for texture painting, must be refreshed in * refresh_texpaint_image_cache before using. diff --git a/source/blender/makesrna/intern/rna_material.cc b/source/blender/makesrna/intern/rna_material.cc index c11d0ea30d8..2d9f6650ffa 100644 --- a/source/blender/makesrna/intern/rna_material.cc +++ b/source/blender/makesrna/intern/rna_material.cc @@ -964,6 +964,15 @@ void RNA_def_material(BlenderRNA *brna) "Determines which inner part of the mesh will produce volumetric effect"); RNA_def_property_update(prop, 0, "rna_Material_draw_update"); + prop = RNA_def_property(srna, "max_vertex_displacement", PROP_FLOAT, PROP_DISTANCE); + RNA_def_property_float_sdna(prop, nullptr, "inflate_bounds"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_text(prop, + "Max Vertex Displacement", + "The max distance a vertex can be displaced." + "Displacements over this threshold may cause visibility issues"); + RNA_def_property_update(prop, 0, "rna_Material_draw_update"); + /* For Preview Render */ prop = RNA_def_property(srna, "preview_render_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, nullptr, "pr_type"); From d64e9759ef6ca27b0d8d2781f3fefcf9e6de9473 Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Tue, 7 Nov 2023 15:51:45 +0100 Subject: [PATCH 54/62] Fix #114377: Workbench: Support None and Channel Packed alpha modes --- .../blender/draw/engines/workbench/workbench_mesh_passes.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/blender/draw/engines/workbench/workbench_mesh_passes.cc b/source/blender/draw/engines/workbench/workbench_mesh_passes.cc index 1271a28707e..18b0e5bdadb 100644 --- a/source/blender/draw/engines/workbench/workbench_mesh_passes.cc +++ b/source/blender/draw/engines/workbench/workbench_mesh_passes.cc @@ -91,7 +91,11 @@ PassMain::Sub &MeshPass::get_subpass( /* TODO(@pragma37): This setting should be exposed on the user side, * either as a global parameter (and set it here) * or by reading the Material Clipping Threshold (and set it per material) */ - sub_pass->push_constant("imageTransparencyCutoff", 0.1f); + float alpha_cutoff = 0.1f; + if (ELEM(image->alpha_mode, IMA_ALPHA_IGNORE, IMA_ALPHA_CHANNEL_PACKED)) { + alpha_cutoff = -FLT_MAX; + } + sub_pass->push_constant("imageTransparencyCutoff", alpha_cutoff); return sub_pass; }; From 40dccc197544acdd7baa1adaf62d26b064b4a78f Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Tue, 7 Nov 2023 16:17:32 +0100 Subject: [PATCH 55/62] Anim: Unit tests for inserting keyframes Cover the current behavior of keyframe insertion with unit tests, so the changes planned in #113278 are less likely to break things. Unit tests added: InsertKeyTest very basic test to ensure keying things by name or with a keying set adds the right keys VisualKeyingTest check if visual keying produces the correct keyframe values CycleAwareKeyingTest check if cycle aware keying remaps the keyframes correctly and adds fcurve modifiers Pull Request: https://projects.blender.org/blender/blender/pulls/114465 --- tests/python/CMakeLists.txt | 7 + tests/python/bl_animation_keyframing.py | 218 ++++++++++++++++++++++++ 2 files changed, 225 insertions(+) create mode 100644 tests/python/bl_animation_keyframing.py diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index 55721fa4913..ae022b1462f 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -377,6 +377,13 @@ add_blender_test( --testdir "${TEST_SRC_DIR}/animation" ) +add_blender_test( + bl_animation_keyframing + --python ${CMAKE_CURRENT_LIST_DIR}/bl_animation_keyframing.py + -- + --testdir "${TEST_SRC_DIR}/animation" +) + add_blender_test( bl_rigging_symmetrize --python ${CMAKE_CURRENT_LIST_DIR}/bl_rigging_symmetrize.py diff --git a/tests/python/bl_animation_keyframing.py b/tests/python/bl_animation_keyframing.py new file mode 100644 index 00000000000..5eaf3460e87 --- /dev/null +++ b/tests/python/bl_animation_keyframing.py @@ -0,0 +1,218 @@ +# SPDX-FileCopyrightText: 2020-2023 Blender Authors +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import unittest +import bpy +import pathlib +import sys +from math import radians + +""" +blender -b -noaudio --factory-startup --python tests/python/bl_animation_keyframing.py -- --testdir /path/to/lib/tests/animation +""" + + +def _fcurve_paths_match(fcurves: list, expected_paths: list) -> bool: + data_paths = list(set([fcurve.data_path for fcurve in fcurves])) + return sorted(data_paths) == sorted(expected_paths) + + +def _get_view3d_context(): + ctx = bpy.context.copy() + + for area in bpy.context.window.screen.areas: + if area.type != 'VIEW_3D': + continue + + ctx['area'] = area + ctx['space'] = area.spaces.active + break + + return ctx + + +def _create_animation_object(): + anim_object = bpy.data.objects.new("anim_object", None) + # Ensure that the rotation mode is correct so we can check against rotation_euler + anim_object.rotation_mode = "XYZ" + bpy.context.scene.collection.objects.link(anim_object) + bpy.context.view_layer.objects.active = anim_object + anim_object.select_set(True) + return anim_object + + +def _insert_by_name_test(insert_key: str, expected_paths: list): + keyed_object = _create_animation_object() + with bpy.context.temp_override(**_get_view3d_context()): + bpy.ops.anim.keyframe_insert_by_name(type=insert_key) + match = _fcurve_paths_match(keyed_object.animation_data.action.fcurves, expected_paths) + bpy.data.objects.remove(keyed_object, do_unlink=True) + return match + + +def _get_keying_set(scene, name: str): + return scene.keying_sets_all[scene.keying_sets_all.find(name)] + + +def _insert_with_keying_set_test(keying_set_name: str, expected_paths: list): + scene = bpy.context.scene + keying_set = _get_keying_set(scene, keying_set_name) + scene.keying_sets.active = keying_set + keyed_object = _create_animation_object() + with bpy.context.temp_override(**_get_view3d_context()): + bpy.ops.anim.keyframe_insert() + match = _fcurve_paths_match(keyed_object.animation_data.action.fcurves, expected_paths) + bpy.data.objects.remove(keyed_object, do_unlink=True) + return match + + +class AbstractKeyframingTest: + def setUp(self): + super().setUp() + bpy.ops.wm.read_homefile(use_factory_startup=True) + + +class InsertKeyTest(AbstractKeyframingTest, unittest.TestCase): + """ Ensure keying things by name or with a keying set adds the right keys. """ + + def test_insert_by_name(self): + self.assertTrue(_insert_by_name_test("Location", ["location"])) + self.assertTrue(_insert_by_name_test("Rotation", ["rotation_euler"])) + self.assertTrue(_insert_by_name_test("Scaling", ["scale"])) + self.assertTrue(_insert_by_name_test("LocRotScale", ["location", "rotation_euler", "scale"])) + + def test_insert_with_keying_set(self): + self.assertTrue(_insert_with_keying_set_test("Location", ["location"])) + self.assertTrue(_insert_with_keying_set_test("Rotation", ["rotation_euler"])) + self.assertTrue(_insert_with_keying_set_test("Scale", ["scale"])) + self.assertTrue(_insert_with_keying_set_test("Location, Rotation & Scale", ["location", "rotation_euler", "scale"])) + + +class VisualKeyingTest(AbstractKeyframingTest, unittest.TestCase): + """ Check if visual keying produces the correct keyframe values. """ + + def test_visual_location_keying_set(self): + t_value = 1 + target = _create_animation_object() + target.location = (t_value, t_value, t_value) + constrained = _create_animation_object() + constraint = constrained.constraints.new("COPY_LOCATION") + constraint.target = target + + with bpy.context.temp_override(**_get_view3d_context()): + bpy.ops.anim.keyframe_insert_by_name(type="BUILTIN_KSI_VisualLoc") + + for fcurve in constrained.animation_data.action.fcurves: + self.assertEqual(fcurve.keyframe_points[0].co.y, t_value) + + bpy.data.objects.remove(target, do_unlink=True) + bpy.data.objects.remove(constrained, do_unlink=True) + + def test_visual_rotation_keying_set(self): + rot_value_deg = 45 + rot_value_rads = radians(rot_value_deg) + + target = _create_animation_object() + target.rotation_euler = (rot_value_rads, rot_value_rads, rot_value_rads) + constrained = _create_animation_object() + constraint = constrained.constraints.new("COPY_ROTATION") + constraint.target = target + + with bpy.context.temp_override(**_get_view3d_context()): + bpy.ops.anim.keyframe_insert_by_name(type="BUILTIN_KSI_VisualRot") + + for fcurve in constrained.animation_data.action.fcurves: + self.assertAlmostEqual(fcurve.keyframe_points[0].co.y, rot_value_rads, places=4) + + bpy.data.objects.remove(target, do_unlink=True) + bpy.data.objects.remove(constrained, do_unlink=True) + + def test_visual_location_user_pref(self): + # When enabling the user preference setting, + # the normal keying sets behave like their visual keying set counterpart. + bpy.context.preferences.edit.use_visual_keying = True + t_value = 1 + target = _create_animation_object() + target.location = (t_value, t_value, t_value) + constrained = _create_animation_object() + constraint = constrained.constraints.new("COPY_LOCATION") + constraint.target = target + + with bpy.context.temp_override(**_get_view3d_context()): + bpy.ops.anim.keyframe_insert_by_name(type="Location") + + for fcurve in constrained.animation_data.action.fcurves: + self.assertEqual(fcurve.keyframe_points[0].co.y, t_value) + + bpy.data.objects.remove(target, do_unlink=True) + bpy.data.objects.remove(constrained, do_unlink=True) + bpy.context.preferences.edit.use_visual_keying = False + + +class CycleAwareKeyingTest(AbstractKeyframingTest, unittest.TestCase): + """ Check if cycle aware keying remaps the keyframes correctly and adds fcurve modifiers. """ + + def test_insert_location_cycle_aware(self): + # In order to make cycle aware keying work, the action needs to be created and have the + # frame_range set plus the use_frame_range flag set to True. + keyed_object = _create_animation_object() + bpy.context.scene.tool_settings.use_keyframe_cycle_aware = True + + with bpy.context.temp_override(**_get_view3d_context()): + bpy.ops.anim.keyframe_insert_by_name(type="Location") + + action = keyed_object.animation_data.action + action.use_cyclic = True + action.use_frame_range = True + cyclic_range_end = 20 + action.frame_range = [1, cyclic_range_end] + + with bpy.context.temp_override(**_get_view3d_context()): + bpy.context.scene.frame_set(5) + bpy.ops.anim.keyframe_insert_by_name(type="Location") + + # Will be mapped to frame 3. + bpy.context.scene.frame_set(22) + bpy.ops.anim.keyframe_insert_by_name(type="Location") + + # Will be mapped to frame 9. + bpy.context.scene.frame_set(-10) + bpy.ops.anim.keyframe_insert_by_name(type="Location") + + # Check that only location keys have been created. + self.assertTrue(_fcurve_paths_match(action.fcurves, ["location"])) + + expected_keys = [1, 3, 5, 9, 20] + + for fcurve in action.fcurves: + self.assertEqual(len(fcurve.keyframe_points), len(expected_keys)) + key_index = 0 + for key in fcurve.keyframe_points: + self.assertEqual(key.co.x, expected_keys[key_index]) + key_index += 1 + + # All fcurves should have a cycles modifier. + self.assertTrue(fcurve.modifiers[0].type == "CYCLES") + + bpy.data.objects.remove(keyed_object, do_unlink=True) + + +def main(): + global args + import argparse + + if '--' in sys.argv: + argv = [sys.argv[0]] + sys.argv[sys.argv.index('--') + 1:] + else: + argv = sys.argv + + parser = argparse.ArgumentParser() + parser.add_argument('--testdir', required=True, type=pathlib.Path) + args, remaining = parser.parse_known_args(argv) + + unittest.main(argv=remaining) + + +if __name__ == "__main__": + main() From fc74f341a5fe9fbf7b01cf46434a231cb4d25453 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Tue, 7 Nov 2023 16:46:38 +0100 Subject: [PATCH 56/62] Refactor: Move code related to animdata to animrig No functional changes. Move the following functions `ANIM_fcurve_delete_from_animdata` and `ANIM_remove_empty_action_from_animdata` to `ANIM_animdata.hh` / `animdata.cc` in animrig This removes some includes to `ED_anim_api.hh` from animrig Pull Request: https://projects.blender.org/blender/blender/pulls/114581 --- source/blender/animrig/ANIM_animdata.hh | 31 ++++++ source/blender/animrig/CMakeLists.txt | 2 + source/blender/animrig/intern/animdata.cc | 95 +++++++++++++++++++ source/blender/animrig/intern/fcurve.cc | 1 + source/blender/animrig/intern/keyframing.cc | 2 +- source/blender/animrig/intern/visualkey.cc | 2 - .../editors/animation/anim_channels_edit.cc | 81 +--------------- .../editors/animation/keyframes_general.cc | 5 +- .../blender/editors/animation/keyframing.cc | 6 +- source/blender/editors/include/ED_anim_api.hh | 14 --- .../editors/space_action/action_edit.cc | 3 +- .../blender/editors/space_graph/graph_edit.cc | 3 +- 12 files changed, 142 insertions(+), 103 deletions(-) create mode 100644 source/blender/animrig/ANIM_animdata.hh create mode 100644 source/blender/animrig/intern/animdata.cc diff --git a/source/blender/animrig/ANIM_animdata.hh b/source/blender/animrig/ANIM_animdata.hh new file mode 100644 index 00000000000..e09343f5957 --- /dev/null +++ b/source/blender/animrig/ANIM_animdata.hh @@ -0,0 +1,31 @@ +/* SPDX-FileCopyrightText: 2023 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup animrig + * + * \brief Functions to work with AnimData. + */ + +struct bAnimContext; +struct AnimData; +struct FCurve; + +namespace blender::animrig { + +/** + * Delete the F-Curve from the given AnimData block (if possible), + * as appropriate according to animation context. + */ +void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *fcu); + +/** + * Unlink the action from animdata if it's empty. + * + * If the action has no F-Curves, unlink it from AnimData if it did not + * come from a NLA Strip being tweaked. + */ +bool ANIM_remove_empty_action_from_animdata(AnimData *adt); + +} // namespace blender::animrig \ No newline at end of file diff --git a/source/blender/animrig/CMakeLists.txt b/source/blender/animrig/CMakeLists.txt index d0bcc381f5d..9f2ae882225 100644 --- a/source/blender/animrig/CMakeLists.txt +++ b/source/blender/animrig/CMakeLists.txt @@ -22,6 +22,7 @@ set(INC_SYS set(SRC intern/action.cc intern/anim_rna.cc + intern/animdata.cc intern/bone_collections.cc intern/bonecolor.cc intern/fcurve.cc @@ -30,6 +31,7 @@ set(SRC intern/visualkey.cc ANIM_action.hh + ANIM_animdata.hh ANIM_armature_iter.hh ANIM_bone_collections.h ANIM_bone_collections.hh diff --git a/source/blender/animrig/intern/animdata.cc b/source/blender/animrig/intern/animdata.cc new file mode 100644 index 00000000000..3a7ea86355c --- /dev/null +++ b/source/blender/animrig/intern/animdata.cc @@ -0,0 +1,95 @@ +/* SPDX-FileCopyrightText: 2023 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup animrig + */ + +#include "ANIM_animdata.hh" +#include "BKE_action.h" +#include "BKE_fcurve.h" +#include "BKE_lib_id.h" +#include "BLI_listbase.h" +#include "DNA_anim_types.h" +#include "ED_anim_api.hh" + +namespace blender::animrig { + +/* -------------------------------------------------------------------- */ +/** \name Public F-Curves API + * \{ */ + +void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *fcu) +{ + /* - if no AnimData, we've got nowhere to remove the F-Curve from + * (this doesn't guarantee that the F-Curve is in there, but at least we tried + * - if no F-Curve, there is nothing to remove + */ + if (ELEM(nullptr, adt, fcu)) { + return; + } + + /* remove from whatever list it came from + * - Action Group + * - Action + * - Drivers + * - TODO... some others? + */ + if ((ac) && (ac->datatype == ANIMCONT_DRIVERS)) { + /* driver F-Curve */ + BLI_remlink(&adt->drivers, fcu); + } + else if (adt->action) { + bAction *act = adt->action; + + /* remove from group or action, whichever one "owns" the F-Curve */ + if (fcu->grp) { + bActionGroup *agrp = fcu->grp; + + /* remove F-Curve from group+action */ + action_groups_remove_channel(act, fcu); + + /* if group has no more channels, remove it too, + * otherwise can have many dangling groups #33541. + */ + if (BLI_listbase_is_empty(&agrp->channels)) { + BLI_freelinkN(&act->groups, agrp); + } + } + else { + BLI_remlink(&act->curves, fcu); + } + + /* if action has no more F-Curves as a result of this, unlink it from + * AnimData if it did not come from a NLA Strip being tweaked. + * + * This is done so that we don't have dangling Object+Action entries in + * channel list that are empty, and linger around long after the data they + * are for has disappeared (and probably won't come back). + */ + ANIM_remove_empty_action_from_animdata(adt); + } + + /* free the F-Curve itself */ + BKE_fcurve_free(fcu); +} + +bool ANIM_remove_empty_action_from_animdata(AnimData *adt) +{ + if (adt->action != nullptr) { + bAction *act = adt->action; + + if (BLI_listbase_is_empty(&act->curves) && (adt->flag & ADT_NLA_EDIT_ON) == 0) { + id_us_min(&act->id); + adt->action = nullptr; + return true; + } + } + + return false; +} + +/** \} */ + +} // namespace blender::animrig \ No newline at end of file diff --git a/source/blender/animrig/intern/fcurve.cc b/source/blender/animrig/intern/fcurve.cc index fdfdbb5a21f..a31559b530c 100644 --- a/source/blender/animrig/intern/fcurve.cc +++ b/source/blender/animrig/intern/fcurve.cc @@ -9,6 +9,7 @@ #include #include +#include "ANIM_animdata.hh" #include "ANIM_fcurve.hh" #include "BKE_fcurve.h" #include "DNA_anim_types.h" diff --git a/source/blender/animrig/intern/keyframing.cc b/source/blender/animrig/intern/keyframing.cc index 96ebfff525a..601cd1071f7 100644 --- a/source/blender/animrig/intern/keyframing.cc +++ b/source/blender/animrig/intern/keyframing.cc @@ -10,6 +10,7 @@ #include #include "ANIM_action.hh" +#include "ANIM_animdata.hh" #include "ANIM_fcurve.hh" #include "ANIM_keyframing.hh" #include "ANIM_rna.hh" @@ -32,7 +33,6 @@ #include "DEG_depsgraph.hh" #include "DEG_depsgraph_query.hh" #include "DNA_anim_types.h" -#include "ED_anim_api.hh" #include "ED_keyframing.hh" #include "MEM_guardedalloc.h" #include "RNA_access.hh" diff --git a/source/blender/animrig/intern/visualkey.cc b/source/blender/animrig/intern/visualkey.cc index 13a7823a679..34a6ea45e31 100644 --- a/source/blender/animrig/intern/visualkey.cc +++ b/source/blender/animrig/intern/visualkey.cc @@ -23,8 +23,6 @@ #include "DNA_object_types.h" #include "DNA_rigidbody_types.h" -#include "ED_keyframing.hh" - #include "RNA_access.hh" #include "RNA_prototypes.h" #include "RNA_types.hh" diff --git a/source/blender/editors/animation/anim_channels_edit.cc b/source/blender/editors/animation/anim_channels_edit.cc index 355b698f5cc..7c6c2f1a00d 100644 --- a/source/blender/editors/animation/anim_channels_edit.cc +++ b/source/blender/editors/animation/anim_channels_edit.cc @@ -46,7 +46,6 @@ #include "UI_interface.hh" #include "UI_view2d.hh" -#include "ED_anim_api.hh" #include "ED_armature.hh" #include "ED_keyframes_edit.hh" /* XXX move the select modes out of there! */ #include "ED_markers.hh" @@ -54,6 +53,8 @@ #include "ED_screen.hh" #include "ED_select_utils.hh" +#include "ANIM_animdata.hh" + #include "WM_api.hh" #include "WM_types.hh" @@ -857,82 +858,6 @@ void ANIM_frame_channel_y_extents(bContext *C, bAnimContext *ac) } /** \} */ -/* -------------------------------------------------------------------- */ -/** \name Public F-Curves API - * \{ */ - -void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *fcu) -{ - /* - if no AnimData, we've got nowhere to remove the F-Curve from - * (this doesn't guarantee that the F-Curve is in there, but at least we tried - * - if no F-Curve, there is nothing to remove - */ - if (ELEM(nullptr, adt, fcu)) { - return; - } - - /* remove from whatever list it came from - * - Action Group - * - Action - * - Drivers - * - TODO... some others? - */ - if ((ac) && (ac->datatype == ANIMCONT_DRIVERS)) { - /* driver F-Curve */ - BLI_remlink(&adt->drivers, fcu); - } - else if (adt->action) { - bAction *act = adt->action; - - /* remove from group or action, whichever one "owns" the F-Curve */ - if (fcu->grp) { - bActionGroup *agrp = fcu->grp; - - /* remove F-Curve from group+action */ - action_groups_remove_channel(act, fcu); - - /* if group has no more channels, remove it too, - * otherwise can have many dangling groups #33541. - */ - if (BLI_listbase_is_empty(&agrp->channels)) { - BLI_freelinkN(&act->groups, agrp); - } - } - else { - BLI_remlink(&act->curves, fcu); - } - - /* if action has no more F-Curves as a result of this, unlink it from - * AnimData if it did not come from a NLA Strip being tweaked. - * - * This is done so that we don't have dangling Object+Action entries in - * channel list that are empty, and linger around long after the data they - * are for has disappeared (and probably won't come back). - */ - ANIM_remove_empty_action_from_animdata(adt); - } - - /* free the F-Curve itself */ - BKE_fcurve_free(fcu); -} - -bool ANIM_remove_empty_action_from_animdata(AnimData *adt) -{ - if (adt->action != nullptr) { - bAction *act = adt->action; - - if (BLI_listbase_is_empty(&act->curves) && (adt->flag & ADT_NLA_EDIT_ON) == 0) { - id_us_min(&act->id); - adt->action = nullptr; - return true; - } - } - - return false; -} - -/** \} */ - /* -------------------------------------------------------------------- */ /** \name Operator Utilities * \{ */ @@ -2211,7 +2136,7 @@ static int animchannels_delete_exec(bContext *C, wmOperator * /*op*/) FCurve *fcu = (FCurve *)ale->data; /* try to free F-Curve */ - ANIM_fcurve_delete_from_animdata(&ac, adt, fcu); + blender::animrig::ANIM_fcurve_delete_from_animdata(&ac, adt, fcu); tag_update_animation_element(ale); break; } diff --git a/source/blender/editors/animation/keyframes_general.cc b/source/blender/editors/animation/keyframes_general.cc index f1c1434bb15..94496024b13 100644 --- a/source/blender/editors/animation/keyframes_general.cc +++ b/source/blender/editors/animation/keyframes_general.cc @@ -34,10 +34,9 @@ #include "RNA_enum_types.hh" #include "RNA_path.hh" -#include "ED_anim_api.hh" #include "ED_keyframes_edit.hh" -#include "ED_keyframing.hh" +#include "ANIM_animdata.hh" #include "ANIM_fcurve.hh" /* This file contains code for various keyframe-editing tools which are 'destructive' @@ -229,7 +228,7 @@ void clean_fcurve(bAnimContext *ac, /* check if curve is really unused and if it is, return signal for deletion */ if (BKE_fcurve_is_empty(fcu)) { AnimData *adt = ale->adt; - ANIM_fcurve_delete_from_animdata(ac, adt, fcu); + blender::animrig::ANIM_fcurve_delete_from_animdata(ac, adt, fcu); ale->key_data = nullptr; } } diff --git a/source/blender/editors/animation/keyframing.cc b/source/blender/editors/animation/keyframing.cc index 41a912ad5cc..dd574e4e396 100644 --- a/source/blender/editors/animation/keyframing.cc +++ b/source/blender/editors/animation/keyframing.cc @@ -39,11 +39,11 @@ #include "DEG_depsgraph.hh" #include "DEG_depsgraph_build.hh" -#include "ED_keyframes_edit.hh" #include "ED_keyframing.hh" #include "ED_object.hh" #include "ED_screen.hh" +#include "ANIM_animdata.hh" #include "ANIM_bone_collections.h" #include "ANIM_fcurve.hh" #include "ANIM_keyframing.hh" @@ -628,14 +628,14 @@ static int clear_anim_v3d_exec(bContext *C, wmOperator * /*op*/) /* delete F-Curve completely */ if (can_delete) { - ANIM_fcurve_delete_from_animdata(nullptr, adt, fcu); + blender::animrig::ANIM_fcurve_delete_from_animdata(nullptr, adt, fcu); DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM); changed = true; } } /* Delete the action itself if it is empty. */ - if (ANIM_remove_empty_action_from_animdata(adt)) { + if (blender::animrig::ANIM_remove_empty_action_from_animdata(adt)) { changed = true; } } diff --git a/source/blender/editors/include/ED_anim_api.hh b/source/blender/editors/include/ED_anim_api.hh index 7ef2f2158d3..bfec6e8d9da 100644 --- a/source/blender/editors/include/ED_anim_api.hh +++ b/source/blender/editors/include/ED_anim_api.hh @@ -718,20 +718,6 @@ void ANIM_set_active_channel(bAnimContext *ac, */ bool ANIM_is_active_channel(bAnimListElem *ale); -/** - * Delete the F-Curve from the given AnimData block (if possible), - * as appropriate according to animation context. - */ -void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *fcu); - -/** - * Unlink the action from animdata if it's empty. - * - * If the action has no F-Curves, unlink it from AnimData if it did not - * come from a NLA Strip being tweaked. - */ -bool ANIM_remove_empty_action_from_animdata(AnimData *adt); - /* ************************************************ */ /* DRAWING API */ /* `anim_draw.cc` */ diff --git a/source/blender/editors/space_action/action_edit.cc b/source/blender/editors/space_action/action_edit.cc index 00aa1419747..a07be36bb76 100644 --- a/source/blender/editors/space_action/action_edit.cc +++ b/source/blender/editors/space_action/action_edit.cc @@ -43,6 +43,7 @@ #include "UI_view2d.hh" +#include "ANIM_animdata.hh" #include "ANIM_fcurve.hh" #include "ANIM_keyframing.hh" #include "ED_anim_api.hh" @@ -1110,7 +1111,7 @@ static bool delete_action_keys(bAnimContext *ac) /* Only delete curve too if it won't be doing anything anymore */ if (BKE_fcurve_is_empty(fcu)) { - ANIM_fcurve_delete_from_animdata(ac, adt, fcu); + blender::animrig::ANIM_fcurve_delete_from_animdata(ac, adt, fcu); ale->key_data = nullptr; } } diff --git a/source/blender/editors/space_graph/graph_edit.cc b/source/blender/editors/space_graph/graph_edit.cc index 343b329a0b0..7eb058244a7 100644 --- a/source/blender/editors/space_graph/graph_edit.cc +++ b/source/blender/editors/space_graph/graph_edit.cc @@ -47,6 +47,7 @@ #include "UI_interface.hh" #include "UI_view2d.hh" +#include "ANIM_animdata.hh" #include "ANIM_fcurve.hh" #include "ANIM_keyframing.hh" #include "ED_anim_api.hh" @@ -765,7 +766,7 @@ static bool delete_graph_keys(bAnimContext *ac) /* Only delete curve too if it won't be doing anything anymore. */ if (BKE_fcurve_is_empty(fcu)) { - ANIM_fcurve_delete_from_animdata(ac, adt, fcu); + blender::animrig::ANIM_fcurve_delete_from_animdata(ac, adt, fcu); ale->key_data = nullptr; } } From c8ccd3d58abe4cb56683049bbf0bc3dc0918598d Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Tue, 7 Nov 2023 17:03:29 +0100 Subject: [PATCH 57/62] Refactor: Rename functions in ANIM_animdata.hh No functional changes. Renaming the following functions `ANIM_remove_empty_action_from_animdata` and `ANIM_fcurve_delete_from_animdata` to `animdata_remove_empty_action` and `animdata_fcurve_delete` The `ANIM` prefix was no longer needed since the code is now in a namespace. In order to make the function name consistent with the functions in `fcurve.cc` the thing it modifies is now at the start of the function name Pull Request: https://projects.blender.org/blender/blender/pulls/114584 --- source/blender/animrig/ANIM_animdata.hh | 4 ++-- source/blender/animrig/intern/animdata.cc | 6 +++--- source/blender/animrig/intern/fcurve.cc | 2 +- source/blender/animrig/intern/keyframing.cc | 2 +- source/blender/editors/animation/anim_channels_edit.cc | 2 +- source/blender/editors/animation/keyframes_general.cc | 2 +- source/blender/editors/animation/keyframing.cc | 4 ++-- source/blender/editors/space_action/action_edit.cc | 2 +- source/blender/editors/space_graph/graph_edit.cc | 2 +- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/source/blender/animrig/ANIM_animdata.hh b/source/blender/animrig/ANIM_animdata.hh index e09343f5957..7902f036ab2 100644 --- a/source/blender/animrig/ANIM_animdata.hh +++ b/source/blender/animrig/ANIM_animdata.hh @@ -18,7 +18,7 @@ namespace blender::animrig { * Delete the F-Curve from the given AnimData block (if possible), * as appropriate according to animation context. */ -void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *fcu); +void animdata_fcurve_delete(bAnimContext *ac, AnimData *adt, FCurve *fcu); /** * Unlink the action from animdata if it's empty. @@ -26,6 +26,6 @@ void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *f * If the action has no F-Curves, unlink it from AnimData if it did not * come from a NLA Strip being tweaked. */ -bool ANIM_remove_empty_action_from_animdata(AnimData *adt); +bool animdata_remove_empty_action(AnimData *adt); } // namespace blender::animrig \ No newline at end of file diff --git a/source/blender/animrig/intern/animdata.cc b/source/blender/animrig/intern/animdata.cc index 3a7ea86355c..539cefd8aa6 100644 --- a/source/blender/animrig/intern/animdata.cc +++ b/source/blender/animrig/intern/animdata.cc @@ -20,7 +20,7 @@ namespace blender::animrig { /** \name Public F-Curves API * \{ */ -void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *fcu) +void animdata_fcurve_delete(bAnimContext *ac, AnimData *adt, FCurve *fcu) { /* - if no AnimData, we've got nowhere to remove the F-Curve from * (this doesn't guarantee that the F-Curve is in there, but at least we tried @@ -68,14 +68,14 @@ void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *f * channel list that are empty, and linger around long after the data they * are for has disappeared (and probably won't come back). */ - ANIM_remove_empty_action_from_animdata(adt); + animdata_remove_empty_action(adt); } /* free the F-Curve itself */ BKE_fcurve_free(fcu); } -bool ANIM_remove_empty_action_from_animdata(AnimData *adt) +bool animdata_remove_empty_action(AnimData *adt) { if (adt->action != nullptr) { bAction *act = adt->action; diff --git a/source/blender/animrig/intern/fcurve.cc b/source/blender/animrig/intern/fcurve.cc index a31559b530c..67f1e67888e 100644 --- a/source/blender/animrig/intern/fcurve.cc +++ b/source/blender/animrig/intern/fcurve.cc @@ -33,7 +33,7 @@ bool delete_keyframe_fcurve(AnimData *adt, FCurve *fcu, float cfra) /* Empty curves get automatically deleted. */ if (BKE_fcurve_is_empty(fcu)) { - ANIM_fcurve_delete_from_animdata(nullptr, adt, fcu); + animdata_fcurve_delete(nullptr, adt, fcu); } return true; diff --git a/source/blender/animrig/intern/keyframing.cc b/source/blender/animrig/intern/keyframing.cc index 601cd1071f7..51f21080676 100644 --- a/source/blender/animrig/intern/keyframing.cc +++ b/source/blender/animrig/intern/keyframing.cc @@ -937,7 +937,7 @@ int clear_keyframe(Main *bmain, continue; } - ANIM_fcurve_delete_from_animdata(nullptr, adt, fcu); + animdata_fcurve_delete(nullptr, adt, fcu); key_count++; } diff --git a/source/blender/editors/animation/anim_channels_edit.cc b/source/blender/editors/animation/anim_channels_edit.cc index 7c6c2f1a00d..60bc6ddf025 100644 --- a/source/blender/editors/animation/anim_channels_edit.cc +++ b/source/blender/editors/animation/anim_channels_edit.cc @@ -2136,7 +2136,7 @@ static int animchannels_delete_exec(bContext *C, wmOperator * /*op*/) FCurve *fcu = (FCurve *)ale->data; /* try to free F-Curve */ - blender::animrig::ANIM_fcurve_delete_from_animdata(&ac, adt, fcu); + blender::animrig::animdata_fcurve_delete(&ac, adt, fcu); tag_update_animation_element(ale); break; } diff --git a/source/blender/editors/animation/keyframes_general.cc b/source/blender/editors/animation/keyframes_general.cc index 94496024b13..05a55412f69 100644 --- a/source/blender/editors/animation/keyframes_general.cc +++ b/source/blender/editors/animation/keyframes_general.cc @@ -228,7 +228,7 @@ void clean_fcurve(bAnimContext *ac, /* check if curve is really unused and if it is, return signal for deletion */ if (BKE_fcurve_is_empty(fcu)) { AnimData *adt = ale->adt; - blender::animrig::ANIM_fcurve_delete_from_animdata(ac, adt, fcu); + blender::animrig::animdata_fcurve_delete(ac, adt, fcu); ale->key_data = nullptr; } } diff --git a/source/blender/editors/animation/keyframing.cc b/source/blender/editors/animation/keyframing.cc index dd574e4e396..e427625e5eb 100644 --- a/source/blender/editors/animation/keyframing.cc +++ b/source/blender/editors/animation/keyframing.cc @@ -628,14 +628,14 @@ static int clear_anim_v3d_exec(bContext *C, wmOperator * /*op*/) /* delete F-Curve completely */ if (can_delete) { - blender::animrig::ANIM_fcurve_delete_from_animdata(nullptr, adt, fcu); + blender::animrig::animdata_fcurve_delete(nullptr, adt, fcu); DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM); changed = true; } } /* Delete the action itself if it is empty. */ - if (blender::animrig::ANIM_remove_empty_action_from_animdata(adt)) { + if (blender::animrig::animdata_remove_empty_action(adt)) { changed = true; } } diff --git a/source/blender/editors/space_action/action_edit.cc b/source/blender/editors/space_action/action_edit.cc index a07be36bb76..ee06603dd72 100644 --- a/source/blender/editors/space_action/action_edit.cc +++ b/source/blender/editors/space_action/action_edit.cc @@ -1111,7 +1111,7 @@ static bool delete_action_keys(bAnimContext *ac) /* Only delete curve too if it won't be doing anything anymore */ if (BKE_fcurve_is_empty(fcu)) { - blender::animrig::ANIM_fcurve_delete_from_animdata(ac, adt, fcu); + blender::animrig::animdata_fcurve_delete(ac, adt, fcu); ale->key_data = nullptr; } } diff --git a/source/blender/editors/space_graph/graph_edit.cc b/source/blender/editors/space_graph/graph_edit.cc index 7eb058244a7..4caa05c7d82 100644 --- a/source/blender/editors/space_graph/graph_edit.cc +++ b/source/blender/editors/space_graph/graph_edit.cc @@ -766,7 +766,7 @@ static bool delete_graph_keys(bAnimContext *ac) /* Only delete curve too if it won't be doing anything anymore. */ if (BKE_fcurve_is_empty(fcu)) { - blender::animrig::ANIM_fcurve_delete_from_animdata(ac, adt, fcu); + blender::animrig::animdata_fcurve_delete(ac, adt, fcu); ale->key_data = nullptr; } } From 1b95e74b8a6b00c6c0d635252c753ebde0db309a Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Tue, 7 Nov 2023 17:24:36 +0100 Subject: [PATCH 58/62] Cleanup: comment style in animrig No functional changes. Functions moved to animrig recently did not adhere to the comment style guidelines Pull Request: https://projects.blender.org/blender/blender/pulls/114586 --- source/blender/animrig/ANIM_fcurve.hh | 6 ++- source/blender/animrig/intern/action.cc | 2 +- source/blender/animrig/intern/animdata.cc | 16 +++--- source/blender/animrig/intern/fcurve.cc | 63 +++++++++++------------ 4 files changed, 44 insertions(+), 43 deletions(-) diff --git a/source/blender/animrig/ANIM_fcurve.hh b/source/blender/animrig/ANIM_fcurve.hh index 9908231f7eb..54c87782891 100644 --- a/source/blender/animrig/ANIM_fcurve.hh +++ b/source/blender/animrig/ANIM_fcurve.hh @@ -29,7 +29,9 @@ bool delete_keyframe_fcurve(AnimData *adt, FCurve *fcu, float cfra); * memory for the array if needed, and will insert the #BezTriple into a * suitable place in chronological order. * - * \note any recalculate of the F-Curve that needs to be done will need to be done by the caller. + * \returns The index of the keyframe array into which the bezt has been added. + * + * \note Any recalculate of the F-Curve that needs to be done will need to be done by the caller. */ int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag); @@ -44,6 +46,8 @@ int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag) * adding a new keyframe to a curve, when the keyframe doesn't exist anywhere else yet. * It returns the index at which the keyframe was added. * + * \returns The index of the keyframe array into which the bezt has been added. + * * \param keyframe_type: The type of keyframe (#eBezTriple_KeyframeType). * \param flag: Optional flags (#eInsertKeyFlags) for controlling how keys get added * and/or whether updates get done. diff --git a/source/blender/animrig/intern/action.cc b/source/blender/animrig/intern/action.cc index 9ddcf7bb363..fa3df36a38f 100644 --- a/source/blender/animrig/intern/action.cc +++ b/source/blender/animrig/intern/action.cc @@ -36,7 +36,7 @@ FCurve *action_fcurve_ensure(Main *bmain, return nullptr; } - /* try to find f-curve matching for this setting + /* Try to find f-curve matching for this setting. * - add if not found and allowed to add one * TODO: add auto-grouping support? how this works will need to be resolved */ diff --git a/source/blender/animrig/intern/animdata.cc b/source/blender/animrig/intern/animdata.cc index 539cefd8aa6..9b9ff598f7c 100644 --- a/source/blender/animrig/intern/animdata.cc +++ b/source/blender/animrig/intern/animdata.cc @@ -22,35 +22,34 @@ namespace blender::animrig { void animdata_fcurve_delete(bAnimContext *ac, AnimData *adt, FCurve *fcu) { - /* - if no AnimData, we've got nowhere to remove the F-Curve from + /* - If no AnimData, we've got nowhere to remove the F-Curve from * (this doesn't guarantee that the F-Curve is in there, but at least we tried - * - if no F-Curve, there is nothing to remove + * - If no F-Curve, there is nothing to remove */ if (ELEM(nullptr, adt, fcu)) { return; } - /* remove from whatever list it came from + /* Remove from whatever list it came from * - Action Group * - Action * - Drivers * - TODO... some others? */ if ((ac) && (ac->datatype == ANIMCONT_DRIVERS)) { - /* driver F-Curve */ BLI_remlink(&adt->drivers, fcu); } else if (adt->action) { bAction *act = adt->action; - /* remove from group or action, whichever one "owns" the F-Curve */ + /* Remove from group or action, whichever one "owns" the F-Curve. */ if (fcu->grp) { bActionGroup *agrp = fcu->grp; - /* remove F-Curve from group+action */ + /* Remove F-Curve from group+action. */ action_groups_remove_channel(act, fcu); - /* if group has no more channels, remove it too, + /* If group has no more channels, remove it too, * otherwise can have many dangling groups #33541. */ if (BLI_listbase_is_empty(&agrp->channels)) { @@ -61,7 +60,7 @@ void animdata_fcurve_delete(bAnimContext *ac, AnimData *adt, FCurve *fcu) BLI_remlink(&act->curves, fcu); } - /* if action has no more F-Curves as a result of this, unlink it from + /* If action has no more F-Curves as a result of this, unlink it from * AnimData if it did not come from a NLA Strip being tweaked. * * This is done so that we don't have dangling Object+Action entries in @@ -71,7 +70,6 @@ void animdata_fcurve_delete(bAnimContext *ac, AnimData *adt, FCurve *fcu) animdata_remove_empty_action(adt); } - /* free the F-Curve itself */ BKE_fcurve_free(fcu); } diff --git a/source/blender/animrig/intern/fcurve.cc b/source/blender/animrig/intern/fcurve.cc index 67f1e67888e..51efc3ccc2d 100644 --- a/source/blender/animrig/intern/fcurve.cc +++ b/source/blender/animrig/intern/fcurve.cc @@ -47,10 +47,10 @@ bool delete_keyframe_fcurve(AnimData *adt, FCurve *fcu, float cfra) /* Change the Y position of a keyframe to match the input, adjusting handles. */ static void replace_bezt_keyframe_ypos(BezTriple *dst, const BezTriple *bezt) { - /* just change the values when replacing, so as to not overwrite handles */ + /* Just change the values when replacing, so as to not overwrite handles. */ float dy = bezt->vec[1][1] - dst->vec[1][1]; - /* just apply delta value change to the handle values */ + /* Just apply delta value change to the handle values. */ dst->vec[0][1] += dy; dst->vec[1][1] += dy; dst->vec[2][1] += dy; @@ -66,14 +66,14 @@ int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag) { int i = 0; - /* are there already keyframes? */ + /* Are there already keyframes? */ if (fcu->bezt) { bool replace; i = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, bezt->vec[1][0], fcu->totvert, &replace); - /* replace an existing keyframe? */ + /* Replace an existing keyframe? */ if (replace) { - /* sanity check: 'i' may in rare cases exceed arraylen */ + /* 'i' may in rare cases exceed arraylen. */ if ((i >= 0) && (i < fcu->totvert)) { if (flag & INSERTKEY_OVERWRITE_FULL) { fcu->bezt[i] = *bezt; @@ -94,7 +94,7 @@ int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag) } /* Keyframing modes allow not replacing the keyframe. */ else if ((flag & INSERTKEY_REPLACE) == 0) { - /* insert new - if we're not restricted to replacing keyframes only */ + /* Insert new - if we're not restricted to replacing keyframes only. */ BezTriple *newb = static_cast( MEM_callocN((fcu->totvert + 1) * sizeof(BezTriple), "beztriple")); @@ -104,15 +104,15 @@ int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag) memcpy(newb, fcu->bezt, i * sizeof(BezTriple)); } - /* add beztriple to paste at index i */ + /* Add beztriple to paste at index i. */ *(newb + i) = *bezt; - /* add the beztriples that occur after the beztriple to be pasted (originally in fcu) */ + /* Add the beztriples that occur after the beztriple to be pasted (originally in fcu). */ if (i < fcu->totvert) { memcpy(newb + i + 1, fcu->bezt + i, (fcu->totvert - i) * sizeof(BezTriple)); } - /* replace (+ free) old with new, only if necessary to do so */ + /* Replace (+ free) old with new, only if necessary to do so. */ MEM_freeN(fcu->bezt); fcu->bezt = newb; @@ -122,26 +122,26 @@ int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag) return -1; } } - /* no keyframes already, but can only add if... + /* No keyframes yet, but can only add if... * 1) keyframing modes say that keyframes can only be replaced, so adding new ones won't know * 2) there are no samples on the curve * NOTE: maybe we may want to allow this later when doing samples -> bezt conversions, * but for now, having both is asking for trouble */ else if ((flag & INSERTKEY_REPLACE) == 0 && (fcu->fpt == nullptr)) { - /* create new keyframes array */ + /* Create new keyframes array. */ fcu->bezt = static_cast(MEM_callocN(sizeof(BezTriple), "beztriple")); *(fcu->bezt) = *bezt; fcu->totvert = 1; } - /* cannot add anything */ + /* Cannot add anything. */ else { - /* return error code -1 to prevent any misunderstandings */ + /* Return error code -1 to prevent any misunderstandings. */ return -1; } - /* we need to return the index, so that some tools which do post-processing can - * detect where we added the BezTriple in the array + /* We need to return the index, so that some tools which do post-processing can + * detect where we added the BezTriple in the array. */ return i; } @@ -205,7 +205,7 @@ int insert_vert_fcurve( uint oldTot = fcu->totvert; int a; - /* set all three points, for nicer start position + /* Set all three points, for nicer start position. * NOTE: +/- 1 on vec.x for left and right handles is so that 'free' handles work ok... */ beztr.vec[0][0] = x - 1.0f; @@ -216,23 +216,23 @@ int insert_vert_fcurve( beztr.vec[2][1] = y; beztr.f1 = beztr.f2 = beztr.f3 = SELECT; - /* set default handle types and interpolation mode */ + /* Set default handle types and interpolation mode. */ if (flag & INSERTKEY_NO_USERPREF) { - /* for Py-API, we want scripts to have predictable behavior, - * hence the option to not depend on the userpref defaults + /* For Py-API, we want scripts to have predictable behavior, + * hence the option to not depend on the userpref defaults. */ beztr.h1 = beztr.h2 = HD_AUTO_ANIM; beztr.ipo = BEZT_IPO_BEZ; } else { /* For UI usage - defaults should come from the user-preferences and/or tool-settings. */ - beztr.h1 = beztr.h2 = U.keyhandles_new; /* use default handle type here */ + beztr.h1 = beztr.h2 = U.keyhandles_new; /* Use default handle type here. */ - /* use default interpolation mode, with exceptions for int/discrete values */ + /* Use default interpolation mode, with exceptions for int/discrete values. */ beztr.ipo = U.ipo_new; } - /* interpolation type used is constrained by the type of values the curve can take */ + /* Interpolation type used is constrained by the type of values the curve can take. */ if (fcu->flag & FCURVE_DISCRETE_VALUES) { beztr.ipo = BEZT_IPO_CONST; } @@ -240,31 +240,30 @@ int insert_vert_fcurve( beztr.ipo = BEZT_IPO_LIN; } - /* set keyframe type value (supplied), which should come from the scene settings in most cases */ + /* Set keyframe type value (supplied), which should come from the scene + * settings in most cases. */ BEZKEYTYPE(&beztr) = keyframe_type; - /* set default values for "easing" interpolation mode settings + /* Set default values for "easing" interpolation mode settings. * NOTE: Even if these modes aren't currently used, if users switch * to these later, we want these to work in a sane way out of * the box. */ - /* "back" easing - this value used to be used when overshoot=0, but that + /* "back" easing - This value used to be used when overshoot=0, but that * introduced discontinuities in how the param worked. */ beztr.back = 1.70158f; - /* "elastic" easing - values here were hand-optimized for a default duration of + /* "elastic" easing - Values here were hand-optimized for a default duration of * ~10 frames (typical mograph motion length) */ beztr.amplitude = 0.8f; beztr.period = 4.1f; - /* add temp beztriple to keyframes */ + /* Add temp beztriple to keyframes. */ a = insert_bezt_fcurve(fcu, &beztr, flag); BKE_fcurve_active_keyframe_set(fcu, &fcu->bezt[a]); - /* what if 'a' is a negative index? - * for now, just exit to prevent any segfaults - */ + /* If `a` is negative return to avoid segfaults. */ if (a < 0) { return -1; } @@ -292,7 +291,7 @@ int insert_vert_fcurve( } } - /* don't recalculate handles if fast is set + /* Don't recalculate handles if fast is set. * - this is a hack to make importers faster * - we may calculate twice (due to auto-handle needing to be calculated twice) */ @@ -300,7 +299,7 @@ int insert_vert_fcurve( BKE_fcurve_handles_recalc(fcu); } - /* return the index at which the keyframe was added */ + /* Return the index at which the keyframe was added. */ return a; } From 772e99b4f7ab032babd3dce342e17c70763600e7 Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Mon, 23 Oct 2023 00:12:16 +0200 Subject: [PATCH 59/62] I18n: extract node group asset sockets Each node group asset exposes various properties through sockets. Although they can generally be considered user-created data, for built-in assets they are also part of the UI and should be translated--especially since more modifiers should be migrated to Geometry Nodes in the future. This commit allows extraction of such socket names and descriptions. Since the message extraction script already extracted names and descriptions for each asset, this commit only adds the socket in the same loop, so that they are extracted while the asset file is already being read. Properties from sockets are not yet translated in the modifier properties editor, this will be enabled in a follow-up commit. --- .../bl_i18n_utils/bl_extract_messages.py | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/scripts/modules/bl_i18n_utils/bl_extract_messages.py b/scripts/modules/bl_i18n_utils/bl_extract_messages.py index ea9664b3da9..634572d0bdc 100644 --- a/scripts/modules/bl_i18n_utils/bl_extract_messages.py +++ b/scripts/modules/bl_i18n_utils/bl_extract_messages.py @@ -941,6 +941,14 @@ def dump_asset_messages(msgs, reports, settings): # Parse the asset blend files asset_files = {} + # Store assets according to this structure: + # {"basename": [ + # {"name": "Name", + # "description": "Description", + # "sockets": [ + # ("Name", "Description"), + # ]}, + # ]} bfiles = glob.glob(assets_dir + "/**/*.blend", recursive=True) for bfile in bfiles: @@ -953,11 +961,18 @@ def dump_asset_messages(msgs, reports, settings): if asset.asset_data is None: # Not an asset continue assets = asset_files.setdefault(basename, []) - assets.append((asset.name, asset.asset_data.description)) + asset_data = {"name": asset.name, + "description": asset.asset_data.description} + for interface in asset.interface.items_tree: + if interface.name == "Geometry": # Ignore common socket + continue + socket_data = asset_data.setdefault("sockets", []) + socket_data.append((interface.name, interface.description)) + assets.append(asset_data) for asset_file in sorted(asset_files): - for asset in sorted(asset_files[asset_file]): - name, description = asset + for asset in sorted(asset_files[asset_file], key=lambda a: a["name"]): + name, description = asset["name"], asset["description"] msgsrc = "Asset name from file " + asset_file process_msg(msgs, settings.DEFAULT_CONTEXT, name, msgsrc, reports, None, settings) @@ -965,6 +980,15 @@ def dump_asset_messages(msgs, reports, settings): process_msg(msgs, settings.DEFAULT_CONTEXT, description, msgsrc, reports, None, settings) + if "sockets" in asset: + for socket_name, socket_description in asset["sockets"]: + msgsrc = f"Socket name from node group {name}, file {asset_file}" + process_msg(msgs, settings.DEFAULT_CONTEXT, socket_name, msgsrc, + reports, None, settings) + msgsrc = f"Socket description from node group {name}, file {asset_file}" + process_msg(msgs, settings.DEFAULT_CONTEXT, socket_description, msgsrc, + reports, None, settings) + def dump_addon_bl_info(msgs, reports, module, settings): for prop in ('name', 'location', 'description', 'warning'): From f48f901b3b20169983e79f093a4611766e39999e Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Mon, 23 Oct 2023 00:14:18 +0200 Subject: [PATCH 60/62] I18n: translate socket properties in the Modifier Properties editor Each node group asset exposes various properties through sockets. Although they can generally be considered user-created data, for built-in assets they are also part of the UI and should be translated--especially since more modifiers should be migrated to Geometry Nodes in the future. This commit enables the translation of those properties in the Modifier Properties editor. Pull Request: https://projects.blender.org/blender/blender/pulls/114256 --- source/blender/modifiers/intern/MOD_nodes.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index f523eb826c6..78a920df007 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -1437,7 +1437,7 @@ static void add_attribute_search_or_value_buttons(const bContext &C, uiItemL(name_row, "", ICON_NONE); } else { - uiItemL(name_row, socket.name ? socket.name : "", ICON_NONE); + uiItemL(name_row, socket.name ? IFACE_(socket.name) : "", ICON_NONE); } uiLayout *prop_row = uiLayoutRow(split, true); @@ -1451,7 +1451,7 @@ static void add_attribute_search_or_value_buttons(const bContext &C, uiItemL(layout, "", ICON_BLANK1); } else { - const char *name = type == SOCK_BOOLEAN ? (socket.name ? socket.name : "") : ""; + const char *name = type == SOCK_BOOLEAN ? (socket.name ? IFACE_(socket.name) : "") : ""; uiItemR(prop_row, md_ptr, rna_path.c_str(), UI_ITEM_NONE, name, ICON_NONE); uiItemDecoratorR(layout, md_ptr, rna_path.c_str(), -1); } @@ -1504,7 +1504,7 @@ static void draw_property_for_socket(const bContext &C, * pointer IDProperties contain no information about their type. */ const bNodeSocketType *typeinfo = socket.socket_typeinfo(); const eNodeSocketDatatype type = typeinfo ? eNodeSocketDatatype(typeinfo->type) : SOCK_CUSTOM; - const char *name = socket.name ? socket.name : ""; + const char *name = socket.name ? IFACE_(socket.name) : ""; switch (type) { case SOCK_OBJECT: { uiItemPointerR(row, md_ptr, rna_path, bmain_ptr, "objects", name, ICON_OBJECT_DATA); From 7231ac0a52767449cbee3e3ea0cfad579e270a07 Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Sun, 22 Oct 2023 13:54:25 +0200 Subject: [PATCH 61/62] I18n: extract and disambiguate a few messages Extract: - "Attribute", when creating a new attribute with `GEOMETRY_OT_attribute_add()`: make the default name in the operator a null string, and set it to "Attribute" translated inside an invoke method instead. - Also for new attributes, from `BKE_id_attribute_calc_unique_name()`, for instance to create a default vertex color layer when going into Vertex Paint mode: use `DATA_()` instead of `IFACE_()`, since it represents user data. Disambiguate: - "Weight" can be the thickness of font glyphs. - "Mark as Asset" and "Clear Asset" are operator names already extracted using the Operator context. They were recently added to a manual translation in the UI, but the existing one can be reused. - "Second" as a time unit in the context of frame snapping. Some messages reported by Satoshi Yamasaki in #43295. Pull Request: https://projects.blender.org/blender/blender/pulls/114159 --- scripts/startup/bl_ui/space_userpref.py | 2 +- source/blender/blenkernel/intern/attribute.cc | 4 +- .../editors/geometry/geometry_attributes.cc | 38 +++++++++++++++++-- .../interface/interface_context_menu.cc | 10 ++++- source/blender/makesrna/intern/rna_scene.cc | 1 + 5 files changed, 46 insertions(+), 9 deletions(-) diff --git a/scripts/startup/bl_ui/space_userpref.py b/scripts/startup/bl_ui/space_userpref.py index bb58c689f06..2292c6dd9c9 100644 --- a/scripts/startup/bl_ui/space_userpref.py +++ b/scripts/startup/bl_ui/space_userpref.py @@ -1076,7 +1076,7 @@ class USERPREF_PT_theme_text_style(ThemePanel, CenterAlignMixIn, Panel): col = flow.column() col.prop(font_style, "points") - col.prop(font_style, "character_weight", text="Weight") + col.prop(font_style, "character_weight", text="Weight", text_ctxt=i18n_contexts.id_text) col = flow.column(align=True) col.prop(font_style, "shadow_offset_x", text="Shadow Offset X") diff --git a/source/blender/blenkernel/intern/attribute.cc b/source/blender/blenkernel/intern/attribute.cc index 68c20c91d4e..16d3ed4b967 100644 --- a/source/blender/blenkernel/intern/attribute.cc +++ b/source/blender/blenkernel/intern/attribute.cc @@ -270,8 +270,8 @@ void BKE_id_attribute_calc_unique_name(ID *id, const char *name, char *outname) const int name_maxncpy = CustomData_name_maxncpy_calc(name); /* Set default name if none specified. - * NOTE: We only call IFACE_() if needed to avoid locale lookup overhead. */ - BLI_strncpy_utf8(outname, (name && name[0]) ? name : IFACE_("Attribute"), name_maxncpy); + * NOTE: We only call DATA_() if needed to avoid locale lookup overhead. */ + BLI_strncpy_utf8(outname, (name && name[0]) ? name : DATA_("Attribute"), name_maxncpy); const char *defname = ""; /* Dummy argument, never used as `name` is never zero length. */ BLI_uniquename_cb(unique_name_cb, &data, defname, '.', outname, name_maxncpy); diff --git a/source/blender/editors/geometry/geometry_attributes.cc b/source/blender/editors/geometry/geometry_attributes.cc index 708403ab679..12603f2fd0a 100644 --- a/source/blender/editors/geometry/geometry_attributes.cc +++ b/source/blender/editors/geometry/geometry_attributes.cc @@ -24,6 +24,10 @@ #include "BKE_paint.hh" #include "BKE_report.h" +#include "BLI_string.h" + +#include "BLT_translation.h" + #include "RNA_access.hh" #include "RNA_define.hh" #include "RNA_enum_types.hh" @@ -241,6 +245,16 @@ static int geometry_attribute_add_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int geometry_attribute_add_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + PropertyRNA *prop; + prop = RNA_struct_find_property(op->ptr, "name"); + if (!RNA_property_is_set(op->ptr, prop)) { + RNA_property_string_set(op->ptr, prop, DATA_("Attribute")); + } + return WM_operator_props_popup_confirm(C, op, event); +} + void GEOMETRY_OT_attribute_add(wmOperatorType *ot) { /* identifiers */ @@ -251,7 +265,7 @@ void GEOMETRY_OT_attribute_add(wmOperatorType *ot) /* api callbacks */ ot->poll = geometry_attributes_poll; ot->exec = geometry_attribute_add_exec; - ot->invoke = WM_operator_props_popup_confirm; + ot->invoke = geometry_attribute_add_invoke; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -259,7 +273,10 @@ void GEOMETRY_OT_attribute_add(wmOperatorType *ot) /* properties */ PropertyRNA *prop; - prop = RNA_def_string(ot->srna, "name", "Attribute", MAX_NAME, "Name", "Name of new attribute"); + /* The default name of the new attribute can be translated if new data translation is enabled, + * but since the user can choose it at invoke time, the translation happens in the invoke + * callback instead of here. */ + prop = RNA_def_string(ot->srna, "name", nullptr, MAX_NAME, "Name", "Name of new attribute"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); prop = RNA_def_enum(ot->srna, @@ -348,6 +365,16 @@ static int geometry_color_attribute_add_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int geometry_color_attribute_add_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + PropertyRNA *prop; + prop = RNA_struct_find_property(op->ptr, "name"); + if (!RNA_property_is_set(op->ptr, prop)) { + RNA_property_string_set(op->ptr, prop, DATA_("Color")); + } + return WM_operator_props_popup_confirm(C, op, event); +} + enum class ConvertAttributeMode { Generic, VertexGroup, @@ -454,7 +481,7 @@ void GEOMETRY_OT_color_attribute_add(wmOperatorType *ot) /* api callbacks */ ot->poll = geometry_attributes_poll; ot->exec = geometry_color_attribute_add_exec; - ot->invoke = WM_operator_props_popup_confirm; + ot->invoke = geometry_color_attribute_add_invoke; ot->ui = geometry_color_attribute_add_ui; /* flags */ @@ -463,8 +490,11 @@ void GEOMETRY_OT_color_attribute_add(wmOperatorType *ot) /* properties */ PropertyRNA *prop; + /* The default name of the new attribute can be translated if new data translation is enabled, + * but since the user can choose it at invoke time, the translation happens in the invoke + * callback instead of here. */ prop = RNA_def_string( - ot->srna, "name", "Color", MAX_NAME, "Name", "Name of new color attribute"); + ot->srna, "name", nullptr, MAX_NAME, "Name", "Name of new color attribute"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); prop = RNA_def_enum(ot->srna, diff --git a/source/blender/editors/interface/interface_context_menu.cc b/source/blender/editors/interface/interface_context_menu.cc index 015b3fc89e5..bd5b9314056 100644 --- a/source/blender/editors/interface/interface_context_menu.cc +++ b/source/blender/editors/interface/interface_context_menu.cc @@ -979,10 +979,16 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but, const wmEvent *ev * which isn't cheap to check. */ uiLayout *sub = uiLayoutColumn(layout, true); uiLayoutSetEnabled(sub, !id->asset_data); - uiItemO(sub, IFACE_("Mark as Asset"), ICON_ASSET_MANAGER, "ASSET_OT_mark_single"); + uiItemO(sub, + CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Mark as Asset"), + ICON_ASSET_MANAGER, + "ASSET_OT_mark_single"); sub = uiLayoutColumn(layout, true); uiLayoutSetEnabled(sub, id->asset_data); - uiItemO(sub, IFACE_("Clear Asset"), ICON_NONE, "ASSET_OT_clear_single"); + uiItemO(sub, + CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Asset"), + ICON_NONE, + "ASSET_OT_clear_single"); uiItemS(layout); } diff --git a/source/blender/makesrna/intern/rna_scene.cc b/source/blender/makesrna/intern/rna_scene.cc index c53c6fe754c..3c6d1ad666c 100644 --- a/source/blender/makesrna/intern/rna_scene.cc +++ b/source/blender/makesrna/intern/rna_scene.cc @@ -3485,6 +3485,7 @@ static void rna_def_tool_settings(BlenderRNA *brna) RNA_def_property_enum_bitflag_sdna(prop, nullptr, "snap_anim_mode"); RNA_def_property_enum_items(prop, rna_enum_snap_animation_element_items); RNA_def_property_ui_text(prop, "Snap Anim Element", "Type of element to snap to"); + RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_UNIT); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr); /* header redraw */ /* image editor uses own set of snap modes */ From b1c7b573c0a71215f1d93d2f450368a401c6d7ed Mon Sep 17 00:00:00 2001 From: Aras Pranckevicius Date: Tue, 7 Nov 2023 18:22:17 +0100 Subject: [PATCH 62/62] mesh: use faster acos() variant in normals calculation Function Module Inclusive Time Exclusive Time -------------------------------------------------------------------------- mesh_render_data_update_normals blender 297.51 0.00 315 -> 297 acos() usage in all places related to normal calculations shows up in the profiler. Given that "angle between faces" is only additional heuristic weight in there (the effect of it at all is very subtle), approximate but faster version of acos() might be just fine. Especially since some other parts of Blender (e.g. mikktspace) use approximate acos in a conceptually the same part. - Adds safe_acos_approx() to BLI_math_base.hh. Implementation the same as already exists in Cycles; max error 0.00258 degrees. Between 2x and 4x faster in my tests. - Changes all normals related calculations to use the function above instead of saacos. Computing normals on a Stanford Lucy (14m verts) mesh: - Mac (arm64, M1 Max): 247ms -> 229ms - Win (x64, Ryzen 5950X): 276ms -> 250ms All places that are about "normal calculation" were changed, including e.g. Corrective Smooth modifier. Applying that one to the same 14m vertices mesh, Mac M1 Max: 9.96s -> 9.76s Tiny changes in several test output expectations w.r.t. normals are observed, these were reviewed and updated expectations checked in svn. Pull Request: https://projects.blender.org/blender/blender/pulls/114501 --- .../blender/blenkernel/intern/mesh_normals.cc | 18 ++++++++++-------- source/blender/blenlib/BLI_math_base.hh | 18 ++++++++++++++++++ source/blender/blenlib/intern/math_geom.cc | 7 ++++--- .../blender/bmesh/intern/bmesh_mesh_normals.cc | 5 +++-- source/blender/bmesh/intern/bmesh_polygon.cc | 3 ++- .../modifiers/intern/MOD_correctivesmooth.cc | 4 +++- 6 files changed, 40 insertions(+), 15 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index 640075689f3..5aa268c6c3a 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -23,6 +23,7 @@ #include "BLI_array_utils.hh" #include "BLI_bit_vector.hh" #include "BLI_linklist.h" +#include "BLI_math_base.hh" #include "BLI_math_vector.hh" #include "BLI_memarena.h" #include "BLI_span.hh" @@ -243,7 +244,7 @@ static void accumulate_face_normal_to_vert(const Span positions, } /* Calculate angle between the two face edges incident on this vertex. */ - const float fac = saacos(-dot_v3v3(edvec_prev, edvec_next)); + const float fac = math::safe_acos_approx(-dot_v3v3(edvec_prev, edvec_next)); const float vnor_add[3] = {face_normal[0] * fac, face_normal[1] * fac, face_normal[2] * fac}; float *vnor = vert_normals[face_verts[i_curr]]; @@ -535,7 +536,7 @@ static CornerNormalSpace lnor_space_define(const float lnor[3], if (!edge_vectors.is_empty()) { float alpha = 0.0f; for (const float3 &vec : edge_vectors) { - alpha += saacosf(dot_v3v3(vec, lnor)); + alpha += math::safe_acos_approx(dot_v3v3(vec, lnor)); } /* This piece of code shall only be called for more than one loop. */ /* NOTE: In theory, this could be `count > 2`, @@ -546,8 +547,8 @@ static CornerNormalSpace lnor_space_define(const float lnor[3], lnor_space.ref_alpha = alpha / float(edge_vectors.size()); } else { - lnor_space.ref_alpha = (saacosf(dot_v3v3(vec_ref, lnor)) + - saacosf(dot_v3v3(vec_other, lnor))) / + lnor_space.ref_alpha = (math::safe_acos_approx(dot_v3v3(vec_ref, lnor)) + + math::safe_acos_approx(dot_v3v3(vec_other, lnor))) / 2.0f; } @@ -567,7 +568,7 @@ static CornerNormalSpace lnor_space_define(const float lnor[3], /* Beta is angle between ref_vec and other_vec, around lnor. */ dtp = dot_v3v3(lnor_space.vec_ref, vec_other); if (LIKELY(dtp < LNOR_SPACE_TRIGO_THRESHOLD)) { - const float beta = saacos(dtp); + const float beta = math::safe_acos_approx(dtp); lnor_space.ref_beta = (dot_v3v3(lnor_space.vec_ortho, vec_other) < 0.0f) ? pi2 - beta : beta; } else { @@ -698,7 +699,7 @@ short2 lnor_space_custom_normal_to_data(const CornerNormalSpace &lnor_space, float vec[3], cos_beta; float alpha; - alpha = saacosf(cos_alpha); + alpha = math::safe_acos_approx(cos_alpha); if (alpha > lnor_space.ref_alpha) { /* Note we could stick to [0, pi] range here, * but makes decoding more complex, not worth it. */ @@ -716,7 +717,7 @@ short2 lnor_space_custom_normal_to_data(const CornerNormalSpace &lnor_space, cos_beta = dot_v3v3(lnor_space.vec_ref, vec); if (cos_beta < LNOR_SPACE_TRIGO_THRESHOLD) { - float beta = saacosf(cos_beta); + float beta = math::safe_acos_approx(cos_beta); if (dot_v3v3(lnor_space.vec_ortho, vec) < 0.0f) { beta = pi2 - beta; } @@ -1097,7 +1098,8 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, /* Code similar to accumulate_vertex_normals_poly_v3. */ /* Calculate angle between the two face edges incident on this vertex. */ - lnor += face_normals[loop_to_face[mlfan_curr_index]] * saacos(math::dot(vec_curr, vec_prev)); + lnor += face_normals[loop_to_face[mlfan_curr_index]] * + math::safe_acos_approx(math::dot(vec_curr, vec_prev)); processed_corners.append(mlfan_vert_index); diff --git a/source/blender/blenlib/BLI_math_base.hh b/source/blender/blenlib/BLI_math_base.hh index 6176f9724bf..dfed31bd5cf 100644 --- a/source/blender/blenlib/BLI_math_base.hh +++ b/source/blender/blenlib/BLI_math_base.hh @@ -192,6 +192,24 @@ template inline T safe_acos(const T &a) return math::acos((a)); } +/* Faster/approximate version of acosf. Max error 4.51803e-5 (0.00258 degrees).*/ +inline float safe_acos_approx(float x) +{ + const float f = fabsf(x); + /* clamp and crush denormals. */ + const float m = (f < 1.0f) ? 1.0f - (1.0f - f) : 1.0f; + /* Based on http://www.pouet.net/topic.php?which=9132&page=2 + * 85% accurate (ULP 0) + * Examined 2130706434 values of acos: + * 15.2000597 avg ULP diff, 4492 max ULP, 4.51803e-05 max error // without "denormal crush" + * Examined 2130706434 values of acos: + * 15.2007108 avg ULP diff, 4492 max ULP, 4.51803e-05 max error // with "denormal crush" + */ + const float a = sqrtf(1.0f - m) * + (1.5707963267f + m * (-0.213300989f + m * (0.077980478f + m * -0.02164095f))); + return x < 0 ? (float)M_PI - a : a; +} + template inline T asin(const T &a) { return std::asin(a); diff --git a/source/blender/blenlib/intern/math_geom.cc b/source/blender/blenlib/intern/math_geom.cc index d45d3f385e2..996711a0855 100644 --- a/source/blender/blenlib/intern/math_geom.cc +++ b/source/blender/blenlib/intern/math_geom.cc @@ -8,6 +8,7 @@ #include "BLI_array.hh" #include "BLI_math_base.h" +#include "BLI_math_base.hh" #include "BLI_math_geom.h" #include "BLI_math_bits.h" @@ -5015,7 +5016,7 @@ void accumulate_vertex_normals_tri_v3(float n1[3], for (i = 0; i < nverts; i++) { const float *cur_edge = vdiffs[i]; - const float fac = saacos(-dot_v3v3(cur_edge, prev_edge)); + const float fac = blender::math::safe_acos_approx(-dot_v3v3(cur_edge, prev_edge)); /* accumulate */ madd_v3_v3fl(vn[i], f_no, fac); @@ -5062,7 +5063,7 @@ void accumulate_vertex_normals_v3(float n1[3], for (i = 0; i < nverts; i++) { const float *cur_edge = vdiffs[i]; - const float fac = saacos(-dot_v3v3(cur_edge, prev_edge)); + const float fac = blender::math::safe_acos_approx(-dot_v3v3(cur_edge, prev_edge)); /* accumulate */ madd_v3_v3fl(vn[i], f_no, fac); @@ -5094,7 +5095,7 @@ void accumulate_vertex_normals_poly_v3(float **vertnos, /* calculate angle between the two poly edges incident on * this vertex */ - const float fac = saacos(-dot_v3v3(cur_edge, prev_edge)); + const float fac = blender::math::safe_acos_approx(-dot_v3v3(cur_edge, prev_edge)); /* accumulate */ madd_v3_v3fl(vertnos[i], polyno, fac); diff --git a/source/blender/bmesh/intern/bmesh_mesh_normals.cc b/source/blender/bmesh/intern/bmesh_mesh_normals.cc index bd7d8fc90e5..8824c6a820b 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_normals.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_normals.cc @@ -16,6 +16,7 @@ #include "BLI_bitmap.h" #include "BLI_linklist_stack.h" +#include "BLI_math_base.hh" #include "BLI_math_vector.h" #include "BLI_task.h" #include "BLI_utildefines.h" @@ -72,7 +73,7 @@ BLI_INLINE void bm_vert_calc_normals_accum_loop(const BMLoop *l_iter, if ((l_iter->prev->e->v1 == l_iter->prev->v) ^ (l_iter->e->v1 == l_iter->v)) { dotprod = -dotprod; } - const float fac = saacos(-dotprod); + const float fac = blender::math::safe_acos_approx(-dotprod); /* Shouldn't happen as normalizing edge-vectors cause degenerate values to be zeroed out. */ BLI_assert(!isnan(fac)); madd_v3_v3fl(v_no, f_no, fac); @@ -642,7 +643,7 @@ static int bm_mesh_loops_calc_normals_for_loop(BMesh *bm, /* Code similar to accumulate_vertex_normals_poly_v3. */ /* Calculate angle between the two face edges incident on this vertex. */ const BMFace *f = lfan_pivot->f; - const float fac = saacos(dot_v3v3(vec_next, vec_curr)); + const float fac = blender::math::safe_acos_approx(dot_v3v3(vec_next, vec_curr)); const float *no = fnos ? fnos[BM_elem_index_get(f)] : f->no; /* Accumulate */ madd_v3_v3fl(lnor, no, fac); diff --git a/source/blender/bmesh/intern/bmesh_polygon.cc b/source/blender/bmesh/intern/bmesh_polygon.cc index 983bf6144f7..ca9ea78ecf7 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.cc +++ b/source/blender/bmesh/intern/bmesh_polygon.cc @@ -18,6 +18,7 @@ #include "BLI_alloca.h" #include "BLI_heap.h" #include "BLI_linklist.h" +#include "BLI_math_base.hh" #include "BLI_math_geom.h" #include "BLI_math_matrix.h" #include "BLI_math_vector.h" @@ -615,7 +616,7 @@ static void bm_loop_normal_accum(const BMLoop *l, float no[3]) normalize_v3(vec1); normalize_v3(vec2); - fac = saacos(-dot_v3v3(vec1, vec2)); + fac = blender::math::safe_acos_approx(-dot_v3v3(vec1, vec2)); madd_v3_v3fl(no, l->f->no, fac); } diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.cc b/source/blender/modifiers/intern/MOD_correctivesmooth.cc index 10bb74dd4e1..814b4157d24 100644 --- a/source/blender/modifiers/intern/MOD_correctivesmooth.cc +++ b/source/blender/modifiers/intern/MOD_correctivesmooth.cc @@ -8,6 +8,7 @@ * Method of smoothing deformation, also known as 'delta-mush'. */ +#include "BLI_math_base.hh" #include "BLI_math_matrix.h" #include "BLI_math_vector.h" #include "BLI_utildefines.h" @@ -470,7 +471,8 @@ static void calc_tangent_spaces(const Mesh *mesh, if (calc_tangent_loop(v_dir_prev, v_dir_next, ts)) { if (r_tangent_weights != nullptr) { - const float weight = fabsf(acosf(dot_v3v3(v_dir_next, v_dir_prev))); + const float weight = fabsf( + blender::math::safe_acos_approx(dot_v3v3(v_dir_next, v_dir_prev))); r_tangent_weights[curr_corner] = weight; r_tangent_weights_per_vertex[corner_verts[curr_corner]] += weight; }