diff --git a/build_files/build_environment/install_linux_packages.py b/build_files/build_environment/install_linux_packages.py index 98eb0b11d0c..c9726b2be61 100755 --- a/build_files/build_environment/install_linux_packages.py +++ b/build_files/build_environment/install_linux_packages.py @@ -689,7 +689,7 @@ PACKAGES_ALL = ( DISTRO_ID_ARCH: "clang", # clang-format is part of the main clang package. }, ), - Package(name="Python", is_mandatory=True, version="3.10.9", version_short="3.10", version_min="3.10", version_mex="3.12", + Package(name="Python", is_mandatory=True, version="3.10.11", version_short="3.10", version_min="3.10", version_mex="3.12", sub_packages=PYTHON_SUBPACKAGES, distro_package_names={DISTRO_ID_DEBIAN: "python3-dev", DISTRO_ID_FEDORA: "python3-devel", @@ -721,7 +721,7 @@ PACKAGES_ALL = ( DISTRO_ID_ARCH: "opencolorio", }, ), - Package(name="IMath Library", is_mandatory=False, version="3.1.5", version_short="3.1", version_min="3.0", version_mex="4.0", + Package(name="IMath Library", is_mandatory=False, version="3.1.7", version_short="3.1", version_min="3.0", version_mex="4.0", sub_packages=(), distro_package_names={DISTRO_ID_DEBIAN: "libimath-dev", DISTRO_ID_FEDORA: "imath-devel", @@ -729,7 +729,7 @@ PACKAGES_ALL = ( DISTRO_ID_ARCH: "imath", }, ), - Package(name="OpenEXR Library", is_mandatory=False, version="3.1.5", version_short="3.1", version_min="3.0", version_mex="4.0", + Package(name="OpenEXR Library", is_mandatory=False, version="3.1.7", version_short="3.1", version_min="3.0", version_mex="4.0", sub_packages=(), distro_package_names={DISTRO_ID_DEBIAN: "libopenexr-dev", DISTRO_ID_FEDORA: "openexr-devel", @@ -737,7 +737,7 @@ PACKAGES_ALL = ( DISTRO_ID_ARCH: "openexr", }, ), - Package(name="OpenImageIO Library", is_mandatory=True, version="2.4.9.0", version_short="2.4", version_min="2.2.0", version_mex="2.5.0", + Package(name="OpenImageIO Library", is_mandatory=True, version="2.4.11.0", version_short="2.4", version_min="2.2.0", version_mex="2.5.0", sub_packages=( Package(name="OpenImageIO Tools", is_mandatory=False, distro_package_names={DISTRO_ID_DEBIAN: "openimageio-tools", @@ -836,7 +836,7 @@ PACKAGES_ALL = ( DISTRO_ID_ARCH: "materialx-git", }, ), - Package(name="USD Library", is_mandatory=False, version="22.11", version_short="22.11", version_min="20.05", version_mex="23.00", + Package(name="USD Library", is_mandatory=False, version="23.05", version_short="23.05", version_min="20.05", version_mex="24.00", sub_packages=(), distro_package_names={DISTRO_ID_DEBIAN: None, DISTRO_ID_FEDORA: "usd-devel", @@ -851,7 +851,7 @@ PACKAGES_ALL = ( DISTRO_ID_ARCH: "opencollada", }, ), - Package(name="Embree Library", is_mandatory=False, version="3.13.4", version_short="3.13", version_min="3.13", version_mex="5.0", + Package(name="Embree Library", is_mandatory=False, version="4.1.0", version_short="4.1", version_min="3.13", version_mex="5.0", sub_packages=(), distro_package_names={DISTRO_ID_DEBIAN: "libembree-dev", DISTRO_ID_FEDORA: "embree-devel", @@ -867,7 +867,7 @@ PACKAGES_ALL = ( DISTRO_ID_ARCH: "openimagedenoise", }, ), - Package(name="Level Zero Library", is_mandatory=False, version="1.7.15", version_short="1.7", version_min="1.7", version_mex="2.0", + Package(name="Level Zero Library", is_mandatory=False, version="1.8.8", version_short="1.8", version_min="1.7", version_mex="2.0", sub_packages=(), distro_package_names={DISTRO_ID_DEBIAN: None, DISTRO_ID_FEDORA: "oneapi-level-zero-devel", @@ -875,7 +875,7 @@ PACKAGES_ALL = ( DISTRO_ID_ARCH: "level-zero-headers", # ??? }, ), - Package(name="OpenPGL Library", is_mandatory=False, version="0.4.1", version_short="0.4", version_min="0.4.1", version_mex="0.5", + Package(name="OpenPGL Library", is_mandatory=False, version="0.5.0", version_short="0.5", version_min="0.5.0", version_mex="0.6", sub_packages=(), distro_package_names={DISTRO_ID_DEBIAN: None, DISTRO_ID_FEDORA: "openpgl-devel", @@ -891,7 +891,7 @@ PACKAGES_ALL = ( DISTRO_ID_ARCH: "openxr", }, ), - Package(name="FFMPEG Library", is_mandatory=False, version="5.1.2", version_short="5.1", version_min="4.0", version_mex="7.0", + Package(name="FFMPEG Library", is_mandatory=False, version="6.0", version_short="6.0", version_min="4.0", version_mex="7.0", sub_packages=( Package(name="AVDevice FFMPEG Library", is_mandatory=False, distro_package_names={DISTRO_ID_DEBIAN: "libavdevice-dev", diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake index ffc56c973eb..f6021d1c01b 100644 --- a/build_files/cmake/platform/platform_win32.cmake +++ b/build_files/cmake/platform/platform_win32.cmake @@ -39,8 +39,14 @@ if(CMAKE_C_COMPILER_ID MATCHES "Clang") set(WITH_WINDOWS_STRIPPED_PDB OFF) endif() else() - if(WITH_BLENDER AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.28.29921) # MSVC 2019 16.9.16 - message(FATAL_ERROR "Compiler is unsupported, MSVC 2019 16.9.16 or newer is required for building blender.") + if(WITH_BLENDER) + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.28.29921) # MSVC 2019 16.9.16 + message(FATAL_ERROR "Compiler is unsupported, MSVC 2019 16.9.16 or newer is required for building blender.") + endif() + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.36.32532 AND # MSVC 2022 17.6.0 has a bad codegen + CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.37.32705) # But it is fixed in 2022 17.7 preview 1 + message(FATAL_ERROR "Compiler is unsupported, MSVC 2022 17.6.x has codegen issues and cannot be used to build blender. Please use MSVC 17.5 for the time being.") + endif() endif() endif() diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 442f06c10f1..24960bcb09f 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -209,6 +209,21 @@ enum_guiding_distribution = ( ('VMM', "VMM", "Use von Mises-Fisher models as directional distribution", 2), ) +enum_guiding_directional_sampling_types = ( + ('MIS', + "Diffuse Product MIS", + "Guided diffuse BSDF component based on the incoming light distribution and the cosine product (closed form product)", + 0), + ('RIS', + "Re-sampled Importance Sampling", + "Perform RIS sampling to guided based on the product of the incoming light distribution and the BSDF", + 1), + ('ROUGHNESS', + "Roughness-based", + "Adjust the guiding probability based on the roughness of the material components", + 2), +) + def enum_openimagedenoise_denoiser(self, context): import _cycles @@ -568,6 +583,13 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): default='PARALLAX_AWARE_VMM', ) + guiding_directional_sampling_type: EnumProperty( + name="Directional Sampling Type", + description="Type of the directional sampling used for guiding", + items=enum_guiding_directional_sampling_types, + default='RIS', + ) + use_surface_guiding: BoolProperty( name="Surface Guiding", description="Use guiding when sampling directions on a surface", @@ -617,6 +639,13 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): default=True, ) + guiding_roughness_threshold: FloatProperty( + name="Guiding Roughness Threshold", + description="The minimal roughness value of a material to apply guiding", + min=0.0, max=1.0, + default=0.05, + ) + max_bounces: IntProperty( name="Max Bounces", description="Total maximum number of bounces", diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 23e6a3626b8..3f19a7cce43 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -337,6 +337,8 @@ class CYCLES_RENDER_PT_sampling_path_guiding_debug(CyclesDebugButtonsPanel, Pane layout.active = cscene.use_guiding layout.prop(cscene, "guiding_distribution_type", text="Distribution Type") + layout.prop(cscene, "guiding_roughness_threshold") + layout.prop(cscene, "guiding_directional_sampling_type", text="Directional Sampling Type") col = layout.column(align=True) col.prop(cscene, "surface_guiding_probability") diff --git a/intern/cycles/blender/device.cpp b/intern/cycles/blender/device.cpp index 3059035f320..abcb6de827c 100644 --- a/intern/cycles/blender/device.cpp +++ b/intern/cycles/blender/device.cpp @@ -30,6 +30,25 @@ int blender_device_threads(BL::Scene &b_scene) return 0; } +void adjust_device_info_from_preferences(DeviceInfo &info, PointerRNA cpreferences) +{ + if (!get_boolean(cpreferences, "peer_memory")) { + info.has_peer_memory = false; + } + + if (info.type == DEVICE_METAL && !get_boolean(cpreferences, "use_metalrt")) { + info.use_hardware_raytracing = false; + } + + if (info.type == DEVICE_ONEAPI && !get_boolean(cpreferences, "use_oneapirt")) { + info.use_hardware_raytracing = false; + } + + if (info.type == DEVICE_HIP && !get_boolean(cpreferences, "use_hiprt")) { + info.use_hardware_raytracing = false; + } +} + DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scene, bool background, @@ -108,35 +127,17 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, } } - if (!get_boolean(cpreferences, "peer_memory")) { - device.has_peer_memory = false; - } + adjust_device_info_from_preferences(device, cpreferences); + foreach (DeviceInfo &info, device.multi_devices) { + adjust_device_info_from_preferences(info, cpreferences); - bool accumulated_use_hardware_raytracing = false; - foreach ( - DeviceInfo &info, - (device.multi_devices.size() != 0 ? device.multi_devices : vector({device}))) - { - if (info.type == DEVICE_METAL && !get_boolean(cpreferences, "use_metalrt")) { - info.use_hardware_raytracing = false; - } - - if (info.type == DEVICE_ONEAPI && !get_boolean(cpreferences, "use_oneapirt")) { - info.use_hardware_raytracing = false; - } - - if (info.type == DEVICE_HIP && !get_boolean(cpreferences, "use_hiprt")) { - info.use_hardware_raytracing = false; - } - - /* There is an accumulative logic here, because Multi-devices are support only for + /* There is an accumulative logic here, because Multi-devices are supported only for * the same backend + CPU in Blender right now, and both oneAPI and Metal have a - * global boolean backend setting (see above) for enabling/disabling HW RT, - * so all sub-devices in the multi-device should enable (or disable) HW RT - * simultaneously (and CPU device are expected to ignore `use_hardware_raytracing` setting). */ - accumulated_use_hardware_raytracing |= info.use_hardware_raytracing; + * global boolean backend setting for enabling/disabling Hardware Ray Tracing, + * so all sub-devices in the multi-device should enable (or disable) Hardware Ray Tracing + * simultaneously (and CPU device is expected to ignore `use_hardware_raytracing` setting). */ + device.use_hardware_raytracing |= info.use_hardware_raytracing; } - device.use_hardware_raytracing = accumulated_use_hardware_raytracing; if (preview) { /* Disable specialization for preview renders. */ diff --git a/intern/cycles/blender/shader.cpp b/intern/cycles/blender/shader.cpp index ecf4384aee7..c6cbeff9213 100644 --- a/intern/cycles/blender/shader.cpp +++ b/intern/cycles/blender/shader.cpp @@ -523,27 +523,6 @@ static ShaderNode *add_node(Scene *scene, else if (b_node.is_a(&RNA_ShaderNodeHoldout)) { node = graph->create_node(); } - else if (b_node.is_a(&RNA_ShaderNodeBsdfAnisotropic)) { - BL::ShaderNodeBsdfAnisotropic b_aniso_node(b_node); - AnisotropicBsdfNode *aniso = graph->create_node(); - - switch (b_aniso_node.distribution()) { - case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN: - aniso->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_ID); - break; - case BL::ShaderNodeBsdfAnisotropic::distribution_GGX: - aniso->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_ID); - break; - case BL::ShaderNodeBsdfAnisotropic::distribution_MULTI_GGX: - aniso->set_distribution(CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID); - break; - case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY: - aniso->set_distribution(CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID); - break; - } - - node = aniso; - } else if (b_node.is_a(&RNA_ShaderNodeBsdfDiffuse)) { node = graph->create_node(); } @@ -566,24 +545,21 @@ static ShaderNode *add_node(Scene *scene, node = subsurface; } - else if (b_node.is_a(&RNA_ShaderNodeBsdfGlossy)) { - BL::ShaderNodeBsdfGlossy b_glossy_node(b_node); + else if (b_node.is_a(&RNA_ShaderNodeBsdfAnisotropic)) { + BL::ShaderNodeBsdfAnisotropic b_glossy_node(b_node); GlossyBsdfNode *glossy = graph->create_node(); switch (b_glossy_node.distribution()) { - case BL::ShaderNodeBsdfGlossy::distribution_SHARP: - glossy->set_distribution(CLOSURE_BSDF_REFLECTION_ID); - break; - case BL::ShaderNodeBsdfGlossy::distribution_BECKMANN: + case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN: glossy->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_ID); break; - case BL::ShaderNodeBsdfGlossy::distribution_GGX: + case BL::ShaderNodeBsdfAnisotropic::distribution_GGX: glossy->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_ID); break; - case BL::ShaderNodeBsdfGlossy::distribution_ASHIKHMIN_SHIRLEY: + case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY: glossy->set_distribution(CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID); break; - case BL::ShaderNodeBsdfGlossy::distribution_MULTI_GGX: + case BL::ShaderNodeBsdfAnisotropic::distribution_MULTI_GGX: glossy->set_distribution(CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID); break; } @@ -593,9 +569,6 @@ static ShaderNode *add_node(Scene *scene, BL::ShaderNodeBsdfGlass b_glass_node(b_node); GlassBsdfNode *glass = graph->create_node(); switch (b_glass_node.distribution()) { - case BL::ShaderNodeBsdfGlass::distribution_SHARP: - glass->set_distribution(CLOSURE_BSDF_SHARP_GLASS_ID); - break; case BL::ShaderNodeBsdfGlass::distribution_BECKMANN: glass->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID); break; @@ -612,9 +585,6 @@ static ShaderNode *add_node(Scene *scene, BL::ShaderNodeBsdfRefraction b_refraction_node(b_node); RefractionBsdfNode *refraction = graph->create_node(); switch (b_refraction_node.distribution()) { - case BL::ShaderNodeBsdfRefraction::distribution_SHARP: - refraction->set_distribution(CLOSURE_BSDF_REFRACTION_ID); - break; case BL::ShaderNodeBsdfRefraction::distribution_BECKMANN: refraction->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID); break; diff --git a/intern/cycles/blender/sync.cpp b/intern/cycles/blender/sync.cpp index 40979dfda0b..c7432433826 100644 --- a/intern/cycles/blender/sync.cpp +++ b/intern/cycles/blender/sync.cpp @@ -440,6 +440,13 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background) GuidingDistributionType guiding_distribution_type = (GuidingDistributionType)get_enum( cscene, "guiding_distribution_type", GUIDING_NUM_TYPES, GUIDING_TYPE_PARALLAX_AWARE_VMM); integrator->set_guiding_distribution_type(guiding_distribution_type); + GuidingDirectionalSamplingType guiding_directional_sampling_type = + (GuidingDirectionalSamplingType)get_enum(cscene, + "guiding_directional_sampling_type", + GUIDING_DIRECTIONAL_SAMPLING_NUM_TYPES, + GUIDING_DIRECTIONAL_SAMPLING_TYPE_RIS); + integrator->set_guiding_directional_sampling_type(guiding_directional_sampling_type); + integrator->set_guiding_roughness_threshold(get_float(cscene, "guiding_roughness_threshold")); } DenoiseParams denoise_params = get_denoise_params(b_scene, b_view_layer, background); diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp index 6db59e81a89..c948fc1a48e 100644 --- a/intern/cycles/bvh/bvh.cpp +++ b/intern/cycles/bvh/bvh.cpp @@ -33,12 +33,16 @@ const char *bvh_layout_name(BVHLayout layout) return "METAL"; case BVH_LAYOUT_HIPRT: return "HIPRT"; + case BVH_LAYOUT_EMBREEGPU: + return "EMBREEGPU"; case BVH_LAYOUT_MULTI_OPTIX: case BVH_LAYOUT_MULTI_METAL: case BVH_LAYOUT_MULTI_HIPRT: + case BVH_LAYOUT_MULTI_EMBREEGPU: case BVH_LAYOUT_MULTI_OPTIX_EMBREE: case BVH_LAYOUT_MULTI_METAL_EMBREE: case BVH_LAYOUT_MULTI_HIPRT_EMBREE: + case BVH_LAYOUT_MULTI_EMBREEGPU_EMBREE: return "MULTI"; case BVH_LAYOUT_ALL: return "ALL"; @@ -88,6 +92,7 @@ BVH *BVH::create(const BVHParams ¶ms, case BVH_LAYOUT_BVH2: return new BVH2(params, geometry, objects); case BVH_LAYOUT_EMBREE: + case BVH_LAYOUT_EMBREEGPU: #ifdef WITH_EMBREE return new BVHEmbree(params, geometry, objects); #else @@ -117,9 +122,11 @@ BVH *BVH::create(const BVHParams ¶ms, case BVH_LAYOUT_MULTI_OPTIX: case BVH_LAYOUT_MULTI_METAL: case BVH_LAYOUT_MULTI_HIPRT: + case BVH_LAYOUT_MULTI_EMBREEGPU: case BVH_LAYOUT_MULTI_OPTIX_EMBREE: case BVH_LAYOUT_MULTI_METAL_EMBREE: case BVH_LAYOUT_MULTI_HIPRT_EMBREE: + case BVH_LAYOUT_MULTI_EMBREEGPU_EMBREE: return new BVHMulti(params, geometry, objects); case BVH_LAYOUT_NONE: case BVH_LAYOUT_ALL: diff --git a/intern/cycles/device/cpu/device_impl.cpp b/intern/cycles/device/cpu/device_impl.cpp index 8434dd52d2f..4cf76c1f5fd 100644 --- a/intern/cycles/device/cpu/device_impl.cpp +++ b/intern/cycles/device/cpu/device_impl.cpp @@ -265,7 +265,8 @@ void CPUDevice::build_bvh(BVH *bvh, Progress &progress, bool refit) #ifdef WITH_EMBREE if (bvh->params.bvh_layout == BVH_LAYOUT_EMBREE || bvh->params.bvh_layout == BVH_LAYOUT_MULTI_OPTIX_EMBREE || - bvh->params.bvh_layout == BVH_LAYOUT_MULTI_METAL_EMBREE) + bvh->params.bvh_layout == BVH_LAYOUT_MULTI_METAL_EMBREE || + bvh->params.bvh_layout == BVH_LAYOUT_MULTI_EMBREEGPU_EMBREE) { BVHEmbree *const bvh_embree = static_cast(bvh); if (refit) { diff --git a/intern/cycles/device/multi/device.cpp b/intern/cycles/device/multi/device.cpp index 9f7ee7636a9..3cf81189186 100644 --- a/intern/cycles/device/multi/device.cpp +++ b/intern/cycles/device/multi/device.cpp @@ -122,6 +122,11 @@ class MultiDevice : public Device { return BVH_LAYOUT_MULTI_HIPRT; } + /* With multiple oneAPI devices, every device needs its own acceleration structure */ + if (bvh_layout_mask == BVH_LAYOUT_EMBREEGPU) { + return BVH_LAYOUT_MULTI_EMBREEGPU; + } + /* When devices do not share a common BVH layout, fall back to creating one for each */ const BVHLayoutMask BVH_LAYOUT_OPTIX_EMBREE = (BVH_LAYOUT_OPTIX | BVH_LAYOUT_EMBREE); if ((bvh_layout_mask_all & BVH_LAYOUT_OPTIX_EMBREE) == BVH_LAYOUT_OPTIX_EMBREE) { @@ -131,6 +136,10 @@ class MultiDevice : public Device { if ((bvh_layout_mask_all & BVH_LAYOUT_METAL_EMBREE) == BVH_LAYOUT_METAL_EMBREE) { return BVH_LAYOUT_MULTI_METAL_EMBREE; } + const BVHLayoutMask BVH_LAYOUT_EMBREEGPU_EMBREE = (BVH_LAYOUT_EMBREEGPU | BVH_LAYOUT_EMBREE); + if ((bvh_layout_mask_all & BVH_LAYOUT_EMBREEGPU_EMBREE) == BVH_LAYOUT_EMBREEGPU_EMBREE) { + return BVH_LAYOUT_MULTI_EMBREEGPU_EMBREE; + } return bvh_layout_mask; } @@ -164,9 +173,11 @@ class MultiDevice : public Device { assert(bvh->params.bvh_layout == BVH_LAYOUT_MULTI_OPTIX || bvh->params.bvh_layout == BVH_LAYOUT_MULTI_METAL || bvh->params.bvh_layout == BVH_LAYOUT_MULTI_HIPRT || + bvh->params.bvh_layout == BVH_LAYOUT_MULTI_EMBREEGPU || bvh->params.bvh_layout == BVH_LAYOUT_MULTI_OPTIX_EMBREE || bvh->params.bvh_layout == BVH_LAYOUT_MULTI_METAL_EMBREE || - bvh->params.bvh_layout == BVH_LAYOUT_MULTI_HIPRT_EMBREE); + bvh->params.bvh_layout == BVH_LAYOUT_MULTI_HIPRT_EMBREE || + bvh->params.bvh_layout == BVH_LAYOUT_MULTI_EMBREEGPU_EMBREE); BVHMulti *const bvh_multi = static_cast(bvh); bvh_multi->sub_bvhs.resize(devices.size()); @@ -193,6 +204,8 @@ class MultiDevice : public Device { params.bvh_layout = BVH_LAYOUT_METAL; else if (bvh->params.bvh_layout == BVH_LAYOUT_MULTI_HIPRT) params.bvh_layout = BVH_LAYOUT_HIPRT; + else if (bvh->params.bvh_layout == BVH_LAYOUT_MULTI_EMBREEGPU) + params.bvh_layout = BVH_LAYOUT_EMBREEGPU; else if (bvh->params.bvh_layout == BVH_LAYOUT_MULTI_OPTIX_EMBREE) params.bvh_layout = sub.device->info.type == DEVICE_OPTIX ? BVH_LAYOUT_OPTIX : BVH_LAYOUT_EMBREE; @@ -202,7 +215,9 @@ class MultiDevice : public Device { else if (bvh->params.bvh_layout == BVH_LAYOUT_MULTI_HIPRT_EMBREE) params.bvh_layout = sub.device->info.type == DEVICE_HIPRT ? BVH_LAYOUT_HIPRT : BVH_LAYOUT_EMBREE; - + else if (bvh->params.bvh_layout == BVH_LAYOUT_MULTI_EMBREEGPU_EMBREE) + params.bvh_layout = sub.device->info.type == DEVICE_ONEAPI ? BVH_LAYOUT_EMBREEGPU : + BVH_LAYOUT_EMBREE; /* Skip building a bottom level acceleration structure for non-instanced geometry on Embree * (since they are put into the top level directly, see bvh_embree.cpp) */ if (!params.top_level && params.bvh_layout == BVH_LAYOUT_EMBREE && diff --git a/intern/cycles/device/oneapi/device_impl.cpp b/intern/cycles/device/oneapi/device_impl.cpp index 15b6d365fb5..2f04a522b7e 100644 --- a/intern/cycles/device/oneapi/device_impl.cpp +++ b/intern/cycles/device/oneapi/device_impl.cpp @@ -122,7 +122,8 @@ bool OneapiDevice::check_peer_access(Device * /*peer_device*/) bool OneapiDevice::can_use_hardware_raytracing_for_features(uint requested_features) const { - /* MNEE and Raytrace kernels work correctly with Hardware Raytracing starting with Embree 4.1. */ + /* MNEE and Ray-trace kernels work correctly with Hardware Ray-tracing starting with Embree 4.1. + */ # if defined(RTC_VERSION) && RTC_VERSION < 40100 return !(requested_features & (KERNEL_FEATURE_MNEE | KERNEL_FEATURE_NODE_RAYTRACE)); # else @@ -135,14 +136,14 @@ BVHLayoutMask OneapiDevice::get_bvh_layout_mask(uint requested_features) const { return (use_hardware_raytracing && can_use_hardware_raytracing_for_features(requested_features)) ? - BVH_LAYOUT_EMBREE : + BVH_LAYOUT_EMBREEGPU : BVH_LAYOUT_BVH2; } # ifdef WITH_EMBREE_GPU void OneapiDevice::build_bvh(BVH *bvh, Progress &progress, bool refit) { - if (embree_device && bvh->params.bvh_layout == BVH_LAYOUT_EMBREE) { + if (embree_device && bvh->params.bvh_layout == BVH_LAYOUT_EMBREEGPU) { BVHEmbree *const bvh_embree = static_cast(bvh); if (refit) { bvh_embree->refit(progress); @@ -435,7 +436,7 @@ void OneapiDevice::const_copy_to(const char *name, void *host, size_t size) << string_human_readable_size(size) << ")"; # ifdef WITH_EMBREE_GPU - if (strcmp(name, "data") == 0) { + if (embree_scene != nullptr && strcmp(name, "data") == 0) { assert(size <= sizeof(KernelData)); /* Update scene handle(since it is different for each device on multi devices) */ diff --git a/intern/cycles/integrator/guiding.h b/intern/cycles/integrator/guiding.h index b7d7e2fe51e..c8be1fcb89b 100644 --- a/intern/cycles/integrator/guiding.h +++ b/intern/cycles/integrator/guiding.h @@ -15,6 +15,8 @@ struct GuidingParams { bool use_volume_guiding = false; GuidingDistributionType type = GUIDING_TYPE_PARALLAX_AWARE_VMM; + GuidingDirectionalSamplingType sampling_type = GUIDING_DIRECTIONAL_SAMPLING_TYPE_PRODUCT_MIS; + float roughness_threshold = 0.05f; int training_samples = 128; bool deterministic = false; @@ -24,7 +26,9 @@ struct GuidingParams { { return !((use == other.use) && (use_surface_guiding == other.use_surface_guiding) && (use_volume_guiding == other.use_volume_guiding) && (type == other.type) && + (sampling_type == other.sampling_type) && (training_samples == other.training_samples) && + (roughness_threshold == other.roughness_threshold) && (deterministic == other.deterministic)); } }; diff --git a/intern/cycles/kernel/data_template.h b/intern/cycles/kernel/data_template.h index 8851a2b62c7..2661d362b05 100644 --- a/intern/cycles/kernel/data_template.h +++ b/intern/cycles/kernel/data_template.h @@ -207,6 +207,8 @@ KERNEL_STRUCT_MEMBER(integrator, int, direct_light_sampling_type) KERNEL_STRUCT_MEMBER(integrator, float, surface_guiding_probability) KERNEL_STRUCT_MEMBER(integrator, float, volume_guiding_probability) KERNEL_STRUCT_MEMBER(integrator, int, guiding_distribution_type) +KERNEL_STRUCT_MEMBER(integrator, int, guiding_directional_sampling_type) +KERNEL_STRUCT_MEMBER(integrator, float, guiding_roughness_threshold) KERNEL_STRUCT_MEMBER(integrator, int, use_guiding) KERNEL_STRUCT_MEMBER(integrator, int, train_guiding) KERNEL_STRUCT_MEMBER(integrator, int, use_surface_guiding) @@ -216,6 +218,8 @@ KERNEL_STRUCT_MEMBER(integrator, int, use_guiding_mis_weights) /* Padding. */ KERNEL_STRUCT_MEMBER(integrator, int, pad1) +KERNEL_STRUCT_MEMBER(integrator, int, pad2) +KERNEL_STRUCT_MEMBER(integrator, int, pad3) KERNEL_STRUCT_END(KernelIntegrator) /* SVM. For shader specialization. */ diff --git a/intern/cycles/kernel/device/gpu/kernel.h b/intern/cycles/kernel/device/gpu/kernel.h index 3e0d0823baa..6bc8a88aa6e 100644 --- a/intern/cycles/kernel/device/gpu/kernel.h +++ b/intern/cycles/kernel/device/gpu/kernel.h @@ -463,7 +463,7 @@ ccl_gpu_kernel_threads(GPU_PARALLEL_SORTED_INDEX_DEFAULT_BLOCK_SIZE) } ccl_gpu_kernel_postfix -/* oneAPI verion needs the local_mem accessor in the arguments. */ +/* oneAPI Verizon needs the local_mem accessor in the arguments. */ #ifdef __KERNEL_ONEAPI__ ccl_gpu_kernel_threads(GPU_PARALLEL_SORT_BLOCK_SIZE) ccl_gpu_kernel_signature(integrator_sort_bucket_pass, @@ -520,7 +520,7 @@ ccl_gpu_kernel_threads(GPU_PARALLEL_SORT_BLOCK_SIZE) } ccl_gpu_kernel_postfix -/* oneAPI verion needs the local_mem accessor in the arguments. */ +/* oneAPI version needs the local_mem accessor in the arguments. */ #ifdef __KERNEL_ONEAPI__ ccl_gpu_kernel_threads(GPU_PARALLEL_SORT_BLOCK_SIZE) ccl_gpu_kernel_signature(integrator_sort_write_pass, diff --git a/intern/cycles/kernel/device/oneapi/kernel.cpp b/intern/cycles/kernel/device/oneapi/kernel.cpp index d807b159633..b2aeec2d714 100644 --- a/intern/cycles/kernel/device/oneapi/kernel.cpp +++ b/intern/cycles/kernel/device/oneapi/kernel.cpp @@ -109,7 +109,7 @@ size_t oneapi_kernel_preferred_local_size(SyclQueue *queue, assert(queue); (void)kernel_global_size; const static size_t preferred_work_group_size_intersect_shading = 32; - /* Shader evalutation kernels seems to use some amount of shared memory, so better + /* Shader evaluation kernels seems to use some amount of shared memory, so better * to avoid usage of maximum work group sizes for them. */ const static size_t preferred_work_group_size_shader_evaluation = 256; const static size_t preferred_work_group_size_default = 1024; @@ -198,7 +198,7 @@ bool oneapi_kernel_is_required_for_features(const std::string &kernel_name, bool oneapi_kernel_is_compatible_with_hardware_raytracing(const std::string &kernel_name) { - /* MNEE and Raytrace kernels work correctly with Hardware Raytracing starting with Embree 4.1. + /* MNEE and Ray-trace kernels work correctly with Hardware Ray-tracing starting with Embree 4.1. */ # if defined(RTC_VERSION) && RTC_VERSION < 40100 return (kernel_name.find(device_kernel_as_string(DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_MNEE)) == diff --git a/intern/cycles/kernel/integrator/guiding.h b/intern/cycles/kernel/integrator/guiding.h index d42848ce3c0..c91f8af67bd 100644 --- a/intern/cycles/kernel/integrator/guiding.h +++ b/intern/cycles/kernel/integrator/guiding.h @@ -7,10 +7,66 @@ #include "kernel/closure/bsdf.h" #include "kernel/film/write.h" +#if OPENPGL_VERSION_MINOR >= 5 +# define RIS_INCOMING_RADIANCE +#endif + CCL_NAMESPACE_BEGIN /* Utilities. */ +struct GuidingRISSample { + float3 rand; + float2 sampled_roughness; + float eta{1.0f}; + int label; + float3 wo; + float bsdf_pdf{0.0f}; + float guide_pdf{0.0f}; + float ris_target{0.0f}; + float ris_pdf{0.0f}; + float ris_weight{0.0f}; + +#ifdef RIS_INCOMING_RADIANCE + float incoming_radiance_pdf{0.0f}; +#else + float cosine{0.0f}; +#endif + BsdfEval bsdf_eval; + float avg_bsdf_eval{0.0f}; + Spectrum eval{zero_spectrum()}; +}; + +ccl_device_forceinline bool calculate_ris_target(ccl_private GuidingRISSample *ris_sample, + ccl_private const float guiding_sampling_prob) +{ +#if defined(__PATH_GUIDING__) + const float pi_factor = 2.0f; + if (ris_sample->avg_bsdf_eval > 0.0f && ris_sample->bsdf_pdf > 1e-10f && + ris_sample->guide_pdf > 0.0f) + { + +# ifdef RIS_INCOMING_RADIANCE + ris_sample->ris_target = (ris_sample->avg_bsdf_eval * + ((((1.0f - guiding_sampling_prob) * (1.0f / (pi_factor * M_PI_F))) + + (guiding_sampling_prob * ris_sample->incoming_radiance_pdf)))); +# else + ris_sample->ris_target = (ris_sample->avg_bsdf_eval / ris_sample->cosine * + ((((1.0f - guiding_sampling_prob) * (1.0f / (pi_factor * M_PI_F))) + + (guiding_sampling_prob * ris_sample->guide_pdf)))); +# endif + ris_sample->ris_pdf = (0.5f * (ris_sample->bsdf_pdf + ris_sample->guide_pdf)); + ris_sample->ris_weight = ris_sample->ris_target / ris_sample->ris_pdf; + return true; + } + ris_sample->ris_target = 0.0f; + ris_sample->ris_pdf = 0.0f; + return false; +#else + return false; +#endif +} + #if defined(__PATH_GUIDING__) static pgl_vec3f guiding_vec3f(const float3 v) { @@ -241,7 +297,7 @@ ccl_device_forceinline void guiding_record_volume_bounce(KernelGlobals kg, openpgl::cpp::SetPDFDirectionIn(state->guiding.path_segment, pdf); openpgl::cpp::SetScatteringWeight(state->guiding.path_segment, guiding_vec3f(weight_rgb)); openpgl::cpp::SetIsDelta(state->guiding.path_segment, false); - openpgl::cpp::SetEta(state->guiding.path_segment, 1.f); + openpgl::cpp::SetEta(state->guiding.path_segment, 1.0f); openpgl::cpp::SetRoughness(state->guiding.path_segment, roughness); #endif } @@ -259,11 +315,11 @@ ccl_device_forceinline void guiding_record_volume_transmission(KernelGlobals kg, if (state->guiding.path_segment) { // TODO (sherholz): need to find a better way to avoid this check - if ((transmittance_weight[0] < 0.f || !std::isfinite(transmittance_weight[0]) || + if ((transmittance_weight[0] < 0.0f || !std::isfinite(transmittance_weight[0]) || std::isnan(transmittance_weight[0])) || - (transmittance_weight[1] < 0.f || !std::isfinite(transmittance_weight[1]) || + (transmittance_weight[1] < 0.0f || !std::isfinite(transmittance_weight[1]) || std::isnan(transmittance_weight[1])) || - (transmittance_weight[2] < 0.f || !std::isfinite(transmittance_weight[2]) || + (transmittance_weight[2] < 0.0f || !std::isfinite(transmittance_weight[2]) || std::isnan(transmittance_weight[2]))) { } @@ -438,7 +494,7 @@ ccl_device_forceinline void guiding_write_debug_passes(KernelGlobals kg, sum_sample_weight += sc->sample_weight; } - avg_roughness = avg_roughness > 0.f ? avg_roughness / sum_sample_weight : 0.f; + avg_roughness = avg_roughness > 0.0f ? avg_roughness / sum_sample_weight : 0.0f; film_write_pass_float(buffer + kernel_data.film.pass_guiding_avg_roughness, avg_roughness); } @@ -498,6 +554,17 @@ ccl_device_forceinline float guiding_bsdf_pdf(KernelGlobals kg, #endif } +ccl_device_forceinline float guiding_surface_incoming_radiance_pdf(KernelGlobals kg, + IntegratorState state, + const float3 wo) +{ +#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4 && OPENPGL_VERSION_MINOR >= 5 + return kg->opgl_surface_sampling_distribution->IncomingRadiancePDF(guiding_vec3f(wo)); +#else + return 0.0f; +#endif +} + /* Guided Volume Phases */ ccl_device_forceinline bool guiding_phase_init(KernelGlobals kg, diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index 9d72f660eab..2b5c9f00bbc 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -413,6 +413,7 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce( float2 bsdf_sampled_roughness = make_float2(1.0f, 1.0f); float bsdf_eta = 1.0f; + float mis_pdf = 1.0f; #if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4 if (kernel_data.integrator.use_surface_guiding) { @@ -424,9 +425,11 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce( &bsdf_eval, &bsdf_wo, &bsdf_pdf, + &mis_pdf, &unguided_bsdf_pdf, &bsdf_sampled_roughness, - &bsdf_eta); + &bsdf_eta, + rng_state); if (bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) { return LABEL_NONE; @@ -451,7 +454,7 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce( if (bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) { return LABEL_NONE; } - + mis_pdf = bsdf_pdf; unguided_bsdf_pdf = bsdf_pdf; } @@ -486,7 +489,7 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce( /* Update path state */ if (!(label & LABEL_TRANSPARENT)) { - INTEGRATOR_STATE_WRITE(state, path, mis_ray_pdf) = bsdf_pdf; + INTEGRATOR_STATE_WRITE(state, path, mis_ray_pdf) = mis_pdf; INTEGRATOR_STATE_WRITE(state, path, mis_origin_n) = sd->N; INTEGRATOR_STATE_WRITE(state, path, min_ray_pdf) = fminf( unguided_bsdf_pdf, INTEGRATOR_STATE(state, path, min_ray_pdf)); diff --git a/intern/cycles/kernel/integrator/surface_shader.h b/intern/cycles/kernel/integrator/surface_shader.h index a0fa9255628..f8fc72875b1 100644 --- a/intern/cycles/kernel/integrator/surface_shader.h +++ b/intern/cycles/kernel/integrator/surface_shader.h @@ -24,6 +24,28 @@ CCL_NAMESPACE_BEGIN /* Guiding */ #ifdef __PATH_GUIDING__ + +ccl_device float surface_shader_average_sample_weight_squared_roughness( + ccl_private const ShaderData *sd) +{ + float avg_squared_roughness = 0.0f; + float sum_sample_weight = 0.0f; + for (int i = 0; i < sd->num_closure; i++) { + ccl_private const ShaderClosure *sc = &sd->closure[i]; + + if (!CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) { + continue; + } + avg_squared_roughness += sc->sample_weight * bsdf_get_specular_roughness_squared(sc); + sum_sample_weight += sc->sample_weight; + } + + avg_squared_roughness = avg_squared_roughness > 0.0f ? + avg_squared_roughness / sum_sample_weight : + 0.0f; + return avg_squared_roughness; +} + ccl_device_inline void surface_shader_prepare_guiding(KernelGlobals kg, IntegratorState state, ccl_private ShaderData *sd, @@ -36,6 +58,9 @@ ccl_device_inline void surface_shader_prepare_guiding(KernelGlobals kg, } const float surface_guiding_probability = kernel_data.integrator.surface_guiding_probability; + const int guiding_directional_sampling_type = + kernel_data.integrator.guiding_directional_sampling_type; + const float guiding_roughness_threshold = kernel_data.integrator.guiding_roughness_threshold; float rand_bsdf_guiding = path_state_rng_1D(kg, rng_state, PRNG_SURFACE_BSDF_GUIDING); /* Compute proportion of diffuse BSDF and BSSRDFs. */ @@ -43,6 +68,8 @@ ccl_device_inline void surface_shader_prepare_guiding(KernelGlobals kg, float bssrdf_sampling_fraction = 0.0f; float bsdf_bssrdf_sampling_sum = 0.0f; + bool fully_opaque = true; + for (int i = 0; i < sd->num_closure; i++) { ShaderClosure *sc = &sd->closure[i]; if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) { @@ -56,6 +83,10 @@ ccl_device_inline void surface_shader_prepare_guiding(KernelGlobals kg, if (CLOSURE_IS_BSSRDF(sc->type)) { bssrdf_sampling_fraction += sweight; } + + if (CLOSURE_IS_BSDF_TRANSPARENT(sc->type) || CLOSURE_IS_BSDF_TRANSMISSION(sc->type)) { + fully_opaque = false; + } } } @@ -64,17 +95,36 @@ ccl_device_inline void surface_shader_prepare_guiding(KernelGlobals kg, bssrdf_sampling_fraction /= bsdf_bssrdf_sampling_sum; } - /* Init guiding (diffuse BSDFs only for now). */ - if (!(diffuse_sampling_fraction > 0.0f && - guiding_bsdf_init(kg, state, sd->P, sd->N, rand_bsdf_guiding))) + /* Init guiding */ + /* The the roughness because the function returns alpha.x * alpha.y. In addition alpha is squared + * again */ + float avg_roughness = surface_shader_average_sample_weight_squared_roughness(sd); + avg_roughness = safe_sqrtf(avg_roughness); + if (!fully_opaque || avg_roughness < guiding_roughness_threshold || + ((guiding_directional_sampling_type == GUIDING_DIRECTIONAL_SAMPLING_TYPE_PRODUCT_MIS) && + (diffuse_sampling_fraction <= 0.0f)) || + !guiding_bsdf_init(kg, state, sd->P, sd->N, rand_bsdf_guiding)) { state->guiding.use_surface_guiding = false; + state->guiding.surface_guiding_sampling_prob = 0.0f; return; } state->guiding.use_surface_guiding = true; - state->guiding.surface_guiding_sampling_prob = surface_guiding_probability * - diffuse_sampling_fraction; + if (kernel_data.integrator.guiding_directional_sampling_type == + GUIDING_DIRECTIONAL_SAMPLING_TYPE_PRODUCT_MIS) + { + state->guiding.surface_guiding_sampling_prob = surface_guiding_probability * + diffuse_sampling_fraction; + } + else if (kernel_data.integrator.guiding_directional_sampling_type == + GUIDING_DIRECTIONAL_SAMPLING_TYPE_RIS) + { + state->guiding.surface_guiding_sampling_prob = surface_guiding_probability; + } + else { // GUIDING_DIRECTIONAL_SAMPLING_TYPE_ROUGHNESS + state->guiding.surface_guiding_sampling_prob = surface_guiding_probability * avg_roughness; + } state->guiding.bssrdf_sampling_prob = bssrdf_sampling_fraction; state->guiding.sample_surface_guiding_rand = rand_bsdf_guiding; @@ -325,12 +375,20 @@ ccl_device_inline kg, sd, wo, NULL, bsdf_eval, 0.0f, 0.0f, light_shader_flags); #if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4 - if (state->guiding.use_surface_guiding) { + if (pdf > 0.0f && state->guiding.use_surface_guiding) { const float guiding_sampling_prob = state->guiding.surface_guiding_sampling_prob; const float bssrdf_sampling_prob = state->guiding.bssrdf_sampling_prob; const float guide_pdf = guiding_bsdf_pdf(kg, state, wo); - pdf = (guiding_sampling_prob * guide_pdf * (1.0f - bssrdf_sampling_prob)) + - (1.0f - guiding_sampling_prob) * pdf; + + if (kernel_data.integrator.guiding_directional_sampling_type == + GUIDING_DIRECTIONAL_SAMPLING_TYPE_RIS) + { + pdf = (0.5f * guide_pdf * (1.0f - bssrdf_sampling_prob)) + 0.5f * pdf; + } + else { + pdf = (guiding_sampling_prob * guide_pdf * (1.0f - bssrdf_sampling_prob)) + + (1.0f - guiding_sampling_prob) * pdf; + } } #endif @@ -406,17 +464,17 @@ surface_shader_bssrdf_sample_weight(ccl_private const ShaderData *ccl_restrict s /* Sample direction for picked BSDF, and return evaluation and pdf for all * BSDFs combined using MIS. */ -ccl_device int surface_shader_bsdf_guided_sample_closure(KernelGlobals kg, - IntegratorState state, - ccl_private ShaderData *sd, - ccl_private const ShaderClosure *sc, - const float3 rand_bsdf, - ccl_private BsdfEval *bsdf_eval, - ccl_private float3 *wo, - ccl_private float *bsdf_pdf, - ccl_private float *unguided_bsdf_pdf, - ccl_private float2 *sampled_rougness, - ccl_private float *eta) +ccl_device int surface_shader_bsdf_guided_sample_closure_mis(KernelGlobals kg, + IntegratorState state, + ccl_private ShaderData *sd, + ccl_private const ShaderClosure *sc, + const float3 rand_bsdf, + ccl_private BsdfEval *bsdf_eval, + ccl_private float3 *wo, + ccl_private float *bsdf_pdf, + ccl_private float *unguided_bsdf_pdf, + ccl_private float2 *sampled_rougness, + ccl_private float *eta) { /* BSSRDF should already have been handled elsewhere. */ kernel_assert(CLOSURE_IS_BSDF(sc->type)); @@ -478,6 +536,10 @@ ccl_device int surface_shader_bsdf_guided_sample_closure(KernelGlobals kg, label = bsdf_label(kg, &sd->closure[idx], *wo); } + else { + *bsdf_pdf = 0.0f; + *unguided_bsdf_pdf = 0.0f; + } } kernel_assert(reduce_min(bsdf_eval_sum(bsdf_eval)) >= 0.0f); @@ -499,6 +561,9 @@ ccl_device int surface_shader_bsdf_guided_sample_closure(KernelGlobals kg, sampled_rougness, eta); # if 0 +// Code path to validate the estimation of the label, sampled roughness and eta +// This should be activated from time to time when the BSDFs change to check if everything +// is still working correctly. if (*unguided_bsdf_pdf > 0.0f) { surface_shader_validate_bsdf_sample(kg, sc, *wo, label, sampled_roughness, eta); } @@ -529,6 +594,309 @@ ccl_device int surface_shader_bsdf_guided_sample_closure(KernelGlobals kg, return label; } + +ccl_device int surface_shader_bsdf_guided_sample_closure_ris(KernelGlobals kg, + IntegratorState state, + ccl_private ShaderData *sd, + ccl_private const ShaderClosure *sc, + const float3 rand_bsdf, + ccl_private const RNGState *rng_state, + ccl_private BsdfEval *bsdf_eval, + ccl_private float3 *wo, + ccl_private float *bsdf_pdf, + ccl_private float *mis_pdf, + ccl_private float *unguided_bsdf_pdf, + ccl_private float2 *sampled_roughness, + ccl_private float *eta) +{ + /* BSSRDF should already have been handled elsewhere. */ + kernel_assert(CLOSURE_IS_BSDF(sc->type)); + + const bool use_surface_guiding = state->guiding.use_surface_guiding; + const float guiding_sampling_prob = state->guiding.surface_guiding_sampling_prob; + const float bssrdf_sampling_prob = state->guiding.bssrdf_sampling_prob; + + /* Decide between sampling guiding distribution and BSDF. */ + float rand_bsdf_guiding = state->guiding.sample_surface_guiding_rand; + + /* Initialize to zero. */ + int label = LABEL_NONE; + Spectrum eval = zero_spectrum(); + bsdf_eval_init(bsdf_eval, CLOSURE_NONE_ID, eval); + + *unguided_bsdf_pdf = 0.0f; + float guide_pdf = 0.0f; + + if (use_surface_guiding && guiding_sampling_prob > 0.0f) { + /* Performing guided sampling using RIS */ + + // selected RIS candidate + int ris_idx = 0; + + // meta data for the two RIS candidates + GuidingRISSample ris_samples[2]; + ris_samples[0].rand = rand_bsdf; + ris_samples[1].rand = path_state_rng_3D(kg, rng_state, PRNG_SURFACE_RIS_GUIDING_0); + + // ---------------------------------------------------- + // generate the first RIS candidate using a BSDF sample + // ---------------------------------------------------- + ris_samples[0].label = bsdf_sample(kg, + sd, + sc, + INTEGRATOR_STATE(state, path, flag), + ris_samples[0].rand, + &ris_samples[0].eval, + &ris_samples[0].wo, + &ris_samples[0].bsdf_pdf, + &ris_samples[0].sampled_roughness, + &ris_samples[0].eta); + + bsdf_eval_init(&ris_samples[0].bsdf_eval, sc->type, ris_samples[0].eval * sc->weight); + if (ris_samples[0].bsdf_pdf > 0.0f) { + if (sd->num_closure > 1) { + float sweight = sc->sample_weight; + ris_samples[0].bsdf_pdf = _surface_shader_bsdf_eval_mis(kg, + sd, + ris_samples[0].wo, + sc, + &ris_samples[0].bsdf_eval, + (ris_samples[0].bsdf_pdf) * + sweight, + sweight, + 0); + kernel_assert(reduce_min(bsdf_eval_sum(&ris_samples[0].bsdf_eval)) >= 0.0f); + } + ris_samples[0].avg_bsdf_eval = average(ris_samples[0].bsdf_eval.sum); + ris_samples[0].guide_pdf = guiding_bsdf_pdf(kg, state, ris_samples[0].wo); + ris_samples[0].guide_pdf *= (1.0f - bssrdf_sampling_prob); +# ifdef RIS_INCOMING_RADIANCE + ris_samples[0].incoming_radiance_pdf = guiding_surface_incoming_radiance_pdf( + kg, state, ris_samples[0].wo); +# else + ris_samples[0].cosine = max(0.01f, fabsf(dot(sd->N, ris_samples[0].wo))); +# endif + ris_samples[0].bsdf_pdf = max(0.0f, ris_samples[0].bsdf_pdf); + } + + // ------------------------------------------------------------------------------ + // generate the second RIS candidate using a sample from the guiding distribution + // ------------------------------------------------------------------------------ + float unguided_bsdf_pdfs[MAX_CLOSURE]; + bsdf_eval_init(&ris_samples[1].bsdf_eval, CLOSURE_NONE_ID, eval); + ris_samples[1].guide_pdf = guiding_bsdf_sample( + kg, state, float3_to_float2(ris_samples[1].rand), &ris_samples[1].wo); + ris_samples[1].guide_pdf *= (1.0f - bssrdf_sampling_prob); +# ifdef RIS_INCOMING_RADIANCE + ris_samples[1].incoming_radiance_pdf = guiding_surface_incoming_radiance_pdf( + kg, state, ris_samples[1].wo); +# else + ris_samples[1].cosine = max(0.01f, fabsf(dot(sd->N, ris_samples[1].wo))); +# endif + ris_samples[1].bsdf_pdf = surface_shader_bsdf_eval_pdfs( + kg, sd, ris_samples[1].wo, &ris_samples[1].bsdf_eval, unguided_bsdf_pdfs, 0); + ris_samples[1].label = ris_samples[0].label; + ris_samples[1].avg_bsdf_eval = average(ris_samples[1].bsdf_eval.sum); + ris_samples[1].bsdf_pdf = max(0.0f, ris_samples[1].bsdf_pdf); + + // ------------------------------------------------------------------------------ + // calculate the RIS target functions for each RIS candidate + // ------------------------------------------------------------------------------ + int num_ris_candidates = 0; + float sum_ris_weights = 0.0f; + if (calculate_ris_target(&ris_samples[0], guiding_sampling_prob)) { + sum_ris_weights += ris_samples[0].ris_weight; + num_ris_candidates++; + } + kernel_assert(ris_samples[0].ris_weight >= 0.0f); + kernel_assert(sum_ris_weights >= 0.0f); + + if (calculate_ris_target(&ris_samples[1], guiding_sampling_prob)) { + sum_ris_weights += ris_samples[1].ris_weight; + num_ris_candidates++; + } + kernel_assert(ris_samples[1].ris_weight >= 0.0f); + kernel_assert(sum_ris_weights >= 0.0f); + + // ------------------------------------------------------------------------------ + // Sample/Select a sample from the RIS candidates proportional to the target + // ------------------------------------------------------------------------------ + if (num_ris_candidates == 0 || !(sum_ris_weights > 1e-10f)) { + *bsdf_pdf = 0.0f; + *mis_pdf = 0.0f; + return label; + } + + float rand_ris_select = rand_bsdf_guiding * sum_ris_weights; + + float sum_ris = 0.0f; + for (int i = 0; i < 2; i++) { + sum_ris += ris_samples[i].ris_weight; + if (rand_ris_select <= sum_ris) { + ris_idx = i; + break; + } + } + + kernel_assert(sum_ris >= 0.0f); + kernel_assert(ris_idx < 2); + + // ------------------------------------------------------------------------------ + // Fill in the sample data for the selected RIS candidate + // ------------------------------------------------------------------------------ + guide_pdf = ris_samples[ris_idx].ris_target * (2.0f / sum_ris_weights); + *unguided_bsdf_pdf = ris_samples[ris_idx].bsdf_pdf; + *mis_pdf = 0.5f * (ris_samples[ris_idx].bsdf_pdf + ris_samples[ris_idx].guide_pdf); + *bsdf_pdf = guide_pdf; + + *wo = ris_samples[ris_idx].wo; + label = ris_samples[ris_idx].label; + + *sampled_roughness = ris_samples[ris_idx].sampled_roughness; + *eta = ris_samples[ris_idx].eta; + *bsdf_eval = ris_samples[ris_idx].bsdf_eval; + + kernel_assert(isfinite_safe(guide_pdf)); + kernel_assert(isfinite_safe(*bsdf_pdf)); + + if (!(*bsdf_pdf > 1e-10f)) { + *bsdf_pdf = 0.0f; + *mis_pdf = 0.0f; + return label; + } + + kernel_assert(*bsdf_pdf > 0.0f); + kernel_assert(*bsdf_pdf >= 1e-20f); + kernel_assert(guide_pdf >= 0.0f); + + /// select label sampled_roughness and eta + if (ris_idx == 1 && ris_samples[1].bsdf_pdf > 0.0f) { + + float rnd = path_state_rng_1D(kg, rng_state, PRNG_SURFACE_RIS_GUIDING_1); + + float sum_pdfs = 0.0f; + int idx = -1; + for (int i = 0; i < sd->num_closure; i++) { + sum_pdfs += unguided_bsdf_pdfs[i]; + if (rnd <= sum_pdfs) { + idx = i; + break; + } + } + // kernel_assert(idx >= 0); + /* Set the default idx to the last in the list. + * in case of numerical problems and rand_bsdf_guiding is just >=1.0f and + * the sum of all unguided_bsdf_pdfs is just < 1.0f. */ + idx = (rnd > sum_pdfs) ? sd->num_closure - 1 : idx; + + label = bsdf_label(kg, &sd->closure[idx], *wo); + bsdf_roughness_eta(kg, &sd->closure[idx], sampled_roughness, eta); + } + + kernel_assert(isfinite_safe(*bsdf_pdf)); + kernel_assert(*bsdf_pdf >= 0.0f); + kernel_assert(reduce_min(bsdf_eval_sum(bsdf_eval)) >= 0.0f); + } + else { + /* Sample BSDF. */ + *bsdf_pdf = 0.0f; + label = bsdf_sample(kg, + sd, + sc, + INTEGRATOR_STATE(state, path, flag), + rand_bsdf, + &eval, + wo, + unguided_bsdf_pdf, + sampled_roughness, + eta); +# if 0 + // Code path to validate the estimation of the label, sampled roughness and eta + // This should be activated from time to time when the BSDFs change to check if everything + // is still working correctly. + if (*unguided_bsdf_pdf > 0.0f) { + surface_shader_validate_bsdf_sample(kg, sc, *wo, label, sampled_roughness, eta); + } +# endif + + if (*unguided_bsdf_pdf != 0.0f) { + bsdf_eval_init(bsdf_eval, sc->type, eval * sc->weight); + + kernel_assert(reduce_min(bsdf_eval_sum(bsdf_eval)) >= 0.0f); + + if (sd->num_closure > 1) { + float sweight = sc->sample_weight; + *unguided_bsdf_pdf = _surface_shader_bsdf_eval_mis( + kg, sd, *wo, sc, bsdf_eval, (*unguided_bsdf_pdf) * sweight, sweight, 0); + kernel_assert(reduce_min(bsdf_eval_sum(bsdf_eval)) >= 0.0f); + } + *bsdf_pdf = *unguided_bsdf_pdf; + *mis_pdf = *bsdf_pdf; + } + + kernel_assert(reduce_min(bsdf_eval_sum(bsdf_eval)) >= 0.0f); + } + + return label; +} + +ccl_device int surface_shader_bsdf_guided_sample_closure(KernelGlobals kg, + IntegratorState state, + ccl_private ShaderData *sd, + ccl_private const ShaderClosure *sc, + const float3 rand_bsdf, + ccl_private BsdfEval *bsdf_eval, + ccl_private float3 *wo, + ccl_private float *bsdf_pdf, + ccl_private float *mis_pdf, + ccl_private float *unguided_bsdf_pdf, + ccl_private float2 *sampled_roughness, + ccl_private float *eta, + ccl_private const RNGState *rng_state) +{ + int label = LABEL_NONE; + if (kernel_data.integrator.guiding_directional_sampling_type == + GUIDING_DIRECTIONAL_SAMPLING_TYPE_PRODUCT_MIS || + kernel_data.integrator.guiding_directional_sampling_type == + GUIDING_DIRECTIONAL_SAMPLING_TYPE_ROUGHNESS) + { + label = surface_shader_bsdf_guided_sample_closure_mis(kg, + state, + sd, + sc, + rand_bsdf, + bsdf_eval, + wo, + bsdf_pdf, + unguided_bsdf_pdf, + sampled_roughness, + eta); + *mis_pdf = (*unguided_bsdf_pdf > 0.0f) ? *bsdf_pdf : 0.0f; + } + else if (kernel_data.integrator.guiding_directional_sampling_type == + GUIDING_DIRECTIONAL_SAMPLING_TYPE_RIS) + { + label = surface_shader_bsdf_guided_sample_closure_ris(kg, + state, + sd, + sc, + rand_bsdf, + rng_state, + bsdf_eval, + wo, + bsdf_pdf, + mis_pdf, + unguided_bsdf_pdf, + sampled_roughness, + eta); + } + if (!(*unguided_bsdf_pdf > 0.0f)) { + *bsdf_pdf = 0.0f; + *mis_pdf = 0.0f; + } + return label; +} + #endif /* Sample direction for picked BSDF, and return evaluation and pdf for all diff --git a/intern/cycles/kernel/osl/shaders/CMakeLists.txt b/intern/cycles/kernel/osl/shaders/CMakeLists.txt index 00336ebfb76..8daad0a111e 100644 --- a/intern/cycles/kernel/osl/shaders/CMakeLists.txt +++ b/intern/cycles/kernel/osl/shaders/CMakeLists.txt @@ -6,7 +6,6 @@ set(SRC_OSL node_add_closure.osl node_ambient_occlusion.osl - node_anisotropic_bsdf.osl node_attribute.osl node_background.osl node_bevel.osl diff --git a/intern/cycles/kernel/osl/shaders/node_anisotropic_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_anisotropic_bsdf.osl deleted file mode 100644 index 13e936f9784..00000000000 --- a/intern/cycles/kernel/osl/shaders/node_anisotropic_bsdf.osl +++ /dev/null @@ -1,45 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 - * Copyright 2011-2022 Blender Foundation */ - -#include "stdcycles.h" - -shader node_anisotropic_bsdf(color Color = 0.0, - string distribution = "GGX", - float Roughness = 0.0, - float Anisotropy = 0.0, - float Rotation = 0.0, - normal Normal = N, - normal Tangent = normalize(dPdu), - output closure color BSDF = 0) -{ - /* rotate tangent around normal */ - vector T = Tangent; - - if (Rotation != 0.0) - T = rotate(T, Rotation * M_2PI, point(0.0, 0.0, 0.0), Normal); - - /* compute roughness */ - float roughness = Roughness * Roughness; - float roughness_u, roughness_v; - float aniso = clamp(Anisotropy, -0.99, 0.99); - - if (aniso < 0.0) { - roughness_u = roughness / (1.0 + aniso); - roughness_v = roughness * (1.0 + aniso); - } - else { - roughness_u = roughness * (1.0 - aniso); - roughness_v = roughness / (1.0 - aniso); - } - - if (distribution == "sharp") - BSDF = Color * reflection(Normal); - else if (distribution == "beckmann") - BSDF = Color * microfacet_beckmann_aniso(Normal, T, roughness_u, roughness_v); - else if (distribution == "GGX") - BSDF = Color * microfacet_ggx_aniso(Normal, T, roughness_u, roughness_v); - else if (distribution == "Multiscatter GGX") - BSDF = Color * microfacet_multi_ggx_aniso(Normal, T, roughness_u, roughness_v, Color); - else - BSDF = Color * ashikhmin_shirley(Normal, T, roughness_u, roughness_v); -} diff --git a/intern/cycles/kernel/osl/shaders/node_glossy_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_glossy_bsdf.osl index 7850f0087bd..6bf5962e69d 100644 --- a/intern/cycles/kernel/osl/shaders/node_glossy_bsdf.osl +++ b/intern/cycles/kernel/osl/shaders/node_glossy_bsdf.osl @@ -7,13 +7,40 @@ shader node_glossy_bsdf(color Color = 0.8, string distribution = "ggx", float Roughness = 0.2, + float Anisotropy = 0.0, + float Rotation = 0.0, normal Normal = N, + normal Tangent = 0.0, output closure color BSDF = 0) { + /* compute roughness */ float roughness = Roughness * Roughness; + float roughness_u, roughness_v; + float aniso = clamp(Anisotropy, -0.99, 0.99); + + /* rotate tangent around normal */ + vector T = Tangent; + + if (abs(aniso) <= 1e-4) { + roughness_u = roughness; + roughness_v = roughness; + } + else { + if (Rotation != 0.0) + T = rotate(T, Rotation * M_2PI, point(0.0, 0.0, 0.0), Normal); + + if (aniso < 0.0) { + roughness_u = roughness / (1.0 + aniso); + roughness_v = roughness * (1.0 + aniso); + } + else { + roughness_u = roughness * (1.0 - aniso); + roughness_v = roughness / (1.0 - aniso); + } + } if (distribution == "Multiscatter GGX") BSDF = Color * microfacet_multi_ggx(Normal, roughness, Color); else - BSDF = Color * microfacet(distribution, Normal, roughness, 0.0, 0); + BSDF = Color * microfacet(distribution, Normal, T, roughness_u, roughness_v, 0.0, 0); } diff --git a/intern/cycles/kernel/svm/closure.h b/intern/cycles/kernel/svm/closure.h index 2706d9e95f1..10e88f126a1 100644 --- a/intern/cycles/kernel/svm/closure.h +++ b/intern/cycles/kernel/svm/closure.h @@ -494,7 +494,10 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, bsdf->ior = 1.0f; bsdf->fresnel = NULL; - if (data_node.y == SVM_STACK_INVALID) { + /* compute roughness */ + float anisotropy = clamp(param2, -0.99f, 0.99f); + if (data_node.y == SVM_STACK_INVALID || fabsf(anisotropy) <= 1e-4f) { + /* Isotropic case. */ bsdf->T = zero_float3(); bsdf->alpha_x = roughness; bsdf->alpha_y = roughness; @@ -507,8 +510,6 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, if (rotation != 0.0f) bsdf->T = rotate_around_axis(bsdf->T, bsdf->N, rotation * M_2PI_F); - /* compute roughness */ - float anisotropy = clamp(param2, -0.99f, 0.99f); if (anisotropy < 0.0f) { bsdf->alpha_x = roughness / (1.0f + anisotropy); bsdf->alpha_y = roughness * (1.0f + anisotropy); diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h index 1f4892dabb6..14951e933fb 100644 --- a/intern/cycles/kernel/types.h +++ b/intern/cycles/kernel/types.h @@ -168,6 +168,11 @@ enum PathTraceDimension { PRNG_SURFACE_AO = 4, PRNG_SURFACE_BEVEL = 5, PRNG_SURFACE_BSDF_GUIDING = 6, + + /* Guiding RIS */ + PRNG_SURFACE_RIS_GUIDING_0 = 10, + PRNG_SURFACE_RIS_GUIDING_1 = 11, + /* Volume */ PRNG_VOLUME_PHASE = 3, PRNG_VOLUME_PHASE_CHANNEL = 4, @@ -513,6 +518,16 @@ typedef enum GuidingDistributionType { GUIDING_NUM_TYPES, } GuidingDistributionType; +/* Guiding Directional Sampling Type */ + +typedef enum GuidingDirectionalSamplingType { + GUIDING_DIRECTIONAL_SAMPLING_TYPE_PRODUCT_MIS = 0, + GUIDING_DIRECTIONAL_SAMPLING_TYPE_RIS = 1, + GUIDING_DIRECTIONAL_SAMPLING_TYPE_ROUGHNESS = 2, + + GUIDING_DIRECTIONAL_SAMPLING_NUM_TYPES, +} GuidingDirectionalSamplingType; + /* Camera Type */ enum CameraType { CAMERA_PERSPECTIVE, CAMERA_ORTHOGRAPHIC, CAMERA_PANORAMA }; @@ -1180,11 +1195,16 @@ typedef enum KernelBVHLayout { BVH_LAYOUT_HIPRT = (1 << 8), BVH_LAYOUT_MULTI_HIPRT = (1 << 9), BVH_LAYOUT_MULTI_HIPRT_EMBREE = (1 << 10), + BVH_LAYOUT_EMBREEGPU = (1 << 11), + BVH_LAYOUT_MULTI_EMBREEGPU = (1 << 12), + BVH_LAYOUT_MULTI_EMBREEGPU_EMBREE = (1 << 13), /* Default BVH layout to use for CPU. */ BVH_LAYOUT_AUTO = BVH_LAYOUT_EMBREE, BVH_LAYOUT_ALL = BVH_LAYOUT_BVH2 | BVH_LAYOUT_EMBREE | BVH_LAYOUT_OPTIX | BVH_LAYOUT_METAL | - BVH_LAYOUT_HIPRT | BVH_LAYOUT_MULTI_HIPRT | BVH_LAYOUT_MULTI_HIPRT_EMBREE, + BVH_LAYOUT_HIPRT | BVH_LAYOUT_MULTI_HIPRT | BVH_LAYOUT_MULTI_HIPRT_EMBREE | + BVH_LAYOUT_EMBREEGPU | BVH_LAYOUT_MULTI_EMBREEGPU | + BVH_LAYOUT_MULTI_EMBREEGPU_EMBREE, } KernelBVHLayout; /* Specialized struct that can become constants in dynamic compilation. */ diff --git a/intern/cycles/scene/geometry.cpp b/intern/cycles/scene/geometry.cpp index b26473697c4..c964cee2f19 100644 --- a/intern/cycles/scene/geometry.cpp +++ b/intern/cycles/scene/geometry.cpp @@ -116,7 +116,8 @@ bool Geometry::need_build_bvh(BVHLayout layout) const layout == BVH_LAYOUT_METAL || layout == BVH_LAYOUT_MULTI_OPTIX_EMBREE || layout == BVH_LAYOUT_MULTI_METAL || layout == BVH_LAYOUT_MULTI_METAL_EMBREE || layout == BVH_LAYOUT_HIPRT || layout == BVH_LAYOUT_MULTI_HIPRT || - layout == BVH_LAYOUT_MULTI_HIPRT_EMBREE; + layout == BVH_LAYOUT_MULTI_HIPRT_EMBREE || layout == BVH_LAYOUT_EMBREEGPU || + layout == BVH_LAYOUT_MULTI_EMBREEGPU || layout == BVH_LAYOUT_MULTI_EMBREEGPU_EMBREE; } bool Geometry::is_instanced() const diff --git a/intern/cycles/scene/integrator.cpp b/intern/cycles/scene/integrator.cpp index 502a6884272..e94ef61ea20 100644 --- a/intern/cycles/scene/integrator.cpp +++ b/intern/cycles/scene/integrator.cpp @@ -60,10 +60,17 @@ NODE_DEFINE(Integrator) SOCKET_INT(volume_max_steps, "Volume Max Steps", 1024); SOCKET_FLOAT(volume_step_rate, "Volume Step Rate", 1.0f); - static NodeEnum guiding_ditribution_enum; - guiding_ditribution_enum.insert("PARALLAX_AWARE_VMM", GUIDING_TYPE_PARALLAX_AWARE_VMM); - guiding_ditribution_enum.insert("DIRECTIONAL_QUAD_TREE", GUIDING_TYPE_DIRECTIONAL_QUAD_TREE); - guiding_ditribution_enum.insert("VMM", GUIDING_TYPE_VMM); + static NodeEnum guiding_distribution_enum; + guiding_distribution_enum.insert("PARALLAX_AWARE_VMM", GUIDING_TYPE_PARALLAX_AWARE_VMM); + guiding_distribution_enum.insert("DIRECTIONAL_QUAD_TREE", GUIDING_TYPE_DIRECTIONAL_QUAD_TREE); + guiding_distribution_enum.insert("VMM", GUIDING_TYPE_VMM); + + static NodeEnum guiding_directional_sampling_type_enum; + guiding_directional_sampling_type_enum.insert("MIS", + GUIDING_DIRECTIONAL_SAMPLING_TYPE_PRODUCT_MIS); + guiding_directional_sampling_type_enum.insert("RIS", GUIDING_DIRECTIONAL_SAMPLING_TYPE_RIS); + guiding_directional_sampling_type_enum.insert("ROUGHNESS", + GUIDING_DIRECTIONAL_SAMPLING_TYPE_ROUGHNESS); SOCKET_BOOLEAN(use_guiding, "Guiding", false); SOCKET_BOOLEAN(deterministic_guiding, "Deterministic Guiding", true); @@ -76,8 +83,13 @@ NODE_DEFINE(Integrator) SOCKET_BOOLEAN(use_guiding_mis_weights, "Use MIS Weights", true); SOCKET_ENUM(guiding_distribution_type, "Guiding Distribution Type", - guiding_ditribution_enum, + guiding_distribution_enum, GUIDING_TYPE_PARALLAX_AWARE_VMM); + SOCKET_ENUM(guiding_directional_sampling_type, + "Guiding Directional Sampling Type", + guiding_directional_sampling_type_enum, + GUIDING_DIRECTIONAL_SAMPLING_TYPE_RIS); + SOCKET_FLOAT(guiding_roughness_threshold, "Guiding Roughness Threshold", 0.05f); SOCKET_BOOLEAN(caustics_reflective, "Reflective Caustics", true); SOCKET_BOOLEAN(caustics_refractive, "Refractive Caustics", true); @@ -239,6 +251,8 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene kintegrator->use_guiding_direct_light = use_guiding_direct_light; kintegrator->use_guiding_mis_weights = use_guiding_mis_weights; kintegrator->guiding_distribution_type = guiding_params.type; + kintegrator->guiding_directional_sampling_type = guiding_params.sampling_type; + kintegrator->guiding_roughness_threshold = guiding_params.roughness_threshold; kintegrator->seed = seed; @@ -409,7 +423,9 @@ GuidingParams Integrator::get_guiding_params(const Device *device) const guiding_params.type = guiding_distribution_type; guiding_params.training_samples = guiding_training_samples; guiding_params.deterministic = deterministic_guiding; - + guiding_params.sampling_type = guiding_directional_sampling_type; + // In Blender/Cycles the user set roughness is squared to behave more linear. + guiding_params.roughness_threshold = guiding_roughness_threshold * guiding_roughness_threshold; return guiding_params; } CCL_NAMESPACE_END diff --git a/intern/cycles/scene/integrator.h b/intern/cycles/scene/integrator.h index 92ac3a254b7..35306272a8d 100644 --- a/intern/cycles/scene/integrator.h +++ b/intern/cycles/scene/integrator.h @@ -54,6 +54,8 @@ class Integrator : public Node { NODE_SOCKET_API(bool, use_guiding_direct_light); NODE_SOCKET_API(bool, use_guiding_mis_weights); NODE_SOCKET_API(GuidingDistributionType, guiding_distribution_type); + NODE_SOCKET_API(GuidingDirectionalSamplingType, guiding_directional_sampling_type); + NODE_SOCKET_API(float, guiding_roughness_threshold); NODE_SOCKET_API(bool, caustics_reflective) NODE_SOCKET_API(bool, caustics_refractive) diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp index 803dd4efac8..4019a169b76 100644 --- a/intern/cycles/scene/shader_nodes.cpp +++ b/intern/cycles/scene/shader_nodes.cpp @@ -2335,68 +2335,6 @@ void BsdfNode::compile(OSLCompiler & /*compiler*/) assert(0); } -/* Anisotropic BSDF Closure */ - -NODE_DEFINE(AnisotropicBsdfNode) -{ - NodeType *type = NodeType::add("anisotropic_bsdf", create, NodeType::SHADER); - - SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f)); - SOCKET_IN_NORMAL(normal, "Normal", zero_float3(), SocketType::LINK_NORMAL); - SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL); - - static NodeEnum distribution_enum; - distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ID); - distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_ID); - distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID); - distribution_enum.insert("ashikhmin_shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID); - SOCKET_ENUM(distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_ID); - - SOCKET_IN_VECTOR(tangent, "Tangent", zero_float3(), SocketType::LINK_TANGENT); - - SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f); - SOCKET_IN_FLOAT(anisotropy, "Anisotropy", 0.5f); - SOCKET_IN_FLOAT(rotation, "Rotation", 0.0f); - - SOCKET_OUT_CLOSURE(BSDF, "BSDF"); - - return type; -} - -AnisotropicBsdfNode::AnisotropicBsdfNode() : BsdfNode(get_node_type()) -{ - closure = CLOSURE_BSDF_MICROFACET_GGX_ID; -} - -void AnisotropicBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes) -{ - if (shader->has_surface_link()) { - ShaderInput *tangent_in = input("Tangent"); - - if (!tangent_in->link) - attributes->add(ATTR_STD_GENERATED); - } - - ShaderNode::attributes(shader, attributes); -} - -void AnisotropicBsdfNode::compile(SVMCompiler &compiler) -{ - closure = distribution; - - if (closure == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID) - BsdfNode::compile( - compiler, input("Roughness"), input("Anisotropy"), input("Rotation"), input("Color")); - else - BsdfNode::compile(compiler, input("Roughness"), input("Anisotropy"), input("Rotation")); -} - -void AnisotropicBsdfNode::compile(OSLCompiler &compiler) -{ - compiler.parameter(this, "distribution"); - compiler.add(this, "node_anisotropic_bsdf"); -} - /* Glossy BSDF Closure */ NODE_DEFINE(GlossyBsdfNode) @@ -2414,7 +2352,12 @@ NODE_DEFINE(GlossyBsdfNode) distribution_enum.insert("ashikhmin_shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID); distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID); SOCKET_ENUM(distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_ID); + + SOCKET_IN_VECTOR(tangent, "Tangent", zero_float3(), SocketType::LINK_TANGENT); + SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f); + SOCKET_IN_FLOAT(anisotropy, "Anisotropy", 0.0f); + SOCKET_IN_FLOAT(rotation, "Rotation", 0.0f); SOCKET_OUT_CLOSURE(BSDF, "BSDF"); @@ -2427,8 +2370,32 @@ GlossyBsdfNode::GlossyBsdfNode() : BsdfNode(get_node_type()) distribution_orig = NBUILTIN_CLOSURES; } +bool GlossyBsdfNode::is_isotropic() +{ + ShaderInput *anisotropy_input = input("Anisotropy"); + /* Keep in sync with the thresholds in OSL's node_glossy_bsdf and SVM's svm_node_closure_bsdf. */ + return (!anisotropy_input->link && fabsf(anisotropy) <= 1e-4f); +} + +void GlossyBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes) +{ + if (shader->has_surface_link()) { + ShaderInput *tangent_in = input("Tangent"); + if (!tangent_in->link && !is_isotropic()) + attributes->add(ATTR_STD_GENERATED); + } + + ShaderNode::attributes(shader, attributes); +} + void GlossyBsdfNode::simplify_settings(Scene *scene) { + /* If the anisotropy is close enough to zero, fall back to the isotropic case. */ + ShaderInput *tangent_input = input("Tangent"); + if (tangent_input->link && is_isotropic()) { + tangent_input->disconnect(); + } + if (distribution_orig == NBUILTIN_CLOSURES) { roughness_orig = roughness; distribution_orig = distribution; @@ -2478,9 +2445,10 @@ void GlossyBsdfNode::compile(SVMCompiler &compiler) if (closure == CLOSURE_BSDF_REFLECTION_ID) BsdfNode::compile(compiler, NULL, NULL); else if (closure == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID) - BsdfNode::compile(compiler, input("Roughness"), NULL, NULL, input("Color")); + BsdfNode::compile( + compiler, input("Roughness"), input("Anisotropy"), input("Rotation"), input("Color")); else - BsdfNode::compile(compiler, input("Roughness"), NULL); + BsdfNode::compile(compiler, input("Roughness"), input("Anisotropy"), input("Rotation")); } void GlossyBsdfNode::compile(OSLCompiler &compiler) diff --git a/intern/cycles/scene/shader_nodes.h b/intern/cycles/scene/shader_nodes.h index 8a9bbe23924..7aaa690a5f7 100644 --- a/intern/cycles/scene/shader_nodes.h +++ b/intern/cycles/scene/shader_nodes.h @@ -495,27 +495,6 @@ class BsdfNode : public BsdfBaseNode { NODE_SOCKET_API(float, surface_mix_weight) }; -class AnisotropicBsdfNode : public BsdfNode { - public: - SHADER_NODE_CLASS(AnisotropicBsdfNode) - - NODE_SOCKET_API(float3, tangent) - NODE_SOCKET_API(float, roughness) - NODE_SOCKET_API(float, anisotropy) - NODE_SOCKET_API(float, rotation) - NODE_SOCKET_API(ClosureType, distribution) - - ClosureType get_closure_type() - { - return distribution; - } - void attributes(Shader *shader, AttributeRequestSet *attributes); - bool has_attribute_dependency() - { - return true; - } -}; - class DiffuseBsdfNode : public BsdfNode { public: SHADER_NODE_CLASS(DiffuseBsdfNode) @@ -624,12 +603,23 @@ class GlossyBsdfNode : public BsdfNode { return distribution; } + NODE_SOCKET_API(float3, tangent) NODE_SOCKET_API(float, roughness) + NODE_SOCKET_API(float, anisotropy) + NODE_SOCKET_API(float, rotation) NODE_SOCKET_API(ClosureType, distribution) + void attributes(Shader *shader, AttributeRequestSet *attributes); + bool has_attribute_dependency() + { + return true; + } + private: float roughness_orig; ClosureType distribution_orig; + + bool is_isotropic(); }; class GlassBsdfNode : public BsdfNode { diff --git a/intern/cycles/util/math.h b/intern/cycles/util/math.h index 018c2599047..7b9726e9133 100644 --- a/intern/cycles/util/math.h +++ b/intern/cycles/util/math.h @@ -567,29 +567,15 @@ ccl_device_inline float triangle_area(ccl_private const float3 &v1, /* Orthonormal vectors */ ccl_device_inline void make_orthonormals(const float3 N, - ccl_private float3 *a, - ccl_private float3 *b) + ccl_private float3 *T, + ccl_private float3 *B) { -#if 0 - if (fabsf(N.y) >= 0.999f) { - *a = make_float3(1, 0, 0); - *b = make_float3(0, 0, 1); - return; - } - if (fabsf(N.z) >= 0.999f) { - *a = make_float3(1, 0, 0); - *b = make_float3(0, 1, 0); - return; - } -#endif - - if (N.x != N.y || N.x != N.z) - *a = make_float3(N.z - N.y, N.x - N.z, N.y - N.x); //(1,1,1)x N - else - *a = make_float3(N.z - N.y, N.x + N.z, -N.y - N.x); //(-1,1,1)x N - - *a = normalize(*a); - *b = cross(N, *a); + /* Duff, Tom, et al. "Building an orthonormal basis, revisited." JCGT 6.1 (2017). */ + float sign = signf(N.z); + float a = -1.0f / (sign + N.z); + float b = N.x * N.y * a; + *T = make_float3(1.0f + sign * N.x * N.x * a, sign * b, -sign * N.x); + *B = make_float3(b, sign + N.y * N.y * a, -N.y); } /* Color division */ diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index c94c8dbc8a7..a06d0c43776 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -1261,7 +1261,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType ![bitmapImage isPlanar]) { /* Try a fast copy if the image is a meshed RGBA 32bit bitmap. */ - toIBuf = (uint8_t *)ibuf->rect; + toIBuf = ibuf->byte_buffer.data; rasterRGB = (uint8_t *)[bitmapImage bitmapData]; for (y = 0; y < imgSize.height; y++) { to_i = (imgSize.height - y - 1) * imgSize.width; @@ -1338,7 +1338,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType } /* Copy the image to ibuf, flipping it vertically. */ - toIBuf = (uint8_t *)ibuf->rect; + toIBuf = ibuf->byte_buffer.data; for (y = 0; y < imgSize.height; y++) { for (x = 0; x < imgSize.width; x++) { to_i = (imgSize.height - y - 1) * imgSize.width + x; diff --git a/intern/ghost/intern/GHOST_SystemWayland.cc b/intern/ghost/intern/GHOST_SystemWayland.cc index 1919a9abcfd..3a51fbedb12 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cc +++ b/intern/ghost/intern/GHOST_SystemWayland.cc @@ -173,7 +173,7 @@ static bool use_gnome_confine_hack = false; * This is a hack because it seems there is no way to check if the compositor supports * server side decorations when initializing WAYLAND. */ -#if defined(WITH_GHOST_WAYLAND_LIBDECOR) && defined(WITH_GHOST_X11) +#ifdef WITH_GHOST_WAYLAND_LIBDECOR # define USE_GNOME_NEEDS_LIBDECOR_HACK #endif @@ -1002,6 +1002,10 @@ static void gwl_display_destroy(GWL_Display *display) delete display->ghost_timer_manager; display->ghost_timer_manager = nullptr; } + /* Pending events may be left unhandled. */ + for (GHOST_IEvent *event : display->events_pending) { + delete event; + } #endif /* USE_EVENT_BACKGROUND_THREAD */ @@ -1333,6 +1337,22 @@ static void ghost_wayland_log_handler(const char *msg, va_list arg) } } +#ifdef WITH_GHOST_X11 +/** + * Check if the system is running X11. + * This is not intended to be a fool-proof check (the `DISPLAY` is not validated for e.g.). + * Just check `DISPLAY` is set and not-empty. + */ +static bool ghost_wayland_is_x11_available() +{ + const char *x11_display = getenv("DISPLAY"); + if (x11_display && x11_display[0]) { + return true; + } + return false; +} +#endif /* WITH_GHOST_X11 */ + static GHOST_TKey xkb_map_gkey(const xkb_keysym_t sym) { @@ -2288,7 +2308,7 @@ static void data_device_handle_enter(void *data, const wl_fixed_t y, struct wl_data_offer *id) { - if (!ghost_wl_surface_own(wl_surface)) { + if (!ghost_wl_surface_own_with_null_check(wl_surface)) { CLOG_INFO(LOG, 2, "enter (skipped)"); return; } @@ -2623,7 +2643,8 @@ static void pointer_handle_enter(void *data, const wl_fixed_t surface_x, const wl_fixed_t surface_y) { - if (!ghost_wl_surface_own(wl_surface)) { + /* Null when just destroyed. */ + if (!ghost_wl_surface_own_with_null_check(wl_surface)) { CLOG_INFO(LOG, 2, "enter (skipped)"); return; } @@ -2662,12 +2683,11 @@ static void pointer_handle_leave(void *data, { /* First clear the `pointer.wl_surface`, since the window won't exist when closing the window. */ static_cast(data)->pointer.wl_surface_window = nullptr; - if (wl_surface && ghost_wl_surface_own(wl_surface)) { - CLOG_INFO(LOG, 2, "leave"); - } - else { + if (!ghost_wl_surface_own_with_null_check(wl_surface)) { CLOG_INFO(LOG, 2, "leave (skipped)"); + return; } + CLOG_INFO(LOG, 2, "leave"); } static void pointer_handle_motion(void *data, @@ -3304,7 +3324,7 @@ static void tablet_tool_handle_proximity_in(void *data, struct zwp_tablet_v2 * /*tablet*/, struct wl_surface *wl_surface) { - if (!ghost_wl_surface_own(wl_surface)) { + if (!ghost_wl_surface_own_with_null_check(wl_surface)) { CLOG_INFO(LOG, 2, "proximity_in (skipped)"); return; } @@ -3723,7 +3743,8 @@ static void keyboard_handle_enter(void *data, struct wl_surface *wl_surface, struct wl_array *keys) { - if (!ghost_wl_surface_own(wl_surface)) { + /* Null when just destroyed. */ + if (!ghost_wl_surface_own_with_null_check(wl_surface)) { CLOG_INFO(LOG, 2, "enter (skipped)"); return; } @@ -3765,7 +3786,7 @@ static void keyboard_handle_leave(void *data, const uint32_t /*serial*/, struct wl_surface *wl_surface) { - if (!(wl_surface && ghost_wl_surface_own(wl_surface))) { + if (!ghost_wl_surface_own_with_null_check(wl_surface)) { CLOG_INFO(LOG, 2, "leave (skipped)"); return; } @@ -5449,6 +5470,13 @@ static void *gwl_display_event_thread_fn(void *display_voidp) break; } } + + /* Wait until the main thread cancels this thread, otherwise this thread may exit + * before cancel is called, causing a crash on exit. */ + while (true) { + pause(); + } + return nullptr; } @@ -5517,12 +5545,21 @@ GHOST_SystemWayland::GHOST_SystemWayland(bool background) } #ifdef WITH_GHOST_WAYLAND_LIBDECOR - /* Ignore windowing requirements when running in background mode, - * as it doesn't make sense to fall back to X11 because of windowing functionality - * in background mode, also LIBDECOR is crashing in background mode `blender -b -f 1` - * for e.g. while it could be fixed, requiring the library at all makes no sense . */ - if (background) { - display_->libdecor_required = false; + if (display_->libdecor_required) { + /* Ignore windowing requirements when running in background mode, + * as it doesn't make sense to fall back to X11 because of windowing functionality + * in background mode, also LIBDECOR is crashing in background mode `blender -b -f 1` + * for e.g. while it could be fixed, requiring the library at all makes no sense . */ + if (background) { + display_->libdecor_required = false; + } +# ifdef WITH_GHOST_X11 + else if (!has_libdecor && !ghost_wayland_is_x11_available()) { + /* Only require LIBDECOR when X11 is available, otherwise there is nothing to fall back to. + * It's better to open without window decorations than failing entirely. */ + display_->libdecor_required = false; + } +# endif /* WITH_GHOST_X11 */ } if (display_->libdecor_required) { @@ -6833,6 +6870,11 @@ bool ghost_wl_surface_own(const struct wl_surface *wl_surface) return wl_proxy_get_tag((struct wl_proxy *)wl_surface) == &ghost_wl_surface_tag_id; } +bool ghost_wl_surface_own_with_null_check(const struct wl_surface *wl_surface) +{ + return wl_surface && ghost_wl_surface_own(wl_surface); +} + bool ghost_wl_surface_own_cursor_pointer(const struct wl_surface *wl_surface) { return wl_proxy_get_tag((struct wl_proxy *)wl_surface) == diff --git a/intern/ghost/intern/GHOST_SystemWayland.hh b/intern/ghost/intern/GHOST_SystemWayland.hh index 0b5984b026d..cc1f9190669 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.hh +++ b/intern/ghost/intern/GHOST_SystemWayland.hh @@ -37,6 +37,14 @@ bool ghost_wl_output_own(const struct wl_output *wl_output); void ghost_wl_output_tag(struct wl_output *wl_output); struct GWL_Output *ghost_wl_output_user_data(struct wl_output *wl_output); +/** + * Enter/exit handlers may be called with a null window surface (when the window just closed), + * so add a version of the function that checks this. + * + * All of the functions could in fact however paranoid null checks make the expected + * state difficult to reason about, so only use this in cases the surface may be null. + */ +bool ghost_wl_surface_own_with_null_check(const struct wl_surface *wl_surface); bool ghost_wl_surface_own(const struct wl_surface *wl_surface); void ghost_wl_surface_tag(struct wl_surface *wl_surface); GHOST_WindowWayland *ghost_wl_surface_user_data(struct wl_surface *wl_surface); diff --git a/intern/ghost/intern/GHOST_SystemWin32.cc b/intern/ghost/intern/GHOST_SystemWin32.cc index 55efddbe7a5..2beed13f42f 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cc +++ b/intern/ghost/intern/GHOST_SystemWin32.cc @@ -2422,7 +2422,7 @@ static uint *getClipboardImageImBuf(int *r_width, int *r_height, UINT format) *r_width = ibuf->x; *r_height = ibuf->y; rgba = (uint *)malloc(4 * ibuf->x * ibuf->y); - memcpy(rgba, ibuf->rect, 4 * ibuf->x * ibuf->y); + memcpy(rgba, ibuf->byte_buffer.data, 4 * ibuf->x * ibuf->y); IMB_freeImBuf(ibuf); } @@ -2513,7 +2513,7 @@ static bool putClipboardImagePNG(uint *rgba, int width, int height) UINT cf = RegisterClipboardFormat("PNG"); /* Load buffer into ImBuf, convert to PNG. */ - ImBuf *ibuf = IMB_allocFromBuffer(rgba, nullptr, width, height, 32); + ImBuf *ibuf = IMB_allocFromBuffer(reinterpret_cast(rgba), nullptr, width, height, 32); ibuf->ftype = IMB_FTYPE_PNG; ibuf->foptions.quality = 15; if (!IMB_saveiff(ibuf, "", IB_rect | IB_mem)) { @@ -2521,7 +2521,7 @@ static bool putClipboardImagePNG(uint *rgba, int width, int height) return false; } - HGLOBAL hMem = GlobalAlloc(GHND, ibuf->encodedbuffersize); + HGLOBAL hMem = GlobalAlloc(GHND, ibuf->encoded_buffer_size); if (!hMem) { IMB_freeImBuf(ibuf); return false; @@ -2534,7 +2534,7 @@ static bool putClipboardImagePNG(uint *rgba, int width, int height) return false; } - memcpy(pMem, ibuf->encodedbuffer, ibuf->encodedbuffersize); + memcpy(pMem, ibuf->encoded_buffer.data, ibuf->encoded_buffer_size); GlobalUnlock(hMem); IMB_freeImBuf(ibuf); diff --git a/intern/ghost/intern/GHOST_WindowWayland.cc b/intern/ghost/intern/GHOST_WindowWayland.cc index 22e00823f8a..673814b9e4a 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.cc +++ b/intern/ghost/intern/GHOST_WindowWayland.cc @@ -73,6 +73,17 @@ struct WGL_XDG_Decor_Window { struct zxdg_toplevel_decoration_v1 *toplevel_decor = nullptr; struct xdg_toplevel *toplevel = nullptr; enum zxdg_toplevel_decoration_v1_mode mode = (enum zxdg_toplevel_decoration_v1_mode)0; + + /** + * Defer calling #xdg_surface_ack_configure. + * \note Accessing the members must lock on `win->frame_pending_mutex`. + */ + struct { + /** When set, ACK configure is expected. */ + bool ack_configure = false; + /** The serial to pass to ACK configure. */ + uint32_t ack_configure_serial = 0; + } pending; }; static void gwl_xdg_decor_window_destroy(WGL_XDG_Decor_Window *decor) @@ -745,6 +756,18 @@ static void gwl_window_frame_update_from_pending_no_lock(GWL_Window *win) wl_surface_set_buffer_scale(win->wl_surface, win->frame.buffer_scale); } + if (win->xdg_decor) { + WGL_XDG_Decor_Window &decor = *win->xdg_decor; + if (decor.pending.ack_configure) { + xdg_surface_ack_configure(decor.surface, decor.pending.ack_configure_serial); + /* The XDG spec states a commit event is required after ACK configure. */ + surface_needs_commit = true; + + decor.pending.ack_configure = false; + decor.pending.ack_configure_serial = 0; + } + } + if (surface_needs_commit) { #ifdef USE_EVENT_BACKGROUND_THREAD /* Postponing the commit avoids flickering when moving between monitors of different scale. */ @@ -1179,6 +1202,12 @@ static void xdg_surface_handle_configure(void *data, } CLOG_INFO(LOG, 2, "configure"); +#ifdef USE_EVENT_BACKGROUND_THREAD + std::lock_guard lock_frame_guard{static_cast(data)->frame_pending_mutex}; +#endif + win->xdg_decor->pending.ack_configure = true; + win->xdg_decor->pending.ack_configure_serial = serial; + #ifdef USE_EVENT_BACKGROUND_THREAD GHOST_SystemWayland *system = win->ghost_system; const bool is_main_thread = system->main_thread_id == std::this_thread::get_id(); @@ -1190,10 +1219,8 @@ static void xdg_surface_handle_configure(void *data, else #endif { - gwl_window_frame_update_from_pending(win); + gwl_window_frame_update_from_pending_no_lock(win); } - - xdg_surface_ack_configure(xdg_surface, serial); } static const xdg_surface_listener xdg_surface_listener = { diff --git a/locale/languages b/locale/languages index 709e17a1ffe..170458e2db9 100644 --- a/locale/languages +++ b/locale/languages @@ -40,7 +40,7 @@ # Skipped (see IMPORT_LANGUAGES_SKIP in settings.py). #23:Greek (Ελληνικά):el_GR 35:Esperanto (Esperanto):eo # Skipped (see IMPORT_LANGUAGES_SKIP in settings.py). #36:Spanish from Spain (Español de España):es_ES -# Skipped (see IMPORT_LANGUAGES_SKIP in settings.py). #34:Estonian (Eestlane):et_EE +# Skipped (see IMPORT_LANGUAGES_SKIP in settings.py). #34:Estonian (Eesti keel):et_EE 42:Basque (Euskara):eu_EU 26:Persian (ﯽﺳﺭﺎﻓ):fa_IR 6:Finnish (Suomi):fi_FI diff --git a/scripts/modules/bl_i18n_utils/settings.py b/scripts/modules/bl_i18n_utils/settings.py index 47632c2357e..2733c2e7fbd 100644 --- a/scripts/modules/bl_i18n_utils/settings.py +++ b/scripts/modules/bl_i18n_utils/settings.py @@ -68,7 +68,7 @@ LANGUAGES = ( (32, "Brazilian Portuguese (Português do Brasil)", "pt_BR"), # Using the utf8 flipped form of Hebrew (עִבְרִית)). (33, "Hebrew (תירִבְעִ)", "he_IL"), - (34, "Estonian (Eestlane)", "et_EE"), + (34, "Estonian (Eesti keel)", "et_EE"), (35, "Esperanto (Esperanto)", "eo"), (36, "Spanish from Spain (Español de España)", "es_ES"), (37, "Amharic (አማርኛ)", "am_ET"), @@ -206,7 +206,7 @@ _str_base = ( r"(?:(?!<\\)(?:\\\\)*\\(?=(?P={_}2)))|" # The most common case. ".(?!(?P={_}2))" - ")+.)" # Don't forget the last char! + ")*.)" # Don't forget the last char! "(?P={_}2)" # And closing quote. ) str_clean_re = _str_base.format(_="g", capt="P") @@ -257,7 +257,8 @@ PYGETTEXT_KEYWORDS = (() + for it in ("modifier_subpanel_register", "gpencil_modifier_subpanel_register")) + # Node socket declarations: contextless names - tuple((r"\.{}\(\s*" + _msg_re + r"(?:,[^),]+)*\s*\)").format(it) + tuple((r"\.{}\(\s*" + _msg_re + r"(?:,[^),]+)*\s*\)" + r"(?![^;]*\.translation_context\()").format(it) for it in ("add_input", "add_output")) + # Node socket declarations: names with contexts diff --git a/scripts/presets/keyconfig/Blender.py b/scripts/presets/keyconfig/Blender.py index 52e4c2d4229..2eb63b16ee8 100644 --- a/scripts/presets/keyconfig/Blender.py +++ b/scripts/presets/keyconfig/Blender.py @@ -250,6 +250,15 @@ class Prefs(bpy.types.KeyConfigPreferences): update=update_fn, ) + use_transform_navigation: BoolProperty( + name="Navigate during Transform", + description=( + "Enable view navigation while using transform operators. " + "Proportional Influence, Automatic Constraints and Auto IK Chain Length shortcuts will require holding Alt key"), + default=False, + update=update_fn, + ) + def draw(self, layout): from bpy import context @@ -313,6 +322,7 @@ class Prefs(bpy.types.KeyConfigPreferences): sub.prop(self, "use_v3d_tab_menu") sub.prop(self, "use_pie_click_drag") sub.prop(self, "use_v3d_shade_ex_pie") + sub.prop(self, "use_transform_navigation") # File Browser settings. col = layout.column() @@ -365,6 +375,7 @@ def load(): use_alt_click_leader=kc_prefs.use_alt_click_leader, use_pie_click_drag=kc_prefs.use_pie_click_drag, use_file_single_click=kc_prefs.use_file_single_click, + use_transform_navigation=kc_prefs.use_transform_navigation, ), ) diff --git a/scripts/presets/keyconfig/keymap_data/blender_default.py b/scripts/presets/keyconfig/keymap_data/blender_default.py index a1545836f56..0f3a0722493 100644 --- a/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -93,6 +93,8 @@ class Params: # Since this means with RMB select enabled in edit-mode for e.g. # `Ctrl-LMB` would be caught by box-select instead of add/extrude. "tool_maybe_tweak_event", + # Changes some transformers modal key-map items to avoid conflicts with navigation operations + "use_transform_navigation", ) def __init__( @@ -119,6 +121,7 @@ class Params: use_file_single_click=False, v3d_tilde_action='VIEW', v3d_alt_mmb_drag_action='RELATIVE', + use_transform_navigation=False, ): from sys import platform self.apple = (platform == 'darwin') @@ -209,6 +212,7 @@ class Params: self.pie_value = 'CLICK_DRAG' if use_pie_click_drag else 'PRESS' self.tool_tweak_event = {"type": self.tool_mouse, "value": 'CLICK_DRAG'} self.tool_maybe_tweak_event = {"type": self.tool_mouse, "value": self.tool_maybe_tweak_value} + self.use_transform_navigation = use_transform_navigation # ------------------------------------------------------------------------------ @@ -1312,7 +1316,7 @@ def km_uv_editor(params): {"properties": [("extend", True)]}), ]) - # 3D cursor + # 2D cursor if params.cursor_tweak_event: items.extend([ ("uv.cursor_set", params.cursor_set_event, None), @@ -1581,13 +1585,16 @@ def km_view3d(params): # Transform. ("transform.translate", {"type": params.select_mouse, "value": 'CLICK_DRAG'}, None), op_tool_optional( - ("transform.translate", {"type": 'G', "value": 'PRESS'}, None), + ("transform.translate", {"type": 'G', "value": 'PRESS'}, + {"properties": [("allow_navigation", params.use_transform_navigation)]}), (op_tool_cycle, "builtin.move"), params), op_tool_optional( - ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None), + ("transform.rotate", {"type": 'R', "value": 'PRESS'}, + {"properties": [("allow_navigation", params.use_transform_navigation)]}), (op_tool_cycle, "builtin.rotate"), params), op_tool_optional( - ("transform.resize", {"type": 'S', "value": 'PRESS'}, None), + ("transform.resize", {"type": 'S', "value": 'PRESS'}, + {"properties": [("allow_navigation", params.use_transform_navigation)]}), (op_tool_cycle, "builtin.scale"), params), op_tool_optional( ("transform.tosphere", {"type": 'S', "value": 'PRESS', "shift": True, "alt": True}, None), @@ -3470,7 +3477,6 @@ def km_animation_channels(params): ("anim.channels_click", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True, "ctrl": True}, {"properties": [("children_only", True)]}), # Rename. - ("anim.channels_rename", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, None), ("anim.channels_rename", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None), # Select keys. ("anim.channel_select_keys", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None), @@ -4681,10 +4687,13 @@ def km_paint_curve(params): ("paintcurve.delete_point", {"type": 'DEL', "value": 'PRESS'}, None), ("paintcurve.draw", {"type": 'RET', "value": 'PRESS'}, None), ("paintcurve.draw", {"type": 'NUMPAD_ENTER', "value": 'PRESS'}, None), - ("transform.translate", {"type": 'G', "value": 'PRESS'}, None), + ("transform.translate", {"type": 'G', "value": 'PRESS'}, + {"properties": [("allow_navigation", params.use_transform_navigation)]}), ("transform.translate", {"type": params.select_mouse, "value": 'CLICK_DRAG'}, None), - ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None), - ("transform.resize", {"type": 'S', "value": 'PRESS'}, None), + ("transform.rotate", {"type": 'R', "value": 'PRESS'}, + {"properties": [("allow_navigation", params.use_transform_navigation)]}), + ("transform.resize", {"type": 'S', "value": 'PRESS'}, + {"properties": [("allow_navigation", params.use_transform_navigation)]}), ]) return keymap @@ -5844,7 +5853,7 @@ def km_eyedropper_colorramp_pointsampling_map(_params): return keymap -def km_transform_modal_map(_params): +def km_transform_modal_map(params): items = [] keymap = ( "Transform Modal Map", @@ -5884,24 +5893,24 @@ def km_transform_modal_map(_params): ("PROPORTIONAL_SIZE_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, None), ("PROPORTIONAL_SIZE_UP", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True, "repeat": True}, None), ("PROPORTIONAL_SIZE_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True, "repeat": True}, None), - ("PROPORTIONAL_SIZE_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS'}, None), - ("PROPORTIONAL_SIZE_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS'}, None), + ("PROPORTIONAL_SIZE_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "alt": params.use_transform_navigation}, None), + ("PROPORTIONAL_SIZE_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "alt": params.use_transform_navigation}, None), ("PROPORTIONAL_SIZE_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "shift": True}, None), ("PROPORTIONAL_SIZE_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "shift": True}, None), - ("PROPORTIONAL_SIZE", {"type": 'TRACKPADPAN', "value": 'ANY'}, None), + ("PROPORTIONAL_SIZE", {"type": 'TRACKPADPAN', "value": 'ANY', "alt": params.use_transform_navigation}, None), ("AUTOIK_CHAIN_LEN_UP", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, None), ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, None), ("AUTOIK_CHAIN_LEN_UP", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True, "repeat": True}, None), ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True, "repeat": True}, None), - ("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS'}, None), - ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS'}, None), + ("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "alt": params.use_transform_navigation}, None), + ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "alt": params.use_transform_navigation}, None), ("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "shift": True}, None), ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "shift": True}, None), ("INSERTOFS_TOGGLE_DIR", {"type": 'T', "value": 'PRESS'}, None), ("NODE_ATTACH_ON", {"type": 'LEFT_ALT', "value": 'RELEASE', "any": True}, None), ("NODE_ATTACH_OFF", {"type": 'LEFT_ALT', "value": 'PRESS', "any": True}, None), - ("AUTOCONSTRAIN", {"type": 'MIDDLEMOUSE', "value": 'ANY'}, None), - ("AUTOCONSTRAINPLANE", {"type": 'MIDDLEMOUSE', "value": 'ANY', "shift": True}, None), + ("AUTOCONSTRAIN", {"type": 'MIDDLEMOUSE', "value": 'ANY', "alt": params.use_transform_navigation}, None), + ("AUTOCONSTRAINPLANE", {"type": 'MIDDLEMOUSE', "value": 'ANY', "shift": True, "alt": params.use_transform_navigation}, None), ("PRECISION", {"type": 'LEFT_SHIFT', "value": 'ANY', "any": True}, None), ("PRECISION", {"type": 'RIGHT_SHIFT', "value": 'ANY', "any": True}, None), ]) diff --git a/scripts/startup/bl_ui/properties_data_mesh.py b/scripts/startup/bl_ui/properties_data_mesh.py index a411a34f563..a79f3092cbe 100644 --- a/scripts/startup/bl_ui/properties_data_mesh.py +++ b/scripts/startup/bl_ui/properties_data_mesh.py @@ -496,16 +496,6 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel): else: col.operator("mesh.customdata_custom_splitnormals_add", icon='ADD') - if me.has_bevel_weight_edge: - col.operator("mesh.customdata_bevel_weight_edge_clear", icon='X') - else: - col.operator("mesh.customdata_bevel_weight_edge_add", icon='ADD') - - if me.has_bevel_weight_vertex: - col.operator("mesh.customdata_bevel_weight_vertex_clear", icon='X') - else: - col.operator("mesh.customdata_bevel_weight_vertex_add", icon='ADD') - if me.has_crease_edge: col.operator("mesh.customdata_crease_edge_clear", icon='X') else: diff --git a/scripts/startup/bl_ui/space_sequencer.py b/scripts/startup/bl_ui/space_sequencer.py index dd88c2b128b..6ab766c5ecf 100644 --- a/scripts/startup/bl_ui/space_sequencer.py +++ b/scripts/startup/bl_ui/space_sequencer.py @@ -434,6 +434,7 @@ class SEQUENCER_MT_view(Menu): if is_sequencer_view: layout.operator_context = 'INVOKE_REGION_WIN' layout.operator("sequencer.view_all") + layout.operator("sequencer.view_frame") layout.operator("view2d.zoom_border", text="Zoom") layout.prop(st, "use_clamp_view") diff --git a/scripts/startup/bl_ui/space_time.py b/scripts/startup/bl_ui/space_time.py index b23a8df2caa..68a38120a6a 100644 --- a/scripts/startup/bl_ui/space_time.py +++ b/scripts/startup/bl_ui/space_time.py @@ -257,6 +257,7 @@ class TIME_PT_playback(TimelinePanelButtons, Panel): col.prop(screen, "use_play_clip_editors", text="Movie Clip Editor") col.prop(screen, "use_play_node_editors", text="Node Editors") col.prop(screen, "use_play_sequence_editors", text="Video Sequencer") + col.prop(screen, "use_play_spreadsheet_editors") col = layout.column(heading="Show") col.prop(scene, "show_subframe", text="Subframes") diff --git a/scripts/startup/bl_ui/space_view3d.py b/scripts/startup/bl_ui/space_view3d.py index ec65e0f37f6..eec21d96dd2 100644 --- a/scripts/startup/bl_ui/space_view3d.py +++ b/scripts/startup/bl_ui/space_view3d.py @@ -1038,10 +1038,22 @@ class VIEW3D_MT_transform_base: # TODO: get rid of the custom text strings? def draw(self, context): layout = self.layout + allow_navigation = getattr( + context.window_manager.keyconfigs.active.preferences, + "use_transform_navigation", + False) - layout.operator("transform.translate") - layout.operator("transform.rotate") - layout.operator("transform.resize", text="Scale") + props = layout.operator("transform.translate") + props.release_confirm = False + props.allow_navigation = allow_navigation + + props = layout.operator("transform.rotate") + props.release_confirm = False + props.allow_navigation = allow_navigation + + props = layout.operator("transform.resize", text="Scale") + props.release_confirm = False + props.allow_navigation = allow_navigation layout.separator() diff --git a/scripts/startup/bl_ui/space_view3d_toolbar.py b/scripts/startup/bl_ui/space_view3d_toolbar.py index 5a9dcf85e42..e2a4ceec635 100644 --- a/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -155,6 +155,17 @@ class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel): bl_options = {'DEFAULT_CLOSED'} bl_ui_units_x = 12 + def draw(self, _context): + # layout = self.layout + pass + + +class VIEW3D_PT_tools_meshedit_options_transform(View3DPanel, Panel): + bl_category = "Tool" + bl_context = ".mesh_edit" # dot on purpose (access from topbar) + bl_label = "Transform" + bl_parent_id = "VIEW3D_PT_tools_meshedit_options" + @classmethod def poll(cls, context): return context.active_object @@ -169,56 +180,47 @@ class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel): ob = context.active_object mesh = ob.data - row = layout.row(align=True, heading="Transform") - row.prop(tool_settings, "use_transform_correct_face_attributes") + col = layout.column(align=True) + col.prop(tool_settings, "use_transform_correct_face_attributes") + sub = col.column(align=True) + sub.active = tool_settings.use_transform_correct_face_attributes + sub.prop(tool_settings, "use_transform_correct_keep_connected") + col.separator() - row = layout.row(align=True) - row.active = tool_settings.use_transform_correct_face_attributes - row.prop(tool_settings, "use_transform_correct_keep_connected") - - row = layout.row(align=True, heading="UVs") - row.prop(tool_settings, "use_edge_path_live_unwrap") - - row = layout.row(heading="Mirror") - sub = row.row(align=True) + col = layout.column(heading="Mirror") + sub = col.row(align=True) sub.prop(mesh, "use_mirror_x", text="X", toggle=True) sub.prop(mesh, "use_mirror_y", text="Y", toggle=True) sub.prop(mesh, "use_mirror_z", text="Z", toggle=True) - row = layout.row(align=True) - row.active = ob.data.use_mirror_x or ob.data.use_mirror_y or ob.data.use_mirror_z - row.prop(mesh, "use_mirror_topology") + col = layout.column(align=True) + col.active = mesh.use_mirror_x or mesh.use_mirror_y or mesh.use_mirror_z + col.prop(mesh, "use_mirror_topology") + col.separator() + + col = layout.column(align=True) + col.prop(tool_settings, "use_mesh_automerge", text="Auto Merge", toggle=False) + sub = col.column(align=True) + sub.active = tool_settings.use_mesh_automerge + sub.prop(tool_settings, "use_mesh_automerge_and_split", toggle=False) + sub.prop(tool_settings, "double_threshold", text="Threshold") -class VIEW3D_PT_tools_meshedit_options_automerge(View3DPanel, Panel): +class VIEW3D_PT_tools_meshedit_options_uvs(View3DPanel, Panel): bl_category = "Tool" bl_context = ".mesh_edit" # dot on purpose (access from topbar) - bl_label = "Auto Merge" + bl_label = "UVs" bl_parent_id = "VIEW3D_PT_tools_meshedit_options" - bl_options = {'DEFAULT_CLOSED'} - - @classmethod - def poll(cls, context): - return context.active_object - - def draw_header(self, context): - tool_settings = context.tool_settings - self.layout.use_property_split = False - self.layout.prop(tool_settings, "use_mesh_automerge", - text=self.bl_label if self.is_popover else "", toggle=False) def draw(self, context): layout = self.layout + layout.use_property_decorate = False + layout.use_property_split = True + tool_settings = context.tool_settings - layout.use_property_split = True - layout.use_property_decorate = False - - col = layout.column(align=True) - col.active = tool_settings.use_mesh_automerge - col.prop(tool_settings, "use_mesh_automerge_and_split", toggle=False) - col.prop(tool_settings, "double_threshold", text="Threshold") + layout.prop(tool_settings, "use_edge_path_live_unwrap") # ********** default tools for editmode_armature **************** @@ -2368,7 +2370,8 @@ classes = ( VIEW3D_PT_tools_object_options, VIEW3D_PT_tools_object_options_transform, VIEW3D_PT_tools_meshedit_options, - VIEW3D_PT_tools_meshedit_options_automerge, + VIEW3D_PT_tools_meshedit_options_transform, + VIEW3D_PT_tools_meshedit_options_uvs, VIEW3D_PT_tools_armatureedit_options, VIEW3D_PT_tools_posemode_options, diff --git a/scripts/startup/nodeitems_builtins.py b/scripts/startup/nodeitems_builtins.py index 3deec135888..583b892656b 100644 --- a/scripts/startup/nodeitems_builtins.py +++ b/scripts/startup/nodeitems_builtins.py @@ -191,7 +191,6 @@ shader_node_categories = [ NodeItem("ShaderNodeBsdfRefraction", poll=object_eevee_cycles_shader_nodes_poll), NodeItem("ShaderNodeBsdfGlass", poll=object_eevee_cycles_shader_nodes_poll), NodeItem("ShaderNodeBsdfTranslucent", poll=object_eevee_cycles_shader_nodes_poll), - NodeItem("ShaderNodeBsdfAnisotropic", poll=object_cycles_shader_nodes_poll), NodeItem("ShaderNodeBsdfVelvet", poll=object_cycles_shader_nodes_poll), NodeItem("ShaderNodeBsdfToon", poll=object_cycles_shader_nodes_poll), NodeItem("ShaderNodeSubsurfaceScattering", poll=object_eevee_cycles_shader_nodes_poll), diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 47308bdad3d..46a16875473 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -25,13 +25,13 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 0 +#define BLENDER_FILE_SUBVERSION 2 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file * was written with too new a version. */ -#define BLENDER_FILE_MIN_VERSION 305 -#define BLENDER_FILE_MIN_SUBVERSION 9 +#define BLENDER_FILE_MIN_VERSION 400 +#define BLENDER_FILE_MIN_SUBVERSION 2 /** User readable version string. */ const char *BKE_blender_version_string(void); diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 360f82cffb1..1a7e0d7fe78 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -314,6 +314,9 @@ void CustomData_free_layers(struct CustomData *data, eCustomDataType type, int t * Returns true if a layer with the specified type exists. */ bool CustomData_has_layer(const struct CustomData *data, eCustomDataType type); +bool CustomData_has_layer_named(const struct CustomData *data, + eCustomDataType type, + const char *name); /** * Returns the number of layers with this type. @@ -700,6 +703,8 @@ enum { CD_CUSTOMLOOPNORMAL, /* Because we play with clnor and temp lnor layers here. */ CD_FAKE_SHARP = CD_FAKE | 200, /* Sharp flag for edges, smooth flag for faces. */ + + CD_FAKE_BWEIGHT = CD_FAKE | 300, /* UV seam flag for edges. */ }; enum { diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index 3d7aa88cd8c..98e75243f2b 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -480,7 +480,7 @@ bool BKE_fcurve_bezt_subdivide_handles(struct BezTriple *bezt, /** * Resize the FCurve 'bezt' array to fit the given length. * - * \param new_totvert new number of elements in the FCurve's `bezt` array. + * \param new_totvert: new number of elements in the FCurve's `bezt` array. * Constraint: `0 <= new_totvert <= fcu->totvert` */ void BKE_fcurve_bezt_shrink(struct FCurve *fcu, int new_totvert); diff --git a/source/blender/blenkernel/BKE_geometry_set_instances.hh b/source/blender/blenkernel/BKE_geometry_set_instances.hh index ec3c9c0d645..244b94d15a7 100644 --- a/source/blender/blenkernel/BKE_geometry_set_instances.hh +++ b/source/blender/blenkernel/BKE_geometry_set_instances.hh @@ -2,8 +2,6 @@ #pragma once -#include "BLI_math_matrix_types.hh" - #include "BKE_geometry_set.hh" namespace blender::bke { @@ -13,36 +11,4 @@ namespace blender::bke { */ GeometrySet object_get_evaluated_geometry_set(const Object &object); -/** - * Used to keep track of a group of instances using the same geometry data. - */ -struct GeometryInstanceGroup { - /** - * The geometry set instanced on each of the transforms. The components are not necessarily - * owned here. For example, they may be owned by the instanced object. This cannot be a - * reference because not all instanced data will necessarily have a #geometry_set_eval. - */ - GeometrySet geometry_set; - - /** - * As an optimization to avoid copying, the same geometry set can be associated with multiple - * instances. Each instance is stored as a transform matrix here. Again, these must be owned - * because they may be transformed from the original data. TODO: Validate that last statement. - */ - Vector transforms; -}; - -/** - * Return flattened vector of the geometry component's recursive instances. I.e. all collection - * instances and object instances will be expanded into the instances of their geometry components. - * Even the instances in those geometry components' will be included. - * - * \note For convenience (to avoid duplication in the caller), the returned vector also contains - * the argument geometry set. - * - * \note This doesn't extract instances from the "dupli" system for non-geometry-nodes instances. - */ -void geometry_set_gather_instances(const GeometrySet &geometry_set, - Vector &r_instance_groups); - } // namespace blender::bke diff --git a/source/blender/blenkernel/BKE_image_wrappers.hh b/source/blender/blenkernel/BKE_image_wrappers.hh index d7bc36f8b2a..3da21d7771f 100644 --- a/source/blender/blenkernel/BKE_image_wrappers.hh +++ b/source/blender/blenkernel/BKE_image_wrappers.hh @@ -57,13 +57,14 @@ template struct ImageBufferAccessor { { if constexpr ((std::is_same_v)) { int offset = (coordinate.y * image_buffer.x + coordinate.x) * Channels; - return float4(&image_buffer.rect_float[offset]); + return float4(&image_buffer.float_buffer.data[offset]); } if constexpr ((std::is_same_v)) { int offset = (coordinate.y * image_buffer.x + coordinate.x); float4 result; - rgba_uchar_to_float(result, - static_cast(static_cast(&image_buffer.rect[offset]))); + rgba_uchar_to_float( + result, + static_cast(static_cast(&image_buffer.byte_buffer.data[offset]))); return result; } return float4(); @@ -73,12 +74,13 @@ template struct ImageBufferAccessor { { if constexpr ((std::is_same_v)) { int offset = (coordinate.y * image_buffer.x + coordinate.x) * Channels; - copy_v4_v4(&image_buffer.rect_float[offset], new_value); + copy_v4_v4(&image_buffer.float_buffer.data[offset], new_value); } if constexpr ((std::is_same_v)) { int offset = (coordinate.y * image_buffer.x + coordinate.x); - rgba_float_to_uchar(static_cast(static_cast(&image_buffer.rect[offset])), - new_value); + rgba_float_to_uchar( + static_cast(static_cast(&image_buffer.byte_buffer.data[offset])), + new_value); } } }; diff --git a/source/blender/blenkernel/BKE_lib_id.h b/source/blender/blenkernel/BKE_lib_id.h index d2a489d60fa..9bdf57b28ac 100644 --- a/source/blender/blenkernel/BKE_lib_id.h +++ b/source/blender/blenkernel/BKE_lib_id.h @@ -311,10 +311,11 @@ void BKE_id_delete(struct Main *bmain, void *idv) ATTR_NONNULL(); /** * Like BKE_id_delete, but with extra corner-case options. * - * \param extra_remapping_flags Additional `ID_REMAP_` flags to pass to remapping code when + * \param extra_remapping_flags: Additional `ID_REMAP_` flags to pass to remapping code when * ensuring that deleted IDs are not used by any other ID in given `bmain`. Typical example would * be e.g. `ID_REMAP_FORCE_UI_POINTERS`, required when default UI-handling callbacks of remapping - * code won't be working (e.g. from readfile code). */ + * code won't be working (e.g. from readfile code). + */ void BKE_id_delete_ex(struct Main *bmain, void *idv, const int extra_remapping_flags) ATTR_NONNULL(1, 2); /** diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h index 990517f128e..70b717004c0 100644 --- a/source/blender/blenkernel/BKE_lib_override.h +++ b/source/blender/blenkernel/BKE_lib_override.h @@ -303,6 +303,27 @@ struct IDOverrideLibraryProperty *BKE_lib_override_library_property_get( */ void BKE_lib_override_library_property_delete(struct IDOverrideLibrary *override, struct IDOverrideLibraryProperty *override_property); +/** + * Delete a property override from the given ID \a override, if it exists. + * + * \return True when the property was found (and thus deleted), false if it wasn't found. + */ +bool BKE_lib_override_library_property_search_and_delete(struct IDOverrideLibrary *override, + const char *rna_path); + +/** Change the RNA path of a library override on a property. + * + * No-op if the property override cannot be found. + * + * \param from_rna_path The RNA path of the property to change. + * \param to_rna_path The new RNA path. The library override system will copy the string to its own + * memory; the caller will retain ownership of the passed pointer. + * \return True if the property was found (and thus changed), false if it wasn't found. + */ +bool BKE_lib_override_library_property_rna_path_change(IDOverrideLibrary *liboverride, + const char *old_rna_path, + const char *new_rna_path); + /** * Get the RNA-property matching the \a library_prop override property. Used for UI to query * additional data about the overridden property (e.g. UI name). diff --git a/source/blender/blenkernel/BKE_mesh.hh b/source/blender/blenkernel/BKE_mesh.hh index d2e03ee3755..3aa5d655891 100644 --- a/source/blender/blenkernel/BKE_mesh.hh +++ b/source/blender/blenkernel/BKE_mesh.hh @@ -86,7 +86,7 @@ void normals_calc_poly_vert(Span vert_positions, * \{ */ /** - * Combined with the automatically calculated face corner normal, this gives a dimentional + * Combined with the automatically calculated face corner normal, this gives a dimensional * coordinate space used to convert normals between the "custom normal" #short2 representation and * a regular #float3 format. */ diff --git a/source/blender/blenkernel/BKE_mesh_legacy_convert.h b/source/blender/blenkernel/BKE_mesh_legacy_convert.h index 44895652d8a..5c1233084d9 100644 --- a/source/blender/blenkernel/BKE_mesh_legacy_convert.h +++ b/source/blender/blenkernel/BKE_mesh_legacy_convert.h @@ -30,107 +30,55 @@ void BKE_mesh_legacy_convert_uvs_to_struct( blender::Vector &loop_layers_to_write); void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh); -/** - * Move face sets to the legacy type from a generic type. - */ -void BKE_mesh_legacy_face_set_from_generic( - blender::MutableSpan poly_layers_to_write); /** * Copy face sets to the generic data type from the legacy type. */ void BKE_mesh_legacy_face_set_to_generic(struct Mesh *mesh); -/** - * Copy edge creases from a separate layer into edges. - */ -void BKE_mesh_legacy_edge_crease_from_layers(struct Mesh *mesh); /** * Copy edge creases from edges to a separate layer. */ void BKE_mesh_legacy_edge_crease_to_layers(struct Mesh *mesh); -/** - * Copy bevel weights from separate layers into vertices and edges. - */ -void BKE_mesh_legacy_bevel_weight_from_layers(struct Mesh *mesh); /** * Copy bevel weights from vertices and edges to separate layers. */ void BKE_mesh_legacy_bevel_weight_to_layers(struct Mesh *mesh); - /** - * Convert the hidden element attributes to the old flag format for writing. + * Move bevel weight to generic float attribute type. */ -void BKE_mesh_legacy_convert_hide_layers_to_flags(struct Mesh *mesh, - blender::MutableSpan legacy_polys); +void BKE_mesh_legacy_bevel_weight_to_generic(struct Mesh *mesh); + /** * Convert the old hide flags (#ME_HIDE) to the hidden element attribute for reading. * Only add the attributes when there are any elements in each domain hidden. */ void BKE_mesh_legacy_convert_flags_to_hide_layers(struct Mesh *mesh); -/** - * Convert the selected element attributes to the old flag format for writing. - */ -void BKE_mesh_legacy_convert_selection_layers_to_flags(struct Mesh *mesh, - blender::MutableSpan legacy_polys); /** * Convert the old selection flags (#SELECT/#ME_FACE_SEL) to the selected element attribute for * reading. Only add the attributes when there are any elements in each domain selected. */ void BKE_mesh_legacy_convert_flags_to_selection_layers(struct Mesh *mesh); -/** - * Move material indices from a generic attribute to #MPoly. - */ -void BKE_mesh_legacy_convert_material_indices_to_mpoly(struct Mesh *mesh, - blender::MutableSpan legacy_polys); /** * Move material indices from the #MPoly struct to a generic attributes. * Only add the attribute when the indices are not all zero. */ void BKE_mesh_legacy_convert_mpoly_to_material_indices(struct Mesh *mesh); -/** Convert from runtime loose edge cache to legacy edge flag. */ -void BKE_mesh_legacy_convert_loose_edges_to_flag(struct Mesh *mesh); - void BKE_mesh_legacy_attribute_flags_to_strings(struct Mesh *mesh); -void BKE_mesh_legacy_attribute_strings_to_flags(struct Mesh *mesh); -void BKE_mesh_legacy_sharp_faces_to_flags(struct Mesh *mesh, - blender::MutableSpan legacy_polys); void BKE_mesh_legacy_sharp_faces_from_flags(struct Mesh *mesh); -void BKE_mesh_legacy_sharp_edges_to_flags(struct Mesh *mesh); void BKE_mesh_legacy_sharp_edges_from_flags(struct Mesh *mesh); -void BKE_mesh_legacy_uv_seam_to_flags(struct Mesh *mesh); void BKE_mesh_legacy_uv_seam_from_flags(struct Mesh *mesh); -struct MVert *BKE_mesh_legacy_convert_positions_to_verts( - Mesh *mesh, - blender::ResourceScope &temp_arrays_for_convert, - blender::Vector &vert_layers_to_write); - void BKE_mesh_legacy_convert_verts_to_positions(Mesh *mesh); -MEdge *BKE_mesh_legacy_convert_edges_to_medge( - Mesh *mesh, - blender::ResourceScope &temp_arrays_for_convert, - blender::Vector &edge_layers_to_write); - void BKE_mesh_legacy_convert_edges_to_generic(Mesh *mesh); -struct MLoop *BKE_mesh_legacy_convert_corners_to_loops( - Mesh *mesh, - blender::ResourceScope &temp_arrays_for_convert, - blender::Vector &loop_layers_to_write); - -blender::MutableSpan BKE_mesh_legacy_convert_offsets_to_polys( - const Mesh *mesh, - blender::ResourceScope &temp_arrays_for_convert, - blender::Vector &poly_layers_to_write); - void BKE_mesh_legacy_convert_polys_to_offsets(Mesh *mesh); void BKE_mesh_legacy_convert_loops_to_corners(struct Mesh *mesh); diff --git a/source/blender/blenkernel/BKE_mesh_remap.h b/source/blender/blenkernel/BKE_mesh_remap.h index 7c7a9c765fd..5ec8f71e973 100644 --- a/source/blender/blenkernel/BKE_mesh_remap.h +++ b/source/blender/blenkernel/BKE_mesh_remap.h @@ -19,7 +19,7 @@ struct CustomData_MeshMasks; struct MemArena; struct Mesh; -/* Generic ways to map some geometry elements from a source mesh to a dest one. */ +/* Generic ways to map some geometry elements from a source mesh to a destination one. */ typedef struct MeshPairRemapItem { int sources_num; @@ -33,7 +33,7 @@ typedef struct MeshPairRemapItem { /* All mapping computing func return this. */ typedef struct MeshPairRemap { int items_num; - MeshPairRemapItem *items; /* array, one item per dest element. */ + MeshPairRemapItem *items; /* Array, one item per destination element. */ struct MemArena *mem; /* memory arena, internal use only. */ } MeshPairRemap; @@ -89,7 +89,7 @@ enum { /* ***** Target's edges ***** */ MREMAP_MODE_EDGE = 1 << 25, - /* Source edge which both vertices are nearest of dest ones. */ + /* Source edge which both vertices are nearest of destination ones. */ MREMAP_MODE_EDGE_VERT_NEAREST = MREMAP_MODE_EDGE | MREMAP_USE_VERT | MREMAP_USE_NEAREST, /* Nearest source edge (using mid-point). */ @@ -98,7 +98,7 @@ enum { /* Nearest edge of nearest poly (using mid-point). */ MREMAP_MODE_EDGE_POLY_NEAREST = MREMAP_MODE_EDGE | MREMAP_USE_POLY | MREMAP_USE_NEAREST, - /* Cast a set of rays from along dest edge, + /* Cast a set of rays from along destination edge, * interpolating its vertices' normals, and use hit source edges. */ MREMAP_MODE_EDGE_EDGEINTERP_VNORPROJ = MREMAP_MODE_EDGE | MREMAP_USE_VERT | MREMAP_USE_NORPROJ | MREMAP_USE_INTERP, @@ -131,10 +131,10 @@ enum { /* Nearest source poly. */ MREMAP_MODE_POLY_NEAREST = MREMAP_MODE_POLY | MREMAP_USE_POLY | MREMAP_USE_NEAREST, - /* Source poly from best normal-matching dest poly. */ + /* Source poly from best normal-matching destination poly. */ MREMAP_MODE_POLY_NOR = MREMAP_MODE_POLY | MREMAP_USE_POLY | MREMAP_USE_NORMAL, - /* Project dest poly onto source mesh using its normal, + /* Project destination poly onto source mesh using its normal, * and use interpolation of all intersecting source polys. */ MREMAP_MODE_POLY_POLYINTERP_PNORPROJ = MREMAP_MODE_POLY | MREMAP_USE_POLY | MREMAP_USE_NORPROJ | MREMAP_USE_INTERP, diff --git a/source/blender/blenkernel/BKE_mesh_sample.hh b/source/blender/blenkernel/BKE_mesh_sample.hh index 6e94d4ccec4..17e4ba0d83d 100644 --- a/source/blender/blenkernel/BKE_mesh_sample.hh +++ b/source/blender/blenkernel/BKE_mesh_sample.hh @@ -35,6 +35,14 @@ void sample_point_attribute(Span corner_verts, IndexMask mask, GMutableSpan dst); +void sample_point_normals(Span corner_verts, + Span looptris, + Span looptri_indices, + Span bary_coords, + Span src, + IndexMask mask, + MutableSpan dst); + void sample_corner_attribute(Span looptris, Span looptri_indices, Span bary_coords, diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 247ba45c13a..61fbaa67724 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -554,8 +554,10 @@ struct bNodeSocket *ntreeAddSocketInterface(struct bNodeTree *ntree, * \{ */ struct bNodeType *nodeTypeFind(const char *idname); +const char *nodeTypeFindAlias(const char *idname); void nodeRegisterType(struct bNodeType *ntype); void nodeUnregisterType(struct bNodeType *ntype); +void nodeRegisterAlias(struct bNodeType *nt, const char *alias); struct GHashIterator *nodeTypeGetIterator(void); /* Helper macros for iterating over node types. */ @@ -893,9 +895,9 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i #define SH_NODE_MIX_SHADER 128 #define SH_NODE_ATTRIBUTE 129 #define SH_NODE_BACKGROUND 130 -#define SH_NODE_BSDF_ANISOTROPIC 131 +#define SH_NODE_BSDF_GLOSSY 131 #define SH_NODE_BSDF_DIFFUSE 132 -#define SH_NODE_BSDF_GLOSSY 133 +#define SH_NODE_BSDF_GLOSSY_LEGACY 133 #define SH_NODE_BSDF_GLASS 134 #define SH_NODE_BSDF_TRANSLUCENT 137 #define SH_NODE_BSDF_TRANSPARENT 138 diff --git a/source/blender/blenkernel/BKE_node.hh b/source/blender/blenkernel/BKE_node.hh index d6c8353da42..ff0ff33e593 100644 --- a/source/blender/blenkernel/BKE_node.hh +++ b/source/blender/blenkernel/BKE_node.hh @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-or-later - * Copyright 2005 Blender Foundation */ + * Copyright 2023 Blender Foundation */ #pragma once diff --git a/source/blender/blenkernel/BKE_pbvh_pixels.hh b/source/blender/blenkernel/BKE_pbvh_pixels.hh index b079f9f2c02..db78a411ab1 100644 --- a/source/blender/blenkernel/BKE_pbvh_pixels.hh +++ b/source/blender/blenkernel/BKE_pbvh_pixels.hh @@ -346,7 +346,7 @@ struct CopyPixelTile { void copy_pixels(ImBuf &tile_buffer, IndexRange group_range) const { - if (tile_buffer.rect_float) { + if (tile_buffer.float_buffer.data) { image::ImageBufferAccessor accessor(tile_buffer); copy_pixels(accessor, group_range); } diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h index a69fee19380..12f8795ae2a 100644 --- a/source/blender/blenkernel/BKE_text.h +++ b/source/blender/blenkernel/BKE_text.h @@ -94,6 +94,9 @@ void txt_sel_clear(struct Text *text); void txt_sel_line(struct Text *text); void txt_sel_set(struct Text *text, int startl, int startc, int endl, int endc); char *txt_sel_to_buf(const struct Text *text, size_t *r_buf_strlen); +/** + * \param in_buffer: UTF8 encoded text, invalid UTF8 byte-sequences are handled gracefully. + */ void txt_insert_buf(struct Text *text, const char *in_buffer, int in_buffer_len) ATTR_NONNULL(1, 2); void txt_split_curline(struct Text *text); diff --git a/source/blender/blenkernel/intern/CCGSubSurf_legacy.c b/source/blender/blenkernel/intern/CCGSubSurf_legacy.c index 35da8edd3b7..7f8b4e64474 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf_legacy.c +++ b/source/blender/blenkernel/intern/CCGSubSurf_legacy.c @@ -334,7 +334,7 @@ static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss, 0, numEffectedF, &data, ccgSubSurf__calcVertNormals_faces_accumulate_cb, &settings); } - /* XXX can I reduce the number of normalisations here? */ + /* XXX can I reduce the number of normalization calls here? */ for (ptrIdx = 0; ptrIdx < numEffectedV; ptrIdx++) { CCGVert *v = (CCGVert *)effectedV[ptrIdx]; float *no = VERT_getNo(v, lvl); diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 68677666b16..df616c15eeb 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -641,8 +641,8 @@ static int animsys_quaternion_evaluate_fcurves(PathResolvedRNA quat_rna, } if (fcurve_offset < 4) { - /* This quaternion was incompletely keyed, so the result is a mixture of the unit quaterion and - * values from FCurves. This means that it's almost certainly no longer of unit length. */ + /* This quaternion was incompletely keyed, so the result is a mixture of the unit quaternion + * and values from FCurves. This means that it's almost certainly no longer of unit length. */ normalize_qt(r_quaternion); } diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index a09ae77e81b..814932772ff 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -446,7 +446,7 @@ bool BuiltinCustomDataLayerProvider::try_create(void *owner, const int element_num = custom_data_access_.get_element_num(owner); if (stored_as_named_attribute_) { - if (CustomData_get_layer_named(custom_data, data_type_, name_.c_str())) { + if (CustomData_has_layer_named(custom_data, data_type_, name_.c_str())) { /* Exists already. */ return false; } @@ -469,7 +469,7 @@ bool BuiltinCustomDataLayerProvider::exists(const void *owner) const return false; } if (stored_as_named_attribute_) { - return CustomData_get_layer_named(custom_data, stored_type_, name_.c_str()) != nullptr; + return CustomData_has_layer_named(custom_data, stored_type_, name_.c_str()); } return CustomData_get_layer(custom_data, stored_type_) != nullptr; } diff --git a/source/blender/blenkernel/intern/brush.cc b/source/blender/blenkernel/intern/brush.cc index 0fee5b6842c..23dc4a31245 100644 --- a/source/blender/blenkernel/intern/brush.cc +++ b/source/blender/blenkernel/intern/brush.cc @@ -2624,18 +2624,22 @@ struct ImBuf *BKE_brush_gen_radial_control_imbuf(Brush *br, bool secondary, bool int half = side / 2; BKE_curvemapping_init(br->curve); - im->rect_float = (float *)MEM_callocN(sizeof(float) * side * side, "radial control rect"); + + float *rect_float = (float *)MEM_callocN(sizeof(float) * side * side, "radial control rect"); + IMB_assign_float_buffer(im, rect_float, IB_DO_NOT_TAKE_OWNERSHIP); + im->x = im->y = side; - const bool have_texture = brush_gen_texture(br, side, secondary, im->rect_float); + const bool have_texture = brush_gen_texture(br, side, secondary, im->float_buffer.data); if (display_gradient || have_texture) { for (int i = 0; i < side; i++) { for (int j = 0; j < side; j++) { const float magn = sqrtf(pow2f(i - half) + pow2f(j - half)); const float strength = BKE_brush_curve_strength_clamped(br, magn, half); - im->rect_float[i * side + j] = (have_texture) ? im->rect_float[i * side + j] * strength : - strength; + im->float_buffer.data[i * side + j] = (have_texture) ? + im->float_buffer.data[i * side + j] * strength : + strength; } } } diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index c644a663e41..420547b8214 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -1382,11 +1382,11 @@ void BKE_histogram_update_sample_line(Histogram *hist, hist->xmax = 1.0f; /* hist->ymax = 1.0f; */ /* now do this on the operator _only_ */ - if (ibuf->rect == NULL && ibuf->rect_float == NULL) { + if (ibuf->byte_buffer.data == NULL && ibuf->float_buffer.data == NULL) { return; } - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings); } @@ -1399,9 +1399,9 @@ void BKE_histogram_update_sample_line(Histogram *hist, 0.0f; } else { - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { float rgba[4]; - fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x)); + fp = (ibuf->float_buffer.data + (ibuf->channels) * (y * ibuf->x + x)); switch (ibuf->channels) { case 4: @@ -1431,8 +1431,8 @@ void BKE_histogram_update_sample_line(Histogram *hist, hist->data_b[i] = rgba[2]; hist->data_a[i] = rgba[3]; } - else if (ibuf->rect) { - cp = (uchar *)(ibuf->rect + y * ibuf->x + x); + else if (ibuf->byte_buffer.data) { + cp = ibuf->byte_buffer.data + 4 * (y * ibuf->x + x); hist->data_luma[i] = (float)IMB_colormanagement_get_luminance_byte(cp) / 255.0f; hist->data_r[i] = (float)cp[0] / 255.0f; hist->data_g[i] = (float)cp[1] / 255.0f; @@ -1492,10 +1492,10 @@ static void scopes_update_cb(void *__restrict userdata, const int savedlines = y / rows_per_sample_line; const bool do_sample_line = (savedlines < scopes->sample_lines) && (y % rows_per_sample_line) == 0; - const bool is_float = (ibuf->rect_float != NULL); + const bool is_float = (ibuf->float_buffer.data != NULL); if (is_float) { - rf = ibuf->rect_float + ((size_t)y) * ibuf->x * ibuf->channels; + rf = ibuf->float_buffer.data + ((size_t)y) * ibuf->x * ibuf->channels; } else { rc = display_buffer + ((size_t)y) * ibuf->x * ibuf->channels; @@ -1616,7 +1616,7 @@ void BKE_scopes_update(Scopes *scopes, void *cache_handle = NULL; struct ColormanageProcessor *cm_processor = NULL; - if (ibuf->rect == NULL && ibuf->rect_float == NULL) { + if (ibuf->byte_buffer.data == NULL && ibuf->float_buffer.data == NULL) { return; } @@ -1692,7 +1692,7 @@ void BKE_scopes_update(Scopes *scopes, scopes->vecscope = MEM_callocN(scopes->waveform_tot * 2 * sizeof(float), "vectorscope point channel"); - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings); } else { diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc index fc3829b422c..f91b60c9057 100644 --- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc +++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc @@ -770,7 +770,7 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, mesh->tag_loose_verts_none(); if (!offsets.any_single_point_profile) { /* If there are no single point profiles, every combination will have faces. */ - mesh->loose_edges_tag_none(); + mesh->tag_loose_edges_none(); } } diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index 2e188eae1a0..ac66a098f29 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -1167,29 +1167,6 @@ static void layerDefault_origindex(void *data, const int count) copy_vn_i((int *)data, count, ORIGINDEX_NONE); } -static void layerInterp_bweight(const void **sources, - const float *weights, - const float * /*sub_weights*/, - int count, - void *dest) -{ - float **in = (float **)sources; - - if (count <= 0) { - return; - } - - float f = 0.0f; - - for (int i = 0; i < count; i++) { - const float interp_weight = weights[i]; - f += *in[i] * interp_weight; - } - - /* Delay writing to the destination in case dest is in sources. */ - *((float *)dest) = f; -} - static void layerInterp_shapekey(const void **sources, const float *weights, const float * /*sub_weights*/, @@ -1786,8 +1763,8 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { {sizeof(int), "", 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}, /* 28: CD_SHAPEKEY */ {sizeof(float[3]), "", 0, N_("ShapeKey"), nullptr, nullptr, layerInterp_shapekey}, - /* 29: CD_BWEIGHT */ - {sizeof(MFloatProperty), "MFloatProperty", 1, nullptr, nullptr, nullptr, layerInterp_bweight}, + /* 29: CD_BWEIGHT */ /* DEPRECATED*/ + {sizeof(MFloatProperty), "MFloatProperty", 1}, /* 30: CD_CREASE */ {sizeof(float), "", 0, nullptr, nullptr, nullptr, layerInterp_propFloat}, /* 31: CD_ORIGSPACE_MLOOP */ @@ -2043,9 +2020,9 @@ const CustomData_MeshMasks CD_MASK_BAREMESH_ORIGINDEX = { }; const CustomData_MeshMasks CD_MASK_MESH = { /*vmask*/ (CD_MASK_PROP_FLOAT3 | CD_MASK_MDEFORMVERT | CD_MASK_MVERT_SKIN | - CD_MASK_PAINT_MASK | CD_MASK_PROP_ALL | CD_MASK_CREASE | CD_MASK_BWEIGHT), + CD_MASK_PAINT_MASK | CD_MASK_PROP_ALL | CD_MASK_CREASE), /*emask*/ - (CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL | CD_MASK_BWEIGHT | CD_MASK_CREASE), + (CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL | CD_MASK_CREASE), /*fmask*/ 0, /*pmask*/ (CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL), @@ -2055,10 +2032,9 @@ const CustomData_MeshMasks CD_MASK_MESH = { const CustomData_MeshMasks CD_MASK_DERIVEDMESH = { /*vmask*/ (CD_MASK_ORIGINDEX | CD_MASK_MDEFORMVERT | CD_MASK_SHAPEKEY | CD_MASK_MVERT_SKIN | CD_MASK_PAINT_MASK | CD_MASK_ORCO | CD_MASK_CLOTH_ORCO | CD_MASK_PROP_ALL | - CD_MASK_CREASE | CD_MASK_BWEIGHT), + CD_MASK_CREASE), /*emask*/ - (CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_EDGE | CD_MASK_BWEIGHT | CD_MASK_PROP_ALL | - CD_MASK_CREASE), + (CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL | CD_MASK_CREASE), /*fmask*/ (CD_MASK_ORIGINDEX | CD_MASK_ORIGSPACE | CD_MASK_PREVIEW_MCOL | CD_MASK_TANGENT), /*pmask*/ (CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL), @@ -2067,9 +2043,9 @@ const CustomData_MeshMasks CD_MASK_DERIVEDMESH = { CD_MASK_PROP_ALL), /* XXX: MISSING #CD_MASK_MLOOPTANGENT ? */ }; const CustomData_MeshMasks CD_MASK_BMESH = { - /*vmask*/ (CD_MASK_MDEFORMVERT | CD_MASK_BWEIGHT | CD_MASK_MVERT_SKIN | CD_MASK_SHAPEKEY | + /*vmask*/ (CD_MASK_MDEFORMVERT | CD_MASK_MVERT_SKIN | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_PAINT_MASK | CD_MASK_PROP_ALL | CD_MASK_CREASE), - /*emask*/ (CD_MASK_BWEIGHT | CD_MASK_CREASE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL), + /*emask*/ (CD_MASK_CREASE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL), /*fmask*/ 0, /*pmask*/ (CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL), @@ -2077,12 +2053,12 @@ const CustomData_MeshMasks CD_MASK_BMESH = { (CD_MASK_MDISPS | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), }; const CustomData_MeshMasks CD_MASK_EVERYTHING = { - /*vmask*/ (CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_MDEFORMVERT | CD_MASK_BWEIGHT | + /*vmask*/ (CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_MDEFORMVERT | CD_MASK_MVERT_SKIN | CD_MASK_ORCO | CD_MASK_CLOTH_ORCO | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_PAINT_MASK | CD_MASK_PROP_ALL | CD_MASK_CREASE), /*emask*/ - (CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_BWEIGHT | CD_MASK_CREASE | - CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL), + (CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_CREASE | CD_MASK_FREESTYLE_EDGE | + CD_MASK_PROP_ALL), /*fmask*/ (CD_MASK_MFACE | CD_MASK_ORIGINDEX | CD_MASK_NORMAL | CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_ORIGSPACE | CD_MASK_TANGENT | CD_MASK_TESSLOOPNORMAL | CD_MASK_PREVIEW_MCOL | @@ -3176,6 +3152,13 @@ void CustomData_free_layers(CustomData *data, const eCustomDataType type, const } } +bool CustomData_has_layer_named(const CustomData *data, + const eCustomDataType type, + const char *name) +{ + return CustomData_get_named_layer_index(data, type, name) != -1; +} + bool CustomData_has_layer(const CustomData *data, const eCustomDataType type) { return (CustomData_get_layer_index(data, type) != -1); @@ -5181,9 +5164,6 @@ void CustomData_blend_write(BlendWriter *writer, case CD_PAINT_MASK: BLO_write_raw(writer, sizeof(float) * count, static_cast(layer.data)); break; - case CD_SCULPT_FACE_SETS: - BLO_write_raw(writer, sizeof(float) * count, static_cast(layer.data)); - break; case CD_GRID_PAINT_MASK: write_grid_paint_mask(writer, count, static_cast(layer.data)); break; diff --git a/source/blender/blenkernel/intern/data_transfer.cc b/source/blender/blenkernel/intern/data_transfer.cc index 3e19f1f550d..e99a8f1d7ae 100644 --- a/source/blender/blenkernel/intern/data_transfer.cc +++ b/source/blender/blenkernel/intern/data_transfer.cc @@ -193,7 +193,7 @@ int BKE_object_data_transfer_dttype_to_cdtype(const int dtdata_type) case DT_TYPE_SKIN: return CD_MVERT_SKIN; case DT_TYPE_BWEIGHT_VERT: - return CD_BWEIGHT; + return CD_FAKE_BWEIGHT; case DT_TYPE_SHARP_EDGE: return CD_FAKE_SHARP; @@ -202,7 +202,7 @@ int BKE_object_data_transfer_dttype_to_cdtype(const int dtdata_type) case DT_TYPE_CREASE: return CD_CREASE; case DT_TYPE_BWEIGHT_EDGE: - return CD_BWEIGHT; + return CD_FAKE_BWEIGHT; case DT_TYPE_FREESTYLE_EDGE: return CD_FREESTYLE_EDGE; @@ -611,7 +611,7 @@ static bool data_transfer_layersmapping_cdlayers_multisrc_to_dst(ListBase *r_map bool *data_dst_to_delete = nullptr; if (!use_layers_src) { - /* No source at all, we can only delete all dest if requested... */ + /* No source at all, we can only delete all destination if requested. */ if (use_delete) { idx_dst = tot_dst; while (idx_dst--) { @@ -977,6 +977,24 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, * since we can't access them from mesh vertices :/ */ return false; } + if (r_map && cddata_type == CD_FAKE_BWEIGHT) { + if (!CustomData_get_layer_named(&me_dst->vdata, CD_PROP_FLOAT, "bevel_weight_vert")) { + CustomData_add_layer_named( + &me_dst->vdata, CD_PROP_FLOAT, CD_SET_DEFAULT, me_dst->totvert, "bevel_weight_vert"); + } + data_transfer_layersmapping_add_item_cd( + r_map, + CD_PROP_FLOAT, + mix_mode, + mix_factor, + mix_weights, + CustomData_get_layer_named(&me_src->vdata, CD_PROP_FLOAT, "bevel_weight_vert"), + CustomData_get_layer_named_for_write( + &me_dst->vdata, CD_PROP_FLOAT, "bevel_weight_vert", me_dst->totvert), + interp, + interp_data); + return true; + } } else if (elem_type == ME_EDGE) { if (!(cddata_type & CD_FAKE)) { /* Unused for edges, currently... */ @@ -1004,7 +1022,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, return true; } if (r_map && cddata_type == CD_FAKE_SEAM) { - if (!CustomData_get_layer_named(&me_dst->edata, CD_PROP_BOOL, ".uv_seam")) { + if (!CustomData_has_layer_named(&me_dst->edata, CD_PROP_BOOL, ".uv_seam")) { CustomData_add_layer_named( &me_dst->edata, CD_PROP_BOOL, CD_SET_DEFAULT, me_dst->totedge, ".uv_seam"); } @@ -1022,7 +1040,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, return true; } if (r_map && cddata_type == CD_FAKE_SHARP) { - if (!CustomData_get_layer_named(&me_dst->edata, CD_PROP_BOOL, "sharp_edge")) { + if (!CustomData_has_layer_named(&me_dst->edata, CD_PROP_BOOL, "sharp_edge")) { CustomData_add_layer_named( &me_dst->edata, CD_PROP_BOOL, CD_SET_DEFAULT, me_dst->totedge, "sharp_edge"); } @@ -1039,6 +1057,25 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, interp_data); return true; } + if (r_map && cddata_type == CD_FAKE_BWEIGHT) { + if (!CustomData_get_layer_named(&me_dst->edata, CD_PROP_FLOAT, "bevel_weight_edge")) { + CustomData_add_layer_named( + &me_dst->edata, CD_PROP_FLOAT, CD_SET_DEFAULT, me_dst->totedge, "bevel_weight_edge"); + } + data_transfer_layersmapping_add_item_cd( + r_map, + CD_PROP_FLOAT, + mix_mode, + mix_factor, + mix_weights, + CustomData_get_layer_named(&me_src->edata, CD_PROP_FLOAT, "bevel_weight_edge"), + CustomData_get_layer_named_for_write( + &me_dst->edata, CD_PROP_FLOAT, "bevel_weight_edge", me_dst->totedge), + interp, + interp_data); + return true; + } + return false; } else if (elem_type == ME_LOOP) { @@ -1110,7 +1147,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, return true; } if (r_map && cddata_type == CD_FAKE_SHARP) { - if (!CustomData_get_layer_named(&me_dst->pdata, CD_PROP_BOOL, "sharp_face")) { + if (!CustomData_has_layer_named(&me_dst->pdata, CD_PROP_BOOL, "sharp_face")) { CustomData_add_layer_named( &me_dst->pdata, CD_PROP_BOOL, CD_SET_DEFAULT, me_dst->totpoly, "sharp_face"); } @@ -1384,7 +1421,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, } /* Check all possible data types. - * Note item mappings and dest mix weights are cached. */ + * Note item mappings and destination mix weights are cached. */ for (int i = 0; i < DT_TYPE_MAX; i++) { const int dtdata_type = 1 << i; int cddata_type; diff --git a/source/blender/blenkernel/intern/dynamicpaint.cc b/source/blender/blenkernel/intern/dynamicpaint.cc index c48a161cfa6..a9124e6c5f5 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.cc +++ b/source/blender/blenkernel/intern/dynamicpaint.cc @@ -3210,12 +3210,15 @@ static void dynamic_paint_output_surface_image_paint_cb(void *__restrict userdat const int pos = ((ImgSeqFormatData *)(surface->data->format_data))->uv_p[index].pixel_index * 4; /* blend wet and dry layers */ - blendColors( - point->color, point->color[3], point->e_color, point->e_color[3], &ibuf->rect_float[pos]); + blendColors(point->color, + point->color[3], + point->e_color, + point->e_color[3], + &ibuf->float_buffer.data[pos]); /* Multiply color by alpha if enabled */ if (surface->flags & MOD_DPAINT_MULALPHA) { - mul_v3_fl(&ibuf->rect_float[pos], ibuf->rect_float[pos + 3]); + mul_v3_fl(&ibuf->float_buffer.data[pos], ibuf->float_buffer.data[pos + 3]); } } @@ -3242,8 +3245,8 @@ static void dynamic_paint_output_surface_image_displace_cb( CLAMP(depth, 0.0f, 1.0f); - copy_v3_fl(&ibuf->rect_float[pos], depth); - ibuf->rect_float[pos + 3] = 1.0f; + copy_v3_fl(&ibuf->float_buffer.data[pos], depth); + ibuf->float_buffer.data[pos + 3] = 1.0f; } static void dynamic_paint_output_surface_image_wave_cb(void *__restrict userdata, @@ -3268,8 +3271,8 @@ static void dynamic_paint_output_surface_image_wave_cb(void *__restrict userdata depth = (0.5f + depth / 2.0f); CLAMP(depth, 0.0f, 1.0f); - copy_v3_fl(&ibuf->rect_float[pos], depth); - ibuf->rect_float[pos + 3] = 1.0f; + copy_v3_fl(&ibuf->float_buffer.data[pos], depth); + ibuf->float_buffer.data[pos + 3] = 1.0f; } static void dynamic_paint_output_surface_image_wetmap_cb(void *__restrict userdata, @@ -3286,8 +3289,8 @@ static void dynamic_paint_output_surface_image_wetmap_cb(void *__restrict userda /* image buffer position */ const int pos = ((ImgSeqFormatData *)(surface->data->format_data))->uv_p[index].pixel_index * 4; - copy_v3_fl(&ibuf->rect_float[pos], (point->wetness > 1.0f) ? 1.0f : point->wetness); - ibuf->rect_float[pos + 3] = 1.0f; + copy_v3_fl(&ibuf->float_buffer.data[pos], (point->wetness > 1.0f) ? 1.0f : point->wetness); + ibuf->float_buffer.data[pos + 3] = 1.0f; } void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface, diff --git a/source/blender/blenkernel/intern/geometry_set_instances.cc b/source/blender/blenkernel/intern/geometry_set_instances.cc index e99efc19276..8b1e32230b3 100644 --- a/source/blender/blenkernel/intern/geometry_set_instances.cc +++ b/source/blender/blenkernel/intern/geometry_set_instances.cc @@ -3,28 +3,16 @@ #include "BKE_collection.h" #include "BKE_geometry_set_instances.hh" #include "BKE_instances.hh" -#include "BKE_material.h" #include "BKE_mesh.hh" #include "BKE_mesh_wrapper.h" #include "BKE_modifier.h" -#include "BKE_pointcloud.h" #include "DNA_collection_types.h" #include "DNA_layer_types.h" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" #include "DNA_object_types.h" namespace blender::bke { -static void geometry_set_collect_recursive(const GeometrySet &geometry_set, - const float4x4 &transform, - Vector &r_sets); - -static void geometry_set_collect_recursive_collection(const Collection &collection, - const float4x4 &transform, - Vector &r_sets); - static void add_final_mesh_as_geometry_component(const Object &object, GeometrySet &geometry_set) { Mesh *mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object( @@ -74,87 +62,6 @@ GeometrySet object_get_evaluated_geometry_set(const Object &object) return {}; } -static void geometry_set_collect_recursive_collection_instance( - const Collection &collection, const float4x4 &transform, Vector &r_sets) -{ - float4x4 offset_matrix = float4x4::identity(); - offset_matrix.location() -= float3(collection.instance_offset); - const float4x4 instance_transform = transform * offset_matrix; - geometry_set_collect_recursive_collection(collection, instance_transform, r_sets); -} - -static void geometry_set_collect_recursive_object(const Object &object, - const float4x4 &transform, - Vector &r_sets) -{ - GeometrySet instance_geometry_set = object_get_evaluated_geometry_set(object); - geometry_set_collect_recursive(instance_geometry_set, transform, r_sets); -} - -static void geometry_set_collect_recursive_collection(const Collection &collection, - const float4x4 &transform, - Vector &r_sets) -{ - LISTBASE_FOREACH (const CollectionObject *, collection_object, &collection.gobject) { - BLI_assert(collection_object->ob != nullptr); - const Object &object = *collection_object->ob; - const float4x4 object_transform = transform * float4x4_view(object.object_to_world); - geometry_set_collect_recursive_object(object, object_transform, r_sets); - } - LISTBASE_FOREACH (const CollectionChild *, collection_child, &collection.children) { - BLI_assert(collection_child->collection != nullptr); - const Collection &collection = *collection_child->collection; - geometry_set_collect_recursive_collection(collection, transform, r_sets); - } -} - -static void geometry_set_collect_recursive(const GeometrySet &geometry_set, - const float4x4 &transform, - Vector &r_sets) -{ - r_sets.append({geometry_set, {transform}}); - - if (geometry_set.has_instances()) { - const Instances &instances = *geometry_set.get_instances_for_read(); - - Span transforms = instances.transforms(); - Span handles = instances.reference_handles(); - Span references = instances.references(); - for (const int i : transforms.index_range()) { - const InstanceReference &reference = references[handles[i]]; - const float4x4 instance_transform = transform * transforms[i]; - - switch (reference.type()) { - case InstanceReference::Type::Object: { - Object &object = reference.object(); - geometry_set_collect_recursive_object(object, instance_transform, r_sets); - break; - } - case InstanceReference::Type::Collection: { - Collection &collection = reference.collection(); - geometry_set_collect_recursive_collection_instance( - collection, instance_transform, r_sets); - break; - } - case InstanceReference::Type::GeometrySet: { - const GeometrySet &geometry_set = reference.geometry_set(); - geometry_set_collect_recursive(geometry_set, instance_transform, r_sets); - break; - } - case InstanceReference::Type::None: { - break; - } - } - } - } -} - -void geometry_set_gather_instances(const GeometrySet &geometry_set, - Vector &r_instance_groups) -{ - geometry_set_collect_recursive(geometry_set, float4x4::identity(), r_instance_groups); -} - void Instances::foreach_referenced_geometry( blender::FunctionRef callback) const { diff --git a/source/blender/blenkernel/intern/gpencil_legacy.c b/source/blender/blenkernel/intern/gpencil_legacy.c index f721a753e24..45b11600128 100644 --- a/source/blender/blenkernel/intern/gpencil_legacy.c +++ b/source/blender/blenkernel/intern/gpencil_legacy.c @@ -2221,8 +2221,7 @@ int BKE_gpencil_object_material_index_get_by_name(Object *ob, const char *name) Material *read_ma = NULL; for (short i = 0; i < *totcol; i++) { read_ma = BKE_object_material_get(ob, i + 1); - /* Material names are like "MAMaterial.001" */ - if (STREQ(name, &read_ma->id.name[2])) { + if (STREQ(name, read_ma->id.name + 2)) { return i; } } @@ -2308,7 +2307,7 @@ bool BKE_gpencil_from_image( ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock); - if (ibuf && ibuf->rect) { + if (ibuf && ibuf->byte_buffer.data) { int img_x = ibuf->x; int img_y = ibuf->y; diff --git a/source/blender/blenkernel/intern/icons.cc b/source/blender/blenkernel/intern/icons.cc index 4c69e650be8..32043717e3e 100644 --- a/source/blender/blenkernel/intern/icons.cc +++ b/source/blender/blenkernel/intern/icons.cc @@ -552,7 +552,7 @@ void BKE_previewimg_ensure(PreviewImage *prv, const int size) if (do_preview) { prv->w[ICON_SIZE_PREVIEW] = thumb->x; prv->h[ICON_SIZE_PREVIEW] = thumb->y; - prv->rect[ICON_SIZE_PREVIEW] = (uint *)MEM_dupallocN(thumb->rect); + prv->rect[ICON_SIZE_PREVIEW] = (uint *)MEM_dupallocN(thumb->byte_buffer.data); prv->flag[ICON_SIZE_PREVIEW] &= ~(PRV_CHANGED | PRV_USER_EDITED | PRV_RENDERING); } if (do_icon) { @@ -571,7 +571,7 @@ void BKE_previewimg_ensure(PreviewImage *prv, const int size) IMB_scaleImBuf(thumb, icon_w, icon_h); prv->w[ICON_SIZE_ICON] = icon_w; prv->h[ICON_SIZE_ICON] = icon_h; - prv->rect[ICON_SIZE_ICON] = (uint *)MEM_dupallocN(thumb->rect); + prv->rect[ICON_SIZE_ICON] = (uint *)MEM_dupallocN(thumb->byte_buffer.data); prv->flag[ICON_SIZE_ICON] &= ~(PRV_CHANGED | PRV_USER_EDITED | PRV_RENDERING); } IMB_freeImBuf(thumb); @@ -588,7 +588,7 @@ ImBuf *BKE_previewimg_to_imbuf(PreviewImage *prv, const int size) if (w > 0 && h > 0 && rect) { /* first allocate imbuf for copying preview into it */ ima = IMB_allocImBuf(w, h, 32, IB_rect); - memcpy(ima->rect, rect, w * h * sizeof(*ima->rect)); + memcpy(ima->byte_buffer.data, rect, w * h * sizeof(uint8_t) * 4); } return ima; diff --git a/source/blender/blenkernel/intern/icons_rasterize.c b/source/blender/blenkernel/intern/icons_rasterize.c index ea19d3527c3..f26123fd923 100644 --- a/source/blender/blenkernel/intern/icons_rasterize.c +++ b/source/blender/blenkernel/intern/icons_rasterize.c @@ -85,7 +85,7 @@ ImBuf *BKE_icon_geom_rasterize(const struct Icon_Geom *geom, const uint size_x, data.rect_size[0] = rect_size[0]; data.rect_size[1] = rect_size[1]; - data.rect = ibuf->rect; + data.rect = (uint *)ibuf->byte_buffer.data; float scale[2]; const bool use_scale = (rect_size[0] != 256) || (rect_size[1] != 256); diff --git a/source/blender/blenkernel/intern/image.cc b/source/blender/blenkernel/intern/image.cc index 61f09f84a51..19a00ac977c 100644 --- a/source/blender/blenkernel/intern/image.cc +++ b/source/blender/blenkernel/intern/image.cc @@ -1138,7 +1138,7 @@ static ImBuf *add_ibuf_for_tile(Image *ima, ImageTile *tile) } if (ibuf != nullptr) { - rect_float = ibuf->rect_float; + rect_float = ibuf->float_buffer.data; IMB_colormanagement_check_is_data(ibuf, ima->colorspace_settings.name); } @@ -1162,7 +1162,7 @@ static ImBuf *add_ibuf_for_tile(Image *ima, ImageTile *tile) } if (ibuf != nullptr) { - rect = (uchar *)ibuf->rect; + rect = ibuf->byte_buffer.data; IMB_colormanagement_assign_rect_colorspace(ibuf, ima->colorspace_settings.name); } @@ -1261,7 +1261,7 @@ static void image_colorspace_from_imbuf(Image *image, const ImBuf *ibuf) { const char *colorspace_name = nullptr; - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { if (ibuf->float_colorspace) { colorspace_name = IMB_colormanagement_colorspace_get_name(ibuf->float_colorspace); } @@ -1270,7 +1270,7 @@ static void image_colorspace_from_imbuf(Image *image, const ImBuf *ibuf) } } - if (ibuf->rect && !colorspace_name) { + if (ibuf->byte_buffer.data && !colorspace_name) { if (ibuf->rect_colorspace) { colorspace_name = IMB_colormanagement_colorspace_get_name(ibuf->rect_colorspace); } @@ -1318,7 +1318,7 @@ void BKE_image_replace_imbuf(Image *image, ImBuf *ibuf) /* Keep generated image type flags consistent with the image buffer. */ if (image->source == IMA_SRC_GENERATED) { - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { image->gen_flag |= IMA_GEN_FLOAT; } else { @@ -1338,11 +1338,11 @@ void BKE_image_replace_imbuf(Image *image, ImBuf *ibuf) static bool image_memorypack_imbuf( Image *ima, ImBuf *ibuf, int view, int tile_number, const char *filepath) { - ibuf->ftype = (ibuf->rect_float) ? IMB_FTYPE_OPENEXR : IMB_FTYPE_PNG; + ibuf->ftype = (ibuf->float_buffer.data) ? IMB_FTYPE_OPENEXR : IMB_FTYPE_PNG; IMB_saveiff(ibuf, filepath, IB_rect | IB_mem); - if (ibuf->encodedbuffer == nullptr) { + if (ibuf->encoded_buffer.data == nullptr) { CLOG_STR_ERROR(&LOG, "memory save for pack error"); IMB_freeImBuf(ibuf); image_free_packedfiles(ima); @@ -1352,8 +1352,8 @@ static bool image_memorypack_imbuf( ImagePackedFile *imapf; PackedFile *pf = MEM_cnew("PackedFile"); - pf->data = ibuf->encodedbuffer; - pf->size = ibuf->encodedsize; + pf->data = IMB_steal_encoded_buffer(ibuf); + pf->size = ibuf->encoded_size; imapf = static_cast(MEM_mallocN(sizeof(ImagePackedFile), "Image PackedFile")); STRNCPY(imapf->filepath, filepath); @@ -1362,8 +1362,6 @@ static bool image_memorypack_imbuf( imapf->tile_number = tile_number; BLI_addtail(&ima->packedfiles, imapf); - ibuf->encodedbuffer = nullptr; - ibuf->encodedsize = 0; ibuf->userflags &= ~IB_BITMAPDIRTY; return true; @@ -1505,26 +1503,12 @@ static uintptr_t image_mem_size(Image *image) if (ibuf == nullptr) { continue; } - ImBuf *ibufm; - int level; - if (ibuf->rect) { - size += MEM_allocN_len(ibuf->rect); - } - if (ibuf->rect_float) { - size += MEM_allocN_len(ibuf->rect_float); - } + size += IMB_get_size_in_memory(ibuf); - for (level = 0; level < IMB_MIPMAP_LEVELS; level++) { - ibufm = ibuf->mipmap[level]; - if (ibufm) { - if (ibufm->rect) { - size += MEM_allocN_len(ibufm->rect); - } - if (ibufm->rect_float) { - size += MEM_allocN_len(ibufm->rect_float); - } - } + for (int level = 0; level < IMB_MIPMAP_LEVELS; level++) { + ImBuf *ibufm = ibuf->mipmap[level]; + size += IMB_get_size_in_memory(ibufm); } } IMB_moviecacheIter_free(iter); @@ -2537,16 +2521,16 @@ void BKE_stamp_info_from_imbuf(RenderResult *rr, ImBuf *ibuf) bool BKE_imbuf_alpha_test(ImBuf *ibuf) { int tot; - if (ibuf->rect_float) { - const float *buf = ibuf->rect_float; + if (ibuf->float_buffer.data) { + const float *buf = ibuf->float_buffer.data; for (tot = ibuf->x * ibuf->y; tot--; buf += 4) { if (buf[3] < 1.0f) { return true; } } } - else if (ibuf->rect) { - uchar *buf = (uchar *)ibuf->rect; + else if (ibuf->byte_buffer.data) { + uchar *buf = ibuf->byte_buffer.data; for (tot = ibuf->x * ibuf->y; tot--; buf += 4) { if (buf[3] != 255) { return true; @@ -4007,9 +3991,8 @@ static ImBuf *image_load_sequence_multilayer(Image *ima, ImageUser *iuser, int e // printf("load from pass %s\n", rpass->name); /* since we free render results, we copy the rect */ ibuf = IMB_allocImBuf(ima->rr->rectx, ima->rr->recty, 32, 0); - ibuf->rect_float = static_cast(MEM_dupallocN(rpass->rect)); - ibuf->flags |= IB_rectfloat; - ibuf->mall = IB_rectfloat; + IMB_assign_float_buffer( + ibuf, static_cast(MEM_dupallocN(rpass->rect)), IB_TAKE_OWNERSHIP); ibuf->channels = rpass->channels; BKE_imbuf_stamp_info(ima->rr, ibuf); @@ -4318,8 +4301,7 @@ static ImBuf *image_get_ibuf_multilayer(Image *ima, ImageUser *iuser) image_init_after_load(ima, iuser, ibuf); - ibuf->rect_float = rpass->rect; - ibuf->flags |= IB_rectfloat; + IMB_assign_float_buffer(ibuf, rpass->rect, IB_DO_NOT_TAKE_OWNERSHIP); ibuf->channels = rpass->channels; BKE_imbuf_stamp_info(ima->rr, ibuf); @@ -4459,56 +4441,29 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **r_loc * * For other cases we need to be sure it stays to default byte buffer space. */ - if (ibuf->rect != rect) { + if (ibuf->byte_buffer.data != (uint8_t *)rect) { const char *colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_BYTE); IMB_colormanagement_assign_rect_colorspace(ibuf, colorspace); } /* invalidate color managed buffers if render result changed */ BLI_thread_lock(LOCK_COLORMANAGE); - if (ibuf->x != rres.rectx || ibuf->y != rres.recty || ibuf->rect_float != rectf) { + if (ibuf->x != rres.rectx || ibuf->y != rres.recty || ibuf->float_buffer.data != rectf) { ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; } ibuf->x = rres.rectx; ibuf->y = rres.recty; + ibuf->channels = channels; - if (rect) { - imb_freerectImBuf(ibuf); - ibuf->rect = rect; - } - else { - /* byte buffer of render result has been freed, make sure image buffers - * does not reference to this buffer anymore - * need check for whether byte buffer was allocated and owned by image itself - * or if it's reusing buffer from render result - */ - if ((ibuf->mall & IB_rect) == 0) { - ibuf->rect = nullptr; - } - } + imb_freerectImBuf(ibuf); - if (rectf) { - ibuf->rect_float = rectf; - ibuf->flags |= IB_rectfloat; - ibuf->channels = channels; - } - else { - ibuf->rect_float = nullptr; - ibuf->flags &= ~IB_rectfloat; - } - - if (rectz) { - ibuf->zbuf_float = rectz; - ibuf->flags |= IB_zbuffloat; - } - else { - ibuf->zbuf_float = nullptr; - ibuf->flags &= ~IB_zbuffloat; - } + IMB_assign_byte_buffer(ibuf, (uint8_t *)rect, IB_DO_NOT_TAKE_OWNERSHIP); + IMB_assign_float_buffer(ibuf, rectf, IB_DO_NOT_TAKE_OWNERSHIP); + IMB_assign_float_z_buffer(ibuf, rectz, IB_DO_NOT_TAKE_OWNERSHIP); /* TODO(sergey): Make this faster by either simply referencing the stamp - * or by changing both ImBug and RenderResult to use same data type to + * or by changing both ImBuf and RenderResult to use same data type to * store metadata. */ if (ibuf->metadata != nullptr) { IMB_metadata_free(ibuf->metadata); @@ -5269,7 +5224,7 @@ uchar *BKE_image_get_pixels_for_frame(struct Image *image, int frame, int tile) ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock); if (ibuf) { - pixels = (uchar *)ibuf->rect; + pixels = ibuf->byte_buffer.data; if (pixels) { pixels = static_cast(MEM_dupallocN(pixels)); @@ -5299,7 +5254,7 @@ float *BKE_image_get_float_pixels_for_frame(struct Image *image, int frame, int ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock); if (ibuf) { - pixels = ibuf->rect_float; + pixels = ibuf->float_buffer.data; if (pixels) { pixels = static_cast(MEM_dupallocN(pixels)); diff --git a/source/blender/blenkernel/intern/image_format.cc b/source/blender/blenkernel/intern/image_format.cc index fc735294d37..2ef2ae4a0e0 100644 --- a/source/blender/blenkernel/intern/image_format.cc +++ b/source/blender/blenkernel/intern/image_format.cc @@ -799,7 +799,7 @@ void BKE_image_format_from_imbuf(ImageFormatData *im_format, const ImBuf *imbuf) if (custom_flags & OPENEXR_COMPRESS) { im_format->exr_codec = R_IMF_EXR_CODEC_ZIP; /* Can't determine compression */ } - if (imbuf->zbuf_float) { + if (imbuf->float_z_buffer.data) { im_format->flag |= R_IMF_FLAG_ZBUF; } } diff --git a/source/blender/blenkernel/intern/image_gpu.cc b/source/blender/blenkernel/intern/image_gpu.cc index 9ac513f310b..1b48541cd52 100644 --- a/source/blender/blenkernel/intern/image_gpu.cc +++ b/source/blender/blenkernel/intern/image_gpu.cc @@ -50,11 +50,11 @@ bool BKE_image_has_gpu_texture_premultiplied_alpha(Image *image, ImBuf *ibuf) } /* Generated images use pre multiplied float buffer, but straight alpha for byte buffers. */ if (image->type == IMA_TYPE_UV_TEST && ibuf) { - return ibuf->rect_float != nullptr; + return ibuf->float_buffer.data != nullptr; } } if (ibuf) { - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { return image ? (image->alpha_mode != IMA_ALPHA_STRAIGHT) : false; } @@ -643,7 +643,7 @@ static ImBuf *update_do_scale(uchar *rect, } /* Scale pixels. */ - ImBuf *ibuf = IMB_allocFromBuffer((uint *)rect, rect_float, part_w, part_h, 4); + ImBuf *ibuf = IMB_allocFromBuffer(rect, rect_float, part_w, part_h, 4); IMB_scaleImBuf(ibuf, *w, *h); return ibuf; @@ -679,8 +679,9 @@ static void gpu_texture_update_scaled(GPUTexture *tex, ibuf = update_do_scale(rect, rect_float, &x, &y, &w, &h, limit_w, limit_h, full_w, full_h); } - void *data = (ibuf->rect_float) ? (void *)(ibuf->rect_float) : (void *)(ibuf->rect); - eGPUDataFormat data_format = (ibuf->rect_float) ? GPU_DATA_FLOAT : GPU_DATA_UBYTE; + void *data = (ibuf->float_buffer.data) ? (void *)(ibuf->float_buffer.data) : + (void *)(ibuf->byte_buffer.data); + eGPUDataFormat data_format = (ibuf->float_buffer.data) ? GPU_DATA_FLOAT : GPU_DATA_UBYTE; GPU_texture_update_sub(tex, data_format, data, x, y, layer, w, h, 1); @@ -742,8 +743,8 @@ static void gpu_texture_update_from_ibuf( } /* Get texture data pointers. */ - float *rect_float = ibuf->rect_float; - uchar *rect = (uchar *)ibuf->rect; + float *rect_float = ibuf->float_buffer.data; + uchar *rect = ibuf->byte_buffer.data; int tex_stride = ibuf->x; int tex_offset = ibuf->channels * (y * ibuf->x + x); @@ -832,10 +833,10 @@ static void gpu_texture_update_from_ibuf( } /* Free buffers if needed. */ - if (rect && rect != (uchar *)ibuf->rect) { + if (rect && rect != ibuf->byte_buffer.data) { MEM_freeN(rect); } - if (rect_float && rect_float != ibuf->rect_float) { + if (rect_float && rect_float != ibuf->float_buffer.data) { MEM_freeN(rect_float); } diff --git a/source/blender/blenkernel/intern/image_save.cc b/source/blender/blenkernel/intern/image_save.cc index 9f669d17395..b0ee3f729a8 100644 --- a/source/blender/blenkernel/intern/image_save.cc +++ b/source/blender/blenkernel/intern/image_save.cc @@ -42,7 +42,7 @@ static char imtype_best_depth(ImBuf *ibuf, const char imtype) { const char depth_ok = BKE_imtype_valid_depths(imtype); - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { if (depth_ok & R_IMF_CHAN_DEPTH_32) { return R_IMF_CHAN_DEPTH_32; } @@ -298,18 +298,10 @@ static void image_save_post(ReportList *reports, /* workaround to ensure the render result buffer is no longer used * by this image, otherwise can crash when a new render result is * created. */ - if (ibuf->rect && !(ibuf->mall & IB_rect)) { - imb_freerectImBuf(ibuf); - } - if (ibuf->rect_float && !(ibuf->mall & IB_rectfloat)) { - imb_freerectfloatImBuf(ibuf); - } - if (ibuf->zbuf && !(ibuf->mall & IB_zbuf)) { - IMB_freezbufImBuf(ibuf); - } - if (ibuf->zbuf_float && !(ibuf->mall & IB_zbuffloat)) { - IMB_freezbuffloatImBuf(ibuf); - } + imb_freerectImBuf(ibuf); + imb_freerectfloatImBuf(ibuf); + IMB_freezbufImBuf(ibuf); + IMB_freezbuffloatImBuf(ibuf); } if (ELEM(ima->source, IMA_SRC_GENERATED, IMA_SRC_VIEWER)) { ima->source = IMA_SRC_FILE; @@ -365,7 +357,8 @@ static bool image_save_single(ReportList *reports, RenderResult *rr = nullptr; bool ok = false; - if (ibuf == nullptr || (ibuf->rect == nullptr && ibuf->rect_float == nullptr)) { + if (ibuf == nullptr || (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data == nullptr)) + { BKE_image_release_ibuf(ima, ibuf, lock); return ok; } diff --git a/source/blender/blenkernel/intern/layer.cc b/source/blender/blenkernel/intern/layer.cc index fbebe8a19d2..8251951647a 100644 --- a/source/blender/blenkernel/intern/layer.cc +++ b/source/blender/blenkernel/intern/layer.cc @@ -1006,7 +1006,7 @@ void BKE_main_view_layers_synced_ensure(const Main *bmain) BKE_scene_view_layers_synced_ensure(scene); } - /* NOTE: This is not (yet?) covered by the dirty tag and deffered re-sync system. */ + /* NOTE: This is not (yet?) covered by the dirty tag and deferred re-sync system. */ BKE_layer_collection_local_sync_all(bmain); } diff --git a/source/blender/blenkernel/intern/lib_override.cc b/source/blender/blenkernel/intern/lib_override.cc index 75adcdb0eda..859c7b44106 100644 --- a/source/blender/blenkernel/intern/lib_override.cc +++ b/source/blender/blenkernel/intern/lib_override.cc @@ -198,8 +198,9 @@ void BKE_lib_override_library_copy(ID *dst_id, const ID *src_id, const bool do_f BKE_lib_override_library_init(dst_id, nullptr); } - /* If source is already overriding data, we copy it but reuse its reference for dest ID. - * Otherwise, source is only an override template, it then becomes reference of dest ID. */ + /* If source is already overriding data, we copy it but reuse its reference for destination ID. + * Otherwise, source is only an override template, it then becomes reference of destination ID. + */ dst_id->override_library->reference = src_id->override_library->reference ? src_id->override_library->reference : const_cast(src_id); @@ -1776,7 +1777,7 @@ static void lib_override_library_remap(Main *bmain, * * In case linked data keep being modified, these conditions may fail and the mapping may start to * return 'wrong' results. However, this is considered as an acceptable limitation here, since this - * is mainly a 'best effort' to recover from situations that should not be hapenning in the first + * is mainly a 'best effort' to recover from situations that should not be happening in the first * place. */ @@ -2061,7 +2062,7 @@ static bool lib_override_library_resync(Main *bmain, } /* Get a mapping of all missing linked IDs that were liboverrides, to search for 'old - * liboverrides' for newly created ones that do not alredy have one, in next step. */ + * liboverrides' for newly created ones that do not already have one, in next step. */ LibOverrideMissingIDsData missing_ids_data = lib_override_library_resync_build_missing_ids_data( bmain); @@ -2638,7 +2639,8 @@ static bool lib_override_library_main_resync_id_skip_check(ID *id, return false; } -/* Clear 'unreachable' tag of existing liboverrides if they are using another reachable liboverride +/** + * Clear 'unreachable' tag of existing liboverrides if they are using another reachable liboverride * (typical case: Mesh object which only relationship to the rest of the liboverride hierarchy is * though its 'parent' pointer (i.e. rest of the hierarchy has no actual relationship to this mesh * object). Sadge. @@ -2646,7 +2648,8 @@ static bool lib_override_library_main_resync_id_skip_check(ID *id, * Logic and rational of this function are very similar to these of * #lib_override_hierarchy_dependencies_recursive_tag_from, but withing specific resync context. * - * \returns True if it finds a non-isolated 'parent' ID, false otherwise. */ + * \returns True if it finds a non-isolated 'parent' ID, false otherwise. + */ static bool lib_override_resync_tagging_finalize_recursive_check_from( Main *bmain, ID *id, const int library_indirect_level) { @@ -3527,6 +3530,41 @@ void lib_override_library_property_clear(IDOverrideLibraryProperty *op) BLI_freelistN(&op->operations); } +bool BKE_lib_override_library_property_search_and_delete(IDOverrideLibrary *override, + const char *rna_path) +{ + IDOverrideLibraryProperty *override_property = BKE_lib_override_library_property_find(override, + rna_path); + if (override_property == nullptr) { + return false; + } + BKE_lib_override_library_property_delete(override, override_property); + return true; +} + +bool BKE_lib_override_library_property_rna_path_change(IDOverrideLibrary *override, + const char *old_rna_path, + const char *new_rna_path) +{ + /* Find the override property by its old RNA path. */ + GHash *override_runtime = override_library_rna_path_mapping_ensure(override); + IDOverrideLibraryProperty *override_property = static_cast( + BLI_ghash_popkey(override_runtime, old_rna_path, nullptr)); + + if (override_property == nullptr) { + return false; + } + + /* Switch over the RNA path. */ + MEM_SAFE_FREE(override_property->rna_path); + override_property->rna_path = BLI_strdup(new_rna_path); + + /* Put property back into the lookup mapping, using the new RNA path. */ + BLI_ghash_insert(override_runtime, override_property->rna_path, override_property); + + return true; +} + void BKE_lib_override_library_property_delete(IDOverrideLibrary *override, IDOverrideLibraryProperty *override_property) { diff --git a/source/blender/blenkernel/intern/main.c b/source/blender/blenkernel/intern/main.c index 20f653809b5..e5b3944613b 100644 --- a/source/blender/blenkernel/intern/main.c +++ b/source/blender/blenkernel/intern/main.c @@ -523,7 +523,7 @@ BlendThumbnail *BKE_main_thumbnail_from_imbuf(Main *bmain, ImBuf *img) IMB_rect_from_float(img); /* Just in case... */ data->width = img->x; data->height = img->y; - memcpy(data->rect, img->rect, data_size - sizeof(*data)); + memcpy(data->rect, img->byte_buffer.data, data_size - sizeof(*data)); } if (bmain) { @@ -542,7 +542,7 @@ ImBuf *BKE_main_thumbnail_to_imbuf(Main *bmain, BlendThumbnail *data) if (data) { img = IMB_allocFromBuffer( - (const uint *)data->rect, NULL, (uint)data->width, (uint)data->height, 4); + (const uint8_t *)data->rect, NULL, (uint)data->width, (uint)data->height, 4); } return img; diff --git a/source/blender/blenkernel/intern/material.cc b/source/blender/blenkernel/intern/material.cc index 92f182bf5b5..56f9ac4af6e 100644 --- a/source/blender/blenkernel/intern/material.cc +++ b/source/blender/blenkernel/intern/material.cc @@ -82,6 +82,8 @@ static void material_init_data(ID *id) BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(material, id)); MEMCPY_STRUCT_AFTER(material, DNA_struct_default_get(Material), id); + + *((short *)id->name) = ID_MA; } static void material_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag) @@ -1992,14 +1994,14 @@ static Material *default_materials[] = {&default_material_empty, static void material_default_gpencil_init(Material *ma) { - strcpy(ma->id.name, "MADefault GPencil"); + BLI_strncpy(ma->id.name + 2, "Default GPencil", MAX_NAME); BKE_gpencil_material_attr_init(ma); add_v3_fl(&ma->gp_style->stroke_rgba[0], 0.6f); } static void material_default_surface_init(Material *ma) { - strcpy(ma->id.name, "MADefault Surface"); + BLI_strncpy(ma->id.name + 2, "Default Surface", MAX_NAME); bNodeTree *ntree = blender::bke::ntreeAddTreeEmbedded( nullptr, &ma->id, "Shader Nodetree", ntreeType_Shader->idname); @@ -2027,7 +2029,7 @@ static void material_default_surface_init(Material *ma) static void material_default_volume_init(Material *ma) { - strcpy(ma->id.name, "MADefault Volume"); + BLI_strncpy(ma->id.name + 2, "Default Volume", MAX_NAME); bNodeTree *ntree = blender::bke::ntreeAddTreeEmbedded( nullptr, &ma->id, "Shader Nodetree", ntreeType_Shader->idname); @@ -2052,7 +2054,7 @@ static void material_default_volume_init(Material *ma) static void material_default_holdout_init(Material *ma) { - strcpy(ma->id.name, "MADefault Holdout"); + BLI_strncpy(ma->id.name + 2, "Default Holdout", MAX_NAME); bNodeTree *ntree = blender::bke::ntreeAddTreeEmbedded( nullptr, &ma->id, "Shader Nodetree", ntreeType_Shader->idname); diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index c988d53058e..71d8c147d87 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -257,68 +257,10 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address mesh->poly_offset_indices = nullptr; } else { - Set names_to_skip; - if (!BLO_write_is_undo(writer)) { - /* When converting to the old mesh format, don't save redundant attributes. */ - names_to_skip.add_multiple_new({"position", - ".edge_verts", - ".corner_vert", - ".corner_edge", - ".hide_vert", - ".hide_edge", - ".hide_poly", - ".uv_seam", - ".select_vert", - ".select_edge", - ".select_poly", - "material_index", - "sharp_face", - "sharp_edge"}); - - mesh->mvert = BKE_mesh_legacy_convert_positions_to_verts( - mesh, temp_arrays_for_legacy_format, vert_layers); - mesh->mloop = BKE_mesh_legacy_convert_corners_to_loops( - mesh, temp_arrays_for_legacy_format, loop_layers); - mesh->medge = BKE_mesh_legacy_convert_edges_to_medge( - mesh, temp_arrays_for_legacy_format, edge_layers); - - MutableSpan legacy_polys = BKE_mesh_legacy_convert_offsets_to_polys( - mesh, temp_arrays_for_legacy_format, poly_layers); - - BKE_mesh_legacy_convert_hide_layers_to_flags(mesh, legacy_polys); - BKE_mesh_legacy_convert_selection_layers_to_flags(mesh, legacy_polys); - BKE_mesh_legacy_convert_material_indices_to_mpoly(mesh, legacy_polys); - BKE_mesh_legacy_sharp_faces_to_flags(mesh, legacy_polys); - BKE_mesh_legacy_bevel_weight_from_layers(mesh); - BKE_mesh_legacy_edge_crease_from_layers(mesh); - BKE_mesh_legacy_sharp_edges_to_flags(mesh); - BKE_mesh_legacy_uv_seam_to_flags(mesh); - BKE_mesh_legacy_attribute_strings_to_flags(mesh); - mesh->active_color_attribute = nullptr; - mesh->default_color_attribute = nullptr; - BKE_mesh_legacy_convert_loose_edges_to_flag(mesh); - mesh->poly_offset_indices = nullptr; - - /* Set deprecated mesh data pointers for forward compatibility. */ - mesh->mpoly = legacy_polys.data(); - mesh->dvert = const_cast(mesh->deform_verts().data()); - } - - CustomData_blend_write_prepare(mesh->vdata, vert_layers, names_to_skip); - CustomData_blend_write_prepare(mesh->edata, edge_layers, names_to_skip); - CustomData_blend_write_prepare(mesh->ldata, loop_layers, names_to_skip); - CustomData_blend_write_prepare(mesh->pdata, poly_layers, names_to_skip); - - if (!BLO_write_is_undo(writer)) { - /* #CustomData expects the layers to be sorted in increasing order based on type. */ - std::stable_sort( - poly_layers.begin(), - poly_layers.end(), - [](const CustomDataLayer &a, const CustomDataLayer &b) { return a.type < b.type; }); - - BKE_mesh_legacy_convert_uvs_to_struct(mesh, temp_arrays_for_legacy_format, loop_layers); - BKE_mesh_legacy_face_set_from_generic(poly_layers); - } + CustomData_blend_write_prepare(mesh->vdata, vert_layers, {}); + CustomData_blend_write_prepare(mesh->edata, edge_layers, {}); + CustomData_blend_write_prepare(mesh->ldata, loop_layers, {}); + CustomData_blend_write_prepare(mesh->pdata, poly_layers, {}); } mesh->runtime = nullptr; diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc index c00ba6d5008..b4ecbde3540 100644 --- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc +++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc @@ -291,8 +291,9 @@ static IMesh meshes_to_imesh(Span meshes, r_info->mesh_poly_offset[mi] = f; /* Get matrix that transforms a coordinate in meshes[mi]'s local space * to the target space. */ - const float4x4 objn_mat = (obmats[mi] == nullptr) ? float4x4::identity() : - clean_transform(*obmats[mi]); + const float4x4 objn_mat = (obmats.is_empty() || obmats[mi] == nullptr) ? + float4x4::identity() : + clean_transform(*obmats[mi]); r_info->to_target_transform[mi] = inv_target_mat * objn_mat; r_info->has_negative_transform[mi] = math::is_negative(objn_mat); @@ -311,7 +312,7 @@ static IMesh meshes_to_imesh(Span meshes, * Skip the matrix multiplication for each point when there is no transform for a mesh, * for example when the first mesh is already in the target space. (Note the logic * directly above, which uses an identity matrix with a null input transform). */ - if (obmats[mi] == nullptr) { + if (obmats.is_empty() || obmats[mi] == nullptr) { threading::parallel_for(vert_positions.index_range(), 2048, [&](IndexRange range) { for (int i : range) { float3 co = vert_positions[i]; @@ -798,7 +799,7 @@ Mesh *direct_mesh_boolean(Span meshes, Vector *r_intersecting_edges) { #ifdef WITH_GMP - BLI_assert(meshes.size() == transforms.size()); + BLI_assert(transforms.is_empty() || meshes.size() == transforms.size()); BLI_assert(material_remaps.size() == 0 || material_remaps.size() == meshes.size()); if (meshes.size() <= 0) { return nullptr; diff --git a/source/blender/blenkernel/intern/mesh_calc_edges.cc b/source/blender/blenkernel/intern/mesh_calc_edges.cc index 203f41863bd..fa8db9dd9e4 100644 --- a/source/blender/blenkernel/intern/mesh_calc_edges.cc +++ b/source/blender/blenkernel/intern/mesh_calc_edges.cc @@ -231,7 +231,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool keep_existing_edges, const bool select } /* Create new edges. */ - if (!CustomData_get_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_edge")) { + if (!CustomData_has_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_edge")) { CustomData_add_layer_named( &mesh->ldata, CD_PROP_INT32, CD_CONSTRUCT, mesh->totloop, ".corner_edge"); } @@ -271,7 +271,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool keep_existing_edges, const bool select if (!keep_existing_edges) { /* All edges are rebuilt from the faces, so there are no loose edges. */ - mesh->loose_edges_tag_none(); + mesh->tag_loose_edges_none(); } /* Explicitly clear edge maps, because that way it can be parallelized. */ diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index 2da4be71ddc..73ea753061f 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -1236,25 +1236,6 @@ void BKE_mesh_tessface_ensure(struct Mesh *mesh) /** \name Sharp Edge Conversion * \{ */ -void BKE_mesh_legacy_sharp_faces_to_flags(Mesh *mesh, blender::MutableSpan legacy_polys) -{ - using namespace blender; - if (const bool *sharp_faces = static_cast( - CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face"))) - { - threading::parallel_for(legacy_polys.index_range(), 4096, [&](const IndexRange range) { - for (const int i : range) { - SET_FLAG_FROM_TEST(legacy_polys[i].flag_legacy, !sharp_faces[i], ME_SMOOTH); - } - }); - } - else { - for (const int i : legacy_polys.index_range()) { - legacy_polys[i].flag_legacy |= ME_SMOOTH; - } - } -} - void BKE_mesh_legacy_sharp_faces_from_flags(Mesh *mesh) { using namespace blender; @@ -1289,28 +1270,6 @@ void BKE_mesh_legacy_sharp_faces_from_flags(Mesh *mesh) /** \name Face Set Conversion * \{ */ -void BKE_mesh_legacy_face_set_from_generic(blender::MutableSpan poly_layers) -{ - using namespace blender; - bool changed = false; - for (CustomDataLayer &layer : poly_layers) { - if (StringRef(layer.name) == ".sculpt_face_set") { - layer.type = CD_SCULPT_FACE_SETS; - layer.name[0] = '\0'; - changed = true; - break; - } - } - if (!changed) { - return; - } - /* #CustomData expects the layers to be sorted in increasing order based on type. */ - std::stable_sort( - poly_layers.begin(), - poly_layers.end(), - [](const CustomDataLayer &a, const CustomDataLayer &b) { return a.type < b.type; }); -} - void BKE_mesh_legacy_face_set_to_generic(Mesh *mesh) { using namespace blender; @@ -1349,41 +1308,6 @@ void BKE_mesh_legacy_face_set_to_generic(Mesh *mesh) /** \name Bevel Weight Conversion * \{ */ -void BKE_mesh_legacy_bevel_weight_from_layers(Mesh *mesh) -{ - using namespace blender; - MutableSpan verts(mesh->mvert, mesh->totvert); - if (const float *weights = static_cast( - CustomData_get_layer(&mesh->vdata, CD_BWEIGHT))) - { - mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT; - for (const int i : verts.index_range()) { - verts[i].bweight_legacy = std::clamp(weights[i], 0.0f, 1.0f) * 255.0f; - } - } - else { - mesh->cd_flag &= ~ME_CDFLAG_VERT_BWEIGHT; - for (const int i : verts.index_range()) { - verts[i].bweight_legacy = 0; - } - } - MutableSpan edges(mesh->medge, mesh->totedge); - if (const float *weights = static_cast( - CustomData_get_layer(&mesh->edata, CD_BWEIGHT))) - { - mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT; - for (const int i : edges.index_range()) { - edges[i].bweight_legacy = std::clamp(weights[i], 0.0f, 1.0f) * 255.0f; - } - } - else { - mesh->cd_flag &= ~ME_CDFLAG_EDGE_BWEIGHT; - for (const int i : edges.index_range()) { - edges[i].bweight_legacy = 0; - } - } -} - void BKE_mesh_legacy_bevel_weight_to_layers(Mesh *mesh) { using namespace blender; @@ -1410,32 +1334,62 @@ void BKE_mesh_legacy_bevel_weight_to_layers(Mesh *mesh) } } +void BKE_mesh_legacy_bevel_weight_to_generic(Mesh *mesh) +{ + using namespace blender; + if (!mesh->attributes().contains("bevel_weight_vert")) { + void *data = nullptr; + const ImplicitSharingInfo *sharing_info = nullptr; + for (const int i : IndexRange(mesh->vdata.totlayer)) { + CustomDataLayer &layer = mesh->vdata.layers[i]; + if (layer.type == CD_BWEIGHT) { + data = layer.data; + sharing_info = layer.sharing_info; + layer.data = nullptr; + layer.sharing_info = nullptr; + CustomData_free_layer(&mesh->vdata, CD_BWEIGHT, mesh->totvert, i); + break; + } + } + if (data != nullptr) { + CustomData_add_layer_named_with_data( + &mesh->vdata, CD_PROP_FLOAT, data, mesh->totvert, "bevel_weight_vert", sharing_info); + } + if (sharing_info != nullptr) { + sharing_info->remove_user_and_delete_if_last(); + } + } + + if (!mesh->attributes().contains("bevel_weight_edge")) { + void *data = nullptr; + const ImplicitSharingInfo *sharing_info = nullptr; + for (const int i : IndexRange(mesh->edata.totlayer)) { + CustomDataLayer &layer = mesh->edata.layers[i]; + if (layer.type == CD_BWEIGHT) { + data = layer.data; + sharing_info = layer.sharing_info; + layer.data = nullptr; + layer.sharing_info = nullptr; + CustomData_free_layer(&mesh->edata, CD_BWEIGHT, mesh->totedge, i); + break; + } + } + if (data != nullptr) { + CustomData_add_layer_named_with_data( + &mesh->edata, CD_PROP_FLOAT, data, mesh->totedge, "bevel_weight_edge", sharing_info); + } + if (sharing_info != nullptr) { + sharing_info->remove_user_and_delete_if_last(); + } + } +} + /** \} */ /* -------------------------------------------------------------------- */ /** \name Edge Crease Conversion * \{ */ -void BKE_mesh_legacy_edge_crease_from_layers(Mesh *mesh) -{ - using namespace blender; - MutableSpan edges(mesh->medge, mesh->totedge); - if (const float *creases = static_cast( - CustomData_get_layer(&mesh->edata, CD_CREASE))) - { - mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE; - for (const int i : edges.index_range()) { - edges[i].crease_legacy = std::clamp(creases[i], 0.0f, 1.0f) * 255.0f; - } - } - else { - mesh->cd_flag &= ~ME_CDFLAG_EDGE_CREASE; - for (const int i : edges.index_range()) { - edges[i].crease_legacy = 0; - } - } -} - void BKE_mesh_legacy_edge_crease_to_layers(Mesh *mesh) { using namespace blender; @@ -1458,26 +1412,6 @@ void BKE_mesh_legacy_edge_crease_to_layers(Mesh *mesh) /** \name Sharp Edge Conversion * \{ */ -void BKE_mesh_legacy_sharp_edges_to_flags(Mesh *mesh) -{ - using namespace blender; - MutableSpan edges(mesh->medge, mesh->totedge); - if (const bool *sharp_edges = static_cast( - CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_edge"))) - { - threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) { - for (const int i : range) { - SET_FLAG_FROM_TEST(edges[i].flag_legacy, sharp_edges[i], ME_SHARP); - } - }); - } - else { - for (const int i : edges.index_range()) { - edges[i].flag_legacy &= ~ME_SHARP; - } - } -} - void BKE_mesh_legacy_sharp_edges_from_flags(Mesh *mesh) { using namespace blender; @@ -1511,26 +1445,6 @@ void BKE_mesh_legacy_sharp_edges_from_flags(Mesh *mesh) /** \name UV Seam Conversion * \{ */ -void BKE_mesh_legacy_uv_seam_to_flags(Mesh *mesh) -{ - using namespace blender; - MutableSpan edges(mesh->medge, mesh->totedge); - if (const bool *uv_seams = static_cast( - CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, ".uv_seam"))) - { - threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) { - for (const int i : range) { - SET_FLAG_FROM_TEST(edges[i].flag_legacy, uv_seams[i], ME_SEAM); - } - }); - } - else { - for (const int i : edges.index_range()) { - edges[i].flag_legacy &= ~ME_SEAM; - } - } -} - void BKE_mesh_legacy_uv_seam_from_flags(Mesh *mesh) { using namespace blender; @@ -1564,40 +1478,6 @@ void BKE_mesh_legacy_uv_seam_from_flags(Mesh *mesh) /** \name Hide Attribute and Legacy Flag Conversion * \{ */ -void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh, - blender::MutableSpan legacy_polys) -{ - using namespace blender; - using namespace blender::bke; - const AttributeAccessor attributes = mesh->attributes(); - - MutableSpan verts(mesh->mvert, mesh->totvert); - const VArray hide_vert = *attributes.lookup_or_default( - ".hide_vert", ATTR_DOMAIN_POINT, false); - threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) { - for (const int i : range) { - SET_FLAG_FROM_TEST(verts[i].flag_legacy, hide_vert[i], ME_HIDE); - } - }); - - MutableSpan edges(mesh->medge, mesh->totedge); - const VArray hide_edge = *attributes.lookup_or_default( - ".hide_edge", ATTR_DOMAIN_EDGE, false); - threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) { - for (const int i : range) { - SET_FLAG_FROM_TEST(edges[i].flag_legacy, hide_edge[i], ME_HIDE); - } - }); - - const VArray hide_poly = *attributes.lookup_or_default( - ".hide_poly", ATTR_DOMAIN_FACE, false); - threading::parallel_for(legacy_polys.index_range(), 4096, [&](IndexRange range) { - for (const int i : range) { - SET_FLAG_FROM_TEST(legacy_polys[i].flag_legacy, hide_poly[i], ME_HIDE); - } - }); -} - void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh) { using namespace blender; @@ -1663,21 +1543,6 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh) /** \name Material Index Conversion * \{ */ -void BKE_mesh_legacy_convert_material_indices_to_mpoly(Mesh *mesh, - blender::MutableSpan legacy_polys) -{ - using namespace blender; - using namespace blender::bke; - const AttributeAccessor attributes = mesh->attributes(); - const VArray material_indices = *attributes.lookup_or_default( - "material_index", ATTR_DOMAIN_FACE, 0); - threading::parallel_for(legacy_polys.index_range(), 4096, [&](IndexRange range) { - for (const int i : range) { - legacy_polys[i].mat_nr_legacy = material_indices[i]; - } - }); -} - void BKE_mesh_legacy_convert_mpoly_to_material_indices(Mesh *mesh) { using namespace blender; @@ -1708,87 +1573,6 @@ void BKE_mesh_legacy_convert_mpoly_to_material_indices(Mesh *mesh) /** \name Generic UV Map Conversion * \{ */ -static const bool *layers_find_bool_named(const Span layers, - const blender::StringRef name) -{ - for (const CustomDataLayer &layer : layers) { - if (layer.type == CD_PROP_BOOL) { - if (layer.name == name) { - return static_cast(layer.data); - } - } - } - return nullptr; -} - -void BKE_mesh_legacy_convert_uvs_to_struct( - Mesh *mesh, - blender::ResourceScope &temp_mloopuv_for_convert, - blender::Vector &loop_layers_to_write) -{ - using namespace blender; - using namespace blender::bke; - const int loops_num = mesh->totloop; - Vector new_layer_to_write; - - /* Don't write the boolean UV map sublayers which will be written in the legacy #MLoopUV type. */ - Set uv_sublayers_to_skip; - char vert_name[MAX_CUSTOMDATA_LAYER_NAME]; - char edge_name[MAX_CUSTOMDATA_LAYER_NAME]; - char pin_name[MAX_CUSTOMDATA_LAYER_NAME]; - for (const CustomDataLayer &layer : loop_layers_to_write) { - if (layer.type == CD_PROP_FLOAT2) { - uv_sublayers_to_skip.add_multiple_new( - {BKE_uv_map_vert_select_name_get(layer.name, vert_name), - BKE_uv_map_edge_select_name_get(layer.name, edge_name), - BKE_uv_map_pin_name_get(layer.name, pin_name)}); - } - } - - for (const CustomDataLayer &layer : loop_layers_to_write) { - if (layer.name[0] && uv_sublayers_to_skip.contains_as(layer.name)) { - continue; - } - if (layer.type != CD_PROP_FLOAT2) { - new_layer_to_write.append(layer); - continue; - } - const Span coords{static_cast(layer.data), loops_num}; - CustomDataLayer mloopuv_layer = layer; - mloopuv_layer.type = CD_MLOOPUV; - MutableSpan mloopuv = temp_mloopuv_for_convert.construct>(loops_num); - mloopuv_layer.data = mloopuv.data(); - - char buffer[MAX_CUSTOMDATA_LAYER_NAME]; - const bool *vert_selection = layers_find_bool_named( - loop_layers_to_write, BKE_uv_map_vert_select_name_get(layer.name, buffer)); - const bool *edge_selection = layers_find_bool_named( - loop_layers_to_write, BKE_uv_map_edge_select_name_get(layer.name, buffer)); - const bool *pin = layers_find_bool_named(loop_layers_to_write, - BKE_uv_map_pin_name_get(layer.name, buffer)); - - threading::parallel_for(mloopuv.index_range(), 2048, [&](IndexRange range) { - for (const int i : range) { - copy_v2_v2(mloopuv[i].uv, coords[i]); - SET_FLAG_FROM_TEST(mloopuv[i].flag, vert_selection && vert_selection[i], MLOOPUV_VERTSEL); - SET_FLAG_FROM_TEST(mloopuv[i].flag, edge_selection && edge_selection[i], MLOOPUV_EDGESEL); - SET_FLAG_FROM_TEST(mloopuv[i].flag, pin && pin[i], MLOOPUV_PINNED); - } - }); - new_layer_to_write.append(mloopuv_layer); - } - - /* #CustomData expects the layers to be sorted in increasing order based on type. */ - std::stable_sort( - new_layer_to_write.begin(), - new_layer_to_write.end(), - [](const CustomDataLayer &a, const CustomDataLayer &b) { return a.type < b.type; }); - - loop_layers_to_write = new_layer_to_write; - mesh->ldata.totlayer = new_layer_to_write.size(); - mesh->ldata.maxlayer = mesh->ldata.totlayer; -} - void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh) { using namespace blender; @@ -1918,40 +1702,6 @@ void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh) /** \name Selection Attribute and Legacy Flag Conversion * \{ */ -void BKE_mesh_legacy_convert_selection_layers_to_flags(Mesh *mesh, - blender::MutableSpan legacy_polys) -{ - using namespace blender; - using namespace blender::bke; - const AttributeAccessor attributes = mesh->attributes(); - - MutableSpan verts(mesh->mvert, mesh->totvert); - const VArray select_vert = *attributes.lookup_or_default( - ".select_vert", ATTR_DOMAIN_POINT, false); - threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) { - for (const int i : range) { - SET_FLAG_FROM_TEST(verts[i].flag_legacy, select_vert[i], SELECT); - } - }); - - MutableSpan edges(mesh->medge, mesh->totedge); - const VArray select_edge = *attributes.lookup_or_default( - ".select_edge", ATTR_DOMAIN_EDGE, false); - threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) { - for (const int i : range) { - SET_FLAG_FROM_TEST(edges[i].flag_legacy, select_edge[i], SELECT); - } - }); - - const VArray select_poly = *attributes.lookup_or_default( - ".select_poly", ATTR_DOMAIN_FACE, false); - threading::parallel_for(legacy_polys.index_range(), 4096, [&](IndexRange range) { - for (const int i : range) { - SET_FLAG_FROM_TEST(legacy_polys[i].flag_legacy, select_poly[i], ME_FACE_SEL); - } - }); -} - void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh) { using namespace blender; @@ -2013,67 +1763,16 @@ void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh) /** \} */ -/* -------------------------------------------------------------------- */ -/** \name Loose Edges - * \{ */ - -void BKE_mesh_legacy_convert_loose_edges_to_flag(Mesh *mesh) -{ - using namespace blender; - using namespace blender::bke; - - const LooseEdgeCache &loose_edges = mesh->loose_edges(); - MutableSpan edges(mesh->medge, mesh->totedge); - threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) { - if (loose_edges.count == 0) { - for (const int64_t i : range) { - edges[i].flag_legacy &= ~ME_LOOSEEDGE; - } - } - else { - for (const int64_t i : range) { - SET_FLAG_FROM_TEST(edges[i].flag_legacy, loose_edges.is_loose_bits[i], ME_LOOSEEDGE); - } - } - }); -} - -/** \} */ - /* -------------------------------------------------------------------- */ /** \name Vertex and Position Conversion * \{ */ -MVert *BKE_mesh_legacy_convert_positions_to_verts( - Mesh *mesh, - blender::ResourceScope &temp_arrays_for_convert, - blender::Vector &vert_layers_to_write) -{ - using namespace blender; - - const Span positions = mesh->vert_positions(); - - CustomDataLayer mvert_layer{}; - mvert_layer.type = CD_MVERT; - MutableSpan verts = temp_arrays_for_convert.construct>(mesh->totvert); - mvert_layer.data = verts.data(); - - threading::parallel_for(verts.index_range(), 2048, [&](IndexRange range) { - for (const int i : range) { - copy_v3_v3(verts[i].co_legacy, positions[i]); - } - }); - - vert_layers_to_write.append(mvert_layer); - return verts.data(); -} - void BKE_mesh_legacy_convert_verts_to_positions(Mesh *mesh) { using namespace blender; using namespace blender::bke; const MVert *mvert = static_cast(CustomData_get_layer(&mesh->vdata, CD_MVERT)); - if (!mvert || CustomData_get_layer_named(&mesh->vdata, CD_PROP_FLOAT3, "position")) { + if (!mvert || CustomData_has_layer_named(&mesh->vdata, CD_PROP_FLOAT3, "position")) { return; } @@ -2098,37 +1797,12 @@ void BKE_mesh_legacy_convert_verts_to_positions(Mesh *mesh) /** \name MEdge and int2 conversion * \{ */ -MEdge *BKE_mesh_legacy_convert_edges_to_medge( - Mesh *mesh, - blender::ResourceScope &temp_arrays_for_convert, - blender::Vector &edge_layers_to_write) -{ - using namespace blender; - const Span edges = mesh->edges(); - - CustomDataLayer medge_layer{}; - medge_layer.type = CD_MEDGE; - MutableSpan legacy_edges = temp_arrays_for_convert.construct>(mesh->totedge); - medge_layer.data = legacy_edges.data(); - - threading::parallel_for(edges.index_range(), 2048, [&](IndexRange range) { - for (const int i : range) { - legacy_edges[i] = {}; - legacy_edges[i].v1 = edges[i][0]; - legacy_edges[i].v2 = edges[i][1]; - } - }); - - edge_layers_to_write.append(medge_layer); - return legacy_edges.data(); -} - void BKE_mesh_legacy_convert_edges_to_generic(Mesh *mesh) { using namespace blender; using namespace blender::bke; const MEdge *medge = static_cast(CustomData_get_layer(&mesh->edata, CD_MEDGE)); - if (!medge || CustomData_get_layer_named(&mesh->edata, CD_PROP_INT32_2D, ".edge_verts")) { + if (!medge || CustomData_has_layer_named(&mesh->edata, CD_PROP_INT32_2D, ".edge_verts")) { return; } @@ -2217,95 +1891,17 @@ void BKE_mesh_legacy_attribute_flags_to_strings(Mesh *mesh) default_from_indices(mesh->ldata); } -void BKE_mesh_legacy_attribute_strings_to_flags(Mesh *mesh) -{ - using namespace blender; - CustomData *vdata = &mesh->vdata; - CustomData *ldata = &mesh->ldata; - - CustomData_clear_layer_flag( - vdata, CD_PROP_BYTE_COLOR, CD_FLAG_COLOR_ACTIVE | CD_FLAG_COLOR_RENDER); - CustomData_clear_layer_flag( - ldata, CD_PROP_BYTE_COLOR, CD_FLAG_COLOR_ACTIVE | CD_FLAG_COLOR_RENDER); - CustomData_clear_layer_flag(ldata, CD_PROP_COLOR, CD_FLAG_COLOR_ACTIVE | CD_FLAG_COLOR_RENDER); - CustomData_clear_layer_flag(vdata, CD_PROP_COLOR, CD_FLAG_COLOR_ACTIVE | CD_FLAG_COLOR_RENDER); - - if (const char *name = mesh->active_color_attribute) { - int i; - if ((i = CustomData_get_named_layer_index(vdata, CD_PROP_BYTE_COLOR, name)) != -1) { - CustomData_set_layer_active_index(vdata, CD_PROP_BYTE_COLOR, i); - vdata->layers[i].flag |= CD_FLAG_COLOR_ACTIVE; - } - else if ((i = CustomData_get_named_layer_index(vdata, CD_PROP_COLOR, name)) != -1) { - CustomData_set_layer_active_index(vdata, CD_PROP_COLOR, i); - vdata->layers[i].flag |= CD_FLAG_COLOR_ACTIVE; - } - else if ((i = CustomData_get_named_layer_index(ldata, CD_PROP_BYTE_COLOR, name)) != -1) { - CustomData_set_layer_active_index(ldata, CD_PROP_BYTE_COLOR, i); - ldata->layers[i].flag |= CD_FLAG_COLOR_ACTIVE; - } - else if ((i = CustomData_get_named_layer_index(ldata, CD_PROP_COLOR, name)) != -1) { - CustomData_set_layer_active_index(ldata, CD_PROP_COLOR, i); - ldata->layers[i].flag |= CD_FLAG_COLOR_ACTIVE; - } - } - if (const char *name = mesh->default_color_attribute) { - int i; - if ((i = CustomData_get_named_layer_index(vdata, CD_PROP_BYTE_COLOR, name)) != -1) { - CustomData_set_layer_render_index(vdata, CD_PROP_BYTE_COLOR, i); - vdata->layers[i].flag |= CD_FLAG_COLOR_RENDER; - } - else if ((i = CustomData_get_named_layer_index(vdata, CD_PROP_COLOR, name)) != -1) { - CustomData_set_layer_render_index(vdata, CD_PROP_COLOR, i); - vdata->layers[i].flag |= CD_FLAG_COLOR_RENDER; - } - else if ((i = CustomData_get_named_layer_index(ldata, CD_PROP_BYTE_COLOR, name)) != -1) { - CustomData_set_layer_render_index(ldata, CD_PROP_BYTE_COLOR, i); - ldata->layers[i].flag |= CD_FLAG_COLOR_RENDER; - } - else if ((i = CustomData_get_named_layer_index(ldata, CD_PROP_COLOR, name)) != -1) { - CustomData_set_layer_render_index(ldata, CD_PROP_COLOR, i); - ldata->layers[i].flag |= CD_FLAG_COLOR_RENDER; - } - } -} - /** \} */ /* -------------------------------------------------------------------- */ /** \name Face Corner Conversion * \{ */ -MLoop *BKE_mesh_legacy_convert_corners_to_loops( - Mesh *mesh, - blender::ResourceScope &temp_arrays_for_convert, - blender::Vector &loop_layers_to_write) -{ - using namespace blender; - const Span corner_verts = mesh->corner_verts(); - const Span corner_edges = mesh->corner_edges(); - - CustomDataLayer mloop_layer{}; - mloop_layer.type = CD_MLOOP; - MutableSpan loops = temp_arrays_for_convert.construct>(mesh->totloop); - mloop_layer.data = loops.data(); - - threading::parallel_for(loops.index_range(), 2048, [&](IndexRange range) { - for (const int i : range) { - loops[i].v = corner_verts[i]; - loops[i].e = corner_edges[i]; - } - }); - - loop_layers_to_write.append(mloop_layer); - return loops.data(); -} - void BKE_mesh_legacy_convert_loops_to_corners(Mesh *mesh) { using namespace blender; - if (CustomData_get_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_vert") && - CustomData_get_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_edge")) + if (CustomData_has_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_vert") && + CustomData_has_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_edge")) { return; } @@ -2335,30 +1931,6 @@ void BKE_mesh_legacy_convert_loops_to_corners(Mesh *mesh) /** \name Poly Offset Conversion * \{ */ -blender::MutableSpan BKE_mesh_legacy_convert_offsets_to_polys( - const Mesh *mesh, - blender::ResourceScope &temp_arrays_for_convert, - blender::Vector &poly_layers_to_write) -{ - using namespace blender; - const OffsetIndices polys = mesh->polys(); - - MutableSpan polys_legacy = temp_arrays_for_convert.construct>(mesh->totpoly); - threading::parallel_for(polys_legacy.index_range(), 2048, [&](IndexRange range) { - for (const int i : range) { - polys_legacy[i].loopstart = polys[i].start(); - polys_legacy[i].totloop = polys[i].size(); - } - }); - - CustomDataLayer layer{}; - layer.type = CD_MPOLY; - layer.data = polys_legacy.data(); - poly_layers_to_write.append(layer); - - return polys_legacy; -} - static bool poly_loops_orders_match(const Span polys) { for (const int i : polys.index_range().drop_back(1)) { diff --git a/source/blender/blenkernel/intern/mesh_runtime.cc b/source/blender/blenkernel/intern/mesh_runtime.cc index a6c6b523e84..2573837f28d 100644 --- a/source/blender/blenkernel/intern/mesh_runtime.cc +++ b/source/blender/blenkernel/intern/mesh_runtime.cc @@ -190,7 +190,7 @@ void Mesh::tag_loose_verts_none() const try_tag_verts_no_face_none(*this); } -void Mesh::loose_edges_tag_none() const +void Mesh::tag_loose_edges_none() const { using namespace blender::bke; this->runtime->loose_edges_cache.ensure([&](LooseEdgeCache &r_data) { @@ -314,9 +314,21 @@ void BKE_mesh_tag_edges_split(struct Mesh *mesh) free_bvh_cache(*mesh->runtime); reset_normals(*mesh->runtime); free_subdiv_ccg(*mesh->runtime); - mesh->runtime->loose_edges_cache.tag_dirty(); - mesh->runtime->loose_verts_cache.tag_dirty(); - mesh->runtime->verts_no_face_cache.tag_dirty(); + if (mesh->runtime->loose_edges_cache.is_cached() && + mesh->runtime->loose_edges_cache.data().count != 0) + { + mesh->runtime->loose_edges_cache.tag_dirty(); + } + if (mesh->runtime->loose_verts_cache.is_cached() && + mesh->runtime->loose_verts_cache.data().count != 0) + { + mesh->runtime->loose_verts_cache.tag_dirty(); + } + if (mesh->runtime->verts_no_face_cache.is_cached() && + mesh->runtime->verts_no_face_cache.data().count != 0) + { + mesh->runtime->verts_no_face_cache.tag_dirty(); + } mesh->runtime->subsurf_face_dot_tags.clear_and_shrink(); mesh->runtime->subsurf_optimal_display_edges.clear_and_shrink(); if (mesh->runtime->shrinkwrap_data) { diff --git a/source/blender/blenkernel/intern/mesh_sample.cc b/source/blender/blenkernel/intern/mesh_sample.cc index 2883751ebc1..15ff46467a5 100644 --- a/source/blender/blenkernel/intern/mesh_sample.cc +++ b/source/blender/blenkernel/intern/mesh_sample.cc @@ -32,6 +32,24 @@ BLI_NOINLINE static void sample_point_attribute(const Span corner_verts, } } +void sample_point_normals(const Span corner_verts, + const Span looptris, + const Span looptri_indices, + const Span bary_coords, + const Span src, + const IndexMask mask, + const MutableSpan dst) +{ + for (const int i : mask) { + const MLoopTri &tri = looptris[looptri_indices[i]]; + const float3 value = attribute_math::mix3(bary_coords[i], + src[corner_verts[tri.tri[0]]], + src[corner_verts[tri.tri[1]]], + src[corner_verts[tri.tri[2]]]); + dst[i] = math::normalize(value); + } +} + void sample_point_attribute(const Span corner_verts, const Span looptris, const Span looptri_indices, diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index ff199eac829..f8853e4fa36 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -71,10 +71,6 @@ #include "tracking_private.h" -/* Convert camera object to legacy format where the camera tracks are stored in the MovieTracking - * structure when saving .blend file. */ -#define USE_LEGACY_CAMERA_OBJECT_FORMAT_ON_SAVE 1 - static void free_buffers(MovieClip *clip); static void movie_clip_init_data(ID *id) @@ -200,39 +196,6 @@ static void movieclip_blend_write(BlendWriter *writer, ID *id, const void *id_ad MovieTracking *tracking = &clip->tracking; -#if USE_LEGACY_CAMERA_OBJECT_FORMAT_ON_SAVE - const bool is_undo = BLO_write_is_undo(writer); - - /* When using legacy format for camera object assign the list of camera tracks to the - * MovieTracking object. Do it in-place as it simplifies the code a bit, and it is not - * supposed to cause threading issues as no other code is meant to access the legacy fields. */ - if (!is_undo) { - MovieTrackingObject *active_tracking_object = BKE_tracking_object_get_active(tracking); - MovieTrackingObject *tracking_camera_object = BKE_tracking_object_get_camera(tracking); - BLI_assert(active_tracking_object != NULL); - BLI_assert(tracking_camera_object != NULL); - - tracking->tracks_legacy = tracking_camera_object->tracks; - tracking->plane_tracks_legacy = tracking_camera_object->plane_tracks; - - /* The active track in the tracking structure used to be shared across all tracking objects. */ - tracking->act_track_legacy = active_tracking_object->active_track; - tracking->act_plane_track_legacy = active_tracking_object->active_plane_track; - - tracking->reconstruction_legacy = tracking_camera_object->reconstruction; - } -#endif - - /* Assign the pixel-space principal point for forward compatibility. */ - /* TODO(sergey): Remove with the next major version update when forward compatibility is allowed - * to be broken. */ - if (!is_undo && clip->lastsize[0] != 0 && clip->lastsize[1] != 0) { - tracking_principal_point_normalized_to_pixel(tracking->camera.principal_point, - clip->lastsize[0], - clip->lastsize[1], - tracking->camera.principal_legacy); - } - BLO_write_id_struct(writer, MovieClip, id_address, &clip->id); BKE_id_blend_write(writer, &clip->id); @@ -241,39 +204,11 @@ static void movieclip_blend_write(BlendWriter *writer, ID *id, const void *id_ad } LISTBASE_FOREACH (MovieTrackingObject *, object, &tracking->objects) { -#if USE_LEGACY_CAMERA_OBJECT_FORMAT_ON_SAVE - /* When saving cameras object in the legacy format clear the list of tracks. This is because - * the tracking object code is generic and assumes object owns the tracks in the list. For the - * camera tracks that is not the case in the legacy format. */ - if (!is_undo && (object->flag & TRACKING_OBJECT_CAMERA)) { - MovieTrackingObject legacy_object = *object; - BLI_listbase_clear(&legacy_object.tracks); - BLI_listbase_clear(&legacy_object.plane_tracks); - legacy_object.active_track = NULL; - legacy_object.active_plane_track = NULL; - memset(&legacy_object.reconstruction, 0, sizeof(legacy_object.reconstruction)); - BLO_write_struct_at_address(writer, MovieTrackingObject, object, &legacy_object); - } - else -#endif - { - BLO_write_struct(writer, MovieTrackingObject, object); - } - + BLO_write_struct(writer, MovieTrackingObject, object); write_movieTracks(writer, &object->tracks); write_moviePlaneTracks(writer, &object->plane_tracks); write_movieReconstruction(writer, &object->reconstruction); } - -#if USE_LEGACY_CAMERA_OBJECT_FORMAT_ON_SAVE - if (!is_undo) { - BLI_listbase_clear(&tracking->tracks_legacy); - BLI_listbase_clear(&tracking->plane_tracks_legacy); - tracking->act_track_legacy = NULL; - tracking->act_plane_track_legacy = NULL; - memset(&tracking->reconstruction_legacy, 0, sizeof(tracking->reconstruction_legacy)); - } -#endif } static void direct_link_movieReconstruction(BlendDataReader *reader, @@ -613,11 +548,9 @@ void BKE_movieclip_convert_multilayer_ibuf(struct ImBuf *ibuf) movieclip_convert_multilayer_add_layer, movieclip_convert_multilayer_add_pass); if (ctx.combined_pass != NULL) { - BLI_assert(ibuf->rect_float == NULL); - ibuf->rect_float = ctx.combined_pass; + BLI_assert(ibuf->float_buffer.data == NULL); + IMB_assign_float_buffer(ibuf, ctx.combined_pass, IB_TAKE_OWNERSHIP); ibuf->channels = ctx.num_combined_channels; - ibuf->flags |= IB_rectfloat; - ibuf->mall |= IB_rectfloat; } IMB_exr_close(ibuf->userdata); ibuf->userdata = NULL; @@ -1797,7 +1730,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, scopes->track_disabled = false; - if (ibuf && (ibuf->rect || ibuf->rect_float)) { + if (ibuf && (ibuf->byte_buffer.data || ibuf->float_buffer.data)) { MovieTrackingMarker undist_marker = *marker; if (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) { @@ -2114,7 +2047,7 @@ GPUTexture *BKE_movieclip_get_gpu_texture(MovieClip *clip, MovieClipUser *cuser) /* This only means RGBA16F instead of RGBA32F. */ const bool high_bitdepth = false; - const bool store_premultiplied = ibuf->rect_float ? false : true; + const bool store_premultiplied = ibuf->float_buffer.data ? false : true; *tex = IMB_create_gpu_texture(clip->id.name + 2, ibuf, high_bitdepth, store_premultiplied); /* Do not generate mips for movieclips... too slow. */ diff --git a/source/blender/blenkernel/intern/multires_reshape_smooth.cc b/source/blender/blenkernel/intern/multires_reshape_smooth.cc index 8eef74fab3b..6f426205b97 100644 --- a/source/blender/blenkernel/intern/multires_reshape_smooth.cc +++ b/source/blender/blenkernel/intern/multires_reshape_smooth.cc @@ -822,18 +822,15 @@ static void foreach_edge(const SubdivForeachContext *foreach_context, return; } - /* Ignore all inner face edges as they have sharpness of zero when using Catmull-Clark mode. In - * simple mode, all edges have maximum sharpness, so they can't be skipped. */ - if (coarse_edge_index == ORIGINDEX_NONE && - reshape_smooth_context->smoothing_type != MULTIRES_SUBDIVIDE_SIMPLE) - { + /* Ignore all inner face edges as they have sharpness of zero. */ + if (coarse_edge_index == ORIGINDEX_NONE) { return; } /* Ignore all loose edges as well, as they are not communicated to the OpenSubdiv. */ - if (!reshape_smooth_context->loose_base_edges.is_empty() && - reshape_smooth_context->loose_base_edges[coarse_edge_index]) - { - return; + if (!reshape_smooth_context->loose_base_edges.is_empty()) { + if (reshape_smooth_context->loose_base_edges[coarse_edge_index]) { + return; + } } /* Edges without crease are to be ignored as well. */ const float crease = get_effective_crease(reshape_smooth_context, coarse_edge_index); diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index f14e6a5e58c..e6ebf4b44cd 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -1352,6 +1352,7 @@ namespace blender::bke { static GHash *nodetreetypes_hash = nullptr; static GHash *nodetypes_hash = nullptr; +static GHash *nodetypes_alias_hash = nullptr; static GHash *nodesockettypes_hash = nullptr; } // namespace blender::bke @@ -1416,6 +1417,19 @@ bNodeType *nodeTypeFind(const char *idname) return nullptr; } +const char *nodeTypeFindAlias(const char *alias) +{ + if (alias[0]) { + const char *idname = static_cast( + BLI_ghash_lookup(blender::bke::nodetypes_alias_hash, alias)); + if (idname) { + return idname; + } + } + + return alias; +} + static void node_free_type(void *nodetype_v) { bNodeType *nodetype = static_cast(nodetype_v); @@ -1458,6 +1472,11 @@ void nodeUnregisterType(bNodeType *nt) BLI_ghash_remove(blender::bke::nodetypes_hash, nt->idname, nullptr, node_free_type); } +void nodeRegisterAlias(bNodeType *nt, const char *alias) +{ + BLI_ghash_insert(blender::bke::nodetypes_alias_hash, BLI_strdup(alias), BLI_strdup(nt->idname)); +} + namespace blender::bke { bool node_type_is_undefined(const bNode *node) @@ -4389,6 +4408,7 @@ void BKE_node_system_init() { blender::bke::nodetreetypes_hash = BLI_ghash_str_new("nodetreetypes_hash gh"); blender::bke::nodetypes_hash = BLI_ghash_str_new("nodetypes_hash gh"); + blender::bke::nodetypes_alias_hash = BLI_ghash_str_new("nodetypes_alias_hash gh"); blender::bke::nodesockettypes_hash = BLI_ghash_str_new("nodesockettypes_hash gh"); register_nodes(); @@ -4396,6 +4416,11 @@ void BKE_node_system_init() void BKE_node_system_exit() { + if (blender::bke::nodetypes_alias_hash) { + BLI_ghash_free(blender::bke::nodetypes_alias_hash, MEM_freeN, MEM_freeN); + blender::bke::nodetypes_alias_hash = nullptr; + } + if (blender::bke::nodetypes_hash) { NODE_TYPES_BEGIN (nt) { if (nt->rna_ext.free) { diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c index 7fce89617d3..bdff3f3bc0e 100644 --- a/source/blender/blenkernel/intern/object_deform.c +++ b/source/blender/blenkernel/intern/object_deform.c @@ -257,7 +257,7 @@ static void object_defgroup_remove_common(Object *ob, bDeformGroup *dg, const in BKE_object_defgroup_active_index_set(ob, active_index - 1); } - /* remove all dverts */ + /* Remove all deform-verts. */ if (BLI_listbase_is_empty(defbase)) { if (ob->type == OB_MESH) { Mesh *me = ob->data; @@ -404,8 +404,8 @@ void BKE_object_defgroup_remove_all_ex(struct Object *ob, bool only_unlocked) dg = next_dg; } } - else { /* defbase is empty... */ - /* remove all dverts */ + else { /* `defbase` is empty. */ + /* Remove all deform-verts. */ if (ob->type == OB_MESH) { Mesh *me = ob->data; CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c index 312e1357f79..57c944be96e 100644 --- a/source/blender/blenkernel/intern/ocean.c +++ b/source/blender/blenkernel/intern/ocean.c @@ -1286,23 +1286,23 @@ void BKE_ocean_cache_eval_ij(struct OceanCache *och, struct OceanResult *ocr, in j = j % res_y; if (och->ibufs_disp[f]) { - copy_v3_v3(ocr->disp, &och->ibufs_disp[f]->rect_float[4 * (res_x * j + i)]); + copy_v3_v3(ocr->disp, &och->ibufs_disp[f]->float_buffer.data[4 * (res_x * j + i)]); } if (och->ibufs_foam[f]) { - ocr->foam = och->ibufs_foam[f]->rect_float[4 * (res_x * j + i)]; + ocr->foam = och->ibufs_foam[f]->float_buffer.data[4 * (res_x * j + i)]; } if (och->ibufs_spray[f]) { - copy_v3_v3(ocr->Eplus, &och->ibufs_spray[f]->rect_float[4 * (res_x * j + i)]); + copy_v3_v3(ocr->Eplus, &och->ibufs_spray[f]->float_buffer.data[4 * (res_x * j + i)]); } if (och->ibufs_spray_inverse[f]) { - copy_v3_v3(ocr->Eminus, &och->ibufs_spray_inverse[f]->rect_float[4 * (res_x * j + i)]); + copy_v3_v3(ocr->Eminus, &och->ibufs_spray_inverse[f]->float_buffer.data[4 * (res_x * j + i)]); } if (och->ibufs_norm[f]) { - copy_v3_v3(ocr->normal, &och->ibufs_norm[f]->rect_float[4 * (res_x * j + i)]); + copy_v3_v3(ocr->normal, &och->ibufs_norm[f]->float_buffer.data[4 * (res_x * j + i)]); } } @@ -1435,7 +1435,7 @@ void BKE_ocean_bake(struct Ocean *o, BKE_ocean_eval_ij(o, &ocr, x, y); /* add to the image */ - rgb_to_rgba_unit_alpha(&ibuf_disp->rect_float[4 * (res_x * y + x)], ocr.disp); + rgb_to_rgba_unit_alpha(&ibuf_disp->float_buffer.data[4 * (res_x * y + x)], ocr.disp); if (o->_do_jacobian) { /* TODO(@ideasman42): cleanup unused code. */ @@ -1478,18 +1478,19 @@ void BKE_ocean_bake(struct Ocean *o, // foam_result = min_ff(foam_result, 1.0f); - value_to_rgba_unit_alpha(&ibuf_foam->rect_float[4 * (res_x * y + x)], foam_result); + value_to_rgba_unit_alpha(&ibuf_foam->float_buffer.data[4 * (res_x * y + x)], + foam_result); /* spray map baking */ if (o->_do_spray) { - rgb_to_rgba_unit_alpha(&ibuf_spray->rect_float[4 * (res_x * y + x)], ocr.Eplus); - rgb_to_rgba_unit_alpha(&ibuf_spray_inverse->rect_float[4 * (res_x * y + x)], + rgb_to_rgba_unit_alpha(&ibuf_spray->float_buffer.data[4 * (res_x * y + x)], ocr.Eplus); + rgb_to_rgba_unit_alpha(&ibuf_spray_inverse->float_buffer.data[4 * (res_x * y + x)], ocr.Eminus); } } if (o->_do_normals) { - rgb_to_rgba_unit_alpha(&ibuf_normal->rect_float[4 * (res_x * y + x)], ocr.normal); + rgb_to_rgba_unit_alpha(&ibuf_normal->float_buffer.data[4 * (res_x * y + x)], ocr.normal); } } } diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc index 2711fa89eb4..6fd99702cf8 100644 --- a/source/blender/blenkernel/intern/pbvh_pixels.cc +++ b/source/blender/blenkernel/intern/pbvh_pixels.cc @@ -637,12 +637,11 @@ static void apply_watertight_check(PBVH *pbvh, Image *image, ImageUser *image_us int pixel_offset = pixel_row.start_image_coordinate.y * image_buffer->x + pixel_row.start_image_coordinate.x; for (int x = 0; x < pixel_row.num_pixels; x++) { - if (image_buffer->rect_float) { - copy_v4_fl(&image_buffer->rect_float[pixel_offset * 4], 1.0); + if (image_buffer->float_buffer.data) { + copy_v4_fl(&image_buffer->float_buffer.data[pixel_offset * 4], 1.0); } - if (image_buffer->rect) { - uint8_t *dest = static_cast( - static_cast(&image_buffer->rect[pixel_offset])); + if (image_buffer->byte_buffer.data) { + uint8_t *dest = &image_buffer->byte_buffer.data[pixel_offset * 4]; copy_v4_uchar(dest, 255); } pixel_offset += 1; diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c index f31e33d0768..656b2eb99ad 100644 --- a/source/blender/blenkernel/intern/studiolight.c +++ b/source/blender/blenkernel/intern/studiolight.c @@ -484,7 +484,7 @@ static void studiolight_create_equirect_radiance_gputexture(StudioLight *sl) 1, GPU_RGBA16F, GPU_TEXTURE_USAGE_SHADER_READ, - ibuf->rect_float); + ibuf->float_buffer.data); GPUTexture *tex = sl->equirect_radiance_gputexture; GPU_texture_filter_mode(tex, true); GPU_texture_extend_mode(tex, GPU_SAMPLER_EXTEND_MODE_REPEAT); @@ -498,7 +498,7 @@ static void studiolight_create_matcap_gputexture(StudioLightImage *sli) ImBuf *ibuf = sli->ibuf; float *gpu_matcap_3components = MEM_callocN(sizeof(float[3]) * ibuf->x * ibuf->y, __func__); - const float(*offset4)[4] = (const float(*)[4])ibuf->rect_float; + const float(*offset4)[4] = (const float(*)[4])ibuf->float_buffer.data; float(*offset3)[3] = (float(*)[3])gpu_matcap_3components; for (int i = 0; i < ibuf->x * ibuf->y; i++, offset4++, offset3++) { copy_v3_v3(*offset3, *offset4); @@ -545,7 +545,7 @@ static void studiolight_create_equirect_irradiance_gputexture(StudioLight *sl) 1, GPU_RGBA16F, GPU_TEXTURE_USAGE_SHADER_READ, - ibuf->rect_float); + ibuf->float_buffer.data); GPUTexture *tex = sl->equirect_irradiance_gputexture; GPU_texture_filter_mode(tex, true); GPU_texture_extend_mode(tex, GPU_SAMPLER_EXTEND_MODE_REPEAT); @@ -681,7 +681,7 @@ static void studiolight_spherical_harmonics_calculate_coefficients(StudioLight * for (int face = 0; face < 6; face++) { ITER_PIXELS (float, - sl->radiance_cubemap_buffers[face]->rect_float, + sl->radiance_cubemap_buffers[face]->float_buffer.data, 4, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE) @@ -976,7 +976,7 @@ BLI_INLINE void studiolight_evaluate_specular_radiance_buffer(ImBuf *radiance_bu float accum[3] = {0.0f, 0.0f, 0.0f}; float accum_weight = 0.00001f; ITER_PIXELS (float, - radiance_buffer->rect_float, + radiance_buffer->float_buffer.data, 4, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE, STUDIOLIGHT_RADIANCE_CUBEMAP_SIZE) diff --git a/source/blender/blenkernel/intern/subdiv_mesh.cc b/source/blender/blenkernel/intern/subdiv_mesh.cc index eabf6847b40..afe85ff3e19 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.cc +++ b/source/blender/blenkernel/intern/subdiv_mesh.cc @@ -1208,7 +1208,7 @@ Mesh *BKE_subdiv_to_mesh(Subdiv *subdiv, result->tag_loose_verts_none(); } if (coarse_mesh->loose_edges().count == 0) { - result->loose_edges_tag_none(); + result->tag_loose_edges_none(); } if (subdiv->settings.is_simple) { diff --git a/source/blender/blenkernel/intern/tracking.cc b/source/blender/blenkernel/intern/tracking.cc index 879b2773f48..290a64dacbd 100644 --- a/source/blender/blenkernel/intern/tracking.cc +++ b/source/blender/blenkernel/intern/tracking.cc @@ -2277,48 +2277,46 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, resibuf = IMB_dupImBuf(ibuf); - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { if (undistort) { libmv_cameraIntrinsicsUndistortFloat(distortion->intrinsics, - ibuf->rect_float, + ibuf->float_buffer.data, ibuf->x, ibuf->y, overscan, ibuf->channels, - resibuf->rect_float); + resibuf->float_buffer.data); } else { libmv_cameraIntrinsicsDistortFloat(distortion->intrinsics, - ibuf->rect_float, + ibuf->float_buffer.data, ibuf->x, ibuf->y, overscan, ibuf->channels, - resibuf->rect_float); + resibuf->float_buffer.data); } - if (ibuf->rect) { - imb_freerectImBuf(ibuf); - } + imb_freerectImBuf(ibuf); } else { if (undistort) { libmv_cameraIntrinsicsUndistortByte(distortion->intrinsics, - (uchar *)ibuf->rect, + ibuf->byte_buffer.data, ibuf->x, ibuf->y, overscan, ibuf->channels, - (uchar *)resibuf->rect); + resibuf->byte_buffer.data); } else { libmv_cameraIntrinsicsDistortByte(distortion->intrinsics, - (uchar *)ibuf->rect, + ibuf->byte_buffer.data, ibuf->x, ibuf->y, overscan, ibuf->channels, - (uchar *)resibuf->rect); + resibuf->byte_buffer.data); } } @@ -2573,7 +2571,7 @@ ImBuf *BKE_tracking_sample_pattern(const int frame_width, } pattern_ibuf = IMB_allocImBuf( - num_samples_x, num_samples_y, 32, search_ibuf->rect_float ? IB_rectfloat : IB_rect); + num_samples_x, num_samples_y, 32, search_ibuf->float_buffer.data ? IB_rectfloat : IB_rect); tracking_get_marker_coords_for_tracking( frame_width, frame_height, marker, src_pixel_x, src_pixel_y); @@ -2606,8 +2604,8 @@ ImBuf *BKE_tracking_sample_pattern(const int frame_width, mask = BKE_tracking_track_get_mask(frame_width, frame_height, track, marker); } - if (search_ibuf->rect_float) { - libmv_samplePlanarPatchFloat(search_ibuf->rect_float, + if (search_ibuf->float_buffer.data) { + libmv_samplePlanarPatchFloat(search_ibuf->float_buffer.data, search_ibuf->x, search_ibuf->y, 4, @@ -2616,12 +2614,12 @@ ImBuf *BKE_tracking_sample_pattern(const int frame_width, num_samples_x, num_samples_y, mask, - pattern_ibuf->rect_float, + pattern_ibuf->float_buffer.data, &warped_position_x, &warped_position_y); } else { - libmv_samplePlanarPatchByte((uchar *)search_ibuf->rect, + libmv_samplePlanarPatchByte(search_ibuf->byte_buffer.data, search_ibuf->x, search_ibuf->y, 4, @@ -2630,7 +2628,7 @@ ImBuf *BKE_tracking_sample_pattern(const int frame_width, num_samples_x, num_samples_y, mask, - (uchar *)pattern_ibuf->rect, + pattern_ibuf->byte_buffer.data, &warped_position_x, &warped_position_y); } @@ -2712,7 +2710,7 @@ ImBuf *BKE_tracking_get_search_imbuf(const ImBuf *ibuf, return nullptr; } - searchibuf = IMB_allocImBuf(w, h, 32, ibuf->rect_float ? IB_rectfloat : IB_rect); + searchibuf = IMB_allocImBuf(w, h, 32, ibuf->float_buffer.data ? IB_rectfloat : IB_rect); IMB_rectcpy(searchibuf, ibuf, 0, 0, x, y, w, h); @@ -2766,7 +2764,7 @@ ImBuf *BKE_tracking_get_plane_imbuf(const ImBuf *frame_ibuf, /* Create new result image with the same type of content as the original. */ ImBuf *plane_ibuf = IMB_allocImBuf( - num_samples_x, num_samples_y, 32, frame_ibuf->rect_float ? IB_rectfloat : IB_rect); + num_samples_x, num_samples_y, 32, frame_ibuf->float_buffer.data ? IB_rectfloat : IB_rect); /* Calculate corner coordinates in pixel space, as separate X/Y arrays. */ const double src_pixel_x[4] = {corners[0][0] * frame_width, @@ -2782,8 +2780,8 @@ ImBuf *BKE_tracking_get_plane_imbuf(const ImBuf *frame_ibuf, double warped_position_x, warped_position_y; /* Actual sampling. */ - if (frame_ibuf->rect_float != nullptr) { - libmv_samplePlanarPatchFloat(frame_ibuf->rect_float, + if (frame_ibuf->float_buffer.data != nullptr) { + libmv_samplePlanarPatchFloat(frame_ibuf->float_buffer.data, frame_ibuf->x, frame_ibuf->y, 4, @@ -2792,12 +2790,12 @@ ImBuf *BKE_tracking_get_plane_imbuf(const ImBuf *frame_ibuf, num_samples_x, num_samples_y, nullptr, - plane_ibuf->rect_float, + plane_ibuf->float_buffer.data, &warped_position_x, &warped_position_y); } else { - libmv_samplePlanarPatchByte((uchar *)frame_ibuf->rect, + libmv_samplePlanarPatchByte(frame_ibuf->byte_buffer.data, frame_ibuf->x, frame_ibuf->y, 4, @@ -2806,7 +2804,7 @@ ImBuf *BKE_tracking_get_plane_imbuf(const ImBuf *frame_ibuf, num_samples_x, num_samples_y, nullptr, - (uchar *)plane_ibuf->rect, + plane_ibuf->byte_buffer.data, &warped_position_x, &warped_position_y); } @@ -2834,8 +2832,8 @@ void BKE_tracking_disable_channels( for (int x = 0; x < ibuf->x; x++) { int pixel = ibuf->x * y + x; - if (ibuf->rect_float) { - float *rrgbf = ibuf->rect_float + pixel * 4; + if (ibuf->float_buffer.data) { + float *rrgbf = ibuf->float_buffer.data + pixel * 4; float r = disable_red ? 0.0f : rrgbf[0]; float g = disable_green ? 0.0f : rrgbf[1]; float b = disable_blue ? 0.0f : rrgbf[2]; @@ -2852,10 +2850,10 @@ void BKE_tracking_disable_channels( } } else { - char *rrgb = (char *)ibuf->rect + pixel * 4; - char r = disable_red ? 0 : rrgb[0]; - char g = disable_green ? 0 : rrgb[1]; - char b = disable_blue ? 0 : rrgb[2]; + uchar *rrgb = ibuf->byte_buffer.data + pixel * 4; + uchar r = disable_red ? 0 : rrgb[0]; + uchar g = disable_green ? 0 : rrgb[1]; + uchar b = disable_blue ? 0 : rrgb[2]; if (grayscale) { float gray = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale; @@ -2871,7 +2869,7 @@ void BKE_tracking_disable_channels( } } - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { ibuf->userflags |= IB_RECT_INVALID; } } diff --git a/source/blender/blenkernel/intern/tracking_detect.cc b/source/blender/blenkernel/intern/tracking_detect.cc index e767cbe7129..01c3944e7bf 100644 --- a/source/blender/blenkernel/intern/tracking_detect.cc +++ b/source/blender/blenkernel/intern/tracking_detect.cc @@ -117,11 +117,11 @@ static void run_configured_detector(MovieTracking *tracking, { struct libmv_Features *features = nullptr; - if (ibuf->rect_float) { - features = libmv_detectFeaturesFloat(ibuf->rect_float, ibuf->x, ibuf->y, 4, options); + if (ibuf->float_buffer.data) { + features = libmv_detectFeaturesFloat(ibuf->float_buffer.data, ibuf->x, ibuf->y, 4, options); } - else if (ibuf->rect) { - features = libmv_detectFeaturesByte((uchar *)ibuf->rect, ibuf->x, ibuf->y, 4, options); + else if (ibuf->byte_buffer.data) { + features = libmv_detectFeaturesByte(ibuf->byte_buffer.data, ibuf->x, ibuf->y, 4, options); } if (features != nullptr) { diff --git a/source/blender/blenkernel/intern/tracking_region_tracker.cc b/source/blender/blenkernel/intern/tracking_region_tracker.cc index 48a258d1bbf..0c595c1003e 100644 --- a/source/blender/blenkernel/intern/tracking_region_tracker.cc +++ b/source/blender/blenkernel/intern/tracking_region_tracker.cc @@ -80,13 +80,13 @@ static float *track_get_search_floatbuf(ImBuf *ibuf, gray_pixels = MEM_cnew_array(width * height, "tracking floatBuf"); - if (searchibuf->rect_float) { + if (searchibuf->float_buffer.data) { float_rgba_to_gray( - searchibuf->rect_float, gray_pixels, width * height, 0.2126f, 0.7152f, 0.0722f); + searchibuf->float_buffer.data, gray_pixels, width * height, 0.2126f, 0.7152f, 0.0722f); } else { uint8_rgba_to_float_gray( - (uchar *)searchibuf->rect, gray_pixels, width * height, 0.2126f, 0.7152f, 0.0722f); + searchibuf->byte_buffer.data, gray_pixels, width * height, 0.2126f, 0.7152f, 0.0722f); } IMB_freeImBuf(searchibuf); diff --git a/source/blender/blenkernel/intern/tracking_stabilize.cc b/source/blender/blenkernel/intern/tracking_stabilize.cc index a230c57b636..b55b94d9e7c 100644 --- a/source/blender/blenkernel/intern/tracking_stabilize.cc +++ b/source/blender/blenkernel/intern/tracking_stabilize.cc @@ -1356,10 +1356,10 @@ ImBuf *BKE_tracking_stabilize_frame( /* Allocate frame for stabilization result, copy alpha mode and color-space. */ ibuf_flags = 0; - if (ibuf->rect) { + if (ibuf->byte_buffer.data) { ibuf_flags |= IB_rect; } - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { ibuf_flags |= IB_rectfloat; } @@ -1402,7 +1402,7 @@ ImBuf *BKE_tracking_stabilize_frame( BLI_task_parallel_range( 0, tmpibuf->y, &data, tracking_stabilize_frame_interpolation_cb, &settings); - if (tmpibuf->rect_float) { + if (tmpibuf->float_buffer.data) { tmpibuf->userflags |= IB_RECT_INVALID; } diff --git a/source/blender/blenkernel/intern/tracking_util.cc b/source/blender/blenkernel/intern/tracking_util.cc index 8228f12750a..f8d457dca9c 100644 --- a/source/blender/blenkernel/intern/tracking_util.cc +++ b/source/blender/blenkernel/intern/tracking_util.cc @@ -625,16 +625,14 @@ static ImBuf *make_grayscale_ibuf_copy(ImBuf *ibuf) */ const size_t num_pixels = size_t(grayscale->x) * size_t(grayscale->y); grayscale->channels = 1; - if ((grayscale->rect_float = MEM_cnew_array(num_pixels, "tracking grayscale image")) != - nullptr) - { - grayscale->mall |= IB_rectfloat; - grayscale->flags |= IB_rectfloat; + float *rect_float = MEM_cnew_array(num_pixels, "tracking grayscale image"); + if (rect_float != nullptr) { + IMB_assign_float_buffer(grayscale, rect_float, IB_TAKE_OWNERSHIP); for (int i = 0; i < grayscale->x * grayscale->y; i++) { - const float *pixel = ibuf->rect_float + ibuf->channels * i; + const float *pixel = ibuf->float_buffer.data + ibuf->channels * i; - grayscale->rect_float[i] = 0.2126f * pixel[0] + 0.7152f * pixel[1] + 0.0722f * pixel[2]; + rect_float[i] = 0.2126f * pixel[0] + 0.7152f * pixel[1] + 0.0722f * pixel[2]; } } @@ -643,8 +641,8 @@ static ImBuf *make_grayscale_ibuf_copy(ImBuf *ibuf) static void ibuf_to_float_image(const ImBuf *ibuf, libmv_FloatImage *float_image) { - BLI_assert(ibuf->rect_float != nullptr); - float_image->buffer = ibuf->rect_float; + BLI_assert(ibuf->float_buffer.data != nullptr); + float_image->buffer = ibuf->float_buffer.data; float_image->width = ibuf->x; float_image->height = ibuf->y; float_image->channels = ibuf->channels; @@ -655,13 +653,11 @@ static ImBuf *float_image_to_ibuf(libmv_FloatImage *float_image) ImBuf *ibuf = IMB_allocImBuf(float_image->width, float_image->height, 32, 0); size_t num_total_channels = size_t(ibuf->x) * size_t(ibuf->y) * float_image->channels; ibuf->channels = float_image->channels; - if ((ibuf->rect_float = MEM_cnew_array(num_total_channels, "tracking grayscale image")) != - nullptr) - { - ibuf->mall |= IB_rectfloat; - ibuf->flags |= IB_rectfloat; + float *rect_float = MEM_cnew_array(num_total_channels, "tracking grayscale image"); + if (rect_float != nullptr) { + IMB_assign_float_buffer(ibuf, rect_float, IB_TAKE_OWNERSHIP); - memcpy(ibuf->rect_float, float_image->buffer, num_total_channels * sizeof(float)); + memcpy(rect_float, float_image->buffer, num_total_channels * sizeof(float)); } return ibuf; } @@ -700,7 +696,7 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor, final_ibuf = IMB_allocImBuf(width, height, 32, IB_rectfloat); - if (orig_ibuf->rect_float != nullptr) { + if (orig_ibuf->float_buffer.data != nullptr) { IMB_rectcpy(final_ibuf, orig_ibuf, dst_offset_x, @@ -721,8 +717,8 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor, int dst_x = x + dst_offset_x, dst_y = y + dst_offset_y; int dst_index = (dst_y * width + dst_x) * 4, src_index = (src_y * orig_ibuf->x + src_x) * 4; - rgba_uchar_to_float(final_ibuf->rect_float + dst_index, - (uchar *)orig_ibuf->rect + src_index); + rgba_uchar_to_float(final_ibuf->float_buffer.data + dst_index, + orig_ibuf->byte_buffer.data + src_index); } } } @@ -804,7 +800,7 @@ static libmv_CacheKey accessor_get_image_callback(struct libmv_FrameAccessorUser ibuf = accessor_get_ibuf(accessor, clip_index, frame, input_mode, downscale, region, transform); if (ibuf) { - *destination = ibuf->rect_float; + *destination = ibuf->float_buffer.data; *width = ibuf->x; *height = ibuf->y; *channels = ibuf->channels; diff --git a/source/blender/blenlib/BLI_function_ref.hh b/source/blender/blenlib/BLI_function_ref.hh index 9f1cba83034..2aa2769b99f 100644 --- a/source/blender/blenlib/BLI_function_ref.hh +++ b/source/blender/blenlib/BLI_function_ref.hh @@ -111,7 +111,8 @@ template class FunctionRef { */ template>, FunctionRef>))> + !std::is_same_v>, FunctionRef>)), + BLI_ENABLE_IF((std::is_invocable_r_v))> FunctionRef(Callable &&callable) : callback_(callback_fn>), callable_(intptr_t(&callable)) diff --git a/source/blender/blenlib/BLI_index_range.hh b/source/blender/blenlib/BLI_index_range.hh index 7f1266c6716..7991f68c5bc 100644 --- a/source/blender/blenlib/BLI_index_range.hh +++ b/source/blender/blenlib/BLI_index_range.hh @@ -105,6 +105,11 @@ class IndexRange { return a.current_ == b.current_; } + constexpr friend int64_t operator-(const Iterator &a, const Iterator &b) + { + return a.current_ - b.current_; + } + constexpr int64_t operator*() const { return current_; @@ -151,6 +156,11 @@ class IndexRange { return size_; } + constexpr IndexRange index_range() const + { + return IndexRange(size_); + } + /** * Returns true if the size is zero. */ diff --git a/source/blender/blenlib/BLI_linear_allocator.hh b/source/blender/blenlib/BLI_linear_allocator.hh index a897845db45..a4d7a357b63 100644 --- a/source/blender/blenlib/BLI_linear_allocator.hh +++ b/source/blender/blenlib/BLI_linear_allocator.hh @@ -16,24 +16,30 @@ namespace blender { +/** + * If enabled, #LinearAllocator keeps track of how much memory it owns and how much it has + * allocated. + */ +// #define BLI_DEBUG_LINEAR_ALLOCATOR_SIZE + template class LinearAllocator : NonCopyable, NonMovable { private: BLI_NO_UNIQUE_ADDRESS Allocator allocator_; - Vector owned_buffers_; - Vector> unused_borrowed_buffers_; + Vector owned_buffers_; uintptr_t current_begin_; uintptr_t current_end_; -#ifdef DEBUG - int64_t debug_allocated_amount_ = 0; -#endif - /* Buffers larger than that are not packed together with smaller allocations to avoid wasting * memory. */ constexpr static inline int64_t large_buffer_threshold = 4096; public: +#ifdef BLI_DEBUG_LINEAR_ALLOCATOR_SIZE + int64_t user_requested_size_ = 0; + int64_t owned_allocation_size_ = 0; +#endif + LinearAllocator() { current_begin_ = 0; @@ -65,8 +71,8 @@ template class LinearAllocator : NonCopya const uintptr_t potential_allocation_end = potential_allocation_begin + size; if (potential_allocation_end <= current_end_) { -#ifdef DEBUG - debug_allocated_amount_ += size; +#ifdef BLI_DEBUG_LINEAR_ALLOCATOR_SIZE + user_requested_size_ += size; #endif current_begin_ = potential_allocation_end; return reinterpret_cast(potential_allocation_begin); @@ -75,6 +81,9 @@ template class LinearAllocator : NonCopya this->allocate_new_buffer(size + alignment, alignment); return this->allocate(size, alignment); } +#ifdef BLI_DEBUG_LINEAR_ALLOCATOR_SIZE + user_requested_size_ += size; +#endif return this->allocator_large_buffer(size, alignment); }; @@ -189,9 +198,11 @@ template class LinearAllocator : NonCopya * Tell the allocator to use up the given memory buffer, before allocating new memory from the * system. */ - void provide_buffer(void *buffer, uint size) + void provide_buffer(void *buffer, const int64_t size) { - unused_borrowed_buffers_.append(Span(static_cast(buffer), size)); + BLI_assert(owned_buffers_.is_empty()); + current_begin_ = uintptr_t(buffer); + current_end_ = current_begin_ + size; } template @@ -200,19 +211,28 @@ template class LinearAllocator : NonCopya this->provide_buffer(aligned_buffer.ptr(), Size); } + /** + * This allocator takes ownership of the buffers owned by `other`. Therefor, when `other` is + * destructed, memory allocated using it is not freed. + * + * Note that the caller is responsible for making sure that buffers passed into #provide_buffer + * of `other` live at least as long as this allocator. + */ + void transfer_ownership_from(LinearAllocator<> &other) + { + owned_buffers_.extend(other.owned_buffers_); +#ifdef BLI_DEBUG_LINEAR_ALLOCATOR_SIZE + user_requested_size_ += other.user_requested_size_; + owned_allocation_size_ += other.owned_allocation_size_; +#endif + other.owned_buffers_.clear(); + std::destroy_at(&other); + new (&other) LinearAllocator<>(); + } + private: void allocate_new_buffer(int64_t min_allocation_size, int64_t min_alignment) { - for (int64_t i : unused_borrowed_buffers_.index_range()) { - Span buffer = unused_borrowed_buffers_[i]; - if (buffer.size() >= min_allocation_size) { - unused_borrowed_buffers_.remove_and_reorder(i); - current_begin_ = uintptr_t(buffer.begin()); - current_end_ = uintptr_t(buffer.end()); - return; - } - } - /* Possibly allocate more bytes than necessary for the current allocation. This way more small * allocations can be packed together. Large buffers are allocated exactly to avoid wasting too * much memory. */ @@ -224,16 +244,23 @@ template class LinearAllocator : NonCopya std::max(size_in_bytes, grow_size)); } - void *buffer = allocator_.allocate(size_in_bytes, min_alignment, __func__); - owned_buffers_.append(buffer); + void *buffer = this->allocated_owned(size_in_bytes, min_alignment); current_begin_ = uintptr_t(buffer); current_end_ = current_begin_ + size_in_bytes; } void *allocator_large_buffer(const int64_t size, const int64_t alignment) + { + return this->allocated_owned(size, alignment); + } + + void *allocated_owned(const int64_t size, const int64_t alignment) { void *buffer = allocator_.allocate(size, alignment, __func__); owned_buffers_.append(buffer); +#ifdef BLI_DEBUG_LINEAR_ALLOCATOR_SIZE + owned_allocation_size_ += size; +#endif return buffer; } }; diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index 027f0c72327..3a8756c921d 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -285,7 +285,8 @@ BLI_INLINE void BLI_listbase_clear(struct ListBase *lb) lb->first = lb->last = (void *)0; } -/** Validate the integrity of a given ListBase, returns `true` if evrything is OK, false otherwise. +/** Validate the integrity of a given ListBase, returns `true` if everything is OK, false + * otherwise. */ bool BLI_listbase_validate(struct ListBase *lb); diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h index 5cfeeeeeebc..87335c2a214 100644 --- a/source/blender/blenlib/BLI_path_util.h +++ b/source/blender/blenlib/BLI_path_util.h @@ -621,7 +621,7 @@ bool BLI_path_frame_check_chars(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUS /** \} */ /* -------------------------------------------------------------------- */ -/** \name Blender Spesific File Relative Paths +/** \name Blender Specific File Relative Paths * \{ */ /** diff --git a/source/blender/blenlib/BLI_span.hh b/source/blender/blenlib/BLI_span.hh index ddbe42b6706..916e42625ce 100644 --- a/source/blender/blenlib/BLI_span.hh +++ b/source/blender/blenlib/BLI_span.hh @@ -531,6 +531,14 @@ template class MutableSpan { return size_; } + /** + * Returns the number of bytes referenced by this Span. + */ + constexpr int64_t size_in_bytes() const + { + return sizeof(T) * size_; + } + /** * Returns true if the size is zero. */ diff --git a/source/blender/blenlib/BLI_task.hh b/source/blender/blenlib/BLI_task.hh index 60585e35099..55f814e2cfb 100644 --- a/source/blender/blenlib/BLI_task.hh +++ b/source/blender/blenlib/BLI_task.hh @@ -30,6 +30,7 @@ # endif #endif +#include "BLI_function_ref.hh" #include "BLI_index_range.hh" #include "BLI_lazy_threading.hh" #include "BLI_utildefines.h" @@ -37,7 +38,7 @@ namespace blender::threading { template -void parallel_for_each(Range &&range, const Function &function) +inline void parallel_for_each(Range &&range, const Function &function) { #ifdef WITH_TBB tbb::parallel_for_each(range, function); @@ -48,27 +49,45 @@ void parallel_for_each(Range &&range, const Function &function) #endif } +namespace detail { +void parallel_for_impl(IndexRange range, + int64_t grain_size, + FunctionRef function); +} // namespace detail + template -void parallel_for(IndexRange range, int64_t grain_size, const Function &function) +inline void parallel_for(IndexRange range, int64_t grain_size, const Function &function) { - if (range.size() == 0) { + if (range.is_empty()) { return; } -#ifdef WITH_TBB - /* Invoking tbb for small workloads has a large overhead. */ - if (range.size() >= grain_size) { - lazy_threading::send_hint(); - tbb::parallel_for( - tbb::blocked_range(range.first(), range.one_after_last(), grain_size), - [&](const tbb::blocked_range &subrange) { - function(IndexRange(subrange.begin(), subrange.size())); - }); + if (range.size() <= grain_size) { + function(range); return; } -#else - UNUSED_VARS(grain_size); -#endif - function(range); + detail::parallel_for_impl(range, grain_size, function); +} + +/** + * Move the sub-range boundaries down to the next aligned index. The "global" begin and end + * remain fixed though. + */ +inline IndexRange align_sub_range(const IndexRange unaligned_range, + const int64_t alignment, + const IndexRange global_range) +{ + const int64_t global_begin = global_range.start(); + const int64_t global_end = global_range.one_after_last(); + const int64_t alignment_mask = ~(alignment - 1); + + const int64_t unaligned_begin = unaligned_range.start(); + const int64_t unaligned_end = unaligned_range.one_after_last(); + const int64_t aligned_begin = std::max(global_begin, unaligned_begin & alignment_mask); + const int64_t aligned_end = unaligned_end == global_end ? + unaligned_end : + std::max(global_begin, unaligned_end & alignment_mask); + const IndexRange aligned_range{aligned_begin, aligned_end - aligned_begin}; + return aligned_range; } /** @@ -79,34 +98,23 @@ void parallel_for(IndexRange range, int64_t grain_size, const Function &function * larger, which means that work is distributed less evenly. */ template -void parallel_for_aligned(const IndexRange range, - const int64_t grain_size, - const int64_t alignment, - const Function &function) +inline void parallel_for_aligned(const IndexRange range, + const int64_t grain_size, + const int64_t alignment, + const Function &function) { - const int64_t global_begin = range.start(); - const int64_t global_end = range.one_after_last(); - const int64_t alignment_mask = ~(alignment - 1); parallel_for(range, grain_size, [&](const IndexRange unaligned_range) { - /* Move the sub-range boundaries down to the next aligned index. The "global" begin and end - * remain fixed though. */ - const int64_t unaligned_begin = unaligned_range.start(); - const int64_t unaligned_end = unaligned_range.one_after_last(); - const int64_t aligned_begin = std::max(global_begin, unaligned_begin & alignment_mask); - const int64_t aligned_end = unaligned_end == global_end ? - unaligned_end : - std::max(global_begin, unaligned_end & alignment_mask); - const IndexRange aligned_range{aligned_begin, aligned_end - aligned_begin}; + const IndexRange aligned_range = align_sub_range(unaligned_range, alignment, range); function(aligned_range); }); } template -Value parallel_reduce(IndexRange range, - int64_t grain_size, - const Value &identity, - const Function &function, - const Reduction &reduction) +inline Value parallel_reduce(IndexRange range, + int64_t grain_size, + const Value &identity, + const Function &function, + const Reduction &reduction) { #ifdef WITH_TBB if (range.size() >= grain_size) { @@ -125,11 +133,30 @@ Value parallel_reduce(IndexRange range, return function(range, identity); } +template +inline Value parallel_reduce_aligned(const IndexRange range, + const int64_t grain_size, + const int64_t alignment, + const Value &identity, + const Function &function, + const Reduction &reduction) +{ + parallel_reduce( + range, + grain_size, + identity, + [&](const IndexRange unaligned_range, const Value &ident) { + const IndexRange aligned_range = align_sub_range(unaligned_range, alignment, range); + function(aligned_range, ident); + }, + reduction); +} + /** * Execute all of the provided functions. The functions might be executed in parallel or in serial * or some combination of both. */ -template void parallel_invoke(Functions &&...functions) +template inline void parallel_invoke(Functions &&...functions) { #ifdef WITH_TBB tbb::parallel_invoke(std::forward(functions)...); @@ -144,7 +171,7 @@ template void parallel_invoke(Functions &&...functions) * tasks. */ template -void parallel_invoke(const bool use_threading, Functions &&...functions) +inline void parallel_invoke(const bool use_threading, Functions &&...functions) { if (use_threading) { lazy_threading::send_hint(); @@ -156,7 +183,7 @@ void parallel_invoke(const bool use_threading, Functions &&...functions) } /** See #BLI_task_isolate for a description of what isolating a task means. */ -template void isolate_task(const Function &function) +template inline void isolate_task(const Function &function) { #ifdef WITH_TBB lazy_threading::ReceiverIsolation isolation; diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index 0c976a59093..3340f61c7c2 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -403,7 +403,7 @@ int BLI_rename_overwrite(const char *from, const char *to) * Support for checking the files aren't the same could be added, however path comparison * alone is *not* a guarantee the files are different (given the possibility of accessing * the same file through different paths via symbolic-links), we could instead support a - * verizon of Python's * `os.path.samefile(..)` which compares the I-node & device. + * version of Python's `os.path.samefile(..)` which compares the I-node & device. * In this particular case we would not want to follow symbolic-links as well. * Since this functionality isn't required at the moment, leave this as-is. * Noting it as a potential improvement. */ diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index 62474e42fe8..516651fdb89 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -352,7 +352,7 @@ void mat3_normalized_to_quat_fast(float q[4], const float mat[3][3]) BLI_assert(!(q[0] < 0.0f)); - /* Sometimes normalisation is necessary due to round-off errors in the above + /* Sometimes normalization is necessary due to round-off errors in the above * calculations. The comparison here uses tighter tolerances than * BLI_ASSERT_UNIT_QUAT(), so it's likely that even after a few more * transformations the quaternion will still be considered unit-ish. */ diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index 3a00932851c..2f79159f1ea 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -350,8 +350,8 @@ static int path_normalize_impl(char *path, bool check_blend_relative_prefix) * as these directories are expected to be skipped. */ BLI_assert(!IS_PARENT_DIR(start)); const size_t start_len = path_len - (start - path); - memmove(path_first_non_slash_part, start, start_len + 1); BLI_assert(strlen(start) == start_len); + memmove(path_first_non_slash_part, start, start_len + 1); path_len -= start - path_first_non_slash_part; BLI_assert(strlen(path) == path_len); } @@ -963,7 +963,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); - BLI_snprintf(frame_str, sizeof(frame_str), "%.*d", ch_span, frame); + SNPRINTF(frame_str, "%.*d", ch_span, frame); BLI_str_replace_range(path, path_maxncpy, ch_sta, ch_end, frame_str); return true; } @@ -983,7 +983,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); - BLI_snprintf(frame_str, sizeof(frame_str), "%.*d-%.*d", ch_span, sta, ch_span, end); + SNPRINTF(frame_str, "%.*d-%.*d", ch_span, sta, ch_span, end); BLI_str_replace_range(path, path_maxncpy, ch_sta, ch_end, frame_str); return true; } diff --git a/source/blender/blenlib/intern/string_cursor_utf8.c b/source/blender/blenlib/intern/string_cursor_utf8.c index 861f332cbb5..14215b65cfe 100644 --- a/source/blender/blenlib/intern/string_cursor_utf8.c +++ b/source/blender/blenlib/intern/string_cursor_utf8.c @@ -344,7 +344,7 @@ void BLI_str_cursor_step_bounds_utf8( BLI_str_cursor_step_utf8(str, str_maxlen, r_start, STRCUR_DIR_PREV, STRCUR_JUMP_DELIM, false); } if ((prev >= next) && (next != STRCUR_DELIM_NONE)) { - /* Expand forward if we are between similar content, after whitespace, or at beginning. */ + /* Expand forward if we are between similar content. */ BLI_str_cursor_step_utf8(str, str_maxlen, r_end, STRCUR_DIR_NEXT, STRCUR_JUMP_DELIM, false); } } @@ -361,11 +361,11 @@ void BLI_str_cursor_step_bounds_utf32( *r_end = pos; if ((prev <= next) && (prev != STRCUR_DELIM_NONE)) { - /* Expand backward if we are between similar content, before whitespace, or at end. */ + /* Expand backward if we are between similar content. */ BLI_str_cursor_step_utf32(str, str_maxlen, r_start, STRCUR_DIR_PREV, STRCUR_JUMP_DELIM, false); } if ((prev >= next) && (next != STRCUR_DELIM_NONE)) { - /* Expand forward if we are between similar content, after whitespace, or at beginning. */ + /* Expand forward if we are between similar content. */ BLI_str_cursor_step_utf32(str, str_maxlen, r_end, STRCUR_DIR_NEXT, STRCUR_JUMP_DELIM, false); } } diff --git a/source/blender/blenlib/intern/task_range.cc b/source/blender/blenlib/intern/task_range.cc index 20551aba93b..59060d8c872 100644 --- a/source/blender/blenlib/intern/task_range.cc +++ b/source/blender/blenlib/intern/task_range.cc @@ -14,6 +14,7 @@ #include "BLI_lazy_threading.hh" #include "BLI_task.h" +#include "BLI_task.hh" #include "BLI_threads.h" #include "atomic_ops.h" @@ -154,3 +155,28 @@ int BLI_task_parallel_thread_id(const TaskParallelTLS * /*tls*/) return 0; #endif } + +namespace blender::threading::detail { + +void parallel_for_impl(const IndexRange range, + const int64_t grain_size, + const FunctionRef function) +{ +#ifdef WITH_TBB + /* Invoking tbb for small workloads has a large overhead. */ + if (range.size() >= grain_size) { + lazy_threading::send_hint(); + tbb::parallel_for( + tbb::blocked_range(range.first(), range.one_after_last(), grain_size), + [function](const tbb::blocked_range &subrange) { + function(IndexRange(subrange.begin(), subrange.size())); + }); + return; + } +#else + UNUSED_VARS(grain_size); +#endif + function(range); +} + +} // namespace blender::threading::detail diff --git a/source/blender/blenlib/tests/BLI_function_ref_test.cc b/source/blender/blenlib/tests/BLI_function_ref_test.cc index ea6334dd7ed..112b2a91507 100644 --- a/source/blender/blenlib/tests/BLI_function_ref_test.cc +++ b/source/blender/blenlib/tests/BLI_function_ref_test.cc @@ -130,4 +130,23 @@ TEST(function_ref, InitializeWithNull) EXPECT_FALSE(f); } +static int overload_test(const FunctionRef /*fn*/) +{ + return 1; +} + +static int overload_test(const FunctionRef /*fn*/) +{ + return 2; +} + +TEST(function_ref, OverloadSelection) +{ + const auto fn_1 = [](std::string /*x*/) {}; + const auto fn_2 = [](int /*x*/) {}; + + EXPECT_EQ(overload_test(fn_1), 1); + EXPECT_EQ(overload_test(fn_2), 2); +} + } // namespace blender::tests diff --git a/source/blender/blenlib/tests/BLI_linear_allocator_test.cc b/source/blender/blenlib/tests/BLI_linear_allocator_test.cc index 2ed1786f9e0..612c436ae6a 100644 --- a/source/blender/blenlib/tests/BLI_linear_allocator_test.cc +++ b/source/blender/blenlib/tests/BLI_linear_allocator_test.cc @@ -149,4 +149,23 @@ TEST(linear_allocator, ConstructArray) } } +TEST(linear_allocator, TransferOwnership) +{ + LinearAllocator<> main_allocator; + MutableSpan values; + + /* Allocate a large buffer that is likely to be given back to the system when freed. This test + * essentially only fails by crashing with a segfault. */ + const int size = 1'000'000; + const int value = 42; + const int index = 500'000; + { + LinearAllocator<> nested_allocator; + values = nested_allocator.allocate_array(size); + values[index] = value; + main_allocator.transfer_ownership_from(nested_allocator); + } + EXPECT_EQ(values[index], value); +} + } // namespace blender::tests diff --git a/source/blender/blenlib/tests/BLI_path_util_test.cc b/source/blender/blenlib/tests/BLI_path_util_test.cc index 58efd5abbf6..06bf9211370 100644 --- a/source/blender/blenlib/tests/BLI_path_util_test.cc +++ b/source/blender/blenlib/tests/BLI_path_util_test.cc @@ -117,6 +117,10 @@ TEST(path_util, Normalize_UnbalancedAbsolute) NORMALIZE("/a/b/c/../../../../../d", "/d"); NORMALIZE("/a/b/c/../../../../d", "/d"); NORMALIZE("/a/b/c/../../../d", "/d"); + + /* Use a longer path as it may hit corner cases. */ + NORMALIZE("/home/username/Downloads/../../../../../Users/Example/Desktop/test.jpg", + "/Users/Example/Desktop/test.jpg"); } /* #BLI_path_normalize: with relative paths that result in leading "../". */ diff --git a/source/blender/blenlib/tests/BLI_string_test.cc b/source/blender/blenlib/tests/BLI_string_test.cc index 253f76d62b2..f3f03a9f9dc 100644 --- a/source/blender/blenlib/tests/BLI_string_test.cc +++ b/source/blender/blenlib/tests/BLI_string_test.cc @@ -30,7 +30,7 @@ TEST(string, StrCopyUTF8_ASCII) const char src[] = {__VA_ARGS__, 0}; \ char dst[sizeof(src)]; \ memset(dst, 0xff, sizeof(dst)); \ - BLI_strncpy_utf8(dst, src, sizeof(dst)); \ + STRNCPY_UTF8(dst, src); \ EXPECT_EQ(strlen(dst), sizeof(dst) - 1); \ EXPECT_STREQ(dst, src); \ } @@ -70,7 +70,7 @@ TEST(string, StrCopyUTF8_TruncateEncoding) EXPECT_EQ(BLI_str_utf8_size(src), byte_size); \ char dst[sizeof(src)]; \ memset(dst, 0xff, sizeof(dst)); \ - BLI_strncpy_utf8(dst, src, sizeof(dst)); \ + STRNCPY_UTF8(dst, src); \ EXPECT_EQ(strlen(dst), sizeof(dst) - 1); \ EXPECT_STREQ(dst, src); \ BLI_strncpy_utf8(dst, src, sizeof(dst) - 1); \ @@ -97,13 +97,13 @@ TEST(string, StrCopyUTF8_TerminateEncodingEarly) EXPECT_EQ(BLI_str_utf8_size(src), byte_size); \ char dst[sizeof(src)]; \ memset(dst, 0xff, sizeof(dst)); \ - BLI_strncpy_utf8(dst, src, sizeof(dst)); \ + STRNCPY_UTF8(dst, src); \ EXPECT_EQ(strlen(dst), sizeof(dst) - 1); \ EXPECT_STREQ(dst, src); \ for (int i = sizeof(dst) - 1; i > 1; i--) { \ src[i] = '\0'; \ memset(dst, 0xff, sizeof(dst)); \ - const int dst_copied = BLI_strncpy_utf8_rlen(dst, src, sizeof(dst)); \ + const int dst_copied = STRNCPY_UTF8_RLEN(dst, src); \ EXPECT_STREQ(dst, src); \ EXPECT_EQ(strlen(dst), i); \ EXPECT_EQ(dst_copied, i); \ diff --git a/source/blender/blenloader/BLO_read_write.h b/source/blender/blenloader/BLO_read_write.h index b1a31e56bac..f5e4c9f76c9 100644 --- a/source/blender/blenloader/BLO_read_write.h +++ b/source/blender/blenloader/BLO_read_write.h @@ -271,12 +271,15 @@ struct BlendFileReadReport *BLO_read_data_reports(BlendDataReader *reader); * However, now only pointers to ID data blocks are updated. * \{ */ -/** Search for the new address of given `id`, during liblinking part of blendfile reading process. +/** + * Search for the new address of given `id`, + * during library linking part of blend-file reading process. * - * \param self_id the ID owner of the given `id` pointer. Note that it may be an embedded ID. - * \param do_linked_only If `true`, only return found pointer if it is a linked ID. Used to - * preventlinked data to point to local IDs. - * \return the new address of the given ID pointer, or null if not found. */ + * \param self_id: the ID owner of the given `id` pointer. Note that it may be an embedded ID. + * \param do_linked_only: If `true`, only return found pointer if it is a linked ID. Used to + * prevent linked data to point to local IDs. + * \return the new address of the given ID pointer, or null if not found. + */ ID *BLO_read_get_new_id_address(BlendLibReader *reader, struct ID *self_id, const bool do_linked_only, diff --git a/source/blender/blenloader/intern/blend_validate.cc b/source/blender/blenloader/intern/blend_validate.cc index f04fdee2288..ae9c26d3cba 100644 --- a/source/blender/blenloader/intern/blend_validate.cc +++ b/source/blender/blenloader/intern/blend_validate.cc @@ -199,7 +199,7 @@ bool BLO_main_validate_shapekeys(Main *bmain, ReportList *reports) shapekey->from); /* NOTE: also need to remap UI data ID pointers here, since `bmain` is not the current * `G_MAIN`, default UI-handling remapping callback (defined by call to - * `BKE_library_callback_remap_editor_id_reference_set`) won't work on exoected data here. */ + * `BKE_library_callback_remap_editor_id_reference_set`) won't work on expected data here. */ BKE_id_delete_ex(bmain, shapekey, ID_REMAP_FORCE_UI_POINTERS); } diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index 03defc23049..b3fa2dd58f6 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -3572,6 +3572,9 @@ static void do_versions_after_linking(FileData *fd, Main *main) if (!main->is_read_invalid) { do_versions_after_linking_300(fd, main); } + if (!main->is_read_invalid) { + do_versions_after_linking_400(fd, main); + } if (!main->is_read_invalid) { do_versions_after_linking_cycles(main); } diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h index 51d8fd838d6..d057c3702ee 100644 --- a/source/blender/blenloader/intern/readfile.h +++ b/source/blender/blenloader/intern/readfile.h @@ -98,7 +98,7 @@ typedef struct FileData { /** * Store mapping from old ID pointers (the values they have in the .blend file) to new ones, * typically from value in `bhead->old` to address in memory where the ID was read. - * Used during liblinking process (see #lib_link_all). + * Used during library-linking process (see #lib_link_all). */ struct OldNewMap *libmap; @@ -115,7 +115,7 @@ typedef struct FileData { /** Used for undo. */ ListBase *old_mainlist; /** - * IDMap using uuids as keys of all the old IDs in the old bmain. Used during undo to find a + * IDMap using UUID's as keys of all the old IDs in the old bmain. Used during undo to find a * matching old data when reading a new ID. */ struct IDNameLib_Map *old_idmap_uuid; @@ -234,6 +234,7 @@ void do_versions_after_linking_270(struct Main *bmain); void do_versions_after_linking_280(struct FileData *fd, struct Main *bmain); void do_versions_after_linking_290(struct FileData *fd, struct Main *bmain); void do_versions_after_linking_300(struct FileData *fd, struct Main *bmain); +void do_versions_after_linking_400(struct FileData *fd, struct Main *bmain); void do_versions_after_linking_cycles(struct Main *bmain); /** diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index 9b140705c2c..16162d30184 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -996,8 +996,8 @@ void blo_do_versions_250(FileData *fd, Library *UNUSED(lib), Main *bmain) * to the evaluated #Mesh, so here we ensure that the basis * shape key is always set in the mesh coordinates. */ for (me = bmain->meshes.first; me; me = me->id.next) { - if ((key = blo_do_versions_newlibadr(fd, &me->id, ID_IS_LINKED(me), me->key)) && - key->refkey) { + if ((key = blo_do_versions_newlibadr(fd, &me->id, ID_IS_LINKED(me), me->key)) && key->refkey) + { data = key->refkey->data; tot = MIN2(me->totvert, key->refkey->totelem); MVert *verts = (MVert *)CustomData_get_layer_for_write(&me->vdata, CD_MVERT, me->totvert); @@ -1008,8 +1008,8 @@ void blo_do_versions_250(FileData *fd, Library *UNUSED(lib), Main *bmain) } for (lt = bmain->lattices.first; lt; lt = lt->id.next) { - if ((key = blo_do_versions_newlibadr(fd, <->id, ID_IS_LINKED(lt), lt->key)) && - key->refkey) { + if ((key = blo_do_versions_newlibadr(fd, <->id, ID_IS_LINKED(lt), lt->key)) && key->refkey) + { data = key->refkey->data; tot = MIN2(lt->pntsu * lt->pntsv * lt->pntsw, key->refkey->totelem); @@ -1020,8 +1020,8 @@ void blo_do_versions_250(FileData *fd, Library *UNUSED(lib), Main *bmain) } for (cu = bmain->curves.first; cu; cu = cu->id.next) { - if ((key = blo_do_versions_newlibadr(fd, &cu->id, ID_IS_LINKED(cu), cu->key)) && - key->refkey) { + if ((key = blo_do_versions_newlibadr(fd, &cu->id, ID_IS_LINKED(cu), cu->key)) && key->refkey) + { data = key->refkey->data; for (nu = cu->nurb.first; nu; nu = nu->next) { diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 693b6a668e3..4b4e2b6b5f4 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -497,44 +497,6 @@ static bool do_versions_sequencer_color_balance_sop(Sequence *seq, void * /*user return true; } -static bNodeLink *find_connected_link(bNodeTree *ntree, bNodeSocket *in_socket) -{ - LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) { - if (link->tosock == in_socket) { - return link; - } - } - return nullptr; -} - -static void add_realize_instances_before_socket(bNodeTree *ntree, - bNode *node, - bNodeSocket *geometry_socket) -{ - BLI_assert(geometry_socket->type == SOCK_GEOMETRY); - bNodeLink *link = find_connected_link(ntree, geometry_socket); - if (link == nullptr) { - return; - } - - /* If the realize instances node is already before this socket, no need to continue. */ - if (link->fromnode->type == GEO_NODE_REALIZE_INSTANCES) { - return; - } - - bNode *realize_node = nodeAddStaticNode(nullptr, ntree, GEO_NODE_REALIZE_INSTANCES); - realize_node->parent = node->parent; - realize_node->locx = node->locx - 100; - realize_node->locy = node->locy; - nodeAddLink(ntree, - link->fromnode, - link->fromsock, - realize_node, - static_cast(realize_node->inputs.first)); - link->fromnode = realize_node; - link->fromsock = static_cast(realize_node->outputs.first); -} - /** * If a node used to realize instances implicitly and will no longer do so in 3.0, add a "Realize * Instances" node in front of it to avoid changing behavior. Don't do this if the node will be @@ -682,6 +644,11 @@ static bool seq_speed_factor_set(Sequence *seq, void *user_data) seq_speed_factor_fix_rna_path(seq, &scene->adt->drivers); } + /* Pitch value of 0 has been found in some files. This would cause problems. */ + if (seq->pitch <= 0.0f) { + seq->pitch = 1.0f; + } + seq->speed_factor = seq->pitch; } else { @@ -2214,6 +2181,46 @@ static void versioning_replace_legacy_mix_rgb_node(bNodeTree *ntree) } } +static void versioning_replace_legacy_glossy_node(bNodeTree *ntree) +{ + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { + if (node->type == SH_NODE_BSDF_GLOSSY_LEGACY) { + strcpy(node->idname, "ShaderNodeBsdfAnisotropic"); + node->type = SH_NODE_BSDF_GLOSSY; + } + } +} + +static void versioning_remove_microfacet_sharp_distribution(bNodeTree *ntree) +{ + /* Find all glossy, glass and refraction BSDF nodes that have their distribution + * set to SHARP and set them to GGX, disconnect any link to the Roughness input + * and set its value to zero. */ + LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { + if (!ELEM(node->type, SH_NODE_BSDF_GLOSSY, SH_NODE_BSDF_GLASS, SH_NODE_BSDF_REFRACTION)) { + continue; + } + if (node->custom1 != SHD_GLOSSY_SHARP_DEPRECATED) { + continue; + } + + node->custom1 = SHD_GLOSSY_GGX; + LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) { + if (!STREQ(socket->identifier, "Roughness")) { + continue; + } + + if (socket->link != nullptr) { + nodeRemLink(ntree, socket->link); + } + bNodeSocketValueFloat *socket_value = (bNodeSocketValueFloat *)socket->default_value; + socket_value->value = 0.0f; + + break; + } + } +} + static void version_fix_image_format_copy(Main *bmain, ImageFormatData *format) { /* Fix bug where curves in image format were not properly copied to file output @@ -2315,6 +2322,73 @@ static void version_ensure_missing_regions(ScrArea *area, SpaceLink *sl) } } +/** + * Change override RNA path from `frame_{start,end}` to `frame_{start,end}_raw`. + * See #102662. + */ +static void version_liboverride_nla_strip_frame_start_end(IDOverrideLibrary *liboverride, + const char *parent_rna_path, + NlaStrip *strip) +{ + if (!strip) { + return; + } + + /* Escape the strip name for inclusion in the RNA path. */ + char name_esc_strip[sizeof(strip->name) * 2]; + BLI_str_escape(name_esc_strip, strip->name, sizeof(name_esc_strip)); + + const std::string rna_path_strip = std::string(parent_rna_path) + ".strips[\"" + name_esc_strip + + "\"]"; + + { /* Rename .frame_start -> .frame_start_raw: */ + const std::string rna_path_prop = rna_path_strip + ".frame_start"; + BKE_lib_override_library_property_rna_path_change( + liboverride, rna_path_prop.c_str(), (rna_path_prop + "_raw").c_str()); + } + + { /* Rename .frame_end -> .frame_end_raw: */ + const std::string rna_path_prop = rna_path_strip + ".frame_end"; + BKE_lib_override_library_property_rna_path_change( + liboverride, rna_path_prop.c_str(), (rna_path_prop + "_raw").c_str()); + } + + { /* Remove .frame_start_ui: */ + const std::string rna_path_prop = rna_path_strip + ".frame_start_ui"; + BKE_lib_override_library_property_search_and_delete(liboverride, rna_path_prop.c_str()); + } + + { /* Remove .frame_end_ui: */ + const std::string rna_path_prop = rna_path_strip + ".frame_end_ui"; + BKE_lib_override_library_property_search_and_delete(liboverride, rna_path_prop.c_str()); + } + + /* Handle meta-strip contents. */ + LISTBASE_FOREACH (NlaStrip *, substrip, &strip->strips) { + version_liboverride_nla_strip_frame_start_end(liboverride, rna_path_strip.c_str(), substrip); + } +} + +/** Fix the `frame_start` and `frame_end` overrides on NLA strips. See #102662. */ +static void version_liboverride_nla_frame_start_end(ID *id, AnimData *adt, void * /*user_data*/) +{ + IDOverrideLibrary *liboverride = id->override_library; + if (!liboverride) { + return; + } + + int track_index; + LISTBASE_FOREACH_INDEX (NlaTrack *, track, &adt->nla_tracks, track_index) { + char *rna_path_track = BLI_sprintfN("animation_data.nla_tracks[%d]", track_index); + + LISTBASE_FOREACH (NlaStrip *, strip, &track->strips) { + version_liboverride_nla_strip_frame_start_end(liboverride, rna_path_track, strip); + } + + MEM_freeN(rna_path_track); + } +} + /* NOLINTNEXTLINE: readability-function-size */ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) { @@ -3249,20 +3323,6 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } } - if (!MAIN_VERSION_ATLEAST(bmain, 301, 5)) { - LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) { - if (ntree->type != NTREE_GEOMETRY) { - continue; - } - LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { - if (node->type != GEO_NODE_REALIZE_INSTANCES) { - continue; - } - node->custom1 |= GEO_NODE_REALIZE_INSTANCES_LEGACY_BEHAVIOR; - } - } - } - if (!MAIN_VERSION_ATLEAST(bmain, 301, 6)) { /* Add node storage for map range node. */ FOREACH_NODETREE_BEGIN (bmain, ntree, id) { @@ -4409,5 +4469,14 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) */ { /* Keep this block, even when empty. */ + + /* Convert anisotropic BSDF node to glossy BSDF. */ + FOREACH_NODETREE_BEGIN (bmain, ntree, id) { + versioning_replace_legacy_glossy_node(ntree); + versioning_remove_microfacet_sharp_distribution(ntree); + } + FOREACH_NODETREE_END; + + BKE_animdata_main_cb(bmain, version_liboverride_nla_frame_start_end, NULL); } } diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index 1fc1e0146ff..4eddad3ba1b 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -12,9 +12,11 @@ #include "BLI_assert.h" #include "BLI_listbase.h" +#include "BLI_set.hh" #include "BKE_main.h" #include "BKE_mesh_legacy_convert.h" +#include "BKE_node.hh" #include "BKE_tracking.h" #include "BLO_readfile.h" @@ -25,6 +27,11 @@ // static CLG_LogRef LOG = {"blo.readfile.doversion"}; +void do_versions_after_linking_400(FileData * /*fd*/, Main *bmain) +{ + UNUSED_VARS(bmain); +} + static void version_mesh_legacy_to_struct_of_array_format(Mesh &mesh) { BKE_mesh_legacy_convert_flags_to_selection_layers(&mesh); @@ -52,13 +59,6 @@ static void version_motion_tracking_legacy_camera_object(MovieClip &movieclip) BLI_assert(tracking_camera_object != nullptr); - /* NOTE: The regular .blend file saving converts the new format to the legacy format, but the - * auto-save one does not do this. Likely, the regular saving clears the new storage before - * write, so it can be used to make a decision here. - * - * The idea is basically to not override the new storage if it exists. This is only supposed to - * happen for auto-save files. */ - if (BLI_listbase_is_empty(&tracking_camera_object->tracks)) { tracking_camera_object->tracks = tracking.tracks_legacy; active_tracking_object->active_track = tracking.act_track_legacy; @@ -90,17 +90,29 @@ static void version_movieclips_legacy_camera_object(Main *bmain) } } +static void version_geometry_nodes_add_realize_instance_nodes(bNodeTree *ntree) +{ + LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree->nodes) { + if (STREQ(node->idname, "GeometryNodeMeshBoolean")) { + add_realize_instances_before_socket(ntree, node, nodeFindSocket(node, SOCK_IN, "Mesh 2")); + } + } +} + void blo_do_versions_400(FileData * /*fd*/, Library * /*lib*/, Main *bmain) { - // if (!MAIN_VERSION_ATLEAST(bmain, 400, 0)) { - /* This is done here because we will continue to write with the old format until 4.0, so we need - * to convert even "current" files. Keep the check commented out for now so the versioning isn't - * turned off right after the 4.0 bump. */ - LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) { - version_mesh_legacy_to_struct_of_array_format(*mesh); + if (!MAIN_VERSION_ATLEAST(bmain, 400, 1)) { + LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) { + version_mesh_legacy_to_struct_of_array_format(*mesh); + } + version_movieclips_legacy_camera_object(bmain); + } + + if (!MAIN_VERSION_ATLEAST(bmain, 400, 2)) { + LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) { + BKE_mesh_legacy_bevel_weight_to_generic(mesh); + } } - version_movieclips_legacy_camera_object(bmain); - // } /** * Versioning code until next subversion bump goes here. @@ -113,5 +125,11 @@ void blo_do_versions_400(FileData * /*fd*/, Library * /*lib*/, Main *bmain) */ { /* Keep this block, even when empty. */ + + LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) { + if (ntree->type == NTREE_GEOMETRY) { + version_geometry_nodes_add_realize_instance_nodes(ntree); + } + } } } diff --git a/source/blender/blenloader/intern/versioning_common.cc b/source/blender/blenloader/intern/versioning_common.cc index 50b636356cf..fa6d9899f4c 100644 --- a/source/blender/blenloader/intern/versioning_common.cc +++ b/source/blender/blenloader/intern/versioning_common.cc @@ -286,3 +286,40 @@ void node_tree_relink_with_socket_id_map(bNodeTree &ntree, } } } + +static blender::Vector find_connected_links(bNodeTree *ntree, bNodeSocket *in_socket) +{ + blender::Vector links; + LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) { + if (link->tosock == in_socket) { + links.append(link); + } + } + return links; +} + +void add_realize_instances_before_socket(bNodeTree *ntree, + bNode *node, + bNodeSocket *geometry_socket) +{ + BLI_assert(geometry_socket->type == SOCK_GEOMETRY); + blender::Vector links = find_connected_links(ntree, geometry_socket); + for (bNodeLink *link : links) { + /* If the realize instances node is already before this socket, no need to continue. */ + if (link->fromnode->type == GEO_NODE_REALIZE_INSTANCES) { + return; + } + + bNode *realize_node = nodeAddStaticNode(nullptr, ntree, GEO_NODE_REALIZE_INSTANCES); + realize_node->parent = node->parent; + realize_node->locx = node->locx - 100; + realize_node->locy = node->locy; + nodeAddLink(ntree, + link->fromnode, + link->fromsock, + realize_node, + static_cast(realize_node->inputs.first)); + link->fromnode = realize_node; + link->fromsock = static_cast(realize_node->outputs.first); + } +} diff --git a/source/blender/blenloader/intern/versioning_common.h b/source/blender/blenloader/intern/versioning_common.h index 8c142707fdd..82f382519a2 100644 --- a/source/blender/blenloader/intern/versioning_common.h +++ b/source/blender/blenloader/intern/versioning_common.h @@ -110,6 +110,10 @@ ARegion *do_versions_add_region(int regiontype, const char *name); void sequencer_init_preview_region(ARegion *region); +void add_realize_instances_before_socket(bNodeTree *ntree, + bNode *node, + bNodeSocket *geometry_socket); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenloader/intern/versioning_cycles.c b/source/blender/blenloader/intern/versioning_cycles.c index 3a4454ef7e3..07f7ae47c09 100644 --- a/source/blender/blenloader/intern/versioning_cycles.c +++ b/source/blender/blenloader/intern/versioning_cycles.c @@ -181,8 +181,8 @@ static void displacement_principled_nodes(bNode *node) static bool node_has_roughness(const bNode *node) { return ELEM(node->type, - SH_NODE_BSDF_ANISOTROPIC, SH_NODE_BSDF_GLASS, + SH_NODE_BSDF_GLOSSY_LEGACY, SH_NODE_BSDF_GLOSSY, SH_NODE_BSDF_REFRACTION); } diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index d93ecbbbc6c..5ccde7e44b0 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -964,18 +964,18 @@ static void bm_to_mesh_shape(BMesh *bm, static void assert_bmesh_has_no_mesh_only_attributes(const BMesh &bm) { (void)bm; /* Unused in the release builds. */ - BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_FLOAT3, "position") == nullptr); - BLI_assert(CustomData_get_layer_named(&bm.ldata, CD_PROP_FLOAT3, ".corner_vert") == nullptr); - BLI_assert(CustomData_get_layer_named(&bm.ldata, CD_PROP_FLOAT3, ".corner_edge") == nullptr); + BLI_assert(!CustomData_has_layer_named(&bm.vdata, CD_PROP_FLOAT3, "position")); + BLI_assert(!CustomData_has_layer_named(&bm.ldata, CD_PROP_FLOAT3, ".corner_vert")); + BLI_assert(!CustomData_has_layer_named(&bm.ldata, CD_PROP_FLOAT3, ".corner_edge")); /* The "hide" attributes are stored as flags on #BMesh. */ - BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_BOOL, ".hide_vert") == nullptr); - BLI_assert(CustomData_get_layer_named(&bm.edata, CD_PROP_BOOL, ".hide_edge") == nullptr); - BLI_assert(CustomData_get_layer_named(&bm.pdata, CD_PROP_BOOL, ".hide_poly") == nullptr); + BLI_assert(!CustomData_has_layer_named(&bm.vdata, CD_PROP_BOOL, ".hide_vert")); + BLI_assert(!CustomData_has_layer_named(&bm.edata, CD_PROP_BOOL, ".hide_edge")); + BLI_assert(!CustomData_has_layer_named(&bm.pdata, CD_PROP_BOOL, ".hide_poly")); /* The "selection" attributes are stored as flags on #BMesh. */ - BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_BOOL, ".select_vert") == nullptr); - BLI_assert(CustomData_get_layer_named(&bm.edata, CD_PROP_BOOL, ".select_edge") == nullptr); - BLI_assert(CustomData_get_layer_named(&bm.pdata, CD_PROP_BOOL, ".select_poly") == nullptr); + BLI_assert(!CustomData_has_layer_named(&bm.vdata, CD_PROP_BOOL, ".select_vert")); + BLI_assert(!CustomData_has_layer_named(&bm.edata, CD_PROP_BOOL, ".select_edge")); + BLI_assert(!CustomData_has_layer_named(&bm.pdata, CD_PROP_BOOL, ".select_poly")); } static void bmesh_to_mesh_calc_object_remap(Main &bmain, @@ -1276,6 +1276,9 @@ static void bm_to_mesh_verts(const BMesh &bm, bmesh_block_copy_to_mesh_attributes(info, vert_i, src_vert.head.data); any_loose_vert_local = any_loose_vert_local || src_vert.e == nullptr; } + if (any_loose_vert_local) { + any_loose_vert.store(true, std::memory_order_relaxed); + } if (!select_vert.is_empty()) { for (const int vert_i : range) { select_vert[vert_i] = BM_elem_flag_test(bm_verts[vert_i], BM_ELEM_SELECT); @@ -1341,7 +1344,7 @@ static void bm_to_mesh_edges(const BMesh &bm, }); if (!any_loose_edge) { - mesh.loose_edges_tag_none(); + mesh.tag_loose_edges_none(); } } diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 3f5dde9a155..69792071438 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -234,7 +234,7 @@ void _bmo_slot_copy(BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS], slot_dst->data.buf = NULL; slot_dst->len = slot_src->len; if (slot_dst->len) { - /* check dest has all flags enabled that the source has */ + /* Check destination has all flags enabled that the source has. */ const eBMOpSlotSubType_Elem src_elem_flag = (slot_src->slot_subtype.elem & BM_ALL_NOLOOP); const eBMOpSlotSubType_Elem dst_elem_flag = (slot_dst->slot_subtype.elem & BM_ALL_NOLOOP); diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 04aa678b6a6..aa3903e547b 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -336,6 +336,8 @@ typedef struct BevelParams { float pro_super_r; /** Bevel amount affected by weights on edges or verts. */ bool use_weights; + int bweight_offset_vert; + int bweight_offset_edge; /** Should bevel prefer to slide along edges rather than keep widths spec? */ bool loop_slide; /** Should offsets be limited by collisions? */ @@ -1279,9 +1281,12 @@ static void offset_meet_lines_percent_or_absolute(BevelParams *bp, d5 = bp->offset * BM_edge_calc_length(e5.e) / 100.0f; } if (bp->use_weights) { - CustomData *cd = &bp->bm->edata; - e1_wt = BM_elem_float_data_get(cd, e1->e, CD_BWEIGHT); - e2_wt = BM_elem_float_data_get(cd, e2->e, CD_BWEIGHT); + e1_wt = bp->bweight_offset_edge == -1 ? + 0.0f : + BM_ELEM_CD_GET_FLOAT(e1->e, bp->bweight_offset_edge); + e2_wt = bp->bweight_offset_edge == -1 ? + 0.0f : + BM_ELEM_CD_GET_FLOAT(e2->e, bp->bweight_offset_edge); } else { e1_wt = 1.0f; @@ -1607,9 +1612,10 @@ static bool offset_on_edge_between(BevelParams *bp, if (bp->offset_type == BEVEL_AMT_PERCENT) { float wt = 1.0; if (bp->use_weights) { - CustomData *cd = &bp->bm->edata; - wt = 0.5f * (BM_elem_float_data_get(cd, e1->e, CD_BWEIGHT) + - BM_elem_float_data_get(cd, e2->e, CD_BWEIGHT)); + wt = bp->bweight_offset_edge == -1 ? + 0.0f : + 0.5f * (BM_ELEM_CD_GET_FLOAT(e1->e, bp->bweight_offset_edge) + + BM_ELEM_CD_GET_FLOAT(e2->e, bp->bweight_offset_edge)); } interp_v3_v3v3(meetco, v->co, v2->co, wt * bp->offset / 100.0f); } @@ -6441,7 +6447,8 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) bv->offset *= weight; } else if (bp->use_weights) { - weight = BM_elem_float_data_get(&bm->vdata, v, CD_BWEIGHT); + weight = bp->bweight_offset_vert == -1 ? 0.0f : + BM_ELEM_CD_GET_FLOAT(v, bp->bweight_offset_vert); bv->offset *= weight; } /* Find center axis. NOTE: Don't use vert normal, can give unwanted results. */ @@ -6521,7 +6528,9 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) e->offset_r_spec = e->offset_l_spec; } if (bp->use_weights) { - weight = BM_elem_float_data_get(&bm->edata, e->e, CD_BWEIGHT); + weight = bp->bweight_offset_edge == -1 ? + 0.0f : + BM_ELEM_CD_GET_FLOAT(e->e, bp->bweight_offset_edge); e->offset_l_spec *= weight; e->offset_r_spec *= weight; } @@ -7755,6 +7764,10 @@ void BM_mesh_bevel(BMesh *bm, .pro_super_r = -logf(2.0) / logf(sqrtf(profile)), /* Convert to superellipse exponent. */ .affect_type = affect_type, .use_weights = use_weights, + .bweight_offset_vert = CustomData_get_offset_named( + &bm->vdata, CD_PROP_FLOAT, "bevel_weight_vert"), + .bweight_offset_edge = CustomData_get_offset_named( + &bm->edata, CD_PROP_FLOAT, "bevel_weight_edge"), .loop_slide = loop_slide, .limit_offset = limit_offset, .offset_adjust = (bp.affect_type != BEVEL_AFFECT_VERTICES) && diff --git a/source/blender/compositor/intern/COM_Debug.cc b/source/blender/compositor/intern/COM_Debug.cc index 83ab3adfc26..5ad5c456c46 100644 --- a/source/blender/compositor/intern/COM_Debug.cc +++ b/source/blender/compositor/intern/COM_Debug.cc @@ -452,7 +452,7 @@ void DebugInfo::export_operation(const NodeOperation *op, MemoryBuffer *render) const int num_channels = render->get_num_channels(); ImBuf *ibuf = IMB_allocImBuf(width, height, 8 * num_channels, IB_rectfloat); - MemoryBuffer mem_ibuf(ibuf->rect_float, 4, width, height); + MemoryBuffer mem_ibuf(ibuf->float_buffer.data, 4, width, height); mem_ibuf.copy_from(render, render->get_rect(), 0, num_channels, 0); const std::string file_name = operation_class_name(op) + "_" + std::to_string(op->get_id()) + diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cc b/source/blender/compositor/intern/COM_MemoryBuffer.cc index edff127c6c0..2a1f87990c5 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.cc +++ b/source/blender/compositor/intern/COM_MemoryBuffer.cc @@ -342,12 +342,12 @@ void MemoryBuffer::copy_from(const ImBuf *src, const int to_channel_offset, const bool ensure_linear_space) { - if (src->rect_float) { - const MemoryBuffer mem_buf(src->rect_float, src->channels, src->x, src->y, false); + if (src->float_buffer.data) { + const MemoryBuffer mem_buf(src->float_buffer.data, src->channels, src->x, src->y, false); copy_from(&mem_buf, area, channel_offset, elem_size, to_x, to_y, to_channel_offset); } - else if (src->rect) { - const uchar *uc_buf = (uchar *)src->rect; + else if (src->byte_buffer.data) { + const uchar *uc_buf = src->byte_buffer.data; const int elem_stride = src->channels; const int row_stride = elem_stride * src->x; copy_from(uc_buf, diff --git a/source/blender/compositor/operations/COM_ImageOperation.cc b/source/blender/compositor/operations/COM_ImageOperation.cc index e1ac5e42be3..ab176c26ecf 100644 --- a/source/blender/compositor/operations/COM_ImageOperation.cc +++ b/source/blender/compositor/operations/COM_ImageOperation.cc @@ -55,7 +55,8 @@ ImBuf *BaseImageOperation::get_im_buf() } ibuf = BKE_image_acquire_ibuf(image_, &iuser, nullptr); - if (ibuf == nullptr || (ibuf->rect == nullptr && ibuf->rect_float == nullptr)) { + if (ibuf == nullptr || (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data == nullptr)) + { BKE_image_release_ibuf(image_, ibuf, nullptr); return nullptr; } @@ -67,11 +68,11 @@ void BaseImageOperation::init_execution() ImBuf *stackbuf = get_im_buf(); buffer_ = stackbuf; if (stackbuf) { - image_float_buffer_ = stackbuf->rect_float; - image_byte_buffer_ = stackbuf->rect; - image_depth_buffer_ = stackbuf->zbuf_float; - if (stackbuf->zbuf_float) { - depth_buffer_ = new MemoryBuffer(stackbuf->zbuf_float, 1, stackbuf->x, stackbuf->y); + image_float_buffer_ = stackbuf->float_buffer.data; + image_byte_buffer_ = stackbuf->byte_buffer.data; + image_depth_buffer_ = stackbuf->float_z_buffer.data; + if (stackbuf->float_z_buffer.data) { + depth_buffer_ = new MemoryBuffer(stackbuf->float_z_buffer.data, 1, stackbuf->x, stackbuf->y); } imagewidth_ = stackbuf->x; imageheight_ = stackbuf->y; @@ -106,7 +107,7 @@ void BaseImageOperation::determine_canvas(const rcti & /*preferred_area*/, rcti static void sample_image_at_location( ImBuf *ibuf, float x, float y, PixelSampler sampler, bool make_linear_rgb, float color[4]) { - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { switch (sampler) { case PixelSampler::Nearest: nearest_interpolation_color(ibuf, nullptr, color, x, y); diff --git a/source/blender/compositor/operations/COM_ImageOperation.h b/source/blender/compositor/operations/COM_ImageOperation.h index 1eaa828fe2a..db92b62e599 100644 --- a/source/blender/compositor/operations/COM_ImageOperation.h +++ b/source/blender/compositor/operations/COM_ImageOperation.h @@ -5,6 +5,7 @@ #include "BKE_image.h" #include "BLI_listbase.h" +#include "BLI_sys_types.h" #include "BLI_utildefines.h" #include "COM_MultiThreadedOperation.h" #include "MEM_guardedalloc.h" @@ -24,7 +25,7 @@ class BaseImageOperation : public MultiThreadedOperation { ImageUser *image_user_; /* TODO: Remove raw buffers when removing Tiled implementation. */ float *image_float_buffer_; - unsigned int *image_byte_buffer_; + uint8_t *image_byte_buffer_; float *image_depth_buffer_; MemoryBuffer *depth_buffer_; diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.cc b/source/blender/compositor/operations/COM_KeyingScreenOperation.cc index f4fe88e306a..3ecb5ef837a 100644 --- a/source/blender/compositor/operations/COM_KeyingScreenOperation.cc +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.cc @@ -140,11 +140,11 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::build_voronoi_t if (pattern_ibuf) { for (int j = 0; j < pattern_ibuf->x * pattern_ibuf->y; j++) { - if (pattern_ibuf->rect_float) { - add_v3_v3(site->color, &pattern_ibuf->rect_float[4 * j]); + if (pattern_ibuf->float_buffer.data) { + add_v3_v3(site->color, &pattern_ibuf->float_buffer.data[4 * j]); } else { - uchar *rrgb = (uchar *)pattern_ibuf->rect; + uchar *rrgb = pattern_ibuf->byte_buffer.data; site->color[0] += srgb_to_linearrgb(float(rrgb[4 * j + 0]) / 255.0f); site->color[1] += srgb_to_linearrgb(float(rrgb[4 * j + 1]) / 255.0f); diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.cc b/source/blender/compositor/operations/COM_MovieClipOperation.cc index bbc762bf667..ae52318f974 100644 --- a/source/blender/compositor/operations/COM_MovieClipOperation.cc +++ b/source/blender/compositor/operations/COM_MovieClipOperation.cc @@ -36,7 +36,7 @@ void MovieClipBaseOperation::init_execution() if (ibuf) { movie_clip_buffer_ = ibuf; - if (ibuf->rect_float == nullptr || ibuf->userflags & IB_RECT_INVALID) { + if (ibuf->float_buffer.data == nullptr || ibuf->userflags & IB_RECT_INVALID) { IMB_float_from_rect(ibuf); ibuf->userflags &= ~IB_RECT_INVALID; } @@ -73,7 +73,7 @@ void MovieClipBaseOperation::execute_pixel_sampled(float output[4], if (ibuf == nullptr) { zero_v4(output); } - else if (ibuf->rect == nullptr && ibuf->rect_float == nullptr) { + else if (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data == nullptr) { /* Happens for multi-layer EXR, i.e. */ zero_v4(output); } diff --git a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cc b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cc index 4b9bd9d7d3a..d2e09139497 100644 --- a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cc +++ b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cc @@ -321,10 +321,10 @@ void OutputStereoOperation::deinit_execution() ibuf[i] = IMB_allocImBuf(width, height, format_.planes, 0); ibuf[i]->channels = channels_; - ibuf[i]->rect_float = rectf; - ibuf[i]->mall |= IB_rectfloat; ibuf[i]->dither = rd_->dither_intensity; + IMB_assign_float_buffer(ibuf[i], rectf, IB_TAKE_OWNERSHIP); + /* do colormanagement in the individual views, so it doesn't need to do in the stereo */ IMB_colormanagement_imbuf_for_write(ibuf[i], true, false, &format_); } diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cc b/source/blender/compositor/operations/COM_OutputFileOperation.cc index 4b8ba0bbeb5..b7771888a39 100644 --- a/source/blender/compositor/operations/COM_OutputFileOperation.cc +++ b/source/blender/compositor/operations/COM_OutputFileOperation.cc @@ -257,10 +257,10 @@ void OutputSingleLayerOperation::deinit_execution() const char *suffix; ibuf->channels = size; - ibuf->rect_float = output_buffer_; - ibuf->mall |= IB_rectfloat; ibuf->dither = rd_->dither_intensity; + IMB_assign_float_buffer(ibuf, output_buffer_, IB_TAKE_OWNERSHIP); + IMB_colormanagement_imbuf_for_write(ibuf, save_as_render_, false, &format_); suffix = BKE_scene_multiview_view_suffix_get(rd_, view_name_); diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cc b/source/blender/compositor/operations/COM_ViewerOperation.cc index 8b124b14a36..4e166e1a723 100644 --- a/source/blender/compositor/operations/COM_ViewerOperation.cc +++ b/source/blender/compositor/operations/COM_ViewerOperation.cc @@ -155,13 +155,13 @@ void ViewerOperation::init_image() } /* now we combine the input with ibuf */ - output_buffer_ = ibuf->rect_float; + output_buffer_ = ibuf->float_buffer.data; /* needed for display buffer update */ ibuf_ = ibuf; if (do_depth_buffer_) { - depth_buffer_ = ibuf->zbuf_float; + depth_buffer_ = ibuf->float_z_buffer.data; } BKE_image_release_ibuf(image_, ibuf_, lock); diff --git a/source/blender/draw/engines/eevee_next/eevee_pipeline.cc b/source/blender/draw/engines/eevee_next/eevee_pipeline.cc index 2b80070b5ef..78ff35136aa 100644 --- a/source/blender/draw/engines/eevee_next/eevee_pipeline.cc +++ b/source/blender/draw/engines/eevee_next/eevee_pipeline.cc @@ -293,7 +293,7 @@ void DeferredLayer::begin_sync() /* Textures. */ prepass_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx); - /* Uniform Buf. */ + /* Uniform Buffer. */ prepass_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get()); inst_.velocity.bind_resources(&prepass_ps_); @@ -338,11 +338,11 @@ void DeferredLayer::begin_sync() gbuffer_ps_.bind_image(RBUFS_AOV_VALUE_SLOT, &inst_.render_buffers.aov_value_tx); /* Cryptomatte. */ gbuffer_ps_.bind_image(RBUFS_CRYPTOMATTE_SLOT, &inst_.render_buffers.cryptomatte_tx); - /* Storage Buf. */ + /* Storage Buffer. */ gbuffer_ps_.bind_ssbo(RBUFS_AOV_BUF_SLOT, &inst_.film.aovs_info); /* Textures. */ gbuffer_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx); - /* Uniform Buf. */ + /* Uniform Buffer. */ gbuffer_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get()); inst_.sampling.bind_resources(&gbuffer_ps_); diff --git a/source/blender/draw/engines/eevee_next/eevee_sampling.hh b/source/blender/draw/engines/eevee_next/eevee_sampling.hh index c2bf23d20fc..0a4a77a166a 100644 --- a/source/blender/draw/engines/eevee_next/eevee_sampling.hh +++ b/source/blender/draw/engines/eevee_next/eevee_sampling.hh @@ -89,7 +89,7 @@ class Sampling { template void bind_resources(draw::detail::PassBase *pass) { - /* Storage Buf. */ + /* Storage Buffer. */ pass->bind_ssbo(SAMPLING_BUF_SLOT, &data_); } diff --git a/source/blender/draw/engines/eevee_next/eevee_velocity.hh b/source/blender/draw/engines/eevee_next/eevee_velocity.hh index 6f18b05d476..40cb9a5b4f9 100644 --- a/source/blender/draw/engines/eevee_next/eevee_velocity.hh +++ b/source/blender/draw/engines/eevee_next/eevee_velocity.hh @@ -120,13 +120,13 @@ class VelocityModule { template void bind_resources(draw::detail::Pass *pass) { - /* Storage Buf. */ + /* Storage Buffer. */ pass->bind_ssbo(VELOCITY_OBJ_PREV_BUF_SLOT, &(*object_steps[STEP_PREVIOUS])); pass->bind_ssbo(VELOCITY_OBJ_NEXT_BUF_SLOT, &(*object_steps[next_step_])); pass->bind_ssbo(VELOCITY_GEO_PREV_BUF_SLOT, &(*geometry_steps[STEP_PREVIOUS])); pass->bind_ssbo(VELOCITY_GEO_NEXT_BUF_SLOT, &(*geometry_steps[next_step_])); pass->bind_ssbo(VELOCITY_INDIRECTION_BUF_SLOT, &indirection_buf); - /* Uniform Buf. */ + /* Uniform Buffer. */ pass->bind_ubo(VELOCITY_CAMERA_PREV_BUF, &(*camera_steps[STEP_PREVIOUS])); pass->bind_ubo(VELOCITY_CAMERA_CURR_BUF, &(*camera_steps[STEP_CURRENT])); pass->bind_ubo(VELOCITY_CAMERA_NEXT_BUF, &(*camera_steps[next_step_])); diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_data.c b/source/blender/draw/engines/gpencil/gpencil_draw_data.c index 1ebf3982a12..6c99f27d0b8 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_data.c +++ b/source/blender/draw/engines/gpencil/gpencil_draw_data.c @@ -46,7 +46,7 @@ static struct GPUTexture *gpencil_image_texture_get(Image *image, bool *r_alpha_ ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock); - if (ibuf != NULL && ibuf->rect != NULL) { + if (ibuf != NULL && ibuf->byte_buffer.data != NULL) { gpu_tex = BKE_image_get_gpu_texture(image, &iuser, ibuf); *r_alpha_premult = (image->alpha_mode == IMA_ALPHA_PREMUL); } diff --git a/source/blender/draw/engines/image/image_buffer_cache.hh b/source/blender/draw/engines/image/image_buffer_cache.hh index 5c6b01d8add..9f865ee9323 100644 --- a/source/blender/draw/engines/image/image_buffer_cache.hh +++ b/source/blender/draw/engines/image/image_buffer_cache.hh @@ -70,11 +70,11 @@ struct FloatBufferCache { ImBuf *cached_float_buffer(ImBuf *image_buffer) { /* Check if we can use the float buffer of the given image_buffer. */ - if (image_buffer->rect_float != nullptr) { + if (image_buffer->float_buffer.data != nullptr) { BLI_assert_msg( IMB_colormanagement_space_name_is_scene_linear( IMB_colormanagement_get_float_colorspace(image_buffer)), - "Expected rect_float to be scene_linear - if there are code paths where this " + "Expected float buffer to be scene_linear - if there are code paths where this " "isn't the case we should convert those and add to the FloatBufferCache as well."); return image_buffer; } @@ -90,12 +90,8 @@ struct FloatBufferCache { /* Generate a new float buffer. */ IMB_float_from_rect(image_buffer); ImBuf *new_imbuf = IMB_allocImBuf(image_buffer->x, image_buffer->y, image_buffer->planes, 0); - new_imbuf->rect_float = image_buffer->rect_float; - new_imbuf->flags |= IB_rectfloat; - new_imbuf->mall |= IB_rectfloat; - image_buffer->rect_float = nullptr; - image_buffer->flags &= ~IB_rectfloat; - image_buffer->mall &= ~IB_rectfloat; + + IMB_assign_float_buffer(new_imbuf, IMB_steal_float_buffer(image_buffer), IB_TAKE_OWNERSHIP); cache_.append(FloatImageBuffer(image_buffer, new_imbuf)); return new_imbuf; diff --git a/source/blender/draw/engines/image/image_drawing_mode.hh b/source/blender/draw/engines/image/image_drawing_mode.hh index afed17118d0..9a7d037763c 100644 --- a/source/blender/draw/engines/image/image_drawing_mode.hh +++ b/source/blender/draw/engines/image/image_drawing_mode.hh @@ -389,10 +389,10 @@ template class ScreenSpaceDrawingMode : public AbstractD ImBuf *float_buffer, PartialUpdateChecker::CollectResult &iterator) const { ImBuf *src = iterator.tile_data.tile_buffer; - BLI_assert(float_buffer->rect_float != nullptr); - BLI_assert(float_buffer->rect == nullptr); - BLI_assert(src->rect_float == nullptr); - BLI_assert(src->rect != nullptr); + BLI_assert(float_buffer->float_buffer.data != nullptr); + BLI_assert(float_buffer->byte_buffer.data == nullptr); + BLI_assert(src->float_buffer.data == nullptr); + BLI_assert(src->byte_buffer.data != nullptr); /* Calculate the overlap between the updated region and the buffer size. Partial Update Checker * always returns a tile (256x256). Which could lay partially outside the buffer when using @@ -503,7 +503,7 @@ template class ScreenSpaceDrawingMode : public AbstractD info.clipping_uv_bounds.xmin * (1.0 - xf) - tile_offset_x; nearest_interpolation_color(tile_buffer, nullptr, - &extracted_buffer.rect_float[offset * 4], + &extracted_buffer.float_buffer.data[offset * 4], u * tile_buffer->x, v * tile_buffer->y); offset++; @@ -513,7 +513,7 @@ template class ScreenSpaceDrawingMode : public AbstractD GPU_texture_update_sub(texture, GPU_DATA_FLOAT, - extracted_buffer.rect_float, + extracted_buffer.float_buffer.data, gpu_texture_region_to_update.xmin, gpu_texture_region_to_update.ymin, 0, @@ -563,7 +563,7 @@ template class ScreenSpaceDrawingMode : public AbstractD BKE_image_release_ibuf(image, tile_buffer, lock); } IMB_gpu_clamp_half_float(&texture_buffer); - GPU_texture_update(info.texture, GPU_DATA_FLOAT, texture_buffer.rect_float); + GPU_texture_update(info.texture, GPU_DATA_FLOAT, texture_buffer.float_buffer.data); imb_freerectImbuf_all(&texture_buffer); } diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert.glsl index 36bb708d084..b10e48441c4 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert.glsl @@ -74,6 +74,11 @@ void main() finalColor = EDIT_MESH_face_color(m_data.x); bool occluded = true; +# ifdef GPU_METAL + /* Apply depth bias to overlay in order to prevent z-fighting on Apple Silicon GPUs. */ + gl_Position.z -= 5e-5; +# endif + #elif defined(FACEDOT) finalColor = EDIT_MESH_facedot_color(norAndFlag.w); diff --git a/source/blender/draw/engines/workbench/shaders/infos/workbench_volume_info.hh b/source/blender/draw/engines/workbench/shaders/infos/workbench_volume_info.hh index e461e6ee077..5b417b93f9e 100644 --- a/source/blender/draw/engines/workbench/shaders/infos/workbench_volume_info.hh +++ b/source/blender/draw/engines/workbench/shaders/infos/workbench_volume_info.hh @@ -23,6 +23,7 @@ GPU_SHADER_CREATE_INFO(workbench_volume) GPU_SHADER_CREATE_INFO(workbench_next_volume) .define("WORKBENCH_NEXT") + .sampler(6, ImageType::UINT_2D, "stencil_tx") .additional_info("workbench_volume_common", "draw_object_infos_new", "draw_view"); /** \} */ diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl index 8d2bd08cf30..dca146ec2ed 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl @@ -222,6 +222,14 @@ vec4 volume_integration(vec3 ray_ori, vec3 ray_dir, float ray_inc, float ray_max void main() { +#ifdef WORKBENCH_NEXT + uint stencil = texelFetch(stencil_tx, ivec2(gl_FragCoord.xy), 0).r; + if (stencil != 0) { + /* Don't draw on top of "in front" objects. */ + discard; + return; + } +#endif #ifdef VOLUME_SLICE /* Manual depth test. TODO: remove. */ float depth = texelFetch(depthBuffer, ivec2(gl_FragCoord.xy), 0).r; diff --git a/source/blender/draw/engines/workbench/workbench_private.hh b/source/blender/draw/engines/workbench/workbench_private.hh index 5366314d073..524c45c111b 100644 --- a/source/blender/draw/engines/workbench/workbench_private.hh +++ b/source/blender/draw/engines/workbench/workbench_private.hh @@ -334,6 +334,8 @@ class VolumePass { Texture dummy_volume_tx_ = {"Volume.Dummy Volume Tx"}; Texture dummy_coba_tx_ = {"Volume.Dummy Coba Tx"}; + GPUTexture *stencil_tx_ = nullptr; + GPUShader *shaders_[2 /*slice*/][2 /*coba*/][3 /*interpolation*/][2 /*smoke*/]; public: diff --git a/source/blender/draw/engines/workbench/workbench_resources.cc b/source/blender/draw/engines/workbench/workbench_resources.cc index 72fc923639b..5410e0579e9 100644 --- a/source/blender/draw/engines/workbench/workbench_resources.cc +++ b/source/blender/draw/engines/workbench/workbench_resources.cc @@ -15,15 +15,15 @@ static bool get_matcap_tx(Texture &matcap_tx, StudioLight &studio_light) STUDIOLIGHT_MATCAP_SPECULAR_GPUTEXTURE); ImBuf *matcap_diffuse = studio_light.matcap_diffuse.ibuf; ImBuf *matcap_specular = studio_light.matcap_specular.ibuf; - if (matcap_diffuse && matcap_diffuse->rect_float) { + if (matcap_diffuse && matcap_diffuse->float_buffer.data) { int layers = 1; - float *buffer = matcap_diffuse->rect_float; + float *buffer = matcap_diffuse->float_buffer.data; Vector combined_buffer = {}; - if (matcap_specular && matcap_specular->rect_float) { + if (matcap_specular && matcap_specular->float_buffer.data) { int size = matcap_diffuse->x * matcap_diffuse->y * 4; - combined_buffer.extend(matcap_diffuse->rect_float, size); - combined_buffer.extend(matcap_specular->rect_float, size); + combined_buffer.extend(matcap_diffuse->float_buffer.data, size); + combined_buffer.extend(matcap_specular->float_buffer.data, size); buffer = combined_buffer.begin(); layers++; } diff --git a/source/blender/draw/engines/workbench/workbench_volume_next.cc b/source/blender/draw/engines/workbench/workbench_volume_next.cc index 847b36ac7fb..52358956d01 100644 --- a/source/blender/draw/engines/workbench/workbench_volume_next.cc +++ b/source/blender/draw/engines/workbench/workbench_volume_next.cc @@ -19,6 +19,8 @@ void VolumePass::sync(SceneResources &resources) dummy_shadow_tx_.ensure_3d(GPU_RGBA8, int3(1), GPU_TEXTURE_USAGE_SHADER_READ, float4(1)); dummy_volume_tx_.ensure_3d(GPU_RGBA8, int3(1), GPU_TEXTURE_USAGE_SHADER_READ, float4(0)); dummy_coba_tx_.ensure_1d(GPU_RGBA8, 1, GPU_TEXTURE_USAGE_SHADER_READ, float4(0)); + + stencil_tx_ = resources.depth_tx.stencil_view(); } void VolumePass::object_sync_volume(Manager &manager, @@ -53,6 +55,7 @@ void VolumePass::object_sync_volume(Manager &manager, BKE_volume_density_scale(volume, ob->object_to_world); sub_ps.bind_texture("depthBuffer", &resources.depth_tx); + sub_ps.bind_texture("stencil_tx", &stencil_tx_); sub_ps.bind_texture("densityTexture", grid->texture); /* TODO: implement shadow texture, see manta_smoke_calc_transparency. */ sub_ps.bind_texture("shadowTexture", dummy_shadow_tx_); @@ -157,6 +160,7 @@ void VolumePass::object_sync_modifier(Manager &manager, sub_ps.push_constant("densityScale", 10.0f * settings.display_thickness); sub_ps.bind_texture("depthBuffer", &resources.depth_tx); + sub_ps.bind_texture("stencil_tx", &stencil_tx_); if (use_slice) { draw_slice_ps(manager, sub_ps, ob_ref, settings.slice_axis, settings.slice_depth); diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc index 06e20d2565e..012e0923dee 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc +++ b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc @@ -454,7 +454,8 @@ MeshRenderData *mesh_render_data_create(Object *object, mr->vert_crease_ofs = CustomData_get_offset(&mr->bm->vdata, CD_CREASE); mr->edge_crease_ofs = CustomData_get_offset(&mr->bm->edata, CD_CREASE); - mr->bweight_ofs = CustomData_get_offset(&mr->bm->edata, CD_BWEIGHT); + mr->bweight_ofs = CustomData_get_offset_named( + &mr->bm->edata, CD_PROP_FLOAT, "bevel_weight_edge"); #ifdef WITH_FREESTYLE mr->freestyle_edge_ofs = CustomData_get_offset(&mr->bm->edata, CD_FREESTYLE_EDGE); mr->freestyle_face_ofs = CustomData_get_offset(&mr->bm->pdata, CD_FREESTYLE_FACE); diff --git a/source/blender/draw/intern/draw_curves.cc b/source/blender/draw/intern/draw_curves.cc index 46802f8f4f7..1da141e2d55 100644 --- a/source/blender/draw/intern/draw_curves.cc +++ b/source/blender/draw/intern/draw_curves.cc @@ -61,7 +61,6 @@ static int g_tf_target_width; static int g_tf_target_height; static GPUVertBuf *g_dummy_vbo = nullptr; -static GPUTexture *g_dummy_texture = nullptr; static DRWPass *g_tf_pass; /* XXX can be a problem with multiple DRWManager in the future */ using CurvesInfosBuf = blender::draw::UniformBuffer; @@ -121,8 +120,6 @@ void DRW_curves_init(DRWData *drw_data) GPU_vertbuf_attr_fill(g_dummy_vbo, dummy_id, vert); /* Create vbo immediately to bind to texture buffer. */ GPU_vertbuf_use(g_dummy_vbo); - - g_dummy_texture = GPU_texture_create_from_vertbuf("hair_dummy_attr", g_dummy_vbo); } } @@ -318,12 +315,12 @@ DRWShadingGroup *DRW_shgroup_curves_create_sub(Object *object, DRWShadingGroup *shgrp = DRW_shgroup_create_sub(shgrp_parent); - /* Fix issue with certain driver not drawing anything if there is no texture bound to + /* Fix issue with certain driver not drawing anything if there is nothing bound to * "ac", "au", "u" or "c". */ - DRW_shgroup_uniform_texture(shgrp, "u", g_dummy_texture); - DRW_shgroup_uniform_texture(shgrp, "au", g_dummy_texture); - DRW_shgroup_uniform_texture(shgrp, "c", g_dummy_texture); - DRW_shgroup_uniform_texture(shgrp, "ac", g_dummy_texture); + DRW_shgroup_buffer_texture(shgrp, "u", g_dummy_vbo); + DRW_shgroup_buffer_texture(shgrp, "au", g_dummy_vbo); + DRW_shgroup_buffer_texture(shgrp, "c", g_dummy_vbo); + DRW_shgroup_buffer_texture(shgrp, "ac", g_dummy_vbo); /* TODO: Generalize radius implementation for curves data type. */ float hair_rad_shape = 0.0f; @@ -415,7 +412,7 @@ void DRW_curves_update() /* Update legacy hair too, to avoid verbosity in callers. */ DRW_hair_update(); - if (!GPU_transform_feedback_support()) { + if (drw_curves_shader_type_get() == PART_REFINE_SHADER_TRANSFORM_FEEDBACK_WORKAROUND) { /** * Workaround to transform feedback not working on mac. * On some system it crashes (see #58489) and on some other it renders garbage (see #60171). @@ -538,5 +535,4 @@ void DRW_curves_free() DRW_hair_free(); GPU_VERTBUF_DISCARD_SAFE(g_dummy_vbo); - DRW_TEXTURE_FREE_SAFE(g_dummy_texture); } diff --git a/source/blender/draw/intern/draw_hair.cc b/source/blender/draw/intern/draw_hair.cc index 7919c80c9a7..100275bd604 100644 --- a/source/blender/draw/intern/draw_hair.cc +++ b/source/blender/draw/intern/draw_hair.cc @@ -64,7 +64,6 @@ static int g_tf_target_width; static int g_tf_target_height; static GPUVertBuf *g_dummy_vbo = nullptr; -static GPUTexture *g_dummy_texture = nullptr; static DRWPass *g_tf_pass; /* XXX can be a problem with multiple #DRWManager in the future */ static blender::draw::UniformBuffer *g_dummy_curves_info = nullptr; @@ -96,8 +95,6 @@ void DRW_hair_init(void) /* Create VBO immediately to bind to texture buffer. */ GPU_vertbuf_use(g_dummy_vbo); - g_dummy_texture = GPU_texture_create_from_vertbuf("hair_dummy_attr", g_dummy_vbo); - g_dummy_curves_info = MEM_new>( "g_dummy_curves_info"); memset(g_dummy_curves_info->is_point_attribute, @@ -266,15 +263,15 @@ DRWShadingGroup *DRW_shgroup_hair_create_sub(Object *object, } } - /* Fix issue with certain driver not drawing anything if there is no texture bound to + /* Fix issue with certain driver not drawing anything if there is nothing bound to * "ac", "au", "u" or "c". */ if (hair_cache->num_uv_layers == 0) { - DRW_shgroup_uniform_texture(shgrp, "u", g_dummy_texture); - DRW_shgroup_uniform_texture(shgrp, "au", g_dummy_texture); + DRW_shgroup_buffer_texture(shgrp, "u", g_dummy_vbo); + DRW_shgroup_buffer_texture(shgrp, "au", g_dummy_vbo); } if (hair_cache->num_col_layers == 0) { - DRW_shgroup_uniform_texture(shgrp, "c", g_dummy_texture); - DRW_shgroup_uniform_texture(shgrp, "ac", g_dummy_texture); + DRW_shgroup_buffer_texture(shgrp, "c", g_dummy_vbo); + DRW_shgroup_buffer_texture(shgrp, "ac", g_dummy_vbo); } DRW_hair_duplimat_get(object, psys, md, dupli_mat); @@ -314,7 +311,7 @@ DRWShadingGroup *DRW_shgroup_hair_create_sub(Object *object, void DRW_hair_update() { - if (!GPU_transform_feedback_support()) { + if (drw_hair_shader_type_get() == PART_REFINE_SHADER_TRANSFORM_FEEDBACK_WORKAROUND) { /** * Workaround to transform feedback not working on mac. * On some system it crashes (see #58489) and on some other it renders garbage (see #60171). @@ -433,6 +430,5 @@ void DRW_hair_update() void DRW_hair_free(void) { GPU_VERTBUF_DISCARD_SAFE(g_dummy_vbo); - DRW_TEXTURE_FREE_SAFE(g_dummy_texture); MEM_delete(g_dummy_curves_info); } diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index ae874e44414..c425e025955 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -2792,6 +2792,9 @@ void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d, cons /* Only background (non-edit) objects are used for occlusion. */ continue; } + if (!BKE_object_is_visible_in_viewport(v3d, ob)) { + continue; + } drw_engines_cache_populate(ob); } DEG_OBJECT_ITER_END; diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 04e9122c994..22c9217dc35 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -203,16 +203,13 @@ static void change_frame_seq_preview_begin(bContext *C, const wmEvent *event, Sp } } -static void change_frame_seq_preview_end(bContext *C, SpaceSeq *sseq) +static void change_frame_seq_preview_end(SpaceSeq *sseq) { BLI_assert(sseq != NULL); UNUSED_VARS_NDEBUG(sseq); if (ED_sequencer_special_preview_get() != NULL) { ED_sequencer_special_preview_clear(); } - - Scene *scene = CTX_data_scene(C); - WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); } static bool use_sequencer_snapping(bContext *C) @@ -260,6 +257,36 @@ static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event return OPERATOR_RUNNING_MODAL; } +static bool need_extra_redraw_after_scrubbing_ends(bContext *C) +{ + if (CTX_wm_space_seq(C)) { + /* During scrubbing in the sequencer, a preview of the final video might be drawn. After + * scrubbing, the actual result should be shown again. */ + return true; + } + wmWindowManager *wm = CTX_wm_manager(C); + Object *object = CTX_data_active_object(C); + if (object && object->type == OB_GPENCIL_LEGACY) { + LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { + bScreen *screen = WM_window_get_active_screen(win); + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + SpaceLink *sl = (SpaceLink *)area->spacedata.first; + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + if ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) { + if (v3d->gp_flag & V3D_GP_SHOW_ONION_SKIN) { + /* Grease pencil onion skin is not drawn during scrubbing. Redraw is necessary after + * scrubbing ends to show onion skin again. */ + return true; + } + } + } + } + } + } + return false; +} + static void change_frame_cancel(bContext *C, wmOperator *UNUSED(op)) { bScreen *screen = CTX_wm_screen(C); @@ -267,7 +294,12 @@ static void change_frame_cancel(bContext *C, wmOperator *UNUSED(op)) SpaceSeq *sseq = CTX_wm_space_seq(C); if (sseq != NULL) { - change_frame_seq_preview_end(C, sseq); + change_frame_seq_preview_end(sseq); + } + + if (need_extra_redraw_after_scrubbing_ends(C)) { + Scene *scene = CTX_data_scene(C); + WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); } } @@ -323,7 +355,11 @@ static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event) SpaceSeq *sseq = CTX_wm_space_seq(C); if (sseq != NULL) { - change_frame_seq_preview_end(C, sseq); + change_frame_seq_preview_end(sseq); + } + if (need_extra_redraw_after_scrubbing_ends(C)) { + Scene *scene = CTX_data_scene(C); + WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); } } diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c index de09b1baa67..69518d251e4 100644 --- a/source/blender/editors/animation/fmodifier_ui.c +++ b/source/blender/editors/animation/fmodifier_ui.c @@ -397,8 +397,8 @@ static void generator_panel_draw(const bContext *C, Panel *panel) uiLayoutColumn(split, false); uiLayout *title_col = uiLayoutColumn(split, false); uiLayout *title_row = uiLayoutRow(title_col, true); - uiItemL(title_row, IFACE_("A"), ICON_NONE); - uiItemL(title_row, IFACE_("B"), ICON_NONE); + uiItemL(title_row, CTX_IFACE_(BLT_I18NCONTEXT_ID_ACTION, "A"), ICON_NONE); + uiItemL(title_row, CTX_IFACE_(BLT_I18NCONTEXT_ID_ACTION, "B"), ICON_NONE); } uiLayout *first_row = uiLayoutRow(col, true); diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c index 05851d8694f..9a218948896 100644 --- a/source/blender/editors/armature/armature_add.c +++ b/source/blender/editors/armature/armature_add.c @@ -1142,7 +1142,7 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op) * A symmetrizable selection contains selected ebones of the input direction * and unique selected bones with an unique flippable name. * - * Storing temp ptrs to mirrored unselected ebones. */ + * Storing temp pointers to mirrored unselected ebones. */ for (ebone_iter = arm->edbo->first; ebone_iter; ebone_iter = ebone_iter->next) { if (!(EBONE_VISIBLE(arm, ebone_iter) && (ebone_iter->flag & BONE_SELECTED))) { /* Skipping invisible selected bones. */ diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index 5d2ee150ea0..460ef112521 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -1051,7 +1051,8 @@ static int paste_text_exec(bContext *C, wmOperator *op) int len; } clipboard_system = {NULL}, clipboard_vfont = {NULL}; - clipboard_system.buf = WM_clipboard_text_get(selection, &clipboard_system.len); + /* No need for UTF8 validation as the conversion handles invalid sequences gracefully. */ + clipboard_system.buf = WM_clipboard_text_get(selection, false, &clipboard_system.len); if (clipboard_system.buf == NULL) { return OPERATOR_CANCELLED; diff --git a/source/blender/editors/gpencil_legacy/gpencil_fill.c b/source/blender/editors/gpencil_legacy/gpencil_fill.c index 3e73f0ebc36..798a63f0bc8 100644 --- a/source/blender/editors/gpencil_legacy/gpencil_fill.c +++ b/source/blender/editors/gpencil_legacy/gpencil_fill.c @@ -1322,13 +1322,13 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf) GPU_matrix_pop(); /* create a image to see result of template */ - if (ibuf->rect_float) { - GPU_offscreen_read_color(offscreen, GPU_DATA_FLOAT, ibuf->rect_float); + if (ibuf->float_buffer.data) { + GPU_offscreen_read_color(offscreen, GPU_DATA_FLOAT, ibuf->float_buffer.data); } - else if (ibuf->rect) { - GPU_offscreen_read_color(offscreen, GPU_DATA_UBYTE, ibuf->rect); + else if (ibuf->byte_buffer.data) { + GPU_offscreen_read_color(offscreen, GPU_DATA_UBYTE, ibuf->byte_buffer.data); } - if (ibuf->rect_float && ibuf->rect) { + if (ibuf->float_buffer.data && ibuf->byte_buffer.data) { IMB_rect_from_float(ibuf); } @@ -1347,22 +1347,22 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf) /* Return pixel data (RGBA) at index. */ static void get_pixel(const ImBuf *ibuf, const int idx, float r_col[4]) { - BLI_assert(ibuf->rect_float != NULL); - memcpy(r_col, &ibuf->rect_float[idx * 4], sizeof(float[4])); + BLI_assert(ibuf->float_buffer.data != NULL); + memcpy(r_col, &ibuf->float_buffer.data[idx * 4], sizeof(float[4])); } /* Set pixel data (RGBA) at index. */ static void set_pixel(ImBuf *ibuf, int idx, const float col[4]) { - BLI_assert(ibuf->rect_float != NULL); - float *rrectf = &ibuf->rect_float[idx * 4]; + BLI_assert(ibuf->float_buffer.data != NULL); + float *rrectf = &ibuf->float_buffer.data[idx * 4]; copy_v4_v4(rrectf, col); } /* Helper: Check if one image row is empty. */ static bool is_row_filled(const ImBuf *ibuf, const int row_index) { - float *row = &ibuf->rect_float[ibuf->x * 4 * row_index]; + float *row = &ibuf->float_buffer.data[ibuf->x * 4 * row_index]; return (row[0] == 0.0f && memcmp(row, row + 1, ((ibuf->x * 4) - 1) * sizeof(float)) != 0); } diff --git a/source/blender/editors/gpencil_legacy/gpencil_trace_utils.c b/source/blender/editors/gpencil_legacy/gpencil_trace_utils.c index 447bafbb06a..cf538a9e912 100644 --- a/source/blender/editors/gpencil_legacy/gpencil_trace_utils.c +++ b/source/blender/editors/gpencil_legacy/gpencil_trace_utils.c @@ -114,12 +114,12 @@ static void pixel_at_index(const ImBuf *ibuf, const int32_t idx, float r_col[4]) { BLI_assert(idx < (ibuf->x * ibuf->y)); - if (ibuf->rect_float) { - const float *frgba = &ibuf->rect_float[idx * 4]; + if (ibuf->float_buffer.data) { + const float *frgba = &ibuf->float_buffer.data[idx * 4]; copy_v4_v4(r_col, frgba); } else { - uchar *cp = (uchar *)(ibuf->rect + idx); + uchar *cp = ibuf->byte_buffer.data + 4 * idx; r_col[0] = (float)cp[0] / 255.0f; r_col[1] = (float)cp[1] / 255.0f; r_col[2] = (float)cp[2] / 255.0f; diff --git a/source/blender/editors/gpencil_legacy/gpencil_weight_paint.c b/source/blender/editors/gpencil_legacy/gpencil_weight_paint.c index fb800c33581..96f015331bb 100644 --- a/source/blender/editors/gpencil_legacy/gpencil_weight_paint.c +++ b/source/blender/editors/gpencil_legacy/gpencil_weight_paint.c @@ -808,8 +808,8 @@ static bool gpencil_weightpaint_brush_init(bContext *C, wmOperator *op) gso->fn_kdtree = NULL; gso->fn_used = 0; gso->fn_size = 0; - gso->use_find_nearest = ((gso->brush->gpencil_weight_tool == GPWEIGHT_TOOL_BLUR) || - (gso->brush->gpencil_weight_tool == GPWEIGHT_TOOL_SMEAR)); + gso->use_find_nearest = ELEM( + gso->brush->gpencil_weight_tool, GPWEIGHT_TOOL_BLUR, GPWEIGHT_TOOL_SMEAR); gso->gpd = ED_gpencil_data_get_active(C); gso->scene = scene; diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 1c5058a2a2b..492c70968f1 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -419,8 +419,9 @@ void paintface_select_linked(struct bContext *C, struct Object *ob, const int mval[2], bool select); -/** Grow the selection of faces. - * \param face_step If true will also select faces that only touch on the corner. +/** + * Grow the selection of faces. + * \param face_step: If true will also select faces that only touch on the corner. */ void paintface_select_more(struct Mesh *mesh, bool face_step); void paintface_select_less(struct Mesh *mesh, bool face_step); @@ -586,10 +587,6 @@ void ED_mesh_uv_loop_reset_ex(struct Mesh *me, int layernum); bool ED_mesh_color_ensure(struct Mesh *me, const char *name); int ED_mesh_color_add( struct Mesh *me, const char *name, bool active_set, bool do_init, struct ReportList *reports); -int ED_mesh_sculpt_color_add(struct Mesh *me, - const char *name, - bool do_init, - struct ReportList *reports); void ED_mesh_report_mirror(struct wmOperator *op, int totmirr, int totfail); void ED_mesh_report_mirror_ex(struct wmOperator *op, int totmirr, int totfail, char selectmode); diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index 1af4ee05374..d121dec7bc2 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -125,8 +125,9 @@ int BIF_countTransformOrientation(const struct bContext *C); #define P_CURSOR_EDIT (1 << 16) #define P_CLNOR_INVALIDATE (1 << 17) #define P_VIEW2D_EDGE_PAN (1 << 18) +#define P_VIEW3D_NAVIGATION (1 << 19) /* For properties performed when confirming the transformation. */ -#define P_POST_TRANSFORM (1 << 19) +#define P_POST_TRANSFORM (1 << 20) void Transform_Properties(struct wmOperatorType *ot, int flags); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index e3a32956074..54ddd61ed89 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -43,6 +43,7 @@ struct SnapObjectContext; struct View3D; struct ViewContext; struct ViewLayer; +struct ViewOpsData; struct bContext; struct bPoseChannel; struct bScreen; @@ -210,6 +211,19 @@ bool ED_view3d_depth_unproject_v3(const struct ARegion *region, double depth, float r_location_world[3]); +/** + * Utilities to perform navigation. + * Call `ED_view3d_navigation_init` to create a context and `ED_view3d_navigation_do` to perform + * navigation in modal operators. + * + * \note modal map events can also be used in `ED_view3d_navigation_do`. + */ +struct ViewOpsData *ED_view3d_navigation_init(struct bContext *C); +bool ED_view3d_navigation_do(struct bContext *C, + struct ViewOpsData *vod, + const struct wmEvent *event); +void ED_view3d_navigation_free(struct bContext *C, struct ViewOpsData *vod); + /* Projection */ #define IS_CLIPPED 12000 diff --git a/source/blender/editors/interface/interface_draw.cc b/source/blender/editors/interface/interface_draw.cc index 366b7c72856..4d53c23b0ca 100644 --- a/source/blender/editors/interface/interface_draw.cc +++ b/source/blender/editors/interface/interface_draw.cc @@ -301,7 +301,7 @@ void ui_draw_but_IMAGE(ARegion * /*region*/, ibuf->y, GPU_RGBA8, false, - ibuf->rect, + ibuf->byte_buffer.data, 1.0f, 1.0f, col); @@ -2053,11 +2053,11 @@ void ui_draw_but_TRACKPREVIEW(ARegion * /*region*/, height, scopes->track_pos); if (tmpibuf) { - if (tmpibuf->rect_float) { + if (tmpibuf->float_buffer.data) { IMB_rect_from_float(tmpibuf); } - if (tmpibuf->rect) { + if (tmpibuf->byte_buffer.data) { scopes->track_preview = tmpibuf; } else { @@ -2095,7 +2095,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion * /*region*/, drawibuf->y, GPU_RGBA8, true, - drawibuf->rect, + drawibuf->byte_buffer.data, 1.0f, 1.0f, nullptr); diff --git a/source/blender/editors/interface/interface_handlers.cc b/source/blender/editors/interface/interface_handlers.cc index a799877e2fe..749f74d253c 100644 --- a/source/blender/editors/interface/interface_handlers.cc +++ b/source/blender/editors/interface/interface_handlers.cc @@ -2435,19 +2435,21 @@ static void ui_apply_but( /** \name Button Copy & Paste * \{ */ -static void ui_but_get_pasted_text_from_clipboard(char **buf_paste, int *buf_len) +static void ui_but_get_pasted_text_from_clipboard(const bool ensure_utf8, + char **r_buf_paste, + int *r_buf_len) { /* get only first line even if the clipboard contains multiple lines */ int length; - char *text = WM_clipboard_text_get_firstline(false, &length); + char *text = WM_clipboard_text_get_firstline(false, ensure_utf8, &length); if (text) { - *buf_paste = text; - *buf_len = length; + *r_buf_paste = text; + *r_buf_len = length; } else { - *buf_paste = static_cast(MEM_callocN(sizeof(char), __func__)); - *buf_len = 0; + *r_buf_paste = static_cast(MEM_callocN(sizeof(char), __func__)); + *r_buf_len = 0; } } @@ -2831,7 +2833,7 @@ static void ui_but_paste(bContext *C, uiBut *but, uiHandleButtonData *data, cons int buf_paste_len = 0; char *buf_paste; - ui_but_get_pasted_text_from_clipboard(&buf_paste, &buf_paste_len); + ui_but_get_pasted_text_from_clipboard(UI_but_is_utf8(but), &buf_paste, &buf_paste_len); const bool has_required_data = !(but->poin == nullptr && but->rnapoin.data == nullptr); @@ -3310,13 +3312,9 @@ static bool ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, const in if (mode == UI_TEXTEDIT_PASTE) { /* extract the first line from the clipboard */ int buf_len; - char *pbuf = WM_clipboard_text_get_firstline(false, &buf_len); + char *pbuf = WM_clipboard_text_get_firstline(false, UI_but_is_utf8(but), &buf_len); if (pbuf) { - if (UI_but_is_utf8(but)) { - buf_len -= BLI_str_utf8_invalid_strip(pbuf, size_t(buf_len)); - } - ui_textedit_insert_buf(but, data, pbuf, buf_len); changed = true; @@ -3508,9 +3506,12 @@ static void ui_textedit_end(bContext *C, uiBut *but, uiHandleButtonData *data) if (but) { if (UI_but_is_utf8(but)) { const int strip = BLI_str_utf8_invalid_strip(but->editstr, strlen(but->editstr)); - /* not a file?, strip non utf-8 chars */ + /* Strip non-UTF8 characters unless buttons support this. + * This should never happen as all text input should be valid UTF8, + * there is a small chance existing data contains invalid sequences. + * This could check could be made into an assertion if `but->editstr` + * is valid UTF8 when #ui_textedit_begin assigns the string. */ if (strip) { - /* won't happen often so isn't that annoying to keep it here for a while */ printf("%s: invalid utf8 - stripped chars %d\n", __func__, strip); } } @@ -3732,9 +3733,9 @@ static void ui_do_but_textedit( if (event->val == KM_DBL_CLICK && had_selection == false) { int selsta, selend; BLI_str_cursor_step_bounds_utf8(data->str, strlen(data->str), but->pos, &selsta, &selend); - but->pos = (short)selend; - but->selsta = (short)selsta; - but->selend = (short)selend; + but->pos = short(selend); + but->selsta = short(selsta); + but->selend = short(selend); retval = WM_UI_HANDLER_BREAK; changed = true; } diff --git a/source/blender/editors/interface/interface_icons.cc b/source/blender/editors/interface/interface_icons.cc index f3af18b6bb6..c56564531e2 100644 --- a/source/blender/editors/interface/interface_icons.cc +++ b/source/blender/editors/interface/interface_icons.cc @@ -77,7 +77,7 @@ struct IconImage { int w; int h; - uint *rect; + uint8_t *rect; const uchar *datatoc_rect; int datatoc_size; }; @@ -192,18 +192,19 @@ static DrawInfo *def_internal_icon( if (bbuf) { int y, imgsize; - iimg->rect = static_cast(MEM_mallocN(size * size * sizeof(uint), __func__)); + iimg->rect = static_cast(MEM_mallocN(size * size * sizeof(uint), __func__)); /* Here we store the rect in the icon - same as before */ if (size == bbuf->x && size == bbuf->y && xofs == 0 && yofs == 0) { - memcpy(iimg->rect, bbuf->rect, size * size * sizeof(int)); + memcpy(iimg->rect, bbuf->byte_buffer.data, size * size * 4 * sizeof(uint8_t)); } else { /* this code assumes square images */ imgsize = bbuf->x; for (y = 0; y < size; y++) { - memcpy( - &iimg->rect[y * size], &bbuf->rect[(y + yofs) * imgsize + xofs], size * sizeof(int)); + memcpy(&iimg->rect[y * size], + &bbuf->byte_buffer.data[(y + yofs) * imgsize + xofs], + size * 4 * sizeof(uint8_t)); } } } @@ -759,8 +760,7 @@ static void icon_verify_datatoc(IconImage *iimg) IMB_scaleImBuf(bbuf, iimg->w, iimg->h); } - iimg->rect = bbuf->rect; - bbuf->rect = nullptr; + iimg->rect = IMB_steal_byte_buffer(bbuf); IMB_freeImBuf(bbuf); } } @@ -777,6 +777,9 @@ static ImBuf *create_mono_icon_with_border(ImBuf *buf, const int icon_width = (ICON_GRID_W + 2 * ICON_MONO_BORDER_OUTSET) / resolution_divider; const int icon_height = (ICON_GRID_W + 2 * ICON_MONO_BORDER_OUTSET) / resolution_divider; + const uint *buf_rect = reinterpret_cast(buf->byte_buffer.data); + uint *result_rect = reinterpret_cast(result->byte_buffer.data); + for (int y = 0; y < ICON_GRID_ROWS; y++) { for (int x = 0; x < ICON_GRID_COLS; x++) { const IconType icontype = icontypes[y * ICON_GRID_COLS + x]; @@ -805,7 +808,7 @@ static ImBuf *create_mono_icon_with_border(ImBuf *buf, for (int ax = asx; ax < aex; ax++) { for (int ay = asy; ay < aey; ay++) { const int offset_read = (sy + ay) * buf->x + (sx + ax); - const uint color_read = buf->rect[offset_read]; + const uint color_read = buf_rect[offset_read]; const float alpha_read = ((color_read & 0xff000000) >> 24) / 255.0; alpha_accum += alpha_read; alpha_samples += 1; @@ -824,7 +827,7 @@ static ImBuf *create_mono_icon_with_border(ImBuf *buf, const float border_srgb[4] = { 0, 0, 0, MIN2(1.0f, blurred_alpha * border_sharpness) * border_intensity}; - const uint color_read = buf->rect[offset_write]; + const uint color_read = buf_rect[offset_write]; const uchar *orig_color = (uchar *)&color_read; float border_rgba[4]; @@ -839,7 +842,8 @@ static ImBuf *create_mono_icon_with_border(ImBuf *buf, const uint alpha_mask = uint(dest_srgb[3] * 255) << 24; const uint cpack = rgb_to_cpack(dest_srgb[0], dest_srgb[1], dest_srgb[2]) | alpha_mask; - result->rect[offset_write] = cpack; + + result_rect[offset_write] = cpack; } } } @@ -914,8 +918,8 @@ void UI_icons_reload_internal_textures() icongltex.tex[0] = GPU_texture_create_2d( "icons", b32buf->x, b32buf->y, 2, GPU_RGBA8, GPU_TEXTURE_USAGE_SHADER_READ, nullptr); - GPU_texture_update_mipmap(icongltex.tex[0], 0, GPU_DATA_UBYTE, b32buf->rect); - GPU_texture_update_mipmap(icongltex.tex[0], 1, GPU_DATA_UBYTE, b16buf->rect); + GPU_texture_update_mipmap(icongltex.tex[0], 0, GPU_DATA_UBYTE, b32buf->byte_buffer.data); + GPU_texture_update_mipmap(icongltex.tex[0], 1, GPU_DATA_UBYTE, b16buf->byte_buffer.data); } if (need_icons_with_border && icongltex.tex[1] == nullptr) { @@ -926,8 +930,10 @@ void UI_icons_reload_internal_textures() GPU_RGBA8, GPU_TEXTURE_USAGE_SHADER_READ, nullptr); - GPU_texture_update_mipmap(icongltex.tex[1], 0, GPU_DATA_UBYTE, b32buf_border->rect); - GPU_texture_update_mipmap(icongltex.tex[1], 1, GPU_DATA_UBYTE, b16buf_border->rect); + GPU_texture_update_mipmap( + icongltex.tex[1], 0, GPU_DATA_UBYTE, b32buf_border->byte_buffer.data); + GPU_texture_update_mipmap( + icongltex.tex[1], 1, GPU_DATA_UBYTE, b16buf_border->byte_buffer.data); } } @@ -1316,7 +1322,8 @@ static void ui_studiolight_icon_job_exec(void *customdata, Icon *icon = *tmp; DrawInfo *di = icon_ensure_drawinfo(icon); StudioLight *sl = static_cast(icon->obj); - BKE_studiolight_preview(di->data.buffer.image->rect, sl, icon->id_type); + BKE_studiolight_preview( + reinterpret_cast(di->data.buffer.image->rect), sl, icon->id_type); } static void ui_studiolight_kill_icon_preview_job(wmWindowManager *wm, int icon_id) @@ -1401,7 +1408,7 @@ void ui_icon_ensure_deferred(const bContext *C, const int icon_id, const bool bi img->w = STUDIOLIGHT_ICON_SIZE; img->h = STUDIOLIGHT_ICON_SIZE; const size_t size = STUDIOLIGHT_ICON_SIZE * STUDIOLIGHT_ICON_SIZE * sizeof(uint); - img->rect = static_cast(MEM_mallocN(size, __func__)); + img->rect = static_cast(MEM_mallocN(size, __func__)); memset(img->rect, 0, size); di->data.buffer.image = img; @@ -1499,12 +1506,11 @@ PreviewImage *UI_icon_to_preview(int icon_id) if (bbuf) { PreviewImage *prv = BKE_previewimg_create(); - prv->rect[0] = bbuf->rect; + prv->rect[0] = reinterpret_cast(IMB_steal_byte_buffer(bbuf)); prv->w[0] = bbuf->x; prv->h[0] = bbuf->y; - bbuf->rect = nullptr; IMB_freeImBuf(bbuf); return prv; @@ -1521,7 +1527,7 @@ static void icon_draw_rect(float x, float /*aspect*/, int rw, int rh, - uint *rect, + uint8_t *rect, float alpha, const float desaturate) { @@ -1878,7 +1884,8 @@ static void icon_draw_size(float x, ImBuf *ibuf = static_cast(icon->obj); GPU_blend(GPU_BLEND_ALPHA_PREMULT); - icon_draw_rect(x, y, w, h, aspect, ibuf->x, ibuf->y, ibuf->rect, alpha, desaturate); + icon_draw_rect( + x, y, w, h, aspect, ibuf->x, ibuf->y, ibuf->byte_buffer.data, alpha, desaturate); GPU_blend(GPU_BLEND_ALPHA); } else if (di->type == ICON_TYPE_VECTOR) { @@ -1918,7 +1925,7 @@ static void icon_draw_size(float x, } GPU_blend(GPU_BLEND_ALPHA_PREMULT); - icon_draw_rect(x, y, w, h, aspect, w, h, ibuf->rect, alpha, desaturate); + icon_draw_rect(x, y, w, h, aspect, w, h, ibuf->byte_buffer.data, alpha, desaturate); GPU_blend(GPU_BLEND_ALPHA); } else if (di->type == ICON_TYPE_EVENT) { @@ -2003,8 +2010,16 @@ static void icon_draw_size(float x, /* Preview images use premultiplied alpha. */ GPU_blend(GPU_BLEND_ALPHA_PREMULT); - icon_draw_rect( - x, y, w, h, aspect, pi->w[size], pi->h[size], pi->rect[size], alpha, desaturate); + icon_draw_rect(x, + y, + w, + h, + aspect, + pi->w[size], + pi->h[size], + reinterpret_cast(pi->rect[size]), + alpha, + desaturate); GPU_blend(GPU_BLEND_ALPHA); } } diff --git a/source/blender/editors/interface/interface_ops.cc b/source/blender/editors/interface/interface_ops.cc index a471d98cc21..c40aabe65fd 100644 --- a/source/blender/editors/interface/interface_ops.cc +++ b/source/blender/editors/interface/interface_ops.cc @@ -1396,7 +1396,6 @@ static bool copy_to_selected_button(bContext *C, bool all, bool poll) Main *bmain = CTX_data_main(C); PointerRNA ptr, lptr; PropertyRNA *prop, *lprop; - bool success = false; int index; /* try to reset the nominated setting to its default value */ @@ -1407,36 +1406,31 @@ static bool copy_to_selected_button(bContext *C, bool all, bool poll) return false; } + bool success = false; char *path = nullptr; bool use_path_from_id; ListBase lb = {nullptr}; - if (!UI_context_copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path)) { - return false; - } - if (BLI_listbase_is_empty(&lb)) { - MEM_SAFE_FREE(path); - return false; - } + if (UI_context_copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path)) { + LISTBASE_FOREACH (CollectionPointerLink *, link, &lb) { + if (link->ptr.data == ptr.data) { + continue; + } - LISTBASE_FOREACH (CollectionPointerLink *, link, &lb) { - if (link->ptr.data == ptr.data) { - continue; - } + if (!UI_context_copy_to_selected_check( + &ptr, &link->ptr, prop, path, use_path_from_id, &lptr, &lprop)) + { + continue; + } - if (!UI_context_copy_to_selected_check( - &ptr, &link->ptr, prop, path, use_path_from_id, &lptr, &lprop)) - { - continue; - } - - if (poll) { - success = true; - break; - } - if (RNA_property_copy(bmain, &lptr, &ptr, prop, (all) ? -1 : index)) { - RNA_property_update(C, &lptr, prop); - success = true; + if (poll) { + success = true; + break; + } + if (RNA_property_copy(bmain, &lptr, &ptr, prop, (all) ? -1 : index)) { + RNA_property_update(C, &lptr, prop); + success = true; + } } } diff --git a/source/blender/editors/interface/interface_region_menu_popup.cc b/source/blender/editors/interface/interface_region_menu_popup.cc index 2a23191eb49..d29539b9fa6 100644 --- a/source/blender/editors/interface/interface_region_menu_popup.cc +++ b/source/blender/editors/interface/interface_region_menu_popup.cc @@ -191,11 +191,11 @@ static void ui_popup_menu_create_block(bContext *C, if (!pup->but) { pup->block->flag |= UI_BLOCK_NO_FLIP; } - /* A title is only provided when a Menu has a label, this is not alwas the case, see e.g. + /* A title is only provided when a Menu has a label, this is not always the case, see e.g. * `VIEW3D_MT_edit_mesh_context_menu` -- this specifies its own label inside the draw function * depending on vertex/edge/face mode. We still want to flag the uiBlock (but only insert into - * the puphash if we have a title provided). Choosing an entry in a menu will still handle - * puphash later (see `button_activate_exit`) though multiple menus without a label might fight + * the `puphash` if we have a title provided). Choosing an entry in a menu will still handle + * `puphash` later (see `button_activate_exit`) though multiple menus without a label might fight * for the same storage of the menu memory. Using idname instead (or in combination with the * label) for the hash could be looked at to solve this. */ pup->block->flag |= UI_BLOCK_POPUP_MEMORY; diff --git a/source/blender/editors/interface/interface_template_asset_view.cc b/source/blender/editors/interface/interface_template_asset_view.cc index c18ee3c37d8..7f33b3a6990 100644 --- a/source/blender/editors/interface/interface_template_asset_view.cc +++ b/source/blender/editors/interface/interface_template_asset_view.cc @@ -88,9 +88,8 @@ static void asset_view_draw_item(uiList *ui_list, uiBlock *block = uiLayoutGetBlock(layout); const bool show_names = list_data->show_names; - /* TODO ED_fileselect_init_layout(). Share somehow? */ - const float size_x = (96.0f / 20.0f) * UI_UNIT_X; - const float size_y = (96.0f / 20.0f) * UI_UNIT_Y - (show_names ? 0 : UI_UNIT_Y); + const float size_x = UI_preview_tile_size_x(); + const float size_y = show_names ? UI_preview_tile_size_y() : UI_preview_tile_size_y_no_label(); uiBut *but = uiDefIconTextBut(block, UI_BTYPE_PREVIEW_TILE, 0, @@ -110,6 +109,7 @@ static void asset_view_draw_item(uiList *ui_list, ED_asset_handle_get_preview_icon_id(&asset_handle), /* NOLINTNEXTLINE: bugprone-suspicious-enum-usage */ UI_HAS_ICON | UI_BUT_ICON_PREVIEW); + but->emboss = UI_EMBOSS_NONE; if (!ui_list->dyn_data->custom_drag_optype) { asset_view_item_but_drag_set(but, &asset_handle); } @@ -268,9 +268,14 @@ void uiTemplateAssetView(uiLayout *layout, template_list_flags |= UI_TEMPLATE_LIST_NO_FILTER_OPTIONS; } + uiLayout *subcol = uiLayoutColumn(col, false); + + uiLayoutSetScaleX(subcol, 0.8f); + uiLayoutSetScaleY(subcol, 0.8f); + /* TODO can we have some kind of model-view API to handle referencing, filtering and lazy loading * (of previews) of the items? */ - uiList *list = uiTemplateList_ex(col, + uiList *list = uiTemplateList_ex(subcol, C, "UI_UL_asset_view", list_id, diff --git a/source/blender/editors/interface/interface_template_list.cc b/source/blender/editors/interface/interface_template_list.cc index 30a59bb42c4..e9c16a4169e 100644 --- a/source/blender/editors/interface/interface_template_list.cc +++ b/source/blender/editors/interface/interface_template_list.cc @@ -644,7 +644,12 @@ static void *uilist_item_use_dynamic_tooltip(PointerRNA *itemptr, const char *pr static char *uilist_item_tooltip_func(bContext * /*C*/, void *argN, const char *tip) { char *dyn_tooltip = static_cast(argN); - return BLI_sprintfN("%s - %s", tip, dyn_tooltip); + std::string tooltip_string = dyn_tooltip; + if (tip && tip[0]) { + tooltip_string += '\n'; + tooltip_string += tip; + } + return BLI_strdupn(tooltip_string.c_str(), tooltip_string.size()); } /** @@ -745,6 +750,9 @@ static void ui_template_list_layout_draw(const bContext *C, int i = 0; if (input_data->dataptr.data && input_data->prop) { + + const bool editable = (RNA_property_flag(input_data->prop) & PROP_EDITABLE); + /* create list items */ for (i = visual_info.start_idx; i < visual_info.end_idx; i++) { PointerRNA *itemptr = &items->item_vec[i].item; @@ -775,7 +783,7 @@ static void ui_template_list_layout_draw(const bContext *C, org_i, 0, 0, - TIP_("Double click to rename")); + editable ? TIP_("Double click to rename") : ""); if ((dyntip_data = uilist_item_use_dynamic_tooltip(itemptr, input_data->item_dyntip_propname))) { UI_but_func_tooltip_set(but, uilist_item_tooltip_func, dyntip_data, MEM_freeN); diff --git a/source/blender/editors/interface/interface_widgets.cc b/source/blender/editors/interface/interface_widgets.cc index 4bce1637405..37b528eeab7 100644 --- a/source/blender/editors/interface/interface_widgets.cc +++ b/source/blender/editors/interface/interface_widgets.cc @@ -4114,7 +4114,9 @@ static void widget_preview_tile(uiBut *but, int roundboxalign, const float zoom) { - widget_list_itembut(wcol, rect, state, roundboxalign, zoom); + if (!ELEM(but->emboss, UI_EMBOSS_NONE, UI_EMBOSS_NONE_OR_STATUS)) { + widget_list_itembut(wcol, rect, state, roundboxalign, zoom); + } ui_draw_preview_item_stateless( &UI_style_get()->widget, rect, but->drawstr, but->icon, wcol->text, UI_STYLE_TEXT_CENTER); @@ -4685,6 +4687,9 @@ void ui_draw_but(const bContext *C, ARegion *region, uiStyle *style, uiBut *but, but->drawflag |= UI_BUT_NO_TEXT_PADDING; } break; + case UI_BTYPE_PREVIEW_TILE: + wt = widget_type(UI_WTYPE_PREVIEW_TILE); + break; default: wt = widget_type(UI_WTYPE_ICON); break; @@ -5473,7 +5478,6 @@ void ui_draw_preview_item_stateless(const uiFontStyle *fstyle, { rcti trect = *rect; const float text_size = UI_UNIT_Y; - float font_dims[2] = {0.0f, 0.0f}; const bool has_text = name && name[0]; if (has_text) { @@ -5488,15 +5492,11 @@ void ui_draw_preview_item_stateless(const uiFontStyle *fstyle, return; } - BLF_width_and_height( - fstyle->uifont_id, name, BLF_DRAW_STR_DUMMY_MAX, &font_dims[0], &font_dims[1]); - /* text rect */ - trect.ymin += U.widget_unit / 2; - trect.ymax = trect.ymin + font_dims[1]; - if (trect.xmax > rect->xmax - PREVIEW_PAD) { - trect.xmax = rect->xmax - PREVIEW_PAD; - } + trect.ymax = trect.ymin + text_size; + trect.ymin += PREVIEW_PAD; + trect.xmin += PREVIEW_PAD; + trect.xmax -= PREVIEW_PAD; { char drawstr[UI_MAX_DRAW_STR]; diff --git a/source/blender/editors/interface/views/grid_view.cc b/source/blender/editors/interface/views/grid_view.cc index 8b0c42e2bda..ff0bcb3388f 100644 --- a/source/blender/editors/interface/views/grid_view.cc +++ b/source/blender/editors/interface/views/grid_view.cc @@ -328,6 +328,7 @@ void GridViewLayoutBuilder::build_grid_tile(uiLayout &grid_layout, AbstractGridViewItem &item) const { uiLayout *overlap = uiLayoutOverlap(&grid_layout); + uiLayoutSetFixedSize(overlap, true); item.add_grid_tile_button(block_); item.build_grid_tile(*uiLayoutRow(overlap, false)); @@ -338,7 +339,7 @@ void GridViewLayoutBuilder::build_from_view(const AbstractGridView &grid_view, { uiLayout *parent_layout = current_layout(); - uiLayout &layout = *uiLayoutColumn(current_layout(), false); + uiLayout &layout = *uiLayoutColumn(current_layout(), true); const GridViewStyle &style = grid_view.get_style(); const int cols_per_row = std::max(uiLayoutGetWidth(&layout) / style.tile_width, 1); @@ -347,12 +348,8 @@ void GridViewLayoutBuilder::build_from_view(const AbstractGridView &grid_view, build_visible_helper.fill_layout_before_visible(block_); - /* Use `-cols_per_row` because the grid layout uses a multiple of the passed absolute value for - * the number of columns then, rather than distributing the number of items evenly over rows and - * stretching the items to fit (see #uiLayoutItemGridFlow.columns_len). */ - uiLayout *grid_layout = uiLayoutGridFlow(&layout, true, -cols_per_row, true, true, true); - int item_idx = 0; + uiLayout *row = nullptr; grid_view.foreach_item([&](AbstractGridViewItem &item) { /* Skip if item isn't visible. */ if (!build_visible_helper.is_item_visible(item_idx)) { @@ -360,20 +357,15 @@ void GridViewLayoutBuilder::build_from_view(const AbstractGridView &grid_view, return; } - build_grid_tile(*grid_layout, item); + /* Start a new row for every first item in the row. */ + if ((item_idx % cols_per_row) == 0) { + row = uiLayoutRow(&layout, true); + } + + build_grid_tile(*row, item); item_idx++; }); - /* If there are not enough items to fill the layout, add padding items so the layout doesn't - * stretch over the entire width. */ - if (grid_view.get_item_count() < cols_per_row) { - for (int padding_item_idx = 0; padding_item_idx < (cols_per_row - grid_view.get_item_count()); - padding_item_idx++) - { - uiItemS(grid_layout); - } - } - UI_block_layout_set_current(&block_, parent_layout); build_visible_helper.fill_layout_after_visible(block_); @@ -435,6 +427,7 @@ void PreviewGridItem::build_grid_tile(uiLayout &layout) const preview_icon_id, /* NOLINTNEXTLINE: bugprone-suspicious-enum-usage */ UI_HAS_ICON | UI_BUT_ICON_PREVIEW); + but->emboss = UI_EMBOSS_NONE; } void PreviewGridItem::set_on_activate_fn(ActivateFn fn) diff --git a/source/blender/editors/lattice/editlattice_undo.c b/source/blender/editors/lattice/editlattice_undo.c index f21c36db411..90dba2dc33f 100644 --- a/source/blender/editors/lattice/editlattice_undo.c +++ b/source/blender/editors/lattice/editlattice_undo.c @@ -71,8 +71,8 @@ static void undolatt_to_editlatt(UndoLattice *ult, EditLatt *editlatt) memcpy(editlatt->latt->def, ult->def, sizeof(BPoint) * len_src); } - /* Even for the same amount of points we dont just copy memory for MDeformVert, relations to - * MDeformWeight might have changed. */ + /* Even for the same amount of points we don't just copy memory for MDeformVert, + * relations to #MDeformWeight might have changed. */ if (editlatt->latt->dvert && ult->dvert) { BKE_defvert_array_free(editlatt->latt->dvert, len_dst); editlatt->latt->dvert = MEM_mallocN(sizeof(MDeformVert) * len_src, "Lattice MDeformVert"); diff --git a/source/blender/editors/mesh/editmesh_path.c b/source/blender/editors/mesh/editmesh_path.c index e65a0875dee..6f532e7588f 100644 --- a/source/blender/editors/mesh/editmesh_path.c +++ b/source/blender/editors/mesh/editmesh_path.c @@ -149,6 +149,7 @@ static bool path_select_poll_property(const bContext *C, struct UserData { BMesh *bm; Mesh *me; + int cd_offset; const struct PathSelectParams *op_params; }; @@ -182,7 +183,24 @@ static void mouse_mesh_shortest_path_vert(Scene *UNUSED(scene), BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; - struct UserData user_data = {bm, obedit->data, op_params}; + int cd_offset = -1; + switch (op_params->edge_mode) { + case EDGE_MODE_SELECT: + case EDGE_MODE_TAG_SEAM: + case EDGE_MODE_TAG_SHARP: +#ifdef WITH_FREESTYLE + case EDGE_MODE_TAG_FREESTYLE: +#endif + break; + case EDGE_MODE_TAG_CREASE: + cd_offset = CustomData_get_offset(&bm->edata, CD_CREASE); + break; + case EDGE_MODE_TAG_BEVEL: + cd_offset = CustomData_get_offset_named(&bm->edata, CD_PROP_FLOAT, "bevel_weight_edge"); + break; + } + + struct UserData user_data = {bm, obedit->data, cd_offset, op_params}; LinkNode *path = NULL; bool is_path_ordered = false; @@ -281,7 +299,6 @@ static bool edgetag_test_cb(BMEdge *e, void *user_data_v) { struct UserData *user_data = user_data_v; const char edge_mode = user_data->op_params->edge_mode; - BMesh *bm = user_data->bm; switch (edge_mode) { case EDGE_MODE_SELECT: @@ -291,11 +308,11 @@ static bool edgetag_test_cb(BMEdge *e, void *user_data_v) case EDGE_MODE_TAG_SHARP: return BM_elem_flag_test(e, BM_ELEM_SMOOTH) ? false : true; case EDGE_MODE_TAG_CREASE: - return BM_elem_float_data_get(&bm->edata, e, CD_CREASE) ? true : false; case EDGE_MODE_TAG_BEVEL: - return BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT) ? true : false; + return BM_ELEM_CD_GET_FLOAT(e, user_data->cd_offset); #ifdef WITH_FREESTYLE case EDGE_MODE_TAG_FREESTYLE: { + BMesh *bm = user_data->bm; FreestyleEdge *fed = CustomData_bmesh_get(&bm->edata, e->head.data, CD_FREESTYLE_EDGE); return (!fed) ? false : (fed->flag & FREESTYLE_EDGE_MARK) ? true : false; } @@ -320,10 +337,8 @@ static void edgetag_set_cb(BMEdge *e, bool val, void *user_data_v) BM_elem_flag_set(e, BM_ELEM_SMOOTH, !val); break; case EDGE_MODE_TAG_CREASE: - BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (val) ? 1.0f : 0.0f); - break; case EDGE_MODE_TAG_BEVEL: - BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (val) ? 1.0f : 0.0f); + BM_ELEM_CD_SET_FLOAT(e, user_data->cd_offset, (val) ? 1.0f : 0.0f); break; #ifdef WITH_FREESTYLE case EDGE_MODE_TAG_FREESTYLE: { @@ -352,8 +367,8 @@ static void edgetag_ensure_cd_flag(Mesh *me, const char edge_mode) } break; case EDGE_MODE_TAG_BEVEL: - if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) { - BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT); + if (!CustomData_has_layer_named(&bm->edata, CD_PROP_FLOAT, "bevel_weight_edge")) { + BM_data_layer_add_named(bm, &bm->edata, CD_PROP_FLOAT, "bevel_weight_edge"); } break; #ifdef WITH_FREESTYLE @@ -380,7 +395,24 @@ static void mouse_mesh_shortest_path_edge(Scene *scene, BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; - struct UserData user_data = {bm, obedit->data, op_params}; + int cd_offset = -1; + switch (op_params->edge_mode) { + case EDGE_MODE_SELECT: + case EDGE_MODE_TAG_SEAM: + case EDGE_MODE_TAG_SHARP: +#ifdef WITH_FREESTYLE + case EDGE_MODE_TAG_FREESTYLE: +#endif + break; + case EDGE_MODE_TAG_CREASE: + cd_offset = CustomData_get_offset(&bm->edata, CD_CREASE); + break; + case EDGE_MODE_TAG_BEVEL: + cd_offset = CustomData_get_offset_named(&bm->edata, CD_PROP_FLOAT, "bevel_weight_edge"); + break; + } + + struct UserData user_data = {bm, obedit->data, cd_offset, op_params}; LinkNode *path = NULL; bool is_path_ordered = false; @@ -516,7 +548,24 @@ static void mouse_mesh_shortest_path_face(Scene *UNUSED(scene), BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; - struct UserData user_data = {bm, obedit->data, op_params}; + int cd_offset = -1; + switch (op_params->edge_mode) { + case EDGE_MODE_SELECT: + case EDGE_MODE_TAG_SEAM: + case EDGE_MODE_TAG_SHARP: +#ifdef WITH_FREESTYLE + case EDGE_MODE_TAG_FREESTYLE: +#endif + break; + case EDGE_MODE_TAG_CREASE: + cd_offset = CustomData_get_offset(&bm->edata, CD_CREASE); + break; + case EDGE_MODE_TAG_BEVEL: + cd_offset = CustomData_get_offset_named(&bm->edata, CD_PROP_FLOAT, "bevel_weight_edge"); + break; + } + + struct UserData user_data = {bm, obedit->data, cd_offset, op_params}; LinkNode *path = NULL; bool is_path_ordered = false; diff --git a/source/blender/editors/mesh/editmesh_select_similar.c b/source/blender/editors/mesh/editmesh_select_similar.c index 88e5f5614d6..ebeeae58a2e 100644 --- a/source/blender/editors/mesh/editmesh_select_similar.c +++ b/source/blender/editors/mesh/editmesh_select_similar.c @@ -630,7 +630,6 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) const float thresh = RNA_float_get(op->ptr, "threshold"); const float thresh_radians = thresh * (float)M_PI + FLT_EPSILON; const int compare = RNA_enum_get(op->ptr, "compare"); - int custom_data_type = -1; int tot_edges_selected_all = 0; uint objects_len = 0; @@ -669,15 +668,6 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) break; } - switch (type) { - case SIMEDGE_CREASE: - custom_data_type = CD_CREASE; - break; - case SIMEDGE_BEVEL: - custom_data_type = CD_BWEIGHT; - break; - } - int tree_index = 0; for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *ob = objects[ob_index]; @@ -696,14 +686,31 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) } break; } - case SIMEDGE_CREASE: - case SIMEDGE_BEVEL: { - if (!CustomData_has_layer(&bm->edata, custom_data_type)) { + case SIMEDGE_CREASE: { + if (!CustomData_has_layer(&bm->edata, CD_CREASE)) { BLI_kdtree_1d_insert(tree_1d, tree_index++, (float[1]){0.0f}); continue; } break; } + case SIMEDGE_BEVEL: { + if (!CustomData_has_layer_named(&bm->edata, CD_PROP_FLOAT, "bevel_weight_edge")) { + BLI_kdtree_1d_insert(tree_1d, tree_index++, (float[1]){0.0f}); + continue; + } + break; + } + } + + int custom_data_offset; + switch (type) { + case SIMEDGE_CREASE: + custom_data_offset = CustomData_get_offset(&bm->edata, CD_CREASE); + break; + case SIMEDGE_BEVEL: + custom_data_offset = CustomData_get_offset_named( + &bm->edata, CD_PROP_FLOAT, "bevel_weight_edge"); + break; } float ob_m3[3][3], ob_m3_inv[3][3]; @@ -763,8 +770,7 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) } case SIMEDGE_CREASE: case SIMEDGE_BEVEL: { - const float *value = CustomData_bmesh_get( - &bm->edata, edge->head.data, custom_data_type); + const float *value = BM_ELEM_CD_GET_FLOAT_P(edge, custom_data_offset); BLI_kdtree_1d_insert(tree_1d, tree_index++, value); break; } @@ -799,9 +805,13 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) } break; } - case SIMEDGE_CREASE: + case SIMEDGE_CREASE: { + has_custom_data_layer = CustomData_has_layer(&bm->edata, CD_CREASE); + ATTR_FALLTHROUGH; + } case SIMEDGE_BEVEL: { - has_custom_data_layer = CustomData_has_layer(&bm->edata, custom_data_type); + has_custom_data_layer = CustomData_has_layer_named( + &bm->edata, CD_PROP_FLOAT, "bevel_weight_edge"); if (!has_custom_data_layer) { /* Proceed only if we have to select all the edges that have custom data value of 0.0f. * In this case we will just select all the edges. @@ -817,6 +827,17 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) copy_m3_m4(ob_m3, ob->object_to_world); invert_m3_m3(ob_m3_inv, ob_m3); + int custom_data_offset; + switch (type) { + case SIMEDGE_CREASE: + custom_data_offset = CustomData_get_offset(&bm->edata, CD_CREASE); + break; + case SIMEDGE_BEVEL: + custom_data_offset = CustomData_get_offset_named( + &bm->edata, CD_PROP_FLOAT, "bevel_weight_edge"); + break; + } + BMEdge *edge; /* Mesh edge. */ BMIter iter; /* Selected edges iterator. */ @@ -903,8 +924,7 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) break; } - const float *value = CustomData_bmesh_get( - &bm->edata, edge->head.data, custom_data_type); + const float *value = BM_ELEM_CD_GET_FLOAT_P(edge, custom_data_offset); if (ED_select_similar_compare_float_tree(tree_1d, *value, thresh, compare)) { select = true; } diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc index 9c0a393d52a..a8b6518dbbb 100644 --- a/source/blender/editors/mesh/mesh_data.cc +++ b/source/blender/editors/mesh/mesh_data.cc @@ -464,49 +464,6 @@ static bool layers_poll(bContext *C) !ID_IS_LINKED(data) && !ID_IS_OVERRIDE_LIBRARY(data)); } -/*********************** Sculpt Vertex colors operators ************************/ - -int ED_mesh_sculpt_color_add(Mesh *me, const char *name, const bool do_init, ReportList *reports) -{ - /* If no name is supplied, provide a backwards compatible default. */ - if (!name) { - name = "Color"; - } - - if (const CustomDataLayer *layer = BKE_id_attribute_find( - &me->id, me->active_color_attribute, CD_PROP_COLOR, ATTR_DOMAIN_POINT)) - { - int dummy; - const CustomData *data = mesh_customdata_get_type(me, BM_LOOP, &dummy); - return CustomData_get_named_layer(data, CD_PROP_BYTE_COLOR, layer->name); - } - - CustomDataLayer *layer = BKE_id_attribute_new( - &me->id, name, CD_PROP_COLOR, ATTR_DOMAIN_POINT, reports); - - if (do_init) { - const char *active_name = me->active_color_attribute; - if (const CustomDataLayer *active_layer = BKE_id_attributes_color_find(&me->id, active_name)) { - if (const BMEditMesh *em = me->edit_mesh) { - BMesh &bm = *em->bm; - const int src_i = CustomData_get_named_layer(&bm.vdata, CD_PROP_COLOR, active_name); - const int dst_i = CustomData_get_named_layer(&bm.vdata, CD_PROP_COLOR, layer->name); - BM_data_layer_copy(&bm, &bm.vdata, CD_PROP_COLOR, src_i, dst_i); - } - else { - memcpy(layer->data, active_layer->data, CustomData_get_elem_size(layer) * me->totloop); - } - } - } - - DEG_id_tag_update(&me->id, 0); - WM_main_add_notifier(NC_GEOM | ND_DATA, me); - - int dummy; - const CustomData *data = mesh_customdata_get_type(me, BM_VERT, &dummy); - return CustomData_get_named_layer(data, CD_PROP_COLOR, layer->name); -} - /*********************** UV texture operators ************************/ static bool uv_texture_remove_poll(bContext *C) @@ -868,126 +825,6 @@ void MESH_OT_customdata_custom_splitnormals_clear(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* Vertex bevel weight. */ - -static int mesh_customdata_bevel_weight_vertex_state(bContext *C) -{ - const Object *object = ED_object_context(C); - - if (object && object->type == OB_MESH) { - const Mesh *mesh = static_cast(object->data); - if (!ID_IS_LINKED(mesh)) { - const CustomData *data = GET_CD_DATA(mesh, vdata); - return CustomData_has_layer(data, CD_BWEIGHT); - } - } - return -1; -} - -static bool mesh_customdata_bevel_weight_vertex_add_poll(bContext *C) -{ - return mesh_customdata_bevel_weight_vertex_state(C) == 0; -} - -static int mesh_customdata_bevel_weight_vertex_add_exec(bContext *C, wmOperator * /*op*/) -{ - return mesh_customdata_add_exec__internal(C, BM_VERT, CD_BWEIGHT); -} - -void MESH_OT_customdata_bevel_weight_vertex_add(wmOperatorType *ot) -{ - ot->name = "Add Vertex Bevel Weight"; - ot->idname = "MESH_OT_customdata_bevel_weight_vertex_add"; - ot->description = "Add a vertex bevel weight layer"; - - ot->exec = mesh_customdata_bevel_weight_vertex_add_exec; - ot->poll = mesh_customdata_bevel_weight_vertex_add_poll; - - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -static bool mesh_customdata_bevel_weight_vertex_clear_poll(bContext *C) -{ - return (mesh_customdata_bevel_weight_vertex_state(C) == 1); -} - -static int mesh_customdata_bevel_weight_vertex_clear_exec(bContext *C, wmOperator * /*op*/) -{ - return mesh_customdata_clear_exec__internal(C, BM_VERT, CD_BWEIGHT); -} - -void MESH_OT_customdata_bevel_weight_vertex_clear(wmOperatorType *ot) -{ - ot->name = "Clear Vertex Bevel Weight"; - ot->idname = "MESH_OT_customdata_bevel_weight_vertex_clear"; - ot->description = "Clear the vertex bevel weight layer"; - - ot->exec = mesh_customdata_bevel_weight_vertex_clear_exec; - ot->poll = mesh_customdata_bevel_weight_vertex_clear_poll; - - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/* Edge bevel weight. */ - -static int mesh_customdata_bevel_weight_edge_state(bContext *C) -{ - const Object *ob = ED_object_context(C); - - if (ob && ob->type == OB_MESH) { - const Mesh *mesh = static_cast(ob->data); - if (!ID_IS_LINKED(mesh)) { - const CustomData *data = GET_CD_DATA(mesh, edata); - return CustomData_has_layer(data, CD_BWEIGHT); - } - } - return -1; -} - -static bool mesh_customdata_bevel_weight_edge_add_poll(bContext *C) -{ - return mesh_customdata_bevel_weight_edge_state(C) == 0; -} - -static int mesh_customdata_bevel_weight_edge_add_exec(bContext *C, wmOperator * /*op*/) -{ - return mesh_customdata_add_exec__internal(C, BM_EDGE, CD_BWEIGHT); -} - -void MESH_OT_customdata_bevel_weight_edge_add(wmOperatorType *ot) -{ - ot->name = "Add Edge Bevel Weight"; - ot->idname = "MESH_OT_customdata_bevel_weight_edge_add"; - ot->description = "Add an edge bevel weight layer"; - - ot->exec = mesh_customdata_bevel_weight_edge_add_exec; - ot->poll = mesh_customdata_bevel_weight_edge_add_poll; - - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -static bool mesh_customdata_bevel_weight_edge_clear_poll(bContext *C) -{ - return mesh_customdata_bevel_weight_edge_state(C) == 1; -} - -static int mesh_customdata_bevel_weight_edge_clear_exec(bContext *C, wmOperator * /*op*/) -{ - return mesh_customdata_clear_exec__internal(C, BM_EDGE, CD_BWEIGHT); -} - -void MESH_OT_customdata_bevel_weight_edge_clear(wmOperatorType *ot) -{ - ot->name = "Clear Edge Bevel Weight"; - ot->idname = "MESH_OT_customdata_bevel_weight_edge_clear"; - ot->description = "Clear the edge bevel weight layer"; - - ot->exec = mesh_customdata_bevel_weight_edge_clear_exec; - ot->poll = mesh_customdata_bevel_weight_edge_clear_poll; - - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - /* Edge crease. */ static int mesh_customdata_crease_edge_state(bContext *C) @@ -1149,7 +986,7 @@ static void mesh_add_verts(Mesh *mesh, int len) CustomData_copy_layout(&mesh->vdata, &vdata, CD_MASK_MESH.vmask, CD_SET_DEFAULT, totvert); CustomData_copy_data(&mesh->vdata, &vdata, 0, 0, mesh->totvert); - if (!CustomData_get_layer_named(&vdata, CD_PROP_FLOAT3, "position")) { + if (!CustomData_has_layer_named(&vdata, CD_PROP_FLOAT3, "position")) { CustomData_add_layer_named(&vdata, CD_PROP_FLOAT3, CD_SET_DEFAULT, totvert, "position"); } @@ -1183,7 +1020,7 @@ static void mesh_add_edges(Mesh *mesh, int len) CustomData_copy_layout(&mesh->edata, &edata, CD_MASK_MESH.emask, CD_SET_DEFAULT, totedge); CustomData_copy_data(&mesh->edata, &edata, 0, 0, mesh->totedge); - if (!CustomData_get_layer_named(&edata, CD_PROP_INT32_2D, ".edge_verts")) { + if (!CustomData_has_layer_named(&edata, CD_PROP_INT32_2D, ".edge_verts")) { CustomData_add_layer_named(&edata, CD_PROP_INT32_2D, CD_SET_DEFAULT, totedge, ".edge_verts"); } @@ -1216,10 +1053,10 @@ static void mesh_add_loops(Mesh *mesh, int len) CustomData_copy_layout(&mesh->ldata, &ldata, CD_MASK_MESH.lmask, CD_SET_DEFAULT, totloop); CustomData_copy_data(&mesh->ldata, &ldata, 0, 0, mesh->totloop); - if (!CustomData_get_layer_named(&ldata, CD_PROP_INT32, ".corner_vert")) { + if (!CustomData_has_layer_named(&ldata, CD_PROP_INT32, ".corner_vert")) { CustomData_add_layer_named(&ldata, CD_PROP_INT32, CD_SET_DEFAULT, totloop, ".corner_vert"); } - if (!CustomData_get_layer_named(&ldata, CD_PROP_INT32, ".corner_edge")) { + if (!CustomData_has_layer_named(&ldata, CD_PROP_INT32, ".corner_edge")) { CustomData_add_layer_named(&ldata, CD_PROP_INT32, CD_SET_DEFAULT, totloop, ".corner_edge"); } diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 42022daa113..a6001824b75 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -323,10 +323,6 @@ void MESH_OT_customdata_skin_add(struct wmOperatorType *ot); void MESH_OT_customdata_skin_clear(struct wmOperatorType *ot); void MESH_OT_customdata_custom_splitnormals_add(struct wmOperatorType *ot); void MESH_OT_customdata_custom_splitnormals_clear(struct wmOperatorType *ot); -void MESH_OT_customdata_bevel_weight_vertex_add(struct wmOperatorType *ot); -void MESH_OT_customdata_bevel_weight_vertex_clear(struct wmOperatorType *ot); -void MESH_OT_customdata_bevel_weight_edge_add(struct wmOperatorType *ot); -void MESH_OT_customdata_bevel_weight_edge_clear(struct wmOperatorType *ot); void MESH_OT_customdata_crease_vertex_add(struct wmOperatorType *ot); void MESH_OT_customdata_crease_vertex_clear(struct wmOperatorType *ot); void MESH_OT_customdata_crease_edge_add(struct wmOperatorType *ot); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 68d4437f0f8..ee888cced53 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -141,10 +141,6 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_customdata_skin_clear); WM_operatortype_append(MESH_OT_customdata_custom_splitnormals_add); WM_operatortype_append(MESH_OT_customdata_custom_splitnormals_clear); - WM_operatortype_append(MESH_OT_customdata_bevel_weight_vertex_add); - WM_operatortype_append(MESH_OT_customdata_bevel_weight_vertex_clear); - WM_operatortype_append(MESH_OT_customdata_bevel_weight_edge_add); - WM_operatortype_append(MESH_OT_customdata_bevel_weight_edge_clear); WM_operatortype_append(MESH_OT_customdata_crease_vertex_add); WM_operatortype_append(MESH_OT_customdata_crease_vertex_clear); WM_operatortype_append(MESH_OT_customdata_crease_edge_add); diff --git a/source/blender/editors/object/object_bake.cc b/source/blender/editors/object/object_bake.cc index 768f69c78f9..a105c9874fb 100644 --- a/source/blender/editors/object/object_bake.cc +++ b/source/blender/editors/object/object_bake.cc @@ -188,11 +188,11 @@ static bool multiresbake_check(bContext *C, wmOperator *op) ok = false; } else { - if (ibuf->rect == nullptr && ibuf->rect_float == nullptr) { + if (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data == nullptr) { ok = false; } - if (ibuf->rect_float && !ELEM(ibuf->channels, 0, 4)) { + if (ibuf->float_buffer.data && !ELEM(ibuf->channels, 0, 4)) { ok = false; } diff --git a/source/blender/editors/object/object_bake_api.cc b/source/blender/editors/object/object_bake_api.cc index 179fb3dff69..ba13859d68c 100644 --- a/source/blender/editors/object/object_bake_api.cc +++ b/source/blender/editors/object/object_bake_api.cc @@ -186,7 +186,7 @@ static void bias_tangent_normal_pixels( BLI_assert(channels >= 3); for (int y = 0; y < height; y++) { - float *pixels = rect + ((size_t)stride) * y * channels; + float *pixels = rect + size_t(stride) * y * channels; for (int x = 0; x < width; x++, pixels += channels) { if (fabsf(pixels[0] - 0.5f) < 1.0f / 255.0f) { pixels[0] = 0.5f + 1e-5f; @@ -233,7 +233,7 @@ static bool write_internal_bake_pixels(Image *image, RE_bake_mask_fill(pixel_array, pixels_num, mask_buffer); } - is_float = (ibuf->rect_float != nullptr); + is_float = (ibuf->float_buffer.data != nullptr); /* colormanagement conversions */ if (!is_noncolor) { @@ -262,7 +262,7 @@ static bool write_internal_bake_pixels(Image *image, /* populates the ImBuf */ if (is_clear) { if (is_float) { - IMB_buffer_float_from_float(ibuf->rect_float, + IMB_buffer_float_from_float(ibuf->float_buffer.data, buffer, ibuf->channels, IB_PROFILE_LINEAR_RGB, @@ -274,7 +274,7 @@ static bool write_internal_bake_pixels(Image *image, ibuf->x); } else { - IMB_buffer_byte_from_float((uchar *)ibuf->rect, + IMB_buffer_byte_from_float(ibuf->byte_buffer.data, buffer, ibuf->channels, ibuf->dither, @@ -289,7 +289,7 @@ static bool write_internal_bake_pixels(Image *image, } else { if (is_float) { - IMB_buffer_float_from_float_mask(ibuf->rect_float, + IMB_buffer_float_from_float_mask(ibuf->float_buffer.data, buffer, ibuf->channels, ibuf->x, @@ -299,7 +299,7 @@ static bool write_internal_bake_pixels(Image *image, mask_buffer); } else { - IMB_buffer_byte_from_float_mask((uchar *)ibuf->rect, + IMB_buffer_byte_from_float_mask(ibuf->byte_buffer.data, buffer, ibuf->channels, ibuf->dither, @@ -320,7 +320,7 @@ static bool write_internal_bake_pixels(Image *image, ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; BKE_image_mark_dirty(image, ibuf); - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { ibuf->userflags |= IB_RECT_INVALID; } @@ -382,7 +382,7 @@ static bool write_external_bake_pixels(const char *filepath, /* populates the ImBuf */ if (is_float) { - IMB_buffer_float_from_float(ibuf->rect_float, + IMB_buffer_float_from_float(ibuf->float_buffer.data, buffer, ibuf->channels, IB_PROFILE_LINEAR_RGB, @@ -406,7 +406,7 @@ static bool write_external_bake_pixels(const char *filepath, bias_tangent_normal_pixels(buffer, ibuf->channels, ibuf->x, ibuf->y, ibuf->x); } - IMB_buffer_byte_from_float((uchar *)ibuf->rect, + IMB_buffer_byte_from_float(ibuf->byte_buffer.data, buffer, ibuf->channels, ibuf->dither, diff --git a/source/blender/editors/object/object_vgroup.cc b/source/blender/editors/object/object_vgroup.cc index 576dd83cf61..dc6c5ca0886 100644 --- a/source/blender/editors/object/object_vgroup.cc +++ b/source/blender/editors/object/object_vgroup.cc @@ -2796,7 +2796,7 @@ static int vertex_group_copy_exec(bContext *C, wmOperator * /*op*/) void OBJECT_OT_vertex_group_copy(wmOperatorType *ot) { /* identifiers */ - ot->name = "Copy Vertex Group"; + ot->name = "Duplicate Vertex Group"; ot->idname = "OBJECT_OT_vertex_group_copy"; ot->description = "Make a copy of the active vertex group"; diff --git a/source/blender/editors/render/render_internal.cc b/source/blender/editors/render/render_internal.cc index 13f4f25b5ac..63f52dcaec4 100644 --- a/source/blender/editors/render/render_internal.cc +++ b/source/blender/editors/render/render_internal.cc @@ -234,7 +234,7 @@ static void image_buffer_rect_update(RenderJob *rj, linear_offset_y = offset_y; } else { - rectf = ibuf->rect_float; + rectf = ibuf->float_buffer.data; linear_stride = ibuf->x; linear_offset_x = 0; linear_offset_y = 0; diff --git a/source/blender/editors/render/render_opengl.cc b/source/blender/editors/render/render_opengl.cc index c4b31ab78ab..702a78deec5 100644 --- a/source/blender/editors/render/render_opengl.cc +++ b/source/blender/editors/render/render_opengl.cc @@ -301,7 +301,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R * TODO(sergey): In the case of output to float container (EXR) * it actually makes sense to keep float buffer instead. */ - if (ibuf_result->rect_float != nullptr) { + if (ibuf_result->float_buffer.data != nullptr) { IMB_rect_from_float(ibuf_result); imb_freerectfloatImBuf(ibuf_result); } @@ -315,7 +315,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R if (gpd) { int i; uchar *gp_rect; - uchar *render_rect = (uchar *)ibuf_result->rect; + uchar *render_rect = ibuf_result->byte_buffer.data; DRW_opengl_context_enable(); GPU_offscreen_bind(oglrender->ofs, true); @@ -404,11 +404,11 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R if ((scene->r.stamp & R_STAMP_ALL) && (scene->r.stamp & R_STAMP_DRAW)) { float *rectf = nullptr; uchar *rect = nullptr; - if (ibuf_result->rect_float) { - rectf = ibuf_result->rect_float; + if (ibuf_result->float_buffer.data) { + rectf = ibuf_result->float_buffer.data; } else { - rect = (uchar *)ibuf_result->rect; + rect = ibuf_result->byte_buffer.data; } BKE_image_stamp_buf(scene, camera, nullptr, rect, rectf, rr->rectx, rr->recty, 4); } diff --git a/source/blender/editors/render/render_preview.cc b/source/blender/editors/render/render_preview.cc index 092fa0d0d00..db1baf20804 100644 --- a/source/blender/editors/render/render_preview.cc +++ b/source/blender/editors/render/render_preview.cc @@ -1352,7 +1352,8 @@ static void icon_copy_rect(ImBuf *ibuf, uint w, uint h, uint *rect) short ex, ey, dx, dy; /* paranoia test */ - if (ibuf == nullptr || (ibuf->rect == nullptr && ibuf->rect_float == nullptr)) { + if (ibuf == nullptr || (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data == nullptr)) + { return; } @@ -1382,11 +1383,11 @@ static void icon_copy_rect(ImBuf *ibuf, uint w, uint h, uint *rect) IMB_scalefastImBuf(ima, ex, ey); /* if needed, convert to 32 bits */ - if (ima->rect == nullptr) { + if (ima->byte_buffer.data == nullptr) { IMB_rect_from_float(ima); } - srect = ima->rect; + srect = reinterpret_cast(ima->byte_buffer.data); drect = rect; drect += dy * w + dx; @@ -1440,7 +1441,8 @@ static void icon_preview_startjob(void *customdata, bool *stop, bool *do_update) * already there. Very expensive for large images. Need to find a way to * only get existing `ibuf`. */ ibuf = BKE_image_acquire_ibuf(ima, &iuser, nullptr); - if (ibuf == nullptr || (ibuf->rect == nullptr && ibuf->rect_float == nullptr)) { + if (ibuf == nullptr || + (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data == nullptr)) { BKE_image_release_ibuf(ima, ibuf, nullptr); return; } @@ -1458,7 +1460,7 @@ static void icon_preview_startjob(void *customdata, bool *stop, bool *do_update) memset(sp->pr_rect, 0x88, sp->sizex * sp->sizey * sizeof(uint)); - if (!(br->icon_imbuf) || !(br->icon_imbuf->rect)) { + if (!(br->icon_imbuf) || !(br->icon_imbuf->byte_buffer.data)) { return; } diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index c91bee21295..186d81cf068 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -430,7 +430,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf, bool need_fallback = true; /* Early out */ - if (ibuf->rect == NULL && ibuf->rect_float == NULL) { + if (ibuf->byte_buffer.data == NULL && ibuf->float_buffer.data == NULL) { return; } @@ -449,7 +449,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf, state.do_shader_unbind = false; immDrawPixelsTexSetupAttributes(&state); - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { if (ibuf->float_colorspace) { ok = IMB_colormanagement_setup_glsl_draw_from_space( view_settings, display_settings, ibuf->float_colorspace, ibuf->dither, true, false); @@ -465,7 +465,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf, } if (ok) { - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { eGPUTextureFormat format = 0; if (ibuf->channels == 3) { @@ -486,7 +486,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf, ibuf->y, format, use_filter, - ibuf->rect_float, + ibuf->float_buffer.data, clip_min_x, clip_min_y, clip_max_x, @@ -496,7 +496,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf, NULL); } } - else if (ibuf->rect) { + else if (ibuf->byte_buffer.data) { /* ibuf->rect is always RGBA */ immDrawPixelsTexTiled_clipping(&state, x, @@ -505,7 +505,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf, ibuf->y, GPU_RGBA8, use_filter, - ibuf->rect, + ibuf->byte_buffer.data, clip_min_x, clip_min_y, clip_max_x, @@ -618,7 +618,7 @@ int ED_draw_imbuf_method(ImBuf *ibuf) /* Use faster GLSL when CPU to GPU transfer is unlikely to be a bottleneck, * otherwise do color management on CPU side. */ const size_t threshold = sizeof(float[4]) * 2048 * 2048; - const size_t data_size = (ibuf->rect_float) ? sizeof(float) : sizeof(uchar); + const size_t data_size = (ibuf->float_buffer.data) ? sizeof(float) : sizeof(uchar); const size_t size = ibuf->x * ibuf->y * ibuf->channels * data_size; return (size > threshold) ? IMAGE_DRAW_METHOD_2DTEXTURE : IMAGE_DRAW_METHOD_GLSL; diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 49aeb74451b..aa06a239e11 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -4498,6 +4498,11 @@ static bool match_region_with_redraws(const ScrArea *area, return true; } break; + case SPACE_SPREADSHEET: + if ((redraws & TIME_SPREADSHEETS)) { + return true; + } + break; default: break; } diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c index 892959698c4..51d06098178 100644 --- a/source/blender/editors/screen/screendump.c +++ b/source/blender/editors/screen/screendump.c @@ -43,7 +43,7 @@ #include "screen_intern.h" typedef struct ScreenshotData { - uint *dumprect; + uint8_t *dumprect; int dumpsx, dumpsy; rcti crop; bool use_crop; @@ -61,7 +61,7 @@ static int screenshot_data_create(bContext *C, wmOperator *op, ScrArea *area) /* do redraw so we don't show popups/menus */ WM_redraw_windows(C); - uint *dumprect = WM_window_pixels_read(C, win, dumprect_size); + uint8_t *dumprect = WM_window_pixels_read(C, win, dumprect_size); if (dumprect) { ScreenshotData *scd = MEM_callocN(sizeof(ScreenshotData), "screenshot"); @@ -118,12 +118,12 @@ static int screenshot_exec(bContext *C, wmOperator *op) /* operator ensures the extension */ ibuf = IMB_allocImBuf(scd->dumpsx, scd->dumpsy, 24, 0); - ibuf->rect = scd->dumprect; + IMB_assign_byte_buffer(ibuf, scd->dumprect, IB_DO_NOT_TAKE_OWNERSHIP); /* crop to show only single editor */ if (use_crop) { IMB_rect_crop(ibuf, &scd->crop); - scd->dumprect = ibuf->rect; + scd->dumprect = ibuf->byte_buffer.data; } if ((scd->im_format.planes == R_IMF_PLANES_BW) && diff --git a/source/blender/editors/sculpt_paint/paint_cursor.cc b/source/blender/editors/sculpt_paint/paint_cursor.cc index 7ad41d07f98..da7d0259ab2 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.cc +++ b/source/blender/editors/sculpt_paint/paint_cursor.cc @@ -164,7 +164,7 @@ static void load_tex_task_cb_ex(void *__restrict userdata, if (mtex->tex && mtex->tex->type == TEX_IMAGE && mtex->tex->ima) { ImBuf *tex_ibuf = BKE_image_pool_acquire_ibuf(mtex->tex->ima, &mtex->tex->iuser, pool); /* For consistency, sampling always returns color in linear space. */ - if (tex_ibuf && tex_ibuf->rect_float == nullptr) { + if (tex_ibuf && tex_ibuf->float_buffer.data == nullptr) { convert_to_linear = true; colorspace = tex_ibuf->rect_colorspace; } diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.cc b/source/blender/editors/sculpt_paint/paint_image_2d.cc index b3153a6c4a9..eb79a564226 100644 --- a/source/blender/editors/sculpt_paint/paint_image_2d.cc +++ b/source/blender/editors/sculpt_paint/paint_image_2d.cc @@ -262,7 +262,7 @@ static void brush_painter_mask_imbuf_update(BrushPainter *painter, if (!use_texture_old) { brush_imbuf_tex_co(&tex_mapping, x, y, texco); - res = (ushort)(65535.0f * BKE_brush_sample_masktex(scene, brush, texco, thread, pool)); + res = ushort(65535.0f * BKE_brush_sample_masktex(scene, brush, texco, thread, pool)); } /* read from old texture buffer */ @@ -419,13 +419,13 @@ static ImBuf *brush_painter_imbuf_new( if (use_float) { /* write to float pixel */ - float *dstf = ibuf->rect_float + (y * size + x) * 4; + float *dstf = ibuf->float_buffer.data + (y * size + x) * 4; mul_v3_v3fl(dstf, rgba, rgba[3]); /* premultiply */ dstf[3] = rgba[3]; } else { /* write to byte pixel */ - uchar *dst = (uchar *)ibuf->rect + (y * size + x) * 4; + uchar *dst = ibuf->byte_buffer.data + (y * size + x) * 4; rgb_float_to_uchar(dst, rgba); dst[3] = unit_float_to_uchar_clamp(rgba[3]); @@ -504,12 +504,12 @@ static void brush_painter_imbuf_update(BrushPainter *painter, if (use_float) { /* handle float pixel */ - float *bf = ibuf->rect_float + (y * ibuf->x + x) * 4; - float *tf = texibuf->rect_float + (y * texibuf->x + x) * 4; + float *bf = ibuf->float_buffer.data + (y * ibuf->x + x) * 4; + float *tf = texibuf->float_buffer.data + (y * texibuf->x + x) * 4; /* read from old texture buffer */ if (use_texture_old) { - const float *otf = oldtexibuf->rect_float + + const float *otf = oldtexibuf->float_buffer.data + ((y - origy + yt) * oldtexibuf->x + (x - origx + xt)) * 4; copy_v4_v4(rgba, otf); } @@ -525,12 +525,12 @@ static void brush_painter_imbuf_update(BrushPainter *painter, uchar crgba[4]; /* handle byte pixel */ - uchar *b = (uchar *)ibuf->rect + (y * ibuf->x + x) * 4; - uchar *t = (uchar *)texibuf->rect + (y * texibuf->x + x) * 4; + uchar *b = ibuf->byte_buffer.data + (y * ibuf->x + x) * 4; + uchar *t = texibuf->byte_buffer.data + (y * texibuf->x + x) * 4; /* read from old texture buffer */ if (use_texture_old) { - uchar *ot = (uchar *)oldtexibuf->rect + + uchar *ot = oldtexibuf->byte_buffer.data + ((y - origy + yt) * oldtexibuf->x + (x - origx + xt)) * 4; crgba[0] = ot[0]; crgba[1] = ot[1]; @@ -820,8 +820,8 @@ static bool paint_2d_ensure_tile_canvas(ImagePaintState *s, int i) if (ibuf->channels != 4) { s->tiles[i].state = PAINT2D_TILE_MISSING; } - else if ((s->tiles[0].canvas->rect && !ibuf->rect) || - (s->tiles[0].canvas->rect_float && !ibuf->rect_float)) + else if ((s->tiles[0].canvas->byte_buffer.data && !ibuf->byte_buffer.data) || + (s->tiles[0].canvas->float_buffer.data && !ibuf->float_buffer.data)) { s->tiles[i].state = PAINT2D_TILE_MISSING; } @@ -849,12 +849,12 @@ static bool paint_2d_ensure_tile_canvas(ImagePaintState *s, int i) /* keep these functions in sync */ static void paint_2d_ibuf_rgb_get(ImBuf *ibuf, int x, int y, float r_rgb[4]) { - if (ibuf->rect_float) { - const float *rrgbf = ibuf->rect_float + (ibuf->x * y + x) * 4; + if (ibuf->float_buffer.data) { + const float *rrgbf = ibuf->float_buffer.data + (ibuf->x * y + x) * 4; copy_v4_v4(r_rgb, rrgbf); } else { - uchar *rrgb = (uchar *)ibuf->rect + (ibuf->x * y + x) * 4; + uchar *rrgb = ibuf->byte_buffer.data + (ibuf->x * y + x) * 4; straight_uchar_to_premul_float(r_rgb, rrgb); } } @@ -872,8 +872,8 @@ static void paint_2d_ibuf_rgb_set( } } - if (ibuf->rect_float) { - float *rrgbf = ibuf->rect_float + (ibuf->x * y + x) * 4; + if (ibuf->float_buffer.data) { + float *rrgbf = ibuf->float_buffer.data + (ibuf->x * y + x) * 4; float map_alpha = (rgb[3] == 0.0f) ? rrgbf[3] : rrgbf[3] / rgb[3]; mul_v3_v3fl(rrgbf, rgb, map_alpha); @@ -881,7 +881,7 @@ static void paint_2d_ibuf_rgb_set( } else { uchar straight[4]; - uchar *rrgb = (uchar *)ibuf->rect + (ibuf->x * y + x) * 4; + uchar *rrgb = ibuf->byte_buffer.data + (ibuf->x * y + x) * 4; premul_float_to_straight_uchar(straight, rgb); rrgb[0] = straight[0]; @@ -1212,13 +1212,19 @@ static void paint_2d_do_making_brush(ImagePaintState *s, int origx = region->destx - tx * ED_IMAGE_UNDO_TILE_SIZE; int origy = region->desty - ty * ED_IMAGE_UNDO_TILE_SIZE; - if (tile->canvas->rect_float) { - tmpbuf.rect_float = static_cast(ED_image_paint_tile_find( - undo_tiles, s->image, tile->canvas, &tile->iuser, tx, ty, &mask, false)); + if (tile->canvas->float_buffer.data) { + IMB_assign_float_buffer( + &tmpbuf, + static_cast(ED_image_paint_tile_find( + undo_tiles, s->image, tile->canvas, &tile->iuser, tx, ty, &mask, false)), + IB_DO_NOT_TAKE_OWNERSHIP); } else { - tmpbuf.rect = static_cast(ED_image_paint_tile_find( - undo_tiles, s->image, tile->canvas, &tile->iuser, tx, ty, &mask, false)); + IMB_assign_byte_buffer( + &tmpbuf, + static_cast(ED_image_paint_tile_find( + undo_tiles, s->image, tile->canvas, &tile->iuser, tx, ty, &mask, false)), + IB_DO_NOT_TAKE_OWNERSHIP); } IMB_rectblend(tile->canvas, @@ -1404,7 +1410,7 @@ static int paint_2d_canvas_set(ImagePaintState *s) Image *ima = s->brush->clone.image; ImBuf *ibuf = BKE_image_acquire_ibuf(ima, nullptr, nullptr); - if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) { + if (!ima || !ibuf || !(ibuf->byte_buffer.data || ibuf->float_buffer.data)) { BKE_image_release_ibuf(ima, ibuf, nullptr); return 0; } @@ -1412,10 +1418,10 @@ static int paint_2d_canvas_set(ImagePaintState *s) s->clonecanvas = ibuf; /* temporarily add float rect for cloning */ - if (s->tiles[0].canvas->rect_float && !s->clonecanvas->rect_float) { + if (s->tiles[0].canvas->float_buffer.data && !s->clonecanvas->float_buffer.data) { IMB_float_from_rect(s->clonecanvas); } - else if (!s->tiles[0].canvas->rect_float && !s->clonecanvas->rect) { + else if (!s->tiles[0].canvas->float_buffer.data && !s->clonecanvas->byte_buffer.data) { IMB_rect_from_float(s->clonecanvas); } } @@ -1535,8 +1541,11 @@ void paint_2d_stroke(void *ps, /* OCIO_TODO: float buffers are now always linear, so always use color correction * this should probably be changed when texture painting color space is supported */ - brush_painter_2d_require_imbuf( - painter->brush, tile, (ibuf->rect_float != nullptr), !is_data, painter->cache_invert); + brush_painter_2d_require_imbuf(painter->brush, + tile, + (ibuf->float_buffer.data != nullptr), + !is_data, + painter->cache_invert); brush_painter_2d_refresh_cache(s, painter, tile, new_coord, mval, pressure, distance, size); @@ -1706,11 +1715,11 @@ static void paint_2d_fill_add_pixel_byte(const int x_px, return; } - coordinate = ((size_t)y_px) * ibuf->x + x_px; + coordinate = size_t(y_px) * ibuf->x + x_px; if (!BLI_BITMAP_TEST(touched, coordinate)) { float color_f[4]; - uchar *color_b = (uchar *)(ibuf->rect + coordinate); + uchar *color_b = ibuf->byte_buffer.data + 4 * coordinate; rgba_uchar_to_float(color_f, color_b); straight_to_premul_v4(color_f); @@ -1735,10 +1744,10 @@ static void paint_2d_fill_add_pixel_float(const int x_px, return; } - coordinate = ((size_t)y_px) * ibuf->x + x_px; + coordinate = size_t(y_px) * ibuf->x + x_px; if (!BLI_BITMAP_TEST(touched, coordinate)) { - if (len_squared_v4v4(ibuf->rect_float + 4 * coordinate, color) <= threshold_sq) { + if (len_squared_v4v4(ibuf->float_buffer.data + 4 * coordinate, color) <= threshold_sq) { BLI_stack_push(stack, &coordinate); } BLI_BITMAP_SET(touched, coordinate, true); @@ -1810,7 +1819,7 @@ void paint_2d_bucket_fill(const bContext *C, return; } - do_float = (ibuf->rect_float != nullptr); + do_float = (ibuf->float_buffer.data != nullptr); /* first check if our image is float. If it is not we should correct the color to * be in gamma space. strictly speaking this is not correct, but blender does not paint * byte images in linear space */ @@ -1830,8 +1839,8 @@ void paint_2d_bucket_fill(const bContext *C, if (do_float) { for (x_px = 0; x_px < ibuf->x; x_px++) { for (y_px = 0; y_px < ibuf->y; y_px++) { - blend_color_mix_float(ibuf->rect_float + 4 * (((size_t)y_px) * ibuf->x + x_px), - ibuf->rect_float + 4 * (((size_t)y_px) * ibuf->x + x_px), + blend_color_mix_float(ibuf->float_buffer.data + 4 * (size_t(y_px) * ibuf->x + x_px), + ibuf->float_buffer.data + 4 * (size_t(y_px) * ibuf->x + x_px), color_f); } } @@ -1839,8 +1848,8 @@ void paint_2d_bucket_fill(const bContext *C, else { for (x_px = 0; x_px < ibuf->x; x_px++) { for (y_px = 0; y_px < ibuf->y; y_px++) { - blend_color_mix_byte((uchar *)(ibuf->rect + ((size_t)y_px) * ibuf->x + x_px), - (uchar *)(ibuf->rect + ((size_t)y_px) * ibuf->x + x_px), + blend_color_mix_byte(ibuf->byte_buffer.data + 4 * (size_t(y_px) * ibuf->x + x_px), + ibuf->byte_buffer.data + 4 * (size_t(y_px) * ibuf->x + x_px), (uchar *)&color_b); } } @@ -1871,15 +1880,15 @@ void paint_2d_bucket_fill(const bContext *C, ED_imapaint_dirty_region(ima, ibuf, iuser, 0, 0, ibuf->x, ibuf->y, false); stack = BLI_stack_new(sizeof(size_t), __func__); - touched = BLI_BITMAP_NEW(((size_t)ibuf->x) * ibuf->y, "bucket_fill_bitmap"); + touched = BLI_BITMAP_NEW(size_t(ibuf->x) * ibuf->y, "bucket_fill_bitmap"); - coordinate = (((size_t)y_px) * ibuf->x + x_px); + coordinate = (size_t(y_px) * ibuf->x + x_px); if (do_float) { - copy_v4_v4(pixel_color, ibuf->rect_float + 4 * coordinate); + copy_v4_v4(pixel_color, ibuf->float_buffer.data + 4 * coordinate); } else { - int pixel_color_b = *(ibuf->rect + coordinate); + int pixel_color_b = *ibuf->byte_buffer.data + 4 * coordinate; rgba_uchar_to_float(pixel_color, (uchar *)&pixel_color_b); straight_to_premul_v4(pixel_color); } @@ -1891,8 +1900,8 @@ void paint_2d_bucket_fill(const bContext *C, while (!BLI_stack_is_empty(stack)) { BLI_stack_pop(stack, &coordinate); - IMB_blend_color_float(ibuf->rect_float + 4 * (coordinate), - ibuf->rect_float + 4 * (coordinate), + IMB_blend_color_float(ibuf->float_buffer.data + 4 * (coordinate), + ibuf->float_buffer.data + 4 * (coordinate), color_f, IMB_BlendMode(br->blend)); @@ -1935,8 +1944,8 @@ void paint_2d_bucket_fill(const bContext *C, while (!BLI_stack_is_empty(stack)) { BLI_stack_pop(stack, &coordinate); - IMB_blend_color_byte((uchar *)(ibuf->rect + coordinate), - (uchar *)(ibuf->rect + coordinate), + IMB_blend_color_byte(ibuf->byte_buffer.data + 4 * coordinate, + ibuf->byte_buffer.data + 4 * coordinate, (uchar *)&color_b, IMB_BlendMode(br->blend)); @@ -2039,7 +2048,7 @@ void paint_2d_gradient_fill( line_len_sq_inv = 1.0f / line_len; line_len = sqrtf(line_len); - do_float = (ibuf->rect_float != nullptr); + do_float = (ibuf->float_buffer.data != nullptr); /* this will be substituted by something else when selection is available */ ED_imapaint_dirty_region(ima, ibuf, iuser, 0, 0, ibuf->x, ibuf->y, false); @@ -2065,8 +2074,8 @@ void paint_2d_gradient_fill( /* convert to premultiplied */ mul_v3_fl(color_f, color_f[3]); color_f[3] *= brush_alpha; - IMB_blend_color_float(ibuf->rect_float + 4 * (((size_t)y_px) * ibuf->x + x_px), - ibuf->rect_float + 4 * (((size_t)y_px) * ibuf->x + x_px), + IMB_blend_color_float(ibuf->float_buffer.data + 4 * (size_t(y_px) * ibuf->x + x_px), + ibuf->float_buffer.data + 4 * (size_t(y_px) * ibuf->x + x_px), color_f, IMB_BlendMode(br->blend)); } @@ -2094,8 +2103,8 @@ void paint_2d_gradient_fill( linearrgb_to_srgb_v3_v3(color_f, color_f); rgba_float_to_uchar((uchar *)&color_b, color_f); ((uchar *)&color_b)[3] *= brush_alpha; - IMB_blend_color_byte((uchar *)(ibuf->rect + ((size_t)y_px) * ibuf->x + x_px), - (uchar *)(ibuf->rect + ((size_t)y_px) * ibuf->x + x_px), + IMB_blend_color_byte(ibuf->byte_buffer.data + 4 * (size_t(y_px) * ibuf->x + x_px), + ibuf->byte_buffer.data + 4 * (size_t(y_px) * ibuf->x + x_px), (uchar *)&color_b, IMB_BlendMode(br->blend)); } diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.cc b/source/blender/editors/sculpt_paint/paint_image_proj.cc index 1ad9652bd84..b9b6f34dcb1 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.cc +++ b/source/blender/editors/sculpt_paint/paint_image_proj.cc @@ -761,7 +761,7 @@ static bool project_paint_PickColor( float x, y; uvco_to_wrapped_pxco(uv, ibuf->x, ibuf->y, &x, &y); - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { if (rgba_fp) { bilinear_interpolation_color_wrap(ibuf, nullptr, rgba_fp, x, y); } @@ -792,21 +792,21 @@ static bool project_paint_PickColor( yi = mod_i(int(uv[1] * ibuf->y), ibuf->y); if (rgba) { - if (ibuf->rect_float) { - const float *rgba_tmp_fp = ibuf->rect_float + (xi + yi * ibuf->x * 4); + if (ibuf->float_buffer.data) { + const float *rgba_tmp_fp = ibuf->float_buffer.data + (xi + yi * ibuf->x * 4); premul_float_to_straight_uchar(rgba, rgba_tmp_fp); } else { - *((uint *)rgba) = *(uint *)(((char *)ibuf->rect) + ((xi + yi * ibuf->x) * 4)); + *((uint *)rgba) = *(uint *)(((char *)ibuf->byte_buffer.data) + ((xi + yi * ibuf->x) * 4)); } } if (rgba_fp) { - if (ibuf->rect_float) { - copy_v4_v4(rgba_fp, (ibuf->rect_float + ((xi + yi * ibuf->x) * 4))); + if (ibuf->float_buffer.data) { + copy_v4_v4(rgba_fp, (ibuf->float_buffer.data + ((xi + yi * ibuf->x) * 4))); } else { - uchar *tmp_ch = ((uchar *)ibuf->rect) + ((xi + yi * ibuf->x) * 4); + uchar *tmp_ch = ibuf->byte_buffer.data + ((xi + yi * ibuf->x) * 4); straight_uchar_to_premul_float(rgba_fp, tmp_ch); } } @@ -1653,7 +1653,7 @@ static void project_face_pixel(const float *lt_tri_uv[3], /* use */ uvco_to_wrapped_pxco(uv_other, ibuf_other->x, ibuf_other->y, &x, &y); - if (ibuf_other->rect_float) { /* from float to float */ + if (ibuf_other->float_buffer.data) { /* from float to float */ bilinear_interpolation_color_wrap(ibuf_other, nullptr, rgba_f, x, y); } else { /* from char to float */ @@ -1686,7 +1686,7 @@ static float project_paint_uvpixel_mask(const ProjPaintState *ps, project_face_pixel(lt_other_tri_uv, ibuf_other, w, rgba_ub, rgba_f); - if (ibuf_other->rect_float) { /* from float to float */ + if (ibuf_other->float_buffer.data) { /* from float to float */ mask = ((rgba_f[0] + rgba_f[1] + rgba_f[2]) * (1.0f / 3.0f)) * rgba_f[3]; } else { /* from char to float */ @@ -1928,13 +1928,13 @@ static ProjPixel *project_paint_uvpixel_init(const ProjPaintState *ps, projPixel->valid = projima->valid[tile_index]; - if (ibuf->rect_float) { - projPixel->pixel.f_pt = ibuf->rect_float + ((x_px + y_px * ibuf->x) * 4); + if (ibuf->float_buffer.data) { + projPixel->pixel.f_pt = ibuf->float_buffer.data + ((x_px + y_px * ibuf->x) * 4); projPixel->origColor.f_pt = (float *)projima->undoRect[tile_index] + 4 * tile_offset; zero_v4(projPixel->newColor.f); } else { - projPixel->pixel.ch_pt = (uchar *)(ibuf->rect + (x_px + y_px * ibuf->x)); + projPixel->pixel.ch_pt = ibuf->byte_buffer.data + (x_px + y_px * ibuf->x) * 4; projPixel->origColor.uint_pt = (uint *)projima->undoRect[tile_index] + tile_offset; projPixel->newColor.uint_ = 0; } @@ -1976,8 +1976,8 @@ static ProjPixel *project_paint_uvpixel_init(const ProjPaintState *ps, /* #BKE_image_acquire_ibuf - TODO: this may be slow. */ - if (ibuf->rect_float) { - if (ibuf_other->rect_float) { /* from float to float */ + if (ibuf->float_buffer.data) { + if (ibuf_other->float_buffer.data) { /* from float to float */ project_face_pixel( lt_other_tri_uv, ibuf_other, w, nullptr, ((ProjPixelClone *)projPixel)->clonepx.f); } @@ -1995,7 +1995,7 @@ static ProjPixel *project_paint_uvpixel_init(const ProjPaintState *ps, } } else { - if (ibuf_other->rect_float) { /* float to char */ + if (ibuf_other->float_buffer.data) { /* float to char */ float rgba[4]; project_face_pixel(lt_other_tri_uv, ibuf_other, w, nullptr, rgba); premul_to_straight_v4(rgba); @@ -2019,7 +2019,7 @@ static ProjPixel *project_paint_uvpixel_init(const ProjPaintState *ps, BKE_image_release_ibuf(other_tpage, ibuf_other, nullptr); } else { - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { ((ProjPixelClone *)projPixel)->clonepx.f[3] = 0; } else { @@ -2033,7 +2033,7 @@ static ProjPixel *project_paint_uvpixel_init(const ProjPaintState *ps, /* no need to initialize the bucket, we're only checking buckets faces and for this * the faces are already initialized in project_paint_delayed_face_init(...) */ - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { if (!project_paint_PickColor( ps, co, ((ProjPixelClone *)projPixel)->clonepx.f, nullptr, true)) { /* zero alpha - ignore */ @@ -2051,7 +2051,7 @@ static ProjPixel *project_paint_uvpixel_init(const ProjPaintState *ps, } #ifdef PROJ_DEBUG_PAINT - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { projPixel->pixel.f_pt[0] = 0; } else { @@ -5302,7 +5302,7 @@ static void do_projectpaint_thread(TaskPool *__restrict /*pool*/, void *ph_v) last_projIma = projImages + last_index; last_projIma->touch = true; - is_floatbuf = (last_projIma->ibuf->rect_float != nullptr); + is_floatbuf = (last_projIma->ibuf->float_buffer.data != nullptr); } /* end copy */ @@ -5395,7 +5395,7 @@ static void do_projectpaint_thread(TaskPool *__restrict /*pool*/, void *ph_v) } else { if (is_floatbuf) { - BLI_assert(ps->reproject_ibuf->rect_float != nullptr); + BLI_assert(ps->reproject_ibuf->float_buffer.data != nullptr); bicubic_interpolation_color(ps->reproject_ibuf, nullptr, @@ -5412,7 +5412,7 @@ static void do_projectpaint_thread(TaskPool *__restrict /*pool*/, void *ph_v) } } else { - BLI_assert(ps->reproject_ibuf->rect != nullptr); + BLI_assert(ps->reproject_ibuf->byte_buffer.data != nullptr); bicubic_interpolation_color(ps->reproject_ibuf, projPixel->newColor.ch, @@ -5529,7 +5529,7 @@ static void do_projectpaint_thread(TaskPool *__restrict /*pool*/, void *ph_v) last_projIma = projImages + last_index; last_projIma->touch = true; - is_floatbuf = (last_projIma->ibuf->rect_float != nullptr); + is_floatbuf = (last_projIma->ibuf->float_buffer.data != nullptr); } /* end copy */ @@ -5669,20 +5669,20 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po bool uchar_dest = false; /* Check if the destination images are float or uchar. */ for (i = 0; i < ps->image_tot; i++) { - if (ps->projImages[i].ibuf->rect != nullptr) { + if (ps->projImages[i].ibuf->byte_buffer.data != nullptr) { uchar_dest = true; } - if (ps->projImages[i].ibuf->rect_float != nullptr) { + if (ps->projImages[i].ibuf->float_buffer.data != nullptr) { float_dest = true; } } /* Generate missing data if needed. */ - if (float_dest && ps->reproject_ibuf->rect_float == nullptr) { + if (float_dest && ps->reproject_ibuf->float_buffer.data == nullptr) { IMB_float_from_rect(ps->reproject_ibuf); ps->reproject_ibuf_free_float = true; } - if (uchar_dest && ps->reproject_ibuf->rect == nullptr) { + if (uchar_dest && ps->reproject_ibuf->byte_buffer.data == nullptr) { IMB_rect_from_float(ps->reproject_ibuf); ps->reproject_ibuf_free_uchar = true; } @@ -6163,7 +6163,7 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op) ps.reproject_ibuf = BKE_image_acquire_ibuf(image, nullptr, nullptr); if ((ps.reproject_ibuf == nullptr) || - ((ps.reproject_ibuf->rect || ps.reproject_ibuf->rect_float) == false)) + ((ps.reproject_ibuf->byte_buffer.data || ps.reproject_ibuf->float_buffer.data) == false)) { BKE_report(op->reports, RPT_ERROR, "Image data could not be found"); return OPERATOR_CANCELLED; diff --git a/source/blender/editors/sculpt_paint/paint_ops.cc b/source/blender/editors/sculpt_paint/paint_ops.cc index ebabff27b47..88515e4b231 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.cc +++ b/source/blender/editors/sculpt_paint/paint_ops.cc @@ -472,7 +472,7 @@ static int palette_extract_img_exec(bContext *C, wmOperator *op) ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock); - if (ibuf && ibuf->rect) { + if (ibuf && ibuf->byte_buffer.data) { /* Extract all colors. */ const int range = int(pow(10.0f, threshold)); for (int row = 0; row < ibuf->y; row++) { diff --git a/source/blender/editors/sculpt_paint/paint_stroke.cc b/source/blender/editors/sculpt_paint/paint_stroke.cc index 8864471e3d9..a71f6d93175 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.cc +++ b/source/blender/editors/sculpt_paint/paint_stroke.cc @@ -324,7 +324,7 @@ static bool paint_brush_update(bContext *C, if (brush->mtex.tex && brush->mtex.tex->type == TEX_IMAGE && brush->mtex.tex->ima) { ImBuf *tex_ibuf = BKE_image_pool_acquire_ibuf( brush->mtex.tex->ima, &brush->mtex.tex->iuser, nullptr); - if (tex_ibuf && tex_ibuf->rect_float == nullptr) { + if (tex_ibuf && tex_ibuf->float_buffer.data == nullptr) { ups->do_linear_conversion = true; ups->colorspace = tex_ibuf->rect_colorspace; } diff --git a/source/blender/editors/sculpt_paint/paint_utils.cc b/source/blender/editors/sculpt_paint/paint_utils.cc index 4791a8e7c1e..ba021a27f01 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.cc +++ b/source/blender/editors/sculpt_paint/paint_utils.cc @@ -235,8 +235,8 @@ static void imapaint_tri_weights(float matrix[4][4], h[1] = (co[1] - view[1]) * 2.0f / view[3] - 1.0f; h[2] = 1.0f; - /* solve for (w1,w2,w3)/perspdiv in: - * h * perspdiv = Project * Model * (w1 * v1 + w2 * v2 + w3 * v3) */ + /* Solve for `(w1,w2,w3)/perspdiv` in: + * `h * perspdiv = Project * Model * (w1 * v1 + w2 * v2 + w3 * v3)`. */ wmat[0][0] = pv1[0]; wmat[1][0] = pv2[0]; @@ -253,7 +253,7 @@ static void imapaint_tri_weights(float matrix[4][4], copy_v3_v3(w, h); - /* w is still divided by perspdiv, make it sum to one */ + /* w is still divided by `perspdiv`, make it sum to one */ divw = w[0] + w[1] + w[2]; if (divw != 0.0f) { mul_v3_fl(w, 1.0f / divw); @@ -358,7 +358,7 @@ static int imapaint_pick_face(ViewContext *vc, const int mval[2], uint *r_index, ED_view3d_select_id_validate(vc); *r_index = DRW_select_buffer_sample_point(vc->depsgraph, vc->region, vc->v3d, mval); - if ((*r_index) == 0 || (*r_index) > (uint)totpoly) { + if ((*r_index) == 0 || (*r_index) > uint(totpoly)) { return 0; } @@ -472,11 +472,11 @@ void paint_sample_color( } ImBuf *ibuf = BKE_image_acquire_ibuf(image, &iuser, nullptr); - if (ibuf && (ibuf->rect || ibuf->rect_float)) { + if (ibuf && (ibuf->byte_buffer.data || ibuf->float_buffer.data)) { u = u * ibuf->x; v = v * ibuf->y; - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { float rgba_f[4]; if (interp == SHD_INTERP_CLOSEST) { nearest_interpolation_color_wrap(ibuf, nullptr, rgba_f, u, v); diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.cc b/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.cc index 7b059e447d6..05b925a98d4 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.cc +++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.cc @@ -58,7 +58,7 @@ bool ED_wpaint_ensure_data(bContext *C, return false; } - /* if nothing was added yet, we make dverts and a vertex deform group */ + /* If nothing was added yet, we make deform-verts and a vertex deform group. */ if (BKE_mesh_deform_verts(me) == nullptr) { BKE_object_defgroup_data_create(&me->id); WM_event_add_notifier(C, NC_GEOM | ND_DATA, me); @@ -136,8 +136,7 @@ int ED_wpaint_mirror_vgroup_ensure(Object *ob, const int vgroup_active) } } - /* curdef should never be nullptr unless this is - * a light and BKE_object_defgroup_add_name fails */ + /* `mirrdef` shouldn't be -1 unless the object is a light & #BKE_object_defgroup_new fails. */ return mirrdef; } diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.cc b/source/blender/editors/sculpt_paint/sculpt_face_set.cc index 430ad30258a..566e7e57386 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.cc +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.cc @@ -705,7 +705,7 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op) } case SCULPT_FACE_SETS_FROM_BEVEL_WEIGHT: { const float *bevel_weights = static_cast( - CustomData_get_layer(&mesh->edata, CD_BWEIGHT)); + CustomData_get_layer_named(&mesh->edata, CD_PROP_FLOAT, "bevel_weight_edge")); sculpt_face_sets_init_flood_fill( ob, [&](const int /*from_face*/, const int edge, const int /*to_face*/) -> bool { return bevel_weights ? bevel_weights[edge] < threshold : true; diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc index 782b17ccca9..2358178f6ae 100644 --- a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc +++ b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc @@ -73,12 +73,12 @@ class ImageBufferFloat4 { float4 read_pixel(ImBuf *image_buffer) const { - return &image_buffer->rect_float[pixel_offset * 4]; + return &image_buffer->float_buffer.data[pixel_offset * 4]; } void write_pixel(ImBuf *image_buffer, const float4 pixel_data) const { - copy_v4_v4(&image_buffer->rect_float[pixel_offset * 4], pixel_data); + copy_v4_v4(&image_buffer->float_buffer.data[pixel_offset * 4], pixel_data); } const char *get_colorspace_name(ImBuf *image_buffer) @@ -107,15 +107,16 @@ class ImageBufferByte4 { { float4 result; rgba_uchar_to_float(result, - static_cast( - static_cast(&(image_buffer->rect[pixel_offset])))); + static_cast(static_cast( + &(image_buffer->byte_buffer.data[4 * pixel_offset])))); return result; } void write_pixel(ImBuf *image_buffer, const float4 pixel_data) const { - rgba_float_to_uchar( - static_cast(static_cast(&image_buffer->rect[pixel_offset])), pixel_data); + rgba_float_to_uchar(static_cast(static_cast( + &image_buffer->byte_buffer.data[4 * pixel_offset])), + pixel_data); } const char *get_colorspace_name(ImBuf *image_buffer) @@ -381,7 +382,7 @@ static void do_paint_pixels(void *__restrict userdata, continue; } - if (image_buffer->rect_float != nullptr) { + if (image_buffer->float_buffer.data != nullptr) { kernel_float4.init_brush_color(image_buffer, brush_color); } else { @@ -393,7 +394,7 @@ static void do_paint_pixels(void *__restrict userdata, continue; } bool pixels_painted = false; - if (image_buffer->rect_float != nullptr) { + if (image_buffer->float_buffer.data != nullptr) { pixels_painted = kernel_float4.paint(pbvh_data.geom_primitives, node_data.uv_primitives, pixel_row, diff --git a/source/blender/editors/space_clip/clip_buttons.cc b/source/blender/editors/space_clip/clip_buttons.cc index 6e9d213a107..2c55fc3c5e5 100644 --- a/source/blender/editors/space_clip/clip_buttons.cc +++ b/source/blender/editors/space_clip/clip_buttons.cc @@ -802,7 +802,7 @@ void uiTemplateMovieclipInformation(uiLayout *layout, ofs += BLI_snprintf_rlen(str + ofs, sizeof(str) - ofs, TIP_("%d x %d"), width, height); if (ibuf) { - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { if (ibuf->channels != 4) { ofs += BLI_snprintf_rlen( str + ofs, sizeof(str) - ofs, TIP_(", %d float channel(s)"), ibuf->channels); diff --git a/source/blender/editors/space_clip/clip_editor.cc b/source/blender/editors/space_clip/clip_editor.cc index 3febebe043e..9c54b37d1b3 100644 --- a/source/blender/editors/space_clip/clip_editor.cc +++ b/source/blender/editors/space_clip/clip_editor.cc @@ -243,7 +243,7 @@ ImBuf *ED_space_clip_get_buffer(const SpaceClip *sc) ibuf = BKE_movieclip_get_postprocessed_ibuf(sc->clip, &sc->user, sc->postproc_flag); - if (ibuf && (ibuf->rect || ibuf->rect_float)) { + if (ibuf && (ibuf->byte_buffer.data || ibuf->float_buffer.data)) { return ibuf; } @@ -266,7 +266,7 @@ ImBuf *ED_space_clip_get_stable_buffer(const SpaceClip *sc, ibuf = BKE_movieclip_get_stable_ibuf( sc->clip, &sc->user, loc, scale, angle, sc->postproc_flag); - if (ibuf && (ibuf->rect || ibuf->rect_float)) { + if (ibuf && (ibuf->byte_buffer.data || ibuf->float_buffer.data)) { return ibuf; } @@ -323,13 +323,13 @@ bool ED_space_clip_color_sample(const SpaceClip *sc, CLAMP(x, 0, ibuf->x - 1); CLAMP(y, 0, ibuf->y - 1); - if (ibuf->rect_float) { - fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x)); + if (ibuf->float_buffer.data) { + fp = (ibuf->float_buffer.data + (ibuf->channels) * (y * ibuf->x + x)); copy_v3_v3(r_col, fp); ret = true; } - else if (ibuf->rect) { - cp = (uchar *)(ibuf->rect + y * ibuf->x + x); + else if (ibuf->byte_buffer.data) { + cp = ibuf->byte_buffer.data + 4 * (y * ibuf->x + x); rgb_uchar_to_float(r_col, cp); IMB_colormanagement_colorspace_to_scene_linear_v3(r_col, ibuf->rect_colorspace); ret = true; diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c index 507156d8341..0152054d4c7 100644 --- a/source/blender/editors/space_console/console_ops.c +++ b/source/blender/editors/space_console/console_ops.c @@ -1064,7 +1064,7 @@ static int console_paste_exec(bContext *C, wmOperator *op) ConsoleLine *ci = console_history_verify(C); int buf_len; - char *buf_str = WM_clipboard_text_get(selection, &buf_len); + char *buf_str = WM_clipboard_text_get(selection, true, &buf_len); char *buf_step, *buf_next; if (buf_str == NULL) { diff --git a/source/blender/editors/space_file/file_draw.cc b/source/blender/editors/space_file/file_draw.cc index 54b32b9a4e7..bb278d744f9 100644 --- a/source/blender/editors/space_file/file_draw.cc +++ b/source/blender/editors/space_file/file_draw.cc @@ -435,7 +435,7 @@ static void file_draw_preview(const FileDirEntry *file, imb->y, GPU_RGBA8, true, - imb->rect, + imb->byte_buffer.data, scale, scale, 1.0f, diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index cc41d280899..17d91c13e20 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -2741,9 +2741,12 @@ static void file_expand_directory(bContext *C) BKE_appdir_folder_default_or_root()); } else if (params->dir[0] == '~') { + /* While path handling expansion typically doesn't support home directory expansion + * in Blender, this is a convenience to be able to type in a single character. + * Even though this is a UNIX convention, it's harmless to expand on WIN32 as well. */ char tmpstr[sizeof(params->dir) - 1]; STRNCPY(tmpstr, params->dir + 1); - BLI_path_join(params->dir, sizeof(params->dir), BKE_appdir_folder_default_or_root(), tmpstr); + BLI_path_join(params->dir, sizeof(params->dir), BKE_appdir_folder_home(), tmpstr); } else if (params->dir[0] == '\0') diff --git a/source/blender/editors/space_file/filelist.cc b/source/blender/editors/space_file/filelist.cc index 1013af8ac29..11ec6b7e68a 100644 --- a/source/blender/editors/space_file/filelist.cc +++ b/source/blender/editors/space_file/filelist.cc @@ -1114,10 +1114,12 @@ void filelist_init_icons(void) if (tile < SPECIAL_IMG_MAX) { ibuf = IMB_allocImBuf(SPECIAL_IMG_SIZE, SPECIAL_IMG_SIZE, 32, IB_rect); for (k = 0; k < SPECIAL_IMG_SIZE; k++) { - memcpy(&ibuf->rect[k * SPECIAL_IMG_SIZE], - &bbuf->rect[(k + y * SPECIAL_IMG_SIZE) * SPECIAL_IMG_SIZE * SPECIAL_IMG_COLS + - x * SPECIAL_IMG_SIZE], - SPECIAL_IMG_SIZE * sizeof(int)); + memcpy( + &ibuf->byte_buffer.data[4 * (k * SPECIAL_IMG_SIZE)], + &bbuf->byte_buffer + .data[4 * ((k + y * SPECIAL_IMG_SIZE) * SPECIAL_IMG_SIZE * SPECIAL_IMG_COLS + + x * SPECIAL_IMG_SIZE)], + SPECIAL_IMG_SIZE * sizeof(uint8_t) * 4); } gSpecialFileImages[tile] = ibuf; } diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 4bddbf66f5e..9ed30666676 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -946,7 +946,7 @@ void uiTemplateImage(uiLayout *layout, void *lock; ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock); - if (ibuf && ibuf->rect_float && (ibuf->flags & IB_halffloat) == 0) { + if (ibuf && ibuf->float_buffer.data && (ibuf->flags & IB_halffloat) == 0) { uiItemR(col, &imaptr, "use_half_precision", 0, NULL, ICON_NONE); } BKE_image_release_ibuf(ima, ibuf, lock); @@ -1200,7 +1200,7 @@ void uiTemplateImageInfo(uiLayout *layout, bContext *C, Image *ima, ImageUser *i ofs += BLI_snprintf_rlen(str + ofs, len - ofs, TIP_("%d x %d, "), ibuf->x, ibuf->y); - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { if (ibuf->channels != 4) { ofs += BLI_snprintf_rlen( str + ofs, len - ofs, TIP_("%d float channel(s)"), ibuf->channels); @@ -1220,7 +1220,7 @@ void uiTemplateImageInfo(uiLayout *layout, bContext *C, Image *ima, ImageUser *i ofs += BLI_strncpy_rlen(str + ofs, TIP_(" RGB byte"), len - ofs); } } - if (ibuf->zbuf || ibuf->zbuf_float) { + if (ibuf->z_buffer.data || ibuf->float_z_buffer.data) { ofs += BLI_strncpy_rlen(str + ofs, TIP_(" + Z"), len - ofs); } diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c index 8f702a0049c..be02699792a 100644 --- a/source/blender/editors/space_image/image_edit.c +++ b/source/blender/editors/space_image/image_edit.c @@ -167,7 +167,7 @@ ImBuf *ED_space_image_acquire_buffer(SpaceImage *sima, void **r_lock, int tile) return ibuf; } - if (ibuf->rect || ibuf->rect_float) { + if (ibuf->byte_buffer.data || ibuf->float_buffer.data) { return ibuf; } BKE_image_release_ibuf(sima->image, ibuf, *r_lock); @@ -197,7 +197,7 @@ int ED_space_image_get_display_channel_mask(ImBuf *ibuf) const bool color = ibuf->channels >= 3; const bool alpha = ibuf->channels == 4; - const bool zbuf = ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels == 1); + const bool zbuf = ibuf->z_buffer.data || ibuf->float_z_buffer.data || (ibuf->channels == 1); if (!alpha) { result &= ~(SI_USE_ALPHA | SI_SHOW_ALPHA); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 3dd8959a14f..35ce3ce6dee 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -231,7 +231,7 @@ static bool image_from_context_has_data_poll(bContext *C) void *lock; ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock); - const bool has_buffer = (ibuf && (ibuf->rect || ibuf->rect_float)); + const bool has_buffer = (ibuf && (ibuf->byte_buffer.data || ibuf->float_buffer.data)); BKE_image_release_ibuf(ima, ibuf, lock); return has_buffer; } @@ -2743,8 +2743,8 @@ static int image_flip_exec(bContext *C, wmOperator *op) const int size_x = ibuf->x; const int size_y = ibuf->y; - if (ibuf->rect_float) { - float *float_pixels = (float *)ibuf->rect_float; + if (ibuf->float_buffer.data) { + float *float_pixels = ibuf->float_buffer.data; float *orig_float_pixels = MEM_dupallocN(float_pixels); for (int x = 0; x < size_x; x++) { @@ -2761,23 +2761,23 @@ static int image_flip_exec(bContext *C, wmOperator *op) } MEM_freeN(orig_float_pixels); - if (ibuf->rect) { + if (ibuf->byte_buffer.data) { IMB_rect_from_float(ibuf); } } - else if (ibuf->rect) { - char *char_pixels = (char *)ibuf->rect; - char *orig_char_pixels = MEM_dupallocN(char_pixels); + else if (ibuf->byte_buffer.data) { + uchar *char_pixels = ibuf->byte_buffer.data; + uchar *orig_char_pixels = MEM_dupallocN(char_pixels); for (int x = 0; x < size_x; x++) { const int source_pixel_x = use_flip_x ? size_x - x - 1 : x; for (int y = 0; y < size_y; y++) { const int source_pixel_y = use_flip_y ? size_y - y - 1 : y; - const char *source_pixel = + const uchar *source_pixel = &orig_char_pixels[4 * (source_pixel_x + source_pixel_y * size_x)]; - char *target_pixel = &char_pixels[4 * (x + y * size_x)]; + uchar *target_pixel = &char_pixels[4 * (x + y * size_x)]; - copy_v4_v4_char(target_pixel, source_pixel); + copy_v4_v4_uchar(target_pixel, source_pixel); } } MEM_freeN(orig_char_pixels); @@ -2981,9 +2981,9 @@ static int image_invert_exec(bContext *C, wmOperator *op) } /* TODO: make this into an IMB_invert_channels(ibuf,r,g,b,a) method!? */ - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { - float *fp = (float *)ibuf->rect_float; + float *fp = ibuf->float_buffer.data; for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, fp += 4) { if (r) { fp[0] = 1.0f - fp[0]; @@ -2999,13 +2999,13 @@ static int image_invert_exec(bContext *C, wmOperator *op) } } - if (ibuf->rect) { + if (ibuf->byte_buffer.data) { IMB_rect_from_float(ibuf); } } - else if (ibuf->rect) { + else if (ibuf->byte_buffer.data) { - char *cp = (char *)ibuf->rect; + uchar *cp = ibuf->byte_buffer.data; for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, cp += 4) { if (r) { cp[0] = 255 - cp[0]; @@ -3371,13 +3371,13 @@ bool ED_space_image_color_sample( CLAMP(x, 0, ibuf->x - 1); CLAMP(y, 0, ibuf->y - 1); - if (ibuf->rect_float) { - fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x)); + if (ibuf->float_buffer.data) { + fp = (ibuf->float_buffer.data + (ibuf->channels) * (y * ibuf->x + x)); copy_v3_v3(r_col, fp); ret = true; } - else if (ibuf->rect) { - cp = (uchar *)(ibuf->rect + y * ibuf->x + x); + else if (ibuf->byte_buffer.data) { + cp = ibuf->byte_buffer.data + 4 * (y * ibuf->x + x); rgb_uchar_to_float(r_col, cp); IMB_colormanagement_colorspace_to_scene_linear_v3(r_col, ibuf->rect_colorspace); ret = true; @@ -4024,7 +4024,7 @@ static void tile_fill_init(PointerRNA *ptr, Image *ima, ImageTile *tile) /* Initialize properties from reference tile. */ RNA_int_set(ptr, "width", ibuf->x); RNA_int_set(ptr, "height", ibuf->y); - RNA_boolean_set(ptr, "float", ibuf->rect_float != NULL); + RNA_boolean_set(ptr, "float", ibuf->float_buffer.data != NULL); RNA_boolean_set(ptr, "alpha", ibuf->planes > 24); BKE_image_release_ibuf(ima, ibuf, NULL); diff --git a/source/blender/editors/space_image/image_undo.cc b/source/blender/editors/space_image/image_undo.cc index 13f13e4dcda..be88ed8808b 100644 --- a/source/blender/editors/space_image/image_undo.cc +++ b/source/blender/editors/space_image/image_undo.cc @@ -117,7 +117,7 @@ struct PaintTile { ImageUser iuser; union { float *fp; - uint32_t *uint; + uint8_t *byte_ptr; void *pt; } rect; uint16_t *mask; @@ -189,6 +189,21 @@ void *ED_image_paint_tile_find(PaintTileMap *paint_tile_map, return ptile->rect.pt; } +/* Set the given buffer data as an owning data of the imbuf's buffer. + * Returns the data pointer which was stolen from the imbuf before assignment. */ +static uint8_t *image_undo_steal_and_assign_byte_buffer(ImBuf *ibuf, uint8_t *new_buffer_data) +{ + uint8_t *old_buffer_data = IMB_steal_byte_buffer(ibuf); + IMB_assign_byte_buffer(ibuf, new_buffer_data, IB_TAKE_OWNERSHIP); + return old_buffer_data; +} +static float *image_undo_steal_and_assign_float_buffer(ImBuf *ibuf, float *new_buffer_data) +{ + float *old_buffer_data = IMB_steal_float_buffer(ibuf); + IMB_assign_float_buffer(ibuf, new_buffer_data, IB_TAKE_OWNERSHIP); + return old_buffer_data; +} + void *ED_image_paint_tile_push(PaintTileMap *paint_tile_map, Image *image, ImBuf *ibuf, @@ -204,7 +219,7 @@ void *ED_image_paint_tile_push(PaintTileMap *paint_tile_map, if (use_thread_lock) { BLI_spin_lock(&paint_tiles_lock); } - const bool has_float = (ibuf->rect_float != nullptr); + const bool has_float = (ibuf->float_buffer.data != nullptr); /* check if tile is already pushed */ @@ -240,7 +255,7 @@ void *ED_image_paint_tile_push(PaintTileMap *paint_tile_map, MEM_callocN(sizeof(uint16_t) * square_i(ED_IMAGE_UNDO_TILE_SIZE), "PaintTile.mask")); } - ptile->rect.pt = MEM_callocN((ibuf->rect_float ? sizeof(float[4]) : sizeof(char[4])) * + ptile->rect.pt = MEM_callocN((ibuf->float_buffer.data ? sizeof(float[4]) : sizeof(char[4])) * square_i(ED_IMAGE_UNDO_TILE_SIZE), "PaintTile.rect"); @@ -261,10 +276,10 @@ void *ED_image_paint_tile_push(PaintTileMap *paint_tile_map, ED_IMAGE_UNDO_TILE_SIZE); if (has_float) { - std::swap(ptile->rect.fp, (*tmpibuf)->rect_float); + ptile->rect.fp = image_undo_steal_and_assign_float_buffer(*tmpibuf, ptile->rect.fp); } else { - std::swap(ptile->rect.uint, (*tmpibuf)->rect); + ptile->rect.byte_ptr = image_undo_steal_and_assign_byte_buffer(*tmpibuf, ptile->rect.byte_ptr); } PaintTileKey key = {}; @@ -296,15 +311,18 @@ static void ptile_restore_runtime_map(PaintTileMap *paint_tile_map) for (PaintTile *ptile : paint_tile_map->map.values()) { Image *image = ptile->image; ImBuf *ibuf = BKE_image_acquire_ibuf(image, &ptile->iuser, nullptr); - const bool has_float = (ibuf->rect_float != nullptr); + const bool has_float = (ibuf->float_buffer.data != nullptr); if (has_float) { - std::swap(ptile->rect.fp, tmpibuf->rect_float); + ptile->rect.fp = image_undo_steal_and_assign_float_buffer(tmpibuf, ptile->rect.fp); } else { - std::swap(ptile->rect.uint, tmpibuf->rect); + ptile->rect.byte_ptr = image_undo_steal_and_assign_byte_buffer(tmpibuf, + ptile->rect.byte_ptr); } + /* TODO(sergey): Look into implementing API which does not require such temporary buffer + * assignment. */ IMB_rectcpy(ibuf, tmpibuf, ptile->x_tile * ED_IMAGE_UNDO_TILE_SIZE, @@ -315,16 +333,17 @@ static void ptile_restore_runtime_map(PaintTileMap *paint_tile_map) ED_IMAGE_UNDO_TILE_SIZE); if (has_float) { - std::swap(ptile->rect.fp, tmpibuf->rect_float); + ptile->rect.fp = image_undo_steal_and_assign_float_buffer(tmpibuf, ptile->rect.fp); } else { - std::swap(ptile->rect.uint, tmpibuf->rect); + ptile->rect.byte_ptr = image_undo_steal_and_assign_byte_buffer(tmpibuf, + ptile->rect.byte_ptr); } /* Force OpenGL reload (maybe partial update will operate better?) */ BKE_image_free_gputextures(image); - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { ibuf->userflags |= IB_RECT_INVALID; /* force recreate of char rect */ } if (ibuf->mipmap[0]) { @@ -353,7 +372,7 @@ static uint32_t index_from_xy(uint32_t tile_x, uint32_t tile_y, const uint32_t t struct UndoImageTile { union { float *fp; - uint32_t *uint_ptr; + uint8_t *byte_ptr; void *pt; } rect; int users; @@ -368,7 +387,7 @@ static UndoImageTile *utile_alloc(bool has_float) MEM_mallocN(sizeof(float[4]) * square_i(ED_IMAGE_UNDO_TILE_SIZE), __func__)); } else { - utile->rect.uint_ptr = static_cast( + utile->rect.byte_ptr = static_cast( MEM_mallocN(sizeof(uint32_t) * square_i(ED_IMAGE_UNDO_TILE_SIZE), __func__)); } return utile; @@ -377,43 +396,47 @@ static UndoImageTile *utile_alloc(bool has_float) static void utile_init_from_imbuf( UndoImageTile *utile, const uint32_t x, const uint32_t y, const ImBuf *ibuf, ImBuf *tmpibuf) { - const bool has_float = ibuf->rect_float; + const bool has_float = ibuf->float_buffer.data; if (has_float) { - std::swap(utile->rect.fp, tmpibuf->rect_float); + utile->rect.fp = image_undo_steal_and_assign_float_buffer(tmpibuf, utile->rect.fp); } else { - std::swap(utile->rect.uint_ptr, tmpibuf->rect); + utile->rect.byte_ptr = image_undo_steal_and_assign_byte_buffer(tmpibuf, utile->rect.byte_ptr); } + /* TODO(sergey): Look into implementing API which does not require such temporary buffer + * assignment. */ IMB_rectcpy(tmpibuf, ibuf, 0, 0, x, y, ED_IMAGE_UNDO_TILE_SIZE, ED_IMAGE_UNDO_TILE_SIZE); if (has_float) { - std::swap(utile->rect.fp, tmpibuf->rect_float); + utile->rect.fp = image_undo_steal_and_assign_float_buffer(tmpibuf, utile->rect.fp); } else { - std::swap(utile->rect.uint_ptr, tmpibuf->rect); + utile->rect.byte_ptr = image_undo_steal_and_assign_byte_buffer(tmpibuf, utile->rect.byte_ptr); } } static void utile_restore( const UndoImageTile *utile, const uint x, const uint y, ImBuf *ibuf, ImBuf *tmpibuf) { - const bool has_float = ibuf->rect_float; - float *prev_rect_float = tmpibuf->rect_float; - uint32_t *prev_rect = tmpibuf->rect; + const bool has_float = ibuf->float_buffer.data; + float *prev_rect_float = tmpibuf->float_buffer.data; + uint8_t *prev_rect = tmpibuf->byte_buffer.data; if (has_float) { - tmpibuf->rect_float = utile->rect.fp; + tmpibuf->float_buffer.data = utile->rect.fp; } else { - tmpibuf->rect = utile->rect.uint_ptr; + tmpibuf->byte_buffer.data = utile->rect.byte_ptr; } + /* TODO(sergey): Look into implementing API which does not require such temporary buffer + * assignment. */ IMB_rectcpy(ibuf, tmpibuf, x, y, 0, 0, ED_IMAGE_UNDO_TILE_SIZE, ED_IMAGE_UNDO_TILE_SIZE); - tmpibuf->rect_float = prev_rect_float; - tmpibuf->rect = prev_rect; + tmpibuf->float_buffer.data = prev_rect_float; + tmpibuf->byte_buffer.data = prev_rect; } static void utile_decref(UndoImageTile *utile) @@ -473,7 +496,7 @@ static UndoImageBuf *ubuf_from_image_no_tiles(Image *image, const ImBuf *ibuf) STRNCPY(ubuf->ibuf_filepath, ibuf->filepath); ubuf->image_state.source = image->source; - ubuf->image_state.use_float = ibuf->rect_float != nullptr; + ubuf->image_state.use_float = ibuf->float_buffer.data != nullptr; return ubuf; } @@ -482,7 +505,7 @@ static void ubuf_from_image_all_tiles(UndoImageBuf *ubuf, const ImBuf *ibuf) { ImBuf *tmpibuf = imbuf_alloc_temp_tile(); - const bool has_float = ibuf->rect_float; + const bool has_float = ibuf->float_buffer.data; int i = 0; for (uint y_tile = 0; y_tile < ubuf->tiles_dims[1]; y_tile += 1) { uint y = y_tile << ED_IMAGE_UNDO_TILE_BITS; @@ -509,12 +532,13 @@ static void ubuf_ensure_compat_ibuf(const UndoImageBuf *ubuf, ImBuf *ibuf) { /* We could have both float and rect buffers, * in this case free the float buffer if it's unused. */ - if ((ibuf->rect_float != nullptr) && (ubuf->image_state.use_float == false)) { + if ((ibuf->float_buffer.data != nullptr) && (ubuf->image_state.use_float == false)) { imb_freerectfloatImBuf(ibuf); } if (ibuf->x == ubuf->image_dims[0] && ibuf->y == ubuf->image_dims[1] && - (ubuf->image_state.use_float ? (void *)ibuf->rect_float : (void *)ibuf->rect)) + (ubuf->image_state.use_float ? (void *)ibuf->float_buffer.data : + (void *)ibuf->byte_buffer.data)) { return; } @@ -602,7 +626,7 @@ static void uhandle_restore_list(ListBase *undo_handles, bool use_init) /* TODO(@jbakker): only mark areas that are actually updated to improve performance. */ BKE_image_partial_update_mark_full_update(image); - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { ibuf->userflags |= IB_RECT_INVALID; /* Force recreate of char `rect` */ } if (ibuf->mipmap[0]) { @@ -832,7 +856,7 @@ static bool image_undosys_step_encode(struct bContext *C, struct Main * /*bmain* ImBuf *ibuf = BKE_image_acquire_ibuf(uh->image_ref.ptr, &uh->iuser, nullptr); - const bool has_float = ibuf->rect_float; + const bool has_float = ibuf->float_buffer.data; BLI_assert(ubuf_pre->post == nullptr); ubuf_pre->post = ubuf_from_image_no_tiles(uh->image_ref.ptr, ibuf); diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc index fbabfc21514..ede3fee7411 100644 --- a/source/blender/editors/space_node/drawnode.cc +++ b/source/blender/editors/space_node/drawnode.cc @@ -504,7 +504,6 @@ static void node_shader_set_butfunc(bNodeType *ntype) case SH_NODE_VECTOR_DISPLACEMENT: ntype->draw_buttons = node_shader_buts_displacement; break; - case SH_NODE_BSDF_GLOSSY: case SH_NODE_BSDF_GLASS: case SH_NODE_BSDF_REFRACTION: ntype->draw_buttons = node_shader_buts_glossy; diff --git a/source/blender/editors/space_node/node_view.cc b/source/blender/editors/space_node/node_view.cc index 7ae833e8473..e852a5be358 100644 --- a/source/blender/editors/space_node/node_view.cc +++ b/source/blender/editors/space_node/node_view.cc @@ -510,14 +510,14 @@ bool ED_space_node_color_sample( CLAMP(x, 0, ibuf->x - 1); CLAMP(y, 0, ibuf->y - 1); - if (ibuf->rect_float) { - fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x)); + if (ibuf->float_buffer.data) { + fp = (ibuf->float_buffer.data + (ibuf->channels) * (y * ibuf->x + x)); /* #IB_PROFILE_NONE is default but in fact its linear. */ copy_v3_v3(r_col, fp); ret = true; } - else if (ibuf->rect) { - cp = (uchar *)(ibuf->rect + y * ibuf->x + x); + else if (ibuf->byte_buffer.data) { + cp = ibuf->byte_buffer.data + 4 * (y * ibuf->x + x); rgb_uchar_to_float(r_col, cp); IMB_colormanagement_colorspace_to_scene_linear_v3(r_col, ibuf->rect_colorspace); ret = true; @@ -549,7 +549,7 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event) return; } - if (!ibuf->rect) { + if (!ibuf->byte_buffer.data) { IMB_rect_from_float(ibuf); } @@ -577,8 +577,8 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event) info->zp = nullptr; info->zfp = nullptr; - if (ibuf->rect) { - cp = (uchar *)(ibuf->rect + y * ibuf->x + x); + if (ibuf->byte_buffer.data) { + cp = ibuf->byte_buffer.data + 4 * (y * ibuf->x + x); info->col[0] = cp[0]; info->col[1] = cp[1]; @@ -596,8 +596,8 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event) info->color_manage = true; } - if (ibuf->rect_float) { - fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x)); + if (ibuf->float_buffer.data) { + fp = (ibuf->float_buffer.data + (ibuf->channels) * (y * ibuf->x + x)); info->colf[0] = fp[0]; info->colf[1] = fp[1]; @@ -607,12 +607,12 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event) info->color_manage = true; } - if (ibuf->zbuf) { - info->z = ibuf->zbuf[y * ibuf->x + x]; + if (ibuf->z_buffer.data) { + info->z = ibuf->z_buffer.data[y * ibuf->x + x]; info->zp = &info->z; } - if (ibuf->zbuf_float) { - info->zf = ibuf->zbuf_float[y * ibuf->x + x]; + if (ibuf->float_z_buffer.data) { + info->zf = ibuf->float_z_buffer.data[y * ibuf->x + x]; info->zfp = &info->zf; } diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index c6ee4ddffe6..d4be8f43f0b 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -1762,8 +1762,8 @@ static void *sequencer_OCIO_transform_ibuf(const bContext *C, *r_glsl_used = false; display_buffer = NULL; } - else if (ibuf->rect_float) { - display_buffer = ibuf->rect_float; + else if (ibuf->float_buffer.data) { + display_buffer = ibuf->float_buffer.data; *r_data = GPU_DATA_FLOAT; if (ibuf->channels == 4) { @@ -1787,8 +1787,8 @@ static void *sequencer_OCIO_transform_ibuf(const bContext *C, *r_glsl_used = IMB_colormanagement_setup_glsl_draw_ctx(C, ibuf->dither, true); } } - else if (ibuf->rect) { - display_buffer = ibuf->rect; + else if (ibuf->byte_buffer.data) { + display_buffer = ibuf->byte_buffer.data; *r_glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx( C, ibuf->rect_colorspace, ibuf->dither, false); @@ -1799,7 +1799,7 @@ static void *sequencer_OCIO_transform_ibuf(const bContext *C, /* There is data to be displayed, but GLSL is not initialized * properly, in this case we fallback to CPU-based display transform. */ - if ((ibuf->rect || ibuf->rect_float) && !*r_glsl_used) { + if ((ibuf->byte_buffer.data || ibuf->float_buffer.data) && !*r_glsl_used) { display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, r_buffer_cache_handle); *r_format = GPU_RGBA8; *r_data = GPU_DATA_UBYTE; @@ -1896,11 +1896,11 @@ static void sequencer_draw_display_buffer(const bContext *C, if (scope) { ibuf = scope; - if (ibuf->rect_float && ibuf->rect == NULL) { + if (ibuf->float_buffer.data && ibuf->byte_buffer.data == NULL) { IMB_rect_from_float(ibuf); } - display_buffer = (uchar *)ibuf->rect; + display_buffer = ibuf->byte_buffer.data; format = GPU_RGBA8; data = GPU_DATA_UBYTE; } @@ -1992,7 +1992,7 @@ static ImBuf *sequencer_get_scope(Scene *scene, SpaceSeq *sseq, ImBuf *ibuf, boo if (!scopes->zebra_ibuf) { ImBuf *display_ibuf = IMB_dupImBuf(ibuf); - if (display_ibuf->rect_float) { + if (display_ibuf->float_buffer.data) { IMB_colormanagement_imbuf_make_display_space( display_ibuf, &scene->view_settings, &scene->display_settings); } diff --git a/source/blender/editors/space_sequencer/sequencer_gizmo_retime_type.cc b/source/blender/editors/space_sequencer/sequencer_gizmo_retime_type.cc index 08bb18252dc..233ae95f3f1 100644 --- a/source/blender/editors/space_sequencer/sequencer_gizmo_retime_type.cc +++ b/source/blender/editors/space_sequencer/sequencer_gizmo_retime_type.cc @@ -445,9 +445,9 @@ static void gizmo_retime_handle_draw(const bContext *C, wmGizmo *gz) RetimeHandleMoveGizmo *gizmo = (RetimeHandleMoveGizmo *)gz; const View2D *v2d = UI_view2d_fromcontext(C); - /* TODO: This is hardcoded behavior, same as preselect gizmos in 3D view. + /* TODO: This is hard-coded behavior, same as pre-select gizmos in 3D view. * Better solution would be to check operator keymap and display this information in status bar - * and tooltip. */ + * and tool-tip. */ wmEvent *event = CTX_wm_window(C)->eventstate; gizmo->create_transition_operation = (event->modifier & KM_SHIFT) != 0; diff --git a/source/blender/editors/space_sequencer/sequencer_retiming.cc b/source/blender/editors/space_sequencer/sequencer_retiming.cc index bab13a7f9e8..f0328901d0c 100644 --- a/source/blender/editors/space_sequencer/sequencer_retiming.cc +++ b/source/blender/editors/space_sequencer/sequencer_retiming.cc @@ -216,7 +216,7 @@ static int sequencer_retiming_handle_move_modal(bContext *C, wmOperator *op, con const bool handle_is_transition = SEQ_retiming_handle_is_transition_type(handle); const bool prev_handle_is_transition = SEQ_retiming_handle_is_transition_type(handle - 1); - /* When working with transiton, change handles when moving past pivot point. */ + /* When working with transition, change handles when moving past pivot point. */ if (handle_is_transition || prev_handle_is_transition) { SeqRetimingHandle *transition_start, *transition_end; if (handle_is_transition) { diff --git a/source/blender/editors/space_sequencer/sequencer_scopes.c b/source/blender/editors/space_sequencer/sequencer_scopes.c index 762f2c178ab..34e134f56fa 100644 --- a/source/blender/editors/space_sequencer/sequencer_scopes.c +++ b/source/blender/editors/space_sequencer/sequencer_scopes.c @@ -126,8 +126,8 @@ static ImBuf *make_waveform_view_from_ibuf_byte(ImBuf *ibuf) { ImBuf *rval = IMB_allocImBuf(ibuf->x + 3, 515, 32, IB_rect); int x, y; - const uchar *src = (uchar *)ibuf->rect; - uchar *tgt = (uchar *)rval->rect; + const uchar *src = ibuf->byte_buffer.data; + uchar *tgt = rval->byte_buffer.data; int w = ibuf->x + 3; int h = 515; float waveform_gamma = 0.2; @@ -167,8 +167,8 @@ static ImBuf *make_waveform_view_from_ibuf_float(ImBuf *ibuf) { ImBuf *rval = IMB_allocImBuf(ibuf->x + 3, 515, 32, IB_rect); int x, y; - const float *src = ibuf->rect_float; - uchar *tgt = (uchar *)rval->rect; + const float *src = ibuf->float_buffer.data; + uchar *tgt = rval->byte_buffer.data; int w = ibuf->x + 3; int h = 515; float waveform_gamma = 0.2; @@ -210,7 +210,7 @@ static ImBuf *make_waveform_view_from_ibuf_float(ImBuf *ibuf) ImBuf *make_waveform_view_from_ibuf(ImBuf *ibuf) { - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { return make_waveform_view_from_ibuf_float(ibuf); } return make_waveform_view_from_ibuf_byte(ibuf); @@ -220,8 +220,8 @@ static ImBuf *make_sep_waveform_view_from_ibuf_byte(ImBuf *ibuf) { ImBuf *rval = IMB_allocImBuf(ibuf->x + 3, 515, 32, IB_rect); int x, y; - const uchar *src = (const uchar *)ibuf->rect; - uchar *tgt = (uchar *)rval->rect; + const uchar *src = ibuf->byte_buffer.data; + uchar *tgt = rval->byte_buffer.data; int w = ibuf->x + 3; int sw = ibuf->x / 3; int h = 515; @@ -265,8 +265,8 @@ static ImBuf *make_sep_waveform_view_from_ibuf_float(ImBuf *ibuf) { ImBuf *rval = IMB_allocImBuf(ibuf->x + 3, 515, 32, IB_rect); int x, y; - const float *src = ibuf->rect_float; - uchar *tgt = (uchar *)rval->rect; + const float *src = ibuf->float_buffer.data; + uchar *tgt = rval->byte_buffer.data; int w = ibuf->x + 3; int sw = ibuf->x / 3; int h = 515; @@ -312,7 +312,7 @@ static ImBuf *make_sep_waveform_view_from_ibuf_float(ImBuf *ibuf) ImBuf *make_sep_waveform_view_from_ibuf(ImBuf *ibuf) { - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { return make_sep_waveform_view_from_ibuf_float(ibuf); } return make_sep_waveform_view_from_ibuf_byte(ibuf); @@ -321,8 +321,8 @@ ImBuf *make_sep_waveform_view_from_ibuf(ImBuf *ibuf) static void draw_zebra_byte(ImBuf *src, ImBuf *ibuf, float perc) { uint limit = 255.0f * perc / 100.0f; - uchar *p = (uchar *)src->rect; - uchar *o = (uchar *)ibuf->rect; + uchar *p = src->byte_buffer.data; + uchar *o = ibuf->byte_buffer.data; int x; int y; @@ -351,8 +351,8 @@ static void draw_zebra_byte(ImBuf *src, ImBuf *ibuf, float perc) static void draw_zebra_float(ImBuf *src, ImBuf *ibuf, float perc) { float limit = perc / 100.0f; - const float *p = src->rect_float; - uchar *o = (uchar *)ibuf->rect; + const float *p = src->float_buffer.data; + uchar *o = ibuf->byte_buffer.data; int x; int y; @@ -383,7 +383,7 @@ ImBuf *make_zebra_view_from_ibuf(ImBuf *ibuf, float perc) { ImBuf *new_ibuf = IMB_allocImBuf(ibuf->x, ibuf->y, 32, IB_rect); - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { draw_zebra_float(ibuf, new_ibuf, perc); } else { @@ -394,7 +394,7 @@ ImBuf *make_zebra_view_from_ibuf(ImBuf *ibuf, float perc) static void draw_histogram_marker(ImBuf *ibuf, int x) { - uchar *p = (uchar *)ibuf->rect; + uchar *p = ibuf->byte_buffer.data; int barh = ibuf->y * 0.1; p += 4 * (x + ibuf->x * (ibuf->y - barh + 1)); @@ -407,7 +407,7 @@ static void draw_histogram_marker(ImBuf *ibuf, int x) static void draw_histogram_bar(ImBuf *ibuf, int x, float val, int col) { - uchar *p = (uchar *)ibuf->rect; + uchar *p = ibuf->byte_buffer.data; int barh = ibuf->y * val * 0.9f; p += 4 * (x + ibuf->x); @@ -430,7 +430,7 @@ static void make_histogram_view_from_ibuf_byte_fn(void *__restrict userdata, { MakeHistogramViewData *data = userdata; const ImBuf *ibuf = data->ibuf; - const uchar *src = (uchar *)ibuf->rect; + const uchar *src = ibuf->byte_buffer.data; uint32_t(*cur_bins)[HIS_STEPS] = tls->userdata_chunk; @@ -506,7 +506,7 @@ static ImBuf *make_histogram_view_from_ibuf_byte(ImBuf *ibuf) } } - wform_put_border((uchar *)rval->rect, rval->x, rval->y); + wform_put_border(rval->byte_buffer.data, rval->x, rval->y); return rval; } @@ -529,7 +529,7 @@ static void make_histogram_view_from_ibuf_float_fn(void *__restrict userdata, { const MakeHistogramViewData *data = userdata; const ImBuf *ibuf = data->ibuf; - const float *src = ibuf->rect_float; + const float *src = ibuf->float_buffer.data; uint32_t(*cur_bins)[HIS_STEPS] = tls->userdata_chunk; @@ -590,7 +590,7 @@ static ImBuf *make_histogram_view_from_ibuf_float(ImBuf *ibuf) draw_histogram_marker(rval, get_bin_float(0.0)); draw_histogram_marker(rval, get_bin_float(1.0)); - wform_put_border((uchar *)rval->rect, rval->x, rval->y); + wform_put_border(rval->byte_buffer.data, rval->x, rval->y); return rval; } @@ -599,16 +599,16 @@ static ImBuf *make_histogram_view_from_ibuf_float(ImBuf *ibuf) ImBuf *make_histogram_view_from_ibuf(ImBuf *ibuf) { - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { return make_histogram_view_from_ibuf_float(ibuf); } return make_histogram_view_from_ibuf_byte(ibuf); } -static void vectorscope_put_cross(uchar r, uchar g, uchar b, char *tgt, int w, int h, int size) +static void vectorscope_put_cross(uchar r, uchar g, uchar b, uchar *tgt, int w, int h, int size) { float rgb[3], yuv[3]; - char *p; + uchar *p; rgb[0] = (float)r / 255.0f; rgb[1] = (float)g / 255.0f; @@ -623,7 +623,7 @@ static void vectorscope_put_cross(uchar r, uchar g, uchar b, char *tgt, int w, i for (int y = -size; y <= size; y++) { for (int x = -size; x <= size; x++) { - char *q = p + 4 * (y * w + x); + uchar *q = p + 4 * (y * w + x); q[0] = r; q[1] = g; q[2] = b; @@ -636,8 +636,8 @@ static ImBuf *make_vectorscope_view_from_ibuf_byte(ImBuf *ibuf) { ImBuf *rval = IMB_allocImBuf(515, 515, 32, IB_rect); int x, y; - const char *src = (const char *)ibuf->rect; - char *tgt = (char *)rval->rect; + const uchar *src = ibuf->byte_buffer.data; + uchar *tgt = rval->byte_buffer.data; float rgb[3], yuv[3]; int w = 515; int h = 515; @@ -659,8 +659,8 @@ static ImBuf *make_vectorscope_view_from_ibuf_byte(ImBuf *ibuf) for (y = 0; y < ibuf->y; y++) { for (x = 0; x < ibuf->x; x++) { - const char *src1 = src + 4 * (ibuf->x * y + x); - char *p; + const uchar *src1 = src + 4 * (ibuf->x * y + x); + uchar *p; rgb[0] = (float)src1[0] / 255.0f; rgb[1] = (float)src1[1] / 255.0f; @@ -681,8 +681,8 @@ static ImBuf *make_vectorscope_view_from_ibuf_float(ImBuf *ibuf) { ImBuf *rval = IMB_allocImBuf(515, 515, 32, IB_rect); int x, y; - const float *src = ibuf->rect_float; - char *tgt = (char *)rval->rect; + const float *src = ibuf->float_buffer.data; + uchar *tgt = rval->byte_buffer.data; float rgb[3], yuv[3]; int w = 515; int h = 515; @@ -705,7 +705,7 @@ static ImBuf *make_vectorscope_view_from_ibuf_float(ImBuf *ibuf) for (y = 0; y < ibuf->y; y++) { for (x = 0; x < ibuf->x; x++) { const float *src1 = src + 4 * (ibuf->x * y + x); - const char *p; + const uchar *p; memcpy(rgb, src1, sizeof(float[3])); @@ -725,7 +725,7 @@ static ImBuf *make_vectorscope_view_from_ibuf_float(ImBuf *ibuf) ImBuf *make_vectorscope_view_from_ibuf(ImBuf *ibuf) { - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { return make_vectorscope_view_from_ibuf_float(ibuf); } return make_vectorscope_view_from_ibuf_byte(ibuf); diff --git a/source/blender/editors/space_sequencer/sequencer_thumbnails.c b/source/blender/editors/space_sequencer/sequencer_thumbnails.c index c20717dd386..bed48f4d060 100644 --- a/source/blender/editors/space_sequencer/sequencer_thumbnails.c +++ b/source/blender/editors/space_sequencer/sequencer_thumbnails.c @@ -541,14 +541,14 @@ void draw_seq_strip_thumbnail(View2D *v2d, /* Transparency on overlap. */ if (seq->flag & SEQ_OVERLAP) { GPU_blend(GPU_BLEND_ALPHA); - if (ibuf->rect) { - uchar *buf = (uchar *)ibuf->rect; + if (ibuf->byte_buffer.data) { + uchar *buf = ibuf->byte_buffer.data; for (int pixel = ibuf->x * ibuf->y; pixel--; buf += 4) { buf[3] = OVERLAP_ALPHA; } } - else if (ibuf->rect_float) { - float *buf = (float *)ibuf->rect_float; + else if (ibuf->float_buffer.data) { + float *buf = ibuf->float_buffer.data; for (int pixel = ibuf->x * ibuf->y; pixel--; buf += ibuf->channels) { buf[3] = (OVERLAP_ALPHA / 255.0f); } diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index 9fd00e3ef4f..616cc817c24 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -132,7 +132,7 @@ static void text_listener(const wmSpaceTypeListenerParams *params) switch (wmn->action) { case NA_EDITED: if (st->text) { - text_drawcache_tag_update(st, 1); + text_drawcache_tag_update(st, true); text_update_edited(st->text); } diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c index 27a88301307..1655b2f0338 100644 --- a/source/blender/editors/space_text/text_draw.c +++ b/source/blender/editors/space_text/text_draw.c @@ -712,7 +712,7 @@ static void text_update_drawcache(SpaceText *st, ARegion *region) drawcache->valid_tail = 0; } -void text_drawcache_tag_update(SpaceText *st, int full) +void text_drawcache_tag_update(SpaceText *st, const bool full) { /* This happens if text editor ops are called from Python. */ if (st == NULL) { diff --git a/source/blender/editors/space_text/text_intern.h b/source/blender/editors/space_text/text_intern.h index 7fdc557e7d2..f0ad70e7e8f 100644 --- a/source/blender/editors/space_text/text_intern.h +++ b/source/blender/editors/space_text/text_intern.h @@ -85,7 +85,7 @@ void wrap_offset_in_line(const struct SpaceText *st, int *offc); int text_get_char_pos(const struct SpaceText *st, const char *line, int cur); -void text_drawcache_tag_update(struct SpaceText *st, int full); +void text_drawcache_tag_update(struct SpaceText *st, bool full); void text_free_caches(struct SpaceText *st); bool text_do_suggest_select(struct SpaceText *st, struct ARegion *region, const int mval[2]); diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 58dffa36b2d..b9d73224e32 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -306,7 +306,7 @@ static int text_new_exec(bContext *C, wmOperator *UNUSED(op)) st->top = 0; st->runtime.scroll_ofs_px[0] = 0; st->runtime.scroll_ofs_px[1] = 0; - text_drawcache_tag_update(st, 1); + text_drawcache_tag_update(st, true); } WM_event_add_notifier(C, NC_TEXT | NA_ADDED, text); @@ -389,7 +389,7 @@ static int text_open_exec(bContext *C, wmOperator *op) st->runtime.scroll_ofs_px[1] = 0; } - text_drawcache_tag_update(st, 1); + text_drawcache_tag_update(st, true); WM_event_add_notifier(C, NC_TEXT | NA_ADDED, text); MEM_freeN(op->customdata); @@ -479,7 +479,7 @@ static int text_reload_exec(bContext *C, wmOperator *op) text_update_edited(text); text_update_cursor_moved(C); - text_drawcache_tag_update(CTX_wm_space_text(C), 1); + text_drawcache_tag_update(st, true); WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text); text->flags &= ~TXT_ISDIRTY; @@ -538,7 +538,7 @@ static int text_unlink_exec(bContext *C, wmOperator *UNUSED(op)) BKE_id_delete(bmain, text); - text_drawcache_tag_update(st, 1); + text_drawcache_tag_update(st, true); WM_event_add_notifier(C, NC_TEXT | NA_REMOVED, NULL); return OPERATOR_FINISHED; @@ -918,18 +918,22 @@ void TEXT_OT_refresh_pyconstraints(wmOperatorType *ot) static int text_paste_exec(bContext *C, wmOperator *op) { - const bool selection = RNA_boolean_get(op->ptr, "selection"); + SpaceText *st = CTX_wm_space_text(C); Text *text = CTX_data_edit_text(C); + + const bool selection = RNA_boolean_get(op->ptr, "selection"); + char *buf; int buf_len; - buf = WM_clipboard_text_get(selection, &buf_len); + /* No need for UTF8 validation as the conversion handles invalid sequences gracefully. */ + buf = WM_clipboard_text_get(selection, false, &buf_len); if (!buf) { return OPERATOR_CANCELLED; } - text_drawcache_tag_update(CTX_wm_space_text(C), 0); + text_drawcache_tag_update(st, false); ED_text_undo_push_init(C); @@ -949,7 +953,7 @@ static int text_paste_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text); /* run the script while editing, evil but useful */ - if (CTX_wm_space_text(C)->live_edit) { + if (st->live_edit) { text_run_script(C, NULL); } @@ -1070,9 +1074,10 @@ void TEXT_OT_copy(wmOperatorType *ot) static int text_cut_exec(bContext *C, wmOperator *UNUSED(op)) { + SpaceText *st = CTX_wm_space_text(C); Text *text = CTX_data_edit_text(C); - text_drawcache_tag_update(CTX_wm_space_text(C), 0); + text_drawcache_tag_update(st, false); txt_copy_clipboard(text); @@ -1083,7 +1088,7 @@ static int text_cut_exec(bContext *C, wmOperator *UNUSED(op)) WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text); /* run the script while editing, evil but useful */ - if (CTX_wm_space_text(C)->live_edit) { + if (st->live_edit) { text_run_script(C, NULL); } @@ -1148,9 +1153,10 @@ void TEXT_OT_indent_or_autocomplete(wmOperatorType *ot) static int text_indent_exec(bContext *C, wmOperator *UNUSED(op)) { + SpaceText *st = CTX_wm_space_text(C); Text *text = CTX_data_edit_text(C); - text_drawcache_tag_update(CTX_wm_space_text(C), 0); + text_drawcache_tag_update(st, false); ED_text_undo_push_init(C); @@ -1193,9 +1199,10 @@ void TEXT_OT_indent(wmOperatorType *ot) static int text_unindent_exec(bContext *C, wmOperator *UNUSED(op)) { + SpaceText *st = CTX_wm_space_text(C); Text *text = CTX_data_edit_text(C); - text_drawcache_tag_update(CTX_wm_space_text(C), 0); + text_drawcache_tag_update(st, false); ED_text_undo_push_init(C); @@ -1238,7 +1245,7 @@ static int text_line_break_exec(bContext *C, wmOperator *UNUSED(op)) int a, curts; int space = (text->flags & TXT_TABSTOSPACES) ? st->tabnumber : 1; - text_drawcache_tag_update(st, 0); + text_drawcache_tag_update(st, false); /* Double check tabs/spaces before splitting the line. */ curts = txt_setcurr_tab_spaces(text, space); @@ -1290,11 +1297,12 @@ void TEXT_OT_line_break(wmOperatorType *ot) static int text_comment_exec(bContext *C, wmOperator *op) { + SpaceText *st = CTX_wm_space_text(C); Text *text = CTX_data_edit_text(C); int type = RNA_enum_get(op->ptr, "type"); const char *prefix = ED_text_format_comment_line_prefix(text); - text_drawcache_tag_update(CTX_wm_space_text(C), 0); + text_drawcache_tag_update(st, false); ED_text_undo_push_init(C); @@ -1476,7 +1484,7 @@ static int text_convert_whitespace_exec(bContext *C, wmOperator *op) text_update_edited(text); text_update_cursor_moved(C); - text_drawcache_tag_update(st, 1); + text_drawcache_tag_update(st, true); WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text); return OPERATOR_FINISHED; @@ -2405,7 +2413,7 @@ static int text_delete_exec(bContext *C, wmOperator *op) Text *text = CTX_data_edit_text(C); int type = RNA_enum_get(op->ptr, "type"); - text_drawcache_tag_update(st, 0); + text_drawcache_tag_update(st, true); /* behavior could be changed here, * but for now just don't jump words when we have a selection */ @@ -3478,7 +3486,7 @@ static int text_insert_exec(bContext *C, wmOperator *op) size_t i = 0; uint code; - text_drawcache_tag_update(st, 0); + text_drawcache_tag_update(st, false); str = RNA_string_get_alloc(op->ptr, "text", NULL, 0, &str_len); @@ -3513,6 +3521,7 @@ static int text_insert_exec(bContext *C, wmOperator *op) static int text_insert_invoke(bContext *C, wmOperator *op, const wmEvent *event) { + SpaceText *st = CTX_wm_space_text(C); uint auto_close_char = 0; int ret; @@ -3550,7 +3559,7 @@ static int text_insert_invoke(bContext *C, wmOperator *op, const wmEvent *event) } /* run the script while editing, evil but useful */ - if (ret == OPERATOR_FINISHED && CTX_wm_space_text(C)->live_edit) { + if (ret == OPERATOR_FINISHED && st->live_edit) { text_run_script(C, NULL); } @@ -3629,7 +3638,7 @@ static int text_find_and_replace(bContext *C, wmOperator *op, short mode) } text_update_cursor_moved(C); WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text); - text_drawcache_tag_update(CTX_wm_space_text(C), 1); + text_drawcache_tag_update(st, true); } } MEM_freeN(tmp); @@ -3715,7 +3724,7 @@ static int text_replace_all(bContext *C) } while (found); WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text); - text_drawcache_tag_update(CTX_wm_space_text(C), 1); + text_drawcache_tag_update(st, true); } else { /* Restore position */ diff --git a/source/blender/editors/space_text/text_undo.cc b/source/blender/editors/space_text/text_undo.cc index 39b90841cfe..a42bf3417e0 100644 --- a/source/blender/editors/space_text/text_undo.cc +++ b/source/blender/editors/space_text/text_undo.cc @@ -209,7 +209,7 @@ static void text_undosys_step_decode(struct bContext *C, st->text = text; } text_update_cursor_moved(C); - text_drawcache_tag_update(st, 1); + text_drawcache_tag_update(st, true); WM_event_add_notifier(C, NC_TEXT | NA_EDITED, text); } diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 921ade101c7..22c6d63eaab 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -305,10 +305,12 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float BMEdge *eed; BMIter iter; - const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); + const int cd_vert_bweight_offset = CustomData_get_offset_named( + &bm->vdata, CD_PROP_FLOAT, "bevel_weight_vert"); const int cd_vert_crease_offset = CustomData_get_offset(&bm->vdata, CD_CREASE); const int cd_vert_skin_offset = CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN); - const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); + const int cd_edge_bweight_offset = CustomData_get_offset_named( + &bm->edata, CD_PROP_FLOAT, "bevel_weight_edge"); const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE); has_skinradius = (cd_vert_skin_offset != -1); @@ -997,10 +999,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float if (apply_vcos || median->bv_weight || median->v_crease || median->skin[0] || median->skin[1]) { if (median->bv_weight) { - if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) { - BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT); + if (!CustomData_has_layer_named(&bm->vdata, CD_PROP_FLOAT, "bevel_weight_vert")) { + BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_FLOAT, "bevel_weight_vert"); } - cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); + cd_vert_bweight_offset = CustomData_get_offset_named( + &bm->vdata, CD_PROP_FLOAT, "bevel_weight_vert"); BLI_assert(cd_vert_bweight_offset != -1); scale_bv_weight = compute_scale_factor(ve_median->bv_weight, median->bv_weight); @@ -1067,10 +1070,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float if (median->be_weight || median->e_crease) { if (median->be_weight) { - if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) { - BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT); + if (!CustomData_has_layer_named(&bm->edata, CD_PROP_FLOAT, "bevel_weight_edge")) { + BM_data_layer_add_named(bm, &bm->edata, CD_PROP_FLOAT, "bevel_weight_edge"); } - cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT); + cd_edge_bweight_offset = CustomData_get_offset_named( + &bm->edata, CD_PROP_FLOAT, "bevel_weight_edge"); BLI_assert(cd_edge_bweight_offset != -1); scale_be_weight = compute_scale_factor(ve_median->be_weight, median->be_weight); diff --git a/source/blender/editors/space_view3d/view3d_draw.cc b/source/blender/editors/space_view3d/view3d_draw.cc index 8d5f6cb200d..77c6c238edf 100644 --- a/source/blender/editors/space_view3d/view3d_draw.cc +++ b/source/blender/editors/space_view3d/view3d_draw.cc @@ -1973,7 +1973,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph, * When using workbench the color differences haven't been reported as a bug. But users also use * the viewport rendering to render Eevee scenes. In the later situation the saved colors are * totally wrong. */ - const bool do_color_management = (ibuf->rect_float == nullptr); + const bool do_color_management = (ibuf->float_buffer.data == nullptr); ED_view3d_draw_offscreen(depsgraph, scene, drawtype, @@ -1991,11 +1991,11 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph, ofs, nullptr); - if (ibuf->rect_float) { - GPU_offscreen_read_color(ofs, GPU_DATA_FLOAT, ibuf->rect_float); + if (ibuf->float_buffer.data) { + GPU_offscreen_read_color(ofs, GPU_DATA_FLOAT, ibuf->float_buffer.data); } - else if (ibuf->rect) { - GPU_offscreen_read_color(ofs, GPU_DATA_UBYTE, ibuf->rect); + else if (ibuf->byte_buffer.data) { + GPU_offscreen_read_color(ofs, GPU_DATA_UBYTE, ibuf->byte_buffer.data); } /* unbind */ @@ -2011,7 +2011,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph, GPU_framebuffer_bind(old_fb); } - if (ibuf->rect_float && ibuf->rect) { + if (ibuf->float_buffer.data && ibuf->byte_buffer.data) { IMB_rect_from_float(ibuf); } diff --git a/source/blender/editors/space_view3d/view3d_navigate.cc b/source/blender/editors/space_view3d/view3d_navigate.cc index c57c6b9bb2a..bcb2bea1aab 100644 --- a/source/blender/editors/space_view3d/view3d_navigate.cc +++ b/source/blender/editors/space_view3d/view3d_navigate.cc @@ -74,6 +74,8 @@ const char *viewops_operator_idname_get(eV3D_OpMode nav_type) case V3D_OP_MODE_NDOF_ORBIT_ZOOM: return "VIEW3D_OT_ndof_orbit_zoom"; #endif + case V3D_OP_MODE_NONE: + break; } BLI_assert(false); return nullptr; @@ -1942,3 +1944,142 @@ void VIEW3D_OT_view_pan(wmOperatorType *ot) } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Navigation Utilities + * \{ */ + +/* Detect the navigation operation, by the name of the navigation operator (obtained by + * `wmKeyMapItem::idname`) */ +static eV3D_OpMode view3d_navigation_type_from_idname(const char *idname) +{ + const char *op_name = idname + sizeof("VIEW3D_OT_"); + for (int i = 0; i < V3D_OP_MODE_LEN; i++) { + if (STREQ(op_name, viewops_operator_idname_get((eV3D_OpMode)i) + sizeof("VIEW3D_OT_"))) { + return (eV3D_OpMode)i; + } + } + return V3D_OP_MODE_NONE; +} + +/* Unlike `viewops_data_create`, `ED_view3d_navigation_init` creates a navigation context along + * with an array of `wmKeyMapItem`s used for navigation. */ +ViewOpsData *ED_view3d_navigation_init(bContext *C) +{ + if (!CTX_wm_region_view3d(C)) { + return NULL; + } + + ViewOpsData *vod = MEM_cnew(__func__); + viewops_data_init_context(C, vod); + + vod->keymap = WM_keymap_find_all(CTX_wm_manager(C), "3D View", SPACE_VIEW3D, 0); + return vod; +} + +/* Checks and initializes the navigation modal operation. */ +static int view3d_navigation_invoke(bContext *C, + ViewOpsData *vod, + const wmEvent *event, + struct wmKeyMapItem *kmi, + eV3D_OpMode nav_type) +{ + switch (nav_type) { + case V3D_OP_MODE_ZOOM: + if (!view3d_zoom_or_dolly_poll(C)) { + return OPERATOR_CANCELLED; + } + break; + case V3D_OP_MODE_MOVE: + case V3D_OP_MODE_VIEW_PAN: + if (!view3d_location_poll(C)) { + return OPERATOR_CANCELLED; + } + break; + case V3D_OP_MODE_ROTATE: + if (!view3d_rotation_poll(C)) { + return OPERATOR_CANCELLED; + } + break; + case V3D_OP_MODE_VIEW_ROLL: + case V3D_OP_MODE_DOLLY: +#ifdef WITH_INPUT_NDOF + case V3D_OP_MODE_NDOF_ORBIT: + case V3D_OP_MODE_NDOF_ORBIT_ZOOM: +#endif + case V3D_OP_MODE_NONE: + break; + } + + return view3d_navigation_invoke_generic(C, vod, event, kmi->ptr, nav_type); +} + +bool ED_view3d_navigation_do(bContext *C, ViewOpsData *vod, const wmEvent *event) +{ + if (!vod) { + return false; + } + + wmEvent event_tmp; + if (event->type == EVT_MODAL_MAP) { + /* Workaround to use the original event values. */ + event_tmp = *event; + event_tmp.type = event->prev_type; + event_tmp.val = event->prev_val; + event = &event_tmp; + } + + int op_return = OPERATOR_CANCELLED; + + if (vod->is_modal_event) { + const eV3D_OpEvent event_code = view3d_navigate_event(vod, event); + op_return = view3d_navigation_modal(C, vod, event_code, event->xy); + if (op_return != OPERATOR_RUNNING_MODAL) { + viewops_data_end_navigation(C, vod); + vod->is_modal_event = false; + } + } + else { + eV3D_OpMode nav_type; + LISTBASE_FOREACH (wmKeyMapItem *, kmi, &vod->keymap->items) { + if (!STRPREFIX(kmi->idname, "VIEW3D")) { + continue; + } + if (kmi->flag & KMI_INACTIVE) { + continue; + } + if ((nav_type = view3d_navigation_type_from_idname(kmi->idname)) == V3D_OP_MODE_NONE) { + continue; + } + if (!WM_event_match(event, kmi)) { + continue; + } + + op_return = view3d_navigation_invoke(C, vod, event, kmi, nav_type); + if (op_return == OPERATOR_RUNNING_MODAL) { + vod->is_modal_event = true; + } + else { + viewops_data_end_navigation(C, vod); + } + break; + } + } + + if (op_return != OPERATOR_CANCELLED) { + /* Although #ED_view3d_update_viewmat is already called when redrawing the 3D View, do it here + * as well, so the updated matrix values can be accessed by the operator. */ + ED_view3d_update_viewmat( + vod->depsgraph, vod->scene, vod->v3d, vod->region, NULL, NULL, NULL, false); + + return true; + } + return false; +} + +void ED_view3d_navigation_free(bContext *C, ViewOpsData *vod) +{ + viewops_data_free(C, vod); +} + +/** \} */ diff --git a/source/blender/editors/space_view3d/view3d_navigate.h b/source/blender/editors/space_view3d/view3d_navigate.h index 21de7bbc92e..cd4313bdb4c 100644 --- a/source/blender/editors/space_view3d/view3d_navigate.h +++ b/source/blender/editors/space_view3d/view3d_navigate.h @@ -33,6 +33,7 @@ struct wmEvent; struct wmOperator; typedef enum eV3D_OpMode { + V3D_OP_MODE_NONE = -1, V3D_OP_MODE_ZOOM = 0, V3D_OP_MODE_ROTATE, V3D_OP_MODE_MOVE, @@ -44,6 +45,11 @@ typedef enum eV3D_OpMode { V3D_OP_MODE_NDOF_ORBIT_ZOOM, #endif } eV3D_OpMode; +#ifndef WITH_INPUT_NDOF +# define V3D_OP_MODE_LEN V3D_OP_MODE_DOLLY + 1 +#else +# define V3D_OP_MODE_LEN V3D_OP_MODE_NDOF_ORBIT_ZOOM + 1 +#endif enum eV3D_OpPropFlag { V3D_OP_PROP_MOUSE_CO = (1 << 0), @@ -179,6 +185,10 @@ typedef struct ViewOpsData { * See #view3d_orbit_apply_dyn_ofs code-comments for an example, also see: #104385. */ bool use_dyn_ofs_ortho_correction; + + /** Used for navigation on non view3d operators. */ + wmKeyMap *keymap; + bool is_modal_event; } ViewOpsData; /* view3d_navigate.cc */ diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c index 4a06f78b427..24f453ca583 100644 --- a/source/blender/editors/space_view3d/view3d_utils.c +++ b/source/blender/editors/space_view3d/view3d_utils.c @@ -891,7 +891,7 @@ static void view3d_boxview_sync_axis(RegionView3D *rv3d_dst, RegionView3D *rv3d_ mul_qt_v3(viewinv, view_dst_x); mul_qt_v3(viewinv, view_dst_y); - /* check source and dest have a matching axis */ + /* Check source and destination have a matching axis. */ for (i = 0; i < 3; i++) { if (((fabsf(view_src_x[i]) > axis_eps) || (fabsf(view_src_y[i]) > axis_eps)) && ((fabsf(view_dst_x[i]) > axis_eps) || (fabsf(view_dst_y[i]) > axis_eps))) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 73938f1d959..0b3b213b0a9 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -92,9 +92,6 @@ void setTransformViewMatrices(TransInfo *t) unit_m4(t->persinv); t->persp = RV3D_ORTHO; } - - calculateCenter2D(t); - calculateCenterLocal(t, t->center_global); } void setTransformViewAspect(TransInfo *t, float r_aspect[3]) @@ -926,15 +923,17 @@ static bool transform_event_modal_constraint(TransInfo *t, short modal_type) int transformEvent(TransInfo *t, const wmEvent *event) { bool handled = false; + bool is_navigating = t->vod ? ((RegionView3D *)t->region->regiondata)->rflag & RV3D_NAVIGATING : + false; /* Handle modal numinput events first, if already activated. */ - if (((event->val == KM_PRESS) || (event->type == EVT_MODAL_MAP)) && hasNumInput(&t->num) && - handleNumInput(t->context, &(t->num), event)) + if (!is_navigating && ((event->val == KM_PRESS) || (event->type == EVT_MODAL_MAP)) && + hasNumInput(&t->num) && handleNumInput(t->context, &(t->num), event)) { t->redraw |= TREDRAW_HARD; handled = true; } - else if (event->type == MOUSEMOVE) { + else if (!is_navigating && event->type == MOUSEMOVE) { copy_v2_v2_int(t->mval, event->mval); /* Use this for soft redraw. Might cause flicker in object mode */ diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index fcca03b981e..c49e8338e12 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -41,6 +41,7 @@ struct TransDataContainer; struct TransInfo; struct TransSnap; struct ViewLayer; +struct ViewOpsData; struct bContext; struct wmEvent; struct wmKeyConfig; @@ -673,6 +674,8 @@ typedef struct TransInfo { /** Currently only used for random curve of proportional editing. */ struct RNG *rng; + struct ViewOpsData *vod; + /** Typically for mode settings. */ TransCustomDataContainer custom; diff --git a/source/blender/editors/transform/transform_convert_mesh_edge.c b/source/blender/editors/transform/transform_convert_mesh_edge.c index 6ad5c260b85..6de532a3d6e 100644 --- a/source/blender/editors/transform/transform_convert_mesh_edge.c +++ b/source/blender/editors/transform/transform_convert_mesh_edge.c @@ -67,10 +67,11 @@ static void createTransEdge(bContext *UNUSED(C), TransInfo *t) /* create data we need */ if (t->mode == TFM_BWEIGHT) { - if (!CustomData_has_layer(&em->bm->edata, CD_BWEIGHT)) { - BM_data_layer_add(em->bm, &em->bm->edata, CD_BWEIGHT); + if (!CustomData_has_layer_named(&em->bm->edata, CD_PROP_FLOAT, "bevel_weight_edge")) { + BM_data_layer_add_named(em->bm, &em->bm->edata, CD_PROP_FLOAT, "bevel_weight_edge"); } - cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT); + cd_edge_float_offset = CustomData_get_offset_named( + &em->bm->edata, CD_PROP_FLOAT, "bevel_weight_edge"); } else { /* if (t->mode == TFM_EDGE_CREASE) { */ BLI_assert(t->mode == TFM_EDGE_CREASE); diff --git a/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c b/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c index f1428bdfebc..5123b906e54 100644 --- a/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c +++ b/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c @@ -28,7 +28,7 @@ #include "transform_convert.h" /* -------------------------------------------------------------------- */ -/** \name Edit Mesh #CD_BWEIGHT and #CD_CREASE Transform Creation +/** \name Edit Mesh Bevel Weight and #CD_CREASE Transform Creation * \{ */ static float *tc_mesh_cdata_transdata_center(const struct TransIslandData *island_data, @@ -85,10 +85,10 @@ static void createTransMeshVertCData(bContext *UNUSED(C), TransInfo *t) int cd_offset = -1; if (t->mode == TFM_BWEIGHT) { - if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) { - BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT); + if (!CustomData_has_layer_named(&bm->vdata, CD_PROP_FLOAT, "bevel_weight_vert")) { + BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_FLOAT, "bevel_weight_vert"); } - cd_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); + cd_offset = CustomData_get_offset_named(&bm->vdata, CD_PROP_FLOAT, "bevel_weight_vert"); } else { if (!CustomData_has_layer(&bm->vdata, CD_CREASE)) { diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 70806896743..4873b455fe4 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -660,7 +660,16 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve t->flag |= T_NO_CURSOR_WRAP; } + if (op && (t->flag & T_MODAL) && !(t->flag & T_RELEASE_CONFIRM) && + (prop = RNA_struct_find_property(op->ptr, "allow_navigation")) && + RNA_property_boolean_get(op->ptr, prop)) + { + t->vod = ED_view3d_navigation_init(C); + } + setTransformViewMatrices(t); + calculateCenter2D(t); + calculateCenterLocal(t, t->center_global); initNumInput(&t->num); transform_gizmo_3d_model_from_constraint_and_mode_init(t); @@ -770,6 +779,10 @@ void postTrans(bContext *C, TransInfo *t) } freeSnapping(t); + + if (t->vod) { + ED_view3d_navigation_free(C, t->vod); + } } void applyTransObjects(TransInfo *t) diff --git a/source/blender/editors/transform/transform_gizmo_3d.cc b/source/blender/editors/transform/transform_gizmo_3d.cc index 8b5780ab91b..726704fb3db 100644 --- a/source/blender/editors/transform/transform_gizmo_3d.cc +++ b/source/blender/editors/transform/transform_gizmo_3d.cc @@ -474,6 +474,23 @@ static void protectflag_to_drawflags(short protectflag, short *drawflags) } } +/* Similar to #transform_object_deform_pose_armature_get but does not check visibility. */ +static Object *gizmo_3d_transform_space_object_get(Scene *scene, ViewLayer *view_layer) +{ + BKE_view_layer_synced_ensure(scene, view_layer); + Object *ob = BKE_view_layer_active_object_get(view_layer); + if (ob && ob->mode & OB_MODE_WEIGHT_PAINT) { + /* It is assumed that when the object is in Weight Paint mode, it is not in Edit mode. So we + * don't need to check the #OB_MODE_EDIT flag. */ + BLI_assert(!(ob->mode & OB_MODE_EDIT)); + Object *obpose = BKE_object_pose_armature_get(ob); + if (obpose != nullptr) { + ob = obpose; + } + } + return ob; +} + /** * Run \a user_fn for each coordinate of elements selected in View3D (vertices, particles...). * \note Each coordinate has the space matrix of the active object. @@ -519,15 +536,7 @@ static int gizmo_3d_foreach_selected(const bContext *C, const bool is_curve_edit = GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd); int a, totsel = 0; - BKE_view_layer_synced_ensure(scene, view_layer); - Object *ob = BKE_view_layer_active_object_get(view_layer); - Object *obedit = OBEDIT_FROM_OBACT(ob); - if (ob && ob->mode & OB_MODE_WEIGHT_PAINT) { - Object *obpose = BKE_object_pose_armature_get(ob); - if (obpose != nullptr) { - ob = obpose; - } - } + Object *ob = gizmo_3d_transform_space_object_get(scene, view_layer); if (is_gp_edit) { float diff_mat[4][4]; @@ -586,7 +595,7 @@ static int gizmo_3d_foreach_selected(const bContext *C, } } } - else if (obedit) { + else if (Object *obedit = OBEDIT_FROM_OBACT(ob)) { #define FOREACH_EDIT_OBJECT_BEGIN(ob_iter, use_mat_local) \ { \ @@ -937,15 +946,8 @@ int ED_transform_calc_gizmo_stats(const bContext *C, (params->orientation_index - 1) : BKE_scene_orientation_get_index(scene, SCE_ORIENT_DEFAULT); - BKE_view_layer_synced_ensure(scene, view_layer); - Object *ob = BKE_view_layer_active_object_get(view_layer); + Object *ob = gizmo_3d_transform_space_object_get(scene, view_layer); Object *obedit = OBEDIT_FROM_OBACT(ob); - if (ob && ob->mode & OB_MODE_WEIGHT_PAINT) { - Object *obpose = BKE_object_pose_armature_get(ob); - if (obpose != nullptr) { - ob = obpose; - } - } tbounds->use_matrix_space = false; unit_m3(tbounds->axis); @@ -972,7 +974,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, copy_m3_m4(diff_mat, ob->object_to_world); normalize_m3(diff_mat); invert_m3(diff_mat); - mul_m3_m3m3(tbounds->axis, tbounds->axis, diff_mat); + mul_m3_m3_pre(tbounds->axis, diff_mat); normalize_m3(tbounds->axis); tbounds->use_matrix_space = true; @@ -997,7 +999,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C, bGPdata *gpd = CTX_data_gpencil_data(C); const bool is_gp_edit = GPENCIL_ANY_MODE(gpd); if (!is_gp_edit && (obedit || (ob && (ob->mode & (OB_MODE_POSE | OB_MODE_SCULPT))))) { - if (ob && (ob->mode & OB_MODE_POSE)) { + if (ob->mode & OB_MODE_POSE) { invert_m4_m4(ob->world_to_object, ob->object_to_world); } mul_m4_v3(ob->object_to_world, tbounds->center); diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 12e9a99a323..b501649a614 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -399,7 +399,7 @@ static int transformops_data(bContext *C, wmOperator *op, const wmEvent *event) static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event) { - int exit_code; + int exit_code = OPERATOR_PASS_THROUGH; TransInfo *t = op->customdata; const eTfmMode mode_prev = t->mode; @@ -419,6 +419,31 @@ static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event) exit_code = transformEvent(t, event); t->context = NULL; + /* Allow navigation while transforming. */ + if (t->vod && (exit_code & OPERATOR_PASS_THROUGH) && ED_view3d_navigation_do(C, t->vod, event)) { + RegionView3D *rv3d = t->region->regiondata; + if (rv3d->rflag & RV3D_NAVIGATING) { + /* Do not update transform while navigating. This can be distracting. */ + return OPERATOR_RUNNING_MODAL; + } + + if (t->modifiers & MOD_PRECISION) { + /* Remove Precision modifier, it may have be unintentionally enabled. */ + t->modifiers &= ~MOD_PRECISION; + t->mouse.precision = 0; + } + + /* Make sure `t->mval` is up to date before calling #transformViewUpdate. */ + copy_v2_v2_int(t->mval, event->mval); + + /* Call before #applyMouseInput. */ + tranformViewUpdate(t); + + /* Mouse input is outdated. */ + applyMouseInput(t, &t->mouse, t->mval, t->values); + t->redraw |= TREDRAW_HARD; + } + transformApply(C, t); exit_code |= transformEnd(C, t); @@ -752,6 +777,15 @@ void Transform_Properties(struct wmOperatorType *ot, int flags) RNA_def_property_flag(prop, PROP_HIDDEN); } + if (flags & P_VIEW3D_NAVIGATION) { + prop = RNA_def_boolean(ot->srna, + "allow_navigation", + 0, + "Allow Navigation", + "Allow navigation while transforming"); + RNA_def_property_flag(prop, PROP_HIDDEN); + } + if (flags & P_POST_TRANSFORM) { prop = RNA_def_boolean(ot->srna, "use_automerge_and_split", @@ -786,7 +820,7 @@ static void TRANSFORM_OT_translate(struct wmOperatorType *ot) Transform_Properties(ot, P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_ALIGN_SNAP | P_OPTIONS | P_GPENCIL_EDIT | P_CURSOR_EDIT | P_VIEW2D_EDGE_PAN | - P_POST_TRANSFORM); + P_VIEW3D_NAVIGATION | P_POST_TRANSFORM); } static void TRANSFORM_OT_resize(struct wmOperatorType *ot) @@ -825,7 +859,7 @@ static void TRANSFORM_OT_resize(struct wmOperatorType *ot) Transform_Properties(ot, P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP | - P_OPTIONS | P_GPENCIL_EDIT | P_CENTER); + P_OPTIONS | P_GPENCIL_EDIT | P_CENTER | P_VIEW3D_NAVIGATION); } static void TRANSFORM_OT_skin_resize(struct wmOperatorType *ot) @@ -902,7 +936,7 @@ static void TRANSFORM_OT_rotate(struct wmOperatorType *ot) Transform_Properties(ot, P_ORIENT_AXIS | P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | - P_GEO_SNAP | P_GPENCIL_EDIT | P_CENTER); + P_GEO_SNAP | P_GPENCIL_EDIT | P_CENTER | P_VIEW3D_NAVIGATION); } static void TRANSFORM_OT_tilt(struct wmOperatorType *ot) @@ -1147,7 +1181,7 @@ static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot) "When Even mode is active, flips between the two adjacent edge loops"); RNA_def_boolean(ot->srna, "use_clamp", true, "Clamp", "Clamp within the edge extents"); - Transform_Properties(ot, P_MIRROR | P_GEO_SNAP | P_CORRECT_UV); + Transform_Properties(ot, P_MIRROR | P_GEO_SNAP | P_CORRECT_UV | P_VIEW3D_NAVIGATION); } static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot) @@ -1182,7 +1216,7 @@ static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot) "When Even mode is active, flips between the two adjacent edge loops"); RNA_def_boolean(ot->srna, "use_clamp", true, "Clamp", "Clamp within the edge extents"); - Transform_Properties(ot, P_MIRROR | P_GEO_SNAP | P_CORRECT_UV); + Transform_Properties(ot, P_MIRROR | P_GEO_SNAP | P_CORRECT_UV | P_VIEW3D_NAVIGATION); } static void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot) @@ -1330,7 +1364,7 @@ static void TRANSFORM_OT_transform(struct wmOperatorType *ot) Transform_Properties(ot, P_ORIENT_AXIS | P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | - P_ALIGN_SNAP | P_GPENCIL_EDIT | P_CENTER); + P_ALIGN_SNAP | P_GPENCIL_EDIT | P_CENTER | P_VIEW3D_NAVIGATION); } static int transform_from_gizmo_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) diff --git a/source/blender/editors/transform/transform_snap.cc b/source/blender/editors/transform/transform_snap.cc index a1fc4ba75f2..b4ace5773ce 100644 --- a/source/blender/editors/transform/transform_snap.cc +++ b/source/blender/editors/transform/transform_snap.cc @@ -715,6 +715,10 @@ static eSnapTargetOP snap_target_select_from_spacetype(TransInfo *t) /* Exclude editmesh when using proportional edit */ ret |= SCE_SNAP_TARGET_NOT_EDITED; } + /* UV editing must never snap to the selection as this is what is transformed. */ + if (t->spacetype == SPACE_IMAGE) { + ret |= SCE_SNAP_TARGET_NOT_SELECTED; + } } else if (ELEM(obedit_type, OB_ARMATURE, OB_CURVES_LEGACY, OB_SURF, OB_LATTICE, OB_MBALL)) { /* Temporary limited to edit mode armature, curves, surfaces, lattices, and metaballs. */ diff --git a/source/blender/editors/util/ed_util_imbuf.c b/source/blender/editors/util/ed_util_imbuf.c index 03ce5b00e0c..6dda715e915 100644 --- a/source/blender/editors/util/ed_util_imbuf.c +++ b/source/blender/editors/util/ed_util_imbuf.c @@ -79,7 +79,7 @@ static void image_sample_pixel_color_ubyte(const ImBuf *ibuf, uchar r_col[4], float r_col_linear[4]) { - const uchar *cp = (uchar *)(ibuf->rect + coord[1] * ibuf->x + coord[0]); + const uchar *cp = ibuf->byte_buffer.data + 4 * (coord[1] * ibuf->x + coord[0]); copy_v4_v4_uchar(r_col, cp); rgba_uchar_to_float(r_col_linear, r_col); IMB_colormanagement_colorspace_to_scene_linear_v4(r_col_linear, false, ibuf->rect_colorspace); @@ -87,7 +87,7 @@ static void image_sample_pixel_color_ubyte(const ImBuf *ibuf, static void image_sample_pixel_color_float(ImBuf *ibuf, const int coord[2], float r_col[4]) { - const float *cp = ibuf->rect_float + (ibuf->channels) * (coord[1] * ibuf->x + coord[0]); + const float *cp = ibuf->float_buffer.data + (ibuf->channels) * (coord[1] * ibuf->x + coord[0]); copy_v4_v4(r_col, cp); } @@ -198,7 +198,7 @@ static void image_sample_apply(bContext *C, wmOperator *op, const wmEvent *event sample_rect.xmax = min_ii(ibuf->x, sample_rect.xmin + info->sample_size) - 1; sample_rect.ymax = min_ii(ibuf->y, sample_rect.ymin + info->sample_size) - 1; - if (ibuf->rect) { + if (ibuf->byte_buffer.data) { image_sample_rect_color_ubyte(ibuf, &sample_rect, info->col, info->linearcol); rgba_uchar_to_float(info->colf, info->col); @@ -206,7 +206,7 @@ static void image_sample_apply(bContext *C, wmOperator *op, const wmEvent *event info->colfp = info->colf; info->color_manage = true; } - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { image_sample_rect_color_float(ibuf, &sample_rect, info->colf); if (ibuf->channels == 4) { @@ -227,19 +227,21 @@ static void image_sample_apply(bContext *C, wmOperator *op, const wmEvent *event info->color_manage = true; } - if (ibuf->zbuf) { + if (ibuf->z_buffer.data) { /* TODO: blend depth (not urgent). */ - info->z = ibuf->zbuf[y * ibuf->x + x]; + info->z = ibuf->z_buffer.data[y * ibuf->x + x]; info->zp = &info->z; - if (ibuf->zbuf == (int *)ibuf->rect) { + /* NOTE: Follows legacy code. Although it is unclear how z-buffer can be the same as a 4 + * channel RGBA 8bpp buffer. */ + if (ibuf->z_buffer.data == (int *)ibuf->byte_buffer.data) { info->colp = NULL; } } - if (ibuf->zbuf_float) { + if (ibuf->float_z_buffer.data) { /* TODO: blend depth (not urgent). */ - info->zf = ibuf->zbuf_float[y * ibuf->x + x]; + info->zf = ibuf->float_z_buffer.data[y * ibuf->x + x]; info->zfp = &info->zf; - if (ibuf->zbuf_float == ibuf->rect_float) { + if (ibuf->float_z_buffer.data == ibuf->float_buffer.data) { info->colfp = NULL; } } @@ -322,8 +324,8 @@ static void sequencer_sample_apply(bContext *C, wmOperator *op, const wmEvent *e info->colp = NULL; info->colfp = NULL; - if (ibuf->rect) { - cp = (uchar *)(ibuf->rect + y * ibuf->x + x); + if (ibuf->byte_buffer.data) { + cp = ibuf->byte_buffer.data + 4 * (y * ibuf->x + x); info->col[0] = cp[0]; info->col[1] = cp[1]; @@ -343,8 +345,8 @@ static void sequencer_sample_apply(bContext *C, wmOperator *op, const wmEvent *e info->color_manage = true; } - if (ibuf->rect_float) { - fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x)); + if (ibuf->float_buffer.data) { + fp = (ibuf->float_buffer.data + (ibuf->channels) * (y * ibuf->x + x)); info->colf[0] = fp[0]; info->colf[1] = fp[1]; diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c index bdd3149884c..16e2caffb58 100644 --- a/source/blender/editors/util/numinput.c +++ b/source/blender/editors/util/numinput.c @@ -506,7 +506,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event) if (event->modifier & KM_CTRL) { /* extract the first line from the clipboard */ int pbuf_len; - char *pbuf = WM_clipboard_text_get_firstline(false, &pbuf_len); + char *pbuf = WM_clipboard_text_get_firstline(false, true, &pbuf_len); if (pbuf) { const bool success = editstr_insert_at_cursor(n, pbuf, pbuf_len); diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.cc b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc index 8c8c30f5deb..d16e34593c6 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.cc +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc @@ -1441,7 +1441,7 @@ static void pack_islands_endjob(void *pidv) DEG_id_tag_update(static_cast(obedit->data), ID_RECALC_GEOMETRY); WM_main_add_notifier(NC_GEOM | ND_DATA, obedit->data); } - WM_main_add_notifier(NC_SPACE | ND_SPACE_IMAGE, NULL); + WM_main_add_notifier(NC_SPACE | ND_SPACE_IMAGE, nullptr); if (pid->undo_str) { ED_undo_push(pid->undo_context, pid->undo_str); diff --git a/source/blender/freestyle/intern/stroke/Canvas.cpp b/source/blender/freestyle/intern/stroke/Canvas.cpp index 829de562333..85711fdd4f0 100644 --- a/source/blender/freestyle/intern/stroke/Canvas.cpp +++ b/source/blender/freestyle/intern/stroke/Canvas.cpp @@ -376,11 +376,11 @@ void Canvas::loadMap(const char *iFileName, const char *iMapName, uint iNbLevels int h = qimg->y; int rowbytes = w * 4; GrayImage tmp(w, h); - char *pix; + uchar *pix; for (y = 0; y < h; ++y) { for (x = 0; x < w; ++x) { - pix = (char *)qimg->rect + y * rowbytes + x * 4; + pix = qimg->byte_buffer.data + y * rowbytes + x * 4; float c = (pix[0] * 11 + pix[1] * 16 + pix[2] * 5) / 32; tmp.setPixel(x, y, c); } @@ -417,7 +417,7 @@ void Canvas::loadMap(const char *iFileName, const char *iMapName, uint iNbLevels for (x = 0; x < ow; ++x) { int c = pyramid->pixel(x, y, i); // 255 * pyramid->pixel(x, y, i); // soc qtmp.setPixel(x, y, qRgb(c, c, c)); - pix = (char *)qtmp->rect + y * rowbytes + x * 4; + pix = qtmp->byte_buffer.data + y * rowbytes + x * 4; pix[0] = pix[1] = pix[2] = c; } } diff --git a/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp b/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp index 8e88b6c41f6..35b11a41d6a 100644 --- a/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp +++ b/source/blender/freestyle/intern/view_map/SteerableViewMap.cpp @@ -244,7 +244,7 @@ void SteerableViewMap::saveSteerableViewMap() const // soc QImage qtmp(ow, oh, QImage::Format_RGB32); ImBuf *ibuf = IMB_allocImBuf(ow, oh, 32, IB_rect); int rowbytes = ow * 4; - char *pix; + uchar *pix; for (int y = 0; y < oh; ++y) { // soc for (int x = 0; x < ow; ++x) { // soc @@ -255,7 +255,7 @@ void SteerableViewMap::saveSteerableViewMap() const // int c = (int)(_imagesPyramids[i]->pixel(x, y, j)); // soc qtmp.setPixel(x, y, qRgb(c, c, c)); - pix = (char *)ibuf->rect + y * rowbytes + x * 4; + pix = ibuf->byte_buffer.data + y * rowbytes + x * 4; pix[0] = pix[1] = pix[2] = c; } } diff --git a/source/blender/geometry/intern/mesh_split_edges.cc b/source/blender/geometry/intern/mesh_split_edges.cc index 9594ce346f2..1811191fb20 100644 --- a/source/blender/geometry/intern/mesh_split_edges.cc +++ b/source/blender/geometry/intern/mesh_split_edges.cc @@ -21,7 +21,6 @@ static inline bool naive_edges_equal(const int2 &edge1, const int2 &edge2) static void add_new_vertices(Mesh &mesh, const Span new_to_old_verts_map) { /* These types aren't supported for interpolation below. */ - CustomData_free_layers(&mesh.vdata, CD_BWEIGHT, mesh.totvert); CustomData_free_layers(&mesh.vdata, CD_SHAPEKEY, mesh.totvert); CustomData_free_layers(&mesh.vdata, CD_CLOTH_ORCO, mesh.totvert); CustomData_free_layers(&mesh.vdata, CD_MVERT_SKIN, mesh.totvert); diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index 334c3df094f..2238d851333 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -1158,7 +1158,7 @@ static void execute_realize_mesh_tasks(const RealizeInstancesOptions &options, material_indices.finish(); if (all_meshes_info.no_loose_edges_hint) { - dst_mesh->loose_edges_tag_none(); + dst_mesh->tag_loose_edges_none(); } if (all_meshes_info.no_loose_verts_hint) { dst_mesh->tag_loose_verts_none(); diff --git a/source/blender/geometry/intern/uv_pack.cc b/source/blender/geometry/intern/uv_pack.cc index 6a491deafea..992f07bcb8a 100644 --- a/source/blender/geometry/intern/uv_pack.cc +++ b/source/blender/geometry/intern/uv_pack.cc @@ -1150,12 +1150,12 @@ static bool rotate_inside_square(const Span island_indices, return false; /* Nothing to do. */ } - /* Transform phis. */ + /* Transform phis, rotate by best_angle, then translate back to the origin. No scale. */ for (const int64_t j : island_indices.index_range()) { const int64_t i = island_indices[j]->index; const PackIsland *island = islands[i]; - const float island_scale = island->can_scale_(params) ? scale : 1.0f; - island->build_transformation(island_scale, square_finder.best_angle, matrix); + const float identity_scale = 1.0f; /* Don't rescale the placement, just rotate. */ + island->build_transformation(identity_scale, square_finder.best_angle, matrix); r_phis[i].rotation += square_finder.best_angle; mul_m2_v2(matrix, r_phis[i].translation); r_phis[i].translation.x -= square_finder.best_bounds.xmin; @@ -1777,17 +1777,25 @@ class OverlapMerger { sub_params.merge_overlap = false; const float result = pack_islands(sub_islands, sub_params); - /* Must loop backwards! */ + /* Must loop backwards, or we will miss sub-sub-islands. */ for (int64_t i = merge_trace.size() - 3; i >= 0; i -= 3) { PackIsland *sub_a = merge_trace[i]; PackIsland *sub_b = merge_trace[i + 1]; PackIsland *merge = merge_trace[i + 2]; + + /* Copy `angle`, `pre_translate` and `pre_rotate` from merged island to sub islands. */ sub_a->angle = merge->angle; sub_b->angle = merge->angle; sub_a->pre_translate = merge->pre_translate; sub_b->pre_translate = merge->pre_translate; sub_a->pre_rotate_ = merge->pre_rotate_; sub_b->pre_rotate_ = merge->pre_rotate_; + + /* If the merged island is pinned, the sub-islands are also pinned to correct scaling. */ + if (merge->pinned) { + sub_a->pinned = true; + sub_b->pinned = true; + } delete merge; } @@ -1823,8 +1831,24 @@ float pack_islands(const Span &islands, const UVPackIsland_Params finalize_geometry(islands, params); + /* Count the number of islands which can scale and which can translate. */ + int64_t can_scale_count = 0; + int64_t can_translate_count = 0; + for (const int64_t i : islands.index_range()) { + if (islands[i]->can_scale_(params)) { + can_scale_count++; + } + if (islands[i]->can_translate_(params)) { + can_translate_count++; + } + } + + if (can_translate_count == 0) { + return 1.0f; /* Nothing to do, all islands are locked. */ + } + if (params.margin_method == ED_UVPACK_MARGIN_FRACTION && params.margin > 0.0f && - params.scale_to_fit) + can_scale_count > 0) { /* Uses a line search on scale. ~10x slower than other method. */ return pack_islands_margin_fraction(islands, params.margin, false, params); @@ -1837,28 +1861,24 @@ float pack_islands(const Span &islands, const UVPackIsland_Params case ED_UVPACK_MARGIN_SCALED: /* Default for Blender 3.3 and later. */ margin = calc_margin_from_aabb_length_sum(islands, params); break; - case ED_UVPACK_MARGIN_FRACTION: /* Added as an option in Blender 3.4. */ - BLI_assert(params.margin == 0.0f); /* Other (slower) cases are handled above. */ + case ED_UVPACK_MARGIN_FRACTION: /* Added as an option in Blender 3.4. */ + /* Most other cases are handled above, unless pinning is involved. */ break; default: BLI_assert_unreachable(); } - /* TODO: Only line-search if *some* islands can scale and *some* are locked. */ - switch (params.pin_method) { - case ED_UVPACK_PIN_LOCK_ALL: - case ED_UVPACK_PIN_LOCK_SCALE: - case ED_UVPACK_PIN_LOCK_ROTATION_SCALE: - return pack_islands_margin_fraction(islands, margin, true, params); - default: - break; + if (can_scale_count > 0 && can_scale_count != islands.size()) { + /* Search for the best scale parameter. (slow) */ + return pack_islands_margin_fraction(islands, margin, true, params); } + /* Either all of the islands can scale, or none of them can. + * In either case, we pack them all tight to the origin. */ blender::Array phis(islands.size()); - const float scale = 1.0f; const float max_uv = pack_islands_scale_margin(islands, scale, margin, params, phis); - const float result = params.scale_to_fit ? 1.0f / max_uv : 1.0f; + const float result = can_scale_count > 0 ? 1.0f / max_uv : 1.0f; for (const int64_t i : islands.index_range()) { BLI_assert(result == 1.0f || islands[i]->can_scale_(params)); islands[i]->place_(scale, phis[i]); diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 04aa8aaea90..ebbb267f63f 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -464,7 +464,6 @@ set(GLSL_SRC shaders/material/gpu_shader_material_add_shader.glsl shaders/material/gpu_shader_material_ambient_occlusion.glsl - shaders/material/gpu_shader_material_anisotropic.glsl shaders/material/gpu_shader_material_attribute.glsl shaders/material/gpu_shader_material_background.glsl shaders/material/gpu_shader_material_bevel.glsl diff --git a/source/blender/gpu/GPU_debug.h b/source/blender/gpu/GPU_debug.h index 60d0440e4ec..2487026ce46 100644 --- a/source/blender/gpu/GPU_debug.h +++ b/source/blender/gpu/GPU_debug.h @@ -87,7 +87,7 @@ void *GPU_debug_capture_scope_create(const char *name); /** * Used to declare the region within which GPU calls are captured when the scope is triggered. * - * \param scope Pointer to capture scope object created with GPU_debug_capture_scope_create. + * \param scope: Pointer to capture scope object created with GPU_debug_capture_scope_create. * \return True if the capture tool is actively capturing this scope when function is executed. * Otherwise, False. */ diff --git a/source/blender/gpu/intern/gpu_texture.cc b/source/blender/gpu/intern/gpu_texture.cc index 35aab01be06..62ff6c2a0c6 100644 --- a/source/blender/gpu/intern/gpu_texture.cc +++ b/source/blender/gpu/intern/gpu_texture.cc @@ -178,6 +178,9 @@ bool Texture::init_view(GPUTexture *src_, void Texture::usage_set(eGPUTextureUsage usage_flags) { gpu_image_usage_flags_ = usage_flags; + /* Metal: Texture clearing is done using frame-buffer clear. This has no performance impact. */ + /* TODO(fclem): Move this to metal backend instead to avoid side effects in other back-ends. */ + gpu_image_usage_flags_ |= GPU_TEXTURE_USAGE_ATTACHMENT; } /** \} */ diff --git a/source/blender/gpu/metal/mtl_shader.mm b/source/blender/gpu/metal/mtl_shader.mm index 94c3ef22a5d..b96de86da64 100644 --- a/source/blender/gpu/metal/mtl_shader.mm +++ b/source/blender/gpu/metal/mtl_shader.mm @@ -1390,9 +1390,15 @@ bool MTLShader::bake_compute_pipeline_state(MTLContext *ctx) } /* Compile PSO. */ + MTLComputePipelineDescriptor *desc = [[MTLComputePipelineDescriptor alloc] init]; + desc.maxTotalThreadsPerThreadgroup = 1024; + desc.computeFunction = compute_function; + id pso = [ctx->device - newComputePipelineStateWithFunction:compute_function - error:&error]; + newComputePipelineStateWithDescriptor:desc + options:MTLPipelineOptionNone + reflection:nullptr + error:&error]; if (error) { NSLog(@"Failed to create PSO for compute shader: %s error %@\n", this->name, error); diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_anisotropic.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_anisotropic.glsl deleted file mode 100644 index 77de9e096a6..00000000000 --- a/source/blender/gpu/shaders/material/gpu_shader_material_anisotropic.glsl +++ /dev/null @@ -1,27 +0,0 @@ - -void node_bsdf_anisotropic(vec4 color, - float roughness, - float anisotropy, - float rotation, - vec3 N, - vec3 T, - float weight, - const float do_multiscatter, - out Closure result) -{ - N = safe_normalize(N); - vec3 V = cameraVec(g_data.P); - float NV = dot(N, V); - - vec2 split_sum = brdf_lut(NV, roughness); - - ClosureReflection reflection_data; - reflection_data.weight = weight; - reflection_data.color = (do_multiscatter != 0.0) ? - F_brdf_multi_scatter(color.rgb, color.rgb, split_sum) : - F_brdf_single_scatter(color.rgb, color.rgb, split_sum); - reflection_data.N = N; - reflection_data.roughness = roughness; - - result = closure_eval(reflection_data); -} diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl index 2e48ddd1c5e..15c1c515c0f 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl @@ -1,6 +1,13 @@ -void node_bsdf_glossy( - vec4 color, float roughness, vec3 N, float weight, float do_multiscatter, out Closure result) +void node_bsdf_glossy(vec4 color, + float roughness, + float anisotropy, + float rotation, + vec3 N, + vec3 T, + float weight, + const float do_multiscatter, + out Closure result) { N = safe_normalize(N); vec3 V = cameraVec(g_data.P); diff --git a/source/blender/gpu/vulkan/vk_context.cc b/source/blender/gpu/vulkan/vk_context.cc index 234ca47adf9..a167fa2402c 100644 --- a/source/blender/gpu/vulkan/vk_context.cc +++ b/source/blender/gpu/vulkan/vk_context.cc @@ -142,7 +142,7 @@ VKStateManager &VKContext::state_manager_get() /** \} */ /* -------------------------------------------------------------------- */ -/** \name Framebuffer +/** \name Frame-buffer * \{ */ void VKContext::activate_framebuffer(VKFrameBuffer &framebuffer) diff --git a/source/blender/gpu/vulkan/vk_framebuffer.hh b/source/blender/gpu/vulkan/vk_framebuffer.hh index e8fcbce657c..a3fa5a088e0 100644 --- a/source/blender/gpu/vulkan/vk_framebuffer.hh +++ b/source/blender/gpu/vulkan/vk_framebuffer.hh @@ -33,9 +33,9 @@ class VKFrameBuffer : public FrameBuffer { /** * Should we flip the viewport to match Blenders coordinate system. We flip the viewport for - * offscreen framebuffers. + * off-screen frame-buffers. * - * When two framebuffers are blitted we also check if the coordinate system should be flipped + * When two frame-buffers are blitted we also check if the coordinate system should be flipped * during blitting. */ bool flip_viewport_ = false; diff --git a/source/blender/gpu/vulkan/vk_pipeline.cc b/source/blender/gpu/vulkan/vk_pipeline.cc index 0fcb543ab95..5eabab52582 100644 --- a/source/blender/gpu/vulkan/vk_pipeline.cc +++ b/source/blender/gpu/vulkan/vk_pipeline.cc @@ -169,7 +169,7 @@ void VKPipeline::finalize(VKContext &context, viewport_state.scissorCount = 1; pipeline_create_info.pViewportState = &viewport_state; - /* Multisample state. */ + /* Multi-sample state. */ VkPipelineMultisampleStateCreateInfo multisample_state = {}; multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; diff --git a/source/blender/gpu/vulkan/vk_pipeline_state.cc b/source/blender/gpu/vulkan/vk_pipeline_state.cc index e4d78eee17c..01c6eaaf117 100644 --- a/source/blender/gpu/vulkan/vk_pipeline_state.cc +++ b/source/blender/gpu/vulkan/vk_pipeline_state.cc @@ -20,7 +20,7 @@ VKPipelineStateManager::VKPipelineStateManager() depth_stencil_state = {}; depth_stencil_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; - /* TODO should be extracted from current framebuffer and should not be done here and now. */ + /* TODO should be extracted from current frame-buffer and should not be done here and now. */ /* When the attachments differ the state should be forced. */ VkPipelineColorBlendAttachmentState color_blend_attachment = {}; color_blend_attachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | @@ -364,4 +364,4 @@ void VKPipelineStateManager::set_shadow_bias(const bool enable) } } -} // namespace blender::gpu \ No newline at end of file +} // namespace blender::gpu diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index 256bd93669d..272293f4198 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -43,6 +43,8 @@ #include "../blenlib/BLI_sys_types.h" #include "../gpu/GPU_texture.h" +#include "IMB_imbuf_types.h" + #ifdef __cplusplus extern "C" { #endif @@ -130,19 +132,43 @@ bool IMB_initImBuf( * (transferring ownership to the in imbuf). * \attention Defined in allocimbuf.c */ -struct ImBuf *IMB_allocFromBufferOwn( - unsigned int *rect, float *rectf, unsigned int w, unsigned int h, unsigned int channels); +struct ImBuf *IMB_allocFromBufferOwn(uint8_t *byte_buffer, + float *float_buffer, + unsigned int w, + unsigned int h, + unsigned int channels); /** * Create a copy of a pixel buffer and wrap it to a new ImBuf * \attention Defined in allocimbuf.c */ -struct ImBuf *IMB_allocFromBuffer(const unsigned int *rect, - const float *rectf, +struct ImBuf *IMB_allocFromBuffer(const uint8_t *byte_buffer, + const float *float_buffer, unsigned int w, unsigned int h, unsigned int channels); +/* Assign the content of the corresponding buffer with the given data and ownership. + * The current content of the buffer is released corresponding to its ownership configuration. + * + * NOTE: Does not modify the the topology (width, height, number of channels) or the mipmaps in any + * way. */ +void IMB_assign_byte_buffer(struct ImBuf *ibuf, uint8_t *buffer_data, ImBufOwnership ownership); +void IMB_assign_float_buffer(struct ImBuf *ibuf, float *buffer_data, ImBufOwnership ownership); +void IMB_assign_z_buffer(struct ImBuf *ibuf, int *buffer_data, ImBufOwnership ownership); +void IMB_assign_float_z_buffer(struct ImBuf *ibuf, float *buffer_data, ImBufOwnership ownership); + +/* Make corresponding buffers available for modification. + * Is achieved by ensuring that the given ImBuf is the only owner of the underlying buffer data. */ +void IMB_make_writable_byte_buffer(struct ImBuf *ibuf); +void IMB_make_writable_float_buffer(struct ImBuf *ibuf); + +/* Steal the buffer data pointer: the ImBuf is no longer an owner of this data. + * NOTE: If the ImBuf does not own the data the behavior is undefined. */ +uint8_t *IMB_steal_byte_buffer(struct ImBuf *ibuf); +float *IMB_steal_float_buffer(struct ImBuf *ibuf); +uint8_t *IMB_steal_encoded_buffer(struct ImBuf *ibuf); + /** * Increase reference count to imbuf * (to delete an imbuf you have to call freeImBuf as many times as it diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h index 2ec4dd6b73a..5da3f9af3cb 100644 --- a/source/blender/imbuf/IMB_imbuf_types.h +++ b/source/blender/imbuf/IMB_imbuf_types.h @@ -5,6 +5,8 @@ #include "DNA_vec_types.h" /* for rcti */ +#include "BLI_sys_types.h" + #ifdef __cplusplus extern "C" { #endif @@ -151,6 +153,42 @@ typedef enum eImBufFlags { /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Imbuf buffer storage + * \{ */ + +/* Specialization of an ownership whenever a bare pointer is provided to the ImBuf buffers + * assignment API. */ +typedef enum ImBufOwnership { + /* The ImBuf simply shares pointer with data owned by someone else, and will not perform any + * memory management when the ImBuf frees the buffer. */ + IB_DO_NOT_TAKE_OWNERSHIP = 0, + + /* The ImBuf takes ownership of the buffer data, and will use MEM_freeN() to free this memory + * when the ImBuf needs to free the data. */ + IB_TAKE_OWNERSHIP = 1, +} ImBufOwnership; + +/* Different storage specialization. */ +/* TODO(sergey): Once everything is C++ replace with a template. */ + +typedef struct ImBufIntBuffer { + int *data; + ImBufOwnership ownership; +} ImBufIntBuffer; + +typedef struct ImBufByteBuffer { + uint8_t *data; + ImBufOwnership ownership; +} ImBufByteBuffer; + +typedef struct ImBufFloatBuffer { + float *data; + ImBufOwnership ownership; +} ImBufFloatBuffer; + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Image Buffer * \{ */ @@ -171,8 +209,6 @@ typedef struct ImBuf { /* flags */ /** Controls which components should exist. */ int flags; - /** what is malloced internal, and can be freed */ - int mall; /* pixels */ @@ -180,23 +216,24 @@ typedef struct ImBuf { * - color space defaults to `sRGB`. * - alpha defaults to 'straight'. */ - unsigned int *rect; + ImBufByteBuffer byte_buffer; + /** Image pixel buffer (float representation): * - color space defaults to 'linear' (`rec709`). * - alpha defaults to 'premul'. * \note May need gamma correction to `sRGB` when generating 8bit representations. * \note Formats that support higher more than 8 but channels load as floats. */ - float *rect_float; + ImBufFloatBuffer float_buffer; /** Resolution in pixels per meter. Multiply by `0.0254` for DPI. */ double ppm[2]; /* zbuffer */ /** z buffer data, original zbuffer */ - int *zbuf; + ImBufIntBuffer z_buffer; /** z buffer data, camera coordinates */ - float *zbuf_float; + ImBufFloatBuffer float_z_buffer; /* parameters used by conversion between byte and float */ /** random dither value, for conversion from float -> byte rect */ @@ -231,11 +268,11 @@ typedef struct ImBuf { /* some parameters to pass along for packing images */ /** Compressed image only used with PNG and EXR currently. */ - unsigned char *encodedbuffer; - /** Size of data written to `encodedbuffer`. */ - unsigned int encodedsize; - /** Size of `encodedbuffer` */ - unsigned int encodedbuffersize; + ImBufByteBuffer encoded_buffer; + /** Size of data written to `encoded_buffer`. */ + unsigned int encoded_size; + /** Size of `encoded_buffer` */ + unsigned int encoded_buffer_size; /* color management */ /** color space of byte buffer */ diff --git a/source/blender/imbuf/intern/IMB_filter.h b/source/blender/imbuf/intern/IMB_filter.h index 7855c5a52f4..2e836576636 100644 --- a/source/blender/imbuf/intern/IMB_filter.h +++ b/source/blender/imbuf/intern/IMB_filter.h @@ -8,14 +8,16 @@ #pragma once +#include "BLI_sys_types.h" + struct ImBuf; void imb_filterx(struct ImBuf *ibuf); -void IMB_premultiply_rect(unsigned int *rect, char planes, int w, int h); +void IMB_premultiply_rect(uint8_t *rect, char planes, int w, int h); void IMB_premultiply_rect_float(float *rect_float, int channels, int w, int h); -void IMB_unpremultiply_rect(unsigned int *rect, char planes, int w, int h); +void IMB_unpremultiply_rect(uint8_t *rect, char planes, int w, int h); void IMB_unpremultiply_rect_float(float *rect_float, int channels, int w, int h); /** diff --git a/source/blender/imbuf/intern/allocimbuf.cc b/source/blender/imbuf/intern/allocimbuf.cc index 6ec77ec1a12..4ddd3344293 100644 --- a/source/blender/imbuf/intern/allocimbuf.cc +++ b/source/blender/imbuf/intern/allocimbuf.cc @@ -61,6 +61,89 @@ void imb_mmap_unlock(void) } #endif +/* Free the specified buffer storage, freeing memory when needed and restoring the state of the + * buffer to its defaults. */ +template static void imb_free_buffer(BufferType &buffer) +{ + if (buffer.data) { + switch (buffer.ownership) { + case IB_DO_NOT_TAKE_OWNERSHIP: + break; + + case IB_TAKE_OWNERSHIP: + MEM_freeN(buffer.data); + break; + } + } + + /* Reset buffer to defaults. */ + buffer.data = nullptr; + buffer.ownership = IB_DO_NOT_TAKE_OWNERSHIP; +} + +/* Allocate pixel storage of the given buffer. The buffer owns the allocated memory. + * Returns true of allocation succeeded, false otherwise. */ +template +bool imb_alloc_buffer( + BufferType &buffer, const uint x, const uint y, const uint channels, const size_t type_size) +{ + buffer.data = static_cast( + imb_alloc_pixels(x, y, channels, type_size, __func__)); + if (!buffer.data) { + return false; + } + + buffer.ownership = IB_TAKE_OWNERSHIP; + + return true; +} + +/* Make the buffer available for modification. + * Is achieved by ensuring that the buffer is the only owner of its data. */ +template void imb_make_writeable_buffer(BufferType &buffer) +{ + if (!buffer.data) { + return; + } + + switch (buffer.ownership) { + case IB_DO_NOT_TAKE_OWNERSHIP: + buffer.data = static_cast(MEM_dupallocN(buffer.data)); + buffer.ownership = IB_TAKE_OWNERSHIP; + break; + + case IB_TAKE_OWNERSHIP: + break; + } +} + +template +auto imb_steal_buffer_data(BufferType &buffer) -> decltype(BufferType::data) +{ + if (!buffer.data) { + return nullptr; + } + + switch (buffer.ownership) { + case IB_DO_NOT_TAKE_OWNERSHIP: + BLI_assert(!"Unexpected behavior: stealing non-owned data pointer"); + return nullptr; + + case IB_TAKE_OWNERSHIP: { + decltype(BufferType::data) data = buffer.data; + + buffer.data = nullptr; + buffer.ownership = IB_DO_NOT_TAKE_OWNERSHIP; + + return data; + } + } + + BLI_assert_unreachable(); + + return nullptr; +} + void imb_freemipmapImBuf(ImBuf *ibuf) { int a; @@ -83,15 +166,11 @@ void imb_freerectfloatImBuf(ImBuf *ibuf) return; } - if (ibuf->rect_float && (ibuf->mall & IB_rectfloat)) { - MEM_freeN(ibuf->rect_float); - ibuf->rect_float = nullptr; - } + imb_free_buffer(ibuf->float_buffer); imb_freemipmapImBuf(ibuf); - ibuf->rect_float = nullptr; - ibuf->mall &= ~IB_rectfloat; + ibuf->flags &= ~IB_rectfloat; } void imb_freerectImBuf(ImBuf *ibuf) @@ -100,14 +179,11 @@ void imb_freerectImBuf(ImBuf *ibuf) return; } - if (ibuf->rect && (ibuf->mall & IB_rect)) { - MEM_freeN(ibuf->rect); - } - ibuf->rect = nullptr; + imb_free_buffer(ibuf->byte_buffer); imb_freemipmapImBuf(ibuf); - ibuf->mall &= ~IB_rect; + ibuf->flags &= ~IB_rect; } static void freeencodedbufferImBuf(ImBuf *ibuf) @@ -116,14 +192,12 @@ static void freeencodedbufferImBuf(ImBuf *ibuf) return; } - if (ibuf->encodedbuffer && (ibuf->mall & IB_mem)) { - MEM_freeN(ibuf->encodedbuffer); - } + imb_free_buffer(ibuf->encoded_buffer); - ibuf->encodedbuffer = nullptr; - ibuf->encodedbuffersize = 0; - ibuf->encodedsize = 0; - ibuf->mall &= ~IB_mem; + ibuf->encoded_buffer_size = 0; + ibuf->encoded_size = 0; + + ibuf->flags &= ~IB_mem; } void IMB_freezbufImBuf(ImBuf *ibuf) @@ -132,12 +206,9 @@ void IMB_freezbufImBuf(ImBuf *ibuf) return; } - if (ibuf->zbuf && (ibuf->mall & IB_zbuf)) { - MEM_freeN(ibuf->zbuf); - } + imb_free_buffer(ibuf->z_buffer); - ibuf->zbuf = nullptr; - ibuf->mall &= ~IB_zbuf; + ibuf->flags &= ~IB_zbuf; } void IMB_freezbuffloatImBuf(ImBuf *ibuf) @@ -146,12 +217,9 @@ void IMB_freezbuffloatImBuf(ImBuf *ibuf) return; } - if (ibuf->zbuf_float && (ibuf->mall & IB_zbuffloat)) { - MEM_freeN(ibuf->zbuf_float); - } + imb_free_buffer(ibuf->float_z_buffer); - ibuf->zbuf_float = nullptr; - ibuf->mall &= ~IB_zbuffloat; + ibuf->flags &= ~IB_zbuffloat; } void imb_freerectImbuf_all(ImBuf *ibuf) @@ -234,14 +302,12 @@ bool addzbufImBuf(ImBuf *ibuf) IMB_freezbufImBuf(ibuf); - if ((ibuf->zbuf = static_cast( - imb_alloc_pixels(ibuf->x, ibuf->y, 1, sizeof(uint), __func__)))) - { - ibuf->mall |= IB_zbuf; - ibuf->flags |= IB_zbuf; - return true; + if (!imb_alloc_buffer(ibuf->z_buffer, ibuf->x, ibuf->y, 1, sizeof(uint))) { + return false; } + ibuf->flags |= IB_zbuf; + return false; } @@ -253,15 +319,13 @@ bool addzbuffloatImBuf(ImBuf *ibuf) IMB_freezbuffloatImBuf(ibuf); - if ((ibuf->zbuf_float = static_cast( - imb_alloc_pixels(ibuf->x, ibuf->y, 1, sizeof(float), __func__)))) - { - ibuf->mall |= IB_zbuffloat; - ibuf->flags |= IB_zbuffloat; - return true; + if (!imb_alloc_buffer(ibuf->float_z_buffer, ibuf->x, ibuf->y, 1, sizeof(float))) { + return false; } - return false; + ibuf->flags |= IB_zbuffloat; + + return true; } bool imb_addencodedbufferImBuf(ImBuf *ibuf) @@ -272,61 +336,52 @@ bool imb_addencodedbufferImBuf(ImBuf *ibuf) freeencodedbufferImBuf(ibuf); - if (ibuf->encodedbuffersize == 0) { - ibuf->encodedbuffersize = 10000; + if (ibuf->encoded_buffer_size == 0) { + ibuf->encoded_buffer_size = 10000; } - ibuf->encodedsize = 0; + ibuf->encoded_size = 0; - if ((ibuf->encodedbuffer = static_cast(MEM_mallocN(ibuf->encodedbuffersize, __func__)))) - { - ibuf->mall |= IB_mem; - ibuf->flags |= IB_mem; - return true; + if (!imb_alloc_buffer(ibuf->encoded_buffer, ibuf->encoded_buffer_size, 1, 1, sizeof(uint8_t))) { + return false; } - return false; + ibuf->flags |= IB_mem; + + return true; } bool imb_enlargeencodedbufferImBuf(ImBuf *ibuf) { - uint newsize, encodedsize; - void *newbuffer; - if (ibuf == nullptr) { return false; } - if (ibuf->encodedbuffersize < ibuf->encodedsize) { + if (ibuf->encoded_buffer_size < ibuf->encoded_size) { printf("%s: error in parameters\n", __func__); return false; } - newsize = 2 * ibuf->encodedbuffersize; + uint newsize = 2 * ibuf->encoded_buffer_size; if (newsize < 10000) { newsize = 10000; } - newbuffer = MEM_mallocN(newsize, __func__); - if (newbuffer == nullptr) { + ImBufByteBuffer new_buffer; + if (!imb_alloc_buffer(new_buffer, newsize, 1, 1, sizeof(uint8_t))) { return false; } - if (ibuf->encodedbuffer) { - memcpy(newbuffer, ibuf->encodedbuffer, ibuf->encodedsize); + if (ibuf->encoded_buffer.data) { + memcpy(new_buffer.data, ibuf->encoded_buffer.data, ibuf->encoded_size); } else { - ibuf->encodedsize = 0; + ibuf->encoded_size = 0; } - encodedsize = ibuf->encodedsize; + imb_free_buffer(ibuf->encoded_buffer); - freeencodedbufferImBuf(ibuf); - - ibuf->encodedbuffersize = newsize; - ibuf->encodedsize = encodedsize; - ibuf->encodedbuffer = static_cast(newbuffer); - ibuf->mall |= IB_mem; + ibuf->encoded_buffer_size = newsize; ibuf->flags |= IB_mem; return true; @@ -350,20 +405,21 @@ bool imb_addrectfloatImBuf(ImBuf *ibuf, const uint channels) return false; } - if (ibuf->rect_float) { + /* NOTE: Follows the historical code. + * Is unclear if it is desired or not to free mipmaps. If mipmaps are to be preserved a simple + * `imb_free_buffer(ibuf->float_buffer)` can be used instead. */ + if (ibuf->float_buffer.data) { imb_freerectfloatImBuf(ibuf); /* frees mipmap too, hrm */ } - ibuf->channels = channels; - if ((ibuf->rect_float = static_cast( - imb_alloc_pixels(ibuf->x, ibuf->y, channels, sizeof(float), __func__)))) - { - ibuf->mall |= IB_rectfloat; - ibuf->flags |= IB_rectfloat; - return true; + if (!imb_alloc_buffer(ibuf->float_buffer, ibuf->x, ibuf->y, channels, sizeof(float))) { + return false; } - return false; + ibuf->channels = channels; + ibuf->flags |= IB_rectfloat; + + return true; } bool imb_addrectImBuf(ImBuf *ibuf) @@ -376,63 +432,141 @@ bool imb_addrectImBuf(ImBuf *ibuf) /* Don't call imb_freerectImBuf, it frees mipmaps, * this call is used only too give float buffers display. */ - if (ibuf->rect && (ibuf->mall & IB_rect)) { - MEM_freeN(ibuf->rect); - } - ibuf->rect = nullptr; + imb_free_buffer(ibuf->byte_buffer); - if ((ibuf->rect = static_cast( - imb_alloc_pixels(ibuf->x, ibuf->y, 4, sizeof(uchar), __func__)))) - { - ibuf->mall |= IB_rect; - ibuf->flags |= IB_rect; - if (ibuf->planes > 32) { - return addzbufImBuf(ibuf); - } - - return true; + if (!imb_alloc_buffer(ibuf->byte_buffer, ibuf->x, ibuf->y, 4, sizeof(uint8_t))) { + return false; } - return false; + ibuf->flags |= IB_rect; + + if (ibuf->planes > 32) { + return addzbufImBuf(ibuf); + } + + return true; } -struct ImBuf *IMB_allocFromBufferOwn(uint *rect, float *rectf, uint w, uint h, uint channels) +uint8_t *IMB_steal_byte_buffer(ImBuf *ibuf) { - ImBuf *ibuf = nullptr; + uint8_t *data = imb_steal_buffer_data(ibuf->byte_buffer); + ibuf->flags &= ~IB_rect; + return data; +} - if (!(rect || rectf)) { +float *IMB_steal_float_buffer(ImBuf *ibuf) +{ + float *data = imb_steal_buffer_data(ibuf->float_buffer); + ibuf->flags &= ~IB_rectfloat; + return data; +} + +uint8_t *IMB_steal_encoded_buffer(ImBuf *ibuf) +{ + uint8_t *data = imb_steal_buffer_data(ibuf->encoded_buffer); + + ibuf->encoded_size = 0; + ibuf->encoded_buffer_size = 0; + + ibuf->flags &= ~IB_mem; + + return data; +} + +void IMB_make_writable_byte_buffer(ImBuf *ibuf) +{ + imb_make_writeable_buffer(ibuf->byte_buffer); +} + +void IMB_make_writable_float_buffer(ImBuf *ibuf) +{ + imb_make_writeable_buffer(ibuf->float_buffer); +} + +void IMB_assign_byte_buffer(ImBuf *ibuf, uint8_t *buffer_data, const ImBufOwnership ownership) +{ + imb_free_buffer(ibuf->byte_buffer); + ibuf->flags &= ~IB_rect; + + if (buffer_data) { + ibuf->byte_buffer.data = buffer_data; + ibuf->byte_buffer.ownership = ownership; + + ibuf->flags |= IB_rect; + } +} + +void IMB_assign_float_buffer(ImBuf *ibuf, float *buffer_data, const ImBufOwnership ownership) +{ + imb_free_buffer(ibuf->float_buffer); + ibuf->flags &= ~IB_rectfloat; + + if (buffer_data) { + ibuf->float_buffer.data = buffer_data; + ibuf->float_buffer.ownership = ownership; + + ibuf->flags |= IB_rectfloat; + } +} + +void IMB_assign_z_buffer(struct ImBuf *ibuf, int *buffer_data, ImBufOwnership ownership) +{ + imb_free_buffer(ibuf->z_buffer); + ibuf->flags &= ~IB_zbuf; + + if (buffer_data) { + ibuf->z_buffer.ownership = ownership; + ibuf->z_buffer.data = buffer_data; + + ibuf->flags |= IB_zbuf; + } +} + +void IMB_assign_float_z_buffer(struct ImBuf *ibuf, float *buffer_data, ImBufOwnership ownership) +{ + imb_free_buffer(ibuf->float_z_buffer); + ibuf->flags &= ~IB_zbuffloat; + + if (buffer_data) { + ibuf->float_z_buffer.ownership = ownership; + ibuf->float_z_buffer.data = buffer_data; + + ibuf->flags |= IB_zbuffloat; + } +} + +ImBuf *IMB_allocFromBufferOwn( + uint8_t *byte_buffer, float *float_buffer, uint w, uint h, uint channels) +{ + if (!(byte_buffer || float_buffer)) { return nullptr; } - ibuf = IMB_allocImBuf(w, h, 32, 0); + ImBuf *ibuf = IMB_allocImBuf(w, h, 32, 0); ibuf->channels = channels; - /* Avoid #MEM_dupallocN since the buffers might not be allocated using guarded-allocation. */ - if (rectf) { - BLI_assert(MEM_allocN_len(rectf) == sizeof(float[4]) * w * h); - ibuf->rect_float = rectf; - - ibuf->flags |= IB_rectfloat; - ibuf->mall |= IB_rectfloat; + if (float_buffer) { + /* TODO(sergey): The 4 channels is the historical code. Should probably be `channels`, but + * needs a dedicated investigation. */ + BLI_assert(MEM_allocN_len(float_buffer) == sizeof(float[4]) * w * h); + IMB_assign_float_buffer(ibuf, float_buffer, IB_TAKE_OWNERSHIP); } - if (rect) { - BLI_assert(MEM_allocN_len(rect) == sizeof(uchar[4]) * w * h); - ibuf->rect = rect; - ibuf->flags |= IB_rect; - ibuf->mall |= IB_rect; + if (byte_buffer) { + BLI_assert(MEM_allocN_len(byte_buffer) == sizeof(uint8_t[4]) * w * h); + IMB_assign_byte_buffer(ibuf, byte_buffer, IB_TAKE_OWNERSHIP); } return ibuf; } struct ImBuf *IMB_allocFromBuffer( - const uint *rect, const float *rectf, uint w, uint h, uint channels) + const uint8_t *byte_buffer, const float *float_buffer, uint w, uint h, uint channels) { ImBuf *ibuf = nullptr; - if (!(rect || rectf)) { + if (!(byte_buffer || float_buffer)) { return nullptr; } @@ -440,22 +574,20 @@ struct ImBuf *IMB_allocFromBuffer( ibuf->channels = channels; - /* Avoid #MEM_dupallocN since the buffers might not be allocated using guarded-allocation. */ - if (rectf) { - const size_t size = sizeof(float[4]) * w * h; - ibuf->rect_float = static_cast(MEM_mallocN(size, __func__)); - memcpy(ibuf->rect_float, rectf, size); + /* NOTE: Avoid #MEM_dupallocN since the buffers might not be allocated using guarded-allocation. + */ + if (float_buffer) { + /* TODO(sergey): The 4 channels is the historical code. Should probably be `channels`, but + * needs a dedicated investigation. */ + imb_alloc_buffer(ibuf->float_buffer, w, h, 4, sizeof(float)); - ibuf->flags |= IB_rectfloat; - ibuf->mall |= IB_rectfloat; + memcpy(ibuf->float_buffer.data, float_buffer, sizeof(float[4]) * w * h); } - if (rect) { - const size_t size = sizeof(uchar[4]) * w * h; - ibuf->rect = static_cast(MEM_mallocN(size, __func__)); - memcpy(ibuf->rect, rect, size); - ibuf->flags |= IB_rect; - ibuf->mall |= IB_rect; + if (byte_buffer) { + imb_alloc_buffer(ibuf->byte_buffer, w, h, 4, sizeof(uint8_t)); + + memcpy(ibuf->byte_buffer.data, byte_buffer, sizeof(uint8_t[4]) * w * h); } return ibuf; @@ -530,16 +662,18 @@ ImBuf *IMB_dupImBuf(const ImBuf *ibuf1) return nullptr; } - if (ibuf1->rect) { + /* TODO(sergey): Use implicit sharing. */ + + if (ibuf1->byte_buffer.data) { flags |= IB_rect; } - if (ibuf1->rect_float) { + if (ibuf1->float_buffer.data) { flags |= IB_rectfloat; } - if (ibuf1->zbuf) { + if (ibuf1->z_buffer.data) { flags |= IB_zbuf; } - if (ibuf1->zbuf_float) { + if (ibuf1->float_z_buffer.data) { flags |= IB_zbuffloat; } @@ -552,47 +686,48 @@ ImBuf *IMB_dupImBuf(const ImBuf *ibuf1) } if (flags & IB_rect) { - memcpy(ibuf2->rect, ibuf1->rect, size_t(x) * y * sizeof(int)); + memcpy(ibuf2->byte_buffer.data, ibuf1->byte_buffer.data, size_t(x) * y * 4 * sizeof(uint8_t)); } if (flags & IB_rectfloat) { - memcpy(ibuf2->rect_float, ibuf1->rect_float, size_t(ibuf1->channels) * x * y * sizeof(float)); + memcpy(ibuf2->float_buffer.data, + ibuf1->float_buffer.data, + size_t(ibuf1->channels) * x * y * sizeof(float)); } if (flags & IB_zbuf) { - memcpy(ibuf2->zbuf, ibuf1->zbuf, size_t(x) * y * sizeof(int)); + memcpy(ibuf2->z_buffer.data, ibuf1->z_buffer.data, size_t(x) * y * sizeof(int)); } if (flags & IB_zbuffloat) { - memcpy(ibuf2->zbuf_float, ibuf1->zbuf_float, size_t(x) * y * sizeof(float)); + memcpy(ibuf2->float_buffer.data, ibuf1->float_buffer.data, size_t(x) * y * sizeof(float)); } - if (ibuf1->encodedbuffer) { - ibuf2->encodedbuffersize = ibuf1->encodedbuffersize; + if (ibuf1->encoded_buffer.data) { + ibuf2->encoded_buffer_size = ibuf1->encoded_buffer_size; if (imb_addencodedbufferImBuf(ibuf2) == false) { IMB_freeImBuf(ibuf2); return nullptr; } - memcpy(ibuf2->encodedbuffer, ibuf1->encodedbuffer, ibuf1->encodedsize); + memcpy(ibuf2->encoded_buffer.data, ibuf1->encoded_buffer.data, ibuf1->encoded_size); } /* silly trick to copy the entire contents of ibuf1 struct over to ibuf */ tbuf = *ibuf1; /* fix pointers */ - tbuf.rect = ibuf2->rect; - tbuf.rect_float = ibuf2->rect_float; - tbuf.encodedbuffer = ibuf2->encodedbuffer; - tbuf.zbuf = ibuf2->zbuf; - tbuf.zbuf_float = ibuf2->zbuf_float; + tbuf.byte_buffer = ibuf2->byte_buffer; + tbuf.float_buffer = ibuf2->float_buffer; + tbuf.encoded_buffer = ibuf2->encoded_buffer; + tbuf.z_buffer = ibuf2->z_buffer; + tbuf.float_z_buffer = ibuf2->float_z_buffer; for (a = 0; a < IMB_MIPMAP_LEVELS; a++) { tbuf.mipmap[a] = nullptr; } tbuf.dds_data.data = nullptr; /* set malloc flag */ - tbuf.mall = ibuf2->mall; tbuf.refcounter = 0; /* for now don't duplicate metadata */ @@ -618,11 +753,11 @@ size_t IMB_get_size_in_memory(ImBuf *ibuf) size += sizeof(ImBuf); - if (ibuf->rect) { + if (ibuf->byte_buffer.data) { channel_size += sizeof(char); } - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { channel_size += sizeof(float); } diff --git a/source/blender/imbuf/intern/anim_movie.cc b/source/blender/imbuf/intern/anim_movie.cc index 005aadaf1f5..34d2564452c 100644 --- a/source/blender/imbuf/intern/anim_movie.cc +++ b/source/blender/imbuf/intern/anim_movie.cc @@ -482,7 +482,9 @@ static ImBuf *avi_fetchibuf(struct anim *anim, int position) } for (y = 0; y < anim->y; y++) { - memcpy(&(ibuf->rect)[((anim->y - y) - 1) * anim->x], &tmp[y * anim->x], anim->x * 4); + memcpy(&(ibuf->byte_buffer.data)[((anim->y - y) - 1) * anim->x], + &tmp[y * anim->x], + anim->x * 4); } MEM_freeN(tmp); @@ -909,8 +911,14 @@ static void ffmpeg_postprocess(struct anim *anim, AVFrame *input) const int src_linesize[4] = {-anim->pFrameRGB->linesize[0], 0, 0, 0}; int dst_size = av_image_get_buffer_size( AVPixelFormat(anim->pFrameRGB->format), anim->pFrameRGB->width, anim->pFrameRGB->height, 1); - av_image_copy_to_buffer( - (uint8_t *)ibuf->rect, dst_size, src, src_linesize, AV_PIX_FMT_RGBA, anim->x, anim->y, 1); + av_image_copy_to_buffer((uint8_t *)ibuf->byte_buffer.data, + dst_size, + src, + src_linesize, + AV_PIX_FMT_RGBA, + anim->x, + anim->y, + 1); if (filter_y) { IMB_filtery(ibuf); } @@ -1459,9 +1467,11 @@ static ImBuf *ffmpeg_fetchibuf(struct anim *anim, int position, IMB_Timecode_Typ } anim->cur_frame_final = IMB_allocImBuf(anim->x, anim->y, planes, 0); - anim->cur_frame_final->rect = static_cast( + + /* Allocate the storage explicitly to ensure the memory is aligned. */ + uint8_t *buffer_data = static_cast( MEM_mallocN_aligned(size_t(4) * anim->x * anim->y, 32, "ffmpeg ibuf")); - anim->cur_frame_final->mall |= IB_rect; + IMB_assign_byte_buffer(anim->cur_frame_final, buffer_data, IB_TAKE_OWNERSHIP); anim->cur_frame_final->rect_colorspace = colormanage_colorspace_get_named(anim->colorspace); diff --git a/source/blender/imbuf/intern/cineon/cineon_dpx.cc b/source/blender/imbuf/intern/cineon/cineon_dpx.cc index 7043a033ed4..f4bf43ac616 100644 --- a/source/blender/imbuf/intern/cineon/cineon_dpx.cc +++ b/source/blender/imbuf/intern/cineon/cineon_dpx.cc @@ -48,7 +48,7 @@ static struct ImBuf *imb_load_dpx_cineon( } if (!(flags & IB_test)) { - if (logImageGetDataRGBA(image, ibuf->rect_float, 1) != 0) { + if (logImageGetDataRGBA(image, ibuf->float_buffer.data, 1) != 0) { logImageClose(image); IMB_freeImBuf(ibuf); return nullptr; @@ -117,7 +117,7 @@ static int imb_save_dpx_cineon(ImBuf *ibuf, const char *filepath, int use_cineon return 0; } - if (ibuf->rect_float != nullptr && bitspersample != 8) { + if (ibuf->float_buffer.data != nullptr && bitspersample != 8) { /* Don't use the float buffer to save 8 BPP picture to prevent color banding * (there's no dithering algorithm behind the #logImageSetDataRGBA function). */ @@ -126,7 +126,7 @@ static int imb_save_dpx_cineon(ImBuf *ibuf, const char *filepath, int use_cineon for (y = 0; y < ibuf->y; y++) { float *dst_ptr = fbuf + 4 * ((ibuf->y - y - 1) * ibuf->x); - float *src_ptr = ibuf->rect_float + 4 * (y * ibuf->x); + float *src_ptr = ibuf->float_buffer.data + 4 * (y * ibuf->x); memcpy(dst_ptr, src_ptr, 4 * ibuf->x * sizeof(float)); } @@ -136,7 +136,7 @@ static int imb_save_dpx_cineon(ImBuf *ibuf, const char *filepath, int use_cineon MEM_freeN(fbuf); } else { - if (ibuf->rect == nullptr) { + if (ibuf->byte_buffer.data == nullptr) { IMB_rect_from_float(ibuf); } @@ -150,7 +150,7 @@ static int imb_save_dpx_cineon(ImBuf *ibuf, const char *filepath, int use_cineon for (y = 0; y < ibuf->y; y++) { for (x = 0; x < ibuf->x; x++) { fbuf_ptr = fbuf + 4 * ((ibuf->y - y - 1) * ibuf->x + x); - rect_ptr = (uchar *)ibuf->rect + 4 * (y * ibuf->x + x); + rect_ptr = ibuf->byte_buffer.data + 4 * (y * ibuf->x + x); fbuf_ptr[0] = float(rect_ptr[0]) / 255.0f; fbuf_ptr[1] = float(rect_ptr[1]) / 255.0f; fbuf_ptr[2] = float(rect_ptr[2]) / 255.0f; diff --git a/source/blender/imbuf/intern/colormanagement.cc b/source/blender/imbuf/intern/colormanagement.cc index 1ded1983936..227532c62d1 100644 --- a/source/blender/imbuf/intern/colormanagement.cc +++ b/source/blender/imbuf/intern/colormanagement.cc @@ -385,7 +385,7 @@ static uchar *colormanage_cache_get(ImBuf *ibuf, return nullptr; } - return (uchar *)cache_ibuf->rect; + return (uchar *)cache_ibuf->byte_buffer.data; } return nullptr; @@ -412,10 +412,7 @@ static void colormanage_cache_put(ImBuf *ibuf, /* buffer itself */ cache_ibuf = IMB_allocImBuf(ibuf->x, ibuf->y, ibuf->planes, 0); - cache_ibuf->rect = (uint *)display_buffer; - - cache_ibuf->mall |= IB_rect; - cache_ibuf->flags |= IB_rect; + IMB_assign_byte_buffer(cache_ibuf, display_buffer, IB_TAKE_OWNERSHIP); /* Store data which is needed to check whether cached buffer * could be used for color managed display settings. */ @@ -1050,15 +1047,15 @@ void colormanage_imbuf_make_linear(ImBuf *ibuf, const char *from_colorspace) return; } - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { const char *to_colorspace = global_role_scene_linear; const bool predivide = IMB_alpha_affects_rgb(ibuf); - if (ibuf->rect) { + if (ibuf->byte_buffer.data) { imb_freerectImBuf(ibuf); } - IMB_colormanagement_transform(ibuf->rect_float, + IMB_colormanagement_transform(ibuf->float_buffer.data, ibuf->x, ibuf->y, ibuf->channels, @@ -1751,7 +1748,7 @@ static void colormanage_display_buffer_process_ex( * this would save byte -> float -> byte conversions making display buffer * computation noticeable faster */ - if (ibuf->rect_float == nullptr && ibuf->rect_colorspace) { + if (ibuf->float_buffer.data == nullptr && ibuf->rect_colorspace) { skip_transform = is_ibuf_rect_in_display_space(ibuf, view_settings, display_settings); } @@ -1760,8 +1757,8 @@ static void colormanage_display_buffer_process_ex( } display_buffer_apply_threaded(ibuf, - ibuf->rect_float, - (uchar *)ibuf->rect, + ibuf->float_buffer.data, + ibuf->byte_buffer.data, display_buffer, display_buffer_byte, cm_processor); @@ -2193,12 +2190,13 @@ void IMB_colormanagement_imbuf_to_byte_texture(uchar *out_buffer, { /* Byte buffer storage, only for sRGB, scene linear and data texture since other * color space conversions can't be done on the GPU. */ - BLI_assert(ibuf->rect && ibuf->rect_float == nullptr); + BLI_assert(ibuf->byte_buffer.data); + BLI_assert(ibuf->float_buffer.data == nullptr); BLI_assert(IMB_colormanagement_space_is_srgb(ibuf->rect_colorspace) || IMB_colormanagement_space_is_scene_linear(ibuf->rect_colorspace) || IMB_colormanagement_space_is_data(ibuf->rect_colorspace)); - const uchar *in_buffer = (uchar *)ibuf->rect; + const uchar *in_buffer = ibuf->byte_buffer.data; const bool use_premultiply = IMB_alpha_affects_rgb(ibuf) && store_premultiplied; for (int y = 0; y < height; y++) { @@ -2275,9 +2273,9 @@ void IMB_colormanagement_imbuf_to_float_texture(float *out_buffer, { /* Float texture are stored in scene linear color space, with premultiplied * alpha depending on the image alpha mode. */ - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { /* Float source buffer. */ - const float *in_buffer = ibuf->rect_float; + const float *in_buffer = ibuf->float_buffer.data; const int in_channels = ibuf->channels; const bool use_unpremultiply = IMB_alpha_affects_rgb(ibuf) && !store_premultiplied; @@ -2320,7 +2318,7 @@ void IMB_colormanagement_imbuf_to_float_texture(float *out_buffer, } else { /* Byte source buffer. */ - const uchar *in_buffer = (uchar *)ibuf->rect; + const uchar *in_buffer = ibuf->byte_buffer.data; const bool use_premultiply = IMB_alpha_affects_rgb(ibuf) && store_premultiplied; OCIO_ConstCPUProcessorRcPtr *processor = (ibuf->rect_colorspace) ? @@ -2458,12 +2456,12 @@ static void colormanagement_imbuf_make_display_space( const ColorManagedDisplaySettings *display_settings, bool make_byte) { - if (!ibuf->rect && make_byte) { + if (!ibuf->byte_buffer.data && make_byte) { imb_addrectImBuf(ibuf); } colormanage_display_buffer_process_ex( - ibuf, ibuf->rect_float, (uchar *)ibuf->rect, view_settings, display_settings); + ibuf, ibuf->float_buffer.data, ibuf->byte_buffer.data, view_settings, display_settings); } void IMB_colormanagement_imbuf_make_display_space( @@ -2491,15 +2489,8 @@ static ImBuf *imbuf_ensure_editable(ImBuf *ibuf, ImBuf *colormanaged_ibuf, bool /* Render pipeline is constructing image buffer itself, * but it's re-using byte and float buffers from render result make copy of this buffers * here sine this buffers would be transformed to other color space here. */ - if (ibuf->rect && (ibuf->mall & IB_rect) == 0) { - ibuf->rect = static_cast(MEM_dupallocN(ibuf->rect)); - ibuf->mall |= IB_rect; - } - - if (ibuf->rect_float && (ibuf->mall & IB_rectfloat) == 0) { - ibuf->rect_float = static_cast(MEM_dupallocN(ibuf->rect_float)); - ibuf->mall |= IB_rectfloat; - } + IMB_make_writable_byte_buffer(ibuf); + IMB_make_writable_float_buffer(ibuf); return ibuf; } @@ -2512,7 +2503,7 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, ImBuf *colormanaged_ibuf = ibuf; /* Update byte buffer if exists but invalid. */ - if (ibuf->rect_float && ibuf->rect && + if (ibuf->float_buffer.data && ibuf->byte_buffer.data && (ibuf->userflags & (IB_DISPLAY_BUFFER_INVALID | IB_RECT_INVALID)) != 0) { IMB_rect_from_float(ibuf); @@ -2545,14 +2536,14 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, colormanaged_ibuf = imbuf_ensure_editable(ibuf, colormanaged_ibuf, allocate_result); - if (colormanaged_ibuf->rect_float && colormanaged_ibuf->channels == 4) { + if (colormanaged_ibuf->float_buffer.data && colormanaged_ibuf->channels == 4) { IMB_alpha_under_color_float( - colormanaged_ibuf->rect_float, colormanaged_ibuf->x, colormanaged_ibuf->y, color); + colormanaged_ibuf->float_buffer.data, colormanaged_ibuf->x, colormanaged_ibuf->y, color); } - if (colormanaged_ibuf->rect) { + if (colormanaged_ibuf->byte_buffer.data) { IMB_alpha_under_color_byte( - (uchar *)colormanaged_ibuf->rect, colormanaged_ibuf->x, colormanaged_ibuf->y, color); + colormanaged_ibuf->byte_buffer.data, colormanaged_ibuf->x, colormanaged_ibuf->y, color); } } @@ -2565,7 +2556,7 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, &image_format->display_settings, byte_output); - if (colormanaged_ibuf->rect_float) { + if (colormanaged_ibuf->float_buffer.data) { /* Float buffer isn't linear anymore, * image format write callback should check for this flag and assume * no space conversion should happen if ibuf->float_colorspace != nullptr. */ @@ -2580,20 +2571,19 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, /* Linear render or regular file output: conversion between two color spaces. */ /* Detect which color space we need to convert between. */ - const char *from_colorspace = (ibuf->rect_float && !(byte_output && ibuf->rect)) ? - /* From float buffer. */ - (ibuf->float_colorspace) ? ibuf->float_colorspace->name : - global_role_scene_linear : - /* From byte buffer. */ - (ibuf->rect_colorspace) ? ibuf->rect_colorspace->name : - global_role_default_byte; + const char *from_colorspace = + (ibuf->float_buffer.data && !(byte_output && ibuf->byte_buffer.data)) ? + /* From float buffer. */ + (ibuf->float_colorspace) ? ibuf->float_colorspace->name : global_role_scene_linear : + /* From byte buffer. */ + (ibuf->rect_colorspace) ? ibuf->rect_colorspace->name : global_role_default_byte; const char *to_colorspace = image_format->linear_colorspace_settings.name; /* TODO: can we check with OCIO if color spaces are the same but have different names? */ if (to_colorspace[0] == '\0' || STREQ(from_colorspace, to_colorspace)) { /* No conversion needed, but may still need to allocate byte buffer for output. */ - if (byte_output && !ibuf->rect) { + if (byte_output && !ibuf->byte_buffer.data) { ibuf->rect_colorspace = ibuf->float_colorspace; IMB_rect_from_float(ibuf); } @@ -2605,9 +2595,9 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, if (byte_output) { colormanaged_ibuf->rect_colorspace = colormanage_colorspace_get_named(to_colorspace); - if (colormanaged_ibuf->rect) { + if (colormanaged_ibuf->byte_buffer.data) { /* Byte to byte. */ - IMB_colormanagement_transform_byte_threaded((uchar *)colormanaged_ibuf->rect, + IMB_colormanagement_transform_byte_threaded(colormanaged_ibuf->byte_buffer.data, colormanaged_ibuf->x, colormanaged_ibuf->y, colormanaged_ibuf->channels, @@ -2620,7 +2610,7 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, } } else { - if (!colormanaged_ibuf->rect_float) { + if (!colormanaged_ibuf->float_buffer.data) { /* Byte to float. */ IMB_float_from_rect(colormanaged_ibuf); imb_freerectImBuf(colormanaged_ibuf); @@ -2629,9 +2619,9 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, from_colorspace = global_role_scene_linear; } - if (colormanaged_ibuf->rect_float) { + if (colormanaged_ibuf->float_buffer.data) { /* Float to float. */ - IMB_colormanagement_transform(colormanaged_ibuf->rect_float, + IMB_colormanagement_transform(colormanaged_ibuf->float_buffer.data, colormanaged_ibuf->x, colormanaged_ibuf->y, colormanaged_ibuf->channels, @@ -2685,9 +2675,9 @@ uchar *IMB_display_buffer_acquire(ImBuf *ibuf, /* early out: no float buffer and byte buffer is already in display space, * let's just use if */ - if (ibuf->rect_float == nullptr && ibuf->rect_colorspace && ibuf->channels == 4) { + if (ibuf->float_buffer.data == nullptr && ibuf->rect_colorspace && ibuf->channels == 4) { if (is_ibuf_rect_in_display_space(ibuf, applied_view_settings, display_settings)) { - return (uchar *)ibuf->rect; + return ibuf->byte_buffer.data; } } @@ -2697,8 +2687,8 @@ uchar *IMB_display_buffer_acquire(ImBuf *ibuf, if (ibuf->invalid_rect.xmin != ibuf->invalid_rect.xmax) { if ((ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) == 0) { IMB_partial_display_buffer_update_threaded(ibuf, - ibuf->rect_float, - (uchar *)ibuf->rect, + ibuf->float_buffer.data, + ibuf->byte_buffer.data, ibuf->x, 0, 0, diff --git a/source/blender/imbuf/intern/divers.cc b/source/blender/imbuf/intern/divers.cc index bdc7563e5ef..c0d3d9e9a7b 100644 --- a/source/blender/imbuf/intern/divers.cc +++ b/source/blender/imbuf/intern/divers.cc @@ -696,12 +696,12 @@ void IMB_buffer_byte_from_byte(uchar *rect_to, void IMB_rect_from_float(ImBuf *ibuf) { /* verify we have a float buffer */ - if (ibuf->rect_float == nullptr) { + if (ibuf->float_buffer.data == nullptr) { return; } /* create byte rect if it didn't exist yet */ - if (ibuf->rect == nullptr) { + if (ibuf->byte_buffer.data == nullptr) { if (imb_addrectImBuf(ibuf) == 0) { return; } @@ -716,7 +716,7 @@ void IMB_rect_from_float(ImBuf *ibuf) COLOR_ROLE_DEFAULT_BYTE) : ibuf->rect_colorspace->name; - float *buffer = static_cast(MEM_dupallocN(ibuf->rect_float)); + float *buffer = static_cast(MEM_dupallocN(ibuf->float_buffer.data)); /* first make float buffer in byte space */ const bool predivide = IMB_alpha_affects_rgb(ibuf); @@ -729,7 +729,7 @@ void IMB_rect_from_float(ImBuf *ibuf) } /* convert float to byte */ - IMB_buffer_byte_from_float((uchar *)ibuf->rect, + IMB_buffer_byte_from_float(ibuf->byte_buffer.data, buffer, ibuf->channels, ibuf->dither, @@ -751,9 +751,10 @@ void IMB_float_from_rect_ex(struct ImBuf *dst, const struct ImBuf *src, const rcti *region_to_update) { - BLI_assert_msg(dst->rect_float != nullptr, + BLI_assert_msg(dst->float_buffer.data != nullptr, "Destination buffer should have a float buffer assigned."); - BLI_assert_msg(src->rect != nullptr, "Source buffer should have a byte buffer assigned."); + BLI_assert_msg(src->byte_buffer.data != nullptr, + "Source buffer should have a byte buffer assigned."); BLI_assert_msg(dst->x == src->x, "Source and destination buffer should have the same dimension"); BLI_assert_msg(dst->y == src->y, "Source and destination buffer should have the same dimension"); BLI_assert_msg(dst->channels = 4, "Destination buffer should have 4 channels."); @@ -766,9 +767,9 @@ void IMB_float_from_rect_ex(struct ImBuf *dst, BLI_assert_msg(region_to_update->ymax <= dst->y, "Region to update should be clipped to the given buffers."); - float *rect_float = dst->rect_float; + float *rect_float = dst->float_buffer.data; rect_float += (region_to_update->xmin + region_to_update->ymin * dst->x) * 4; - uchar *rect = (uchar *)src->rect; + uchar *rect = src->byte_buffer.data; rect += (region_to_update->xmin + region_to_update->ymin * dst->x) * 4; const int region_width = BLI_rcti_size_x(region_to_update); const int region_height = BLI_rcti_size_y(region_to_update); @@ -804,10 +805,8 @@ void IMB_float_from_rect_ex(struct ImBuf *dst, void IMB_float_from_rect(ImBuf *ibuf) { - float *rect_float; - /* verify if we byte and float buffers */ - if (ibuf->rect == nullptr) { + if (ibuf->byte_buffer.data == nullptr) { return; } @@ -815,7 +814,7 @@ void IMB_float_from_rect(ImBuf *ibuf) * so work-in-progress color space conversion doesn't * interfere with other parts of blender */ - rect_float = ibuf->rect_float; + float *rect_float = ibuf->float_buffer.data; if (rect_float == nullptr) { const size_t size = IMB_get_rect_len(ibuf) * sizeof(float[4]); rect_float = static_cast(MEM_callocN(size, "IMB_float_from_rect")); @@ -825,9 +824,8 @@ void IMB_float_from_rect(ImBuf *ibuf) } ibuf->channels = 4; - ibuf->rect_float = rect_float; - ibuf->mall |= IB_rectfloat; - ibuf->flags |= IB_rectfloat; + + IMB_assign_float_buffer(ibuf, rect_float, IB_TAKE_OWNERSHIP); } rcti region_to_update; @@ -843,8 +841,8 @@ void IMB_float_from_rect(ImBuf *ibuf) void IMB_color_to_bw(ImBuf *ibuf) { - float *rct_fl = ibuf->rect_float; - uchar *rct = (uchar *)ibuf->rect; + float *rct_fl = ibuf->float_buffer.data; + uchar *rct = ibuf->byte_buffer.data; size_t i; if (rct_fl) { @@ -889,8 +887,8 @@ void IMB_buffer_float_premultiply(float *buf, int width, int height) void IMB_saturation(ImBuf *ibuf, float sat) { size_t i; - uchar *rct = (uchar *)ibuf->rect; - float *rct_fl = ibuf->rect_float; + uchar *rct = ibuf->byte_buffer.data; + float *rct_fl = ibuf->float_buffer.data; float hsv[3]; if (rct) { diff --git a/source/blender/imbuf/intern/filter.cc b/source/blender/imbuf/intern/filter.cc index 9a6a1e4e82a..02575c400b6 100644 --- a/source/blender/imbuf/intern/filter.cc +++ b/source/blender/imbuf/intern/filter.cc @@ -101,16 +101,12 @@ static void filtcolumf(float *point, int y, int skip) void IMB_filtery(struct ImBuf *ibuf) { - uchar *point; - float *pointf; - int x, y, skip; + uchar *point = ibuf->byte_buffer.data; + float *pointf = ibuf->float_buffer.data; - point = (uchar *)ibuf->rect; - pointf = ibuf->rect_float; - - x = ibuf->x; - y = ibuf->y; - skip = x << 2; + int x = ibuf->x; + int y = ibuf->y; + int skip = x << 2; for (; x > 0; x--) { if (point) { @@ -142,16 +138,12 @@ void IMB_filtery(struct ImBuf *ibuf) void imb_filterx(struct ImBuf *ibuf) { - uchar *point; - float *pointf; - int x, y, skip; + uchar *point = ibuf->byte_buffer.data; + float *pointf = ibuf->float_buffer.data; - point = (uchar *)ibuf->rect; - pointf = ibuf->rect_float; - - x = ibuf->x; - y = ibuf->y; - skip = (x << 2) - 3; + int x = ibuf->x; + int y = ibuf->y; + int skip = (x << 2) - 3; for (; y > 0; y--) { if (point) { @@ -189,14 +181,14 @@ static void imb_filterN(ImBuf *out, ImBuf *in) const int channels = in->channels; const int rowlen = in->x; - if (in->rect && out->rect) { + if (in->byte_buffer.data && out->byte_buffer.data) { for (int y = 0; y < in->y; y++) { /* setup rows */ - const char *row2 = (const char *)in->rect + y * channels * rowlen; + const char *row2 = (const char *)in->byte_buffer.data + y * channels * rowlen; const char *row1 = (y == 0) ? row2 : row2 - channels * rowlen; const char *row3 = (y == in->y - 1) ? row2 : row2 + channels * rowlen; - char *cp = (char *)out->rect + y * channels * rowlen; + char *cp = (char *)out->byte_buffer.data + y * channels * rowlen; for (int x = 0; x < rowlen; x++) { const char *r11, *r13, *r21, *r23, *r31, *r33; @@ -243,14 +235,14 @@ static void imb_filterN(ImBuf *out, ImBuf *in) } } - if (in->rect_float && out->rect_float) { + if (in->float_buffer.data && out->float_buffer.data) { for (int y = 0; y < in->y; y++) { /* setup rows */ - const float *row2 = (const float *)in->rect_float + y * channels * rowlen; + const float *row2 = (const float *)in->float_buffer.data + y * channels * rowlen; const float *row1 = (y == 0) ? row2 : row2 - channels * rowlen; const float *row3 = (y == in->y - 1) ? row2 : row2 + channels * rowlen; - float *cp = (float *)out->rect_float + y * channels * rowlen; + float *cp = (float *)out->float_buffer.data + y * channels * rowlen; for (int x = 0; x < rowlen; x++) { const float *r11, *r13, *r21, *r23, *r31, *r33; @@ -351,11 +343,11 @@ void IMB_mask_filter_extend(char *mask, int width, int height) void IMB_mask_clear(ImBuf *ibuf, const char *mask, int val) { int x, y; - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { for (x = 0; x < ibuf->x; x++) { for (y = 0; y < ibuf->y; y++) { if (mask[ibuf->x * y + x] == val) { - float *col = ibuf->rect_float + 4 * (ibuf->x * y + x); + float *col = ibuf->float_buffer.data + 4 * (ibuf->x * y + x); col[0] = col[1] = col[2] = col[3] = 0.0f; } } @@ -366,7 +358,7 @@ void IMB_mask_clear(ImBuf *ibuf, const char *mask, int val) for (x = 0; x < ibuf->x; x++) { for (y = 0; y < ibuf->y; y++) { if (mask[ibuf->x * y + x] == val) { - char *col = (char *)(ibuf->rect + ibuf->x * y + x); + char *col = (char *)(ibuf->byte_buffer.data + 4 * ibuf->x * y + x); col[0] = col[1] = col[2] = col[3] = 0; } } @@ -409,13 +401,14 @@ void IMB_filter_extend(struct ImBuf *ibuf, char *mask, int filter) const int width = ibuf->x; const int height = ibuf->y; const int depth = 4; /* always 4 channels */ - const int chsize = ibuf->rect_float ? sizeof(float) : sizeof(uchar); + const int chsize = ibuf->float_buffer.data ? sizeof(float) : sizeof(uchar); const size_t bsize = size_t(width) * height * depth * chsize; - const bool is_float = (ibuf->rect_float != nullptr); - void *dstbuf = (void *)MEM_dupallocN(ibuf->rect_float ? (void *)ibuf->rect_float : - (void *)ibuf->rect); + const bool is_float = (ibuf->float_buffer.data != nullptr); + void *dstbuf = MEM_dupallocN(ibuf->float_buffer.data ? (void *)ibuf->float_buffer.data : + (void *)ibuf->byte_buffer.data); char *dstmask = mask == nullptr ? nullptr : (char *)MEM_dupallocN(mask); - void *srcbuf = ibuf->rect_float ? (void *)ibuf->rect_float : (void *)ibuf->rect; + void *srcbuf = ibuf->float_buffer.data ? (void *)ibuf->float_buffer.data : + (void *)ibuf->byte_buffer.data; char *srcmask = mask; int cannot_early_out = 1, r, n, k, i, j, c; float weight[25]; @@ -582,7 +575,7 @@ void IMB_makemipmap(ImBuf *ibuf, int use_filter) imb_freemipmapImBuf(ibuf); /* no mipmap for non RGBA images */ - if (ibuf->rect_float && ibuf->channels < 4) { + if (ibuf->float_buffer.data && ibuf->channels < 4) { return; } @@ -617,13 +610,13 @@ ImBuf *IMB_getmipmap(ImBuf *ibuf, int level) return (level == 0) ? ibuf : ibuf->mipmap[level - 1]; } -void IMB_premultiply_rect(uint *rect, char planes, int w, int h) +void IMB_premultiply_rect(uint8_t *rect, char planes, int w, int h) { - char *cp; + uint8_t *cp; int x, y, val; if (planes == 24) { /* put alpha at 255 */ - cp = (char *)(rect); + cp = rect; for (y = 0; y < h; y++) { for (x = 0; x < w; x++, cp += 4) { @@ -632,7 +625,7 @@ void IMB_premultiply_rect(uint *rect, char planes, int w, int h) } } else { - cp = (char *)(rect); + cp = rect; for (y = 0; y < h; y++) { for (x = 0; x < w; x++, cp += 4) { @@ -669,23 +662,23 @@ void IMB_premultiply_alpha(ImBuf *ibuf) return; } - if (ibuf->rect) { - IMB_premultiply_rect(ibuf->rect, ibuf->planes, ibuf->x, ibuf->y); + if (ibuf->byte_buffer.data) { + IMB_premultiply_rect(ibuf->byte_buffer.data, ibuf->planes, ibuf->x, ibuf->y); } - if (ibuf->rect_float) { - IMB_premultiply_rect_float(ibuf->rect_float, ibuf->channels, ibuf->x, ibuf->y); + if (ibuf->float_buffer.data) { + IMB_premultiply_rect_float(ibuf->float_buffer.data, ibuf->channels, ibuf->x, ibuf->y); } } -void IMB_unpremultiply_rect(uint *rect, char planes, int w, int h) +void IMB_unpremultiply_rect(uint8_t *rect, char planes, int w, int h) { - char *cp; + uchar *cp; int x, y; float val; if (planes == 24) { /* put alpha at 255 */ - cp = (char *)(rect); + cp = rect; for (y = 0; y < h; y++) { for (x = 0; x < w; x++, cp += 4) { @@ -694,7 +687,7 @@ void IMB_unpremultiply_rect(uint *rect, char planes, int w, int h) } } else { - cp = (char *)(rect); + cp = rect; for (y = 0; y < h; y++) { for (x = 0; x < w; x++, cp += 4) { @@ -731,11 +724,11 @@ void IMB_unpremultiply_alpha(ImBuf *ibuf) return; } - if (ibuf->rect) { - IMB_unpremultiply_rect(ibuf->rect, ibuf->planes, ibuf->x, ibuf->y); + if (ibuf->byte_buffer.data) { + IMB_unpremultiply_rect(ibuf->byte_buffer.data, ibuf->planes, ibuf->x, ibuf->y); } - if (ibuf->rect_float) { - IMB_unpremultiply_rect_float(ibuf->rect_float, ibuf->channels, ibuf->x, ibuf->y); + if (ibuf->float_buffer.data) { + IMB_unpremultiply_rect_float(ibuf->float_buffer.data, ibuf->channels, ibuf->x, ibuf->y); } } diff --git a/source/blender/imbuf/intern/format_tiff.cc b/source/blender/imbuf/intern/format_tiff.cc index e46e4db5bf2..f9c98fb4d3f 100644 --- a/source/blender/imbuf/intern/format_tiff.cc +++ b/source/blender/imbuf/intern/format_tiff.cc @@ -48,7 +48,7 @@ ImBuf *imb_load_tiff(const uchar *mem, size_t size, int flags, char colorspace[I bool imb_save_tiff(struct ImBuf *ibuf, const char *filepath, int flags) { - const bool is_16bit = ((ibuf->foptions.flag & TIF_16BIT) && ibuf->rect_float); + const bool is_16bit = ((ibuf->foptions.flag & TIF_16BIT) && ibuf->float_buffer.data); const int file_channels = ibuf->planes >> 3; const TypeDesc data_format = is_16bit ? TypeDesc::UINT16 : TypeDesc::UINT8; diff --git a/source/blender/imbuf/intern/imageprocess.cc b/source/blender/imbuf/intern/imageprocess.cc index 8d875fb09ec..6e1de7e6343 100644 --- a/source/blender/imbuf/intern/imageprocess.cc +++ b/source/blender/imbuf/intern/imageprocess.cc @@ -26,10 +26,10 @@ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf) { size_t size; - uchar rt, *cp = (uchar *)ibuf->rect; - float rtf, *cpf = ibuf->rect_float; + uchar rt, *cp = ibuf->byte_buffer.data; + float rtf, *cpf = ibuf->float_buffer.data; - if (ibuf->rect) { + if (ibuf->byte_buffer.data) { size = ibuf->x * ibuf->y; while (size-- > 0) { @@ -43,7 +43,7 @@ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf) } } - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { size = ibuf->x * ibuf->y; while (size-- > 0) { @@ -63,12 +63,12 @@ static void pixel_from_buffer(const struct ImBuf *ibuf, uchar **outI, float **ou { size_t offset = size_t(ibuf->x) * y * 4 + 4 * x; - if (ibuf->rect) { - *outI = (uchar *)ibuf->rect + offset; + if (ibuf->byte_buffer.data) { + *outI = ibuf->byte_buffer.data + offset; } - if (ibuf->rect_float) { - *outF = ibuf->rect_float + offset; + if (ibuf->float_buffer.data) { + *outF = ibuf->float_buffer.data + offset; } } @@ -80,10 +80,10 @@ void bicubic_interpolation_color( const struct ImBuf *in, uchar outI[4], float outF[4], float u, float v) { if (outF) { - BLI_bicubic_interpolation_fl(in->rect_float, outF, in->x, in->y, 4, u, v); + BLI_bicubic_interpolation_fl(in->float_buffer.data, outF, in->x, in->y, 4, u, v); } else { - BLI_bicubic_interpolation_char((uchar *)in->rect, outI, in->x, in->y, 4, u, v); + BLI_bicubic_interpolation_char(in->byte_buffer.data, outI, in->x, in->y, 4, u, v); } } @@ -92,7 +92,7 @@ void bicubic_interpolation(const ImBuf *in, ImBuf *out, float u, float v, int xo uchar *outI = nullptr; float *outF = nullptr; - if (in == nullptr || (in->rect == nullptr && in->rect_float == nullptr)) { + if (in == nullptr || (in->byte_buffer.data == nullptr && in->float_buffer.data == nullptr)) { return; } @@ -112,26 +112,26 @@ void bilinear_interpolation_color_fl( const struct ImBuf *in, uchar /*outI*/[4], float outF[4], float u, float v) { BLI_assert(outF); - BLI_assert(in->rect_float); - BLI_bilinear_interpolation_fl(in->rect_float, outF, in->x, in->y, 4, u, v); + BLI_assert(in->float_buffer.data); + BLI_bilinear_interpolation_fl(in->float_buffer.data, outF, in->x, in->y, 4, u, v); } void bilinear_interpolation_color_char( const struct ImBuf *in, uchar outI[4], float /*outF*/[4], float u, float v) { BLI_assert(outI); - BLI_assert(in->rect); - BLI_bilinear_interpolation_char((uchar *)in->rect, outI, in->x, in->y, 4, u, v); + BLI_assert(in->byte_buffer.data); + BLI_bilinear_interpolation_char(in->byte_buffer.data, outI, in->x, in->y, 4, u, v); } void bilinear_interpolation_color( const struct ImBuf *in, uchar outI[4], float outF[4], float u, float v) { if (outF) { - BLI_bilinear_interpolation_fl(in->rect_float, outF, in->x, in->y, 4, u, v); + BLI_bilinear_interpolation_fl(in->float_buffer.data, outF, in->x, in->y, 4, u, v); } else { - BLI_bilinear_interpolation_char((uchar *)in->rect, outI, in->x, in->y, 4, u, v); + BLI_bilinear_interpolation_char(in->byte_buffer.data, outI, in->x, in->y, 4, u, v); } } @@ -181,11 +181,12 @@ void bilinear_interpolation_color_wrap( ma_mb = (1.0f - a) * (1.0f - b); if (outF) { + float *in_rect_float = in->float_buffer.data; /* sample including outside of edges of image */ - row1 = in->rect_float + size_t(in->x) * y1 * 4 + 4 * x1; - row2 = in->rect_float + size_t(in->x) * y2 * 4 + 4 * x1; - row3 = in->rect_float + size_t(in->x) * y1 * 4 + 4 * x2; - row4 = in->rect_float + size_t(in->x) * y2 * 4 + 4 * x2; + row1 = in_rect_float + size_t(in->x) * y1 * 4 + 4 * x1; + row2 = in_rect_float + size_t(in->x) * y2 * 4 + 4 * x1; + row3 = in_rect_float + size_t(in->x) * y1 * 4 + 4 * x2; + row4 = in_rect_float + size_t(in->x) * y2 * 4 + 4 * x2; outF[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0]; outF[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1]; @@ -196,11 +197,12 @@ void bilinear_interpolation_color_wrap( clamp_v4(outF, 0.0f, 1.0f); } if (outI) { + uchar *in_rect = in->byte_buffer.data; /* sample including outside of edges of image */ - row1I = (uchar *)in->rect + size_t(in->x) * y1 * 4 + 4 * x1; - row2I = (uchar *)in->rect + size_t(in->x) * y2 * 4 + 4 * x1; - row3I = (uchar *)in->rect + size_t(in->x) * y1 * 4 + 4 * x2; - row4I = (uchar *)in->rect + size_t(in->x) * y2 * 4 + 4 * x2; + row1I = in_rect + size_t(in->x) * y1 * 4 + 4 * x1; + row2I = in_rect + size_t(in->x) * y2 * 4 + 4 * x1; + row3I = in_rect + size_t(in->x) * y1 * 4 + 4 * x2; + row4I = in_rect + size_t(in->x) * y2 * 4 + 4 * x2; /* Tested with white images and this should not wrap back to zero. */ outI[0] = roundf(ma_mb * row1I[0] + a_mb * row3I[0] + ma_b * row2I[0] + a_b * row4I[0]); @@ -215,7 +217,7 @@ void bilinear_interpolation(const ImBuf *in, ImBuf *out, float u, float v, int x uchar *outI = nullptr; float *outF = nullptr; - if (in == nullptr || (in->rect == nullptr && in->rect_float == nullptr)) { + if (in == nullptr || (in->byte_buffer.data == nullptr && in->float_buffer.data == nullptr)) { return; } @@ -235,7 +237,7 @@ void nearest_interpolation_color_char( const struct ImBuf *in, uchar outI[4], float /*outF*/[4], float u, float v) { BLI_assert(outI); - BLI_assert(in->rect); + BLI_assert(in->byte_buffer.data); /* ImBuf in must have a valid rect or rect_float, assume this is already checked */ int x1 = int(u); int y1 = int(v); @@ -247,7 +249,7 @@ void nearest_interpolation_color_char( } const size_t offset = (size_t(in->x) * y1 + x1) * 4; - const uchar *dataI = (uchar *)in->rect + offset; + const uchar *dataI = in->byte_buffer.data + offset; outI[0] = dataI[0]; outI[1] = dataI[1]; outI[2] = dataI[2]; @@ -258,7 +260,7 @@ void nearest_interpolation_color_fl( const struct ImBuf *in, uchar /*outI*/[4], float outF[4], float u, float v) { BLI_assert(outF); - BLI_assert(in->rect_float); + BLI_assert(in->float_buffer.data); /* ImBuf in must have a valid rect or rect_float, assume this is already checked */ int x1 = int(u); int y1 = int(v); @@ -270,7 +272,7 @@ void nearest_interpolation_color_fl( } const size_t offset = (size_t(in->x) * y1 + x1) * 4; - const float *dataF = in->rect_float + offset; + const float *dataF = in->float_buffer.data + offset; copy_v4_v4(outF, dataF); } @@ -308,14 +310,14 @@ void nearest_interpolation_color_wrap( y += in->y; } - dataI = (uchar *)in->rect + size_t(in->x) * y * 4 + 4 * x; + dataI = in->byte_buffer.data + size_t(in->x) * y * 4 + 4 * x; if (outI) { outI[0] = dataI[0]; outI[1] = dataI[1]; outI[2] = dataI[2]; outI[3] = dataI[3]; } - dataF = in->rect_float + size_t(in->x) * y * 4 + 4 * x; + dataF = in->float_buffer.data + size_t(in->x) * y * 4 + 4 * x; if (outF) { outF[0] = dataF[0]; outF[1] = dataF[1]; @@ -329,7 +331,7 @@ void nearest_interpolation(const ImBuf *in, ImBuf *out, float u, float v, int xo uchar *outI = nullptr; float *outF = nullptr; - if (in == nullptr || (in->rect == nullptr && in->rect_float == nullptr)) { + if (in == nullptr || (in->byte_buffer.data == nullptr && in->float_buffer.data == nullptr)) { return; } @@ -481,7 +483,7 @@ void IMB_alpha_under_color_byte(uchar *rect, int x, int y, const float backcol[3 void IMB_sampleImageAtLocation(ImBuf *ibuf, float x, float y, bool make_linear_rgb, float color[4]) { - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { nearest_interpolation_color(ibuf, nullptr, color, x, y); } else { diff --git a/source/blender/imbuf/intern/indexer.cc b/source/blender/imbuf/intern/indexer.cc index 99918969a6d..29b26cf76ef 100644 --- a/source/blender/imbuf/intern/indexer.cc +++ b/source/blender/imbuf/intern/indexer.cc @@ -1392,10 +1392,9 @@ static void index_rebuild_fallback(FallbackIndexBuilderContext *context, IMB_convert_rgba_to_abgr(s_ibuf); - AVI_write_frame(context->proxy_ctx[i], pos, AVI_FORMAT_RGB32, s_ibuf->rect, x * y * 4); - /* note that libavi free's the buffer... */ - s_ibuf->rect = nullptr; + uint8_t *rect = IMB_steal_byte_buffer(s_ibuf); + AVI_write_frame(context->proxy_ctx[i], pos, AVI_FORMAT_RGB32, rect, x * y * 4); IMB_freeImBuf(s_ibuf); } diff --git a/source/blender/imbuf/intern/iris.cc b/source/blender/imbuf/intern/iris.cc index 7fec0f62036..6e80e2ccee1 100644 --- a/source/blender/imbuf/intern/iris.cc +++ b/source/blender/imbuf/intern/iris.cc @@ -210,12 +210,12 @@ static void test_endian_zbuf(struct ImBuf *ibuf) return; #endif - if (ibuf->zbuf == nullptr) { + if (ibuf->z_buffer.data == nullptr) { return; } len = ibuf->x * ibuf->y; - zval = ibuf->zbuf; + zval = ibuf->z_buffer.data; while (len--) { zval[0] = BIG_LONG(zval[0]); @@ -336,8 +336,8 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors if (ibuf->planes > 32) { ibuf->planes = 32; } - base = ibuf->rect; - zbase = (uint *)ibuf->zbuf; + base = (uint *)ibuf->byte_buffer.data; + zbase = (uint *)ibuf->z_buffer.data; if (badorder) { for (size_t z = 0; z < zsize; z++) { @@ -389,7 +389,7 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors goto fail_rle; } - fbase = ibuf->rect_float; + fbase = ibuf->float_buffer.data; if (badorder) { for (size_t z = 0; z < zsize; z++) { @@ -452,8 +452,8 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors ibuf->planes = 32; } - base = ibuf->rect; - zbase = (uint *)ibuf->zbuf; + base = (uint *)ibuf->byte_buffer.data; + zbase = (uint *)ibuf->z_buffer.data; MFILE_SEEK(inf, HEADER_SIZE); rledat = MFILE_DATA(inf); @@ -484,7 +484,7 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors goto fail_uncompressed; } - fbase = ibuf->rect_float; + fbase = ibuf->float_buffer.data; MFILE_SEEK(inf, HEADER_SIZE); rledat = MFILE_DATA(inf); @@ -514,7 +514,7 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors uchar *rect; if (image.zsize == 1) { - rect = (uchar *)ibuf->rect; + rect = ibuf->byte_buffer.data; for (size_t x = size_t(ibuf->x) * size_t(ibuf->y); x > 0; x--) { rect[0] = 255; rect[1] = rect[2] = rect[3]; @@ -523,7 +523,7 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors } else if (image.zsize == 2) { /* Gray-scale with alpha. */ - rect = (uchar *)ibuf->rect; + rect = ibuf->byte_buffer.data; for (size_t x = size_t(ibuf->x) * size_t(ibuf->y); x > 0; x--) { rect[0] = rect[2]; rect[1] = rect[2] = rect[3]; @@ -532,7 +532,7 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors } else if (image.zsize == 3) { /* add alpha */ - rect = (uchar *)ibuf->rect; + rect = ibuf->byte_buffer.data; for (size_t x = size_t(ibuf->x) * size_t(ibuf->y); x > 0; x--) { rect[0] = 255; rect += 4; @@ -542,7 +542,7 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors else { /* bpp == 2 */ if (image.zsize == 1) { - fbase = ibuf->rect_float; + fbase = ibuf->float_buffer.data; for (size_t x = size_t(ibuf->x) * size_t(ibuf->y); x > 0; x--) { fbase[0] = 1; fbase[1] = fbase[2] = fbase[3]; @@ -551,7 +551,7 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors } else if (image.zsize == 2) { /* Gray-scale with alpha. */ - fbase = ibuf->rect_float; + fbase = ibuf->float_buffer.data; for (size_t x = size_t(ibuf->x) * size_t(ibuf->y); x > 0; x--) { fbase[0] = fbase[2]; fbase[1] = fbase[2] = fbase[3]; @@ -560,7 +560,7 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors } else if (image.zsize == 3) { /* add alpha */ - fbase = ibuf->rect_float; + fbase = ibuf->float_buffer.data; for (size_t x = size_t(ibuf->x) * size_t(ibuf->y); x > 0; x--) { fbase[0] = 1; fbase += 4; @@ -579,7 +579,7 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors test_endian_zbuf(ibuf); - if (ibuf->rect) { + if (ibuf->byte_buffer.data) { IMB_convert_rgba_to_abgr(ibuf); } @@ -965,14 +965,15 @@ bool imb_saveiris(struct ImBuf *ibuf, const char *filepath, int flags) short zsize; zsize = (ibuf->planes + 7) >> 3; - if (flags & IB_zbuf && ibuf->zbuf != nullptr) { + if (flags & IB_zbuf && ibuf->z_buffer.data != nullptr) { zsize = 8; } IMB_convert_rgba_to_abgr(ibuf); test_endian_zbuf(ibuf); - const bool ok = output_iris(filepath, ibuf->rect, ibuf->zbuf, ibuf->x, ibuf->y, zsize); + const bool ok = output_iris( + filepath, (uint *)ibuf->byte_buffer.data, ibuf->z_buffer.data, ibuf->x, ibuf->y, zsize); /* restore! Quite clumsy, 2 times a switch... maybe better a malloc ? */ IMB_convert_rgba_to_abgr(ibuf); diff --git a/source/blender/imbuf/intern/jp2.cc b/source/blender/imbuf/intern/jp2.cc index 02bddcd4fdf..1d23e33cdd5 100644 --- a/source/blender/imbuf/intern/jp2.cc +++ b/source/blender/imbuf/intern/jp2.cc @@ -450,7 +450,7 @@ static ImBuf *imb_load_jp2_stream(opj_stream_t *stream, } if (use_float) { - float *rect_float = ibuf->rect_float; + float *rect_float = ibuf->float_buffer.data; if (image->numcomps < 3) { r = image->comps[0].data; @@ -503,7 +503,7 @@ static ImBuf *imb_load_jp2_stream(opj_stream_t *stream, } } else { - uchar *rect_uchar = (uchar *)ibuf->rect; + uchar *rect_uchar = ibuf->byte_buffer.data; if (image->numcomps < 3) { r = image->comps[0].data; @@ -907,8 +907,8 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters) image->y1 = image->y0 + (h - 1) * subsampling_dy + 1 + image->y0; /* set image data */ - rect_uchar = (uchar *)ibuf->rect; - rect_float = ibuf->rect_float; + rect_uchar = ibuf->byte_buffer.data; + rect_float = ibuf->float_buffer.data; /* set the destination channels */ r = image->comps[0].data; diff --git a/source/blender/imbuf/intern/jpeg.cc b/source/blender/imbuf/intern/jpeg.cc index 3dffe885fd8..c00c6ba538c 100644 --- a/source/blender/imbuf/intern/jpeg.cc +++ b/source/blender/imbuf/intern/jpeg.cc @@ -315,7 +315,7 @@ static ImBuf *ibJpegImageFromCinfo(struct jpeg_decompress_struct *cinfo, for (y = ibuf->y - 1; y >= 0; y--) { jpeg_read_scanlines(cinfo, row_pointer, 1); - rect = (uchar *)(ibuf->rect + y * ibuf->x); + rect = ibuf->byte_buffer.data + 4 * y * ibuf->x; buffer = row_pointer[0]; switch (depth) { @@ -626,7 +626,7 @@ static void write_jpeg(struct jpeg_compress_struct *cinfo, struct ImBuf *ibuf) sizeof(JSAMPLE) * cinfo->input_components * cinfo->image_width, "jpeg row_pointer")); for (y = ibuf->y - 1; y >= 0; y--) { - rect = (uchar *)(ibuf->rect + y * ibuf->x); + rect = ibuf->byte_buffer.data + 4 * y * ibuf->x; buffer = row_pointer[0]; switch (cinfo->in_color_space) { diff --git a/source/blender/imbuf/intern/oiio/openimageio_support.cc b/source/blender/imbuf/intern/oiio/openimageio_support.cc index 962d625b028..688784cde0a 100644 --- a/source/blender/imbuf/intern/oiio/openimageio_support.cc +++ b/source/blender/imbuf/intern/oiio/openimageio_support.cc @@ -41,17 +41,17 @@ class ImBufMemWriter : public Filesystem::IOProxy { { /* If buffer is too small increase it. */ size_t end = offset + size; - while (end > ibuf_->encodedbuffersize) { + while (end > ibuf_->encoded_buffer_size) { if (!imb_enlargeencodedbufferImBuf(ibuf_)) { /* Out of memory. */ return 0; } } - memcpy(ibuf_->encodedbuffer + offset, buf, size); + memcpy(ibuf_->encoded_buffer.data + offset, buf, size); - if (end > ibuf_->encodedsize) { - ibuf_->encodedsize = end; + if (end > ibuf_->encoded_size) { + ibuf_->encoded_size = end; } return size; @@ -59,7 +59,7 @@ class ImBufMemWriter : public Filesystem::IOProxy { size_t size() const override { - return ibuf_->encodedsize; + return ibuf_->encoded_size; } private: @@ -116,8 +116,8 @@ static ImBuf *load_pixels( const stride_t ibuf_xstride = sizeof(T) * 4; const stride_t ibuf_ystride = ibuf_xstride * width; const TypeDesc format = is_float ? TypeDesc::FLOAT : TypeDesc::UINT8; - uchar *rect = is_float ? reinterpret_cast(ibuf->rect_float) : - reinterpret_cast(ibuf->rect); + uchar *rect = is_float ? reinterpret_cast(ibuf->float_buffer.data) : + reinterpret_cast(ibuf->byte_buffer.data); void *ibuf_data = rect + ((stride_t(height) - 1) * ibuf_ystride); bool ok = in->read_image( @@ -340,19 +340,19 @@ WriteContext imb_create_write_context(const char *file_format, const int width = ibuf->x; const int height = ibuf->y; - const bool use_float = prefer_float && (ibuf->rect_float != nullptr); + const bool use_float = prefer_float && (ibuf->float_buffer.data != nullptr); if (use_float) { const int mem_channels = ibuf->channels ? ibuf->channels : 4; ctx.mem_xstride = sizeof(float) * mem_channels; ctx.mem_ystride = width * ctx.mem_xstride; - ctx.mem_start = reinterpret_cast(ibuf->rect_float); + ctx.mem_start = reinterpret_cast(ibuf->float_buffer.data); ctx.mem_spec = ImageSpec(width, height, mem_channels, TypeDesc::FLOAT); } else { const int mem_channels = 4; ctx.mem_xstride = sizeof(uchar) * mem_channels; ctx.mem_ystride = width * ctx.mem_xstride; - ctx.mem_start = reinterpret_cast(ibuf->rect); + ctx.mem_start = ibuf->byte_buffer.data; ctx.mem_spec = ImageSpec(width, height, mem_channels, TypeDesc::UINT8); } diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index 3da47fdeeeb..d89609d7d2f 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -280,9 +280,9 @@ class OMemStream : public OStream { void write(const char c[], int n) override { ensure_size(offset + n); - memcpy(ibuf->encodedbuffer + offset, c, n); + memcpy(ibuf->encoded_buffer.data + offset, c, n); offset += n; - ibuf->encodedsize += n; + ibuf->encoded_size += n; } exr_file_offset_t tellp() override @@ -300,7 +300,7 @@ class OMemStream : public OStream { void ensure_size(exr_file_offset_t size) { /* if buffer is too small increase it. */ - while (size > ibuf->encodedbuffersize) { + while (size > ibuf->encoded_buffer_size) { if (!imb_enlargeencodedbufferImBuf(ibuf)) { throw Iex::ErrnoExc("Out of memory."); } @@ -462,7 +462,8 @@ static bool imb_save_openexr_half(ImBuf *ibuf, const char *filepath, const int f { const int channels = ibuf->channels; const bool is_alpha = (channels >= 4) && (ibuf->planes == 32); - const bool is_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != nullptr; /* summarize */ + const bool is_zbuf = (flags & IB_zbuffloat) && + ibuf->float_z_buffer.data != nullptr; /* summarize */ const int width = ibuf->x; const int height = ibuf->y; OStream *file_stream = nullptr; @@ -512,15 +513,15 @@ static bool imb_save_openexr_half(ImBuf *ibuf, const char *filepath, const int f if (is_zbuf) { frameBuffer.insert("Z", Slice(Imf::FLOAT, - (char *)(ibuf->zbuf_float + (height - 1) * width), + (char *)(ibuf->float_z_buffer.data + (height - 1) * width), sizeof(float), sizeof(float) * -width)); } - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { float *from; for (int i = ibuf->y - 1; i >= 0; i--) { - from = ibuf->rect_float + channels * i * width; + from = ibuf->float_buffer.data + channels * i * width; for (int j = ibuf->x; j > 0; j--) { to->r = float_to_half_safe(from[0]); @@ -536,7 +537,7 @@ static bool imb_save_openexr_half(ImBuf *ibuf, const char *filepath, const int f uchar *from; for (int i = ibuf->y - 1; i >= 0; i--) { - from = (uchar *)ibuf->rect + 4 * i * width; + from = ibuf->byte_buffer.data + 4 * i * width; for (int j = ibuf->x; j > 0; j--) { to->r = srgb_to_linearrgb(float(from[0]) / 255.0f); @@ -575,7 +576,8 @@ static bool imb_save_openexr_float(ImBuf *ibuf, const char *filepath, const int { const int channels = ibuf->channels; const bool is_alpha = (channels >= 4) && (ibuf->planes == 32); - const bool is_zbuf = (flags & IB_zbuffloat) && ibuf->zbuf_float != nullptr; /* summarize */ + const bool is_zbuf = (flags & IB_zbuffloat) && + ibuf->float_z_buffer.data != nullptr; /* summarize */ const int width = ibuf->x; const int height = ibuf->y; OStream *file_stream = nullptr; @@ -613,7 +615,7 @@ static bool imb_save_openexr_float(ImBuf *ibuf, const char *filepath, const int /* Last scan-line, stride negative. */ float *rect[4] = {nullptr, nullptr, nullptr, nullptr}; - rect[0] = ibuf->rect_float + channels * (height - 1) * width; + rect[0] = ibuf->float_buffer.data + channels * (height - 1) * width; rect[1] = (channels >= 2) ? rect[0] + 1 : rect[0]; rect[2] = (channels >= 3) ? rect[0] + 2 : rect[0]; rect[3] = (channels >= 4) ? @@ -629,7 +631,7 @@ static bool imb_save_openexr_float(ImBuf *ibuf, const char *filepath, const int if (is_zbuf) { frameBuffer.insert("Z", Slice(Imf::FLOAT, - (char *)(ibuf->zbuf_float + (height - 1) * width), + (char *)(ibuf->float_z_buffer.data + (height - 1) * width), sizeof(float), sizeof(float) * -width)); } @@ -656,7 +658,7 @@ bool imb_save_openexr(struct ImBuf *ibuf, const char *filepath, int flags) { if (flags & IB_mem) { imb_addencodedbufferImBuf(ibuf); - ibuf->encodedsize = 0; + ibuf->encoded_size = 0; } if (ibuf->foptions.flag & OPENEXR_HALF) { @@ -664,7 +666,7 @@ bool imb_save_openexr(struct ImBuf *ibuf, const char *filepath, int flags) } /* when no float rect, we save as half (16 bits is sufficient) */ - if (ibuf->rect_float == nullptr) { + if (ibuf->float_buffer.data == nullptr) { return imb_save_openexr_half(ibuf, filepath, flags); } @@ -2081,7 +2083,7 @@ struct ImBuf *imb_load_openexr(const uchar *mem, /* Inverse correct first pixel for data-window * coordinates (- dw.min.y because of y flip). */ - first = ibuf->rect_float - 4 * (dw.min.x - dw.min.y * width); + first = ibuf->float_buffer.data - 4 * (dw.min.x - dw.min.y * width); /* But, since we read y-flipped (negative y stride) we move to last scan-line. */ first += 4 * (height - 1) * width; @@ -2110,7 +2112,7 @@ struct ImBuf *imb_load_openexr(const uchar *mem, float *firstz; addzbuffloatImBuf(ibuf); - firstz = ibuf->zbuf_float - (dw.min.x - dw.min.y * width); + firstz = ibuf->float_z_buffer.data - (dw.min.x - dw.min.y * width); firstz += (height - 1) * width; frameBuffer.insert( "Z", Slice(Imf::FLOAT, (char *)firstz, sizeof(float), -width * sizeof(float))); @@ -2135,7 +2137,7 @@ struct ImBuf *imb_load_openexr(const uchar *mem, if (num_rgb_channels == 0 && has_luma && exr_has_chroma(*file)) { for (size_t a = 0; a < size_t(ibuf->x) * ibuf->y; a++) { - float *color = ibuf->rect_float + a * 4; + float *color = ibuf->float_buffer.data + a * 4; ycc_to_rgb(color[0] * 255.0f, color[1] * 255.0f, color[2] * 255.0f, @@ -2148,7 +2150,7 @@ struct ImBuf *imb_load_openexr(const uchar *mem, else if (num_rgb_channels <= 1) { /* Convert 1 to 3 channels. */ for (size_t a = 0; a < size_t(ibuf->x) * ibuf->y; a++) { - float *color = ibuf->rect_float + a * 4; + float *color = ibuf->float_buffer.data + a * 4; if (num_rgb_channels <= 1) { color[1] = color[0]; } @@ -2238,7 +2240,7 @@ struct ImBuf *imb_load_filepath_thumbnail_openexr(const char *filepath, if (file->header().hasPreviewImage()) { const Imf::PreviewImage &preview = file->header().previewImage(); ImBuf *ibuf = IMB_allocFromBuffer( - (uint *)preview.pixels(), nullptr, preview.width(), preview.height(), 4); + (uint8_t *)preview.pixels(), nullptr, preview.width(), preview.height(), 4); delete file; delete stream; IMB_flipy(ibuf); @@ -2272,7 +2274,7 @@ struct ImBuf *imb_load_filepath_thumbnail_openexr(const char *filepath, for (int w = 0; w < dest_w; w++) { /* For each destination pixel find single corresponding source pixel. */ int source_x = int(MIN2((w / scale_factor), dw.max.x - 1)); - float *dest_px = &ibuf->rect_float[(h * dest_w + w) * 4]; + float *dest_px = &ibuf->float_buffer.data[(h * dest_w + w) * 4]; dest_px[0] = pixels[source_x].r; dest_px[1] = pixels[source_x].g; dest_px[2] = pixels[source_x].b; diff --git a/source/blender/imbuf/intern/readimage.cc b/source/blender/imbuf/intern/readimage.cc index ac4fd2ddbb2..a71ddd3d8c7 100644 --- a/source/blender/imbuf/intern/readimage.cc +++ b/source/blender/imbuf/intern/readimage.cc @@ -35,7 +35,7 @@ static void imb_handle_alpha(ImBuf *ibuf, char effective_colorspace[IM_MAX_SPACE]) { if (colorspace) { - if (ibuf->rect != nullptr && ibuf->rect_float == nullptr) { + if (ibuf->byte_buffer.data != nullptr && ibuf->float_buffer.data == nullptr) { /* byte buffer is never internally converted to some standard space, * store pointer to its color space descriptor instead */ @@ -59,7 +59,7 @@ static void imb_handle_alpha(ImBuf *ibuf, } else { if (alpha_flags & IB_alphamode_premul) { - if (ibuf->rect) { + if (ibuf->byte_buffer.data) { IMB_unpremultiply_alpha(ibuf); } else { @@ -67,7 +67,7 @@ static void imb_handle_alpha(ImBuf *ibuf, } } else { - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { IMB_premultiply_alpha(ibuf); } else { diff --git a/source/blender/imbuf/intern/rectop.cc b/source/blender/imbuf/intern/rectop.cc index 238db526c53..69b67c6cfb4 100644 --- a/source/blender/imbuf/intern/rectop.cc +++ b/source/blender/imbuf/intern/rectop.cc @@ -252,10 +252,11 @@ void IMB_rect_crop(ImBuf *ibuf, const rcti *crop) return; } - rect_crop_4bytes((void **)&ibuf->rect, size_src, crop); - rect_crop_4bytes((void **)&ibuf->zbuf, size_src, crop); - rect_crop_4bytes((void **)&ibuf->zbuf_float, size_src, crop); - rect_crop_16bytes((void **)&ibuf->rect_float, size_src, crop); + /* TODO(sergey: Validate ownership. */ + rect_crop_4bytes((void **)&ibuf->byte_buffer.data, size_src, crop); + rect_crop_4bytes((void **)&ibuf->z_buffer.data, size_src, crop); + rect_crop_4bytes((void **)&ibuf->float_z_buffer.data, size_src, crop); + rect_crop_16bytes((void **)&ibuf->float_buffer.data, size_src, crop); ibuf->x = size_dst[0]; ibuf->y = size_dst[1]; @@ -289,10 +290,11 @@ void IMB_rect_size_set(ImBuf *ibuf, const uint size[2]) return; } - rect_realloc_4bytes((void **)&ibuf->rect, size); - rect_realloc_4bytes((void **)&ibuf->zbuf, size); - rect_realloc_4bytes((void **)&ibuf->zbuf_float, size); - rect_realloc_16bytes((void **)&ibuf->rect_float, size); + /* TODO(sergey: Validate ownership. */ + rect_realloc_4bytes((void **)&ibuf->byte_buffer.data, size); + rect_realloc_4bytes((void **)&ibuf->z_buffer.data, size); + rect_realloc_4bytes((void **)&ibuf->float_z_buffer.data, size); + rect_realloc_16bytes((void **)&ibuf->float_buffer.data, size); ibuf->x = size[0]; ibuf->y = size[1]; @@ -533,16 +535,18 @@ void IMB_rectblend(ImBuf *dbuf, return; } - const bool do_char = (sbuf && sbuf->rect && dbuf->rect && obuf->rect); - const bool do_float = (sbuf && sbuf->rect_float && dbuf->rect_float && obuf->rect_float); + const bool do_char = (sbuf && sbuf->byte_buffer.data && dbuf->byte_buffer.data && + obuf->byte_buffer.data); + const bool do_float = (sbuf && sbuf->float_buffer.data && dbuf->float_buffer.data && + obuf->float_buffer.data); if (do_char) { - drect = dbuf->rect + size_t(desty) * dbuf->x + destx; - orect = obuf->rect + size_t(origy) * obuf->x + origx; + drect = (uint *)dbuf->byte_buffer.data + size_t(desty) * dbuf->x + destx; + orect = (uint *)obuf->byte_buffer.data + size_t(origy) * obuf->x + origx; } if (do_float) { - drectf = dbuf->rect_float + (size_t(desty) * dbuf->x + destx) * 4; - orectf = obuf->rect_float + (size_t(origy) * obuf->x + origx) * 4; + drectf = dbuf->float_buffer.data + (size_t(desty) * dbuf->x + destx) * 4; + orectf = obuf->float_buffer.data + (size_t(origy) * obuf->x + origx) * 4; } if (dmaskrect) { @@ -554,10 +558,10 @@ void IMB_rectblend(ImBuf *dbuf, if (sbuf) { if (do_char) { - srect = sbuf->rect + size_t(srcy) * sbuf->x + srcx; + srect = (uint *)sbuf->byte_buffer.data + size_t(srcy) * sbuf->x + srcx; } if (do_float) { - srectf = sbuf->rect_float + (size_t(srcy) * sbuf->x + srcx) * 4; + srectf = sbuf->float_buffer.data + (size_t(srcy) * sbuf->x + srcx) * 4; } srcskip = sbuf->x; @@ -1049,8 +1053,8 @@ void IMB_rectfill(ImBuf *drect, const float col[4]) { int num; - if (drect->rect) { - uint *rrect = drect->rect; + if (drect->byte_buffer.data) { + uint *rrect = (uint *)drect->byte_buffer.data; char ccol[4]; ccol[0] = int(col[0] * 255); @@ -1064,8 +1068,8 @@ void IMB_rectfill(ImBuf *drect, const float col[4]) } } - if (drect->rect_float) { - float *rrectf = drect->rect_float; + if (drect->float_buffer.data) { + float *rrectf = drect->float_buffer.data; num = drect->x * drect->y; for (; num > 0; num--) { @@ -1111,13 +1115,13 @@ void IMB_rectfill_area_replace( for (int x = x1; x < x2; x++) { size_t offset = size_t(ibuf->x) * y * 4 + 4 * x; - if (ibuf->rect) { - uchar *rrect = (uchar *)ibuf->rect + offset; + if (ibuf->byte_buffer.data) { + uchar *rrect = ibuf->byte_buffer.data + offset; memcpy(rrect, col_char, sizeof(uchar[4])); } - if (ibuf->rect_float) { - float *rrectf = ibuf->rect_float + offset; + if (ibuf->float_buffer.data) { + float *rrectf = ibuf->float_buffer.data + offset; memcpy(rrectf, col, sizeof(float[4])); } } @@ -1246,24 +1250,32 @@ void IMB_rectfill_area(ImBuf *ibuf, if (!ibuf) { return; } - buf_rectfill_area( - (uchar *)ibuf->rect, ibuf->rect_float, ibuf->x, ibuf->y, col, display, x1, y1, x2, y2); + buf_rectfill_area(ibuf->byte_buffer.data, + ibuf->float_buffer.data, + ibuf->x, + ibuf->y, + col, + display, + x1, + y1, + x2, + y2); } void IMB_rectfill_alpha(ImBuf *ibuf, const float value) { int i; - if (ibuf->rect_float && (ibuf->channels == 4)) { - float *fbuf = ibuf->rect_float + 3; + if (ibuf->float_buffer.data && (ibuf->channels == 4)) { + float *fbuf = ibuf->float_buffer.data + 3; for (i = ibuf->x * ibuf->y; i > 0; i--, fbuf += 4) { *fbuf = value; } } - if (ibuf->rect) { + if (ibuf->byte_buffer.data) { const uchar cvalue = value * 255; - uchar *cbuf = ((uchar *)ibuf->rect) + 3; + uchar *cbuf = ibuf->byte_buffer.data + 3; for (i = ibuf->x * ibuf->y; i > 0; i--, cbuf += 4) { *cbuf = cvalue; } diff --git a/source/blender/imbuf/intern/rotate.cc b/source/blender/imbuf/intern/rotate.cc index 037eabca045..20ba5a2cb91 100644 --- a/source/blender/imbuf/intern/rotate.cc +++ b/source/blender/imbuf/intern/rotate.cc @@ -21,7 +21,7 @@ void IMB_flipy(struct ImBuf *ibuf) return; } - if (ibuf->rect) { + if (ibuf->byte_buffer.data) { uint *top, *bottom, *line; x_size = ibuf->x; @@ -29,7 +29,7 @@ void IMB_flipy(struct ImBuf *ibuf) const size_t stride = x_size * sizeof(int); - top = ibuf->rect; + top = (uint *)ibuf->byte_buffer.data; bottom = top + ((y_size - 1) * x_size); line = static_cast(MEM_mallocN(stride, "linebuf")); @@ -46,7 +46,7 @@ void IMB_flipy(struct ImBuf *ibuf) MEM_freeN(line); } - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { float *topf = nullptr, *bottomf = nullptr, *linef = nullptr; x_size = ibuf->x; @@ -54,7 +54,7 @@ void IMB_flipy(struct ImBuf *ibuf) const size_t stride = x_size * 4 * sizeof(float); - topf = ibuf->rect_float; + topf = ibuf->float_buffer.data; bottomf = topf + 4 * ((y_size - 1) * x_size); linef = static_cast(MEM_mallocN(stride, "linebuf")); @@ -84,24 +84,25 @@ void IMB_flipx(struct ImBuf *ibuf) x = ibuf->x; y = ibuf->y; - if (ibuf->rect) { + if (ibuf->byte_buffer.data) { + uint *rect = (uint *)ibuf->byte_buffer.data; for (yi = y - 1; yi >= 0; yi--) { const size_t x_offset = size_t(x) * yi; for (xr = x - 1, xl = 0; xr >= xl; xr--, xl++) { - SWAP(uint, ibuf->rect[x_offset + xr], ibuf->rect[x_offset + xl]); + SWAP(uint, rect[x_offset + xr], rect[x_offset + xl]); } } } - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { + float *rect_float = ibuf->float_buffer.data; for (yi = y - 1; yi >= 0; yi--) { const size_t x_offset = size_t(x) * yi; for (xr = x - 1, xl = 0; xr >= xl; xr--, xl++) { - memcpy(&px_f, &ibuf->rect_float[(x_offset + xr) * 4], sizeof(float[4])); - memcpy(&ibuf->rect_float[(x_offset + xr) * 4], - &ibuf->rect_float[(x_offset + xl) * 4], - sizeof(float[4])); - memcpy(&ibuf->rect_float[(x_offset + xl) * 4], &px_f, sizeof(float[4])); + memcpy(&px_f, &rect_float[(x_offset + xr) * 4], sizeof(float[4])); + memcpy( + &rect_float[(x_offset + xr) * 4], &rect_float[(x_offset + xl) * 4], sizeof(float[4])); + memcpy(&rect_float[(x_offset + xl) * 4], &px_f, sizeof(float[4])); } } } diff --git a/source/blender/imbuf/intern/scaling.cc b/source/blender/imbuf/intern/scaling.cc index e8a659734e7..cdee47de1fa 100644 --- a/source/blender/imbuf/intern/scaling.cc +++ b/source/blender/imbuf/intern/scaling.cc @@ -28,14 +28,14 @@ static void imb_half_x_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1) float af, rf, gf, bf, *p1f, *_p1f, *destf; bool do_rect, do_float; - do_rect = (ibuf1->rect != nullptr); - do_float = (ibuf1->rect_float != nullptr && ibuf2->rect_float != nullptr); + do_rect = (ibuf1->byte_buffer.data != nullptr); + do_float = (ibuf1->float_buffer.data != nullptr && ibuf2->float_buffer.data != nullptr); - _p1 = (uchar *)ibuf1->rect; - dest = (uchar *)ibuf2->rect; + _p1 = ibuf1->byte_buffer.data; + dest = ibuf2->byte_buffer.data; - _p1f = ibuf1->rect_float; - destf = ibuf2->rect_float; + _p1f = ibuf1->float_buffer.data; + destf = ibuf2->float_buffer.data; for (y = ibuf2->y; y > 0; y--) { p1 = _p1; @@ -86,7 +86,7 @@ struct ImBuf *IMB_half_x(struct ImBuf *ibuf1) if (ibuf1 == nullptr) { return nullptr; } - if (ibuf1->rect == nullptr && ibuf1->rect_float == nullptr) { + if (ibuf1->byte_buffer.data == nullptr && ibuf1->float_buffer.data == nullptr) { return nullptr; } @@ -113,22 +113,22 @@ struct ImBuf *IMB_double_fast_x(struct ImBuf *ibuf1) if (ibuf1 == nullptr) { return nullptr; } - if (ibuf1->rect == nullptr && ibuf1->rect_float == nullptr) { + if (ibuf1->byte_buffer.data == nullptr && ibuf1->float_buffer.data == nullptr) { return nullptr; } - do_rect = (ibuf1->rect != nullptr); - do_float = (ibuf1->rect_float != nullptr); + do_rect = (ibuf1->byte_buffer.data != nullptr); + do_float = (ibuf1->float_buffer.data != nullptr); ibuf2 = IMB_allocImBuf(2 * ibuf1->x, ibuf1->y, ibuf1->planes, ibuf1->flags); if (ibuf2 == nullptr) { return nullptr; } - p1 = (int *)ibuf1->rect; - dest = (int *)ibuf2->rect; - p1f = (float *)ibuf1->rect_float; - destf = (float *)ibuf2->rect_float; + p1 = (int *)ibuf1->byte_buffer.data; + dest = (int *)ibuf2->byte_buffer.data; + p1f = (float *)ibuf1->float_buffer.data; + destf = (float *)ibuf2->float_buffer.data; for (i = ibuf1->y * ibuf1->x; i > 0; i--) { if (do_rect) { @@ -156,7 +156,7 @@ struct ImBuf *IMB_double_x(struct ImBuf *ibuf1) if (ibuf1 == nullptr) { return nullptr; } - if (ibuf1->rect == nullptr && ibuf1->rect_float == nullptr) { + if (ibuf1->byte_buffer.data == nullptr && ibuf1->float_buffer.data == nullptr) { return nullptr; } @@ -176,13 +176,14 @@ static void imb_half_y_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1) p1 = p2 = nullptr; p1f = p2f = nullptr; - const bool do_rect = (ibuf1->rect != nullptr); - const bool do_float = (ibuf1->rect_float != nullptr && ibuf2->rect_float != nullptr); + const bool do_rect = (ibuf1->byte_buffer.data != nullptr); + const bool do_float = (ibuf1->float_buffer.data != nullptr && + ibuf2->float_buffer.data != nullptr); - _p1 = (uchar *)ibuf1->rect; - dest = (uchar *)ibuf2->rect; - _p1f = (float *)ibuf1->rect_float; - destf = (float *)ibuf2->rect_float; + _p1 = ibuf1->byte_buffer.data; + dest = ibuf2->byte_buffer.data; + _p1f = (float *)ibuf1->float_buffer.data; + destf = (float *)ibuf2->float_buffer.data; for (y = ibuf2->y; y > 0; y--) { if (do_rect) { @@ -239,7 +240,7 @@ struct ImBuf *IMB_half_y(struct ImBuf *ibuf1) if (ibuf1 == nullptr) { return nullptr; } - if (ibuf1->rect == nullptr && ibuf1->rect_float == nullptr) { + if (ibuf1->byte_buffer.data == nullptr && ibuf1->float_buffer.data == nullptr) { return nullptr; } @@ -267,22 +268,22 @@ struct ImBuf *IMB_double_fast_y(struct ImBuf *ibuf1) if (ibuf1 == nullptr) { return nullptr; } - if (ibuf1->rect == nullptr && ibuf1->rect_float == nullptr) { + if (ibuf1->byte_buffer.data == nullptr && ibuf1->float_buffer.data == nullptr) { return nullptr; } - const bool do_rect = (ibuf1->rect != nullptr); - const bool do_float = (ibuf1->rect_float != nullptr); + const bool do_rect = (ibuf1->byte_buffer.data != nullptr); + const bool do_float = (ibuf1->float_buffer.data != nullptr); ibuf2 = IMB_allocImBuf(ibuf1->x, 2 * ibuf1->y, ibuf1->planes, ibuf1->flags); if (ibuf2 == nullptr) { return nullptr; } - p1 = (int *)ibuf1->rect; - dest1 = (int *)ibuf2->rect; - p1f = (float *)ibuf1->rect_float; - dest1f = (float *)ibuf2->rect_float; + p1 = (int *)ibuf1->byte_buffer.data; + dest1 = (int *)ibuf2->byte_buffer.data; + p1f = (float *)ibuf1->float_buffer.data; + dest1f = (float *)ibuf2->float_buffer.data; for (y = ibuf1->y; y > 0; y--) { if (do_rect) { @@ -311,7 +312,7 @@ struct ImBuf *IMB_double_y(struct ImBuf *ibuf1) if (ibuf1 == nullptr) { return nullptr; } - if (ibuf1->rect == nullptr) { + if (ibuf1->byte_buffer.data == nullptr) { return nullptr; } @@ -355,10 +356,11 @@ MINLINE void premul_ushort_to_straight_uchar(uchar *result, const ushort color[4 void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1) { int x, y; - const bool do_rect = (ibuf1->rect != nullptr); - const bool do_float = (ibuf1->rect_float != nullptr) && (ibuf2->rect_float != nullptr); + const bool do_rect = (ibuf1->byte_buffer.data != nullptr); + const bool do_float = (ibuf1->float_buffer.data != nullptr) && + (ibuf2->float_buffer.data != nullptr); - if (do_rect && (ibuf2->rect == nullptr)) { + if (do_rect && (ibuf2->byte_buffer.data == nullptr)) { imb_addrectImBuf(ibuf2); } @@ -374,8 +376,8 @@ void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1) if (do_rect) { uchar *cp1, *cp2, *dest; - cp1 = (uchar *)ibuf1->rect; - dest = (uchar *)ibuf2->rect; + cp1 = ibuf1->byte_buffer.data; + dest = ibuf2->byte_buffer.data; for (y = ibuf2->y; y > 0; y--) { cp2 = cp1 + (ibuf1->x << 2); @@ -408,8 +410,8 @@ void imb_onehalf_no_alloc(struct ImBuf *ibuf2, struct ImBuf *ibuf1) if (do_float) { float *p1f, *p2f, *destf; - p1f = ibuf1->rect_float; - destf = ibuf2->rect_float; + p1f = ibuf1->float_buffer.data; + destf = ibuf2->float_buffer.data; for (y = ibuf2->y; y > 0; y--) { p2f = p1f + (ibuf1->x << 2); for (x = ibuf2->x; x > 0; x--) { @@ -436,7 +438,7 @@ ImBuf *IMB_onehalf(struct ImBuf *ibuf1) if (ibuf1 == nullptr) { return nullptr; } - if (ibuf1->rect == nullptr && ibuf1->rect_float == nullptr) { + if (ibuf1->byte_buffer.data == nullptr && ibuf1->float_buffer.data == nullptr) { return nullptr; } @@ -854,22 +856,20 @@ static bool q_scale_linear_interpolation(struct ImBuf *ibuf, int newx, int newy) return false; } - if (ibuf->rect) { + if (ibuf->byte_buffer.data) { uchar *newrect = static_cast(MEM_mallocN(sizeof(int) * newx * newy, "q_scale rect")); - q_scale_byte((uchar *)ibuf->rect, newrect, ibuf->x, ibuf->y, newx, newy); + q_scale_byte(ibuf->byte_buffer.data, newrect, ibuf->x, ibuf->y, newx, newy); - imb_freerectImBuf(ibuf); - ibuf->mall |= IB_rect; - ibuf->rect = (uint *)newrect; + IMB_assign_byte_buffer(ibuf, newrect, IB_TAKE_OWNERSHIP); } - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { float *newrect = static_cast( MEM_mallocN(sizeof(float[4]) * newx * newy, "q_scale rectfloat")); - q_scale_float(ibuf->rect_float, newrect, ibuf->x, ibuf->y, newx, newy); - imb_freerectfloatImBuf(ibuf); - ibuf->mall |= IB_rectfloat; - ibuf->rect_float = newrect; + q_scale_float(ibuf->float_buffer.data, newrect, ibuf->x, ibuf->y, newx, newy); + + IMB_assign_float_buffer(ibuf, newrect, IB_TAKE_OWNERSHIP); } + ibuf->x = newx; ibuf->y = newy; @@ -878,8 +878,8 @@ static bool q_scale_linear_interpolation(struct ImBuf *ibuf, int newx, int newy) static ImBuf *scaledownx(struct ImBuf *ibuf, int newx) { - const bool do_rect = (ibuf->rect != nullptr); - const bool do_float = (ibuf->rect_float != nullptr); + const bool do_rect = (ibuf->byte_buffer.data != nullptr); + const bool do_float = (ibuf->float_buffer.data != nullptr); const size_t rect_size = IMB_get_rect_len(ibuf) * 4; uchar *rect, *_newrect, *newrect; @@ -916,11 +916,11 @@ static ImBuf *scaledownx(struct ImBuf *ibuf, int newx) add = (ibuf->x - 0.01) / newx; if (do_rect) { - rect = (uchar *)ibuf->rect; + rect = ibuf->byte_buffer.data; newrect = _newrect; } if (do_float) { - rectf = ibuf->rect_float; + rectf = ibuf->float_buffer.data; newrectf = _newrectf; } @@ -999,19 +999,20 @@ static ImBuf *scaledownx(struct ImBuf *ibuf, int newx) } if (do_rect) { - // printf("%ld %ld\n", (uchar *)rect - ((uchar *)ibuf->rect), rect_size); - BLI_assert((uchar *)rect - ((uchar *)ibuf->rect) == rect_size); /* see bug #26502. */ + // printf("%ld %ld\n", (uchar *)rect - ibuf->byte_buffer.data, rect_size); + BLI_assert((uchar *)rect - ibuf->byte_buffer.data == rect_size); /* see bug #26502. */ + imb_freerectImBuf(ibuf); - ibuf->mall |= IB_rect; - ibuf->rect = (uint *)_newrect; + IMB_assign_byte_buffer(ibuf, _newrect, IB_TAKE_OWNERSHIP); } if (do_float) { - // printf("%ld %ld\n", rectf - ibuf->rect_float, rect_size); - BLI_assert((rectf - ibuf->rect_float) == rect_size); /* see bug #26502. */ + // printf("%ld %ld\n", rectf - ibuf->float_buffer.data, rect_size); + BLI_assert((rectf - ibuf->float_buffer.data) == rect_size); /* see bug #26502. */ + imb_freerectfloatImBuf(ibuf); - ibuf->mall |= IB_rectfloat; - ibuf->rect_float = _newrectf; + IMB_assign_float_buffer(ibuf, _newrectf, IB_TAKE_OWNERSHIP); } + (void)rect_size; /* UNUSED in release builds */ ibuf->x = newx; @@ -1020,8 +1021,8 @@ static ImBuf *scaledownx(struct ImBuf *ibuf, int newx) static ImBuf *scaledowny(struct ImBuf *ibuf, int newy) { - const bool do_rect = (ibuf->rect != nullptr); - const bool do_float = (ibuf->rect_float != nullptr); + const bool do_rect = (ibuf->byte_buffer.data != nullptr); + const bool do_float = (ibuf->float_buffer.data != nullptr); const size_t rect_size = IMB_get_rect_len(ibuf) * 4; uchar *rect, *_newrect, *newrect; @@ -1060,11 +1061,11 @@ static ImBuf *scaledowny(struct ImBuf *ibuf, int newy) for (x = skipx - 4; x >= 0; x -= 4) { if (do_rect) { - rect = ((uchar *)ibuf->rect) + x; + rect = ibuf->byte_buffer.data + x; newrect = _newrect + x; } if (do_float) { - rectf = ibuf->rect_float + x; + rectf = ibuf->float_buffer.data + x; newrectf = _newrectf + x; } @@ -1142,19 +1143,20 @@ static ImBuf *scaledowny(struct ImBuf *ibuf, int newy) } if (do_rect) { - // printf("%ld %ld\n", (uchar *)rect - ((uchar *)ibuf->rect), rect_size); - BLI_assert((uchar *)rect - ((uchar *)ibuf->rect) == rect_size); /* see bug #26502. */ + // printf("%ld %ld\n", (uchar *)rect - byte_buffer.data, rect_size); + BLI_assert((uchar *)rect - ibuf->byte_buffer.data == rect_size); /* see bug #26502. */ + imb_freerectImBuf(ibuf); - ibuf->mall |= IB_rect; - ibuf->rect = (uint *)_newrect; + IMB_assign_byte_buffer(ibuf, _newrect, IB_TAKE_OWNERSHIP); } if (do_float) { - // printf("%ld %ld\n", rectf - ibuf->rect_float, rect_size); - BLI_assert((rectf - ibuf->rect_float) == rect_size); /* see bug #26502. */ + // printf("%ld %ld\n", rectf - ibuf->float_buffer.data, rect_size); + BLI_assert((rectf - ibuf->float_buffer.data) == rect_size); /* see bug #26502. */ + imb_freerectfloatImBuf(ibuf); - ibuf->mall |= IB_rectfloat; - ibuf->rect_float = (float *)_newrectf; + IMB_assign_float_buffer(ibuf, _newrectf, IB_TAKE_OWNERSHIP); } + (void)rect_size; /* UNUSED in release builds */ ibuf->y = newy; @@ -1171,18 +1173,18 @@ static ImBuf *scaleupx(struct ImBuf *ibuf, int newx) if (ibuf == nullptr) { return nullptr; } - if (ibuf->rect == nullptr && ibuf->rect_float == nullptr) { + if (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data == nullptr) { return ibuf; } - if (ibuf->rect) { + if (ibuf->byte_buffer.data) { do_rect = true; _newrect = static_cast(MEM_mallocN(newx * ibuf->y * sizeof(int), "scaleupx")); if (_newrect == nullptr) { return ibuf; } } - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { do_float = true; _newrectf = static_cast(MEM_mallocN(sizeof(float[4]) * newx * ibuf->y, "scaleupxf")); if (_newrectf == nullptr) { @@ -1193,8 +1195,8 @@ static ImBuf *scaleupx(struct ImBuf *ibuf, int newx) } } - rect = (uchar *)ibuf->rect; - rectf = (float *)ibuf->rect_float; + rect = ibuf->byte_buffer.data; + rectf = ibuf->float_buffer.data; newrect = _newrect; newrectf = _newrectf; @@ -1350,13 +1352,11 @@ static ImBuf *scaleupx(struct ImBuf *ibuf, int newx) if (do_rect) { imb_freerectImBuf(ibuf); - ibuf->mall |= IB_rect; - ibuf->rect = (uint *)_newrect; + IMB_assign_byte_buffer(ibuf, _newrect, IB_TAKE_OWNERSHIP); } if (do_float) { imb_freerectfloatImBuf(ibuf); - ibuf->mall |= IB_rectfloat; - ibuf->rect_float = (float *)_newrectf; + IMB_assign_float_buffer(ibuf, _newrectf, IB_TAKE_OWNERSHIP); } ibuf->x = newx; @@ -1373,18 +1373,18 @@ static ImBuf *scaleupy(struct ImBuf *ibuf, int newy) if (ibuf == nullptr) { return nullptr; } - if (ibuf->rect == nullptr && ibuf->rect_float == nullptr) { + if (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data == nullptr) { return ibuf; } - if (ibuf->rect) { + if (ibuf->byte_buffer.data) { do_rect = true; _newrect = static_cast(MEM_mallocN(ibuf->x * newy * sizeof(int), "scaleupy")); if (_newrect == nullptr) { return ibuf; } } - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { do_float = true; _newrectf = static_cast(MEM_mallocN(sizeof(float[4]) * ibuf->x * newy, "scaleupyf")); if (_newrectf == nullptr) { @@ -1395,8 +1395,8 @@ static ImBuf *scaleupy(struct ImBuf *ibuf, int newy) } } - rect = (uchar *)ibuf->rect; - rectf = (float *)ibuf->rect_float; + rect = ibuf->byte_buffer.data; + rectf = ibuf->float_buffer.data; newrect = _newrect; newrectf = _newrectf; @@ -1439,7 +1439,7 @@ static ImBuf *scaleupy(struct ImBuf *ibuf, int newy) for (x = ibuf->x; x > 0; x--) { sample = 0; if (do_rect) { - rect = ((uchar *)ibuf->rect) + 4 * (x - 1); + rect = ibuf->byte_buffer.data + 4 * (x - 1); newrect = _newrect + 4 * (x - 1); val_a = rect[0]; @@ -1465,7 +1465,7 @@ static ImBuf *scaleupy(struct ImBuf *ibuf, int newy) rect += 2 * skipx; } if (do_float) { - rectf = ibuf->rect_float + 4 * (x - 1); + rectf = ibuf->float_buffer.data + 4 * (x - 1); newrectf = _newrectf + 4 * (x - 1); val_af = rectf[0]; @@ -1553,13 +1553,11 @@ static ImBuf *scaleupy(struct ImBuf *ibuf, int newy) if (do_rect) { imb_freerectImBuf(ibuf); - ibuf->mall |= IB_rect; - ibuf->rect = (uint *)_newrect; + IMB_assign_byte_buffer(ibuf, _newrect, IB_TAKE_OWNERSHIP); } if (do_float) { imb_freerectfloatImBuf(ibuf); - ibuf->mall |= IB_rectfloat; - ibuf->rect_float = (float *)_newrectf; + IMB_assign_float_buffer(ibuf, _newrectf, IB_TAKE_OWNERSHIP); } ibuf->y = newy; @@ -1573,14 +1571,14 @@ static void scalefast_Z_ImBuf(ImBuf *ibuf, int newx, int newy) int x, y; int ofsx, ofsy, stepx, stepy; - if (ibuf->zbuf) { + if (ibuf->z_buffer.data) { _newzbuf = static_cast(MEM_mallocN(newx * newy * sizeof(int), __func__)); if (_newzbuf == nullptr) { IMB_freezbufImBuf(ibuf); } } - if (ibuf->zbuf_float) { + if (ibuf->float_z_buffer.data) { _newzbuf_float = static_cast( MEM_mallocN(size_t(newx) * newy * sizeof(float), __func__)); if (_newzbuf_float == nullptr) { @@ -1601,7 +1599,7 @@ static void scalefast_Z_ImBuf(ImBuf *ibuf, int newx, int newy) for (y = newy; y > 0; y--, ofsy += stepy) { if (newzbuf) { - zbuf = ibuf->zbuf; + zbuf = ibuf->z_buffer.data; zbuf += (ofsy >> 16) * ibuf->x; ofsx = 32768; for (x = newx; x > 0; x--, ofsx += stepx) { @@ -1610,7 +1608,7 @@ static void scalefast_Z_ImBuf(ImBuf *ibuf, int newx, int newy) } if (newzbuf_float) { - zbuf_float = ibuf->zbuf_float; + zbuf_float = ibuf->float_z_buffer.data; zbuf_float += (ofsy >> 16) * ibuf->x; ofsx = 32768; for (x = newx; x > 0; x--, ofsx += stepx) { @@ -1621,14 +1619,12 @@ static void scalefast_Z_ImBuf(ImBuf *ibuf, int newx, int newy) if (_newzbuf) { IMB_freezbufImBuf(ibuf); - ibuf->mall |= IB_zbuf; - ibuf->zbuf = _newzbuf; + IMB_assign_z_buffer(ibuf, _newzbuf, IB_TAKE_OWNERSHIP); } if (_newzbuf_float) { IMB_freezbuffloatImBuf(ibuf); - ibuf->mall |= IB_zbuffloat; - ibuf->zbuf_float = _newzbuf_float; + IMB_assign_float_z_buffer(ibuf, _newzbuf_float, IB_TAKE_OWNERSHIP); } } @@ -1639,7 +1635,7 @@ bool IMB_scaleImBuf(struct ImBuf *ibuf, uint newx, uint newy) if (ibuf == nullptr) { return false; } - if (ibuf->rect == nullptr && ibuf->rect_float == nullptr) { + if (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data == nullptr) { return false; } @@ -1697,10 +1693,10 @@ bool IMB_scalefastImBuf(struct ImBuf *ibuf, uint newx, uint newy) if (ibuf == nullptr) { return false; } - if (ibuf->rect) { + if (ibuf->byte_buffer.data) { do_rect = true; } - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { do_float = true; } if (do_rect == false && do_float == false) { @@ -1737,7 +1733,7 @@ bool IMB_scalefastImBuf(struct ImBuf *ibuf, uint newx, uint newy) for (y = newy; y > 0; y--, ofsy += stepy) { if (do_rect) { - rect = ibuf->rect; + rect = (uint *)ibuf->byte_buffer.data; rect += (ofsy >> 16) * ibuf->x; ofsx = 32768; @@ -1747,7 +1743,7 @@ bool IMB_scalefastImBuf(struct ImBuf *ibuf, uint newx, uint newy) } if (do_float) { - rectf = (struct imbufRGBA *)ibuf->rect_float; + rectf = (struct imbufRGBA *)ibuf->float_buffer.data; rectf += (ofsy >> 16) * ibuf->x; ofsx = 32768; @@ -1759,14 +1755,12 @@ bool IMB_scalefastImBuf(struct ImBuf *ibuf, uint newx, uint newy) if (do_rect) { imb_freerectImBuf(ibuf); - ibuf->mall |= IB_rect; - ibuf->rect = _newrect; + IMB_assign_byte_buffer(ibuf, reinterpret_cast(_newrect), IB_TAKE_OWNERSHIP); } if (do_float) { imb_freerectfloatImBuf(ibuf); - ibuf->mall |= IB_rectfloat; - ibuf->rect_float = (float *)_newrectf; + IMB_assign_float_buffer(ibuf, reinterpret_cast(_newrectf), IB_TAKE_OWNERSHIP); } scalefast_Z_ImBuf(ibuf, newx, newy); @@ -1837,13 +1831,13 @@ static void *do_scale_thread(void *data_v) if (data->byte_buffer) { uchar *pixel = data->byte_buffer + 4 * offset; - BLI_bilinear_interpolation_char((uchar *)ibuf->rect, pixel, ibuf->x, ibuf->y, 4, u, v); + BLI_bilinear_interpolation_char(ibuf->byte_buffer.data, pixel, ibuf->x, ibuf->y, 4, u, v); } if (data->float_buffer) { float *pixel = data->float_buffer + ibuf->channels * offset; BLI_bilinear_interpolation_fl( - ibuf->rect_float, pixel, ibuf->x, ibuf->y, ibuf->channels, u, v); + ibuf->float_buffer.data, pixel, ibuf->x, ibuf->y, ibuf->channels, u, v); } } } @@ -1863,12 +1857,12 @@ void IMB_scaleImBuf_threaded(ImBuf *ibuf, uint newx, uint newy) init_data.newx = newx; init_data.newy = newy; - if (ibuf->rect) { + if (ibuf->byte_buffer.data) { init_data.byte_buffer = static_cast( MEM_mallocN(4 * newx * newy * sizeof(char), "threaded scale byte buffer")); } - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { init_data.float_buffer = static_cast( MEM_mallocN(ibuf->channels * newx * newy * sizeof(float), "threaded scale float buffer")); } @@ -1881,15 +1875,13 @@ void IMB_scaleImBuf_threaded(ImBuf *ibuf, uint newx, uint newy) ibuf->x = newx; ibuf->y = newy; - if (ibuf->rect) { + if (ibuf->byte_buffer.data) { imb_freerectImBuf(ibuf); - ibuf->mall |= IB_rect; - ibuf->rect = (uint *)init_data.byte_buffer; + IMB_assign_byte_buffer(ibuf, init_data.byte_buffer, IB_TAKE_OWNERSHIP); } - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { imb_freerectfloatImBuf(ibuf); - ibuf->mall |= IB_rectfloat; - ibuf->rect_float = init_data.float_buffer; + IMB_assign_float_buffer(ibuf, init_data.float_buffer, IB_TAKE_OWNERSHIP); } } diff --git a/source/blender/imbuf/intern/stereoimbuf.cc b/source/blender/imbuf/intern/stereoimbuf.cc index 61117646e38..5178dc30de6 100644 --- a/source/blender/imbuf/intern/stereoimbuf.cc +++ b/source/blender/imbuf/intern/stereoimbuf.cc @@ -616,7 +616,7 @@ static void imb_stereo3d_squeeze_rectf( IMB_stereo3d_write_dimensions(s3d->display_mode, false, x, y, &width, &height); ibuf = IMB_allocImBuf(width, height, channels, IB_rectfloat); - IMB_buffer_float_from_float(ibuf->rect_float, + IMB_buffer_float_from_float(ibuf->float_buffer.data, rectf, channels, IB_PROFILE_LINEAR_RGB, @@ -628,7 +628,7 @@ static void imb_stereo3d_squeeze_rectf( width); IMB_scaleImBuf_threaded(ibuf, x, y); - memcpy(rectf, ibuf->rect_float, x * y * sizeof(float[4])); + memcpy(rectf, ibuf->float_buffer.data, x * y * sizeof(float[4])); IMB_freeImBuf(ibuf); } @@ -650,7 +650,7 @@ static void imb_stereo3d_squeeze_rect( IMB_stereo3d_write_dimensions(s3d->display_mode, false, x, y, &width, &height); ibuf = IMB_allocImBuf(width, height, channels, IB_rect); - IMB_buffer_byte_from_byte((uchar *)ibuf->rect, + IMB_buffer_byte_from_byte(ibuf->byte_buffer.data, (uchar *)rect, IB_PROFILE_SRGB, IB_PROFILE_SRGB, @@ -661,7 +661,7 @@ static void imb_stereo3d_squeeze_rect( width); IMB_scaleImBuf_threaded(ibuf, x, y); - memcpy(rect, ibuf->rect, x * y * sizeof(uint)); + memcpy(rect, ibuf->byte_buffer.data, x * y * sizeof(uint)); IMB_freeImBuf(ibuf); } @@ -789,12 +789,12 @@ ImBuf *IMB_stereo3d_ImBuf(const ImageFormatData *im_format, ImBuf *ibuf_left, Im ibuf_left->x, ibuf_left->y, ibuf_left->channels, - (int *)ibuf_left->rect, - (int *)ibuf_right->rect, - (int *)ibuf_stereo->rect, - ibuf_left->rect_float, - ibuf_right->rect_float, - ibuf_stereo->rect_float); + (int *)ibuf_left->byte_buffer.data, + (int *)ibuf_right->byte_buffer.data, + (int *)ibuf_stereo->byte_buffer.data, + ibuf_left->float_buffer.data, + ibuf_right->float_buffer.data, + ibuf_stereo->float_buffer.data); imb_stereo3d_write_doit(&s3d_data, &im_format->stereo3d_format); imb_stereo3d_squeeze_ImBuf(ibuf_stereo, &im_format->stereo3d_format, ibuf_left->x, ibuf_left->y); @@ -1293,7 +1293,7 @@ void IMB_ImBufFromStereo3d(const Stereo3dFormat *s3d, Stereo3DData s3d_data = {{nullptr}}; ImBuf *ibuf_left, *ibuf_right; size_t width, height; - const bool is_float = (ibuf_stereo3d->rect_float != nullptr); + const bool is_float = (ibuf_stereo3d->float_buffer.data != nullptr); IMB_stereo3d_read_dimensions(s3d->display_mode, ((s3d->flag & S3D_SQUEEZED_FRAME) == 0), @@ -1331,12 +1331,12 @@ void IMB_ImBufFromStereo3d(const Stereo3dFormat *s3d, ibuf_left->x, ibuf_left->y, ibuf_left->channels, - (int *)ibuf_left->rect, - (int *)ibuf_right->rect, - (int *)ibuf_stereo3d->rect, - ibuf_left->rect_float, - ibuf_right->rect_float, - ibuf_stereo3d->rect_float); + (int *)ibuf_left->byte_buffer.data, + (int *)ibuf_right->byte_buffer.data, + (int *)ibuf_stereo3d->byte_buffer.data, + ibuf_left->float_buffer.data, + ibuf_right->float_buffer.data, + ibuf_stereo3d->float_buffer.data); imb_stereo3d_read_doit(&s3d_data, s3d); @@ -1355,12 +1355,12 @@ void IMB_ImBufFromStereo3d(const Stereo3dFormat *s3d, ibuf_left->x, ibuf_left->y, 1, - (int *)ibuf_left->zbuf, - (int *)ibuf_right->zbuf, - (int *)ibuf_stereo3d->zbuf, - ibuf_left->zbuf_float, - ibuf_right->zbuf_float, - ibuf_stereo3d->zbuf_float); + ibuf_left->z_buffer.data, + ibuf_right->z_buffer.data, + ibuf_stereo3d->z_buffer.data, + ibuf_left->float_z_buffer.data, + ibuf_right->float_z_buffer.data, + ibuf_stereo3d->float_z_buffer.data); imb_stereo3d_read_doit(&s3d_data, s3d); } diff --git a/source/blender/imbuf/intern/thumbs.cc b/source/blender/imbuf/intern/thumbs.cc index d9ed732d3ac..87ec77168d8 100644 --- a/source/blender/imbuf/intern/thumbs.cc +++ b/source/blender/imbuf/intern/thumbs.cc @@ -405,8 +405,8 @@ static ImBuf *thumb_create_ex(const char *file_path, short ex = MAX2(1, short(img->x * scale)); short ey = MAX2(1, short(img->y * scale)); /* Save some time by only scaling byte buffer. */ - if (img->rect_float) { - if (img->rect == nullptr) { + if (img->float_buffer.data) { + if (img->byte_buffer.data == nullptr) { IMB_rect_from_float(img); } imb_freerectfloatImBuf(img); diff --git a/source/blender/imbuf/intern/thumbs_font.cc b/source/blender/imbuf/intern/thumbs_font.cc index ccf8b23d36b..243565d415b 100644 --- a/source/blender/imbuf/intern/thumbs_font.cc +++ b/source/blender/imbuf/intern/thumbs_font.cc @@ -27,7 +27,7 @@ struct ImBuf *IMB_thumb_load_font(const char *filename, uint x, uint y) const float col[4] = {1.0f, 1.0f, 1.0f, 0.0f}; IMB_rectfill(ibuf, col); - if (!BLF_thumb_preview(filename, (uchar *)ibuf->rect, ibuf->x, ibuf->y, ibuf->channels)) { + if (!BLF_thumb_preview(filename, ibuf->byte_buffer.data, ibuf->x, ibuf->y, ibuf->channels)) { IMB_freeImBuf(ibuf); ibuf = nullptr; } diff --git a/source/blender/imbuf/intern/transform.cc b/source/blender/imbuf/intern/transform.cc index 35fe4bc4a6e..75335193c86 100644 --- a/source/blender/imbuf/intern/transform.cc +++ b/source/blender/imbuf/intern/transform.cc @@ -221,11 +221,12 @@ class PixelPointer { NumChannels; if constexpr (std::is_same_v) { - pointer = image_buffer->rect_float + offset; + pointer = image_buffer->float_buffer.data + offset; } else if constexpr (std::is_same_v) { pointer = const_cast( - static_cast(static_cast(image_buffer->rect)) + offset); + static_cast(static_cast(image_buffer->byte_buffer.data)) + + offset); } else { pointer = nullptr; @@ -401,7 +402,7 @@ class Sampler { } else if constexpr (Filter == IMB_FILTER_BILINEAR && std::is_same_v) { if constexpr (std::is_same_v) { - BLI_bilinear_interpolation_wrap_fl(source->rect_float, + BLI_bilinear_interpolation_wrap_fl(source->float_buffer.data, r_sample.data(), source->x, source->y, @@ -412,7 +413,7 @@ class Sampler { } else { const double2 wrapped_uv = uv_wrapper.modify_uv(source, uv); - BLI_bilinear_interpolation_fl(source->rect_float, + BLI_bilinear_interpolation_fl(source->float_buffer.data, r_sample.data(), source->x, source->y, @@ -448,7 +449,7 @@ class Sampler { } const size_t offset = (size_t(source->x) * y1 + x1) * NumChannels; - const float *dataF = source->rect_float + offset; + const float *dataF = source->float_buffer.data + offset; for (int i = 0; i < NumChannels; i++) { r_sample[i] = dataF[i]; } @@ -701,10 +702,10 @@ static void transform_threaded(TransformUserData *user_data, const eIMBTransform { ScanlineThreadFunc scanline_func = nullptr; - if (user_data->dst->rect_float && user_data->src->rect_float) { + if (user_data->dst->float_buffer.data && user_data->src->float_buffer.data) { scanline_func = get_scanline_function(user_data, mode); } - else if (user_data->dst->rect && user_data->src->rect) { + else if (user_data->dst->byte_buffer.data && user_data->src->byte_buffer.data) { /* Number of channels is always 4 when using uchar buffers (sRGB + straight alpha). */ scanline_func = get_scanline_function(mode); } diff --git a/source/blender/imbuf/intern/util_gpu.cc b/source/blender/imbuf/intern/util_gpu.cc index 885f1ce87d0..079f01784d3 100644 --- a/source/blender/imbuf/intern/util_gpu.cc +++ b/source/blender/imbuf/intern/util_gpu.cc @@ -45,7 +45,7 @@ static void imb_gpu_get_format(const ImBuf *ibuf, eGPUDataFormat *r_data_format, eGPUTextureFormat *r_texture_format) { - const bool float_rect = (ibuf->rect_float != nullptr); + const bool float_rect = (ibuf->float_buffer.data != nullptr); const bool is_grayscale = use_grayscale && imb_is_grayscale_texture_format_compatible(ibuf); if (float_rect) { @@ -114,9 +114,10 @@ static void *imb_gpu_get_data(const ImBuf *ibuf, const bool store_premultiplied, bool *r_freedata) { - bool is_float_rect = (ibuf->rect_float != nullptr); + bool is_float_rect = (ibuf->float_buffer.data != nullptr); const bool is_grayscale = imb_is_grayscale_texture_format_compatible(ibuf); - void *data_rect = (is_float_rect) ? (void *)ibuf->rect_float : (void *)ibuf->rect; + void *data_rect = (is_float_rect) ? (void *)ibuf->float_buffer.data : + (void *)ibuf->byte_buffer.data; bool freedata = false; if (is_float_rect) { @@ -192,7 +193,7 @@ static void *imb_gpu_get_data(const ImBuf *ibuf, } if (do_rescale) { - uint *rect = (is_float_rect) ? nullptr : (uint *)data_rect; + uint8_t *rect = (is_float_rect) ? nullptr : (uint8_t *)data_rect; float *rect_float = (is_float_rect) ? (float *)data_rect : nullptr; ImBuf *scale_ibuf = IMB_allocFromBuffer(rect, rect_float, ibuf->x, ibuf->y, 4); @@ -202,11 +203,12 @@ static void *imb_gpu_get_data(const ImBuf *ibuf, MEM_freeN(data_rect); } - data_rect = (is_float_rect) ? (void *)scale_ibuf->rect_float : (void *)scale_ibuf->rect; + data_rect = (is_float_rect) ? (void *)scale_ibuf->float_buffer.data : + (void *)scale_ibuf->byte_buffer.data; *r_freedata = freedata = true; /* Steal the rescaled buffer to avoid double free. */ - scale_ibuf->rect_float = nullptr; - scale_ibuf->rect = nullptr; + (void)IMB_steal_byte_buffer(scale_ibuf); + (void)IMB_steal_float_buffer(scale_ibuf); IMB_freeImBuf(scale_ibuf); } @@ -411,14 +413,16 @@ void IMB_gpu_clamp_half_float(ImBuf *image_buffer) { const float half_min = -65504; const float half_max = 65504; - if (!image_buffer->rect_float) { + if (!image_buffer->float_buffer.data) { return; } + float *rect_float = image_buffer->float_buffer.data; + int rect_float_len = image_buffer->x * image_buffer->y * (image_buffer->channels == 0 ? 4 : image_buffer->channels); for (int i = 0; i < rect_float_len; i++) { - image_buffer->rect_float[i] = clamp_f(image_buffer->rect_float[i], half_min, half_max); + rect_float[i] = clamp_f(rect_float[i], half_min, half_max); } } diff --git a/source/blender/imbuf/intern/webp.cc b/source/blender/imbuf/intern/webp.cc index 6a44c3bce74..8a03f3d7bf3 100644 --- a/source/blender/imbuf/intern/webp.cc +++ b/source/blender/imbuf/intern/webp.cc @@ -63,7 +63,7 @@ ImBuf *imb_loadwebp(const uchar *mem, size_t size, int flags, char colorspace[IM ibuf->ftype = IMB_FTYPE_WEBP; imb_addrectImBuf(ibuf); /* Flip the image during decoding to match Blender. */ - uchar *last_row = (uchar *)(ibuf->rect + (ibuf->y - 1) * ibuf->x); + uchar *last_row = ibuf->byte_buffer.data + 4 * (ibuf->y - 1) * ibuf->x; if (WebPDecodeRGBAInto(mem, size, last_row, size_t(ibuf->x) * ibuf->y * 4, -4 * ibuf->x) == nullptr) { @@ -136,7 +136,7 @@ struct ImBuf *imb_load_filepath_thumbnail_webp(const char *filepath, config.options.flip = 1; config.output.is_external_memory = 1; config.output.colorspace = MODE_RGBA; - config.output.u.RGBA.rgba = (uint8_t *)ibuf->rect; + config.output.u.RGBA.rgba = ibuf->byte_buffer.data; config.output.u.RGBA.stride = 4 * ibuf->x; config.output.u.RGBA.size = size_t(config.output.u.RGBA.stride * ibuf->y); @@ -167,7 +167,7 @@ bool imb_savewebp(struct ImBuf *ibuf, const char *filepath, int /*flags*/) if (bytesperpixel == 3) { /* We must convert the ImBuf RGBA buffer to RGB as WebP expects a RGB buffer. */ const size_t num_pixels = ibuf->x * ibuf->y; - const uint8_t *rgba_rect = (uint8_t *)ibuf->rect; + const uint8_t *rgba_rect = ibuf->byte_buffer.data; uint8_t *rgb_rect = static_cast( MEM_mallocN(sizeof(uint8_t) * num_pixels * 3, "webp rgb_rect")); for (int i = 0; i < num_pixels; i++) { @@ -189,7 +189,7 @@ bool imb_savewebp(struct ImBuf *ibuf, const char *filepath, int /*flags*/) MEM_freeN(rgb_rect); } else if (bytesperpixel == 4) { - last_row = (uchar *)(ibuf->rect + (ibuf->y - 1) * ibuf->x); + last_row = ibuf->byte_buffer.data + 4 * (ibuf->y - 1) * ibuf->x; if (ibuf->foptions.quality == 100.0f) { encoded_data_size = WebPEncodeLosslessRGBA( diff --git a/source/blender/imbuf/intern/writeimage.cc b/source/blender/imbuf/intern/writeimage.cc index 9d970c7317e..7d3f953ff19 100644 --- a/source/blender/imbuf/intern/writeimage.cc +++ b/source/blender/imbuf/intern/writeimage.cc @@ -42,7 +42,7 @@ bool IMB_saveiff(struct ImBuf *ibuf, const char *filepath, int flags) * have already created this byte buffer. This is a basic fallback for other * cases where we do not have a specific desired output colorspace. */ if (!(type->flag & IM_FTYPE_FLOAT)) { - if (ibuf->rect == nullptr && ibuf->rect_float) { + if (ibuf->byte_buffer.data == nullptr && ibuf->float_buffer.data) { ibuf->rect_colorspace = colormanage_colorspace_get_roled(COLOR_ROLE_DEFAULT_BYTE); IMB_rect_from_float(ibuf); } diff --git a/source/blender/io/avi/CMakeLists.txt b/source/blender/io/avi/CMakeLists.txt index 947f2be8a6a..814498368ca 100644 --- a/source/blender/io/avi/CMakeLists.txt +++ b/source/blender/io/avi/CMakeLists.txt @@ -5,6 +5,7 @@ set(INC . ../../blenlib ../../imbuf + ../../makesdna ../../../../intern/guardedalloc ) diff --git a/source/blender/io/collada/MeshImporter.cpp b/source/blender/io/collada/MeshImporter.cpp index 22cc7d9066b..18770718e9a 100644 --- a/source/blender/io/collada/MeshImporter.cpp +++ b/source/blender/io/collada/MeshImporter.cpp @@ -553,7 +553,7 @@ void MeshImporter::mesh_add_edges(Mesh *mesh, int len) CustomData_copy_layout(&mesh->edata, &edata, CD_MASK_MESH.emask, CD_SET_DEFAULT, totedge); CustomData_copy_data(&mesh->edata, &edata, 0, 0, mesh->totedge); - if (!CustomData_get_layer_named(&edata, CD_PROP_INT32_2D, ".edge_verts")) { + if (!CustomData_has_layer_named(&edata, CD_PROP_INT32_2D, ".edge_verts")) { CustomData_add_layer_named(&edata, CD_PROP_INT32_2D, CD_CONSTRUCT, totedge, ".edge_verts"); } diff --git a/source/blender/io/common/intern/path_util.cc b/source/blender/io/common/intern/path_util.cc index 363f3bd79b1..da5c21ae054 100644 --- a/source/blender/io/common/intern/path_util.cc +++ b/source/blender/io/common/intern/path_util.cc @@ -65,7 +65,7 @@ void path_reference_copy(const Set> ©_se continue; } if (0 == BLI_path_cmp_normalized(src, dst)) { - continue; /* Source and dest are the same. */ + continue; /* Source and destination are the same. */ } if (!BLI_file_ensure_parent_dir_exists(dst)) { fprintf(stderr, "Can't make directory for '%s', not copying\n", dst); diff --git a/source/blender/io/usd/intern/usd_capi_export.cc b/source/blender/io/usd/intern/usd_capi_export.cc index ce0d9996482..c9770cfdfb1 100644 --- a/source/blender/io/usd/intern/usd_capi_export.cc +++ b/source/blender/io/usd/intern/usd_capi_export.cc @@ -103,8 +103,10 @@ static bool prim_path_valid(const char *path) return true; } -/* Perform validation of export parameter settings. Returns - * true if the paramters are valid; returns false otherwise. */ +/** + * Perform validation of export parameter settings. + * \return true if the parameters are valid; returns false otherwise. + */ static bool export_params_valid(const USDExportParams ¶ms) { bool valid = true; diff --git a/source/blender/io/usd/intern/usd_writer_curves.cc b/source/blender/io/usd/intern/usd_writer_curves.cc index 769faa7559b..dd84e3ef0c7 100644 --- a/source/blender/io/usd/intern/usd_writer_curves.cc +++ b/source/blender/io/usd/intern/usd_writer_curves.cc @@ -296,7 +296,7 @@ static void populate_curve_props_for_nurbs(const bke::CurvesGeometry &geometry, Array temp_knots(knots_num); bke::curves::nurbs::calculate_knots(tot_points, mode, order, is_cyclic, temp_knots); - /* Knots should be the concatentation of all batched curves. + /* Knots should be the concatenation of all batched curves. * https://graphics.pixar.com/usd/dev/api/class_usd_geom_nurbs_curves.html#details */ for (int i_knot = 0; i_knot < knots_num; i_knot++) { knots.push_back(double(temp_knots[i_knot])); diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index ed48efc5f29..8fbef11d320 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -567,9 +567,10 @@ typedef enum eItasc_Flags { ITASC_INITIAL_REITERATION = (1 << 1), ITASC_REITERATION = (1 << 2), ITASC_SIMULATION = (1 << 3), - - /* Set this flag to always translate root bones (i.e. bones without a parent) to (0, 0, 0). - * This was the pre-3.6 behaviour, and this flag was introduced for backward compatibility. */ + /** + * Set this flag to always translate root bones (i.e. bones without a parent) to (0, 0, 0). + * This was the pre-3.6 behavior, and this flag was introduced for backward compatibility. + */ ITASC_TRANSLATE_ROOT_BONES = (1 << 4), } eItasc_Flags; diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 5644ab57d6a..f0404e93e2f 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -201,7 +201,6 @@ typedef enum eCustomDataType { #define CD_MASK_SHAPE_KEYINDEX (1 << CD_SHAPE_KEYINDEX) #define CD_MASK_SHAPEKEY (1 << CD_SHAPEKEY) -#define CD_MASK_BWEIGHT (1 << CD_BWEIGHT) #define CD_MASK_CREASE (1 << CD_CREASE) #define CD_MASK_ORIGSPACE_MLOOP (1LL << CD_ORIGSPACE_MLOOP) #define CD_MASK_PREVIEW_MLOOPCOL (1LL << CD_PREVIEW_MLOOPCOL) diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index a99c3fffe4b..69a6fbdf471 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -324,12 +324,12 @@ typedef struct Mesh { * \note To allow setting this status on meshes without changing them, this does not tag the * cache dirty. If the mesh was changed first, the relevant dirty tags should be called first. */ - void loose_edges_tag_none() const; + void tag_loose_edges_none() const; /** - * Set the number of vertices not connected to edges to zero. Similar to #loose_edges_tag_none(). + * Set the number of vertices not connected to edges to zero. Similar to #tag_loose_edges_none(). * There may still be vertices only used by loose edges though. * - * \note If both #loose_edges_tag_none() and #tag_loose_verts_none() are called, + * \note If both #tag_loose_edges_none() and #tag_loose_verts_none() are called, * all vertices are used by faces, so #verts_no_faces() will be tagged empty as well. */ void tag_loose_verts_none() const; diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 88b64edb96c..645f45656c1 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -1518,11 +1518,6 @@ typedef struct NodeGeometryRaycast { /* eCustomDataType. */ int8_t data_type; - - /* Deprecated input types in new Ray-cast node. Can be removed when legacy nodes are no longer - * supported. */ - uint8_t input_type_ray_direction; - uint8_t input_type_ray_length; } NodeGeometryRaycast; typedef struct NodeGeometryCurveFill { @@ -1698,7 +1693,7 @@ typedef struct NodeShaderMix { /* glossy distributions */ #define SHD_GLOSSY_BECKMANN 0 -#define SHD_GLOSSY_SHARP 1 +#define SHD_GLOSSY_SHARP_DEPRECATED 1 /* deprecated */ #define SHD_GLOSSY_GGX 2 #define SHD_GLOSSY_ASHIKHMIN_SHIRLEY 3 #define SHD_GLOSSY_MULTI_GGX 4 @@ -2437,10 +2432,6 @@ typedef enum GeometryNodeDeleteGeometryMode { GEO_NODE_DELETE_GEOMETRY_MODE_ONLY_FACE = 2, } GeometryNodeDeleteGeometryMode; -typedef enum GeometryNodeRealizeInstancesFlag { - GEO_NODE_REALIZE_INSTANCES_LEGACY_BEHAVIOR = (1 << 0), -} GeometryNodeRealizeInstancesFlag; - typedef enum GeometryNodeScaleElementsMode { GEO_NODE_SCALE_ELEMENTS_UNIFORM = 0, GEO_NODE_SCALE_ELEMENTS_SINGLE_AXIS = 1, diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index 1fb64e7540e..816797bc0f8 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -572,6 +572,7 @@ typedef enum eScreen_Redraws_Flag { // TIME_CONTINUE_PHYSICS = (1 << 7), /* UNUSED */ TIME_NODES = (1 << 8), TIME_CLIPS = (1 << 9), + TIME_SPREADSHEETS = (1 << 10), TIME_FOLLOW = (1 << 15), } eScreen_Redraws_Flag; diff --git a/source/blender/makesrna/intern/rna_gpencil_legacy.c b/source/blender/makesrna/intern/rna_gpencil_legacy.c index 029add6a242..8d5c1e86cf1 100644 --- a/source/blender/makesrna/intern/rna_gpencil_legacy.c +++ b/source/blender/makesrna/intern/rna_gpencil_legacy.c @@ -2163,7 +2163,7 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_EULER); RNA_def_property_float_sdna(prop, NULL, "rotation"); RNA_def_property_ui_text(prop, "Rotation", "Values for changes in rotation"); - RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 100, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_update(prop, 0, "rna_GpencilLayerMatrix_update"); prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ); diff --git a/source/blender/makesrna/intern/rna_gpencil_legacy_modifier.c b/source/blender/makesrna/intern/rna_gpencil_legacy_modifier.c index e42988daafc..c0714d14162 100644 --- a/source/blender/makesrna/intern/rna_gpencil_legacy_modifier.c +++ b/source/blender/makesrna/intern/rna_gpencil_legacy_modifier.c @@ -1655,7 +1655,7 @@ static void rna_def_modifier_gpenciloffset(BlenderRNA *brna) prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_EULER); RNA_def_property_float_sdna(prop, NULL, "rot"); RNA_def_property_ui_text(prop, "Rotation", "Values for changes in rotation"); - RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 100, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ); @@ -1673,7 +1673,7 @@ static void rna_def_modifier_gpenciloffset(BlenderRNA *brna) prop = RNA_def_property(srna, "random_rotation", PROP_FLOAT, PROP_EULER); RNA_def_property_float_sdna(prop, NULL, "rnd_rot"); RNA_def_property_ui_text(prop, "Random Rotation", "Value for changes in rotation"); - RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 100, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); prop = RNA_def_property(srna, "random_scale", PROP_FLOAT, PROP_XYZ); @@ -2371,7 +2371,7 @@ static void rna_def_modifier_gpencilarray(BlenderRNA *brna) prop = RNA_def_property(srna, "random_rotation", PROP_FLOAT, PROP_EULER); RNA_def_property_float_sdna(prop, NULL, "rnd_rot"); RNA_def_property_ui_text(prop, "Random Rotation", "Value for changes in rotation"); - RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 100, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); prop = RNA_def_property(srna, "random_scale", PROP_FLOAT, PROP_XYZ); diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index 215daa4421c..3933ab813da 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -553,7 +553,7 @@ static int rna_Image_depth_get(PointerRNA *ptr) if (!ibuf) { planes = 0; } - else if (ibuf->rect_float) { + else if (ibuf->float_buffer.data) { planes = ibuf->planes * 4; } else { @@ -619,12 +619,12 @@ static void rna_Image_pixels_get(PointerRNA *ptr, float *values) if (ibuf) { size = ibuf->x * ibuf->y * ibuf->channels; - if (ibuf->rect_float) { - memcpy(values, ibuf->rect_float, sizeof(float) * size); + if (ibuf->float_buffer.data) { + memcpy(values, ibuf->float_buffer.data, sizeof(float) * size); } else { for (i = 0; i < size; i++) { - values[i] = ((uchar *)ibuf->rect)[i] * (1.0f / 255.0f); + values[i] = ibuf->byte_buffer.data[i] * (1.0f / 255.0f); } } } @@ -644,12 +644,12 @@ static void rna_Image_pixels_set(PointerRNA *ptr, const float *values) if (ibuf) { size = ibuf->x * ibuf->y * ibuf->channels; - if (ibuf->rect_float) { - memcpy(ibuf->rect_float, values, sizeof(float) * size); + if (ibuf->float_buffer.data) { + memcpy(ibuf->float_buffer.data, values, sizeof(float) * size); } else { for (i = 0; i < size; i++) { - ((uchar *)ibuf->rect)[i] = unit_float_to_uchar_clamp(values[i]); + ibuf->byte_buffer.data[i] = unit_float_to_uchar_clamp(values[i]); } } @@ -695,7 +695,7 @@ static bool rna_Image_is_float_get(PointerRNA *ptr) ibuf = BKE_image_acquire_ibuf(im, NULL, &lock); if (ibuf) { - is_float = ibuf->rect_float != NULL; + is_float = ibuf->float_buffer.data != NULL; } BKE_image_release_ibuf(im, ibuf, lock); diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c index ebf5cd849e2..207fa35839d 100644 --- a/source/blender/makesrna/intern/rna_image_api.c +++ b/source/blender/makesrna/intern/rna_image_api.c @@ -169,7 +169,7 @@ static void rna_Image_update(Image *image, ReportList *reports) return; } - if (ibuf->rect) { + if (ibuf->byte_buffer.data) { IMB_rect_from_float(ibuf); } diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 6f80bfa99ab..173362073c2 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -98,11 +98,6 @@ static CustomData *rna_mesh_ldata_helper(Mesh *me) return (me->edit_mesh) ? &me->edit_mesh->bm->ldata : &me->ldata; } -static CustomData *rna_mesh_fdata_helper(Mesh *me) -{ - return (me->edit_mesh) ? NULL : &me->fdata; -} - static CustomData *rna_mesh_vdata(const PointerRNA *ptr) { Mesh *me = rna_mesh(ptr); @@ -137,32 +132,6 @@ static void rna_cd_layer_name_set(CustomData *cdata, CustomDataLayer *cdl, const CustomData_set_layer_unique_name(cdata, cdl - cdata->layers); } -/* avoid using where possible!, ideally the type is known */ -static CustomData *rna_cd_from_layer(PointerRNA *ptr, CustomDataLayer *cdl) -{ - /* find out where we come from by */ - Mesh *me = (Mesh *)ptr->owner_id; - CustomData *cd; - - /* rely on negative values wrapping */ -# define TEST_CDL(cmd) \ - if ((void)(cd = cmd(me)), ARRAY_HAS_ITEM(cdl, cd->layers, cd->totlayer)) { \ - return cd; \ - } \ - ((void)0) - - TEST_CDL(rna_mesh_vdata_helper); - TEST_CDL(rna_mesh_edata_helper); - TEST_CDL(rna_mesh_pdata_helper); - TEST_CDL(rna_mesh_ldata_helper); - TEST_CDL(rna_mesh_fdata_helper); - -# undef TEST_CDL - - /* should _never_ happen */ - return NULL; -} - static void rna_MeshVertexLayer_name_set(PointerRNA *ptr, const char *value) { CustomDataLayer *layer = (CustomDataLayer *)ptr->data; @@ -209,19 +178,6 @@ static void rna_MeshLoopLayer_name_set(PointerRNA *ptr, const char *value) rna_cd_layer_name_set(rna_mesh_ldata(ptr), layer, value); } } -/* only for layers shared between types */ -static void rna_MeshAnyLayer_name_set(PointerRNA *ptr, const char *value) -{ - CustomDataLayer *layer = (CustomDataLayer *)ptr->data; - - if (CD_TYPE_AS_MASK(layer->type) & CD_MASK_PROP_ALL) { - BKE_id_attribute_rename(ptr->owner_id, layer->name, value, NULL); - } - else { - CustomData *cd = rna_cd_from_layer(ptr, layer); - rna_cd_layer_name_set(cd, layer, value); - } -} static bool rna_Mesh_has_custom_normals_get(PointerRNA *ptr) { @@ -229,16 +185,6 @@ static bool rna_Mesh_has_custom_normals_get(PointerRNA *ptr) return BKE_mesh_has_custom_loop_normals(me); } -static bool rna_Mesh_has_edge_bevel_weight_get(PointerRNA *ptr) -{ - return CustomData_has_layer(rna_mesh_edata(ptr), CD_BWEIGHT); -} - -static bool rna_Mesh_has_vertex_bevel_weight_get(PointerRNA *ptr) -{ - return CustomData_has_layer(rna_mesh_vdata(ptr), CD_BWEIGHT); -} - static bool rna_Mesh_has_edge_crease_get(PointerRNA *ptr) { return CustomData_has_layer(rna_mesh_edata(ptr), CD_CREASE); @@ -543,40 +489,6 @@ static void rna_MeshVertex_select_set(PointerRNA *ptr, bool value) select_vert[index] = value; } -static float rna_MeshVertex_bevel_weight_get(PointerRNA *ptr) -{ - const Mesh *mesh = rna_mesh(ptr); - const int index = rna_MeshVertex_index_get(ptr); - const float *values = (const float *)CustomData_get_layer(&mesh->vdata, CD_BWEIGHT); - return values == NULL ? 0.0f : values[index]; -} - -static void rna_MeshVertex_bevel_weight_set(PointerRNA *ptr, float value) -{ - Mesh *mesh = rna_mesh(ptr); - const int index = rna_MeshVertex_index_get(ptr); - float *values = (float *)CustomData_add_layer( - &mesh->vdata, CD_BWEIGHT, CD_SET_DEFAULT, mesh->totvert); - values[index] = clamp_f(value, 0.0f, 1.0f); -} - -static float rna_MEdge_bevel_weight_get(PointerRNA *ptr) -{ - const Mesh *mesh = rna_mesh(ptr); - const int index = rna_MeshEdge_index_get(ptr); - const float *values = (const float *)CustomData_get_layer(&mesh->edata, CD_BWEIGHT); - return values == NULL ? 0.0f : values[index]; -} - -static void rna_MEdge_bevel_weight_set(PointerRNA *ptr, float value) -{ - Mesh *mesh = rna_mesh(ptr); - const int index = rna_MeshEdge_index_get(ptr); - float *values = (float *)CustomData_add_layer( - &mesh->edata, CD_BWEIGHT, CD_SET_DEFAULT, mesh->totedge); - values[index] = clamp_f(value, 0.0f, 1.0f); -} - static float rna_MEdge_crease_get(PointerRNA *ptr) { const Mesh *mesh = rna_mesh(ptr); @@ -1334,182 +1246,6 @@ static void rna_mesh_color_active_set(PointerRNA *ptr, bool value) BKE_id_attributes_active_color_set(&mesh->id, layer->name); } -/* sculpt_vertex_color_layers */ - -DEFINE_CUSTOMDATA_LAYER_COLLECTION(sculpt_vertex_color, vdata, CD_PROP_COLOR) - -static PointerRNA rna_Mesh_sculpt_vertex_color_active_get(PointerRNA *ptr) -{ - Mesh *mesh = (Mesh *)ptr->data; - CustomDataLayer *layer = BKE_id_attribute_search( - &mesh->id, mesh->active_color_attribute, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_POINT); - return rna_pointer_inherit_refine(ptr, &RNA_MeshVertColorLayer, layer); -} - -static void rna_Mesh_sculpt_vertex_color_active_set(PointerRNA *ptr, - const PointerRNA value, - ReportList *UNUSED(reports)) -{ - Mesh *mesh = (Mesh *)ptr->data; - CustomDataLayer *layer = (CustomDataLayer *)value.data; - - if (!layer) { - return; - } - - BKE_id_attributes_active_color_set(&mesh->id, layer->name); -} - -static int rna_Mesh_sculpt_vertex_color_active_index_get(PointerRNA *ptr) -{ - Mesh *mesh = (Mesh *)ptr->data; - CustomDataLayer *layer = BKE_id_attribute_search( - &mesh->id, mesh->active_color_attribute, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_POINT); - if (!layer) { - return 0; - } - CustomData *vdata = rna_mesh_vdata(ptr); - return layer - vdata->layers + CustomData_get_layer_index(vdata, CD_PROP_COLOR); -} - -static void rna_Mesh_sculpt_vertex_color_active_index_set(PointerRNA *ptr, int value) -{ - Mesh *mesh = (Mesh *)ptr->data; - CustomData *vdata = rna_mesh_vdata(ptr); - - if (value < 0 || value >= CustomData_number_of_layers(vdata, CD_PROP_COLOR)) { - fprintf(stderr, "Invalid loop byte attribute index %d\n", value); - return; - } - - CustomDataLayer *layer = vdata->layers + CustomData_get_layer_index(vdata, CD_PROP_COLOR) + - value; - - BKE_id_attributes_active_color_set(&mesh->id, layer->name); -} - -static void rna_MeshVertColorLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) -{ - Mesh *me = rna_mesh(ptr); - CustomDataLayer *layer = (CustomDataLayer *)ptr->data; - rna_iterator_array_begin( - iter, layer->data, sizeof(MPropCol), (me->edit_mesh) ? 0 : me->totvert, 0, NULL); -} - -static int rna_MeshVertColorLayer_data_length(PointerRNA *ptr) -{ - Mesh *me = rna_mesh(ptr); - return (me->edit_mesh) ? 0 : me->totvert; -} - -static int rna_float_layer_check(CollectionPropertyIterator *UNUSED(iter), void *data) -{ - CustomDataLayer *layer = (CustomDataLayer *)data; - return (layer->type != CD_PROP_FLOAT); -} - -static void rna_Mesh_vertex_float_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) -{ - CustomData *vdata = rna_mesh_vdata(ptr); - rna_iterator_array_begin(iter, - (void *)vdata->layers, - sizeof(CustomDataLayer), - vdata->totlayer, - 0, - rna_float_layer_check); -} -static void rna_Mesh_polygon_float_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) -{ - CustomData *pdata = rna_mesh_pdata(ptr); - rna_iterator_array_begin(iter, - (void *)pdata->layers, - sizeof(CustomDataLayer), - pdata->totlayer, - 0, - rna_float_layer_check); -} - -static int rna_Mesh_vertex_float_layers_length(PointerRNA *ptr) -{ - return CustomData_number_of_layers(rna_mesh_vdata(ptr), CD_PROP_FLOAT); -} -static int rna_Mesh_polygon_float_layers_length(PointerRNA *ptr) -{ - return CustomData_number_of_layers(rna_mesh_pdata(ptr), CD_PROP_FLOAT); -} - -static int rna_int_layer_check(CollectionPropertyIterator *UNUSED(iter), void *data) -{ - CustomDataLayer *layer = (CustomDataLayer *)data; - return (layer->type != CD_PROP_INT32); -} - -static void rna_Mesh_vertex_int_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) -{ - CustomData *vdata = rna_mesh_vdata(ptr); - rna_iterator_array_begin(iter, - (void *)vdata->layers, - sizeof(CustomDataLayer), - vdata->totlayer, - 0, - rna_int_layer_check); -} -static void rna_Mesh_polygon_int_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) -{ - CustomData *pdata = rna_mesh_pdata(ptr); - rna_iterator_array_begin(iter, - (void *)pdata->layers, - sizeof(CustomDataLayer), - pdata->totlayer, - 0, - rna_int_layer_check); -} - -static int rna_Mesh_vertex_int_layers_length(PointerRNA *ptr) -{ - return CustomData_number_of_layers(rna_mesh_vdata(ptr), CD_PROP_INT32); -} -static int rna_Mesh_polygon_int_layers_length(PointerRNA *ptr) -{ - return CustomData_number_of_layers(rna_mesh_pdata(ptr), CD_PROP_INT32); -} - -static int rna_string_layer_check(CollectionPropertyIterator *UNUSED(iter), void *data) -{ - CustomDataLayer *layer = (CustomDataLayer *)data; - return (layer->type != CD_PROP_STRING); -} - -static void rna_Mesh_vertex_string_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) -{ - CustomData *vdata = rna_mesh_vdata(ptr); - rna_iterator_array_begin(iter, - (void *)vdata->layers, - sizeof(CustomDataLayer), - vdata->totlayer, - 0, - rna_string_layer_check); -} -static void rna_Mesh_polygon_string_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) -{ - CustomData *pdata = rna_mesh_pdata(ptr); - rna_iterator_array_begin(iter, - (void *)pdata->layers, - sizeof(CustomDataLayer), - pdata->totlayer, - 0, - rna_string_layer_check); -} - -static int rna_Mesh_vertex_string_layers_length(PointerRNA *ptr) -{ - return CustomData_number_of_layers(rna_mesh_vdata(ptr), CD_PROP_STRING); -} -static int rna_Mesh_polygon_string_layers_length(PointerRNA *ptr) -{ - return CustomData_number_of_layers(rna_mesh_pdata(ptr), CD_PROP_STRING); -} - /* Skin vertices */ DEFINE_CUSTOMDATA_LAYER_COLLECTION(skin_vertice, vdata, CD_MVERT_SKIN) @@ -2319,192 +2055,6 @@ static char *rna_MeshColor_path(const PointerRNA *ptr) return rna_LoopCustomData_data_path(ptr, "vertex_colors", CD_PROP_BYTE_COLOR); } -static char *rna_MeshVertColorLayer_path(const PointerRNA *ptr) -{ - const CustomDataLayer *cdl = ptr->data; - char name_esc[sizeof(cdl->name) * 2]; - BLI_str_escape(name_esc, cdl->name, sizeof(name_esc)); - return BLI_sprintfN("sculpt_vertex_colors[\"%s\"]", name_esc); -} - -static char *rna_MeshVertColor_path(const PointerRNA *ptr) -{ - return rna_VertCustomData_data_path(ptr, "sculpt_vertex_colors", CD_PROP_COLOR); -} - -/**** Float Property Layer API ****/ -static char *rna_MeshVertexFloatPropertyLayer_path(const PointerRNA *ptr) -{ - const CustomDataLayer *cdl = ptr->data; - char name_esc[sizeof(cdl->name) * 2]; - BLI_str_escape(name_esc, cdl->name, sizeof(name_esc)); - return BLI_sprintfN("vertex_float_layers[\"%s\"]", name_esc); -} -static char *rna_MeshPolygonFloatPropertyLayer_path(const PointerRNA *ptr) -{ - const CustomDataLayer *cdl = ptr->data; - char name_esc[sizeof(cdl->name) * 2]; - BLI_str_escape(name_esc, cdl->name, sizeof(name_esc)); - return BLI_sprintfN("polygon_float_layers[\"%s\"]", name_esc); -} - -static char *rna_MeshVertexFloatProperty_path(const PointerRNA *ptr) -{ - return rna_VertCustomData_data_path(ptr, "vertex_layers_float", CD_PROP_FLOAT); -} -static char *rna_MeshPolygonFloatProperty_path(const PointerRNA *ptr) -{ - return rna_PolyCustomData_data_path(ptr, "polygon_layers_float", CD_PROP_FLOAT); -} - -static void rna_MeshVertexFloatPropertyLayer_data_begin(CollectionPropertyIterator *iter, - PointerRNA *ptr) -{ - Mesh *me = rna_mesh(ptr); - CustomDataLayer *layer = (CustomDataLayer *)ptr->data; - rna_iterator_array_begin(iter, layer->data, sizeof(MFloatProperty), me->totvert, 0, NULL); -} -static void rna_MeshPolygonFloatPropertyLayer_data_begin(CollectionPropertyIterator *iter, - PointerRNA *ptr) -{ - Mesh *me = rna_mesh(ptr); - CustomDataLayer *layer = (CustomDataLayer *)ptr->data; - rna_iterator_array_begin(iter, layer->data, sizeof(MFloatProperty), me->totpoly, 0, NULL); -} - -static int rna_MeshVertexFloatPropertyLayer_data_length(PointerRNA *ptr) -{ - Mesh *me = rna_mesh(ptr); - return me->totvert; -} -static int rna_MeshPolygonFloatPropertyLayer_data_length(PointerRNA *ptr) -{ - Mesh *me = rna_mesh(ptr); - return me->totpoly; -} - -/**** Int Property Layer API ****/ -static char *rna_MeshVertexIntPropertyLayer_path(const PointerRNA *ptr) -{ - const CustomDataLayer *cdl = ptr->data; - char name_esc[sizeof(cdl->name) * 2]; - BLI_str_escape(name_esc, cdl->name, sizeof(name_esc)); - return BLI_sprintfN("vertex_int_layers[\"%s\"]", name_esc); -} -static char *rna_MeshPolygonIntPropertyLayer_path(const PointerRNA *ptr) -{ - const CustomDataLayer *cdl = ptr->data; - char name_esc[sizeof(cdl->name) * 2]; - BLI_str_escape(name_esc, cdl->name, sizeof(name_esc)); - return BLI_sprintfN("polygon_int_layers[\"%s\"]", name_esc); -} - -static char *rna_MeshVertexIntProperty_path(const PointerRNA *ptr) -{ - return rna_VertCustomData_data_path(ptr, "vertex_layers_int", CD_PROP_INT32); -} -static char *rna_MeshPolygonIntProperty_path(const PointerRNA *ptr) -{ - return rna_PolyCustomData_data_path(ptr, "polygon_layers_int", CD_PROP_INT32); -} - -static void rna_MeshVertexIntPropertyLayer_data_begin(CollectionPropertyIterator *iter, - PointerRNA *ptr) -{ - Mesh *me = rna_mesh(ptr); - CustomDataLayer *layer = (CustomDataLayer *)ptr->data; - rna_iterator_array_begin(iter, layer->data, sizeof(MIntProperty), me->totvert, 0, NULL); -} -static void rna_MeshPolygonIntPropertyLayer_data_begin(CollectionPropertyIterator *iter, - PointerRNA *ptr) -{ - Mesh *me = rna_mesh(ptr); - CustomDataLayer *layer = (CustomDataLayer *)ptr->data; - rna_iterator_array_begin(iter, layer->data, sizeof(MIntProperty), me->totpoly, 0, NULL); -} - -static int rna_MeshVertexIntPropertyLayer_data_length(PointerRNA *ptr) -{ - Mesh *me = rna_mesh(ptr); - return me->totvert; -} -static int rna_MeshPolygonIntPropertyLayer_data_length(PointerRNA *ptr) -{ - Mesh *me = rna_mesh(ptr); - return me->totpoly; -} - -/**** String Property Layer API ****/ -static char *rna_MeshVertexStringPropertyLayer_path(const PointerRNA *ptr) -{ - const CustomDataLayer *cdl = ptr->data; - char name_esc[sizeof(cdl->name) * 2]; - BLI_str_escape(name_esc, cdl->name, sizeof(name_esc)); - return BLI_sprintfN("vertex_string_layers[\"%s\"]", name_esc); -} -static char *rna_MeshPolygonStringPropertyLayer_path(const PointerRNA *ptr) -{ - const CustomDataLayer *cdl = ptr->data; - char name_esc[sizeof(cdl->name) * 2]; - BLI_str_escape(name_esc, cdl->name, sizeof(name_esc)); - return BLI_sprintfN("polygon_string_layers[\"%s\"]", name_esc); -} - -static char *rna_MeshVertexStringProperty_path(const PointerRNA *ptr) -{ - return rna_VertCustomData_data_path(ptr, "vertex_layers_string", CD_PROP_STRING); -} -static char *rna_MeshPolygonStringProperty_path(const PointerRNA *ptr) -{ - return rna_PolyCustomData_data_path(ptr, "polygon_layers_string", CD_PROP_STRING); -} - -static void rna_MeshVertexStringPropertyLayer_data_begin(CollectionPropertyIterator *iter, - PointerRNA *ptr) -{ - Mesh *me = rna_mesh(ptr); - CustomDataLayer *layer = (CustomDataLayer *)ptr->data; - rna_iterator_array_begin(iter, layer->data, sizeof(MStringProperty), me->totvert, 0, NULL); -} -static void rna_MeshPolygonStringPropertyLayer_data_begin(CollectionPropertyIterator *iter, - PointerRNA *ptr) -{ - Mesh *me = rna_mesh(ptr); - CustomDataLayer *layer = (CustomDataLayer *)ptr->data; - rna_iterator_array_begin(iter, layer->data, sizeof(MStringProperty), me->totpoly, 0, NULL); -} - -static int rna_MeshVertexStringPropertyLayer_data_length(PointerRNA *ptr) -{ - Mesh *me = rna_mesh(ptr); - return me->totvert; -} -static int rna_MeshPolygonStringPropertyLayer_data_length(PointerRNA *ptr) -{ - Mesh *me = rna_mesh(ptr); - return me->totpoly; -} - -/* XXX, we don't have proper byte string support yet, so for now use the (bytes + 1) - * bmesh API exposes correct python/byte-string access. */ -void rna_MeshStringProperty_s_get(PointerRNA *ptr, char *value) -{ - MStringProperty *ms = (MStringProperty *)ptr->data; - BLI_strncpy(value, ms->s, (int)ms->s_len + 1); -} - -int rna_MeshStringProperty_s_length(PointerRNA *ptr) -{ - MStringProperty *ms = (MStringProperty *)ptr->data; - return (int)ms->s_len + 1; -} - -void rna_MeshStringProperty_s_set(PointerRNA *ptr, const char *value) -{ - MStringProperty *ms = (MStringProperty *)ptr->data; - STRNCPY(ms->s, value); -} - static char *rna_MeshFaceMap_path(const PointerRNA *ptr) { return rna_PolyCustomData_data_path(ptr, "face_maps", CD_FACEMAP); @@ -2561,64 +2111,6 @@ static void rna_Mesh_vertex_color_remove(struct Mesh *me, BKE_id_attribute_remove(&me->id, layer->name, reports); } -static PointerRNA rna_Mesh_sculpt_vertex_color_new(struct Mesh *me, - ReportList *reports, - const char *name, - const bool do_init) -{ - PointerRNA ptr; - CustomData *vdata; - CustomDataLayer *cdl = NULL; - int index = ED_mesh_sculpt_color_add(me, name, do_init, reports); - - if (index != -1) { - vdata = rna_mesh_vdata_helper(me); - cdl = &vdata->layers[CustomData_get_layer_index_n(vdata, CD_PROP_COLOR, index)]; - } - - RNA_pointer_create(&me->id, &RNA_MeshVertColorLayer, cdl, &ptr); - return ptr; -} - -static void rna_Mesh_sculpt_vertex_color_remove(struct Mesh *me, - ReportList *reports, - CustomDataLayer *layer) -{ - BKE_id_attribute_remove(&me->id, layer->name, reports); -} - -# define DEFINE_CUSTOMDATA_PROPERTY_API( \ - elemname, datatype, cd_prop_type, cdata, countvar, layertype) \ - static PointerRNA rna_Mesh_##elemname##_##datatype##_property_new(struct Mesh *me, \ - const char *name) \ - { \ - PointerRNA ptr; \ - CustomDataLayer *cdl = NULL; \ - int index; \ -\ - CustomData_add_layer_named(&me->cdata, cd_prop_type, CD_SET_DEFAULT, me->countvar, name); \ - index = CustomData_get_named_layer_index(&me->cdata, cd_prop_type, name); \ -\ - cdl = (index == -1) ? NULL : &(me->cdata.layers[index]); \ -\ - RNA_pointer_create(&me->id, &RNA_##layertype, cdl, &ptr); \ - return ptr; \ - } - -DEFINE_CUSTOMDATA_PROPERTY_API( - vertex, float, CD_PROP_FLOAT, vdata, totvert, MeshVertexFloatPropertyLayer) -DEFINE_CUSTOMDATA_PROPERTY_API( - vertex, int, CD_PROP_INT32, vdata, totvert, MeshVertexIntPropertyLayer) -DEFINE_CUSTOMDATA_PROPERTY_API( - vertex, string, CD_PROP_STRING, vdata, totvert, MeshVertexStringPropertyLayer) -DEFINE_CUSTOMDATA_PROPERTY_API( - polygon, float, CD_PROP_FLOAT, pdata, totpoly, MeshPolygonFloatPropertyLayer) -DEFINE_CUSTOMDATA_PROPERTY_API( - polygon, int, CD_PROP_INT32, pdata, totpoly, MeshPolygonIntPropertyLayer) -DEFINE_CUSTOMDATA_PROPERTY_API( - polygon, string, CD_PROP_STRING, pdata, totpoly, MeshPolygonStringPropertyLayer) -# undef DEFINE_CUSTOMDATA_PROPERTY_API - static PointerRNA rna_Mesh_uv_layers_new(struct Mesh *me, ReportList *reports, const char *name, @@ -2788,13 +2280,6 @@ static void rna_def_mvert(BlenderRNA *brna) RNA_def_property_boolean_funcs(prop, "rna_MeshVertex_hide_get", "rna_MeshVertex_hide_set"); RNA_def_property_update(prop, 0, "rna_Mesh_update_select"); - prop = RNA_def_property(srna, "bevel_weight", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_funcs( - prop, "rna_MeshVertex_bevel_weight_get", "rna_MeshVertex_bevel_weight_set", NULL); - RNA_def_property_ui_text( - prop, "Bevel Weight", "Weight used by the Bevel modifier 'Only Vertices' option"); - RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); - prop = RNA_def_property(srna, "groups", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_funcs(prop, "rna_MeshVertex_groups_begin", @@ -2848,12 +2333,6 @@ static void rna_def_medge(BlenderRNA *brna) prop, "Crease", "Weight used by the Subdivision Surface modifier for creasing"); RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); - prop = RNA_def_property(srna, "bevel_weight", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_funcs( - prop, "rna_MEdge_bevel_weight_get", "rna_MEdge_bevel_weight_set", NULL); - RNA_def_property_ui_text(prop, "Bevel Weight", "Weight used by the Bevel modifier"); - RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); - prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_MeshEdge_select_get", "rna_MeshEdge_select_set"); RNA_def_property_ui_text(prop, "Select", ""); @@ -3319,213 +2798,6 @@ static void rna_def_mloopcol(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); } -static void rna_def_MPropCol(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - srna = RNA_def_struct(brna, "MeshVertColorLayer", NULL); - RNA_def_struct_ui_text(srna, - "Mesh Sculpt Vertex Color Layer", - "Layer of sculpt vertex colors in a Mesh data-block"); - RNA_def_struct_sdna(srna, "CustomDataLayer"); - RNA_def_struct_path_func(srna, "rna_MeshVertColorLayer_path"); - RNA_def_struct_ui_icon(srna, ICON_GROUP_VCOL); - - prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); - RNA_def_struct_name_property(srna, prop); - RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshVertexLayer_name_set"); - RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX); - RNA_def_property_ui_text(prop, "Name", "Name of Sculpt Vertex color layer"); - RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); - - prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_funcs(prop, "rna_mesh_color_active_get", "rna_mesh_color_active_set"); - RNA_def_property_ui_text( - prop, "Active", "Sets the sculpt vertex color layer as active for display and editing"); - RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); - - prop = RNA_def_property(srna, "active_render", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "active_rnd", 0); - RNA_def_property_boolean_funcs( - prop, "rna_mesh_color_active_render_get", "rna_mesh_color_active_render_set"); - RNA_def_property_ui_text( - prop, "Active Render", "Sets the sculpt vertex color layer as active for rendering"); - RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); - - prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE); - RNA_def_property_struct_type(prop, "MeshVertColor"); - RNA_def_property_ui_text(prop, "Data", ""); - RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE); - RNA_def_property_collection_funcs(prop, - "rna_MeshVertColorLayer_data_begin", - "rna_iterator_array_next", - "rna_iterator_array_end", - "rna_iterator_array_get", - "rna_MeshVertColorLayer_data_length", - NULL, - NULL, - NULL); - - srna = RNA_def_struct(brna, "MeshVertColor", NULL); - RNA_def_struct_sdna(srna, "MPropCol"); - RNA_def_struct_ui_text(srna, "Mesh Sculpt Vertex Color", "Vertex colors in a Mesh"); - RNA_def_struct_path_func(srna, "rna_MeshVertColor_path"); - - prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR); - RNA_def_property_array(prop, 4); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Color", ""); - RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); -} -static void rna_def_mproperties(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - /* Float */ -# define MESH_FLOAT_PROPERTY_LAYER(elemname) \ - srna = RNA_def_struct(brna, "Mesh" elemname "FloatPropertyLayer", NULL); \ - RNA_def_struct_sdna(srna, "CustomDataLayer"); \ - RNA_def_struct_ui_text(srna, \ - "Mesh " elemname " Float Property Layer", \ - "User defined layer of floating-point number values"); \ - RNA_def_struct_path_func(srna, "rna_Mesh" elemname "FloatPropertyLayer_path"); \ -\ - prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); \ - RNA_def_struct_name_property(srna, prop); \ - RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshAnyLayer_name_set"); \ - RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX); \ - RNA_def_property_ui_text(prop, "Name", ""); \ - RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); \ -\ - prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE); \ - RNA_def_property_struct_type(prop, "Mesh" elemname "FloatProperty"); \ - RNA_def_property_ui_text(prop, "Data", ""); \ - RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE); \ - RNA_def_property_collection_funcs(prop, \ - "rna_Mesh" elemname "FloatPropertyLayer_data_begin", \ - "rna_iterator_array_next", \ - "rna_iterator_array_end", \ - "rna_iterator_array_get", \ - "rna_Mesh" elemname "FloatPropertyLayer_data_length", \ - NULL, \ - NULL, \ - NULL); \ -\ - srna = RNA_def_struct(brna, "Mesh" elemname "FloatProperty", NULL); \ - RNA_def_struct_sdna(srna, "MFloatProperty"); \ - RNA_def_struct_ui_text( \ - srna, \ - "Mesh " elemname " Float Property", \ - "User defined floating-point number value in a float properties layer"); \ - RNA_def_struct_path_func(srna, "rna_Mesh" elemname "FloatProperty_path"); \ -\ - prop = RNA_def_property(srna, "value", PROP_FLOAT, PROP_NONE); \ - RNA_def_property_float_sdna(prop, NULL, "f"); \ - RNA_def_property_ui_text(prop, "Value", ""); \ - RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); \ - ((void)0) - - /* Int */ -# define MESH_INT_PROPERTY_LAYER(elemname) \ - srna = RNA_def_struct(brna, "Mesh" elemname "IntPropertyLayer", NULL); \ - RNA_def_struct_sdna(srna, "CustomDataLayer"); \ - RNA_def_struct_ui_text(srna, \ - "Mesh " elemname " Int Property Layer", \ - "User defined layer of integer number values"); \ - RNA_def_struct_path_func(srna, "rna_Mesh" elemname "IntPropertyLayer_path"); \ -\ - prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); \ - RNA_def_struct_name_property(srna, prop); \ - RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshAnyLayer_name_set"); \ - RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX); \ - RNA_def_property_ui_text(prop, "Name", ""); \ - RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); \ -\ - prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE); \ - RNA_def_property_struct_type(prop, "Mesh" elemname "IntProperty"); \ - RNA_def_property_ui_text(prop, "Data", ""); \ - RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE); \ - RNA_def_property_collection_funcs(prop, \ - "rna_Mesh" elemname "IntPropertyLayer_data_begin", \ - "rna_iterator_array_next", \ - "rna_iterator_array_end", \ - "rna_iterator_array_get", \ - "rna_Mesh" elemname "IntPropertyLayer_data_length", \ - NULL, \ - NULL, \ - NULL); \ -\ - srna = RNA_def_struct(brna, "Mesh" elemname "IntProperty", NULL); \ - RNA_def_struct_sdna(srna, "MIntProperty"); \ - RNA_def_struct_ui_text(srna, \ - "Mesh " elemname " Int Property", \ - "User defined integer number value in an integer properties layer"); \ - RNA_def_struct_path_func(srna, "rna_Mesh" elemname "IntProperty_path"); \ -\ - prop = RNA_def_property(srna, "value", PROP_INT, PROP_NONE); \ - RNA_def_property_int_sdna(prop, NULL, "i"); \ - RNA_def_property_ui_text(prop, "Value", ""); \ - RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); \ - ((void)0) - - /* String */ -# define MESH_STRING_PROPERTY_LAYER(elemname) \ - srna = RNA_def_struct(brna, "Mesh" elemname "StringPropertyLayer", NULL); \ - RNA_def_struct_sdna(srna, "CustomDataLayer"); \ - RNA_def_struct_ui_text(srna, \ - "Mesh " elemname " String Property Layer", \ - "User defined layer of string text values"); \ - RNA_def_struct_path_func(srna, "rna_Mesh" elemname "StringPropertyLayer_path"); \ -\ - prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); \ - RNA_def_struct_name_property(srna, prop); \ - RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshAnyLayer_name_set"); \ - RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX); \ - RNA_def_property_ui_text(prop, "Name", ""); \ - RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); \ -\ - prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE); \ - RNA_def_property_struct_type(prop, "Mesh" elemname "StringProperty"); \ - RNA_def_property_ui_text(prop, "Data", ""); \ - RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE); \ - RNA_def_property_collection_funcs(prop, \ - "rna_Mesh" elemname "StringPropertyLayer_data_begin", \ - "rna_iterator_array_next", \ - "rna_iterator_array_end", \ - "rna_iterator_array_get", \ - "rna_Mesh" elemname "StringPropertyLayer_data_length", \ - NULL, \ - NULL, \ - NULL); \ -\ - srna = RNA_def_struct(brna, "Mesh" elemname "StringProperty", NULL); \ - RNA_def_struct_sdna(srna, "MStringProperty"); \ - RNA_def_struct_ui_text(srna, \ - "Mesh " elemname " String Property", \ - "User defined string text value in a string properties layer"); \ - RNA_def_struct_path_func(srna, "rna_Mesh" elemname "StringProperty_path"); \ -\ - /* low level mesh data access, treat as bytes */ \ - prop = RNA_def_property(srna, "value", PROP_STRING, PROP_BYTESTRING); \ - RNA_def_property_string_sdna(prop, NULL, "s"); \ - RNA_def_property_string_funcs(prop, \ - "rna_MeshStringProperty_s_get", \ - "rna_MeshStringProperty_s_length", \ - "rna_MeshStringProperty_s_set"); \ - RNA_def_property_ui_text(prop, "Value", ""); \ - RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); - - MESH_FLOAT_PROPERTY_LAYER("Vertex"); - MESH_FLOAT_PROPERTY_LAYER("Polygon"); - MESH_INT_PROPERTY_LAYER("Vertex"); - MESH_INT_PROPERTY_LAYER("Polygon"); - MESH_STRING_PROPERTY_LAYER("Vertex") - MESH_STRING_PROPERTY_LAYER("Polygon") -# undef MESH_PROPERTY_LAYER -} - void rna_def_texmat_common(StructRNA *srna, const char *texspace_editable) { PropertyRNA *prop; @@ -3740,61 +3012,6 @@ static void rna_def_loop_colors(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_update(prop, 0, "rna_Mesh_update_data_edit_active_color"); } -static void rna_def_vert_colors(BlenderRNA *brna, PropertyRNA *cprop) -{ - StructRNA *srna; - PropertyRNA *prop; - - FunctionRNA *func; - PropertyRNA *parm; - - RNA_def_property_srna(cprop, "VertColors"); - srna = RNA_def_struct(brna, "VertColors", NULL); - RNA_def_struct_sdna(srna, "Mesh"); - RNA_def_struct_ui_text(srna, "Vert Colors", "Collection of sculpt vertex colors"); - - func = RNA_def_function(srna, "new", "rna_Mesh_sculpt_vertex_color_new"); - RNA_def_function_ui_description(func, "Add a sculpt vertex color layer to Mesh"); - RNA_def_function_flag(func, FUNC_USE_REPORTS); - RNA_def_string(func, "name", "Col", 0, "", "Sculpt Vertex color name"); - RNA_def_boolean(func, - "do_init", - true, - "", - "Whether new layer's data should be initialized by copying current active one"); - parm = RNA_def_pointer(func, "layer", "MeshVertColorLayer", "", "The newly created layer"); - RNA_def_parameter_flags(parm, 0, PARM_RNAPTR); - RNA_def_function_return(func, parm); - - func = RNA_def_function(srna, "remove", "rna_Mesh_sculpt_vertex_color_remove"); - RNA_def_function_ui_description(func, "Remove a vertex color layer"); - RNA_def_function_flag(func, FUNC_USE_REPORTS); - parm = RNA_def_pointer(func, "layer", "MeshVertColorLayer", "", "The layer to remove"); - RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); - RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); - - prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); - RNA_def_property_struct_type(prop, "MeshVertColorLayer"); - RNA_def_property_pointer_funcs(prop, - "rna_Mesh_sculpt_vertex_color_active_get", - "rna_Mesh_sculpt_vertex_color_active_set", - NULL, - NULL); - RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK); - RNA_def_property_ui_text( - prop, "Active Sculpt Vertex Color Layer", "Active sculpt vertex color layer"); - RNA_def_property_update(prop, 0, "rna_Mesh_update_data_edit_active_color"); - - prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED); - RNA_def_property_int_funcs(prop, - "rna_Mesh_sculpt_vertex_color_active_index_get", - "rna_Mesh_sculpt_vertex_color_active_index_set", - "rna_Mesh_sculpt_vertex_color_index_range"); - RNA_def_property_ui_text( - prop, "Active Sculpt Vertex Color Index", "Active sculpt vertex color index"); - RNA_def_property_update(prop, 0, "rna_Mesh_update_data_edit_active_color"); -} - static void rna_def_uv_layers(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; @@ -3845,138 +3062,6 @@ static void rna_def_uv_layers(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); } -/* mesh float layers */ -static void rna_def_vertex_float_layers(BlenderRNA *brna, PropertyRNA *cprop) -{ - StructRNA *srna; - - FunctionRNA *func; - PropertyRNA *parm; - - RNA_def_property_srna(cprop, "VertexFloatProperties"); - srna = RNA_def_struct(brna, "VertexFloatProperties", NULL); - RNA_def_struct_sdna(srna, "Mesh"); - RNA_def_struct_ui_text(srna, "Vertex Float Properties", "Collection of float properties"); - - func = RNA_def_function(srna, "new", "rna_Mesh_vertex_float_property_new"); - RNA_def_function_ui_description(func, "Add a float property layer to Mesh"); - RNA_def_string(func, "name", "Float Prop", 0, "", "Float property name"); - parm = RNA_def_pointer( - func, "layer", "MeshVertexFloatPropertyLayer", "", "The newly created layer"); - RNA_def_parameter_flags(parm, 0, PARM_RNAPTR); - RNA_def_function_return(func, parm); -} - -/* mesh int layers */ -static void rna_def_vertex_int_layers(BlenderRNA *brna, PropertyRNA *cprop) -{ - StructRNA *srna; - - FunctionRNA *func; - PropertyRNA *parm; - - RNA_def_property_srna(cprop, "VertexIntProperties"); - srna = RNA_def_struct(brna, "VertexIntProperties", NULL); - RNA_def_struct_sdna(srna, "Mesh"); - RNA_def_struct_ui_text(srna, "Vertex Int Properties", "Collection of int properties"); - - func = RNA_def_function(srna, "new", "rna_Mesh_vertex_int_property_new"); - RNA_def_function_ui_description(func, "Add a integer property layer to Mesh"); - RNA_def_string(func, "name", "Int Prop", 0, "", "Int property name"); - parm = RNA_def_pointer( - func, "layer", "MeshVertexIntPropertyLayer", "", "The newly created layer"); - RNA_def_parameter_flags(parm, 0, PARM_RNAPTR); - RNA_def_function_return(func, parm); -} - -/* mesh string layers */ -static void rna_def_vertex_string_layers(BlenderRNA *brna, PropertyRNA *cprop) -{ - StructRNA *srna; - - FunctionRNA *func; - PropertyRNA *parm; - - RNA_def_property_srna(cprop, "VertexStringProperties"); - srna = RNA_def_struct(brna, "VertexStringProperties", NULL); - RNA_def_struct_sdna(srna, "Mesh"); - RNA_def_struct_ui_text(srna, "Vertex String Properties", "Collection of string properties"); - - func = RNA_def_function(srna, "new", "rna_Mesh_vertex_string_property_new"); - RNA_def_function_ui_description(func, "Add a string property layer to Mesh"); - RNA_def_string(func, "name", "String Prop", 0, "", "String property name"); - parm = RNA_def_pointer( - func, "layer", "MeshVertexStringPropertyLayer", "", "The newly created layer"); - RNA_def_parameter_flags(parm, 0, PARM_RNAPTR); - RNA_def_function_return(func, parm); -} - -/* mesh float layers */ -static void rna_def_polygon_float_layers(BlenderRNA *brna, PropertyRNA *cprop) -{ - StructRNA *srna; - - FunctionRNA *func; - PropertyRNA *parm; - - RNA_def_property_srna(cprop, "PolygonFloatProperties"); - srna = RNA_def_struct(brna, "PolygonFloatProperties", NULL); - RNA_def_struct_sdna(srna, "Mesh"); - RNA_def_struct_ui_text(srna, "Polygon Float Properties", "Collection of float properties"); - - func = RNA_def_function(srna, "new", "rna_Mesh_polygon_float_property_new"); - RNA_def_function_ui_description(func, "Add a float property layer to Mesh"); - RNA_def_string(func, "name", "Float Prop", 0, "", "Float property name"); - parm = RNA_def_pointer( - func, "layer", "MeshPolygonFloatPropertyLayer", "", "The newly created layer"); - RNA_def_parameter_flags(parm, 0, PARM_RNAPTR); - RNA_def_function_return(func, parm); -} - -/* mesh int layers */ -static void rna_def_polygon_int_layers(BlenderRNA *brna, PropertyRNA *cprop) -{ - StructRNA *srna; - - FunctionRNA *func; - PropertyRNA *parm; - - RNA_def_property_srna(cprop, "PolygonIntProperties"); - srna = RNA_def_struct(brna, "PolygonIntProperties", NULL); - RNA_def_struct_sdna(srna, "Mesh"); - RNA_def_struct_ui_text(srna, "Polygon Int Properties", "Collection of int properties"); - - func = RNA_def_function(srna, "new", "rna_Mesh_polygon_int_property_new"); - RNA_def_function_ui_description(func, "Add a integer property layer to Mesh"); - RNA_def_string(func, "name", "Int Prop", 0, "", "Int property name"); - parm = RNA_def_pointer( - func, "layer", "MeshPolygonIntPropertyLayer", "", "The newly created layer"); - RNA_def_parameter_flags(parm, 0, PARM_RNAPTR); - RNA_def_function_return(func, parm); -} - -/* mesh string layers */ -static void rna_def_polygon_string_layers(BlenderRNA *brna, PropertyRNA *cprop) -{ - StructRNA *srna; - - FunctionRNA *func; - PropertyRNA *parm; - - RNA_def_property_srna(cprop, "PolygonStringProperties"); - srna = RNA_def_struct(brna, "PolygonStringProperties", NULL); - RNA_def_struct_sdna(srna, "Mesh"); - RNA_def_struct_ui_text(srna, "Polygon String Properties", "Collection of string properties"); - - func = RNA_def_function(srna, "new", "rna_Mesh_polygon_string_property_new"); - RNA_def_function_ui_description(func, "Add a string property layer to Mesh"); - RNA_def_string(func, "name", "String Prop", 0, "", "String property name"); - parm = RNA_def_pointer( - func, "layer", "MeshPolygonStringPropertyLayer", "", "The newly created layer"); - RNA_def_parameter_flags(parm, 0, PARM_RNAPTR); - RNA_def_function_return(func, parm); -} - static void rna_def_skin_vertices(BlenderRNA *brna, PropertyRNA *UNUSED(cprop)) { StructRNA *srna; @@ -4469,123 +3554,6 @@ static void rna_def_mesh(BlenderRNA *brna) "Legacy vertex color layers. Deprecated, use color attributes instead"); rna_def_loop_colors(brna, prop); - /* Sculpt Vertex colors */ - - prop = RNA_def_property(srna, "sculpt_vertex_colors", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "vdata.layers", "vdata.totlayer"); - RNA_def_property_collection_funcs(prop, - "rna_Mesh_sculpt_vertex_colors_begin", - NULL, - NULL, - NULL, - "rna_Mesh_sculpt_vertex_colors_length", - NULL, - NULL, - NULL); - RNA_def_property_struct_type(prop, "MeshVertColorLayer"); - RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE); - RNA_def_property_ui_text(prop, - "Sculpt Vertex Colors", - "Sculpt vertex color layers. Deprecated, use color attributes instead"); - rna_def_vert_colors(brna, prop); - - /* TODO: edge customdata layers (bmesh py api can access already). */ - prop = RNA_def_property(srna, "vertex_layers_float", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "vdata.layers", "vdata.totlayer"); - RNA_def_property_collection_funcs(prop, - "rna_Mesh_vertex_float_layers_begin", - NULL, - NULL, - NULL, - "rna_Mesh_vertex_float_layers_length", - NULL, - NULL, - NULL); - RNA_def_property_struct_type(prop, "MeshVertexFloatPropertyLayer"); - RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE); - RNA_def_property_ui_text(prop, "Float Property Layers", ""); - rna_def_vertex_float_layers(brna, prop); - - prop = RNA_def_property(srna, "vertex_layers_int", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "vdata.layers", "vdata.totlayer"); - RNA_def_property_collection_funcs(prop, - "rna_Mesh_vertex_int_layers_begin", - NULL, - NULL, - NULL, - "rna_Mesh_vertex_int_layers_length", - NULL, - NULL, - NULL); - RNA_def_property_struct_type(prop, "MeshVertexIntPropertyLayer"); - RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE); - RNA_def_property_ui_text(prop, "Int Property Layers", ""); - rna_def_vertex_int_layers(brna, prop); - - prop = RNA_def_property(srna, "vertex_layers_string", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "vdata.layers", "vdata.totlayer"); - RNA_def_property_collection_funcs(prop, - "rna_Mesh_vertex_string_layers_begin", - NULL, - NULL, - NULL, - "rna_Mesh_vertex_string_layers_length", - NULL, - NULL, - NULL); - RNA_def_property_struct_type(prop, "MeshVertexStringPropertyLayer"); - RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE); - RNA_def_property_ui_text(prop, "String Property Layers", ""); - rna_def_vertex_string_layers(brna, prop); - - prop = RNA_def_property(srna, "polygon_layers_float", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "pdata.layers", "pdata.totlayer"); - RNA_def_property_collection_funcs(prop, - "rna_Mesh_polygon_float_layers_begin", - NULL, - NULL, - NULL, - "rna_Mesh_polygon_float_layers_length", - NULL, - NULL, - NULL); - RNA_def_property_struct_type(prop, "MeshPolygonFloatPropertyLayer"); - RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE); - RNA_def_property_ui_text(prop, "Float Property Layers", ""); - rna_def_polygon_float_layers(brna, prop); - - prop = RNA_def_property(srna, "polygon_layers_int", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "pdata.layers", "pdata.totlayer"); - RNA_def_property_collection_funcs(prop, - "rna_Mesh_polygon_int_layers_begin", - NULL, - NULL, - NULL, - "rna_Mesh_polygon_int_layers_length", - NULL, - NULL, - NULL); - RNA_def_property_struct_type(prop, "MeshPolygonIntPropertyLayer"); - RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE); - RNA_def_property_ui_text(prop, "Int Property Layers", ""); - rna_def_polygon_int_layers(brna, prop); - - prop = RNA_def_property(srna, "polygon_layers_string", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "pdata.layers", "pdata.totlayer"); - RNA_def_property_collection_funcs(prop, - "rna_Mesh_polygon_string_layers_begin", - NULL, - NULL, - NULL, - "rna_Mesh_polygon_string_layers_length", - NULL, - NULL, - NULL); - RNA_def_property_struct_type(prop, "MeshPolygonStringPropertyLayer"); - RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE); - RNA_def_property_ui_text(prop, "String Property Layers", ""); - rna_def_polygon_string_layers(brna, prop); - /* face-maps */ prop = RNA_def_property(srna, "face_maps", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "pdata.layers", "pdata.totlayer"); @@ -4798,18 +3766,6 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_boolean_funcs(prop, "rna_Mesh_has_custom_normals_get", NULL); RNA_define_verify_sdna(true); - prop = RNA_def_property(srna, "has_bevel_weight_edge", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text( - prop, "Has Edge Bevel Weight", "True if the mesh has an edge bevel weight layer"); - RNA_def_property_boolean_funcs(prop, "rna_Mesh_has_edge_bevel_weight_get", NULL); - - prop = RNA_def_property(srna, "has_bevel_weight_vertex", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text( - prop, "Has Vertex Bevel Weight", "True if the mesh has an vertex bevel weight layer"); - RNA_def_property_boolean_funcs(prop, "rna_Mesh_has_vertex_bevel_weight_get", NULL); - prop = RNA_def_property(srna, "has_crease_edge", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Has Edge Crease", "True if the mesh has an edge crease layer"); @@ -4912,8 +3868,6 @@ void RNA_def_mesh(BlenderRNA *brna) rna_def_mpolygon(brna); rna_def_mloopuv(brna); rna_def_mloopcol(brna); - rna_def_MPropCol(brna); - rna_def_mproperties(brna); rna_def_face_map(brna); } diff --git a/source/blender/makesrna/intern/rna_meta.c b/source/blender/makesrna/intern/rna_meta.c index 03e422df7da..86fbc8eb797 100644 --- a/source/blender/makesrna/intern/rna_meta.c +++ b/source/blender/makesrna/intern/rna_meta.c @@ -387,6 +387,7 @@ static void rna_def_metaball(BlenderRNA *brna) RNA_def_property_float(prop, NULL, "rot"); RNA_def_property_ui_text(prop, "Texture Space Rotation", "Texture space rotation"); RNA_def_property_editable_func(prop, "rna_Meta_texspace_editable"); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 100, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_update(prop, 0, "rna_MetaBall_update_data"); # endif diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c index 6ba6973de26..0e9658e46f6 100644 --- a/source/blender/makesrna/intern/rna_nla.c +++ b/source/blender/makesrna/intern/rna_nla.c @@ -739,6 +739,10 @@ static void rna_def_nlastrip(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Start Frame", ""); RNA_def_property_update( prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update"); + /* The `frame_start` and `frame_end` properties should NOT be considered for library overrides, + * as their setters always enforce a valid state. While library overrides are applied, the + * intermediate state may be invalid, even when the end state is valid. */ + RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON); prop = RNA_def_property(srna, "frame_end", PROP_FLOAT, PROP_TIME); RNA_def_property_float_sdna(prop, NULL, "end"); @@ -746,6 +750,29 @@ static void rna_def_nlastrip(BlenderRNA *brna) RNA_def_property_ui_text(prop, "End Frame", ""); RNA_def_property_update( prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update"); + /* The `frame_start` and `frame_end` properties should NOT be considered for library overrides, + * as their setters always enforce a valid state. While library overrides are applied, the + * intermediate state may be invalid, even when the end state is valid. */ + RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON); + + /* Strip extents without enforcing a valid state. */ + prop = RNA_def_property(srna, "frame_start_raw", PROP_FLOAT, PROP_TIME); + RNA_def_property_float_sdna(prop, NULL, "start"); + RNA_def_property_ui_text(prop, + "Start Frame (raw value)", + "Same as frame_start, except that any value can be set, including ones " + "that create an invalid state"); + RNA_def_property_update( + prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update"); + + prop = RNA_def_property(srna, "frame_end_raw", PROP_FLOAT, PROP_TIME); + RNA_def_property_float_sdna(prop, NULL, "end"); + RNA_def_property_ui_text(prop, + "End Frame (raw value)", + "Same as frame_end, except that any value can be set, including ones " + "that create an invalid state"); + RNA_def_property_update( + prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update"); /* Strip extents, when called from UI elements : */ prop = RNA_def_property(srna, "frame_start_ui", PROP_FLOAT, PROP_TIME); @@ -759,6 +786,9 @@ static void rna_def_nlastrip(BlenderRNA *brna) "property instead"); RNA_def_property_update( prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update"); + /* The `..._ui` properties should NOT be considered for library overrides, as they are meant to + * have different behavior than when setting their non-`..._ui` counterparts. */ + RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON); prop = RNA_def_property(srna, "frame_end_ui", PROP_FLOAT, PROP_TIME); RNA_def_property_float_sdna(prop, NULL, "end"); @@ -771,6 +801,9 @@ static void rna_def_nlastrip(BlenderRNA *brna) "changed, see the \"frame_end\" property instead"); RNA_def_property_update( prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update"); + /* The `..._ui` properties should NOT be considered for library overrides, as they are meant to + * have different behavior than when setting their non-`..._ui` counterparts. */ + RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON); /* Blending */ prop = RNA_def_property(srna, "blend_in", PROP_FLOAT, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index f3e7559bb3d..6af63a01b29 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -1185,6 +1185,9 @@ static bNode *rna_NodeTree_node_new(bNodeTree *ntree, return NULL; } + /* If the given idname is an alias, translate it to the proper idname. */ + type = nodeTypeFindAlias(type); + ntype = nodeTypeFind(type); if (!ntype) { BKE_reportf(reports, RPT_ERROR, "Node type %s undefined", type); @@ -2687,13 +2690,6 @@ static void rna_Node_width_range( *max = *softmax = node->typeinfo->maxwidth; } -static void rna_Node_width_hidden_set(PointerRNA *UNUSED(ptr), float UNUSED(value)) {} - -static float rna_Node_width_hidden_get(PointerRNA *UNUSED(ptr)) -{ - return 0.0f; -} - static void rna_Node_height_range( PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax) { @@ -4747,11 +4743,6 @@ static const EnumPropertyItem node_ycc_items[] = { }; static const EnumPropertyItem node_glossy_items[] = { - {SHD_GLOSSY_SHARP, - "SHARP", - 0, - "Sharp", - "Results in perfectly sharp reflections like a mirror. The Roughness value is not used"}, {SHD_GLOSSY_BECKMANN, "BECKMANN", 0, "Beckmann", ""}, {SHD_GLOSSY_GGX, "GGX", 0, "GGX", ""}, {SHD_GLOSSY_ASHIKHMIN_SHIRLEY, "ASHIKHMIN_SHIRLEY", 0, "Ashikhmin-Shirley", ""}, @@ -4764,25 +4755,7 @@ static const EnumPropertyItem node_glossy_items[] = { {0, NULL, 0, NULL, NULL}, }; -static const EnumPropertyItem node_anisotropic_items[] = { - {SHD_GLOSSY_BECKMANN, "BECKMANN", 0, "Beckmann", ""}, - {SHD_GLOSSY_GGX, "GGX", 0, "GGX", ""}, - {SHD_GLOSSY_MULTI_GGX, - "MULTI_GGX", - 0, - "Multiscatter GGX", - "Slower than GGX but gives a more energy conserving results, which would otherwise be " - "visible as excessive darkening"}, - {SHD_GLOSSY_ASHIKHMIN_SHIRLEY, "ASHIKHMIN_SHIRLEY", 0, "Ashikhmin-Shirley", ""}, - {0, NULL, 0, NULL, NULL}, -}; - static const EnumPropertyItem node_glass_items[] = { - {SHD_GLOSSY_SHARP, - "SHARP", - 0, - "Sharp", - "Results in perfectly sharp reflections like a mirror. The Roughness value is not used"}, {SHD_GLOSSY_BECKMANN, "BECKMANN", 0, "Beckmann", ""}, {SHD_GLOSSY_GGX, "GGX", 0, "GGX", ""}, {SHD_GLOSSY_MULTI_GGX, @@ -4795,11 +4768,6 @@ static const EnumPropertyItem node_glass_items[] = { }; static const EnumPropertyItem node_refraction_items[] = { - {SHD_GLOSSY_SHARP, - "SHARP", - 0, - "Sharp", - "Results in perfectly sharp reflections like a mirror. The Roughness value is not used"}, {SHD_GLOSSY_BECKMANN, "BECKMANN", 0, "Beckmann", ""}, {SHD_GLOSSY_GGX, "GGX", 0, "GGX", ""}, {0, NULL, 0, NULL, NULL}, @@ -6308,17 +6276,6 @@ static void def_refraction(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } -static void def_anisotropic(StructRNA *srna) -{ - PropertyRNA *prop; - - prop = RNA_def_property(srna, "distribution", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "custom1"); - RNA_def_property_enum_items(prop, node_anisotropic_items); - RNA_def_property_ui_text(prop, "Distribution", "Light scattering distribution on rough surface"); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); -} - static void def_toon(StructRNA *srna) { PropertyRNA *prop; @@ -11281,17 +11238,6 @@ static void def_geo_viewer(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } -static void def_geo_realize_instances(StructRNA *srna) -{ - PropertyRNA *prop; - - prop = RNA_def_property(srna, "legacy_behavior", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "custom1", GEO_NODE_REALIZE_INSTANCES_LEGACY_BEHAVIOR); - RNA_def_property_ui_text( - prop, "Legacy Behavior", "Behave like before instance attributes existed"); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update"); -} - static void def_geo_evaluate_at_index(StructRNA *srna) { PropertyRNA *prop; @@ -12618,13 +12564,6 @@ static void rna_def_node(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Width", "Width of the node"); RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, NULL); - prop = RNA_def_property(srna, "width_hidden", PROP_FLOAT, PROP_XYZ); - RNA_def_property_float_funcs( - prop, "rna_Node_width_hidden_get", "rna_Node_width_hidden_set", "rna_Node_width_range"); - RNA_def_property_ui_text( - prop, "Width Hidden", "Deprecated width of the node when it is collapsed"); - RNA_def_property_update(prop, 0, NULL); - prop = RNA_def_property(srna, "height", PROP_FLOAT, PROP_XYZ); RNA_def_property_float_sdna(prop, NULL, "height"); RNA_def_property_float_funcs(prop, NULL, NULL, "rna_Node_height_range"); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 5dee11330d2..f3b0f1a8547 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -3345,6 +3345,7 @@ static void rna_def_object(BlenderRNA *brna) prop = RNA_def_property(srna, "rotation_euler", PROP_FLOAT, PROP_EULER); RNA_def_property_float_sdna(prop, NULL, "rot"); RNA_def_property_editable_array_func(prop, "rna_Object_rotation_euler_editable"); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 100, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_ui_text(prop, "Euler Rotation", "Rotation in Eulers"); RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update"); @@ -3392,6 +3393,7 @@ static void rna_def_object(BlenderRNA *brna) prop, "Delta Rotation (Euler)", "Extra rotation added to the rotation of the object (when using Euler rotations)"); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 100, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_update(prop, NC_OBJECT | ND_TRANSFORM, "rna_Object_internal_update"); prop = RNA_def_property(srna, "delta_rotation_quaternion", PROP_FLOAT, PROP_QUATERNION); diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index cea8fba8902..b68c344c2f2 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -1097,6 +1097,7 @@ static void rna_def_pose_channel(BlenderRNA *brna) RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); RNA_def_property_editable_array_func(prop, "rna_PoseChannel_rotation_euler_editable"); RNA_def_property_ui_text(prop, "Euler Rotation", "Rotation in Eulers"); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 100, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update"); prop = RNA_def_property(srna, "rotation_mode", PROP_ENUM, PROP_NONE); @@ -1356,6 +1357,7 @@ static void rna_def_pose_channel(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "custom_rotation_euler"); RNA_def_property_ui_text( prop, "Custom Shape Rotation", "Adjust the rotation of the custom shape"); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 100, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update"); prop = RNA_def_property(srna, "use_custom_shape_bone_size", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index dea81f37856..d9d3fa959b5 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2934,6 +2934,7 @@ static void rna_def_view3d_cursor(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_float_sdna(prop, NULL, "rotation_euler"); RNA_def_property_ui_text(prop, "Euler Rotation", "3D rotation"); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 100, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_update(prop, NC_WINDOW, NULL); prop = RNA_def_property(srna, "rotation_mode", PROP_ENUM, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c index 4d837a374d1..75105cf21c9 100644 --- a/source/blender/makesrna/intern/rna_screen.c +++ b/source/blender/makesrna/intern/rna_screen.c @@ -666,6 +666,11 @@ static void rna_def_screen(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "redraws_flag", TIME_CLIPS); RNA_def_property_ui_text(prop, "Clip Editors", ""); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TIME, "rna_Screen_redraw_update"); + + prop = RNA_def_property(srna, "use_play_spreadsheet_editors", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "redraws_flag", TIME_SPREADSHEETS); + RNA_def_property_ui_text(prop, "Spreadsheet Editors", ""); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TIME, "rna_Screen_redraw_update"); } void RNA_def_screen(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index deb96a677c0..c4862befdf5 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -7165,7 +7165,7 @@ static void rna_def_space_filebrowser(BlenderRNA *brna) NULL, NULL, NULL); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_flag(prop, PROP_EDITABLE); prop = RNA_def_int(srna, "bookmarks_active", @@ -7196,7 +7196,7 @@ static void rna_def_space_filebrowser(BlenderRNA *brna) NULL, NULL, NULL); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_flag(prop, PROP_EDITABLE); prop = RNA_def_int(srna, "recent_folders_active", diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 2254db4edaf..e82bc8abbb3 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -506,6 +506,7 @@ static void rna_def_texmapping(BlenderRNA *brna) prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_EULER); RNA_def_property_float_sdna(prop, NULL, "rot"); RNA_def_property_ui_text(prop, "Rotation", ""); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 100, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_update(prop, 0, "rna_Texture_mapping_update"); prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ); diff --git a/source/blender/modifiers/intern/MOD_bevel.cc b/source/blender/modifiers/intern/MOD_bevel.cc index 36f33f31a42..b894a35dffe 100644 --- a/source/blender/modifiers/intern/MOD_bevel.cc +++ b/source/blender/modifiers/intern/MOD_bevel.cc @@ -72,10 +72,6 @@ static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_ma if (bmd->defgrp_name[0] != '\0') { r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT; } - if (bmd->lim_flags & MOD_BEVEL_WEIGHT) { - r_cddata_masks->vmask |= CD_MASK_BWEIGHT; - r_cddata_masks->emask |= CD_MASK_BWEIGHT; - } } /* @@ -125,10 +121,15 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * MOD_get_vgroup(ctx->object, mesh, bmd->defgrp_name, &dvert, &vgroup); } + const int bweight_offset_vert = CustomData_get_offset_named( + &bm->vdata, CD_PROP_FLOAT, "bevel_weight_vert"); + const int bweight_offset_edge = CustomData_get_offset_named( + &bm->edata, CD_PROP_FLOAT, "bevel_weight_edge"); + if (bmd->affect_type == MOD_BEVEL_AFFECT_VERTICES) { BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (bmd->lim_flags & MOD_BEVEL_WEIGHT) { - weight = BM_elem_float_data_get(&bm->vdata, v, CD_BWEIGHT); + weight = bweight_offset_vert == -1 ? 0.0f : BM_ELEM_CD_GET_FLOAT(v, bweight_offset_vert); if (weight == 0.0f) { continue; } @@ -165,7 +166,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { if (BM_edge_is_manifold(e)) { if (bmd->lim_flags & MOD_BEVEL_WEIGHT) { - weight = BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT); + weight = bweight_offset_edge == -1 ? 0.0f : BM_ELEM_CD_GET_FLOAT(e, bweight_offset_edge); if (weight == 0.0f) { continue; } diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.cc b/source/blender/modifiers/intern/MOD_solidify_extrude.cc index c1265abd349..60d289c5462 100644 --- a/source/blender/modifiers/intern/MOD_solidify_extrude.cc +++ b/source/blender/modifiers/intern/MOD_solidify_extrude.cc @@ -385,8 +385,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex float *result_edge_bweight = nullptr; if (do_bevel_convex) { - result_edge_bweight = static_cast( - CustomData_add_layer(&result->edata, CD_BWEIGHT, CD_SET_DEFAULT, result->totedge)); + result_edge_bweight = static_cast(CustomData_add_layer_named( + &result->edata, CD_PROP_FLOAT, CD_SET_DEFAULT, result->totedge, "bevel_weight_edge")); } /* Initializes: (`i_end`, `do_shell_align`, `vert_index`). */ diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc index 1d09cef61de..29f4c78a052 100644 --- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc +++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc @@ -191,9 +191,9 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* These might be null. */ const float *orig_vert_bweight = static_cast( - CustomData_get_layer(&mesh->vdata, CD_BWEIGHT)); + CustomData_get_layer_named(&mesh->vdata, CD_PROP_FLOAT, "bevel_weight_vert")); const float *orig_edge_bweight = static_cast( - CustomData_get_layer(&mesh->edata, CD_BWEIGHT)); + CustomData_get_layer_named(&mesh->edata, CD_PROP_FLOAT, "bevel_weight_edge")); const float *orig_edge_crease = static_cast( CustomData_get_layer(&mesh->edata, CD_CREASE)); @@ -2001,11 +2001,11 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, int *origindex_poly = static_cast( CustomData_get_layer_for_write(&result->pdata, CD_ORIGINDEX, result->totpoly)); - float *result_edge_bweight = static_cast( - CustomData_get_layer_for_write(&result->edata, CD_BWEIGHT, result->totedge)); + float *result_edge_bweight = static_cast(CustomData_get_layer_named_for_write( + &result->edata, CD_PROP_FLOAT, "bevel_weight_edge", result->totedge)); if (bevel_convex != 0.0f || orig_vert_bweight != nullptr) { - result_edge_bweight = static_cast( - CustomData_add_layer(&result->edata, CD_BWEIGHT, CD_SET_DEFAULT, result->totedge)); + result_edge_bweight = static_cast(CustomData_add_layer_named( + &result->edata, CD_PROP_FLOAT, CD_SET_DEFAULT, result->totedge, "bevel_weight_edge")); } /* Checks that result has dvert data. */ diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.cc b/source/blender/modifiers/intern/MOD_weightvg_util.cc index def70d0b5d4..07cd6e202c3 100644 --- a/source/blender/modifiers/intern/MOD_weightvg_util.cc +++ b/source/blender/modifiers/intern/MOD_weightvg_util.cc @@ -212,7 +212,7 @@ void weightvg_do_mask(const ModifierEvalContext *ctx, /* Get vgroup idx from its name. */ /* Proceed only if vgroup is valid, else use constant factor. */ - /* Get actual dverts (ie vertex group data). */ + /* Get actual deform-verts (ie vertex group data). */ const MDeformVert *dvert = static_cast( CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT)); /* Proceed only if vgroup is valid, else assume factor = O. */ diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index cf7f97458a6..e24c2f4570b 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -59,10 +59,9 @@ DefNode(ShaderNode, SH_NODE_ATTRIBUTE, def_sh_attribute, "ATT DefNode(ShaderNode, SH_NODE_AMBIENT_OCCLUSION, def_sh_ambient_occlusion,"AMBIENT_OCCLUSION", AmbientOcclusion, "Ambient Occlusion", "Compute how much the hemisphere above the shading point is occluded, for example to add weathering effects to corners.\nNote: For Cycles, this may slow down renders significantly") DefNode(ShaderNode, SH_NODE_BACKGROUND, 0, "BACKGROUND", Background, "Background", "Add background light emission.\nNote: This node should only be used for the world surface output") DefNode(ShaderNode, SH_NODE_HOLDOUT, 0, "HOLDOUT", Holdout, "Holdout", "Create a \"hole\" in the image with zero alpha transparency, which is useful for compositing.\nNote: the holdout shader can only create alpha when transparency is enabled in the film settings") -DefNode(ShaderNode, SH_NODE_BSDF_ANISOTROPIC, def_anisotropic, "BSDF_ANISOTROPIC", BsdfAnisotropic, "Anisotropic BSDF", "Glossy reflection with separate control over U and V direction roughness") DefNode(ShaderNode, SH_NODE_BSDF_DIFFUSE, 0, "BSDF_DIFFUSE", BsdfDiffuse, "Diffuse BSDF", "Lambertian and Oren-Nayar diffuse reflection") DefNode(ShaderNode, SH_NODE_BSDF_PRINCIPLED, def_principled, "BSDF_PRINCIPLED", BsdfPrincipled, "Principled BSDF", "Physically-based, easy-to-use shader for rendering surface materials, based on the Disney principled model also known as the \"PBR\" shader") -DefNode(ShaderNode, SH_NODE_BSDF_GLOSSY, def_glossy, "BSDF_GLOSSY", BsdfGlossy, "Glossy BSDF", "Reflection with microfacet distribution, used for materials such as metal or mirrors") +DefNode(ShaderNode, SH_NODE_BSDF_GLOSSY, def_glossy, "BSDF_GLOSSY", BsdfAnisotropic, "Glossy BSDF", "Reflection with microfacet distribution, used for materials such as metal or mirrors") DefNode(ShaderNode, SH_NODE_BSDF_GLASS, def_glass, "BSDF_GLASS", BsdfGlass, "Glass BSDF", "Glass-like shader mixing refraction and reflection at grazing angles") DefNode(ShaderNode, SH_NODE_BSDF_REFRACTION, def_refraction, "BSDF_REFRACTION", BsdfRefraction, "Refraction BSDF", "Glossy refraction with sharp or microfacet distribution, typically used for materials that transmit light") DefNode(ShaderNode, SH_NODE_BSDF_TRANSLUCENT, 0, "BSDF_TRANSLUCENT", BsdfTranslucent, "Translucent BSDF", "Lambertian diffuse transmission") @@ -282,10 +281,10 @@ DefNode(FunctionNode, FN_NODE_VALUE_TO_STRING, 0, "VALUE_TO_STRING", ValueToStri DefNode(GeometryNode, GEO_NODE_ACCUMULATE_FIELD, def_geo_accumulate_field, "ACCUMULATE_FIELD", AccumulateField, "Accumulate Field", "Add the values of an evaluated field together and output the running total for each element") DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_DOMAIN_SIZE, def_geo_attribute_domain_size, "ATTRIBUTE_DOMAIN_SIZE", AttributeDomainSize, "Domain Size", "Retrieve the number of elements in a geometry for each attribute domain") -DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_STATISTIC, def_geo_attribute_statistic, "ATTRIBUTE_STATISTIC",AttributeStatistic, "Attribute Statistic","Calculate statistics about a data set from a field evaluated on a geometry") +DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_STATISTIC, def_geo_attribute_statistic, "ATTRIBUTE_STATISTIC",AttributeStatistic, "Attribute Statistic", "Calculate statistics about a data set from a field evaluated on a geometry") DefNode(GeometryNode, GEO_NODE_BLUR_ATTRIBUTE, def_geo_blur_attribute, "BLUR_ATTRIBUTE", BlurAttribute, "Blur Attribute", "Mix attribute values of neighboring elements") DefNode(GeometryNode, GEO_NODE_BOUNDING_BOX, 0, "BOUNDING_BOX", BoundBox, "Bounding Box", "Calculate the limits of a geometry's positions and generate a box mesh with those dimensions") -DefNode(GeometryNode, GEO_NODE_CAPTURE_ATTRIBUTE, def_geo_attribute_capture,"CAPTURE_ATTRIBUTE", CaptureAttribute, "Capture Attribute", "Store the result of a field on a geometry and output the data as a node socket. Allows remembering or interpolating data as the geometry changes, such as positions before deformation") +DefNode(GeometryNode, GEO_NODE_CAPTURE_ATTRIBUTE, def_geo_attribute_capture, "CAPTURE_ATTRIBUTE", CaptureAttribute, "Capture Attribute", "Store the result of a field on a geometry and output the data as a node socket. Allows remembering or interpolating data as the geometry changes, such as positions before deformation") DefNode(GeometryNode, GEO_NODE_COLLECTION_INFO, def_geo_collection_info, "COLLECTION_INFO", CollectionInfo, "Collection Info", "Retrieve geometry instances from a collection") DefNode(GeometryNode, GEO_NODE_CONVEX_HULL, 0, "CONVEX_HULL", ConvexHull, "Convex Hull", "Create a mesh that encloses all points in the input geometry with the smallest number of points") DefNode(GeometryNode, GEO_NODE_CURVE_ENDPOINT_SELECTION, 0, "CURVE_ENDPOINT_SELECTION", CurveEndpointSelection, "Endpoint Selection", "Provide a selection for an arbitrary number of endpoints in each spline") @@ -301,7 +300,7 @@ DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_SPIRAL,0, "CURVE_PRIMITIVE_SPIRAL DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_STAR, 0, "CURVE_PRIMITIVE_STAR", CurveStar, "Star", "Generate a poly spline in a star pattern by connecting alternating points of two circles") DefNode(GeometryNode, GEO_NODE_CURVE_SET_HANDLE_TYPE, def_geo_curve_set_handle_type, "CURVE_SET_HANDLES", CurveSetHandles, "Set Handle Type", "Set the handle type for the control points of a Bézier curve") DefNode(GeometryNode, GEO_NODE_CURVE_SPLINE_PARAMETER,0, "SPLINE_PARAMETER", SplineParameter, "Spline Parameter", "Retrieve how far along each spline a control point is") -DefNode(GeometryNode, GEO_NODE_CURVE_SPLINE_TYPE, def_geo_curve_spline_type,"CURVE_SPLINE_TYPE", CurveSplineType, "Set Spline Type", "Change the type of curves") +DefNode(GeometryNode, GEO_NODE_CURVE_SPLINE_TYPE, def_geo_curve_spline_type, "CURVE_SPLINE_TYPE", CurveSplineType, "Set Spline Type", "Change the type of curves") DefNode(GeometryNode, GEO_NODE_CURVE_TO_MESH, 0, "CURVE_TO_MESH", CurveToMesh, "Curve to Mesh", "Convert curves into a mesh, optionally with a custom profile shape defined by curves") DefNode(GeometryNode, GEO_NODE_CURVE_TO_POINTS, def_geo_curve_to_points, "CURVE_TO_POINTS", CurveToPoints, "Curve to Points", "Generate a point cloud by sampling positions along curves") DefNode(GeometryNode, GEO_NODE_CURVE_TOPOLOGY_CURVE_OF_POINT, 0, "CURVE_OF_POINT", CurveOfPoint, "Curve of Point", "Retrieve the curve a control point is part of") @@ -326,7 +325,7 @@ DefNode(GeometryNode, GEO_NODE_IMAGE_INFO, 0, "IMAGE_INFO", ImageInfo, "Image In DefNode(GeometryNode, GEO_NODE_IMAGE_TEXTURE, def_geo_image_texture, "IMAGE_TEXTURE", ImageTexture, "Image Texture", "Sample values from an image texture") DefNode(GeometryNode, GEO_NODE_INDEX_OF_NEAREST, 0, "INDEX_OF_NEAREST", IndexOfNearest, "Index of Nearest", "Find the nearest element in a group. Similar to the \"Sample Nearest\" node") DefNode(GeometryNode, GEO_NODE_IMAGE, def_geo_image, "IMAGE", InputImage, "Image", "Input image") -DefNode(GeometryNode, GEO_NODE_INPUT_CURVE_HANDLES, 0, "INPUT_CURVE_HANDLES", InputCurveHandlePositions,"Curve Handle Positions", "Retrieve the position of each Bézier control point's handles") +DefNode(GeometryNode, GEO_NODE_INPUT_CURVE_HANDLES, 0, "INPUT_CURVE_HANDLES", InputCurveHandlePositions, "Curve Handle Positions", "Retrieve the position of each Bézier control point's handles") DefNode(GeometryNode, GEO_NODE_INPUT_CURVE_TILT, 0, "INPUT_CURVE_TILT", InputCurveTilt, "Curve Tilt", "Retrieve the angle at each control point used to twist the curve's normal around its tangent") DefNode(GeometryNode, GEO_NODE_INPUT_ID, 0, "INPUT_ID", InputID, "ID", "Retrieve a stable random identifier value from the \"id\" attribute on the point domain, or the index if the attribute does not exist") DefNode(GeometryNode, GEO_NODE_INPUT_INDEX, 0, "INDEX", InputIndex, "Index", "Retrieve an integer value indicating the position of each element in the list, starting at zero") @@ -355,12 +354,12 @@ DefNode(GeometryNode, GEO_NODE_INPUT_SPLINE_LENGTH, 0, "SPLINE_LENGTH", SplineLe DefNode(GeometryNode, GEO_NODE_INPUT_SPLINE_RESOLUTION, 0, "INPUT_SPLINE_RESOLUTION", InputSplineResolution, "Spline Resolution", "Retrieve the number of evaluated points that will be generated for every control point on curves") DefNode(GeometryNode, GEO_NODE_INPUT_TANGENT, 0, "INPUT_TANGENT", InputTangent, "Curve Tangent", "Retrieve the direction of curves at each control point") DefNode(GeometryNode, GEO_NODE_INSTANCE_ON_POINTS, 0, "INSTANCE_ON_POINTS", InstanceOnPoints, "Instance on Points", "Generate a reference to geometry at each of the input points, without duplicating its underlying data") -DefNode(GeometryNode, GEO_NODE_INSTANCES_TO_POINTS, 0, "INSTANCES_TO_POINTS",InstancesToPoints, "Instances to Points","Generate points at the origins of instances.\nNote: Nested instances are not affected by this node") +DefNode(GeometryNode, GEO_NODE_INSTANCES_TO_POINTS, 0, "INSTANCES_TO_POINTS",InstancesToPoints, "Instances to Points", "Generate points at the origins of instances.\nNote: Nested instances are not affected by this node") DefNode(GeometryNode, GEO_NODE_IS_VIEWPORT, 0, "IS_VIEWPORT", IsViewport, "Is Viewport", "Retrieve whether the nodes are being evaluated for the viewport rather than the final render") DefNode(GeometryNode, GEO_NODE_JOIN_GEOMETRY, 0, "JOIN_GEOMETRY", JoinGeometry, "Join Geometry", "Merge separately generated geometries into a single one") DefNode(GeometryNode, GEO_NODE_MATERIAL_SELECTION, 0, "MATERIAL_SELECTION", MaterialSelection, "Material Selection", "Provide a selection of faces that use the specified material") DefNode(GeometryNode, GEO_NODE_MEAN_FILTER_SDF_VOLUME, 0, "MEAN_FILTER_SDF_VOLUME", MeanFilterSDFVolume, "Mean Filter SDF Volume", "Smooth the surface of an SDF volume by applying a mean filter") -DefNode(GeometryNode, GEO_NODE_MERGE_BY_DISTANCE, def_geo_merge_by_distance,"MERGE_BY_DISTANCE", MergeByDistance, "Merge by Distance", "Merge vertices or points within a given distance") +DefNode(GeometryNode, GEO_NODE_MERGE_BY_DISTANCE, def_geo_merge_by_distance, "MERGE_BY_DISTANCE", MergeByDistance, "Merge by Distance", "Merge vertices or points within a given distance") DefNode(GeometryNode, GEO_NODE_MESH_BOOLEAN, def_geo_boolean, "MESH_BOOLEAN", MeshBoolean, "Mesh Boolean", "Cut, subtract, or join multiple mesh inputs") DefNode(GeometryNode, GEO_NODE_MESH_FACE_GROUP_BOUNDARIES, 0, "MESH_FACE_SET_BOUNDARIES", MeshFaceSetBoundaries, "Face Group Boundaries", "Find edges on the boundaries between groups of faces with the same ID value") DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CIRCLE, def_geo_mesh_circle, "MESH_PRIMITIVE_CIRCLE", MeshCircle, "Mesh Circle", "Generate a circular ring of edges") @@ -391,7 +390,7 @@ DefNode(GeometryNode, GEO_NODE_POINTS_TO_VOLUME, def_geo_points_to_volume, "POIN DefNode(GeometryNode, GEO_NODE_POINTS, 0, "POINTS", Points, "Points", "Generate a point cloud with positions and radii defined by fields") DefNode(GeometryNode, GEO_NODE_PROXIMITY, def_geo_proximity, "PROXIMITY", Proximity, "Geometry Proximity", "Compute the closest location on the target geometry") DefNode(GeometryNode, GEO_NODE_RAYCAST, def_geo_raycast, "RAYCAST", Raycast, "Raycast", "Cast rays from the context geometry onto a target geometry, and retrieve information from each hit point") -DefNode(GeometryNode, GEO_NODE_REALIZE_INSTANCES, def_geo_realize_instances,"REALIZE_INSTANCES", RealizeInstances, "Realize Instances", "Convert instances into real geometry data") +DefNode(GeometryNode, GEO_NODE_REALIZE_INSTANCES, 0, "REALIZE_INSTANCES", RealizeInstances, "Realize Instances", "Convert instances into real geometry data") DefNode(GeometryNode, GEO_NODE_REMOVE_ATTRIBUTE, 0, "REMOVE_ATTRIBUTE", RemoveAttribute, "Remove Named Attribute", "Delete an attribute with a specified name from a geometry. Typically used to optimize performance") DefNode(GeometryNode, GEO_NODE_REPLACE_MATERIAL, 0, "REPLACE_MATERIAL", ReplaceMaterial, "Replace Material", "Swap one material with another") DefNode(GeometryNode, GEO_NODE_RESAMPLE_CURVE, def_geo_curve_resample, "RESAMPLE_CURVE", ResampleCurve, "Resample Curve", "Generate a poly spline for each input spline") @@ -407,8 +406,8 @@ DefNode(GeometryNode, GEO_NODE_SCALE_ELEMENTS, def_geo_scale_elements, "SCALE_EL DefNode(GeometryNode, GEO_NODE_SCALE_INSTANCES, 0, "SCALE_INSTANCES", ScaleInstances, "Scale Instances", "Scale geometry instances in local or global space") DefNode(GeometryNode, GEO_NODE_SDF_VOLUME_SPHERE, 0, "SDF_VOLUME_SPHERE", SDFVolumeSphere, "SDF Volume Sphere", "Generate an SDF Volume Sphere") DefNode(GeometryNode, GEO_NODE_SELF_OBJECT, 0, "SELF_OBJECT", SelfObject, "Self Object", "Retrieve the object that contains the geometry nodes modifier currently being executed") -DefNode(GeometryNode, GEO_NODE_SEPARATE_COMPONENTS, 0, "SEPARATE_COMPONENTS",SeparateComponents, "Separate Components","Split a geometry into a separate output for each type of data in the geometry") -DefNode(GeometryNode, GEO_NODE_SEPARATE_GEOMETRY, def_geo_separate_geometry,"SEPARATE_GEOMETRY", SeparateGeometry, "Separate Geometry", "Split a geometry into two geometry outputs based on a selection") +DefNode(GeometryNode, GEO_NODE_SEPARATE_COMPONENTS, 0, "SEPARATE_COMPONENTS",SeparateComponents, "Separate Components", "Split a geometry into a separate output for each type of data in the geometry") +DefNode(GeometryNode, GEO_NODE_SEPARATE_GEOMETRY, def_geo_separate_geometry, "SEPARATE_GEOMETRY", SeparateGeometry, "Separate Geometry", "Split a geometry into two geometry outputs based on a selection") DefNode(GeometryNode, GEO_NODE_SET_CURVE_HANDLES, def_geo_curve_set_handle_positions, "SET_CURVE_HANDLES", SetCurveHandlePositions, "Set Handle Positions", "Set the positions for the handles of Bézier curves") DefNode(GeometryNode, GEO_NODE_SET_CURVE_NORMAL, def_geo_set_curve_normal, "SET_CURVE_NORMAL", SetCurveNormal, "Set Curve Normal", "Set the evaluation mode for curve normals") DefNode(GeometryNode, GEO_NODE_SET_CURVE_RADIUS, 0, "SET_CURVE_RADIUS", SetCurveRadius, "Set Curve Radius", "Set the radius of the curve at each control point") @@ -429,10 +428,10 @@ DefNode(GeometryNode, GEO_NODE_STRING_JOIN, 0, "STRING_JOIN", StringJoin, "Join DefNode(GeometryNode, GEO_NODE_STRING_TO_CURVES, def_geo_string_to_curves, "STRING_TO_CURVES", StringToCurves, "String to Curves", "Generate a paragraph of text with a specific font, using a curve instance to store each character") DefNode(GeometryNode, GEO_NODE_SUBDIVIDE_CURVE, 0, "SUBDIVIDE_CURVE", SubdivideCurve, "Subdivide Curve", "Dividing each curve segment into a specified number of pieces") DefNode(GeometryNode, GEO_NODE_SUBDIVIDE_MESH, 0, "SUBDIVIDE_MESH", SubdivideMesh, "Subdivide Mesh", "Divide mesh faces into smaller ones without changing the shape or volume, using linear interpolation to place the new vertices") -DefNode(GeometryNode, GEO_NODE_SUBDIVISION_SURFACE, def_geo_subdivision_surface, "SUBDIVISION_SURFACE",SubdivisionSurface, "Subdivision Surface","Divide mesh faces to form a smooth surface, using the Catmull-Clark subdivision method") +DefNode(GeometryNode, GEO_NODE_SUBDIVISION_SURFACE, def_geo_subdivision_surface, "SUBDIVISION_SURFACE",SubdivisionSurface, "Subdivision Surface", "Divide mesh faces to form a smooth surface, using the Catmull-Clark subdivision method") DefNode(GeometryNode, GEO_NODE_SWITCH, def_geo_switch, "SWITCH", Switch, "Switch", "Switch between two inputs") DefNode(GeometryNode, GEO_NODE_TRANSFORM_GEOMETRY, 0, "TRANSFORM_GEOMETRY", Transform, "Transform Geometry", "Translate, rotate or scale the geometry") -DefNode(GeometryNode, GEO_NODE_TRANSLATE_INSTANCES, 0, "TRANSLATE_INSTANCES",TranslateInstances, "Translate Instances","Move top-level geometry instances in local or global space") +DefNode(GeometryNode, GEO_NODE_TRANSLATE_INSTANCES, 0, "TRANSLATE_INSTANCES",TranslateInstances, "Translate Instances", "Move top-level geometry instances in local or global space") DefNode(GeometryNode, GEO_NODE_TRIANGULATE, def_geo_triangulate, "TRIANGULATE", Triangulate, "Triangulate", "Convert all faces in a mesh to triangular faces") DefNode(GeometryNode, GEO_NODE_TRIM_CURVE, def_geo_curve_trim, "TRIM_CURVE", TrimCurve, "Trim Curve", "Shorten curves by removing portions at the start or end") DefNode(GeometryNode, GEO_NODE_UV_PACK_ISLANDS, 0, "UV_PACK_ISLANDS", UVPackIslands, "Pack UV Islands", "Scale islands of a UV map and move them so they fill the UV space as much as possible") diff --git a/source/blender/nodes/composite/node_composite_tree.cc b/source/blender/nodes/composite/node_composite_tree.cc index b07c38c8682..5d34b9b433f 100644 --- a/source/blender/nodes/composite/node_composite_tree.cc +++ b/source/blender/nodes/composite/node_composite_tree.cc @@ -11,8 +11,6 @@ #include "DNA_node_types.h" #include "DNA_scene_types.h" -#include "BLT_translation.h" - #include "BKE_context.h" #include "BKE_global.h" #include "BKE_image.h" diff --git a/source/blender/nodes/composite/node_composite_util.hh b/source/blender/nodes/composite/node_composite_util.hh index b883af05ff3..19f42594b82 100644 --- a/source/blender/nodes/composite/node_composite_util.hh +++ b/source/blender/nodes/composite/node_composite_util.hh @@ -10,8 +10,6 @@ #include "DNA_ID.h" #include "DNA_node_types.h" -#include "BLT_translation.h" - #include "node_composite_register.hh" #include "node_util.hh" diff --git a/source/blender/nodes/composite/nodes/node_composite_antialiasing.cc b/source/blender/nodes/composite/nodes/node_composite_antialiasing.cc index 6c6d4be6931..5583cefc740 100644 --- a/source/blender/nodes/composite/nodes/node_composite_antialiasing.cc +++ b/source/blender/nodes/composite/nodes/node_composite_antialiasing.cc @@ -5,8 +5,6 @@ * \ingroup cmpnodes */ -#include "BLT_translation.h" - #include "UI_interface.h" #include "UI_resources.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_convert_color_space.cc b/source/blender/nodes/composite/nodes/node_composite_convert_color_space.cc index 47d3d01ad4d..52786ad0c97 100644 --- a/source/blender/nodes/composite/nodes/node_composite_convert_color_space.cc +++ b/source/blender/nodes/composite/nodes/node_composite_convert_color_space.cc @@ -5,8 +5,6 @@ * \ingroup cmpnodes */ -#include "BLT_translation.h" - #include "RNA_access.h" #include "UI_interface.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_cornerpin.cc b/source/blender/nodes/composite/nodes/node_composite_cornerpin.cc index 05cdd257166..3df643c11f3 100644 --- a/source/blender/nodes/composite/nodes/node_composite_cornerpin.cc +++ b/source/blender/nodes/composite/nodes/node_composite_cornerpin.cc @@ -9,8 +9,6 @@ #include "BLI_math_matrix_types.hh" #include "BLI_math_vector_types.hh" -#include "BLT_translation.h" - #include "GPU_shader.h" #include "GPU_texture.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc index 5203609ba30..cf2c0fa3af2 100644 --- a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc +++ b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc @@ -14,8 +14,6 @@ #include "BLI_string_ref.hh" #include "BLI_utildefines.h" -#include "BLT_translation.h" - #include "BKE_context.h" #include "BKE_cryptomatte.hh" #include "BKE_global.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_defocus.cc b/source/blender/nodes/composite/nodes/node_composite_defocus.cc index b52b8d6b5c6..b8513d9ad8b 100644 --- a/source/blender/nodes/composite/nodes/node_composite_defocus.cc +++ b/source/blender/nodes/composite/nodes/node_composite_defocus.cc @@ -7,8 +7,6 @@ #include -#include "BLT_translation.h" - #include "RNA_access.h" #include "UI_interface.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_denoise.cc b/source/blender/nodes/composite/nodes/node_composite_denoise.cc index 5d3e3fe141b..31e7385519c 100644 --- a/source/blender/nodes/composite/nodes/node_composite_denoise.cc +++ b/source/blender/nodes/composite/nodes/node_composite_denoise.cc @@ -7,8 +7,6 @@ #include "BLI_system.h" -#include "BLT_translation.h" - #include "MEM_guardedalloc.h" #include "UI_interface.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_displace.cc b/source/blender/nodes/composite/nodes/node_composite_displace.cc index c617442a5a7..7933aad2f5f 100644 --- a/source/blender/nodes/composite/nodes/node_composite_displace.cc +++ b/source/blender/nodes/composite/nodes/node_composite_displace.cc @@ -10,8 +10,6 @@ #include "GPU_shader.h" #include "GPU_texture.h" -#include "BLT_translation.h" - #include "COM_node_operation.hh" #include "COM_utilities.hh" diff --git a/source/blender/nodes/composite/nodes/node_composite_double_edge_mask.cc b/source/blender/nodes/composite/nodes/node_composite_double_edge_mask.cc index b956a598c08..40a7166d506 100644 --- a/source/blender/nodes/composite/nodes/node_composite_double_edge_mask.cc +++ b/source/blender/nodes/composite/nodes/node_composite_double_edge_mask.cc @@ -8,8 +8,6 @@ #include "UI_interface.h" #include "UI_resources.h" -#include "BLT_translation.h" - #include "COM_node_operation.hh" #include "node_composite_util.hh" diff --git a/source/blender/nodes/composite/nodes/node_composite_id_mask.cc b/source/blender/nodes/composite/nodes/node_composite_id_mask.cc index 930c6e10d64..02050e137eb 100644 --- a/source/blender/nodes/composite/nodes/node_composite_id_mask.cc +++ b/source/blender/nodes/composite/nodes/node_composite_id_mask.cc @@ -7,8 +7,6 @@ #include -#include "BLT_translation.h" - #include "UI_interface.h" #include "UI_resources.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_image.cc b/source/blender/nodes/composite/nodes/node_composite_image.cc index 1d91dc52feb..75c7b612d09 100644 --- a/source/blender/nodes/composite/nodes/node_composite_image.cc +++ b/source/blender/nodes/composite/nodes/node_composite_image.cc @@ -12,8 +12,6 @@ #include "BLI_rect.h" #include "BLI_utildefines.h" -#include "BLT_translation.h" - #include "BKE_context.h" #include "BKE_global.h" #include "BKE_image.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_inpaint.cc b/source/blender/nodes/composite/nodes/node_composite_inpaint.cc index 5b5c349b976..a0289150590 100644 --- a/source/blender/nodes/composite/nodes/node_composite_inpaint.cc +++ b/source/blender/nodes/composite/nodes/node_composite_inpaint.cc @@ -5,8 +5,6 @@ * \ingroup cmpnodes */ -#include "BLT_translation.h" - #include "UI_interface.h" #include "UI_resources.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_keying.cc b/source/blender/nodes/composite/nodes/node_composite_keying.cc index b79962ebd40..c3c7bc4a0d3 100644 --- a/source/blender/nodes/composite/nodes/node_composite_keying.cc +++ b/source/blender/nodes/composite/nodes/node_composite_keying.cc @@ -7,8 +7,6 @@ #include "BLI_math_base.h" -#include "BLT_translation.h" - #include "DNA_movieclip_types.h" #include "UI_interface.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_keyingscreen.cc b/source/blender/nodes/composite/nodes/node_composite_keyingscreen.cc index b2ec9452754..9df0ba06b85 100644 --- a/source/blender/nodes/composite/nodes/node_composite_keyingscreen.cc +++ b/source/blender/nodes/composite/nodes/node_composite_keyingscreen.cc @@ -11,8 +11,6 @@ #include "BLI_math_base.h" #include "BLI_math_color.h" -#include "BLT_translation.h" - #include "BKE_context.h" #include "BKE_lib_id.h" #include "BKE_tracking.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_map_uv.cc b/source/blender/nodes/composite/nodes/node_composite_map_uv.cc index 1c10558ed85..27895cb6ee3 100644 --- a/source/blender/nodes/composite/nodes/node_composite_map_uv.cc +++ b/source/blender/nodes/composite/nodes/node_composite_map_uv.cc @@ -5,8 +5,6 @@ * \ingroup cmpnodes */ -#include "BLT_translation.h" - #include "GPU_shader.h" #include "GPU_texture.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_mask.cc b/source/blender/nodes/composite/nodes/node_composite_mask.cc index c9d631bdd58..949bf2d94c7 100644 --- a/source/blender/nodes/composite/nodes/node_composite_mask.cc +++ b/source/blender/nodes/composite/nodes/node_composite_mask.cc @@ -5,8 +5,6 @@ * \ingroup cmpnodes */ -#include "BLT_translation.h" - #include "BLI_string_utf8.h" #include "DNA_mask_types.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.cc b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.cc index 1058ad94586..6809d7753ad 100644 --- a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.cc +++ b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.cc @@ -5,8 +5,6 @@ * \ingroup cmpnodes */ -#include "BLT_translation.h" - #include "BLI_string_utf8.h" #include "BKE_context.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_output_file.cc b/source/blender/nodes/composite/nodes/node_composite_output_file.cc index efc06c80a8a..f3cd4be5e70 100644 --- a/source/blender/nodes/composite/nodes/node_composite_output_file.cc +++ b/source/blender/nodes/composite/nodes/node_composite_output_file.cc @@ -11,8 +11,6 @@ #include "BLI_string_utils.h" #include "BLI_utildefines.h" -#include "BLT_translation.h" - #include "BKE_context.h" #include "BKE_image_format.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_planetrackdeform.cc b/source/blender/nodes/composite/nodes/node_composite_planetrackdeform.cc index a819e46e56c..629cf11929b 100644 --- a/source/blender/nodes/composite/nodes/node_composite_planetrackdeform.cc +++ b/source/blender/nodes/composite/nodes/node_composite_planetrackdeform.cc @@ -9,8 +9,6 @@ #include "BLI_math_matrix_types.hh" #include "BLI_math_vector_types.hh" -#include "BLT_translation.h" - #include "DNA_defaults.h" #include "DNA_movieclip_types.h" #include "DNA_tracking_types.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.cc b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.cc index a86576b1ffb..f5e8a873ceb 100644 --- a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.cc +++ b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.cc @@ -11,8 +11,6 @@ #include "BLI_math_matrix_types.hh" #include "BLI_math_vector_types.hh" -#include "BLT_translation.h" - #include "UI_interface.h" #include "UI_resources.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_sunbeams.cc b/source/blender/nodes/composite/nodes/node_composite_sunbeams.cc index 2c217743761..bea370751dd 100644 --- a/source/blender/nodes/composite/nodes/node_composite_sunbeams.cc +++ b/source/blender/nodes/composite/nodes/node_composite_sunbeams.cc @@ -5,8 +5,6 @@ * \ingroup cmpnodes */ -#include "BLT_translation.h" - #include "UI_interface.h" #include "UI_resources.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_texture.cc b/source/blender/nodes/composite/nodes/node_composite_texture.cc index abfc0459956..2207412e49c 100644 --- a/source/blender/nodes/composite/nodes/node_composite_texture.cc +++ b/source/blender/nodes/composite/nodes/node_composite_texture.cc @@ -5,8 +5,6 @@ * \ingroup cmpnodes */ -#include "BLT_translation.h" - #include "COM_cached_texture.hh" #include "COM_node_operation.hh" #include "COM_utilities.hh" diff --git a/source/blender/nodes/composite/nodes/node_composite_vec_blur.cc b/source/blender/nodes/composite/nodes/node_composite_vec_blur.cc index 306149fd3ca..1c2969ef34c 100644 --- a/source/blender/nodes/composite/nodes/node_composite_vec_blur.cc +++ b/source/blender/nodes/composite/nodes/node_composite_vec_blur.cc @@ -5,8 +5,6 @@ * \ingroup cmpnodes */ -#include "BLT_translation.h" - #include "UI_interface.h" #include "UI_resources.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_zcombine.cc b/source/blender/nodes/composite/nodes/node_composite_zcombine.cc index 29e6ff52277..fe397fa62de 100644 --- a/source/blender/nodes/composite/nodes/node_composite_zcombine.cc +++ b/source/blender/nodes/composite/nodes/node_composite_zcombine.cc @@ -9,8 +9,6 @@ #include "BLI_math_vector.hh" #include "BLI_math_vector_types.hh" -#include "BLT_translation.h" - #include "UI_interface.h" #include "UI_resources.h" diff --git a/source/blender/nodes/function/node_function_util.hh b/source/blender/nodes/function/node_function_util.hh index 6c740f834a3..75d39e91af0 100644 --- a/source/blender/nodes/function/node_function_util.hh +++ b/source/blender/nodes/function/node_function_util.hh @@ -13,8 +13,6 @@ #include "BKE_node.hh" -#include "BLT_translation.h" - #include "NOD_multi_function.hh" #include "NOD_socket_declarations.hh" diff --git a/source/blender/nodes/function/nodes/node_fn_compare.cc b/source/blender/nodes/function/nodes/node_fn_compare.cc index 931483657c6..f9ae0c3e10a 100644 --- a/source/blender/nodes/function/nodes/node_fn_compare.cc +++ b/source/blender/nodes/function/nodes/node_fn_compare.cc @@ -7,6 +7,8 @@ #include "BLI_string.h" #include "BLI_string_utf8.h" +#include "BLT_translation.h" + #include "UI_interface.h" #include "UI_resources.h" @@ -23,20 +25,22 @@ NODE_STORAGE_FUNCS(NodeFunctionCompare) static void node_declare(NodeDeclarationBuilder &b) { b.is_function_node(); - b.add_input("A").min(-10000.0f).max(10000.0f); - b.add_input("B").min(-10000.0f).max(10000.0f); + b.add_input("A").min(-10000.0f).max(10000.0f).translation_context( + BLT_I18NCONTEXT_ID_NODETREE); + b.add_input("B").min(-10000.0f).max(10000.0f).translation_context( + BLT_I18NCONTEXT_ID_NODETREE); - b.add_input("A", "A_INT"); - b.add_input("B", "B_INT"); + b.add_input("A", "A_INT").translation_context(BLT_I18NCONTEXT_ID_NODETREE); + b.add_input("B", "B_INT").translation_context(BLT_I18NCONTEXT_ID_NODETREE); - b.add_input("A", "A_VEC3"); - b.add_input("B", "B_VEC3"); + b.add_input("A", "A_VEC3").translation_context(BLT_I18NCONTEXT_ID_NODETREE); + b.add_input("B", "B_VEC3").translation_context(BLT_I18NCONTEXT_ID_NODETREE); - b.add_input("A", "A_COL"); - b.add_input("B", "B_COL"); + b.add_input("A", "A_COL").translation_context(BLT_I18NCONTEXT_ID_NODETREE); + b.add_input("B", "B_COL").translation_context(BLT_I18NCONTEXT_ID_NODETREE); - b.add_input("A", "A_STR"); - b.add_input("B", "B_STR"); + b.add_input("A", "A_STR").translation_context(BLT_I18NCONTEXT_ID_NODETREE); + b.add_input("B", "B_STR").translation_context(BLT_I18NCONTEXT_ID_NODETREE); b.add_input("C").default_value(0.9f); b.add_input("Angle").default_value(0.0872665f).subtype(PROP_ANGLE); diff --git a/source/blender/nodes/geometry/node_geometry_tree.cc b/source/blender/nodes/geometry/node_geometry_tree.cc index 174ff3b1cca..3061e8aeac7 100644 --- a/source/blender/nodes/geometry/node_geometry_tree.cc +++ b/source/blender/nodes/geometry/node_geometry_tree.cc @@ -11,8 +11,6 @@ #include "BKE_node.hh" #include "BKE_object.h" -#include "BLT_translation.h" - #include "DNA_modifier_types.h" #include "DNA_node_types.h" #include "DNA_space_types.h" @@ -22,6 +20,8 @@ #include "UI_resources.h" +#include "BLT_translation.h" + #include "node_common.h" #include "node_geometry_register.hh" diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh index 1c9265ea239..dc42e0898d4 100644 --- a/source/blender/nodes/geometry/node_geometry_util.hh +++ b/source/blender/nodes/geometry/node_geometry_util.hh @@ -15,8 +15,6 @@ #include "BKE_node.hh" -#include "BLT_translation.h" - #include "NOD_geometry.h" #include "NOD_geometry_exec.hh" #include "NOD_socket_declarations.hh" diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc index ef5aa8a4c7a..c870eeccdae 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_domain_size.cc @@ -3,8 +3,6 @@ #include "UI_interface.h" #include "UI_resources.h" -#include "BLT_translation.h" - #include "node_geometry_util.hh" namespace blender::nodes::node_geo_attribute_domain_size_cc { diff --git a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc index 6f9842cdb6f..85ea4b1d941 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc @@ -43,12 +43,10 @@ static void node_update(bNodeTree *ntree, bNode *node) case GEO_NODE_BOOLEAN_INTERSECT: case GEO_NODE_BOOLEAN_UNION: bke::nodeSetSocketAvailability(ntree, geometry_1_socket, false); - bke::nodeSetSocketAvailability(ntree, geometry_2_socket, true); node_sock_label(geometry_2_socket, "Mesh"); break; case GEO_NODE_BOOLEAN_DIFFERENCE: bke::nodeSetSocketAvailability(ntree, geometry_1_socket, true); - bke::nodeSetSocketAvailability(ntree, geometry_2_socket, true); node_sock_label(geometry_2_socket, "Mesh 2"); break; } @@ -67,8 +65,6 @@ static void node_geo_exec(GeoNodeExecParams params) const bool hole_tolerant = params.get_input("Hole Tolerant"); Vector meshes; - Vector transforms; - VectorSet materials; Vector> material_remaps; @@ -78,10 +74,8 @@ static void node_geo_exec(GeoNodeExecParams params) /* Note that it technically wouldn't be necessary to realize the instances for the first * geometry input, but the boolean code expects the first shape for the difference operation * to be a single mesh. */ - const Mesh *mesh_in_a = set_a.get_mesh_for_read(); - if (mesh_in_a != nullptr) { + if (const Mesh *mesh_in_a = set_a.get_mesh_for_read()) { meshes.append(mesh_in_a); - transforms.append(nullptr); if (mesh_in_a->totcol == 0) { /* Necessary for faces using the default material when there are no material slots. */ materials.add(nullptr); @@ -93,17 +87,11 @@ static void node_geo_exec(GeoNodeExecParams params) } } - /* The instance transform matrices are owned by the instance group, so we have to - * keep all of them around for use during the boolean operation. */ - Vector set_groups; Vector geometry_sets = params.extract_input>("Mesh 2"); - for (const GeometrySet &geometry_set : geometry_sets) { - bke::geometry_set_gather_instances(geometry_set, set_groups); - } - for (const bke::GeometryInstanceGroup &set_group : set_groups) { - const Mesh *mesh = set_group.geometry_set.get_mesh_for_read(); - if (mesh != nullptr) { + for (const GeometrySet &geometry : geometry_sets) { + if (const Mesh *mesh = geometry.get_mesh_for_read()) { + meshes.append(mesh); Array map(mesh->totcol); for (const int i : IndexRange(mesh->totcol)) { Material *material = mesh->mat[i]; @@ -113,16 +101,6 @@ static void node_geo_exec(GeoNodeExecParams params) } } - for (const bke::GeometryInstanceGroup &set_group : set_groups) { - const Mesh *mesh_in = set_group.geometry_set.get_mesh_for_read(); - if (mesh_in != nullptr) { - meshes.append_n_times(mesh_in, set_group.transforms.size()); - for (const int i : set_group.transforms.index_range()) { - transforms.append(set_group.transforms.begin() + i); - } - } - } - AttributeOutputs attribute_outputs; attribute_outputs.intersecting_edges_id = params.get_output_anonymous_attribute_id_if_needed( "Intersecting Edges"); @@ -130,7 +108,7 @@ static void node_geo_exec(GeoNodeExecParams params) Vector intersecting_edges; Mesh *result = blender::meshintersect::direct_mesh_boolean( meshes, - transforms, + {}, float4x4::identity(), material_remaps, use_self, diff --git a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc index 5c8c6d29dc4..57bf3b87425 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc @@ -548,7 +548,7 @@ static void duplicate_faces(GeometrySet &geometry_set, } new_mesh->tag_loose_verts_none(); - new_mesh->loose_edges_tag_none(); + new_mesh->tag_loose_edges_none(); copy_face_attributes_without_id(edge_mapping, vert_mapping, diff --git a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc index 42ee0e832d9..13e64e7f857 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc @@ -120,7 +120,6 @@ static void expand_mesh(Mesh &mesh, /* Remove types that aren't supported for interpolation in this node. */ if (vert_expand != 0) { CustomData_free_layers(&mesh.vdata, CD_ORCO, mesh.totvert); - CustomData_free_layers(&mesh.vdata, CD_BWEIGHT, mesh.totvert); CustomData_free_layers(&mesh.vdata, CD_SHAPEKEY, mesh.totvert); CustomData_free_layers(&mesh.vdata, CD_CLOTH_ORCO, mesh.totvert); CustomData_free_layers(&mesh.vdata, CD_MVERT_SKIN, mesh.totvert); @@ -129,7 +128,6 @@ static void expand_mesh(Mesh &mesh, CustomData_realloc(&mesh.vdata, old_verts_num, mesh.totvert); } if (edge_expand != 0) { - CustomData_free_layers(&mesh.edata, CD_BWEIGHT, mesh.totedge); CustomData_free_layers(&mesh.edata, CD_FREESTYLE_EDGE, mesh.totedge); const int old_edges_num = mesh.totedge; mesh.totedge += edge_expand; @@ -339,7 +337,12 @@ static void extrude_mesh_vertices(Mesh &mesh, mesh, attribute_outputs.side_id.get(), ATTR_DOMAIN_EDGE, new_edge_range); } + const bool no_loose_vert_hint = mesh.runtime->loose_verts_cache.is_cached() && + mesh.runtime->loose_verts_cache.data().count == 0; BKE_mesh_runtime_clear_cache(&mesh); + if (no_loose_vert_hint) { + mesh.tag_loose_verts_none(); + } } static void fill_quad_consistent_direction(const Span other_poly_verts, @@ -401,6 +404,21 @@ static VectorSet vert_indices_from_edges(const Mesh &mesh, const Span ed return vert_indices; } +static void tag_mesh_added_faces(Mesh &mesh) +{ + const bool no_loose_vert_hint = mesh.runtime->loose_verts_cache.is_cached() && + mesh.runtime->loose_verts_cache.data().count == 0; + const bool no_loose_edge_hint = mesh.runtime->loose_edges_cache.is_cached() && + mesh.runtime->loose_edges_cache.data().count == 0; + BKE_mesh_runtime_clear_cache(&mesh); + if (no_loose_vert_hint) { + mesh.tag_loose_verts_none(); + } + if (no_loose_edge_hint) { + mesh.tag_loose_edges_none(); + } +} + static void extrude_mesh_edges(Mesh &mesh, const Field &selection_field, const Field &offset_field, @@ -679,7 +697,7 @@ static void extrude_mesh_edges(Mesh &mesh, mesh, attribute_outputs.side_id.get(), ATTR_DOMAIN_FACE, new_poly_range); } - BKE_mesh_runtime_clear_cache(&mesh); + tag_mesh_added_faces(mesh); } /** @@ -1090,7 +1108,7 @@ static void extrude_mesh_face_regions(Mesh &mesh, mesh, attribute_outputs.side_id.get(), ATTR_DOMAIN_FACE, side_poly_range); } - BKE_mesh_runtime_clear_cache(&mesh); + tag_mesh_added_faces(mesh); } static void extrude_individual_mesh_faces( @@ -1374,7 +1392,7 @@ static void extrude_individual_mesh_faces( mesh, attribute_outputs.side_id.get(), ATTR_DOMAIN_FACE, side_poly_range); } - BKE_mesh_runtime_clear_cache(&mesh); + tag_mesh_added_faces(mesh); } static void node_geo_exec(GeoNodeExecParams params) diff --git a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc index 83114c97c6d..96779218be1 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc @@ -79,15 +79,15 @@ class ImageFieldsFunction : public mf::MultiFunction { throw std::runtime_error("cannot acquire image buffer"); } - if (image_buffer_->rect_float == nullptr) { + if (image_buffer_->float_buffer.data == nullptr) { BLI_thread_lock(LOCK_IMAGE); - if (!image_buffer_->rect_float) { + if (!image_buffer_->float_buffer.data) { IMB_float_from_rect(image_buffer_); } BLI_thread_unlock(LOCK_IMAGE); } - if (image_buffer_->rect_float == nullptr) { + if (image_buffer_->float_buffer.data == nullptr) { BKE_image_release_ibuf(&image_, image_buffer_, image_lock_); throw std::runtime_error("cannot get float buffer"); } @@ -126,7 +126,7 @@ class ImageFieldsFunction : public mf::MultiFunction { if (px < 0 || py < 0 || px >= ibuf.x || py >= ibuf.y) { return float4(0.0f, 0.0f, 0.0f, 0.0f); } - return ((const float4 *)ibuf.rect_float)[px + py * ibuf.x]; + return ((const float4 *)ibuf.float_buffer.data)[px + py * ibuf.x]; } static float frac(const float x, int *ix) diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc index be32f6369c5..87dae3275d5 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc @@ -5,8 +5,6 @@ #include "BKE_mesh.hh" -#include "BLT_translation.h" - #include "node_geometry_util.hh" namespace blender::nodes::node_geo_input_mesh_face_area_cc { diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc index 1b7503ae877..05d40aeac7b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc @@ -154,7 +154,7 @@ static Mesh *create_circle_mesh(const float radius, std::iota(corner_verts.begin(), corner_verts.end(), 0); std::iota(corner_edges.begin(), corner_edges.end(), 0); - mesh->loose_edges_tag_none(); + mesh->tag_loose_edges_none(); } else if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) { for (const int i : poly_offsets.index_range()) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc index 19576fa2812..7c96cad0b2f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc @@ -724,7 +724,7 @@ Mesh *create_cylinder_or_cone_mesh(const float radius_top, calculate_selection_outputs(config, attribute_outputs, mesh->attributes_for_write()); mesh->tag_loose_verts_none(); - mesh->loose_edges_tag_none(); + mesh->tag_loose_edges_none(); mesh->bounds_set_eager(calculate_bounds_cylinder(config)); return mesh; diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc index 9805e775c4c..f43c10b5b6e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc @@ -150,7 +150,7 @@ Mesh *create_grid_mesh(const int verts_x, } mesh->tag_loose_verts_none(); - mesh->loose_edges_tag_none(); + mesh->tag_loose_edges_none(); const float3 bounds = float3(size_x * 0.5f, size_y * 0.5f, 0.0f); mesh->bounds_set_eager({-bounds, bounds}); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc index ec4f557353a..18cc1a415d4 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc @@ -331,7 +331,7 @@ static Mesh *create_uv_sphere_mesh(const float radius, }); mesh->tag_loose_verts_none(); - mesh->loose_edges_tag_none(); + mesh->tag_loose_edges_none(); mesh->bounds_set_eager(calculate_bounds_uv_sphere(radius, segments, rings)); BLI_assert(BKE_mesh_is_valid(mesh)); diff --git a/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc b/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc index ae8da54d6f4..cb37249d4d8 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc @@ -80,7 +80,7 @@ static void geometry_set_points_to_vertices( } } - mesh->loose_edges_tag_none(); + mesh->tag_loose_edges_none(); geometry_set.replace_mesh(mesh); geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_MESH}); diff --git a/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc index fce242ef753..235d2bf38ad 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc @@ -15,29 +15,13 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_output("Geometry").propagate_all(); } -static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) -{ - uiItemR(layout, ptr, "legacy_behavior", 0, nullptr, ICON_NONE); -} - static void node_geo_exec(GeoNodeExecParams params) { - const bool legacy_behavior = params.node().custom1 & GEO_NODE_REALIZE_INSTANCES_LEGACY_BEHAVIOR; - - if (legacy_behavior) { - params.error_message_add( - NodeWarningType::Info, - TIP_("This node uses legacy behavior with regards to attributes on " - "instances. The behavior can be changed in the node properties in " - "the side bar. In most cases the new behavior is the same for files created in " - "Blender 3.0")); - } - GeometrySet geometry_set = params.extract_input("Geometry"); GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry_set); geometry::RealizeInstancesOptions options; - options.keep_original_ids = legacy_behavior; - options.realize_instance_attributes = !legacy_behavior; + options.keep_original_ids = false; + options.realize_instance_attributes = true; options.propagation_info = params.get_output_propagation_info("Geometry"); geometry_set = geometry::realize_instances(geometry_set, options); params.set_output("Geometry", std::move(geometry_set)); @@ -53,7 +37,6 @@ void register_node_type_geo_realize_instances() geo_node_type_base(&ntype, GEO_NODE_REALIZE_INSTANCES, "Realize Instances", NODE_CLASS_GEOMETRY); ntype.declare = file_ns::node_declare; - ntype.draw_buttons_ex = file_ns::node_layout; ntype.geometry_node_execute = file_ns::node_geo_exec; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/intern/node_util.cc b/source/blender/nodes/intern/node_util.cc index 063c61d6477..89b0e8e45bd 100644 --- a/source/blender/nodes/intern/node_util.cc +++ b/source/blender/nodes/intern/node_util.cc @@ -184,7 +184,7 @@ void node_blend_label(const bNodeTree * /*ntree*/, const char *name; bool enum_label = RNA_enum_name(rna_enum_ramp_blend_items, node->custom1, &name); if (!enum_label) { - name = "Unknown"; + name = IFACE_("Unknown"); } BLI_strncpy_utf8(label, IFACE_(name), label_maxncpy); } @@ -207,7 +207,7 @@ void node_math_label(const bNodeTree * /*ntree*/, const char *name; bool enum_label = RNA_enum_name(rna_enum_node_math_items, node->custom1, &name); if (!enum_label) { - name = "Unknown"; + name = IFACE_("Unknown"); } BLI_strncpy_utf8(label, CTX_IFACE_(BLT_I18NCONTEXT_ID_NODETREE, name), label_maxncpy); } @@ -220,9 +220,9 @@ void node_vector_math_label(const bNodeTree * /*ntree*/, const char *name; bool enum_label = RNA_enum_name(rna_enum_node_vec_math_items, node->custom1, &name); if (!enum_label) { - name = "Unknown"; + name = IFACE_("Unknown"); } - BLI_strncpy_utf8(label, IFACE_(name), label_maxncpy); + BLI_strncpy_utf8(label, CTX_IFACE_(BLT_I18NCONTEXT_ID_NODETREE, name), label_maxncpy); } void node_filter_label(const bNodeTree * /*ntree*/, @@ -233,7 +233,7 @@ void node_filter_label(const bNodeTree * /*ntree*/, const char *name; bool enum_label = RNA_enum_name(rna_enum_node_filter_items, node->custom1, &name); if (!enum_label) { - name = "Unknown"; + name = IFACE_("Unknown"); } BLI_strncpy_utf8(label, IFACE_(name), label_maxncpy); } diff --git a/source/blender/nodes/shader/CMakeLists.txt b/source/blender/nodes/shader/CMakeLists.txt index 60b4d280257..696d07d57b5 100644 --- a/source/blender/nodes/shader/CMakeLists.txt +++ b/source/blender/nodes/shader/CMakeLists.txt @@ -32,7 +32,6 @@ set(SRC nodes/node_shader_bevel.cc nodes/node_shader_blackbody.cc nodes/node_shader_brightness.cc - nodes/node_shader_bsdf_anisotropic.cc nodes/node_shader_bsdf_diffuse.cc nodes/node_shader_bsdf_glass.cc nodes/node_shader_bsdf_glossy.cc diff --git a/source/blender/nodes/shader/node_shader_register.cc b/source/blender/nodes/shader/node_shader_register.cc index e18639f9520..78ffc4ceba3 100644 --- a/source/blender/nodes/shader/node_shader_register.cc +++ b/source/blender/nodes/shader/node_shader_register.cc @@ -17,7 +17,6 @@ void register_shader_nodes() register_node_type_sh_bevel(); register_node_type_sh_blackbody(); register_node_type_sh_brightcontrast(); - register_node_type_sh_bsdf_anisotropic(); register_node_type_sh_bsdf_diffuse(); register_node_type_sh_bsdf_glass(); register_node_type_sh_bsdf_glossy(); diff --git a/source/blender/nodes/shader/node_shader_register.hh b/source/blender/nodes/shader/node_shader_register.hh index 52ebd63fe0c..8fc81c773e1 100644 --- a/source/blender/nodes/shader/node_shader_register.hh +++ b/source/blender/nodes/shader/node_shader_register.hh @@ -13,7 +13,6 @@ void register_node_type_sh_background(); void register_node_type_sh_bevel(); void register_node_type_sh_blackbody(); void register_node_type_sh_brightcontrast(); -void register_node_type_sh_bsdf_anisotropic(); void register_node_type_sh_bsdf_diffuse(); void register_node_type_sh_bsdf_glass(); void register_node_type_sh_bsdf_glossy(); diff --git a/source/blender/nodes/shader/node_shader_tree.cc b/source/blender/nodes/shader/node_shader_tree.cc index bac537027da..c12dd2b5be9 100644 --- a/source/blender/nodes/shader/node_shader_tree.cc +++ b/source/blender/nodes/shader/node_shader_tree.cc @@ -23,8 +23,6 @@ #include "BLI_utildefines.h" #include "BLI_vector.hh" -#include "BLT_translation.h" - #include "BKE_context.h" #include "BKE_layer.h" #include "BKE_lib_id.h" @@ -884,7 +882,6 @@ static void ntree_shader_weight_tree_invert(bNodeTree *ntree, bNode *output_node break; } case SH_NODE_BACKGROUND: - case SH_NODE_BSDF_ANISOTROPIC: case SH_NODE_BSDF_DIFFUSE: case SH_NODE_BSDF_GLASS: case SH_NODE_BSDF_GLOSSY: @@ -942,7 +939,6 @@ static bool closure_node_filter(const bNode *node) case SH_NODE_ADD_SHADER: case SH_NODE_MIX_SHADER: case SH_NODE_BACKGROUND: - case SH_NODE_BSDF_ANISOTROPIC: case SH_NODE_BSDF_DIFFUSE: case SH_NODE_BSDF_GLASS: case SH_NODE_BSDF_GLOSSY: diff --git a/source/blender/nodes/shader/node_shader_util.hh b/source/blender/nodes/shader/node_shader_util.hh index 3fa86d6fb14..a220a53aa02 100644 --- a/source/blender/nodes/shader/node_shader_util.hh +++ b/source/blender/nodes/shader/node_shader_util.hh @@ -20,8 +20,6 @@ #include "BLI_threads.h" #include "BLI_utildefines.h" -#include "BLT_translation.h" - #include "BKE_colorband.h" #include "BKE_colortools.h" #include "BKE_global.h" diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.cc deleted file mode 100644 index d668f3dd0c1..00000000000 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.cc +++ /dev/null @@ -1,77 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later - * Copyright 2005 Blender Foundation */ - -#include "node_shader_util.hh" - -#include "UI_interface.h" -#include "UI_resources.h" - -namespace blender::nodes::node_shader_bsdf_anisotropic_cc { - -static void node_declare(NodeDeclarationBuilder &b) -{ - b.add_input("Color").default_value({0.8f, 0.8f, 0.8f, 1.0f}); - b.add_input("Roughness") - .default_value(0.5f) - .min(0.0f) - .max(1.0f) - .subtype(PROP_FACTOR); - b.add_input("Anisotropy").default_value(0.5f).min(-1.0f).max(1.0f); - b.add_input("Rotation") - .default_value(0.0f) - .min(0.0f) - .max(1.0f) - .subtype(PROP_FACTOR); - b.add_input("Normal").hide_value(); - b.add_input("Tangent").hide_value(); - b.add_input("Weight").unavailable(); - b.add_output("BSDF"); -} - -static void node_shader_buts_anisotropic(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) -{ - uiItemR(layout, ptr, "distribution", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE); -} - -static void node_shader_init_anisotropic(bNodeTree * /*ntree*/, bNode *node) -{ - node->custom1 = SHD_GLOSSY_GGX; -} - -static int node_shader_gpu_bsdf_anisotropic(GPUMaterial *mat, - bNode *node, - bNodeExecData * /*execdata*/, - GPUNodeStack *in, - GPUNodeStack *out) -{ - if (!in[4].link) { - GPU_link(mat, "world_normals_get", &in[4].link); - } - - GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY); - - float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f; - - return GPU_stack_link( - mat, node, "node_bsdf_anisotropic", in, out, GPU_constant(&use_multi_scatter)); -} - -} // namespace blender::nodes::node_shader_bsdf_anisotropic_cc - -/* node type definition */ -void register_node_type_sh_bsdf_anisotropic() -{ - namespace file_ns = blender::nodes::node_shader_bsdf_anisotropic_cc; - - static bNodeType ntype; - - sh_node_type_base(&ntype, SH_NODE_BSDF_ANISOTROPIC, "Anisotropic BSDF", NODE_CLASS_SHADER); - ntype.declare = file_ns::node_declare; - ntype.add_ui_poll = object_cycles_shader_nodes_poll; - ntype.draw_buttons = file_ns::node_shader_buts_anisotropic; - blender::bke::node_type_size_preset(&ntype, blender::bke::eNodeSizePreset::MIDDLE); - ntype.initfunc = file_ns::node_shader_init_anisotropic; - ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_anisotropic; - - nodeRegisterType(&ntype); -} diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.cc index 1390696c015..07ffb89cf08 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.cc +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.cc @@ -34,10 +34,6 @@ static int node_shader_gpu_bsdf_glass(GPUMaterial *mat, GPU_link(mat, "world_normals_get", &in[3].link); } - if (node->custom1 == SHD_GLOSSY_SHARP) { - GPU_link(mat, "set_value_zero", &in[1].link); - } - GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY | GPU_MATFLAG_REFRACT); float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f; diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.cc index d4c8baf2577..f36f17c27f8 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.cc +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.cc @@ -3,6 +3,9 @@ #include "node_shader_util.hh" +#include "UI_interface.h" +#include "UI_resources.h" + namespace blender::nodes::node_shader_bsdf_glossy_cc { static void node_declare(NodeDeclarationBuilder &b) @@ -13,11 +16,23 @@ static void node_declare(NodeDeclarationBuilder &b) .min(0.0f) .max(1.0f) .subtype(PROP_FACTOR); + b.add_input("Anisotropy").default_value(0.0f).min(-1.0f).max(1.0f); + b.add_input("Rotation") + .default_value(0.0f) + .min(0.0f) + .max(1.0f) + .subtype(PROP_FACTOR); b.add_input("Normal").hide_value(); + b.add_input("Tangent").hide_value(); b.add_input("Weight").unavailable(); b.add_output("BSDF"); } +static void node_shader_buts_glossy(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) +{ + uiItemR(layout, ptr, "distribution", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE); +} + static void node_shader_init_glossy(bNodeTree * /*ntree*/, bNode *node) { node->custom1 = SHD_GLOSSY_GGX; @@ -29,12 +44,8 @@ static int node_shader_gpu_bsdf_glossy(GPUMaterial *mat, GPUNodeStack *in, GPUNodeStack *out) { - if (!in[2].link) { - GPU_link(mat, "world_normals_get", &in[2].link); - } - - if (node->custom1 == SHD_GLOSSY_SHARP) { - GPU_link(mat, "set_value_zero", &in[1].link); + if (!in[4].link) { + GPU_link(mat, "world_normals_get", &in[4].link); } GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY); @@ -56,9 +67,14 @@ void register_node_type_sh_bsdf_glossy() sh_node_type_base(&ntype, SH_NODE_BSDF_GLOSSY, "Glossy BSDF", NODE_CLASS_SHADER); ntype.declare = file_ns::node_declare; ntype.add_ui_poll = object_shader_nodes_poll; + ntype.draw_buttons = file_ns::node_shader_buts_glossy; blender::bke::node_type_size_preset(&ntype, blender::bke::eNodeSizePreset::MIDDLE); ntype.initfunc = file_ns::node_shader_init_glossy; ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_glossy; nodeRegisterType(&ntype); + + /* Needed to preserve API compatibility with older versions which had separate + * Glossy and Anisotropic nodes. */ + nodeRegisterAlias(&ntype, "ShaderNodeBsdfGlossy"); } diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.cc b/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.cc index 459f2abace8..ee9afc0d0d0 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.cc +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_refraction.cc @@ -34,10 +34,6 @@ static int node_shader_gpu_bsdf_refraction(GPUMaterial *mat, GPU_link(mat, "world_normals_get", &in[3].link); } - if (node->custom1 == SHD_GLOSSY_SHARP) { - GPU_link(mat, "set_value_zero", &in[1].link); - } - GPU_material_flag_set(mat, GPU_MATFLAG_REFRACT); return GPU_stack_link(mat, node, "node_bsdf_refraction", in, out); diff --git a/source/blender/nodes/texture/node_texture_tree.cc b/source/blender/nodes/texture/node_texture_tree.cc index c67c77cf09d..12a0d82bcad 100644 --- a/source/blender/nodes/texture/node_texture_tree.cc +++ b/source/blender/nodes/texture/node_texture_tree.cc @@ -15,8 +15,6 @@ #include "BLI_threads.h" #include "BLI_utildefines.h" -#include "BLT_translation.h" - #include "BKE_context.h" #include "BKE_layer.h" #include "BKE_linestyle.h" diff --git a/source/blender/nodes/texture/nodes/node_texture_image.cc b/source/blender/nodes/texture/nodes/node_texture_image.cc index 3df6e0d1b30..59c1fb7dfab 100644 --- a/source/blender/nodes/texture/nodes/node_texture_image.cc +++ b/source/blender/nodes/texture/nodes/node_texture_image.cc @@ -40,9 +40,9 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack ** /*in*/, return; } - if (!ibuf->rect_float) { + if (!ibuf->float_buffer.data) { BLI_thread_lock(LOCK_IMAGE); - if (!ibuf->rect_float) { + if (!ibuf->float_buffer.data) { IMB_float_from_rect(ibuf); } BLI_thread_unlock(LOCK_IMAGE); @@ -61,7 +61,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack ** /*in*/, py -= ibuf->y; } - result = ibuf->rect_float + py * ibuf->x * 4 + px * 4; + result = ibuf->float_buffer.data + py * ibuf->x * 4 + px * 4; copy_v4_v4(out, result); BKE_image_release_ibuf(ima, ibuf, nullptr); diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c index 4544ace2435..51d3775a345 100644 --- a/source/blender/python/bmesh/bmesh_py_types_customdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c @@ -87,8 +87,6 @@ PyDoc_STRVAR(bpy_bmlayeraccess_collection__deform_doc, PyDoc_STRVAR( bpy_bmlayeraccess_collection__shape_doc, "Vertex shapekey absolute location (as a 3D Vector).\n\n:type: :class:`BMLayerCollection`"); -PyDoc_STRVAR(bpy_bmlayeraccess_collection__bevel_weight_doc, - "Bevel weight float in [0 - 1].\n\n:type: :class:`BMLayerCollection`"); PyDoc_STRVAR(bpy_bmlayeraccess_collection__crease_doc, "Crease for subdivision surface - float in [0 - 1].\n\n:type: " ":class:`BMLayerCollection`"); @@ -205,11 +203,6 @@ static PyGetSetDef bpy_bmlayeraccess_vert_getseters[] = { (setter)NULL, bpy_bmlayeraccess_collection__shape_doc, (void *)CD_SHAPEKEY}, - {"bevel_weight", - (getter)bpy_bmlayeraccess_collection_get, - (setter)NULL, - bpy_bmlayeraccess_collection__bevel_weight_doc, - (void *)CD_BWEIGHT}, {"crease", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, @@ -261,11 +254,6 @@ static PyGetSetDef bpy_bmlayeraccess_edge_getseters[] = { bpy_bmlayeraccess_collection__string_doc, (void *)CD_PROP_STRING}, - {"bevel_weight", - (getter)bpy_bmlayeraccess_collection_get, - (setter)NULL, - bpy_bmlayeraccess_collection__bevel_weight_doc, - (void *)CD_BWEIGHT}, {"crease", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, @@ -1160,10 +1148,6 @@ PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer) ret = Vector_CreatePyObject_wrap((float *)value, 3, NULL); break; } - case CD_BWEIGHT: { - ret = PyFloat_FromDouble(*(float *)value); - break; - } case CD_CREASE: { ret = PyFloat_FromDouble(*(float *)value); break; @@ -1275,18 +1259,6 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj } break; } - case CD_BWEIGHT: { - const float tmp_val = PyFloat_AsDouble(py_value); - if (UNLIKELY(tmp_val == -1 && PyErr_Occurred())) { - PyErr_Format( - PyExc_TypeError, "expected a float, not a %.200s", Py_TYPE(py_value)->tp_name); - ret = -1; - } - else { - *(float *)value = clamp_f(tmp_val, 0.0f, 1.0f); - } - break; - } case CD_CREASE: { const float tmp_val = PyFloat_AsDouble(py_value); if (UNLIKELY(tmp_val == -1 && PyErr_Occurred())) { diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index 98449e9d810..aaf040d2435 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -2628,6 +2628,10 @@ static int bpy_prop_arg_parse_tag_defines(PyObject *o, void *p) " :arg description: Text used for the tooltip and api documentation.\n" \ " :type description: string\n" +#define BPY_PROPDEF_CTXT_DOC \ + " :arg translation_context: Text used as context to disambiguate translations.\n" \ + " :type translation_context: string\n" + #define BPY_PROPDEF_UNIT_DOC \ " :arg unit: Enumerator in :ref:`rna_enum_property_unit_items`.\n" \ " :type unit: string\n" @@ -2746,6 +2750,7 @@ static int bpy_struct_id_used(StructRNA *srna, char *identifier) PyDoc_STRVAR(BPy_BoolProperty_doc, ".. function:: BoolProperty(name=\"\", " "description=\"\", " + "translation_context=\"*\", " "default=False, " "options={'ANIMATABLE'}, " "override=set(), " @@ -2756,8 +2761,8 @@ PyDoc_STRVAR(BPy_BoolProperty_doc, "set=None)\n" "\n" " Returns a new boolean property definition.\n" - "\n" BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC BPY_PROPDEF_OPTIONS_DOC - BPY_PROPDEF_OPTIONS_OVERRIDE_DOC BPY_PROPDEF_TAGS_DOC + "\n" BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC BPY_PROPDEF_CTXT_DOC + BPY_PROPDEF_OPTIONS_DOC BPY_PROPDEF_OPTIONS_OVERRIDE_DOC BPY_PROPDEF_TAGS_DOC BPY_PROPDEF_SUBTYPE_NUMBER_DOC BPY_PROPDEF_UPDATE_DOC BPY_PROPDEF_GET_DOC BPY_PROPDEF_SET_DOC); static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) @@ -2775,6 +2780,7 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) .srna = srna, }; const char *name = NULL, *description = ""; + const char *translation_context = NULL; bool default_value = false; PropertyRNA *prop; struct BPy_EnumProperty_Parse options_enum = { @@ -2801,6 +2807,7 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) "attr", "name", "description", + "translation_context", "default", "options", "override", @@ -2816,6 +2823,7 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) "|$" /* Optional, keyword only arguments. */ "s" /* `name` */ "s" /* `description` */ + "s" /* `translation_context` */ "O&" /* `default` */ "O&" /* `options` */ "O&" /* `override` */ @@ -2835,6 +2843,7 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) &id_data, &name, &description, + &translation_context, PyC_ParseBool, &default_value, pyrna_enum_bitfield_parse_set, @@ -2869,6 +2878,9 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw) RNA_def_property_boolean_default(prop, default_value); RNA_def_property_ui_text(prop, name ? name : id_data.value, description); + if (translation_context) { + RNA_def_property_translation_context(prop, translation_context); + } if (tags_enum.base.is_set) { RNA_def_property_tags(prop, tags_enum.base.value); @@ -2890,6 +2902,7 @@ PyDoc_STRVAR( BPy_BoolVectorProperty_doc, ".. function:: BoolVectorProperty(name=\"\", " "description=\"\", " + "translation_context=\"*\", " "default=(False, False, False), " "options={'ANIMATABLE'}, " "override=set(), " @@ -2901,7 +2914,7 @@ PyDoc_STRVAR( "set=None)\n" "\n" " Returns a new vector boolean property definition.\n" - "\n" BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC + "\n" BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC BPY_PROPDEF_CTXT_DOC " :arg default: sequence of booleans the length of *size*.\n" " :type default: sequence\n" BPY_PROPDEF_OPTIONS_DOC BPY_PROPDEF_OPTIONS_OVERRIDE_DOC BPY_PROPDEF_TAGS_DOC BPY_PROPDEF_SUBTYPE_NUMBER_ARRAY_DOC BPY_PROPDEF_VECSIZE_DOC @@ -2922,6 +2935,7 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject .srna = srna, }; const char *name = NULL, *description = ""; + const char *translation_context = NULL; bool default_value[RNA_MAX_ARRAY_DIMENSION][PYRNA_STACK_ARRAY] = {{false}}; struct BPyPropArrayLength array_len_info = {.len_total = 3}; PropertyRNA *prop; @@ -2949,6 +2963,7 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject "attr", "name", "description", + "translation_context", "default", "options", "override", @@ -2965,6 +2980,7 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject "|$" /* Optional, keyword only arguments. */ "s" /* `name` */ "s" /* `description` */ + "s" /* `translation_context` */ "O" /* `default` */ "O&" /* `options` */ "O&" /* `override` */ @@ -2985,6 +3001,7 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject &id_data, &name, &description, + &translation_context, &default_py, pyrna_enum_bitfield_parse_set, &options_enum, @@ -3044,6 +3061,9 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject } RNA_def_property_ui_text(prop, name ? name : id_data.value, description); + if (translation_context) { + RNA_def_property_translation_context(prop, translation_context); + } if (tags_enum.base.is_set) { RNA_def_property_tags(prop, tags_enum.base.value); @@ -3065,6 +3085,7 @@ PyDoc_STRVAR( BPy_IntProperty_doc, ".. function:: IntProperty(name=\"\", " "description=\"\", " + "translation_context=\"*\", " "default=0, " "min=-2**31, max=2**31-1, " "soft_min=-2**31, soft_max=2**31-1, " @@ -3078,7 +3099,7 @@ PyDoc_STRVAR( "set=None)\n" "\n" " Returns a new int property definition.\n" - "\n" BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC BPY_PROPDEF_NUM_MIN_DOC + "\n" BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC BPY_PROPDEF_CTXT_DOC BPY_PROPDEF_NUM_MIN_DOC " :type min: int\n" BPY_PROPDEF_NUM_MAX_DOC " :type max: int\n" BPY_PROPDEF_NUM_SOFTMAX_DOC " :type soft_min: int\n" BPY_PROPDEF_NUM_SOFTMIN_DOC " :type soft_max: int\n" BPY_PROPDEF_INT_STEP_DOC BPY_PROPDEF_OPTIONS_DOC @@ -3099,6 +3120,7 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) .srna = srna, }; const char *name = NULL, *description = ""; + const char *translation_context = NULL; int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX; int step = 1; int default_value = 0; @@ -3127,6 +3149,7 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) "attr", "name", "description", + "translation_context", "default", "min", "max", @@ -3147,6 +3170,7 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) "|$" /* Optional, keyword only arguments. */ "s" /* `name` */ "s" /* `description` */ + "s" /* `translation_context` */ "i" /* `default` */ "i" /* `min` */ "i" /* `max` */ @@ -3171,6 +3195,7 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) &id_data, &name, &description, + &translation_context, &default_value, &min, &max, @@ -3209,6 +3234,9 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) RNA_def_property_int_default(prop, default_value); RNA_def_property_ui_text(prop, name ? name : id_data.value, description); + if (translation_context) { + 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); @@ -3231,6 +3259,7 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw) PyDoc_STRVAR(BPy_IntVectorProperty_doc, ".. function:: IntVectorProperty(name=\"\", " "description=\"\", " + "translation_context=\"*\", " "default=(0, 0, 0), min=-2**31, max=2**31-1, " "soft_min=-2**31, " "soft_max=2**31-1, " @@ -3245,7 +3274,7 @@ PyDoc_STRVAR(BPy_IntVectorProperty_doc, "set=None)\n" "\n" " Returns a new vector int property definition.\n" - "\n" BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC + "\n" BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC BPY_PROPDEF_CTXT_DOC " :arg default: sequence of ints the length of *size*.\n" " :type default: sequence\n" BPY_PROPDEF_NUM_MIN_DOC " :type min: int\n" BPY_PROPDEF_NUM_MAX_DOC @@ -3271,6 +3300,7 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject .srna = srna, }; const char *name = NULL, *description = ""; + const char *translation_context = NULL; int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX; int step = 1; int default_value[RNA_MAX_ARRAY_DIMENSION][PYRNA_STACK_ARRAY] = {0}; @@ -3298,30 +3328,18 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject PyObject *set_fn = NULL; static const char *_keywords[] = { - "attr", - "name", - "description", - "default", - "min", - "max", - "soft_min", - "soft_max", - "step", - "options", - "override", - "tags", - "subtype", - "size", - "update", - "get", - "set", - NULL, + "attr", "name", "description", "translation_context", + "default", "min", "max", "soft_min", + "soft_max", "step", "options", "override", + "tags", "subtype", "size", "update", + "get", "set", NULL, }; static _PyArg_Parser _parser = { "O&" /* `attr` */ "|$" /* Optional, keyword only arguments. */ "s" /* `name` */ "s" /* `description` */ + "s" /* `translation_context` */ "O" /* `default` */ "i" /* `min` */ "i" /* `max` */ @@ -3347,6 +3365,7 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject &id_data, &name, &description, + &translation_context, &default_py, &min, &max, @@ -3412,6 +3431,9 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject RNA_def_property_range(prop, min, max); RNA_def_property_ui_text(prop, name ? name : id_data.value, description); + 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); if (tags_enum.base.is_set) { @@ -3433,6 +3455,7 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject PyDoc_STRVAR(BPy_FloatProperty_doc, ".. function:: FloatProperty(name=\"\", " "description=\"\", " + "translation_context=\"*\", " "default=0.0, " "min=-3.402823e+38, max=3.402823e+38, " "soft_min=-3.402823e+38, soft_max=3.402823e+38, " @@ -3448,8 +3471,8 @@ PyDoc_STRVAR(BPy_FloatProperty_doc, "set=None)\n" "\n" " Returns a new float (single precision) property definition.\n" - "\n" BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC BPY_PROPDEF_NUM_MIN_DOC - " :type min: float\n" BPY_PROPDEF_NUM_MAX_DOC + "\n" BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC BPY_PROPDEF_CTXT_DOC + BPY_PROPDEF_NUM_MIN_DOC " :type min: float\n" BPY_PROPDEF_NUM_MAX_DOC " :type max: float\n" BPY_PROPDEF_NUM_SOFTMIN_DOC " :type soft_min: float\n" BPY_PROPDEF_NUM_SOFTMAX_DOC " :type soft_max: float\n" BPY_PROPDEF_FLOAT_STEP_DOC BPY_PROPDEF_FLOAT_PREC_DOC @@ -3471,6 +3494,7 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) .srna = srna, }; const char *name = NULL, *description = ""; + const char *translation_context = NULL; float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX; float step = 3; float default_value = 0.0f; @@ -3502,15 +3526,18 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) PyObject *set_fn = NULL; static const char *_keywords[] = { - "attr", "name", "description", "default", "min", "max", "soft_min", - "soft_max", "step", "precision", "options", "override", "tags", "subtype", - "unit", "update", "get", "set", NULL, + "attr", "name", "description", "translation_context", + "default", "min", "max", "soft_min", + "soft_max", "step", "precision", "options", + "override", "tags", "subtype", "unit", + "update", "get", "set", NULL, }; static _PyArg_Parser _parser = { "O&" /* `attr` */ "|$" /* Optional, keyword only arguments. */ "s" /* `name` */ "s" /* `description` */ + "s" /* `translation_context` */ "f" /* `default` */ "f" /* `min` */ "f" /* `max` */ @@ -3537,6 +3564,7 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) &id_data, &name, &description, + &translation_context, &default_value, &min, &max, @@ -3579,6 +3607,9 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) RNA_def_property_float_default(prop, default_value); RNA_def_property_range(prop, min, max); RNA_def_property_ui_text(prop, name ? name : id_data.value, description); + 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, precision); if (tags_enum.base.is_set) { @@ -3600,6 +3631,7 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw) PyDoc_STRVAR(BPy_FloatVectorProperty_doc, ".. function:: FloatVectorProperty(name=\"\", " "description=\"\", " + "translation_context=\"*\", " "default=(0.0, 0.0, 0.0), " "min=sys.float_info.min, max=sys.float_info.max, " "soft_min=sys.float_info.min, soft_max=sys.float_info.max, " @@ -3616,7 +3648,7 @@ PyDoc_STRVAR(BPy_FloatVectorProperty_doc, "set=None)\n" "\n" " Returns a new vector float property definition.\n" - "\n" BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC + "\n" BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC BPY_PROPDEF_CTXT_DOC " :arg default: sequence of floats the length of *size*.\n" " :type default: sequence\n" BPY_PROPDEF_NUM_MIN_DOC " :type min: float\n" BPY_PROPDEF_NUM_MAX_DOC @@ -3643,6 +3675,7 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec .srna = srna, }; const char *name = NULL, *description = ""; + const char *translation_context = NULL; float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX; float step = 3; float default_value[RNA_MAX_ARRAY_DIMENSION][PYRNA_STACK_ARRAY] = {{0.0f}}; @@ -3676,15 +3709,19 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec PyObject *set_fn = NULL; static const char *_keywords[] = { - "attr", "name", "description", "default", "min", "max", "soft_min", - "soft_max", "step", "precision", "options", "override", "tags", "subtype", - "unit", "size", "update", "get", "set", NULL, + "attr", "name", "description", "translation_context", + "default", "min", "max", "soft_min", + "soft_max", "step", "precision", "options", + "override", "tags", "subtype", "unit", + "size", "update", "get", "set", + NULL, }; static _PyArg_Parser _parser = { "O&" /* `attr` */ "|$" /* Optional, keyword only arguments. */ "s" /* `name` */ "s" /* `description` */ + "s" /* `translation_context` */ "O" /* `default` */ "f" /* `min` */ "f" /* `max` */ @@ -3712,6 +3749,7 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec &id_data, &name, &description, + &translation_context, &default_py, &min, &max, @@ -3783,6 +3821,9 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec RNA_def_property_range(prop, min, max); RNA_def_property_ui_text(prop, name ? name : id_data.value, description); + 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, precision); if (tags_enum.base.is_set) { @@ -3804,6 +3845,7 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec PyDoc_STRVAR(BPy_StringProperty_doc, ".. function:: StringProperty(name=\"\", " "description=\"\", " + "translation_context=\"*\", " "default=\"\", " "maxlen=0, " "options={'ANIMATABLE'}, " @@ -3817,7 +3859,7 @@ PyDoc_STRVAR(BPy_StringProperty_doc, "search_options={'SUGGESTION'})\n" "\n" " Returns a new string property definition.\n" - "\n" BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC + "\n" BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC BPY_PROPDEF_CTXT_DOC " :arg default: initializer string.\n" " :type default: string\n" " :arg maxlen: maximum length of the string.\n" @@ -3838,7 +3880,8 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw struct BPy_PropIDParse id_data = { .srna = srna, }; - const char *name = NULL, *description = "", *default_value = ""; + const char *name = NULL, *description = ""; + const char *translation_context = NULL, *default_value = ""; int maxlen = 0; PropertyRNA *prop; @@ -3870,6 +3913,7 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw "attr", "name", "description", + "translation_context", "default", "maxlen", "options", @@ -3888,6 +3932,7 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw "|$" /* Optional, keyword only arguments. */ "s" /* `name` */ "s" /* `description` */ + "s" /* `translation_context` */ "s" /* `default` */ "i" /* `maxlen` */ "O&" /* `options` */ @@ -3910,6 +3955,7 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw &id_data, &name, &description, + &translation_context, &default_value, &maxlen, pyrna_enum_bitfield_parse_set, @@ -3956,6 +4002,9 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw RNA_def_property_string_default(prop, default_value); } RNA_def_property_ui_text(prop, name ? name : id_data.value, description); + if (translation_context) { + RNA_def_property_translation_context(prop, translation_context); + } if (tags_enum.base.is_set) { RNA_def_property_tags(prop, tags_enum.base.value); @@ -3978,6 +4027,7 @@ PyDoc_STRVAR( ".. function:: EnumProperty(items, " "name=\"\", " "description=\"\", " + "translation_context=\"*\", " "default=None, " "options={'ANIMATABLE'}, " "override=set(), " @@ -4018,7 +4068,7 @@ PyDoc_STRVAR( " will misbehave or even crash." "\n" " :type items: sequence of string tuples or a function\n" BPY_PROPDEF_NAME_DOC - BPY_PROPDEF_DESC_DOC + BPY_PROPDEF_DESC_DOC BPY_PROPDEF_CTXT_DOC " :arg default: The default value for this enum, a string from the identifiers used in " "*items*, or integer matching an item number.\n" " If the *ENUM_FLAG* option is used this must be a set of such string identifiers " @@ -4043,6 +4093,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) .srna = srna, }; const char *name = NULL, *description = ""; + const char *translation_context = NULL; PyObject *default_py = NULL; int default_value = 0; PyObject *items, *items_fast; @@ -4070,6 +4121,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) "items", "name", "description", + "translation_context", "default", "options", "override", @@ -4085,6 +4137,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) "|$" /* Optional, keyword only arguments. */ "s" /* `name` */ "s" /* `description` */ + "s" /* `translation_context` */ "O" /* `default` */ "O&" /* `options` */ "O&" /* `override` */ @@ -4104,6 +4157,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) &items, &name, &description, + &translation_context, &default_py, pyrna_enum_bitfield_parse_set, &options_enum, @@ -4188,6 +4242,9 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw) prop = RNA_def_enum( srna, id_data.value, eitems, default_value, name ? name : id_data.value, description); } + if (translation_context) { + RNA_def_property_translation_context(prop, translation_context); + } if (tags_enum.base.is_set) { RNA_def_property_tags(prop, tags_enum.base.value); @@ -4244,6 +4301,7 @@ PyDoc_STRVAR(BPy_PointerProperty_doc, ".. function:: PointerProperty(type=None, " "name=\"\", " "description=\"\", " + "translation_context=\"*\", " "options={'ANIMATABLE'}, " "override=set(), " "tags=set(), " @@ -4252,8 +4310,8 @@ PyDoc_STRVAR(BPy_PointerProperty_doc, "\n" " Returns a new pointer property definition.\n" "\n" BPY_PROPDEF_POINTER_TYPE_DOC BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC - BPY_PROPDEF_OPTIONS_DOC BPY_PROPDEF_OPTIONS_OVERRIDE_DOC BPY_PROPDEF_TAGS_DOC - BPY_PROPDEF_POLL_DOC BPY_PROPDEF_UPDATE_DOC); + BPY_PROPDEF_CTXT_DOC BPY_PROPDEF_OPTIONS_DOC BPY_PROPDEF_OPTIONS_OVERRIDE_DOC + BPY_PROPDEF_TAGS_DOC BPY_PROPDEF_POLL_DOC BPY_PROPDEF_UPDATE_DOC); PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw) { StructRNA *srna; @@ -4270,6 +4328,7 @@ PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw) .srna = srna, }; const char *name = NULL, *description = ""; + const char *translation_context = NULL; PropertyRNA *prop; StructRNA *ptype; PyObject *type = Py_None; @@ -4292,6 +4351,7 @@ PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw) "type", "name", "description", + "translation_context", "options", "override", "tags", @@ -4305,6 +4365,7 @@ PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw) "|$" /* Optional, keyword only arguments. */ "s" /* `name` */ "s" /* `description` */ + "s" /* `translation_context` */ "O&" /* `options` */ "O&" /* `override` */ "O&" /* `tags` */ @@ -4322,6 +4383,7 @@ PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw) &type, &name, &description, + &translation_context, pyrna_enum_bitfield_parse_set, &options_enum, pyrna_enum_bitfield_parse_set, @@ -4357,6 +4419,9 @@ PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw) } prop = RNA_def_pointer_runtime( srna, id_data.value, ptype, name ? name : id_data.value, description); + if (translation_context) { + RNA_def_property_translation_context(prop, translation_context); + } if (tags_enum.base.is_set) { RNA_def_property_tags(prop, tags_enum.base.value); @@ -4384,14 +4449,15 @@ PyDoc_STRVAR(BPy_CollectionProperty_doc, ".. function:: CollectionProperty(type=None, " "name=\"\", " "description=\"\", " + "translation_context=\"*\", " "options={'ANIMATABLE'}, " "override=set(), " "tags=set())\n" "\n" " Returns a new collection property definition.\n" "\n" BPY_PROPDEF_COLLECTION_TYPE_DOC BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC - BPY_PROPDEF_OPTIONS_DOC BPY_PROPDEF_OPTIONS_OVERRIDE_COLLECTION_DOC - BPY_PROPDEF_TAGS_DOC); + BPY_PROPDEF_CTXT_DOC BPY_PROPDEF_OPTIONS_DOC + BPY_PROPDEF_OPTIONS_OVERRIDE_COLLECTION_DOC BPY_PROPDEF_TAGS_DOC); PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw) { StructRNA *srna; @@ -4408,6 +4474,7 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw) .srna = srna, }; const char *name = NULL, *description = ""; + const char *translation_context = NULL; PropertyRNA *prop; StructRNA *ptype; PyObject *type = Py_None; @@ -4429,6 +4496,7 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw) "type", "name", "description", + "translation_context", "options", "override", "tags", @@ -4440,6 +4508,7 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw) "|$" /* Optional, keyword only arguments. */ "s" /* `name` */ "s" /* `description` */ + "s" /* `translation_context` */ "O&" /* `options` */ "O&" /* `override` */ "O&" /* `tags` */ @@ -4455,6 +4524,7 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw) &type, &name, &description, + &translation_context, pyrna_enum_bitfield_parse_set, &options_enum, pyrna_enum_bitfield_parse_set, @@ -4482,6 +4552,9 @@ PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw) } prop = RNA_def_collection_runtime( srna, id_data.value, ptype, name ? name : id_data.value, description); + if (translation_context) { + RNA_def_property_translation_context(prop, translation_context); + } if (tags_enum.base.is_set) { RNA_def_property_tags(prop, tags_enum.base.value); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 8b251973d14..b4be0e4e844 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -4069,7 +4069,7 @@ PyDoc_STRVAR(pyrna_struct_bl_rna_get_subclass_doc, " :rtype: :class:`bpy.types.Struct` subclass\n"); static PyObject *pyrna_struct_bl_rna_get_subclass(PyObject *cls, PyObject *args) { - char *id; + const char *id; PyObject *ret_default = Py_None; if (!PyArg_ParseTuple(args, "s|O:bl_rna_get_subclass", &id, &ret_default)) { @@ -4086,6 +4086,9 @@ static PyObject *pyrna_struct_bl_rna_get_subclass(PyObject *cls, PyObject *args) PointerRNA ptr; if (srna_base == &RNA_Node) { + /* If the given idname is an alias, translate it to the proper idname. */ + id = nodeTypeFindAlias(id); + bNodeType *nt = nodeTypeFind(id); if (nt) { RNA_pointer_create(NULL, &RNA_Struct, nt->rna_ext.srna, &ptr); diff --git a/source/blender/python/intern/bpy_rna_types_capi.c b/source/blender/python/intern/bpy_rna_types_capi.c index 105a1008a89..ae37be2f761 100644 --- a/source/blender/python/intern/bpy_rna_types_capi.c +++ b/source/blender/python/intern/bpy_rna_types_capi.c @@ -111,7 +111,8 @@ PyDoc_STRVAR(pyrna_WindowManager_clipboard_doc, "Clipboard text storage.\n\n:typ static PyObject *pyrna_WindowManager_clipboard_get(PyObject *UNUSED(self), void *UNUSED(flag)) { int text_len = 0; - char *text = WM_clipboard_text_get(false, &text_len); + /* No need for UTF8 validation as #PyC_UnicodeFromBytesAndSize handles invalid byte sequences. */ + char *text = WM_clipboard_text_get(false, false, &text_len); PyObject *result = PyC_UnicodeFromBytesAndSize(text ? text : "", text_len); if (text != NULL) { MEM_freeN(text); diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c index f40d5e0fb7d..e0d542c9351 100644 --- a/source/blender/python/mathutils/mathutils_Vector.c +++ b/source/blender/python/mathutils/mathutils_Vector.c @@ -2640,7 +2640,7 @@ static PyObject *Vector_swizzle_get(VectorObject *self, void *closure) * Set the items of this vector using a swizzle. * - If value is a vector or list this operates like an array copy, except that * the destination is effectively re-ordered as defined by the swizzle. At - * most min(len(source), len(dest)) values will be copied. + * most `min(len(source), len(destination))` values will be copied. * - If the value is scalar, it is copied to all axes listed in the swizzle. * - If an axis appears more than once in the swizzle, the final occurrence is * the one that determines its value. diff --git a/source/blender/render/intern/multires_bake.cc b/source/blender/render/intern/multires_bake.cc index 06d82cdaf23..950f4ba1033 100644 --- a/source/blender/render/intern/multires_bake.cc +++ b/source/blender/render/intern/multires_bake.cc @@ -420,7 +420,7 @@ static void *do_multires_bake_thread(void *data_v) bake_rasterize(bake_rast, uv[0], uv[1], uv[2]); /* tag image buffer for refresh */ - if (data->ibuf->rect_float) { + if (data->ibuf->float_buffer.data) { data->ibuf->userflags |= IB_RECT_INVALID; } @@ -922,13 +922,13 @@ static void apply_heights_callback(const blender::Span vert_pos thread_data->height_min = min_ff(thread_data->height_min, len); thread_data->height_max = max_ff(thread_data->height_max, len); - if (ibuf->rect_float) { - float *rrgbf = ibuf->rect_float + pixel * 4; + if (ibuf->float_buffer.data) { + float *rrgbf = ibuf->float_buffer.data + pixel * 4; rrgbf[0] = rrgbf[1] = rrgbf[2] = len; rrgbf[3] = 1.0f; } else { - char *rrgb = (char *)ibuf->rect + pixel * 4; + uchar *rrgb = ibuf->byte_buffer.data + pixel * 4; rrgb[0] = rrgb[1] = rrgb[2] = unit_float_to_uchar_clamp(len); rrgb[3] = 255; } @@ -1016,15 +1016,15 @@ static void apply_tangmat_callback(const blender::Span /*vert_p normalize_v3_length(vec, 0.5); add_v3_v3(vec, tmp); - if (ibuf->rect_float) { - float *rrgbf = ibuf->rect_float + pixel * 4; + if (ibuf->float_buffer.data) { + float *rrgbf = ibuf->float_buffer.data + pixel * 4; rrgbf[0] = vec[0]; rrgbf[1] = vec[1]; rrgbf[2] = vec[2]; rrgbf[3] = 1.0f; } else { - uchar *rrgb = (uchar *)ibuf->rect + pixel * 4; + uchar *rrgb = ibuf->byte_buffer.data + pixel * 4; rgb_float_to_uchar(rrgb, vec); rrgb[3] = 255; } @@ -1412,15 +1412,15 @@ static void bake_ibuf_normalize_displacement(ImBuf *ibuf, normalized_displacement = 0.5f; } - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { /* currently baking happens to RGBA only */ - float *fp = ibuf->rect_float + i * 4; + float *fp = ibuf->float_buffer.data + i * 4; fp[0] = fp[1] = fp[2] = normalized_displacement; fp[3] = 1.0f; } - if (ibuf->rect) { - uchar *cp = (uchar *)(ibuf->rect + i); + if (ibuf->byte_buffer.data) { + uchar *cp = ibuf->byte_buffer.data + 4 * i; cp[0] = cp[1] = cp[2] = unit_float_to_uchar_clamp(normalized_displacement); cp[3] = 255; } @@ -1564,7 +1564,7 @@ static void finish_images(MultiresBakeRender *bkr, MultiresBakeResult *result) ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; BKE_image_mark_dirty(ima, ibuf); - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { ibuf->userflags |= IB_RECT_INVALID; } diff --git a/source/blender/render/intern/pipeline.cc b/source/blender/render/intern/pipeline.cc index 0f677d95ac4..833999cee2d 100644 --- a/source/blender/render/intern/pipeline.cc +++ b/source/blender/render/intern/pipeline.cc @@ -1918,7 +1918,7 @@ bool RE_WriteRenderViewsMovie(ReportList *reports, rd, preview ? scene->r.psfra : scene->r.sfra, scene->r.cfra, - (int *)ibuf->rect, + (int *)ibuf->byte_buffer.data, ibuf->x, ibuf->y, suffix, @@ -1952,7 +1952,7 @@ bool RE_WriteRenderViewsMovie(ReportList *reports, rd, preview ? scene->r.psfra : scene->r.sfra, scene->r.cfra, - (int *)ibuf_arr[2]->rect, + (int *)ibuf_arr[2]->byte_buffer.data, ibuf_arr[2]->x, ibuf_arr[2]->y, "", @@ -2458,19 +2458,19 @@ void RE_layer_load_from_file( filepath); } - if (ibuf && (ibuf->rect || ibuf->rect_float)) { + if (ibuf && (ibuf->byte_buffer.data || ibuf->float_buffer.data)) { if (ibuf->x == layer->rectx && ibuf->y == layer->recty) { - if (ibuf->rect_float == nullptr) { + if (ibuf->float_buffer.data == nullptr) { IMB_float_from_rect(ibuf); } - memcpy(rpass->rect, ibuf->rect_float, sizeof(float[4]) * layer->rectx * layer->recty); + memcpy(rpass->rect, ibuf->float_buffer.data, sizeof(float[4]) * layer->rectx * layer->recty); } else { if ((ibuf->x - x >= layer->rectx) && (ibuf->y - y >= layer->recty)) { ImBuf *ibuf_clip; - if (ibuf->rect_float == nullptr) { + if (ibuf->float_buffer.data == nullptr) { IMB_float_from_rect(ibuf); } @@ -2478,8 +2478,9 @@ void RE_layer_load_from_file( if (ibuf_clip) { IMB_rectcpy(ibuf_clip, ibuf, 0, 0, x, y, layer->rectx, layer->recty); - memcpy( - rpass->rect, ibuf_clip->rect_float, sizeof(float[4]) * layer->rectx * layer->recty); + memcpy(rpass->rect, + ibuf_clip->float_buffer.data, + sizeof(float[4]) * layer->rectx * layer->recty); IMB_freeImBuf(ibuf_clip); } else { diff --git a/source/blender/render/intern/render_result.cc b/source/blender/render/intern/render_result.cc index d343b4f0f3a..e8476277f64 100644 --- a/source/blender/render/intern/render_result.cc +++ b/source/blender/render/intern/render_result.cc @@ -931,9 +931,9 @@ ImBuf *RE_render_result_rect_to_ibuf(RenderResult *rr, RenderView *rv = RE_RenderViewGetById(rr, view_id); /* if not exists, BKE_imbuf_write makes one */ - ibuf->rect = (uint *)rv->rect32; - ibuf->rect_float = rv->rectf; - ibuf->zbuf_float = rv->rectz; + IMB_assign_byte_buffer(ibuf, reinterpret_cast(rv->rect32), IB_DO_NOT_TAKE_OWNERSHIP); + IMB_assign_float_buffer(ibuf, rv->rectf, IB_DO_NOT_TAKE_OWNERSHIP); + IMB_assign_float_z_buffer(ibuf, rv->rectz, IB_DO_NOT_TAKE_OWNERSHIP); /* float factor for random dither, imbuf takes care of it */ ibuf->dither = dither; @@ -941,13 +941,13 @@ ImBuf *RE_render_result_rect_to_ibuf(RenderResult *rr, /* prepare to gamma correct to sRGB color space * note that sequence editor can generate 8bpc render buffers */ - if (ibuf->rect) { + if (ibuf->byte_buffer.data) { if (BKE_imtype_valid_depths(imf->imtype) & (R_IMF_CHAN_DEPTH_12 | R_IMF_CHAN_DEPTH_16 | R_IMF_CHAN_DEPTH_24 | R_IMF_CHAN_DEPTH_32)) { if (imf->depth == R_IMF_CHAN_DEPTH_8) { /* Higher depth bits are supported but not needed for current file output. */ - ibuf->rect_float = nullptr; + IMB_assign_float_buffer(ibuf, nullptr, IB_DO_NOT_TAKE_OWNERSHIP); } else { IMB_float_from_rect(ibuf); @@ -955,7 +955,7 @@ ImBuf *RE_render_result_rect_to_ibuf(RenderResult *rr, } else { /* ensure no float buffer remained from previous frame */ - ibuf->rect_float = nullptr; + IMB_assign_float_buffer(ibuf, nullptr, IB_DO_NOT_TAKE_OWNERSHIP); } } @@ -975,27 +975,27 @@ void RE_render_result_rect_from_ibuf(RenderResult *rr, const ImBuf *ibuf, const { RenderView *rv = RE_RenderViewGetById(rr, view_id); - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { rr->have_combined = true; if (!rv->rectf) { rv->rectf = MEM_cnew_array(4 * rr->rectx * rr->recty, "render_seq rectf"); } - memcpy(rv->rectf, ibuf->rect_float, sizeof(float[4]) * rr->rectx * rr->recty); + memcpy(rv->rectf, ibuf->float_buffer.data, sizeof(float[4]) * rr->rectx * rr->recty); /* TSK! Since sequence render doesn't free the *rr render result, the old rect32 * can hang around when sequence render has rendered a 32 bits one before */ MEM_SAFE_FREE(rv->rect32); } - else if (ibuf->rect) { + else if (ibuf->byte_buffer.data) { rr->have_combined = true; if (!rv->rect32) { rv->rect32 = MEM_cnew_array(rr->rectx * rr->recty, "render_seq rect"); } - memcpy(rv->rect32, ibuf->rect, sizeof(int) * rr->rectx * rr->recty); + memcpy(rv->rect32, ibuf->byte_buffer.data, sizeof(int) * rr->rectx * rr->recty); /* Same things as above, old rectf can hang around from previous render. */ MEM_SAFE_FREE(rv->rectf); diff --git a/source/blender/render/intern/texture_image.c b/source/blender/render/intern/texture_image.c index ec79b8e5193..129c9d18076 100644 --- a/source/blender/render/intern/texture_image.c +++ b/source/blender/render/intern/texture_image.c @@ -50,23 +50,23 @@ static void ibuf_get_color(float col[4], struct ImBuf *ibuf, int x, int y) { int ofs = y * ibuf->x + x; - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { if (ibuf->channels == 4) { - const float *fp = ibuf->rect_float + 4 * ofs; + const float *fp = ibuf->float_buffer.data + 4 * ofs; copy_v4_v4(col, fp); } else if (ibuf->channels == 3) { - const float *fp = ibuf->rect_float + 3 * ofs; + const float *fp = ibuf->float_buffer.data + 3 * ofs; copy_v3_v3(col, fp); col[3] = 1.0f; } else { - const float *fp = ibuf->rect_float + ofs; + const float *fp = ibuf->float_buffer.data + ofs; col[0] = col[1] = col[2] = col[3] = *fp; } } else { - const char *rect = (char *)(ibuf->rect + ofs); + const uchar *rect = ibuf->byte_buffer.data + 4 * ofs; col[0] = ((float)rect[0]) * (1.0f / 255.0f); col[1] = ((float)rect[1]) * (1.0f / 255.0f); @@ -126,7 +126,7 @@ int imagewrap(Tex *tex, ima->flag |= IMA_USED_FOR_RENDER; - if (ibuf == NULL || (ibuf->rect == NULL && ibuf->rect_float == NULL)) { + if (ibuf == NULL || (ibuf->byte_buffer.data == NULL && ibuf->float_buffer.data == NULL)) { BKE_image_pool_release_ibuf(ima, ibuf, pool); return retval; } @@ -719,8 +719,8 @@ static int ibuf_get_color_clip(float col[4], ImBuf *ibuf, int x, int y, int extf } } - if (ibuf->rect_float) { - const float *fp = ibuf->rect_float + (x + y * ibuf->x) * ibuf->channels; + if (ibuf->float_buffer.data) { + const float *fp = ibuf->float_buffer.data + (x + y * ibuf->x) * ibuf->channels; if (ibuf->channels == 1) { col[0] = col[1] = col[2] = col[3] = *fp; } @@ -732,7 +732,7 @@ static int ibuf_get_color_clip(float col[4], ImBuf *ibuf, int x, int y, int extf } } else { - const char *rect = (char *)(ibuf->rect + x + y * ibuf->x); + const uchar *rect = ibuf->byte_buffer.data + 4 * (x + y * ibuf->x); float inv_alpha_fac = (1.0f / 255.0f) * rect[3] * (1.0f / 255.0f); col[0] = rect[0] * inv_alpha_fac; col[1] = rect[1] * inv_alpha_fac; @@ -979,7 +979,7 @@ static int imagewraposa_aniso(Tex *tex, ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, pool); } - if ((ibuf == NULL) || ((ibuf->rect == NULL) && (ibuf->rect_float == NULL))) { + if ((ibuf == NULL) || ((ibuf->byte_buffer.data == NULL) && (ibuf->float_buffer.data == NULL))) { if (ima) { BKE_image_pool_release_ibuf(ima, ibuf, pool); } @@ -1383,7 +1383,7 @@ int imagewraposa(Tex *tex, ima->flag |= IMA_USED_FOR_RENDER; } - if (ibuf == NULL || (ibuf->rect == NULL && ibuf->rect_float == NULL)) { + if (ibuf == NULL || (ibuf->byte_buffer.data == NULL && ibuf->float_buffer.data == NULL)) { if (ima) { BKE_image_pool_release_ibuf(ima, ibuf, pool); } diff --git a/source/blender/render/intern/texture_procedural.c b/source/blender/render/intern/texture_procedural.c index 13207543fd7..c816c748c41 100644 --- a/source/blender/render/intern/texture_procedural.c +++ b/source/blender/render/intern/texture_procedural.c @@ -1060,7 +1060,8 @@ static int multitex_nodes_intern(Tex *tex, ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool); /* don't linearize float buffers, assumed to be linear */ - if (ibuf != NULL && ibuf->rect_float == NULL && (retval & TEX_RGB) && scene_color_manage) { + if (ibuf != NULL && ibuf->float_buffer.data == NULL && (retval & TEX_RGB) && + scene_color_manage) { IMB_colormanagement_colorspace_to_scene_linear_v3(texres->trgba, ibuf->rect_colorspace); } @@ -1105,7 +1106,8 @@ static int multitex_nodes_intern(Tex *tex, ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool); /* don't linearize float buffers, assumed to be linear */ - if (ibuf != NULL && ibuf->rect_float == NULL && (retval & TEX_RGB) && scene_color_manage) { + if (ibuf != NULL && ibuf->float_buffer.data == NULL && (retval & TEX_RGB) && + scene_color_manage) { IMB_colormanagement_colorspace_to_scene_linear_v3(texres->trgba, ibuf->rect_colorspace); } diff --git a/source/blender/sequencer/intern/disk_cache.c b/source/blender/sequencer/intern/disk_cache.c index f76b1891435..f2ca5fe78d6 100644 --- a/source/blender/sequencer/intern/disk_cache.c +++ b/source/blender/sequencer/intern/disk_cache.c @@ -424,7 +424,8 @@ static size_t deflate_imbuf_to_file(ImBuf *ibuf, int level, DiskCacheHeaderEntry *header_entry) { - void *data = (ibuf->rect != NULL) ? (void *)ibuf->rect : (void *)ibuf->rect_float; + void *data = (ibuf->byte_buffer.data != NULL) ? (void *)ibuf->byte_buffer.data : + (void *)ibuf->float_buffer.data; /* Apply compression if wanted, otherwise just write directly to the file. */ if (level > 0) { @@ -438,7 +439,8 @@ static size_t deflate_imbuf_to_file(ImBuf *ibuf, static size_t inflate_file_to_imbuf(ImBuf *ibuf, FILE *file, DiskCacheHeaderEntry *header_entry) { - void *data = (ibuf->rect != NULL) ? (void *)ibuf->rect : (void *)ibuf->rect_float; + void *data = (ibuf->byte_buffer.data != NULL) ? (void *)ibuf->byte_buffer.data : + (void *)ibuf->float_buffer.data; char header[4]; fseek(file, header_entry->offset, SEEK_SET); if (fread(header, 1, sizeof(header), file) != sizeof(header)) { @@ -519,7 +521,7 @@ static int seq_disk_cache_add_header_entry(SeqCacheKey *key, ImBuf *ibuf, DiskCa /* Store colorspace name of ibuf. */ const char *colorspace_name; - if (ibuf->rect) { + if (ibuf->byte_buffer.data) { header->entry[i].size_raw = ibuf->x * ibuf->y * ibuf->channels; colorspace_name = IMB_colormanagement_get_rect_colorspace(ibuf); } diff --git a/source/blender/sequencer/intern/effects.c b/source/blender/sequencer/intern/effects.c index afbe74da4b5..965a6836d20 100644 --- a/source/blender/sequencer/intern/effects.c +++ b/source/blender/sequencer/intern/effects.c @@ -78,15 +78,15 @@ static void slice_get_byte_buffers(const SeqRenderData *context, { int offset = 4 * start_line * context->rectx; - *rect1 = (uchar *)ibuf1->rect + offset; - *rect_out = (uchar *)out->rect + offset; + *rect1 = ibuf1->byte_buffer.data + offset; + *rect_out = out->byte_buffer.data + offset; if (ibuf2) { - *rect2 = (uchar *)ibuf2->rect + offset; + *rect2 = ibuf2->byte_buffer.data + offset; } if (ibuf3) { - *rect3 = (uchar *)ibuf3->rect + offset; + *rect3 = ibuf3->byte_buffer.data + offset; } } @@ -103,15 +103,15 @@ static void slice_get_float_buffers(const SeqRenderData *context, { int offset = 4 * start_line * context->rectx; - *rect1 = ibuf1->rect_float + offset; - *rect_out = out->rect_float + offset; + *rect1 = ibuf1->float_buffer.data + offset; + *rect_out = out->float_buffer.data + offset; if (ibuf2) { - *rect2 = ibuf2->rect_float + offset; + *rect2 = ibuf2->float_buffer.data + offset; } if (ibuf3) { - *rect3 = ibuf3->rect_float + offset; + *rect3 = ibuf3->float_buffer.data + offset; } } @@ -142,8 +142,8 @@ static ImBuf *prepare_effect_imbufs(const SeqRenderData *context, /* hmmm, global float option ? */ out = IMB_allocImBuf(x, y, 32, IB_rect); } - else if ((ibuf1 && ibuf1->rect_float) || (ibuf2 && ibuf2->rect_float) || - (ibuf3 && ibuf3->rect_float)) + else if ((ibuf1 && ibuf1->float_buffer.data) || (ibuf2 && ibuf2->float_buffer.data) || + (ibuf3 && ibuf3->float_buffer.data)) { /* if any inputs are rectfloat, output is float too */ @@ -153,31 +153,31 @@ static ImBuf *prepare_effect_imbufs(const SeqRenderData *context, out = IMB_allocImBuf(x, y, 32, IB_rect); } - if (out->rect_float) { - if (ibuf1 && !ibuf1->rect_float) { + if (out->float_buffer.data) { + if (ibuf1 && !ibuf1->float_buffer.data) { seq_imbuf_to_sequencer_space(scene, ibuf1, true); } - if (ibuf2 && !ibuf2->rect_float) { + if (ibuf2 && !ibuf2->float_buffer.data) { seq_imbuf_to_sequencer_space(scene, ibuf2, true); } - if (ibuf3 && !ibuf3->rect_float) { + if (ibuf3 && !ibuf3->float_buffer.data) { seq_imbuf_to_sequencer_space(scene, ibuf3, true); } IMB_colormanagement_assign_float_colorspace(out, scene->sequencer_colorspace_settings.name); } else { - if (ibuf1 && !ibuf1->rect) { + if (ibuf1 && !ibuf1->byte_buffer.data) { IMB_rect_from_float(ibuf1); } - if (ibuf2 && !ibuf2->rect) { + if (ibuf2 && !ibuf2->byte_buffer.data) { IMB_rect_from_float(ibuf2); } - if (ibuf3 && !ibuf3->rect) { + if (ibuf3 && !ibuf3->byte_buffer.data) { IMB_rect_from_float(ibuf3); } } @@ -286,7 +286,7 @@ static void do_alphaover_effect(const SeqRenderData *context, int total_lines, ImBuf *out) { - if (out->rect_float) { + if (out->float_buffer.data) { float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slice_get_float_buffers( @@ -407,7 +407,7 @@ static void do_alphaunder_effect(const SeqRenderData *context, int total_lines, ImBuf *out) { - if (out->rect_float) { + if (out->float_buffer.data) { float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slice_get_float_buffers( @@ -487,7 +487,7 @@ static void do_cross_effect(const SeqRenderData *context, int total_lines, ImBuf *out) { - if (out->rect_float) { + if (out->float_buffer.data) { float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slice_get_float_buffers( @@ -732,7 +732,7 @@ static void do_gammacross_effect(const SeqRenderData *context, int total_lines, ImBuf *out) { - if (out->rect_float) { + if (out->float_buffer.data) { float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slice_get_float_buffers( @@ -811,7 +811,7 @@ static void do_add_effect(const SeqRenderData *context, int total_lines, ImBuf *out) { - if (out->rect_float) { + if (out->float_buffer.data) { float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slice_get_float_buffers( @@ -892,7 +892,7 @@ static void do_sub_effect(const SeqRenderData *context, int total_lines, ImBuf *out) { - if (out->rect_float) { + if (out->float_buffer.data) { float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slice_get_float_buffers( @@ -1053,7 +1053,7 @@ static void do_mul_effect(const SeqRenderData *context, int total_lines, ImBuf *out) { - if (out->rect_float) { + if (out->float_buffer.data) { float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slice_get_float_buffers( @@ -1287,7 +1287,7 @@ static void do_blend_mode_effect(const SeqRenderData *context, int total_lines, ImBuf *out) { - if (out->rect_float) { + if (out->float_buffer.data) { float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slice_get_float_buffers( context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); @@ -1338,7 +1338,7 @@ static void do_colormix_effect(const SeqRenderData *context, ColorMixVars *data = seq->effectdata; fac = data->factor; - if (out->rect_float) { + if (out->float_buffer.data) { float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slice_get_float_buffers( context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out); @@ -1776,23 +1776,23 @@ static ImBuf *do_wipe_effect(const SeqRenderData *context, { ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); - if (out->rect_float) { + if (out->float_buffer.data) { do_wipe_effect_float(seq, fac, context->rectx, context->recty, - ibuf1->rect_float, - ibuf2->rect_float, - out->rect_float); + ibuf1->float_buffer.data, + ibuf2->float_buffer.data, + out->float_buffer.data); } else { do_wipe_effect_byte(seq, fac, context->rectx, context->recty, - (uchar *)ibuf1->rect, - (uchar *)ibuf2->rect, - (uchar *)out->rect); + ibuf1->byte_buffer.data, + ibuf2->byte_buffer.data, + out->byte_buffer.data); } return out; @@ -2254,15 +2254,15 @@ static ImBuf *do_glow_effect(const SeqRenderData *context, int render_size = 100 * context->rectx / context->scene->r.xsch; - if (out->rect_float) { + if (out->float_buffer.data) { do_glow_effect_float(seq, render_size, fac, context->rectx, context->recty, - ibuf1->rect_float, + ibuf1->float_buffer.data, NULL, - out->rect_float); + out->float_buffer.data); } else { do_glow_effect_byte(seq, @@ -2270,9 +2270,9 @@ static ImBuf *do_glow_effect(const SeqRenderData *context, fac, context->rectx, context->recty, - (uchar *)ibuf1->rect, + ibuf1->byte_buffer.data, NULL, - (uchar *)out->rect); + out->byte_buffer.data); } return out; @@ -2333,14 +2333,14 @@ static ImBuf *do_solid_color(const SeqRenderData *context, int x = out->x; int y = out->y; - if (out->rect) { + if (out->byte_buffer.data) { uchar color[4]; color[0] = cv->col[0] * 255; color[1] = cv->col[1] * 255; color[2] = cv->col[2] * 255; color[3] = 255; - uchar *rect = (uchar *)out->rect; + uchar *rect = out->byte_buffer.data; for (int i = 0; i < y; i++) { for (int j = 0; j < x; j++) { @@ -2352,14 +2352,14 @@ static ImBuf *do_solid_color(const SeqRenderData *context, } } } - else if (out->rect_float) { + else if (out->float_buffer.data) { float color[4]; color[0] = cv->col[0]; color[1] = cv->col[1]; color[2] = cv->col[2]; color[3] = 255; - float *rect_float = out->rect_float; + float *rect_float = out->float_buffer.data; for (int i = 0; i < y; i++) { for (int j = 0; j < x; j++) { @@ -2716,7 +2716,7 @@ static void do_overdrop_effect(const SeqRenderData *context, int x = context->rectx; int y = total_lines; - if (out->rect_float) { + if (out->float_buffer.data) { float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slice_get_float_buffers( @@ -2997,7 +2997,7 @@ static void do_gaussian_blur_effect_x_cb(const SeqRenderData *context, int total_lines, ImBuf *out) { - if (out->rect_float) { + if (out->float_buffer.data) { float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slice_get_float_buffers( @@ -3009,7 +3009,7 @@ static void do_gaussian_blur_effect_x_cb(const SeqRenderData *context, total_lines, context->rectx, context->recty, - ibuf->rect_float, + ibuf->float_buffer.data, rect_out); } else { @@ -3024,7 +3024,7 @@ static void do_gaussian_blur_effect_x_cb(const SeqRenderData *context, total_lines, context->rectx, context->recty, - (uchar *)ibuf->rect, + ibuf->byte_buffer.data, rect_out); } } @@ -3036,7 +3036,7 @@ static void do_gaussian_blur_effect_y_cb(const SeqRenderData *context, int total_lines, ImBuf *out) { - if (out->rect_float) { + if (out->float_buffer.data) { float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL; slice_get_float_buffers( @@ -3048,7 +3048,7 @@ static void do_gaussian_blur_effect_y_cb(const SeqRenderData *context, total_lines, context->rectx, context->recty, - ibuf->rect_float, + ibuf->float_buffer.data, rect_out); } else { @@ -3063,7 +3063,7 @@ static void do_gaussian_blur_effect_y_cb(const SeqRenderData *context, total_lines, context->rectx, context->recty, - (uchar *)ibuf->rect, + ibuf->byte_buffer.data, rect_out); } } @@ -3344,7 +3344,8 @@ static ImBuf *do_text_effect(const SeqRenderData *context, /* use max width to enable newlines only */ BLF_wordwrap(font, (data->wrap_width != 0.0f) ? data->wrap_width * width : -1); - BLF_buffer(font, out->rect_float, (uchar *)out->rect, width, height, out->channels, display); + BLF_buffer( + font, out->float_buffer.data, out->byte_buffer.data, width, height, out->channels, display); line_height = BLF_height_max(font); @@ -3384,7 +3385,7 @@ static ImBuf *do_text_effect(const SeqRenderData *context, } if (data->flag & SEQ_TEXT_BOX) { - if (out->rect) { + if (out->byte_buffer.data) { const int margin = data->box_margin * width; const int minx = x + wrap.rect.xmin - margin; const int maxx = x + wrap.rect.xmax + margin; diff --git a/source/blender/sequencer/intern/modifier.c b/source/blender/sequencer/intern/modifier.c index 154284a2e96..da4472700c5 100644 --- a/source/blender/sequencer/intern/modifier.c +++ b/source/blender/sequencer/intern/modifier.c @@ -90,12 +90,12 @@ static ImBuf *modifier_render_mask_input(const SeqRenderData *context, mask_input = seq_render_strip(context, &state, mask_sequence, timeline_frame); if (make_float) { - if (!mask_input->rect_float) { + if (!mask_input->float_buffer.data) { IMB_float_from_rect(mask_input); } } else { - if (!mask_input->rect) { + if (!mask_input->byte_buffer.data) { IMB_rect_from_float(mask_input); } } @@ -139,21 +139,21 @@ static void modifier_init_handle(void *handle_v, int start_line, int tot_line, v handle->apply_callback = init_data->apply_callback; handle->user_data = init_data->user_data; - if (ibuf->rect) { - handle->rect = (uchar *)ibuf->rect + offset; + if (ibuf->byte_buffer.data) { + handle->rect = ibuf->byte_buffer.data + offset; } - if (ibuf->rect_float) { - handle->rect_float = ibuf->rect_float + offset; + if (ibuf->float_buffer.data) { + handle->rect_float = ibuf->float_buffer.data + offset; } if (mask) { - if (mask->rect) { - handle->mask_rect = (uchar *)mask->rect + offset; + if (mask->byte_buffer.data) { + handle->mask_rect = mask->byte_buffer.data + offset; } - if (mask->rect_float) { - handle->mask_rect_float = mask->rect_float + offset; + if (mask->float_buffer.data) { + handle->mask_rect_float = mask->float_buffer.data + offset; } } else { @@ -523,21 +523,21 @@ static void color_balance_init_handle(void *handle_v, handle->height = tot_line; handle->make_float = init_data->make_float; - if (ibuf->rect) { - handle->rect = (uchar *)ibuf->rect + offset; + if (ibuf->byte_buffer.data) { + handle->rect = ibuf->byte_buffer.data + offset; } - if (ibuf->rect_float) { - handle->rect_float = ibuf->rect_float + offset; + if (ibuf->float_buffer.data) { + handle->rect_float = ibuf->float_buffer.data + offset; } if (mask) { - if (mask->rect) { - handle->mask_rect = (uchar *)mask->rect + offset; + if (mask->byte_buffer.data) { + handle->mask_rect = mask->byte_buffer.data + offset; } - if (mask->rect_float) { - handle->mask_rect_float = mask->rect_float + offset; + if (mask->float_buffer.data) { + handle->mask_rect_float = mask->float_buffer.data + offset; } } else { @@ -593,7 +593,7 @@ static void modifier_color_balance_apply( { ColorBalanceInitData init_data; - if (!ibuf->rect_float && make_float) { + if (!ibuf->float_buffer.data && make_float) { imb_addrectfloatImBuf(ibuf, 4); } @@ -613,7 +613,7 @@ static void modifier_color_balance_apply( * free byte buffer if there's float buffer since float buffer would be used for * color balance in favor of byte buffer */ - if (ibuf->rect_float && ibuf->rect) { + if (ibuf->float_buffer.data && ibuf->byte_buffer.data) { imb_freerectImBuf(ibuf); } } @@ -1311,11 +1311,12 @@ static void tonemapmodifier_apply(struct SequenceModifierData *smd, ImBuf *ibuf, SequencerTonemapModifierData *tmmd = (SequencerTonemapModifierData *)smd; AvgLogLum data; data.tmmd = tmmd; - data.colorspace = (ibuf->rect_float != NULL) ? ibuf->float_colorspace : ibuf->rect_colorspace; + data.colorspace = (ibuf->float_buffer.data != NULL) ? ibuf->float_colorspace : + ibuf->rect_colorspace; float lsum = 0.0f; int p = ibuf->x * ibuf->y; - float *fp = ibuf->rect_float; - uchar *cp = (uchar *)ibuf->rect; + float *fp = ibuf->float_buffer.data; + uchar *cp = ibuf->byte_buffer.data; float avl, maxl = -FLT_MAX, minl = FLT_MAX; const float sc = 1.0f / p; float Lav = 0.0f; @@ -1517,7 +1518,7 @@ ImBuf *SEQ_modifier_apply_stack(const SeqRenderData *context, } ImBuf *mask = modifier_mask_get( - smd, context, timeline_frame, frame_offset, ibuf->rect_float != NULL); + smd, context, timeline_frame, frame_offset, ibuf->float_buffer.data != NULL); if (processed_ibuf == ibuf) { processed_ibuf = IMB_dupImBuf(ibuf); diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c index 6b7df3f3e11..e070b4f442a 100644 --- a/source/blender/sequencer/intern/render.c +++ b/source/blender/sequencer/intern/render.c @@ -93,7 +93,7 @@ void seq_imbuf_assign_spaces(Scene *scene, ImBuf *ibuf) IMB_colormanagement_assign_rect_colorspace(ibuf, scene->sequencer_colorspace_settings.name); } #endif - if (ibuf->rect_float != NULL) { + if (ibuf->float_buffer.data != NULL) { IMB_colormanagement_assign_float_colorspace(ibuf, scene->sequencer_colorspace_settings.name); } } @@ -101,13 +101,13 @@ void seq_imbuf_assign_spaces(Scene *scene, ImBuf *ibuf) void seq_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, bool make_float) { /* Early output check: if both buffers are NULL we have nothing to convert. */ - if (ibuf->rect_float == NULL && ibuf->rect == NULL) { + if (ibuf->float_buffer.data == NULL && ibuf->byte_buffer.data == NULL) { return; } /* Get common conversion settings. */ const char *to_colorspace = scene->sequencer_colorspace_settings.name; /* Perform actual conversion logic. */ - if (ibuf->rect_float == NULL) { + if (ibuf->float_buffer.data == NULL) { /* We are not requested to give float buffer and byte buffer is already * in thee required colorspace. Can skip doing anything here. */ @@ -123,16 +123,20 @@ void seq_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, bool make_float) * However, this might also have negative effect by adding weird * artifacts which will then not happen in final render. */ - IMB_colormanagement_transform_byte_threaded( - (uchar *)ibuf->rect, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace); + IMB_colormanagement_transform_byte_threaded(ibuf->byte_buffer.data, + ibuf->x, + ibuf->y, + ibuf->channels, + from_colorspace, + to_colorspace); } else { /* We perform conversion to a float buffer so we don't worry about * precision loss. */ imb_addrectfloatImBuf(ibuf, 4); - IMB_colormanagement_transform_from_byte_threaded(ibuf->rect_float, - (uchar *)ibuf->rect, + IMB_colormanagement_transform_from_byte_threaded(ibuf->float_buffer.data, + ibuf->byte_buffer.data, ibuf->x, ibuf->y, ibuf->channels, @@ -151,11 +155,16 @@ void seq_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, bool make_float) /* We don't want both byte and float buffers around: they'll either run * out of sync or conversion of byte buffer will lose precision in there. */ - if (ibuf->rect != NULL) { + if (ibuf->byte_buffer.data != NULL) { imb_freerectImBuf(ibuf); } - IMB_colormanagement_transform_threaded( - ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, true); + IMB_colormanagement_transform_threaded(ibuf->float_buffer.data, + ibuf->x, + ibuf->y, + ibuf->channels, + from_colorspace, + to_colorspace, + true); } seq_imbuf_assign_spaces(scene, ibuf); } @@ -166,13 +175,18 @@ void SEQ_render_imbuf_from_sequencer_space(Scene *scene, ImBuf *ibuf) const char *to_colorspace = IMB_colormanagement_role_colorspace_name_get( COLOR_ROLE_SCENE_LINEAR); - if (!ibuf->rect_float) { + if (!ibuf->float_buffer.data) { return; } if (to_colorspace && to_colorspace[0] != '\0') { - IMB_colormanagement_transform_threaded( - ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, true); + IMB_colormanagement_transform_threaded(ibuf->float_buffer.data, + ibuf->x, + ibuf->y, + ibuf->channels, + from_colorspace, + to_colorspace, + true); IMB_colormanagement_assign_float_colorspace(ibuf, to_colorspace); } } @@ -554,13 +568,13 @@ static void sequencer_preprocess_transform_crop( static void multibuf(ImBuf *ibuf, const float fmul) { - char *rt; + uchar *rt; float *rt_float; int a; - rt = (char *)ibuf->rect; - rt_float = ibuf->rect_float; + rt = ibuf->byte_buffer.data; + rt_float = ibuf->float_buffer.data; if (rt) { const int imul = (int)(256.0f * fmul); @@ -614,7 +628,7 @@ static ImBuf *input_preprocess(const SeqRenderData *context, { const int x = context->rectx; const int y = context->recty; - preprocessed_ibuf = IMB_allocImBuf(x, y, 32, ibuf->rect_float ? IB_rectfloat : IB_rect); + preprocessed_ibuf = IMB_allocImBuf(x, y, 32, ibuf->float_buffer.data ? IB_rectfloat : IB_rect); sequencer_preprocess_transform_crop(ibuf, preprocessed_ibuf, context, seq, is_proxy_image); @@ -641,11 +655,11 @@ static ImBuf *input_preprocess(const SeqRenderData *context, } if (seq->flag & SEQ_MAKE_FLOAT) { - if (!preprocessed_ibuf->rect_float) { + if (!preprocessed_ibuf->float_buffer.data) { seq_imbuf_to_sequencer_space(scene, preprocessed_ibuf, true); } - if (preprocessed_ibuf->rect) { + if (preprocessed_ibuf->byte_buffer.data) { imb_freerectImBuf(preprocessed_ibuf); } } @@ -921,7 +935,7 @@ static ImBuf *seq_render_image_strip_view(const SeqRenderData *context, } /* We don't need both (speed reasons)! */ - if (ibuf->rect_float != NULL && ibuf->rect != NULL) { + if (ibuf->float_buffer.data != NULL && ibuf->byte_buffer.data != NULL) { imb_freerectImBuf(ibuf); } @@ -1108,7 +1122,7 @@ static ImBuf *seq_render_movie_strip_view(const SeqRenderData *context, seq_imbuf_to_sequencer_space(context->scene, ibuf, false); /* We don't need both (speed reasons)! */ - if (ibuf->rect_float != NULL && ibuf->rect != NULL) { + if (ibuf->float_buffer.data != NULL && ibuf->byte_buffer.data != NULL) { imb_freerectImBuf(ibuf); } @@ -1317,7 +1331,7 @@ ImBuf *seq_render_mask(const SeqRenderData *context, ibuf = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rectfloat); fp_src = maskbuf; - fp_dst = ibuf->rect_float; + fp_dst = ibuf->float_buffer.data; i = context->rectx * context->recty; while (--i) { fp_dst[0] = fp_dst[1] = fp_dst[2] = *fp_src; @@ -1335,7 +1349,7 @@ ImBuf *seq_render_mask(const SeqRenderData *context, ibuf = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect); fp_src = maskbuf; - ub_dst = (uchar *)ibuf->rect; + ub_dst = ibuf->byte_buffer.data; i = context->rectx * context->recty; while (--i) { ub_dst[0] = ub_dst[1] = ub_dst[2] = (uchar)(*fp_src * 255.0f); /* already clamped */ @@ -1563,14 +1577,15 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, if (rres.rectf) { ibufs_arr[view_id] = IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat); - memcpy(ibufs_arr[view_id]->rect_float, + memcpy(ibufs_arr[view_id]->float_buffer.data, rres.rectf, sizeof(float[4]) * rres.rectx * rres.recty); if (rres.rectz) { addzbuffloatImBuf(ibufs_arr[view_id]); - memcpy( - ibufs_arr[view_id]->zbuf_float, rres.rectz, sizeof(float) * rres.rectx * rres.recty); + memcpy(ibufs_arr[view_id]->float_z_buffer.data, + rres.rectz, + sizeof(float) * rres.rectx * rres.recty); } /* float buffers in the sequencer are not linear */ @@ -1578,7 +1593,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, } else if (rres.rect32) { ibufs_arr[view_id] = IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect); - memcpy(ibufs_arr[view_id]->rect, rres.rect32, 4 * rres.rectx * rres.recty); + memcpy(ibufs_arr[view_id]->byte_buffer.data, rres.rect32, 4 * rres.rectx * rres.recty); } if (view_id != context->view_id) { @@ -1730,7 +1745,7 @@ static ImBuf *do_render_strip_uncached(const SeqRenderData *context, IMB_freeImBuf(ibuf); ibuf = i; - if (ibuf->rect_float) { + if (ibuf->float_buffer.data) { seq_imbuf_to_sequencer_space(context->scene, ibuf, false); } } @@ -2093,7 +2108,8 @@ static ImBuf *seq_get_uncached_thumbnail(const SeqRenderData *context, } /* Scale ibuf to thumbnail size. */ - ImBuf *scaled_ibuf = IMB_allocImBuf(rectx, recty, 32, ibuf->rect_float ? IB_rectfloat : IB_rect); + ImBuf *scaled_ibuf = IMB_allocImBuf( + rectx, recty, 32, ibuf->float_buffer.data ? IB_rectfloat : IB_rect); sequencer_thumbnail_transform(ibuf, scaled_ibuf); seq_imbuf_assign_spaces(context->scene, scaled_ibuf); IMB_freeImBuf(ibuf); diff --git a/source/blender/sequencer/intern/strip_retiming.cc b/source/blender/sequencer/intern/strip_retiming.cc index 5006b029eb4..a2138152190 100644 --- a/source/blender/sequencer/intern/strip_retiming.cc +++ b/source/blender/sequencer/intern/strip_retiming.cc @@ -604,7 +604,7 @@ class RetimingRange { { for (int frame = start; frame <= end; frame++) { /* We need number actual number of frames here. */ - const double normal_step = 1 / (double)seq->len; + const double normal_step = 1 / double(seq->len); /* Who needs calculus, when you can have slow code? */ const double val_prev = seq_retiming_evaluate(seq, frame - 1); diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 0027dcf477d..edc08d9b364 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -181,9 +181,9 @@ wmWindow *WM_window_find_by_area(wmWindowManager *wm, const struct ScrArea *area * \warning Drawing (swap-buffers) immediately before calling this function causes * the front-buffer state to be invalid under some EGL configurations. */ -uint *WM_window_pixels_read_from_frontbuffer(const struct wmWindowManager *wm, - const struct wmWindow *win, - int r_size[2]); +uint8_t *WM_window_pixels_read_from_frontbuffer(const struct wmWindowManager *wm, + const struct wmWindow *win, + int r_size[2]); /** A version of #WM_window_pixels_read_from_frontbuffer that samples a pixel at `pos`. */ void WM_window_pixels_read_sample_from_frontbuffer(const wmWindowManager *wm, const struct wmWindow *win, @@ -197,9 +197,9 @@ void WM_window_pixels_read_sample_from_frontbuffer(const wmWindowManager *wm, * \note This is needed because the state of the front-buffer may be damaged * (see in-line code comments for details). */ -uint *WM_window_pixels_read_from_offscreen(struct bContext *C, - struct wmWindow *win, - int r_size[2]); +uint8_t *WM_window_pixels_read_from_offscreen(struct bContext *C, + struct wmWindow *win, + int r_size[2]); /** A version of #WM_window_pixels_read_from_offscreen that samples a pixel at `pos`. */ bool WM_window_pixels_read_sample_from_offscreen(struct bContext *C, struct wmWindow *win, @@ -211,7 +211,7 @@ bool WM_window_pixels_read_sample_from_offscreen(struct bContext *C, * * \note Use off-screen drawing when front-buffer reading is not supported. */ -uint *WM_window_pixels_read(struct bContext *C, struct wmWindow *win, int r_size[2]); +uint8_t *WM_window_pixels_read(struct bContext *C, struct wmWindow *win, int r_size[2]); /** * Read a single pixel from the screen. * @@ -489,6 +489,8 @@ wmKeyMapItem *WM_event_match_keymap_item_from_handlers(struct bContext *C, struct ListBase *handlers, const struct wmEvent *event); +bool WM_event_match(const struct wmEvent *winevent, const struct wmKeyMapItem *kmi); + typedef int (*wmUIHandlerFunc)(struct bContext *C, const struct wmEvent *event, void *userdata); typedef void (*wmUIHandlerRemoveFunc)(struct bContext *C, void *userdata); @@ -1624,14 +1626,15 @@ void WM_job_main_thread_lock_release(struct wmJob *job); /** * Return text from the clipboard. - * - * \note Caller needs to check for valid utf8 if this is a requirement. + * \param selection: Use the "primary" clipboard, see: #WM_CAPABILITY_PRIMARY_CLIPBOARD. + * \param ensure_utf8: Ensure the resulting string does not contain invalid UTF8 encoding. */ -char *WM_clipboard_text_get(bool selection, int *r_len); +char *WM_clipboard_text_get(bool selection, bool ensure_utf8, int *r_len); /** * Convenience function for pasting to areas of Blender which don't support newlines. */ -char *WM_clipboard_text_get_firstline(bool selection, int *r_len); +char *WM_clipboard_text_get_firstline(bool selection, bool ensure_utf8, int *r_len); + void WM_clipboard_text_set(const char *buf, bool selection); /** diff --git a/source/blender/windowmanager/intern/wm_dragdrop.cc b/source/blender/windowmanager/intern/wm_dragdrop.cc index 8b8e2993fe3..6ff19a17687 100644 --- a/source/blender/windowmanager/intern/wm_dragdrop.cc +++ b/source/blender/windowmanager/intern/wm_dragdrop.cc @@ -889,7 +889,7 @@ static void wm_drag_draw_icon(bContext * /*C*/, wmWindow * /*win*/, wmDrag *drag drag->imb->y, GPU_RGBA8, false, - drag->imb->rect, + drag->imb->byte_buffer.data, drag->imbuf_scale, drag->imbuf_scale, 1.0f, diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index ce20e8b6d8a..1d454fd980c 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -1219,9 +1219,9 @@ static void wm_draw_surface(bContext *C, wmSurface *surface) * Include here since it can involve low level buffer switching. * \{ */ -uint *WM_window_pixels_read_from_frontbuffer(const wmWindowManager *wm, - const wmWindow *win, - int r_size[2]) +uint8_t *WM_window_pixels_read_from_frontbuffer(const wmWindowManager *wm, + const wmWindow *win, + int r_size[2]) { /* Don't assert as file-save uses this for a screenshot, where redrawing isn't an option * because of the side-effects of drawing a window on save. @@ -1242,7 +1242,7 @@ uint *WM_window_pixels_read_from_frontbuffer(const wmWindowManager *wm, r_size[0] = WM_window_pixels_x(win); r_size[1] = WM_window_pixels_y(win); const uint rect_len = r_size[0] * r_size[1]; - uint *rect = MEM_mallocN(sizeof(*rect) * rect_len, __func__); + uint8_t *rect = MEM_mallocN(4 * sizeof(uint8_t) * rect_len, __func__); GPU_frontbuffer_read_color(0, 0, r_size[0], r_size[1], 4, GPU_DATA_UBYTE, rect); @@ -1259,7 +1259,7 @@ uint *WM_window_pixels_read_from_frontbuffer(const wmWindowManager *wm, for (i = 0, cp += 3; i < rect_len; i++, cp += 4) { *cp = 0xff; } - return (uint *)rect; + return rect; } void WM_window_pixels_read_sample_from_frontbuffer(const wmWindowManager *wm, @@ -1285,7 +1285,7 @@ void WM_window_pixels_read_sample_from_frontbuffer(const wmWindowManager *wm, } } -uint *WM_window_pixels_read_from_offscreen(bContext *C, wmWindow *win, int r_size[2]) +uint8_t *WM_window_pixels_read_from_offscreen(bContext *C, wmWindow *win, int r_size[2]) { /* NOTE(@ideasman42): There is a problem reading the windows front-buffer after redrawing * the window in some cases (typically to clear UI elements such as menus or search popup). @@ -1310,7 +1310,7 @@ uint *WM_window_pixels_read_from_offscreen(bContext *C, wmWindow *win, int r_siz } const uint rect_len = r_size[0] * r_size[1]; - uint *rect = MEM_mallocN(sizeof(*rect) * rect_len, __func__); + uint8_t *rect = MEM_mallocN(4 * sizeof(uint8_t) * rect_len, __func__); GPU_offscreen_bind(offscreen, false); wm_draw_window_onscreen(C, win, -1); GPU_offscreen_unbind(offscreen, false); @@ -1350,7 +1350,7 @@ bool WM_window_pixels_read_sample_from_offscreen(bContext *C, return true; } -uint *WM_window_pixels_read(bContext *C, wmWindow *win, int r_size[2]) +uint8_t *WM_window_pixels_read(bContext *C, wmWindow *win, int r_size[2]) { if (WM_capabilities_flag() & WM_CAPABILITY_GPU_FRONT_BUFFER_READ) { return WM_window_pixels_read_from_frontbuffer(CTX_wm_manager(C), win, r_size); diff --git a/source/blender/windowmanager/intern/wm_event_system.cc b/source/blender/windowmanager/intern/wm_event_system.cc index a1bfbe5cba2..22ff5e34dc6 100644 --- a/source/blender/windowmanager/intern/wm_event_system.cc +++ b/source/blender/windowmanager/intern/wm_event_system.cc @@ -2205,7 +2205,7 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers) } } -static bool wm_eventmatch(const wmEvent *winevent, const wmKeyMapItem *kmi) +BLI_INLINE bool wm_eventmatch(const wmEvent *winevent, const wmKeyMapItem *kmi) { if (kmi->flag & KMI_INACTIVE) { return false; @@ -6019,6 +6019,11 @@ wmKeyMapItem *WM_event_match_keymap_item_from_handlers( return nullptr; } +bool WM_event_match(const wmEvent *winevent, const wmKeyMapItem *kmi) +{ + return wm_eventmatch(winevent, kmi); +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/windowmanager/intern/wm_files.cc b/source/blender/windowmanager/intern/wm_files.cc index a6c644d155a..f0e343688aa 100644 --- a/source/blender/windowmanager/intern/wm_files.cc +++ b/source/blender/windowmanager/intern/wm_files.cc @@ -1669,7 +1669,7 @@ static ImBuf *blend_file_thumb_from_screenshot(bContext *C, BlendThumbnail **r_t int win_size[2]; /* NOTE: always read from front-buffer as drawing a window can cause problems while saving, * even if this means the thumbnail from the screen-shot fails to be created, see: #98462. */ - uint *buffer = WM_window_pixels_read_from_frontbuffer(wm, win, win_size); + uint8_t *buffer = WM_window_pixels_read_from_frontbuffer(wm, win, win_size); ImBuf *ibuf = IMB_allocFromBufferOwn(buffer, nullptr, win_size[0], win_size[1], 24); if (ibuf) { diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 093f7ca45ab..0fb8d2c5a86 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2311,12 +2311,12 @@ static void radial_control_set_tex(RadialControl *rc) GPU_R8, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW, - ibuf->rect_float); + ibuf->float_buffer.data); GPU_texture_filter_mode(rc->texture, true); GPU_texture_swizzle_set(rc->texture, "111r"); - MEM_freeN(ibuf->rect_float); + MEM_freeN(ibuf->float_buffer.data); MEM_freeN(ibuf); } break; diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index 0a3b291ffdb..73738f01751 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -411,8 +411,8 @@ static void *ocio_transform_ibuf(PlayState *ps, *r_glsl_used = false; display_buffer = NULL; } - else if (ibuf->rect_float) { - display_buffer = ibuf->rect_float; + else if (ibuf->float_buffer.data) { + display_buffer = ibuf->float_buffer.data; *r_data = GPU_DATA_FLOAT; if (ibuf->channels == 4) { @@ -436,8 +436,8 @@ static void *ocio_transform_ibuf(PlayState *ps, &ps->view_settings, &ps->display_settings, ibuf->dither, false); } } - else if (ibuf->rect) { - display_buffer = ibuf->rect; + else if (ibuf->byte_buffer.data) { + display_buffer = ibuf->byte_buffer.data; *r_glsl_used = IMB_colormanagement_setup_glsl_draw_from_space(&ps->view_settings, &ps->display_settings, ibuf->rect_colorspace, @@ -451,7 +451,7 @@ static void *ocio_transform_ibuf(PlayState *ps, /* There is data to be displayed, but GLSL is not initialized * properly, in this case we fallback to CPU-based display transform. */ - if ((ibuf->rect || ibuf->rect_float) && !*r_glsl_used) { + if ((ibuf->byte_buffer.data || ibuf->float_buffer.data) && !*r_glsl_used) { display_buffer = IMB_display_buffer_acquire( ibuf, &ps->view_settings, &ps->display_settings, r_buffer_cache_handle); *r_format = GPU_RGBA8; diff --git a/source/blender/windowmanager/intern/wm_splash_screen.c b/source/blender/windowmanager/intern/wm_splash_screen.c index 42164bf0029..5c8e10cd888 100644 --- a/source/blender/windowmanager/intern/wm_splash_screen.c +++ b/source/blender/windowmanager/intern/wm_splash_screen.c @@ -77,7 +77,7 @@ static void wm_block_splash_add_label(uiBlock *block, const char *label, int x, #ifndef WITH_HEADLESS static void wm_block_splash_image_roundcorners_add(ImBuf *ibuf) { - uchar *rct = (uchar *)ibuf->rect; + uchar *rct = ibuf->byte_buffer.data; if (!rct) { return; } diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 709c3f458bb..6eb362a97e2 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1983,7 +1983,10 @@ void WM_event_remove_timer_notifier(wmWindowManager *wm, wmWindow *win, wmTimer /** \name Clipboard * \{ */ -static char *wm_clipboard_text_get_ex(bool selection, int *r_len, bool firstline) +static char *wm_clipboard_text_get_ex(bool selection, + int *r_len, + const bool ensure_utf8, + const bool firstline) { if (G.background) { *r_len = 0; @@ -1996,8 +1999,18 @@ static char *wm_clipboard_text_get_ex(bool selection, int *r_len, bool firstline return NULL; } + int buf_len = strlen(buf); + + if (ensure_utf8) { + /* TODO(@ideasman42): It would be good if unexpected byte sequences could be interpreted + * instead of stripped - so mixed in characters (typically Latin1) aren't ignored. + * Check on how Python bytes this, see: #PyC_UnicodeFromBytesAndSize, + * there are clever ways to handle this although they increase the size of the buffer. */ + buf_len -= BLI_str_utf8_invalid_strip(buf, buf_len); + } + /* always convert from \r\n to \n */ - char *newbuf = MEM_mallocN(strlen(buf) + 1, __func__); + char *newbuf = MEM_mallocN(buf_len + 1, __func__); char *p2 = newbuf; if (firstline) { @@ -2028,14 +2041,14 @@ static char *wm_clipboard_text_get_ex(bool selection, int *r_len, bool firstline return newbuf; } -char *WM_clipboard_text_get(bool selection, int *r_len) +char *WM_clipboard_text_get(bool selection, bool ensure_utf8, int *r_len) { - return wm_clipboard_text_get_ex(selection, r_len, false); + return wm_clipboard_text_get_ex(selection, r_len, ensure_utf8, false); } -char *WM_clipboard_text_get_firstline(bool selection, int *r_len) +char *WM_clipboard_text_get_firstline(bool selection, bool ensure_utf8, int *r_len) { - return wm_clipboard_text_get_ex(selection, r_len, true); + return wm_clipboard_text_get_ex(selection, r_len, ensure_utf8, true); } void WM_clipboard_text_set(const char *buf, bool selection) @@ -2093,7 +2106,7 @@ ImBuf *WM_clipboard_image_get(void) int width, height; - uint *rgba = GHOST_getClipboardImage(&width, &height); + uint8_t *rgba = (uint8_t *)GHOST_getClipboardImage(&width, &height); if (!rgba) { return NULL; } @@ -2111,13 +2124,13 @@ bool WM_clipboard_image_set(ImBuf *ibuf) } bool free_byte_buffer = false; - if (ibuf->rect == NULL) { + if (ibuf->byte_buffer.data == NULL) { /* Add a byte buffer if it does not have one. */ IMB_rect_from_float(ibuf); free_byte_buffer = true; } - bool success = (bool)GHOST_putClipboardImage(ibuf->rect, ibuf->x, ibuf->y); + bool success = (bool)GHOST_putClipboardImage((uint *)ibuf->byte_buffer.data, ibuf->x, ibuf->y); if (free_byte_buffer) { /* Remove the byte buffer if we added it. */ diff --git a/tests/python/cycles_render_tests.py b/tests/python/cycles_render_tests.py index 36eceb0558d..1e6ca258b0d 100644 --- a/tests/python/cycles_render_tests.py +++ b/tests/python/cycles_render_tests.py @@ -140,8 +140,11 @@ def main(): report.set_compare_engine('cycles', 'CPU') # Increase threshold for motion blur, see #78777. + # + # underwater_caustics.blend gives quite different results on Linux and Intel macOS compared to + # Windows and Arm macOS. test_dir_name = Path(test_dir).name - if test_dir_name == 'motion_blur': + if test_dir_name in ('motion_blur', 'integrator', ): report.set_fail_threshold(0.032) ok = report.run(test_dir, blender, get_arguments, batch=True) diff --git a/tools/check_source/check_spelling_c_config.py b/tools/check_source/check_spelling_c_config.py index e779d6b3f72..33924399d3c 100644 --- a/tools/check_source/check_spelling_c_config.py +++ b/tools/check_source/check_spelling_c_config.py @@ -302,6 +302,7 @@ dict_custom = { "subdirectories", "subdirectory", "suboptimally", + "subrange", "subtractive", "superset", "symmetrize",