WIP: Brush assets project #106303

Draft
Julian Eisel wants to merge 358 commits from brush-assets-project into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
123 changed files with 1182 additions and 575 deletions
Showing only changes of commit 94b18b9e67 - Show all commits

View File

@ -236,6 +236,10 @@ ifndef PYTHON
ifeq (, $(shell command -v $(PYTHON)))
PYTHON:=python
endif
else
# Don't generate __pycache__ files in lib folder, they
# can interfere with updates.
PYTHON:=$(PYTHON) -B
endif
endif

View File

@ -26,8 +26,8 @@
#
##################################################################################################
project("BlenderDependencies")
cmake_minimum_required(VERSION 3.5)
project("BlenderDependencies")
if(POLICY CMP0135)
cmake_policy(SET CMP0135 NEW) # CMake 3.24+ Set the date/time for extracted files to time of extraction
endif()

View File

@ -14,6 +14,7 @@ if(NOT APPLE)
${OIDN_EXTRA_ARGS}
-DOIDN_DEVICE_SYCL=ON
-DOIDN_DEVICE_SYCL_AOT=OFF
-DOIDN_DEVICE_CUDA=ON
-DOIDN_DEVICE_HIP=ON
-DLEVEL_ZERO_ROOT=${LIBDIR}/level-zero
)

View File

@ -10,6 +10,8 @@
# include "device/cuda/device_impl.h"
# include "device/device.h"
# include "integrator/denoiser_oidn_gpu.h"
# include "util/string.h"
# include "util/windows.h"
#endif /* WITH_CUDA */
@ -162,6 +164,12 @@ void device_cuda_info(vector<DeviceInfo> &devices)
(unsigned int)pci_location[1],
(unsigned int)pci_location[2]);
# if defined(WITH_OPENIMAGEDENOISE)
if (OIDNDenoiserGPU::is_device_supported(info)) {
info.denoisers |= DENOISER_OPENIMAGEDENOISE;
}
# endif
/* If device has a kernel timeout and no compute preemption, we assume
* it is connected to a display and will freeze the display while doing
* computations. */

View File

@ -8,6 +8,8 @@
#include "device/cuda/device.h"
#include "device/optix/device_impl.h"
#include "integrator/denoiser_oidn_gpu.h"
#include "util/log.h"
#ifdef WITH_OSL
@ -74,6 +76,11 @@ void device_optix_info(const vector<DeviceInfo> &cuda_devices, vector<DeviceInfo
info.has_osl = true;
# endif
info.denoisers |= DENOISER_OPTIX;
# if defined(WITH_OPENIMAGEDENOISE)
if (OIDNDenoiserGPU::is_device_supported(info)) {
info.denoisers |= DENOISER_OPENIMAGEDENOISE;
}
# endif
devices.push_back(info);
}

View File

@ -111,6 +111,10 @@ uint OIDNDenoiserGPU::get_device_type_mask() const
# ifdef OIDN_DEVICE_SYCL
device_mask |= DEVICE_MASK_ONEAPI;
# endif
# ifdef OIDN_DEVICE_CUDA
device_mask |= DEVICE_MASK_CUDA;
device_mask |= DEVICE_MASK_OPTIX;
# endif
# ifdef OIDN_DEVICE_HIP
device_mask |= DEVICE_MASK_HIP;
# endif
@ -155,9 +159,17 @@ bool OIDNDenoiserGPU::denoise_create_if_needed(DenoiseContext &context)
oidn_device_ = oidnNewSYCLDevice(
(const sycl::queue *)reinterpret_cast<OneapiDevice *>(denoiser_device_)->sycl_queue(),
1);
denoiser_queue_->init_execution();
break;
# endif
# if defined(OIDN_DEVICE_CUDA) && defined(WITH_CUDA)
case DEVICE_CUDA:
case DEVICE_OPTIX: {
/* Directly using the stream from the DeviceQueue returns "invalid resource handle". */
cudaStream_t stream = nullptr;
oidn_device_ = oidnNewCUDADevice(&denoiser_device_->info.num, &stream, 1);
break;
}
# endif
# if defined(OIDN_DEVICE_HIP) && defined(WITH_HIP)
case DEVICE_HIP: {
hipStream_t stream = nullptr;

View File

@ -627,7 +627,7 @@ if(WITH_CYCLES_HIP_BINARIES AND WITH_CYCLES_DEVICE_HIP)
set(hip_flags
${hip_flags}
--amdgpu-target=${arch}
--offload-arch=${arch}
${HIP_HIPCC_FLAGS}
--genco
${CMAKE_CURRENT_SOURCE_DIR}${hip_kernel_src}
@ -639,7 +639,6 @@ if(WITH_CYCLES_HIP_BINARIES AND WITH_CYCLES_DEVICE_HIP)
-I ${CMAKE_CURRENT_SOURCE_DIR}/device/hip
-Wno-parentheses-equality
-Wno-unused-value
--hipcc-func-supp
-ffast-math
${hip_opt_flags}
-o ${CMAKE_CURRENT_BINARY_DIR}/${hip_file})
@ -715,7 +714,6 @@ if(WITH_CYCLES_DEVICE_HIPRT AND WITH_CYCLES_HIP_BINARIES)
-I ${HIPRT_INCLUDE_DIR}
-Wno-parentheses-equality
-Wno-unused-value
--hipcc-func-supp
-ffast-math
-o ${bitcode_file})
if(WITH_CYCLES_DEBUG)

View File

@ -4317,10 +4317,8 @@ static void tablet_tool_handle_tilt(void *data,
CLOG_INFO(LOG, 2, "tilt (x=%.4f, y=%.4f)", UNPACK2(tilt_unit));
GWL_TabletTool *tablet_tool = static_cast<GWL_TabletTool *>(data);
GHOST_TabletData &td = tablet_tool->data;
td.Xtilt = tilt_unit[0];
td.Ytilt = tilt_unit[1];
CLAMP(td.Xtilt, -1.0f, 1.0f);
CLAMP(td.Ytilt, -1.0f, 1.0f);
td.Xtilt = std::clamp(tilt_unit[0], -1.0f, 1.0f);
td.Ytilt = std::clamp(tilt_unit[1], -1.0f, 1.0f);
gwl_tablet_tool_frame_event_add(tablet_tool, GWL_TabletTool_EventTypes::Tilt);
}

View File

@ -104,113 +104,6 @@
/** \} */
/* -------------------------------------------------------------------- */
/** \name Clamp Macros
* \{ */
#define CLAMPIS(a, b, c) ((a) < (b) ? (b) : (a) > (c) ? (c) : (a))
#define CLAMP(a, b, c) \
{ \
if ((a) < (b)) { \
(a) = (b); \
} \
else if ((a) > (c)) { \
(a) = (c); \
} \
} \
(void)0
#define CLAMP_MAX(a, c) \
{ \
if ((a) > (c)) { \
(a) = (c); \
} \
} \
(void)0
#define CLAMP_MIN(a, b) \
{ \
if ((a) < (b)) { \
(a) = (b); \
} \
} \
(void)0
#define CLAMP2(vec, b, c) \
{ \
CLAMP((vec)[0], b, c); \
CLAMP((vec)[1], b, c); \
} \
(void)0
#define CLAMP2_MIN(vec, b) \
{ \
CLAMP_MIN((vec)[0], b); \
CLAMP_MIN((vec)[1], b); \
} \
(void)0
#define CLAMP2_MAX(vec, b) \
{ \
CLAMP_MAX((vec)[0], b); \
CLAMP_MAX((vec)[1], b); \
} \
(void)0
#define CLAMP3(vec, b, c) \
{ \
CLAMP((vec)[0], b, c); \
CLAMP((vec)[1], b, c); \
CLAMP((vec)[2], b, c); \
} \
(void)0
#define CLAMP3_MIN(vec, b) \
{ \
CLAMP_MIN((vec)[0], b); \
CLAMP_MIN((vec)[1], b); \
CLAMP_MIN((vec)[2], b); \
} \
(void)0
#define CLAMP3_MAX(vec, b) \
{ \
CLAMP_MAX((vec)[0], b); \
CLAMP_MAX((vec)[1], b); \
CLAMP_MAX((vec)[2], b); \
} \
(void)0
#define CLAMP4(vec, b, c) \
{ \
CLAMP((vec)[0], b, c); \
CLAMP((vec)[1], b, c); \
CLAMP((vec)[2], b, c); \
CLAMP((vec)[3], b, c); \
} \
(void)0
#define CLAMP4_MIN(vec, b) \
{ \
CLAMP_MIN((vec)[0], b); \
CLAMP_MIN((vec)[1], b); \
CLAMP_MIN((vec)[2], b); \
CLAMP_MIN((vec)[3], b); \
} \
(void)0
#define CLAMP4_MAX(vec, b) \
{ \
CLAMP_MAX((vec)[0], b); \
CLAMP_MAX((vec)[1], b); \
CLAMP_MAX((vec)[2], b); \
CLAMP_MAX((vec)[3], b); \
} \
(void)0
/** \} */
/* -------------------------------------------------------------------- */
/** \name String Macros
* \{ */

View File

@ -32,6 +32,8 @@ def _initialize_once():
for addon in _preferences.addons:
enable(addon.module)
_initialize_ensure_extensions_addon()
def paths():
return [
@ -66,7 +68,7 @@ def _paths_with_extension_repos():
for repo in _preferences.filepaths.extension_repos:
if not repo.enabled:
continue
dirpath = repo.directory
dirpath = repo.directory_or_default
if not os.path.isdir(dirpath):
continue
addon_paths.append((dirpath, "%s.%s" % (_ext_base_pkg_idname, repo.module)))
@ -606,6 +608,13 @@ def module_bl_info(mod, *, info_basis=None):
# -----------------------------------------------------------------------------
# Extensions
def _initialize_ensure_extensions_addon():
if _preferences.experimental.use_extension_repos:
module_name = "bl_pkg"
if module_name not in _preferences.addons:
enable(module_name, default_set=True, persistent=True)
# Module-like class, store singletons.
class _ext_global:
__slots__ = ()
@ -643,7 +652,7 @@ def _extension_dirpath_from_preferences():
for repo in _preferences.filepaths.extension_repos:
if not repo.enabled:
continue
repos_dict[repo.module] = repo.directory
repos_dict[repo.module] = repo.directory_or_default
return repos_dict
@ -805,6 +814,10 @@ def _initialize_extension_repos_pre(*_):
@_bpy.app.handlers.persistent
def _initialize_extension_repos_post(*_, is_first=False):
# When enabling extensions for the first time, ensure the add-on is enabled.
_initialize_ensure_extensions_addon()
do_addons = not is_first
# Map `module_id` -> `dirpath`.

View File

@ -1307,6 +1307,19 @@ class RenderEngine(StructRNA, metaclass=RNAMeta):
__slots__ = ()
class UserExtensionRepo(StructRNA):
__slots__ = ()
@property
def directory_or_default(self):
"""Return ``directory`` or a default path derived from the users scripts path."""
if directory := self.directory:
return directory
import os
import bpy
return os.path.join(bpy.utils.user_resource('SCRIPTS', path="extensions"), self.module)
class HydraRenderEngine(RenderEngine):
__slots__ = ()

View File

@ -75,7 +75,7 @@ class OBJECT_MT_modifier_add(ModifierAddMenu, Menu):
layout.menu("OBJECT_MT_modifier_add_edit")
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'VOLUME', 'GREASEPENCIL'}:
layout.menu("OBJECT_MT_modifier_add_generate")
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE', 'VOLUME'}:
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE', 'VOLUME', 'GREASEPENCIL'}:
layout.menu("OBJECT_MT_modifier_add_deform")
if ob_type in {'MESH', 'CURVE', 'FONT', 'SURFACE', 'LATTICE'}:
layout.menu("OBJECT_MT_modifier_add_physics")
@ -187,6 +187,8 @@ class OBJECT_MT_modifier_add_deform(ModifierAddMenu, Menu):
self.operator_modifier_add(layout, 'WAVE')
if ob_type == 'VOLUME':
self.operator_modifier_add(layout, 'VOLUME_DISPLACE')
if ob_type == 'GREASEPENCIL':
self.operator_modifier_add(layout, 'GREASEPENCIL_SMOOTH')
layout.template_modifier_asset_menu_items(catalog_path=self.bl_label)

View File

@ -943,7 +943,6 @@ def brush_settings_advanced(layout, context, brush, popover=False):
use_frontface = False
if mode == 'SCULPT':
sculpt = context.tool_settings.sculpt
capabilities = brush.sculpt_capabilities
use_accumulate = capabilities.has_accumulate
use_frontface = True
@ -1000,16 +999,16 @@ def brush_settings_advanced(layout, context, brush, popover=False):
col.prop(brush, "use_automasking_view_occlusion", text="Occlusion")
subcol = col.column(align=True)
subcol.active = not brush.use_automasking_view_occlusion
subcol.prop(sculpt, "automasking_view_normal_limit", text="Limit")
subcol.prop(sculpt, "automasking_view_normal_falloff", text="Falloff")
subcol.prop(brush, "automasking_view_normal_limit", text="Limit")
subcol.prop(brush, "automasking_view_normal_falloff", text="Falloff")
col = layout.column()
col.prop(brush, "use_automasking_start_normal", text="Area Normal")
if brush.use_automasking_start_normal:
col = layout.column(align=True)
col.prop(sculpt, "automasking_start_normal_limit", text="Limit")
col.prop(sculpt, "automasking_start_normal_falloff", text="Falloff")
col.prop(brush, "automasking_start_normal_limit", text="Limit")
col.prop(brush, "automasking_start_normal_falloff", text="Falloff")
layout.separator()

View File

@ -2021,10 +2021,9 @@ class USERPREF_PT_extensions(ExtensionsPanel, Panel):
layout = self.layout
row = layout.row()
row.label(text="The add-on to use extensions is disabled! See:")
row.operator(
"wm.url_open", text="Extension Add-on Repository", icon='URL',
).url = "https://projects.blender.org/ideasman42/bl_ext"
row.label(text="The add-on to use extensions is disabled!")
row = layout.row()
row.label(text="Enable \"Blender Extensions\" add-on in Testing to use extensions.")
class USERPREF_PT_extensions_repos(ExtensionsPanel, Panel):

View File

@ -17,11 +17,9 @@ namespace blender::asset_system {
StringRefNull essentials_directory_path()
{
static std::string path = []() {
const char *datafiles_path = BKE_appdir_folder_id(BLENDER_DATAFILES, "assets");
if (datafiles_path == nullptr) {
return "";
}
return datafiles_path;
const std::optional<std::string> datafiles_path = BKE_appdir_folder_id(BLENDER_DATAFILES,
"assets");
return datafiles_path.value_or("");
}();
return path;
}

View File

@ -23,8 +23,9 @@
static int blf_load_font_default(const char *filename, const bool unique)
{
const char *dir = BKE_appdir_folder_id(BLENDER_DATAFILES, BLF_DATAFILES_FONTS_DIR);
if (dir == nullptr) {
const std::optional<std::string> dir = BKE_appdir_folder_id(BLENDER_DATAFILES,
BLF_DATAFILES_FONTS_DIR);
if (!dir.has_value()) {
fprintf(stderr,
"%s: 'fonts' data path not found for '%s', will not be able to display text\n",
__func__,
@ -33,7 +34,7 @@ static int blf_load_font_default(const char *filename, const bool unique)
}
char filepath[FILE_MAX];
BLI_path_join(filepath, sizeof(filepath), dir, filename);
BLI_path_join(filepath, sizeof(filepath), dir->c_str(), filename);
return (unique) ? BLF_load_unique(filepath) : BLF_load(filepath);
}
@ -55,18 +56,15 @@ int BLF_load_mono_default(const bool unique)
static void blf_load_datafiles_dir()
{
const char *datafiles_fonts_dir = BLF_DATAFILES_FONTS_DIR SEP_STR;
const char *path = BKE_appdir_folder_id(BLENDER_DATAFILES, datafiles_fonts_dir);
if (UNLIKELY(!path)) {
const std::optional<std::string> path = BKE_appdir_folder_id(BLENDER_DATAFILES,
datafiles_fonts_dir);
if (!path.has_value()) {
fprintf(stderr, "Font data directory \"%s\" could not be detected!\n", datafiles_fonts_dir);
return;
}
if (UNLIKELY(!BLI_exists(path))) {
fprintf(stderr, "Font data directory \"%s\" does not exist!\n", path);
return;
}
direntry *file_list;
uint file_list_num = BLI_filelist_dir_contents(path, &file_list);
uint file_list_num = BLI_filelist_dir_contents(path->c_str(), &file_list);
for (int i = 0; i < file_list_num; i++) {
if (S_ISDIR(file_list[i].s.st_mode)) {
continue;

View File

@ -12,6 +12,9 @@
#include <stddef.h>
#include <optional>
#include <string>
#include "BLI_compiler_attrs.h"
struct ListBase;
@ -76,25 +79,26 @@ bool BKE_appdir_folder_id_ex(int folder_id,
const char *subfolder,
char *path,
size_t path_maxncpy);
const char *BKE_appdir_folder_id(int folder_id, const char *subfolder) ATTR_WARN_UNUSED_RESULT;
std::optional<std::string> BKE_appdir_folder_id(int folder_id,
const char *subfolder) ATTR_WARN_UNUSED_RESULT;
/**
* Returns the path to a folder in the user area, creating it if it doesn't exist.
*/
const char *BKE_appdir_folder_id_create(int folder_id,
const char *subfolder) ATTR_WARN_UNUSED_RESULT;
std::optional<std::string> BKE_appdir_folder_id_create(int folder_id, const char *subfolder)
ATTR_WARN_UNUSED_RESULT;
/**
* Returns the path to a folder in the user area without checking that it actually exists first.
*/
const char *BKE_appdir_folder_id_user_notest(int folder_id,
const char *subfolder) ATTR_WARN_UNUSED_RESULT;
std::optional<std::string> BKE_appdir_folder_id_user_notest(int folder_id, const char *subfolder)
ATTR_WARN_UNUSED_RESULT;
/**
* Returns the path of the top-level version-specific local, user or system directory.
* If check_is_dir, then the result will be NULL if the directory doesn't exist.
*/
const char *BKE_appdir_resource_path_id_with_version(int folder_id,
bool check_is_dir,
int version);
const char *BKE_appdir_resource_path_id(int folder_id, bool check_is_dir);
std::optional<std::string> BKE_appdir_resource_path_id_with_version(int folder_id,
bool check_is_dir,
int version);
std::optional<std::string> BKE_appdir_resource_path_id(int folder_id, bool check_is_dir);
/**
* Check if this is an install with user files kept together

View File

@ -29,7 +29,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 13
#define BLENDER_FILE_SUBVERSION 14
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and cancel loading the file, showing a warning to

View File

@ -335,7 +335,7 @@ void BKE_mask_clipboard_paste_to_layer(struct Main *bmain, struct MaskLayer *mas
/* `mask_evaluate.cc` */
unsigned int BKE_mask_spline_resolution(struct MaskSpline *spline, int width, int height);
int BKE_mask_spline_resolution(struct MaskSpline *spline, int width, int height);
unsigned int BKE_mask_spline_feather_resolution(struct MaskSpline *spline, int width, int height);
int BKE_mask_spline_differentiate_calc_total(const struct MaskSpline *spline, unsigned int resol);

View File

@ -685,19 +685,20 @@ bool BKE_appdir_folder_id_ex(const int folder_id,
return true;
}
const char *BKE_appdir_folder_id(const int folder_id, const char *subfolder)
std::optional<std::string> BKE_appdir_folder_id(const int folder_id, const char *subfolder)
{
static char path[FILE_MAX] = "";
char path[FILE_MAX] = "";
if (BKE_appdir_folder_id_ex(folder_id, subfolder, path, sizeof(path))) {
return path;
}
return nullptr;
return std::nullopt;
}
const char *BKE_appdir_folder_id_user_notest(const int folder_id, const char *subfolder)
std::optional<std::string> BKE_appdir_folder_id_user_notest(const int folder_id,
const char *subfolder)
{
const int version = BLENDER_VERSION;
static char path[FILE_MAX] = "";
char path[FILE_MAX] = "";
const bool check_is_dir = false;
switch (folder_id) {
@ -739,15 +740,13 @@ const char *BKE_appdir_folder_id_user_notest(const int folder_id, const char *su
}
if ('\0' == path[0]) {
return nullptr;
return std::nullopt;
}
return path;
}
const char *BKE_appdir_folder_id_create(const int folder_id, const char *subfolder)
std::optional<std::string> BKE_appdir_folder_id_create(const int folder_id, const char *subfolder)
{
const char *path;
/* Only for user folders. */
if (!ELEM(folder_id,
BLENDER_USER_DATAFILES,
@ -756,26 +755,26 @@ const char *BKE_appdir_folder_id_create(const int folder_id, const char *subfold
BLENDER_USER_AUTOSAVE))
{
BLI_assert_unreachable();
return nullptr;
return std::nullopt;
}
path = BKE_appdir_folder_id(folder_id, subfolder);
std::optional<std::string> path = BKE_appdir_folder_id(folder_id, subfolder);
if (!path) {
if (!path.has_value()) {
path = BKE_appdir_folder_id_user_notest(folder_id, subfolder);
if (path) {
BLI_dir_create_recursive(path);
if (path.has_value()) {
BLI_dir_create_recursive(path->c_str());
}
}
return path;
}
const char *BKE_appdir_resource_path_id_with_version(const int folder_id,
const bool check_is_dir,
const int version)
std::optional<std::string> BKE_appdir_resource_path_id_with_version(const int folder_id,
const bool check_is_dir,
const int version)
{
static char path[FILE_MAX] = "";
char path[FILE_MAX] = "";
bool ok;
switch (folder_id) {
case BLENDER_RESOURCE_PATH_USER:
@ -793,10 +792,14 @@ const char *BKE_appdir_resource_path_id_with_version(const int folder_id,
BLI_assert_msg(0, "incorrect ID");
break;
}
return ok ? path : nullptr;
if (!ok) {
return std::nullopt;
}
return path;
}
const char *BKE_appdir_resource_path_id(const int folder_id, const bool check_is_dir)
std::optional<std::string> BKE_appdir_resource_path_id(const int folder_id,
const bool check_is_dir)
{
return BKE_appdir_resource_path_id_with_version(folder_id, check_is_dir, BLENDER_VERSION);
}
@ -964,11 +967,13 @@ bool BKE_appdir_program_python_search(char *program_filepath,
SNPRINTF(python_version, "%s%d.%d", basename, version_major, version_minor);
{
const char *python_bin_dir = BKE_appdir_folder_id(BLENDER_SYSTEM_PYTHON, "bin");
if (python_bin_dir) {
const std::optional<std::string> python_bin_dir = BKE_appdir_folder_id(BLENDER_SYSTEM_PYTHON,
"bin");
if (python_bin_dir.has_value()) {
for (int i = 0; i < ARRAY_SIZE(python_names); i++) {
BLI_path_join(program_filepath, program_filepath_maxncpy, python_bin_dir, python_names[i]);
BLI_path_join(
program_filepath, program_filepath_maxncpy, python_bin_dir->c_str(), python_names[i]);
if (
#ifdef _WIN32

View File

@ -6,6 +6,8 @@
* \ingroup bke
*/
#include <algorithm>
#include "MEM_guardedalloc.h"
#include "BLI_listbase.h"
@ -665,7 +667,7 @@ static void splineik_evaluate_bone(
}
if (bulge < 1.0f) {
if (ik_data->flag & CONSTRAINT_SPLINEIK_USE_BULGE_MIN) {
float bulge_min = CLAMPIS(ik_data->bulge_min, 0.0f, 1.0f);
float bulge_min = std::clamp(ik_data->bulge_min, 0.0f, 1.0f);
float hard = max_ff(bulge, bulge_min);
float range = 1.0f - bulge_min;

View File

@ -1089,7 +1089,8 @@ static void setup_app_data(bContext *C,
bmain->filepath[0] = '\0';
}
else if (recover) {
/* In case of auto-save or quit.blend, use original filepath instead. */
/* In case of auto-save or quit.blend, use original filepath instead (see also #read_global in
* `readfile.cc`). */
bmain->recovered = true;
STRNCPY(bmain->filepath, bfd->filepath);
}
@ -1460,13 +1461,13 @@ bool BKE_blendfile_userdef_write_app_template(const char *filepath, ReportList *
bool BKE_blendfile_userdef_write_all(ReportList *reports)
{
char filepath[FILE_MAX];
const char *cfgdir;
std::optional<std::string> cfgdir;
bool ok = true;
const bool use_template_userpref = BKE_appdir_app_template_has_userpref(U.app_template);
if ((cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, nullptr))) {
bool ok_write;
BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_USERPREF_FILE);
BLI_path_join(filepath, sizeof(filepath), cfgdir->c_str(), BLENDER_USERPREF_FILE);
printf("Writing userprefs: \"%s\" ", filepath);
if (use_template_userpref) {
@ -1493,7 +1494,7 @@ bool BKE_blendfile_userdef_write_all(ReportList *reports)
if (use_template_userpref) {
if ((cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, U.app_template))) {
/* Also save app-template preferences. */
BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_USERPREF_FILE);
BLI_path_join(filepath, sizeof(filepath), cfgdir->c_str(), BLENDER_USERPREF_FILE);
printf("Writing userprefs app-template: \"%s\" ", filepath);
if (BKE_blendfile_userdef_write(filepath, reports) != 0) {

View File

@ -9,6 +9,7 @@
/* Allow using deprecated functionality for .blend file I/O. */
#define DNA_DEPRECATED_ALLOW
#include <algorithm>
#include <cfloat>
#include <cmath>
#include <cstddef>
@ -3552,7 +3553,7 @@ static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
}
if (bulge < 1.0f) {
if (data->flag & STRETCHTOCON_USE_BULGE_MIN) {
float bulge_min = CLAMPIS(data->bulge_min, 0.0f, 1.0f);
float bulge_min = std::clamp(data->bulge_min, 0.0f, 1.0f);
float hard = max_ff(bulge, bulge_min);
float range = 1.0f - bulge_min;

View File

@ -1060,7 +1060,9 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
dst_data = static_cast<float3 *>(CustomData_add_layer(
&me_dst->corner_data, CD_NORMAL, CD_SET_DEFAULT, me_dst->corners_num));
}
MutableSpan(dst_data, me_dst->corners_num).copy_from(me_dst->corner_normals());
if (mix_factor != 1.0f) {
MutableSpan(dst_data, me_dst->corners_num).copy_from(me_dst->corner_normals());
}
/* Post-process will convert it back to CD_CUSTOMLOOPNORMAL. */
data_transfer_layersmapping_add_item_cd(r_map,
CD_NORMAL,

View File

@ -524,7 +524,7 @@ static float eff_calc_visibility(ListBase *colliders,
absorption = col->ob->pd->absorption;
/* visibility is only between 0 and 1, calculated from 1-absorption */
visibility *= CLAMPIS(1.0f - absorption, 0.0f, 1.0f);
visibility *= std::clamp(1.0f - absorption, 0.0f, 1.0f);
if (visibility <= 0.0f) {
break;

View File

@ -561,7 +561,7 @@ static bool BKE_gpencil_stroke_extra_points(bGPDstroke *gps,
MDeformVert *new_dv = (MDeformVert *)MEM_mallocN(sizeof(MDeformVert) * new_count, __func__);
for (int i = 0; i < new_count; i++) {
MDeformVert *dv = &gps->dvert[CLAMPIS(i - count_before, 0, gps->totpoints - 1)];
MDeformVert *dv = &gps->dvert[std::clamp(i - count_before, 0, gps->totpoints - 1)];
int inew = i;
new_dv[inew].flag = dv->flag;
new_dv[inew].totweight = dv->totweight;

View File

@ -8,6 +8,7 @@
* Deform coordinates by a lattice object (used by modifier).
*/
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
@ -210,13 +211,13 @@ void BKE_lattice_deform_data_eval_co(LatticeDeformData *lattice_deform_data,
for (ww = wi - 1; ww <= wi + 2; ww++) {
w = weight * tw[ww - wi + 1];
idx_w = CLAMPIS(ww * w_stride, 0, idx_w_max);
idx_w = std::clamp(ww * w_stride, 0, idx_w_max);
for (vv = vi - 1; vv <= vi + 2; vv++) {
v = w * tv[vv - vi + 1];
idx_v = CLAMPIS(vv * v_stride, 0, idx_v_max);
idx_v = std::clamp(vv * v_stride, 0, idx_v_max);
for (uu = ui - 1; uu <= ui + 2; uu++) {
u = v * tu[uu - ui + 1];
idx_u = CLAMPIS(uu, 0, idx_u_max);
idx_u = std::clamp(uu, 0, idx_u_max);
const int idx = idx_w + idx_v + idx_u;
#if BLI_HAVE_SSE2
{

View File

@ -29,10 +29,10 @@
#include "DEG_depsgraph.hh"
#include "DEG_depsgraph_query.hh"
uint BKE_mask_spline_resolution(MaskSpline *spline, int width, int height)
int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height)
{
float max_segment = 0.01f;
uint i, resol = 1;
int i, resol = 1;
if (width != 0 && height != 0) {
max_segment = 1.0f / float(max_ii(width, height));
@ -42,7 +42,7 @@ uint BKE_mask_spline_resolution(MaskSpline *spline, int width, int height)
MaskSplinePoint *point = &spline->points[i];
BezTriple *bezt_curr, *bezt_next;
float a, b, c, len;
uint cur_resol;
int cur_resol;
bezt_curr = &point->bezt;
bezt_next = BKE_mask_spline_point_next_bezt(spline, spline->points, point);
@ -65,13 +65,13 @@ uint BKE_mask_spline_resolution(MaskSpline *spline, int width, int height)
}
}
return CLAMPIS(resol, 1, MASK_RESOL_MAX);
return std::clamp(resol, 1, MASK_RESOL_MAX);
}
uint BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int height)
{
const float max_segment = 0.005;
uint resol = BKE_mask_spline_resolution(spline, width, height);
int resol = BKE_mask_spline_resolution(spline, width, height);
float max_jump = 0.0f;
/* Avoid checking the feather if we already hit the maximum value. */
@ -104,7 +104,7 @@ uint BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int heigh
resol += max_jump / max_segment;
return CLAMPIS(resol, 1, MASK_RESOL_MAX);
return std::clamp(resol, 1, MASK_RESOL_MAX);
}
int BKE_mask_spline_differentiate_calc_total(const MaskSpline *spline, const uint resol)
@ -183,7 +183,7 @@ float (*BKE_mask_spline_differentiate_with_resolution(MaskSpline *spline,
float (*BKE_mask_spline_differentiate(
MaskSpline *spline, int width, int height, uint *r_tot_diff_point))[2]
{
uint resol = BKE_mask_spline_resolution(spline, width, height);
int resol = BKE_mask_spline_resolution(spline, width, height);
return BKE_mask_spline_differentiate_with_resolution(spline, resol, r_tot_diff_point);
}

View File

@ -630,9 +630,9 @@ void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle,
float(*diff_feather_points_flip)[2];
uint tot_diff_feather_points;
const uint resol_a = BKE_mask_spline_resolution(spline, width, height) / 4;
const uint resol_a = uint(BKE_mask_spline_resolution(spline, width, height) / 4);
const uint resol_b = BKE_mask_spline_feather_resolution(spline, width, height) / 4;
const uint resol = CLAMPIS(std::max(resol_a, resol_b), 4, 512);
const uint resol = std::clamp(std::max(resol_a, resol_b), 4u, 512u);
diff_points = BKE_mask_spline_differentiate_with_resolution(spline, resol, &tot_diff_point);

View File

@ -297,6 +297,7 @@ void BKE_mesh_runtime_clear_geometry(Mesh *mesh)
mesh->runtime->corner_to_face_map_cache.tag_dirty();
mesh->runtime->vert_normals_cache.tag_dirty();
mesh->runtime->face_normals_cache.tag_dirty();
mesh->runtime->corner_normals_cache.tag_dirty();
mesh->runtime->loose_edges_cache.tag_dirty();
mesh->runtime->loose_verts_cache.tag_dirty();
mesh->runtime->verts_no_face_cache.tag_dirty();

View File

@ -358,11 +358,11 @@ void multires_set_tot_level(Object *ob, MultiresModifierData *mmd, int lvl)
mmd->totlvl = lvl;
if (ob->mode != OB_MODE_SCULPT) {
mmd->lvl = CLAMPIS(std::max<char>(mmd->lvl, lvl), 0, mmd->totlvl);
mmd->lvl = std::clamp<char>(std::max<char>(mmd->lvl, lvl), 0, mmd->totlvl);
}
mmd->sculptlvl = CLAMPIS(std::max<char>(mmd->sculptlvl, lvl), 0, mmd->totlvl);
mmd->renderlvl = CLAMPIS(std::max<char>(mmd->renderlvl, lvl), 0, mmd->totlvl);
mmd->sculptlvl = std::clamp<char>(std::max<char>(mmd->sculptlvl, lvl), 0, mmd->totlvl);
mmd->renderlvl = std::clamp<char>(std::max<char>(mmd->renderlvl, lvl), 0, mmd->totlvl);
}
static void multires_ccg_mark_as_modified(SubdivCCG *subdiv_ccg, MultiresModifiedFlags flags)
@ -934,7 +934,7 @@ static void multires_disp_run_cb(void *__restrict userdata,
case CALC_DISPLACEMENTS:
/* Copy mask from DM to gpm */
mask = *CCG_grid_elem_mask(key, grid, x, y);
gpm->data[y * gridSize + x] = CLAMPIS(mask, 0, 1);
gpm->data[y * gridSize + x] = std::clamp(mask, 0.0f, 1.0f);
break;
case ADD_DISPLACEMENTS:
/* Add mask displacement to gpm */

View File

@ -7,10 +7,9 @@
* \ingroup bke
*/
#include <cstddef>
#include <algorithm>
#include <cmath>
#include <cstddef>
#include <cstdlib>
#include <cstring>
@ -3398,7 +3397,7 @@ static void hair_create_input_mesh(ParticleSimulationData *sim,
mul_m4_m4m4(root_mat, sim->ob->object_to_world, hairmat);
normalize_m4(root_mat);
bending_stiffness = CLAMPIS(
bending_stiffness = std::clamp(
1.0f - part->bending_random * psys_frand(psys, p + 666), 0.0f, 1.0f);
for (k = 0, key = pa->hair; k < pa->totkey; k++, key++) {

View File

@ -609,13 +609,13 @@ static void studiolight_add_files_from_datafolder(const int folder_id,
const char *subfolder,
int flag)
{
const char *folder = BKE_appdir_folder_id(folder_id, subfolder);
const std::optional<std::string> folder = BKE_appdir_folder_id(folder_id, subfolder);
if (!folder) {
return;
}
direntry *dirs;
const uint dirs_num = BLI_filelist_dir_contents(folder, &dirs);
const uint dirs_num = BLI_filelist_dir_contents(folder->c_str(), &dirs);
int i;
for (i = 0; i < dirs_num; i++) {
if (dirs[i].type & S_IFREG) {

View File

@ -219,8 +219,6 @@ inline constexpr int64_t power_of_2_max(const int64_t x)
/** \name Clamp Macros
* \{ */
#define CLAMPIS(a, b, c) ((a) < (b) ? (b) : (a) > (c) ? (c) : (a))
#define CLAMP(a, b, c) \
{ \
if ((a) < (b)) { \
@ -248,27 +246,6 @@ inline constexpr int64_t power_of_2_max(const int64_t x)
} \
(void)0
#define CLAMP2(vec, b, c) \
{ \
CLAMP((vec)[0], b, c); \
CLAMP((vec)[1], b, c); \
} \
(void)0
#define CLAMP2_MIN(vec, b) \
{ \
CLAMP_MIN((vec)[0], b); \
CLAMP_MIN((vec)[1], b); \
} \
(void)0
#define CLAMP2_MAX(vec, b) \
{ \
CLAMP_MAX((vec)[0], b); \
CLAMP_MAX((vec)[1], b); \
} \
(void)0
#define CLAMP3(vec, b, c) \
{ \
CLAMP((vec)[0], b, c); \
@ -285,23 +262,6 @@ inline constexpr int64_t power_of_2_max(const int64_t x)
} \
(void)0
#define CLAMP3_MAX(vec, b) \
{ \
CLAMP_MAX((vec)[0], b); \
CLAMP_MAX((vec)[1], b); \
CLAMP_MAX((vec)[2], b); \
} \
(void)0
#define CLAMP4(vec, b, c) \
{ \
CLAMP((vec)[0], b, c); \
CLAMP((vec)[1], b, c); \
CLAMP((vec)[2], b, c); \
CLAMP((vec)[3], b, c); \
} \
(void)0
#define CLAMP4_MIN(vec, b) \
{ \
CLAMP_MIN((vec)[0], b); \
@ -311,15 +271,6 @@ inline constexpr int64_t power_of_2_max(const int64_t x)
} \
(void)0
#define CLAMP4_MAX(vec, b) \
{ \
CLAMP_MAX((vec)[0], b); \
CLAMP_MAX((vec)[1], b); \
CLAMP_MAX((vec)[2], b); \
CLAMP_MAX((vec)[3], b); \
} \
(void)0
/** \} */
/* -------------------------------------------------------------------- */

View File

@ -665,7 +665,7 @@ float perlin_ridged_multi_fractal(T p,
for (int i = 1; i <= int(detail); i++) {
p *= lacunarity;
weight = CLAMPIS(signal * gain, 0.0f, 1.0f);
weight = std::clamp(signal * gain, 0.0f, 1.0f);
signal = offset - std::abs(perlin_signed(p));
signal *= signal;
signal *= weight;

View File

@ -10,6 +10,7 @@
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <random>
#include "MEM_guardedalloc.h"
@ -366,8 +367,11 @@ namespace blender {
RandomNumberGenerator RandomNumberGenerator::from_random_seed()
{
const double time = BLI_check_seconds_timer() * 1000000.0;
return RandomNumberGenerator(*reinterpret_cast<const uint32_t *>(&time));
std::random_device rd;
std::mt19937 e{rd()};
std::uniform_int_distribution<uint32_t> dist;
const uint32_t seed = dist(e);
return RandomNumberGenerator(seed);
}
void RandomNumberGenerator::seed_random(uint32_t seed)

View File

@ -57,6 +57,11 @@ typedef struct BlendFileData {
int fileflags;
int globalf;
/** Typically the actual filepath of the read blendfile, except when recovering
* save-on-exit/autosave files. In the latter case, it will be the path of the file that
* generated the auto-saved one being recovered.
*
* NOTE: Currently expected to be the same path as #BlendFileData.filepath. */
char filepath[1024]; /* 1024 = FILE_MAX */
/** TODO: think this isn't needed anymore? */

View File

@ -3109,25 +3109,21 @@ static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead)
bfd->fileflags = fg->fileflags;
bfd->globalf = fg->globalf;
STRNCPY(bfd->filepath, fg->filepath);
/* Error in 2.65 and older: `main->filepath` was not set if you save from startup
* (not after loading file). */
if (bfd->filepath[0] == 0) {
if (fd->fileversion < 265 || (fd->fileversion == 265 && fg->subversion < 1)) {
if ((G.fileflags & G_FILE_RECOVER_READ) == 0) {
STRNCPY(bfd->filepath, BKE_main_blendfile_path(bfd->main));
}
}
/* early 2.50 version patch - filepath not in FileGlobal struct at all */
if (fd->fileversion <= 250) {
STRNCPY(bfd->filepath, BKE_main_blendfile_path(bfd->main));
}
}
/* Note: since 88b24bc6bb, `fg->filepath` is only written for crash recovery and autosave files,
* so only overwrite `fd->relabase` if it is not empty, in case a regular blendfile is opened
* through one of the 'recover' operators.
*
* In all other cases, the path is just set to the current path of the blendfile being read, so
* there is no need to handle anymore older files (pre-2.65) that did not store (correctly) their
* path. */
if (G.fileflags & G_FILE_RECOVER_READ) {
STRNCPY(fd->relabase, fg->filepath);
if (fg->filepath[0] != '\0') {
STRNCPY(fd->relabase, fg->filepath);
/* Used to set expected original filepath in read Main, instead of the path of the recovery
* file itself. */
STRNCPY(bfd->filepath, fg->filepath);
}
}
bfd->curscreen = fg->curscreen;
@ -3589,6 +3585,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
bfd->main = BKE_main_new();
bfd->main->versionfile = fd->fileversion;
STRNCPY(bfd->filepath, filepath);
bfd->type = BLENFILETYPE_BLEND;

View File

@ -65,7 +65,13 @@ struct FileData {
* to detect unchanged data from memfile. */
int undo_direction; /* eUndoStepDir */
/** Now only in use for library appending. */
/** Used for relative paths handling.
*
* Typically the actual filepath of the read blendfile, except when recovering
* save-on-exit/autosave files. In the latter case, it will be the path of the file that
* generated the auto-saved one being recovered.
*
* NOTE: Currently expected to be the same path as #BlendFileData.filepath. */
char relabase[FILE_MAX];
/** General reading variables. */

View File

@ -2703,6 +2703,17 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
FOREACH_NODETREE_END;
}
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 14)) {
const Brush *default_brush = DNA_struct_default_get(Brush);
LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
brush->automasking_start_normal_limit = default_brush->automasking_start_normal_limit;
brush->automasking_start_normal_falloff = default_brush->automasking_start_normal_falloff;
brush->automasking_view_normal_limit = default_brush->automasking_view_normal_limit;
brush->automasking_view_normal_falloff = default_brush->automasking_view_normal_falloff;
}
}
/**
* Always bump subversion in BKE_blender_version.h when adding versioning
* code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check.

View File

@ -817,12 +817,28 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
}
{
/* Use the same tool icon color in the brush cursor */
LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
/* Use the same tool icon color in the brush cursor */
if (brush->ob_mode & OB_MODE_SCULPT) {
BLI_assert(brush->sculpt_tool != 0);
BKE_brush_sculpt_reset(brush);
}
/* Set the default texture mapping.
* Do it for all brushes, since some of them might be coming from the startup file. */
brush->mtex.brush_map_mode = MTEX_MAP_MODE_VIEW;
brush->mask_mtex.brush_map_mode = MTEX_MAP_MODE_VIEW;
}
}
{
const Brush *default_brush = DNA_struct_default_get(Brush);
LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
brush->automasking_start_normal_limit = default_brush->automasking_start_normal_limit;
brush->automasking_start_normal_falloff = default_brush->automasking_start_normal_falloff;
brush->automasking_view_normal_limit = default_brush->automasking_view_normal_limit;
brush->automasking_view_normal_falloff = default_brush->automasking_view_normal_falloff;
}
}
}

View File

@ -65,16 +65,18 @@ static void free_locales()
static void fill_locales()
{
const char *const languages_path = BKE_appdir_folder_id(BLENDER_DATAFILES, "locale");
std::optional<std::string> languages_path = BKE_appdir_folder_id(BLENDER_DATAFILES, "locale");
char languages[FILE_MAX];
LinkNode *lines = nullptr, *line;
LinkNode *lines = nullptr, *line = nullptr;
char *str;
int idx = 0;
free_locales();
BLI_path_join(languages, FILE_MAX, languages_path, "languages");
line = lines = BLI_file_read_as_lines(languages);
if (languages_path.has_value()) {
BLI_path_join(languages, FILE_MAX, languages_path->c_str(), "languages");
line = lines = BLI_file_read_as_lines(languages);
}
/* This whole "parsing" code is a bit weak, in that it expects strictly formatted input file...
* Should not be a problem, though, as this file is script-generated! */
@ -181,7 +183,7 @@ EnumPropertyItem *BLT_lang_RNA_enum_properties()
void BLT_lang_init()
{
#ifdef WITH_INTERNATIONAL
const char *const messagepath = BKE_appdir_folder_id(BLENDER_DATAFILES, "locale");
const std::optional<std::string> messagepath = BKE_appdir_folder_id(BLENDER_DATAFILES, "locale");
#endif
/* Make sure LANG is correct and wouldn't cause #std::runtime_error. */
@ -212,8 +214,8 @@ void BLT_lang_init()
#endif
#ifdef WITH_INTERNATIONAL
if (messagepath) {
bl_locale_init(messagepath, TEXT_DOMAIN_NAME);
if (messagepath.has_value()) {
bl_locale_init(messagepath->c_str(), TEXT_DOMAIN_NAME);
fill_locales();
}
else {

View File

@ -8,6 +8,8 @@
* Creates a solid wireframe from connected faces.
*/
#include <algorithm>
#include "MEM_guardedalloc.h"
#include "DNA_meshdata_types.h"
@ -154,7 +156,7 @@ void BM_mesh_wireframe(BMesh *bm,
const int defgrp_index,
const bool defgrp_invert,
const short mat_offset,
const short mat_max,
const int mat_max,
/* for operators */
const bool use_tag)
{
@ -423,7 +425,7 @@ void BM_mesh_wireframe(BMesh *bm,
f_new = BM_face_create_quad_tri(bm, v_l1, v_l2, v_neg2, v_neg1, f_src, BM_CREATE_NOP);
if (mat_offset) {
f_new->mat_nr = CLAMPIS(f_new->mat_nr + mat_offset, 0, mat_max);
f_new->mat_nr = std::clamp(f_new->mat_nr + mat_offset, 0, mat_max);
}
BM_elem_flag_enable(f_new, BM_ELEM_TAG);
l_new = BM_FACE_FIRST_LOOP(f_new);
@ -436,7 +438,7 @@ void BM_mesh_wireframe(BMesh *bm,
f_new = BM_face_create_quad_tri(bm, v_l2, v_l1, v_pos1, v_pos2, f_src, BM_CREATE_NOP);
if (mat_offset) {
f_new->mat_nr = CLAMPIS(f_new->mat_nr + mat_offset, 0, mat_max);
f_new->mat_nr = std::clamp(f_new->mat_nr + mat_offset, 0, mat_max);
}
BM_elem_flag_enable(f_new, BM_ELEM_TAG);
l_new = BM_FACE_FIRST_LOOP(f_new);
@ -455,7 +457,7 @@ void BM_mesh_wireframe(BMesh *bm,
f_new = BM_face_create_quad_tri(bm, v_b2, v_b1, v_neg1, v_neg2, f_src, BM_CREATE_NOP);
if (mat_offset) {
f_new->mat_nr = CLAMPIS(f_new->mat_nr + mat_offset, 0, mat_max);
f_new->mat_nr = std::clamp(f_new->mat_nr + mat_offset, 0, mat_max);
}
BM_elem_flag_enable(f_new, BM_ELEM_TAG);
l_new = BM_FACE_FIRST_LOOP(f_new);
@ -467,7 +469,7 @@ void BM_mesh_wireframe(BMesh *bm,
f_new = BM_face_create_quad_tri(bm, v_b1, v_b2, v_pos2, v_pos1, f_src, BM_CREATE_NOP);
if (mat_offset) {
f_new->mat_nr = CLAMPIS(f_new->mat_nr + mat_offset, 0, mat_max);
f_new->mat_nr = std::clamp(f_new->mat_nr + mat_offset, 0, mat_max);
}
BM_elem_flag_enable(f_new, BM_ELEM_TAG);
l_new = BM_FACE_FIRST_LOOP(f_new);

View File

@ -29,5 +29,5 @@ void BM_mesh_wireframe(BMesh *bm,
int defgrp_index,
bool defgrp_invert,
short mat_offset,
short mat_max,
int mat_max,
bool use_tag);

View File

@ -105,7 +105,7 @@ void BoxMaskOperation::update_memory_buffer_partial(MemoryBuffer *output,
break;
case CMP_NODE_MASKTYPE_SUBTRACT:
mask_func = [](const bool is_inside, const float *mask, const float *value) {
return is_inside ? CLAMPIS(mask[0] - value[0], 0, 1) : mask[0];
return is_inside ? std::clamp(mask[0] - value[0], 0.0f, 1.0f) : mask[0];
};
break;
case CMP_NODE_MASKTYPE_MULTIPLY:

View File

@ -111,7 +111,7 @@ void EllipseMaskOperation::update_memory_buffer_partial(MemoryBuffer *output,
break;
case CMP_NODE_MASKTYPE_SUBTRACT:
mask_func = [](const bool is_inside, const float *mask, const float *value) {
return is_inside ? CLAMPIS(mask[0] - value[0], 0, 1) : mask[0];
return is_inside ? std::clamp(mask[0] - value[0], 0.0f, 1.0f) : mask[0];
};
break;
case CMP_NODE_MASKTYPE_MULTIPLY:

View File

@ -34,78 +34,6 @@ void FlipOperation::execute_pixel_sampled(float output[4], float x, float y, Pix
input_operation_->read_sampled(output, nx, ny, sampler);
}
bool FlipOperation::determine_depending_area_of_interest(rcti *input,
ReadBufferOperation *read_operation,
rcti *output)
{
rcti new_input;
if (flip_x_) {
const int w = int(this->get_width()) - 1;
new_input.xmax = (w - input->xmin) + 1;
new_input.xmin = (w - input->xmax) - 1;
}
else {
new_input.xmin = input->xmin;
new_input.xmax = input->xmax;
}
if (flip_y_) {
const int h = int(this->get_height()) - 1;
new_input.ymax = (h - input->ymin) + 1;
new_input.ymin = (h - input->ymax) - 1;
}
else {
new_input.ymin = input->ymin;
new_input.ymax = input->ymax;
}
return NodeOperation::determine_depending_area_of_interest(&new_input, read_operation, output);
}
void FlipOperation::determine_canvas(const rcti &preferred_area, rcti &r_area)
{
NodeOperation::determine_canvas(preferred_area, r_area);
if (execution_model_ == eExecutionModel::FullFrame) {
rcti input_area = r_area;
if (flip_x_) {
const int width = BLI_rcti_size_x(&input_area) - 1;
r_area.xmax = (width - input_area.xmin) + 1;
r_area.xmin = (width - input_area.xmax) + 1;
}
if (flip_y_) {
const int height = BLI_rcti_size_y(&input_area) - 1;
r_area.ymax = (height - input_area.ymin) + 1;
r_area.ymin = (height - input_area.ymax) + 1;
}
}
}
void FlipOperation::get_area_of_interest(const int input_idx,
const rcti &output_area,
rcti &r_input_area)
{
BLI_assert(input_idx == 0);
UNUSED_VARS_NDEBUG(input_idx);
if (flip_x_) {
const int w = int(this->get_width()) - 1;
r_input_area.xmax = (w - output_area.xmin) + 1;
r_input_area.xmin = (w - output_area.xmax) + 1;
}
else {
r_input_area.xmin = output_area.xmin;
r_input_area.xmax = output_area.xmax;
}
if (flip_y_) {
const int h = int(this->get_height()) - 1;
r_input_area.ymax = (h - output_area.ymin) + 1;
r_input_area.ymin = (h - output_area.ymax) + 1;
}
else {
r_input_area.ymin = output_area.ymin;
r_input_area.ymax = output_area.ymax;
}
}
void FlipOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs)

View File

@ -16,9 +16,6 @@ class FlipOperation : public MultiThreadedOperation {
public:
FlipOperation();
bool determine_depending_area_of_interest(rcti *input,
ReadBufferOperation *read_operation,
rcti *output) override;
void execute_pixel_sampled(float output[4], float x, float y, PixelSampler sampler) override;
void init_execution() override;
@ -32,8 +29,6 @@ class FlipOperation : public MultiThreadedOperation {
flip_y_ = flipY;
}
void determine_canvas(const rcti &preferred_area, rcti &r_area) override;
void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override;
void update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs) override;

View File

@ -35,7 +35,7 @@ class MathBaseOperation : public MultiThreadedOperation {
float clamp_when_enabled(float value)
{
if (use_clamp_) {
return CLAMPIS(value, 0.0f, 1.0f);
return std::clamp(value, 0.0f, 1.0f);
}
return value;
}

View File

@ -308,7 +308,7 @@ void MixColorBurnOperation::update_memory_buffer_row(PixelCursor &p)
}
else {
tmp = 1.0f - (1.0f - p.color1[0]) / tmp;
p.out[0] = CLAMPIS(tmp, 0.0f, 1.0f);
p.out[0] = std::clamp(tmp, 0.0f, 1.0f);
}
tmp = value_m + value * p.color2[1];
@ -317,7 +317,7 @@ void MixColorBurnOperation::update_memory_buffer_row(PixelCursor &p)
}
else {
tmp = 1.0f - (1.0f - p.color1[1]) / tmp;
p.out[1] = CLAMPIS(tmp, 0.0f, 1.0f);
p.out[1] = std::clamp(tmp, 0.0f, 1.0f);
}
tmp = value_m + value * p.color2[2];
@ -326,7 +326,7 @@ void MixColorBurnOperation::update_memory_buffer_row(PixelCursor &p)
}
else {
tmp = 1.0f - (1.0f - p.color1[2]) / tmp;
p.out[2] = CLAMPIS(tmp, 0.0f, 1.0f);
p.out[2] = std::clamp(tmp, 0.0f, 1.0f);
}
p.out[3] = p.color1[3];

View File

@ -100,8 +100,8 @@ static void sample_bilinear_horizontal(T *reader, int x, int y, float xoffset, f
static inline const float *areatex_sample_internal(const float *areatex, int x, int y)
{
return &areatex[(CLAMPIS(x, 0, SMAA_AREATEX_SIZE - 1) +
CLAMPIS(y, 0, SMAA_AREATEX_SIZE - 1) * SMAA_AREATEX_SIZE) *
return &areatex[(std::clamp(x, 0, SMAA_AREATEX_SIZE - 1) +
std::clamp(y, 0, SMAA_AREATEX_SIZE - 1) * SMAA_AREATEX_SIZE) *
2];
}
@ -948,8 +948,8 @@ void SMAABlendingWeightCalculationOperation::detect_horizontal_corner_pattern(
factor[1] -= rounding * e[0];
}
weights[0] *= CLAMPIS(factor[0], 0.0f, 1.0f);
weights[1] *= CLAMPIS(factor[1], 0.0f, 1.0f);
weights[0] *= std::clamp(factor[0], 0.0f, 1.0f);
weights[1] *= std::clamp(factor[1], 0.0f, 1.0f);
}
void SMAABlendingWeightCalculationOperation::detect_vertical_corner_pattern(
@ -977,8 +977,8 @@ void SMAABlendingWeightCalculationOperation::detect_vertical_corner_pattern(
factor[1] -= rounding * e[1];
}
weights[0] *= CLAMPIS(factor[0], 0.0f, 1.0f);
weights[1] *= CLAMPIS(factor[1], 0.0f, 1.0f);
weights[0] *= std::clamp(factor[0], 0.0f, 1.0f);
weights[1] *= std::clamp(factor[1], 0.0f, 1.0f);
}
/*-----------------------------------------------------------------------------*/

View File

@ -39,7 +39,19 @@ void main()
float input_saturation = compute_saturation(input_color, key_saturation_indices);
float key_saturation = compute_saturation(key_color, key_saturation_indices);
float matte = 1.0f - clamp(input_saturation / key_saturation, 0.0, 1.0);
float matte;
if (input_saturation < 0) {
/* Means main channel of pixel is different from screen, assume this is completely a
* foreground. */
matte = 1.0f;
}
else if (input_saturation >= key_saturation) {
/* Matched main channels and higher saturation on pixel is treated as completely background. */
matte = 0.0f;
}
else {
matte = 1.0f - clamp(input_saturation / key_saturation, 0.0, 1.0);
}
imageStore(output_img, texel, vec4(matte));
}

View File

@ -53,16 +53,16 @@ void main()
#endif
if (update_mip_0) {
imageStore(out_mip_0, src_px + ivec2(0, 1), samp.xxxx);
imageStore(out_mip_0, src_px + ivec2(1, 1), samp.yyyy);
imageStore(out_mip_0, src_px + ivec2(1, 0), samp.zzzz);
imageStore(out_mip_0, src_px + ivec2(0, 0), samp.wwww);
imageStoreFast(out_mip_0, src_px + ivec2(0, 1), samp.xxxx);
imageStoreFast(out_mip_0, src_px + ivec2(1, 1), samp.yyyy);
imageStoreFast(out_mip_0, src_px + ivec2(1, 0), samp.zzzz);
imageStoreFast(out_mip_0, src_px + ivec2(0, 0), samp.wwww);
}
/* Level 1. (No load) */
float max_depth = reduce_max(samp);
ivec2 dst_px = ivec2(kernel_origin + local_px);
imageStore(out_mip_1, dst_px, vec4(max_depth));
imageStoreFast(out_mip_1, dst_px, vec4(max_depth));
store_local_depth(local_px, max_depth);
/* Level 2-5. */
@ -75,7 +75,7 @@ void main()
if (active_thread) { \
max_depth = reduce_max(load_local_depths(local_px)); \
dst_px = ivec2((kernel_origin >> mask_shift) + local_px); \
imageStore(out_mip__, dst_px, vec4(max_depth)); \
imageStoreFast(out_mip__, dst_px, vec4(max_depth)); \
} \
barrier(); /* Wait for previous reads to finish. */ \
if (active_thread) { \
@ -105,14 +105,14 @@ void main()
kernel_origin = ivec2(gl_WorkGroupSize.xy) * ivec2(x, y);
src_px = ivec2(kernel_origin + local_px) * 2;
vec4 samp;
samp.x = imageLoad(out_mip_5, min(src_px + ivec2(0, 1), image_border)).x;
samp.y = imageLoad(out_mip_5, min(src_px + ivec2(1, 1), image_border)).x;
samp.z = imageLoad(out_mip_5, min(src_px + ivec2(1, 0), image_border)).x;
samp.w = imageLoad(out_mip_5, min(src_px + ivec2(0, 0), image_border)).x;
samp.x = imageLoadFast(out_mip_5, min(src_px + ivec2(0, 1), image_border)).x;
samp.y = imageLoadFast(out_mip_5, min(src_px + ivec2(1, 1), image_border)).x;
samp.z = imageLoadFast(out_mip_5, min(src_px + ivec2(1, 0), image_border)).x;
samp.w = imageLoadFast(out_mip_5, min(src_px + ivec2(0, 0), image_border)).x;
/* Level 6. */
float max_depth = reduce_max(samp);
ivec2 dst_px = ivec2(kernel_origin + local_px);
imageStore(out_mip_6, dst_px, vec4(max_depth));
imageStoreFast(out_mip_6, dst_px, vec4(max_depth));
store_local_depth(local_px, max_depth);
mask_shift = 1;

View File

@ -21,6 +21,7 @@
#include "BLI_lasso_2d.h"
#include "BLI_math_color.h"
#include "BLI_math_matrix.h"
#include "BLI_math_vector.hh"
#include "BLI_rand.h"
#include "BLI_time.h"
#include "BLI_utildefines.h"
@ -2893,7 +2894,7 @@ static void gpencil_sbuffer_vertex_color_random(
int ix = int(tpt->m_xy[0] * seed);
int iy = int(tpt->m_xy[1] * seed);
int iz = ix + iy * seed;
float hsv[3];
blender::float3 hsv;
float factor_value[3];
zero_v3(factor_value);
@ -2960,7 +2961,7 @@ static void gpencil_sbuffer_vertex_color_random(
hsv[0] -= 1.0f;
}
CLAMP3(hsv, 0.0f, 1.0f);
hsv = blender::math::clamp(hsv, 0.0f, 1.0f);
hsv_to_rgb_v(hsv, tpt->vert_color);
}
}

View File

@ -150,7 +150,9 @@ class AbstractTreeView : public AbstractView, public TreeViewItemContainer {
void draw_hierarchy_lines(const ARegion &region) const;
void draw_hierarchy_lines_recursive(const ARegion &region,
const TreeViewOrItem &parent,
uint pos) const;
const uint pos,
const float aspect) const;
AbstractTreeViewItem *find_last_visible_descendant(const AbstractTreeViewItem &parent) const;
};

View File

@ -5911,6 +5911,9 @@ const char *ui_but_placeholder_get(uiBut *but)
else if (type && !STREQ(RNA_struct_identifier(type), "UnknownType")) {
placeholder = RNA_struct_ui_name(type);
}
else {
placeholder = RNA_property_ui_name(but->rnaprop);
}
}
else if (but->type == UI_BTYPE_TEXT && but->icon == ICON_VIEWZOOM) {
placeholder = CTX_IFACE_(BLT_I18NCONTEXT_ID_WINDOWMANAGER, "Search");

View File

@ -950,11 +950,11 @@ static void init_internal_icons()
{
# if 0 /* temp disabled */
if ((btheme != nullptr) && btheme->tui.iconfile[0]) {
char *icondir = BKE_appdir_folder_id(BLENDER_DATAFILES, "icons");
std::optional<std::string> icondir = BKE_appdir_folder_id(BLENDER_DATAFILES, "icons");
char iconfilestr[FILE_MAX];
if (icondir) {
BLI_path_join(iconfilestr, sizeof(iconfilestr), icondir, btheme->tui.iconfile);
if (icondir.has_value()) {
BLI_path_join(iconfilestr, sizeof(iconfilestr), icondir->c_str(), btheme->tui.iconfile);
/* if the image is missing bbuf will just be nullptr */
bbuf = IMB_loadiffname(iconfilestr, IB_rect, nullptr);
@ -1054,14 +1054,14 @@ static void init_internal_icons()
static void init_iconfile_list(ListBase *list)
{
BLI_listbase_clear(list);
const char *icondir = BKE_appdir_folder_id(BLENDER_DATAFILES, "icons");
const std::optional<std::string> icondir = BKE_appdir_folder_id(BLENDER_DATAFILES, "icons");
if (icondir == nullptr) {
if (!icondir.has_value()) {
return;
}
direntry *dir;
const int totfile = BLI_filelist_dir_contents(icondir, &dir);
const int totfile = BLI_filelist_dir_contents(icondir->c_str(), &dir);
int index = 1;
for (int i = 0; i < totfile; i++) {
@ -1078,7 +1078,7 @@ static void init_iconfile_list(ListBase *list)
/* check to see if the image is the right size, continue if not */
/* copying strings here should go ok, assuming that we never get back
* a complete path to file longer than 256 chars */
BLI_path_join(iconfilestr, sizeof(iconfilestr), icondir, filename);
BLI_path_join(iconfilestr, sizeof(iconfilestr), icondir->c_str(), filename);
bbuf = IMB_loadiffname(iconfilestr, IB_rect);
if (bbuf) {

View File

@ -216,7 +216,7 @@ static void ui_update_color_picker_buts_rgb(uiBut *from_but,
const int col_len = SNPRINTF_RLEN(col, "%02X%02X%02X", UNPACK3_EX((uint), rgb_hex_uchar, ));
memcpy(bt->poin, col, col_len + 1);
}
else if (bt->str[1] == ' ') {
else if (bt->str.find(' ', 1) == 1) {
if (bt->str[0] == 'R') {
ui_but_value_set(bt, rgb_scene_linear[0]);
}

View File

@ -52,12 +52,14 @@ const RecentCache *get_recent_cache_or_null()
static std::optional<std::string> get_recent_searches_file_path()
{
const char *user_config_dir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, nullptr);
if (!user_config_dir) {
const std::optional<std::string> user_config_dir = BKE_appdir_folder_id_create(
BLENDER_USER_CONFIG, nullptr);
if (!user_config_dir.has_value()) {
return std::nullopt;
}
char filepath[FILE_MAX];
BLI_path_join(filepath, sizeof(filepath), user_config_dir, BLENDER_RECENT_SEARCHES_FILE);
BLI_path_join(
filepath, sizeof(filepath), user_config_dir->c_str(), BLENDER_RECENT_SEARCHES_FILE);
return std::string(filepath);
}

View File

@ -148,7 +148,7 @@ static int template_search_textbut_width(PointerRNA *ptr, PropertyRNA *name_prop
}
/* Clamp to some min/max width. */
return CLAMPIS(
return std::clamp(
estimated_width, TEMPLATE_SEARCH_TEXTBUT_MIN_WIDTH, TEMPLATE_SEARCH_TEXTBUT_MIN_WIDTH * 3);
}

View File

@ -966,14 +966,14 @@ static void shape_preset_trias_from_rect_dash(uiWidgetTrias *tria, const rcti *r
static void shadecolors4(
uchar coltop[4], uchar coldown[4], const uchar *color, short shadetop, short shadedown)
{
coltop[0] = CLAMPIS(color[0] + shadetop, 0, 255);
coltop[1] = CLAMPIS(color[1] + shadetop, 0, 255);
coltop[2] = CLAMPIS(color[2] + shadetop, 0, 255);
coltop[0] = std::clamp(color[0] + shadetop, 0, 255);
coltop[1] = std::clamp(color[1] + shadetop, 0, 255);
coltop[2] = std::clamp(color[2] + shadetop, 0, 255);
coltop[3] = color[3];
coldown[0] = CLAMPIS(color[0] + shadedown, 0, 255);
coldown[1] = CLAMPIS(color[1] + shadedown, 0, 255);
coldown[2] = CLAMPIS(color[2] + shadedown, 0, 255);
coldown[0] = std::clamp(color[0] + shadedown, 0, 255);
coldown[1] = std::clamp(color[1] + shadedown, 0, 255);
coldown[2] = std::clamp(color[2] + shadedown, 0, 255);
coldown[3] = color[3];
}
@ -5218,9 +5218,9 @@ static void ui_draw_popover_back_impl(const uiWidgetColors *wcol,
{
/* Alas, this isn't nice. */
const float unit_half = unit_size / 2;
const float cent_x = mval_origin ? CLAMPIS(mval_origin[0],
rect->xmin + unit_size,
rect->xmax - unit_size) :
const float cent_x = mval_origin ? std::clamp(mval_origin[0],
rect->xmin + unit_size,
rect->xmax - unit_size) :
BLI_rcti_cent_x(rect);
GPU_blend(GPU_BLEND_ALPHA);

View File

@ -172,7 +172,7 @@ static float edge_pan_speed(View2DEdgePanData *vpd,
/* Zoom factor increases speed when zooming in and decreases speed when zooming out. */
const float zoomx = float(BLI_rcti_size_x(&region->winrct) + 1) /
BLI_rctf_size_x(&region->v2d.cur);
const float zoom_factor = 1.0f + CLAMPIS(vpd->zoom_influence, 0.0f, 1.0f) * (zoomx - 1.0f);
const float zoom_factor = 1.0f + std::clamp(vpd->zoom_influence, 0.0f, 1.0f) * (zoomx - 1.0f);
return distance_factor * delay_factor * zoom_factor * vpd->max_speed * U.widget_unit *
float(UI_SCALE_FAC);

View File

@ -135,14 +135,15 @@ AbstractTreeViewItem *AbstractTreeView::find_last_visible_descendant(
void AbstractTreeView::draw_hierarchy_lines_recursive(const ARegion &region,
const TreeViewOrItem &parent,
const uint pos) const
const uint pos,
const float aspect) const
{
for (const auto &item : parent.children_) {
if (!item->is_collapsible() || item->is_collapsed()) {
continue;
}
draw_hierarchy_lines_recursive(region, *item, pos);
draw_hierarchy_lines_recursive(region, *item, pos, aspect);
const AbstractTreeViewItem *first_descendant = item->children_.first().get();
const AbstractTreeViewItem *last_descendant = find_last_visible_descendant(*item);
@ -162,9 +163,10 @@ void AbstractTreeView::draw_hierarchy_lines_recursive(const ARegion &region,
ui_but_to_pixelrect(&last_child_rect, &region, block, &last_child_but);
/* Small vertical padding. */
const short line_padding = UI_UNIT_Y / 4.0f;
const float x = first_child_rect.xmin + first_descendant->indent_width() -
UI_ICON_SIZE * 0.5f + 2 * UI_SCALE_FAC;
const short line_padding = UI_UNIT_Y / 4.0f / aspect;
const float x = first_child_rect.xmin + ((first_descendant->indent_width() -
(0.5f * UI_ICON_SIZE) + U.pixelsize + UI_SCALE_FAC) /
aspect);
immBegin(GPU_PRIM_LINES, 2);
immVertex2f(pos, x, first_child_rect.ymax - line_padding);
immVertex2f(pos, x, last_child_rect.ymin + line_padding);
@ -174,6 +176,8 @@ void AbstractTreeView::draw_hierarchy_lines_recursive(const ARegion &region,
void AbstractTreeView::draw_hierarchy_lines(const ARegion &region) const
{
const float aspect = BLI_rctf_size_y(&region.v2d.cur) / (BLI_rcti_size_y(&region.v2d.mask) + 1);
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
uchar col[4];
@ -191,9 +195,9 @@ void AbstractTreeView::draw_hierarchy_lines(const ARegion &region) const
col[3] = 255;
immUniformColor4ubv(col);
GPU_line_width(1.0f);
GPU_line_width(1.0f / aspect);
GPU_blend(GPU_BLEND_ALPHA);
draw_hierarchy_lines_recursive(region, *this, pos);
draw_hierarchy_lines_recursive(region, *this, pos, aspect);
GPU_blend(GPU_BLEND_NONE);
immUnbindProgram();

View File

@ -334,7 +334,7 @@ static bool edbm_bevel_calc(wmOperator *op)
EDBM_redo_state_restore(&opdata->ob_store[ob_index].mesh_backup, em, false);
}
const int material = CLAMPIS(material_init, -1, obedit->totcol - 1);
const int material = std::clamp(material_init, -1, obedit->totcol - 1);
EDBM_op_init(em,
&bmop,

View File

@ -9,6 +9,8 @@
* an experimental tool for quickly constructing/manipulating faces.
*/
#include <algorithm>
#include "MEM_guardedalloc.h"
#include "DNA_object_types.h"
@ -312,7 +314,7 @@ static int edbm_polybuild_face_at_cursor_invoke(bContext *C, wmOperator *op, con
mul_m4_v3(vc.obedit->world_to_object, center);
if (f_reference->len == 3 && RNA_boolean_get(op->ptr, "create_quads")) {
const float fac = line_point_factor_v3(center, e_act->v1->co, e_act->v2->co);
BMVert *v_new = BM_edge_split(bm, e_act, e_act->v1, nullptr, CLAMPIS(fac, 0.0f, 1.0f));
BMVert *v_new = BM_edge_split(bm, e_act, e_act->v1, nullptr, std::clamp(fac, 0.0f, 1.0f));
copy_v3_v3(v_new->co, center);
edbm_flag_disable_all_multi(vc.scene, vc.view_layer, vc.v3d, BM_ELEM_SELECT);
BM_vert_select_set(bm, v_new, true);
@ -477,7 +479,7 @@ static int edbm_polybuild_split_at_cursor_invoke(bContext *C,
mul_m4_v3(vc.obedit->world_to_object, center);
const float fac = line_point_factor_v3(center, e_act->v1->co, e_act->v2->co);
BMVert *v_new = BM_edge_split(bm, e_act, e_act->v1, nullptr, CLAMPIS(fac, 0.0f, 1.0f));
BMVert *v_new = BM_edge_split(bm, e_act, e_act->v1, nullptr, std::clamp(fac, 0.0f, 1.0f));
copy_v3_v3(v_new->co, center);
edbm_flag_disable_all_multi(vc.scene, vc.view_layer, vc.v3d, BM_ELEM_SELECT);

View File

@ -1332,10 +1332,11 @@ static ImBuf *icon_preview_imbuf_from_brush(Brush *brush)
/* Otherwise lets try to find it in other directories. */
if (!(brush->icon_imbuf)) {
const char *brushicons_dir = BKE_appdir_folder_id(BLENDER_DATAFILES, "brushicons");
const std::optional<std::string> brushicons_dir = BKE_appdir_folder_id(BLENDER_DATAFILES,
"brushicons");
/* Expected to be found, but don't crash if it's not. */
if (brushicons_dir) {
BLI_path_join(filepath, sizeof(filepath), brushicons_dir, brush->icon_filepath);
if (brushicons_dir.has_value()) {
BLI_path_join(filepath, sizeof(filepath), brushicons_dir->c_str(), brush->icon_filepath);
/* Use default color spaces. */
brush->icon_imbuf = IMB_loadiffname(filepath, flags, nullptr);

View File

@ -405,11 +405,13 @@ static void WORKSPACE_OT_append_activate(wmOperatorType *ot)
static WorkspaceConfigFileData *workspace_config_file_read(const char *app_template)
{
const char *cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, app_template);
const std::optional<std::string> cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG,
app_template);
char startup_file_path[FILE_MAX] = {0};
if (cfgdir) {
BLI_path_join(startup_file_path, sizeof(startup_file_path), cfgdir, BLENDER_STARTUP_FILE);
if (cfgdir.has_value()) {
BLI_path_join(
startup_file_path, sizeof(startup_file_path), cfgdir->c_str(), BLENDER_STARTUP_FILE);
}
bool has_path = BLI_exists(startup_file_path);

View File

@ -6,6 +6,7 @@
* \ingroup edsculpt
*/
#include <algorithm>
#include <cfloat>
#include <cmath>
@ -1160,7 +1161,7 @@ static void paint_stroke_add_sample(
const Paint *paint, PaintStroke *stroke, float x, float y, float pressure)
{
PaintSample *sample = &stroke->samples[stroke->cur_sample];
int max_samples = CLAMPIS(paint->num_input_samples, 1, PAINT_MAX_INPUT_SAMPLES);
int max_samples = std::clamp(paint->num_input_samples, 1, PAINT_MAX_INPUT_SAMPLES);
sample->mouse[0] = x;
sample->mouse[1] = y;

View File

@ -725,15 +725,29 @@ static void init_boundary_masking(Object *ob, eBoundaryAutomaskMode mode, int pr
}
}
/* Updates the cached values, preferring brush settings over tool-level settings. */
static void cache_settings_update(Cache &automasking, SculptSession *ss, Sculpt *sd, Brush *brush)
{
automasking.settings.flags = calc_effective_bits(sd, brush);
automasking.settings.initial_face_set = face_set::active_face_set_get(ss);
automasking.settings.view_normal_limit = sd->automasking_view_normal_limit;
automasking.settings.view_normal_falloff = sd->automasking_view_normal_falloff;
automasking.settings.start_normal_limit = sd->automasking_start_normal_limit;
automasking.settings.start_normal_falloff = sd->automasking_start_normal_falloff;
if (brush && (brush->automasking_flags & BRUSH_AUTOMASKING_VIEW_NORMAL)) {
automasking.settings.view_normal_limit = brush->automasking_view_normal_limit;
automasking.settings.view_normal_falloff = brush->automasking_view_normal_falloff;
}
else {
automasking.settings.view_normal_limit = sd->automasking_view_normal_limit;
automasking.settings.view_normal_falloff = sd->automasking_view_normal_falloff;
}
if (brush && (brush->automasking_flags & BRUSH_AUTOMASKING_BRUSH_NORMAL)) {
automasking.settings.start_normal_limit = brush->automasking_start_normal_limit;
automasking.settings.start_normal_falloff = brush->automasking_start_normal_falloff;
}
else {
automasking.settings.start_normal_limit = sd->automasking_start_normal_limit;
automasking.settings.start_normal_falloff = sd->automasking_start_normal_falloff;
}
if (brush && (brush->automasking_flags & BRUSH_AUTOMASKING_CAVITY_ALL)) {
automasking.settings.cavity_curve = brush->automasking_cavity_curve;

View File

@ -10,6 +10,7 @@
#include "BLI_math_color.h"
#include "BLI_math_color_blend.h"
#include "BLI_math_vector.hh"
#include "BLI_task.h"
#include "BLT_translation.h"
@ -92,7 +93,9 @@ static void color_filter_task(Object *ob,
SCULPT_orig_vert_data_update(&orig_data, &vd);
auto_mask::node_update(automask_data, vd);
float orig_color[3], final_color[4], hsv_color[3];
float3 orig_color;
float4 final_color;
float3 hsv_color;
int hue;
float brightness, contrast, gain, delta, offset;
float fade = vd.mask;
@ -209,7 +212,7 @@ static void color_filter_task(Object *ob,
blend_color_interpolate_float(final_color, col, smooth_color, fade);
}
CLAMP4(final_color, 0.0f, 1.0f);
final_color = math::clamp(final_color, 0.0f, 1.0f);
/* Prevent accumulated numeric error from corrupting alpha. */
if (copy_alpha) {

View File

@ -529,7 +529,7 @@ struct StrokeCache {
float4x4 stroke_local_mat;
float multiplane_scrape_angle;
float wet_mix_prev_color[4];
float4 wet_mix_prev_color;
float density_seed;
rcti previous_r; /* previous redraw rectangle */

View File

@ -12,6 +12,7 @@
#include "BLI_hash.h"
#include "BLI_math_color_blend.h"
#include "BLI_math_vector.hh"
#include "BLI_task.h"
#include "BLI_vector.hh"
@ -192,10 +193,10 @@ static void do_paint_brush_task(Object *ob,
ss->cache->automasking.get(), ss, vd.vertex, &automask_data);
mul_v4_v4fl(buffer_color, color_buffer->color[vd.i], brush->alpha * automasking);
float col[4];
float4 col;
SCULPT_vertex_color_get(ss, vd.vertex, col);
IMB_blend_color_float(col, orig_data.col, buffer_color, IMB_BlendMode(brush->blend));
CLAMP4(col, 0.0f, 1.0f);
col = math::clamp(col, 0.0f, 1.0f);
SCULPT_vertex_color_set(ss, vd.vertex, col);
}
BKE_pbvh_vertex_iter_end;
@ -286,7 +287,7 @@ void do_paint_brush(PaintModeSettings *paint_mode_settings,
/* Regular Paint mode. */
/* Wet paint color sampling. */
float wet_color[4] = {0.0f};
float4 wet_color(0);
if (ss->cache->paint_brush.wet_mix > 0.0f) {
const SampleWetPaintData swptd = threading::parallel_reduce(
nodes.index_range(),
@ -308,7 +309,7 @@ void do_paint_brush(PaintModeSettings *paint_mode_settings,
if (swptd.tot_samples > 0 && is_finite_v4(swptd.color)) {
copy_v4_v4(wet_color, swptd.color);
mul_v4_fl(wet_color, 1.0f / swptd.tot_samples);
CLAMP4(wet_color, 0.0f, 1.0f);
wet_color = math::clamp(wet_color, 0.0f, 1.0f);
if (ss->cache->first_time) {
copy_v4_v4(ss->cache->wet_mix_prev_color, wet_color);
@ -318,7 +319,7 @@ void do_paint_brush(PaintModeSettings *paint_mode_settings,
ss->cache->wet_mix_prev_color,
ss->cache->paint_brush.wet_persistence);
copy_v4_v4(ss->cache->wet_mix_prev_color, wet_color);
CLAMP4(ss->cache->wet_mix_prev_color, 0.0f, 1.0f);
ss->cache->wet_mix_prev_color = math::clamp(ss->cache->wet_mix_prev_color, 0.0f, 1.0f);
}
}

View File

@ -382,15 +382,16 @@ static bool fsmenu_write_file_and_refresh_or_report_error(FSMenu *fsmenu,
{
/* NOTE: use warning instead of error here, because the bookmark operation may be part of
* other actions which should not cause the operator to fail entirely. */
const char *cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, nullptr);
if (UNLIKELY(!cfgdir)) {
const std::optional<std::string> cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG,
nullptr);
if (!cfgdir.has_value()) {
BKE_report(reports, RPT_ERROR, "Unable to create configuration directory to write bookmarks");
return false;
}
char filepath[FILE_MAX];
BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_BOOKMARK_FILE);
if (UNLIKELY(!fsmenu_write_file(fsmenu, filepath))) {
BLI_path_join(filepath, sizeof(filepath), cfgdir->c_str(), BLENDER_BOOKMARK_FILE);
if (!fsmenu_write_file(fsmenu, filepath)) {
BKE_reportf(reports, RPT_ERROR, "Unable to open or write bookmark file \"%s\"", filepath);
return false;
}

View File

@ -136,11 +136,13 @@ void ED_fsmenu_entry_set_path(FSMenuEntry *fsentry, const char *path)
fsentry->path = (path && path[0]) ? BLI_strdup(path) : nullptr;
BLI_path_join(tmp_name,
sizeof(tmp_name),
BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, nullptr),
BLENDER_BOOKMARK_FILE);
fsmenu_write_file(ED_fsmenu_get(), tmp_name);
const std::optional<std::string> user_config_dir = BKE_appdir_folder_id_create(
BLENDER_USER_CONFIG, nullptr);
if (user_config_dir.has_value()) {
BLI_path_join(tmp_name, sizeof(tmp_name), user_config_dir->c_str(), BLENDER_BOOKMARK_FILE);
fsmenu_write_file(ED_fsmenu_get(), tmp_name);
}
}
}
@ -200,11 +202,13 @@ void ED_fsmenu_entry_set_name(FSMenuEntry *fsentry, const char *name)
STRNCPY(fsentry->name, name);
}
BLI_path_join(tmp_name,
sizeof(tmp_name),
BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, nullptr),
BLENDER_BOOKMARK_FILE);
fsmenu_write_file(ED_fsmenu_get(), tmp_name);
const std::optional<std::string> user_config_dir = BKE_appdir_folder_id_create(
BLENDER_USER_CONFIG, nullptr);
if (user_config_dir.has_value()) {
BLI_path_join(tmp_name, sizeof(tmp_name), user_config_dir->c_str(), BLENDER_BOOKMARK_FILE);
fsmenu_write_file(ED_fsmenu_get(), tmp_name);
}
}
}

View File

@ -1023,15 +1023,15 @@ void ED_file_exit()
void ED_file_read_bookmarks()
{
const char *const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, nullptr);
const std::optional<std::string> cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, nullptr);
fsmenu_free();
fsmenu_read_system(ED_fsmenu_get(), true);
if (cfgdir) {
if (cfgdir.has_value()) {
char filepath[FILE_MAX];
BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_BOOKMARK_FILE);
BLI_path_join(filepath, sizeof(filepath), cfgdir->c_str(), BLENDER_BOOKMARK_FILE);
fsmenu_read_bookmarks(ED_fsmenu_get(), filepath);
}
}

View File

@ -6,6 +6,8 @@
* \ingroup spinfo
*/
#include <algorithm>
#include "MEM_guardedalloc.h"
#include "BLF_api.h"
@ -325,10 +327,10 @@ int textview_draw(TextViewContext *tvc,
const int mval[2] = {
(mval_init[0] == INT_MAX) ?
INT_MAX :
CLAMPIS(mval_init[0], tvc->draw_rect.xmin, tvc->draw_rect.xmax) - tvc->draw_rect.xmin,
std::clamp(mval_init[0], tvc->draw_rect.xmin, tvc->draw_rect.xmax) - tvc->draw_rect.xmin,
(mval_init[1] == INT_MAX) ?
INT_MAX :
CLAMPIS(mval_init[1], tvc->draw_rect.ymin, tvc->draw_rect.ymax) + tvc->scroll_ymin,
std::clamp(mval_init[1], tvc->draw_rect.ymin, tvc->draw_rect.ymax) + tvc->scroll_ymin,
};
if (r_mval_pick_offset != nullptr) {

View File

@ -2118,6 +2118,7 @@ enum eOutliner_PropModifierOps {
OL_MODIFIER_OP_TOGVIS = 1,
OL_MODIFIER_OP_TOGREN,
OL_MODIFIER_OP_DELETE,
OL_MODIFIER_OP_APPLY,
};
static void pchan_fn(int event, TreeElement *te, TreeStoreElem * /*tselem*/, void * /*arg*/)
@ -2308,11 +2309,18 @@ static void constraint_fn(int event, TreeElement *te, TreeStoreElem * /*tselem*/
}
}
static void modifier_fn(int event, TreeElement *te, TreeStoreElem * /*tselem*/, void *Carg)
struct ModifierFnArgs {
bContext *C;
ReportList *reports;
};
static void modifier_fn(int event, TreeElement *te, TreeStoreElem * /*tselem*/, void *arg)
{
bContext *C = (bContext *)Carg;
ModifierFnArgs *data = static_cast<ModifierFnArgs *>(arg);
bContext *C = data->C;
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
ModifierData *md = (ModifierData *)te->directdata;
Object *ob = (Object *)outliner_search_back(te, ID_OB);
@ -2327,10 +2335,18 @@ static void modifier_fn(int event, TreeElement *te, TreeStoreElem * /*tselem*/,
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
}
else if (event == OL_MODIFIER_OP_DELETE) {
ED_object_modifier_remove(nullptr, bmain, scene, ob, md);
ED_object_modifier_remove(data->reports, bmain, scene, ob, md);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER | NA_REMOVED, ob);
te->store_elem->flag &= ~TSE_SELECTED;
}
else if (event == OL_MODIFIER_OP_APPLY) {
ED_object_modifier_apply(
bmain, data->reports, depsgraph, scene, ob, md, MODIFIER_APPLY_DATA, false);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
DEG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
te->store_elem->flag &= ~TSE_SELECTED;
}
}
static void outliner_do_data_operation(
@ -3457,9 +3473,11 @@ void OUTLINER_OT_constraint_operation(wmOperatorType *ot)
* \{ */
static const EnumPropertyItem prop_modifier_op_types[] = {
{OL_MODIFIER_OP_APPLY, "APPLY", ICON_CHECKMARK, "Apply", ""},
{OL_MODIFIER_OP_DELETE, "DELETE", ICON_X, "Delete", ""},
RNA_ENUM_ITEM_SEPR,
{OL_MODIFIER_OP_TOGVIS, "TOGVIS", ICON_RESTRICT_VIEW_OFF, "Toggle Viewport Use", ""},
{OL_MODIFIER_OP_TOGREN, "TOGREN", ICON_RESTRICT_RENDER_OFF, "Toggle Render Use", ""},
{OL_MODIFIER_OP_DELETE, "DELETE", ICON_X, "Delete", ""},
{0, nullptr, 0, nullptr, nullptr},
};
@ -3468,9 +3486,13 @@ static int outliner_modifier_operation_exec(bContext *C, wmOperator *op)
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
eOutliner_PropModifierOps event = (eOutliner_PropModifierOps)RNA_enum_get(op->ptr, "type");
outliner_do_data_operation(space_outliner, TSE_MODIFIER, event, modifier_fn, C);
ModifierFnArgs args{};
args.C = C;
args.reports = op->reports;
if (event == OL_MODIFIER_OP_DELETE) {
outliner_do_data_operation(space_outliner, TSE_MODIFIER, event, modifier_fn, &args);
if (ELEM(event, OL_MODIFIER_OP_DELETE, OL_MODIFIER_OP_APPLY)) {
outliner_cleanup_tree(space_outliner);
}

View File

@ -3340,7 +3340,7 @@ static void text_cursor_set_apply(bContext *C, wmOperator *op, const wmEvent *ev
if (event->type == TIMER) {
text_cursor_set_to_pos(
st, region, CLAMPIS(event->mval[0], 0, region->winx), event->mval[1], true);
st, region, std::clamp(event->mval[0], 0, int(region->winx)), event->mval[1], true);
ED_space_text_scroll_to_cursor(st, region, false);
WM_event_add_notifier(C, NC_TEXT | ND_CURSOR, st->text);
}

View File

@ -1610,6 +1610,12 @@ static void view3d_header_region_listener(const wmRegionListenerParams *params)
ED_region_tag_redraw(region);
}
break;
case NC_MATERIAL:
/* For the canvas picker. */
if (wmn->data == ND_SHADING_LINKS) {
ED_region_tag_redraw(region);
}
break;
}
/* From top-bar, which ones are needed? split per header? */

View File

@ -6,6 +6,7 @@
* \ingroup edtransform
*/
#include <algorithm>
#include <cstdlib>
#include "MEM_guardedalloc.h"
@ -84,7 +85,7 @@ static void applyTimeSlideValue(TransInfo *t, float sval, float cval)
/* only apply to data if in range */
if ((sval > minx) && (sval < maxx)) {
float cvalc = CLAMPIS(cval, minx, maxx);
float cvalc = std::clamp(cval, minx, maxx);
float timefac;
float *dst;
float ival;

View File

@ -23,7 +23,8 @@ Path::Path()
{
// get the root directory
// soc
setRootDir(BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS, nullptr));
const std::optional<std::string> path = BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS, nullptr);
setRootDir(path.value_or(BKE_appdir_program_dir()));
_pInstance = this;
}

View File

@ -540,10 +540,11 @@ PyObject *Freestyle_Init()
PyDict_SetItemString(PySys_GetObject("modules"), module_definition.m_name, module);
// update 'sys.path' for Freestyle Python API modules
const char *const path = BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS, "freestyle");
if (path) {
const std::optional<std::string> path = BKE_appdir_folder_id(BLENDER_SYSTEM_SCRIPTS,
"freestyle");
if (path.has_value()) {
char modpath[FILE_MAX];
BLI_path_join(modpath, sizeof(modpath), path, "modules");
BLI_path_join(modpath, sizeof(modpath), path->c_str(), "modules");
PyObject *sys_path = PySys_GetObject("path"); /* borrow */
PyObject *py_modpath = PyC_UnicodeFromBytes(modpath);
PyList_Append(sys_path, py_modpath);

View File

@ -359,6 +359,7 @@ struct SStruct {
#define texelFetchOffset(__tex, __texel, __lod, __offset) \
_texelFetch_internal(__tex, __texel, __lod, __offset)
#define imageLoad(__image, __coord) _texelFetch_internal(__image, __coord, 0)
#define imageLoadFast(__image, __coord) _texelFetch_internal_fast(__image, __coord, 0)
#define texture2(__tex, __uv) _texture_internal_samp(__tex, __uv)
#define texture3(__tex, __uv, _bias) _texture_internal_bias(__tex, __uv, bias(float(_bias)))
#define textureLod(__tex, __uv, __lod) _texture_internal_level(__tex, __uv, level(float(__lod)))
@ -497,6 +498,14 @@ inline vec<S, 4> _texelFetch_internal(thread _mtl_combined_image_sampler_1d<S, A
}
}
template<typename S, typename T, access A>
inline vec<S, 4> _texelFetch_internal_fast(thread _mtl_combined_image_sampler_1d<S, A> tex,
T texel,
uint lod = 0)
{
return tex.texture->read(uint(texel));
}
template<typename S, typename T>
inline vec<S, 4> _texelFetch_internal(
const thread _mtl_combined_image_sampler_buffer<S, access::read> tex, T texel, uint lod = 0)
@ -510,6 +519,13 @@ inline vec<S, 4> _texelFetch_internal(
}
}
template<typename S, typename T>
inline vec<S, 4> _texelFetch_internal_fast(
const thread _mtl_combined_image_sampler_buffer<S, access::read> tex, T texel, uint lod = 0)
{
return tex.texture->read(uint(texel));
}
template<typename S, typename T, access A>
inline vec<S, 4> _texelFetch_internal(thread _mtl_combined_image_sampler_1d<S, A> tex,
T texel,
@ -526,6 +542,16 @@ inline vec<S, 4> _texelFetch_internal(thread _mtl_combined_image_sampler_1d<S, A
}
}
template<typename S, typename T, access A>
inline vec<S, 4> _texelFetch_internal_fast(thread _mtl_combined_image_sampler_1d<S, A> tex,
T texel,
uint lod,
T offset)
{
/* LODs not supported for 1d textures. This must be zero. */
return tex.texture->read(uint(texel + offset), 0);
}
template<typename S, typename T, access A>
inline vec<S, 4> _texelFetch_internal(thread _mtl_combined_image_sampler_1d_array<S, A> tex,
vec<T, 2> texel,
@ -546,6 +572,16 @@ inline vec<S, 4> _texelFetch_internal(thread _mtl_combined_image_sampler_1d_arra
}
}
template<typename S, typename T, access A>
inline vec<S, 4> _texelFetch_internal_fast(thread _mtl_combined_image_sampler_1d_array<S, A> tex,
vec<T, 2> texel,
uint lod,
vec<T, 2> offset = vec<T, 2>(0, 0))
{
/* LODs not supported for 1d textures. This must be zero. */
return tex.texture->read(uint(texel.x + offset.x), uint(texel.y + offset.y), 0);
}
template<typename S, typename T, access A>
inline vec<S, 4> _texelFetch_internal(thread _mtl_combined_image_sampler_2d<S, A> tex,
vec<T, 2> texel,
@ -565,6 +601,15 @@ inline vec<S, 4> _texelFetch_internal(thread _mtl_combined_image_sampler_2d<S, A
}
}
template<typename S, typename T, access A>
inline vec<S, 4> _texelFetch_internal_fast(thread _mtl_combined_image_sampler_2d<S, A> tex,
vec<T, 2> texel,
uint lod,
vec<T, 2> offset = vec<T, 2>(0))
{
return tex.texture->read(uint2(texel + offset), lod);
}
template<typename S, typename T, access A>
inline vec<S, 4> _texelFetch_internal(thread _mtl_combined_image_sampler_2d_array<S, A> tex,
vec<T, 3> texel,
@ -584,6 +629,15 @@ inline vec<S, 4> _texelFetch_internal(thread _mtl_combined_image_sampler_2d_arra
}
}
template<typename S, typename T, access A>
inline vec<S, 4> _texelFetch_internal_fast(thread _mtl_combined_image_sampler_2d_array<S, A> tex,
vec<T, 3> texel,
uint lod,
vec<T, 3> offset = vec<T, 3>(0))
{
return tex.texture->read(uint2(texel.xy + offset.xy), uint(texel.z + offset.z), lod);
}
template<typename S, typename T, access A>
inline vec<S, 4> _texelFetch_internal(thread _mtl_combined_image_sampler_3d<S, A> tex,
vec<T, 3> texel,
@ -604,6 +658,15 @@ inline vec<S, 4> _texelFetch_internal(thread _mtl_combined_image_sampler_3d<S, A
}
}
template<typename S, typename T, access A>
inline vec<S, 4> _texelFetch_internal_fast(thread _mtl_combined_image_sampler_3d<S, A> tex,
vec<T, 3> texel,
uint lod,
vec<T, 3> offset = vec<T, 3>(0))
{
return tex.texture->read(uint3(texel + offset), lod);
}
template<typename T, access A>
inline _msl_return_float _texelFetch_internal(
thread _mtl_combined_image_sampler_depth_2d<float, A> tex,
@ -626,6 +689,17 @@ inline _msl_return_float _texelFetch_internal(
}
}
template<typename T, access A>
inline _msl_return_float _texelFetch_internal_fast(
thread _mtl_combined_image_sampler_depth_2d<float, A> tex,
vec<T, 2> texel,
uint lod,
vec<T, 2> offset = vec<T, 2>(0))
{
_msl_return_float fl = {tex.texture->read(uint2(texel + offset), lod)};
return fl;
}
template<typename S, typename T, access A>
inline vec<S, 4> _texture_internal_samp(thread _mtl_combined_image_sampler_2d_array<S, A> tex,
vec<T, 3> texel,

View File

@ -12,6 +12,7 @@
/* Fast store variant macro. In GLSL this is the same as imageStore, but assumes no bounds
* checking. */
#define imageStoreFast imageStore
#define imageLoadFast imageLoad
/* Texture format tokens -- Type explicitness required by other Graphics APIs. */
#define depth2D sampler2D

View File

@ -653,7 +653,6 @@ static void colormanage_free_config()
void colormanagement_init()
{
const char *ocio_env;
const char *configdir;
char configfile[FILE_MAX];
OCIO_ConstConfigRcPtr *config = nullptr;
@ -669,10 +668,11 @@ void colormanagement_init()
}
if (config == nullptr) {
configdir = BKE_appdir_folder_id(BLENDER_DATAFILES, "colormanagement");
const std::optional<std::string> configdir = BKE_appdir_folder_id(BLENDER_DATAFILES,
"colormanagement");
if (configdir) {
BLI_path_join(configfile, sizeof(configfile), configdir, BCM_CONFIG_FILE);
if (configdir.has_value()) {
BLI_path_join(configfile, sizeof(configfile), configdir->c_str(), BCM_CONFIG_FILE);
config = OCIO_configCreateFromFile(configfile);
}

View File

@ -66,7 +66,7 @@ const char *imb_ext_image[] = {
const char *imb_ext_movie[] = {
".avi", ".flc", ".mov", ".movie", ".mp4", ".m4v", ".m2v", ".m2t", ".m2ts", ".mts",
".ts", ".mv", ".avs", ".wmv", ".ogv", ".ogg", ".r3d", ".dv", ".mpeg", ".mpg",
".mpg2", ".vob", ".mkv", ".flv", ".divx", ".xvid", ".mxf", ".webm", nullptr,
".mpg2", ".vob", ".mkv", ".flv", ".divx", ".xvid", ".mxf", ".webm", ".gif", nullptr,
};
/** Sort of wrong having audio extensions in imbuf. */

View File

@ -11,6 +11,7 @@
#include "BLI_math_color.h"
#include "BLI_math_matrix.h"
#include "BLI_math_vector.h"
#include "BLI_math_vector.hh"
#include "DNA_gpencil_legacy_types.h"
#include "DNA_material_types.h"
@ -287,11 +288,11 @@ void GpencilExporterPDF::color_set(bGPDlayer *gpl, const bool do_fill)
HPDF_Page_GSave(page_);
HPDF_ExtGState gstate = (need_state) ? HPDF_CreateExtGState(pdf_) : nullptr;
float col[3];
float3 col;
if (do_fill) {
interp_v3_v3v3(col, fill_color_, gpl->tintcolor, gpl->tintcolor[3]);
linearrgb_to_srgb_v3_v3(col, col);
CLAMP3(col, 0.0f, 1.0f);
col = math::clamp(col, 0.0f, 1.0f);
HPDF_Page_SetRGBFill(page_, col[0], col[1], col[2]);
if (gstate) {
HPDF_ExtGState_SetAlphaFill(gstate, clamp_f(fill_opacity, 0.0f, 1.0f));
@ -300,7 +301,7 @@ void GpencilExporterPDF::color_set(bGPDlayer *gpl, const bool do_fill)
else {
interp_v3_v3v3(col, stroke_color_, gpl->tintcolor, gpl->tintcolor[3]);
linearrgb_to_srgb_v3_v3(col, col);
CLAMP3(col, 0.0f, 1.0f);
col = math::clamp(col, 0.0f, 1.0f);
HPDF_Page_SetRGBFill(page_, col[0], col[1], col[2]);
HPDF_Page_SetRGBStroke(page_, col[0], col[1], col[2]);

View File

@ -92,7 +92,12 @@
.pose_smooth_iterations = 4, \
.pose_ik_segments = 1, \
.hardness = 0.0f, \
\
.automasking_boundary_edges_propagation_steps = 1, \
.automasking_start_normal_limit = 0.34906585f, /* 20 degrees */ \
.automasking_start_normal_falloff = 0.25f, \
.automasking_view_normal_limit = 1.570796, /* 90 degrees */ \
.automasking_view_normal_falloff = 0.25f, \
.automasking_cavity_blur_steps = 0,\
.automasking_cavity_factor = 1.0f,\
\

View File

@ -317,6 +317,11 @@ typedef struct Brush {
int automasking_flags;
int automasking_boundary_edges_propagation_steps;
float automasking_start_normal_limit;
float automasking_start_normal_falloff;
float automasking_view_normal_limit;
float automasking_view_normal_falloff;
int elastic_deform_type;
float elastic_deform_volume_preservation;

View File

@ -829,4 +829,11 @@
.color = {1.0f, 1.0f, 1.0f}, \
}
#define _DNA_DEFAULT_GreasePencilSmoothModifierData \
{ \
.flag = MOD_GREASE_PENCIL_SMOOTH_MOD_LOCATION, \
.factor = 1.0f, \
.step = 1, \
}
/* clang-format off */

View File

@ -97,6 +97,7 @@ typedef enum ModifierType {
eModifierType_GreasePencilSubdiv = 62,
eModifierType_GreasePencilColor = 63,
eModifierType_GreasePencilTint = 64,
eModifierType_GreasePencilSmooth = 65,
NUM_MODIFIER_TYPES,
} ModifierType;
@ -2607,3 +2608,27 @@ typedef enum GreasePencilTintModifierFlag {
/* Use vertex group as factors instead of influence. */
MOD_GREASE_PENCIL_TINT_USE_WEIGHT_AS_FACTOR = (1 << 0),
} GreasePencilTintModifierFlag;
typedef struct GreasePencilSmoothModifierData {
ModifierData modifier;
GreasePencilModifierInfluenceData influence;
/** `eGreasePencilSmooth_Flag. */
int flag;
/** Factor of smooth. */
float factor;
/** How many times apply smooth. */
int step;
char _pad[4];
void *_pad1;
} GreasePencilSmoothModifierData;
typedef enum eGreasePencilSmooth_Flag {
MOD_GREASE_PENCIL_SMOOTH_OPEN_INFLUENCE_PANEL = (1 << 0),
MOD_GREASE_PENCIL_SMOOTH_MOD_LOCATION = (1 << 1),
MOD_GREASE_PENCIL_SMOOTH_MOD_STRENGTH = (1 << 2),
MOD_GREASE_PENCIL_SMOOTH_MOD_THICKNESS = (1 << 3),
MOD_GREASE_PENCIL_SMOOTH_MOD_UV = (1 << 4),
MOD_GREASE_PENCIL_SMOOTH_KEEP_SHAPE = (1 << 5),
MOD_GREASE_PENCIL_SMOOTH_SMOOTH_ENDS = (1 << 6),
} eGreasePencilSmooth_Flag;

View File

@ -53,7 +53,7 @@
.dampfac = 1.0f, \
.gravityfac = 1.0f, \
.fieldfac = 1.0f, \
.brush_map_mode = MTEX_MAP_MODE_TILED, \
.brush_map_mode = MTEX_MAP_MODE_VIEW, \
.random_angle = 2.0f * (float)M_PI, \
.brush_angle_mode = 0, \
} \

View File

@ -623,6 +623,10 @@ typedef struct bUserExtensionRepo {
*/
char module[48];
/**
* The "local" directory where extensions are stored.
* When unset, use `{BLENDER_USER_SCRIPTS}/extensions/{bUserExtensionRepo::module}`.
*/
char dirpath[1024]; /* FILE_MAX */
char remote_path[1024]; /* FILE_MAX */

View File

@ -294,6 +294,9 @@ SDNA_DEFAULT_DECL_STRUCT(WeldModifierData);
SDNA_DEFAULT_DECL_STRUCT(WireframeModifierData);
SDNA_DEFAULT_DECL_STRUCT(GreasePencilSubdivModifierData);
/* Grease Pencil 3.0 modifiers. */
SDNA_DEFAULT_DECL_STRUCT(GreasePencilSmoothModifierData);
/* DNA_gpencil_modifier_defaults.h */
SDNA_DEFAULT_DECL_STRUCT(ArmatureGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(ArrayGpencilModifierData);
@ -542,6 +545,9 @@ const void *DNA_default_table[SDNA_TYPE_MAX] = {
SDNA_DEFAULT_DECL(WireframeModifierData),
SDNA_DEFAULT_DECL(GreasePencilSubdivModifierData),
/* Grease Pencil 3.0 defaults. */
SDNA_DEFAULT_DECL(GreasePencilSmoothModifierData),
/* DNA_gpencil_modifier_defaults.h */
SDNA_DEFAULT_DECL(ArmatureGpencilModifierData),
SDNA_DEFAULT_DECL(ArrayGpencilModifierData),

View File

@ -179,7 +179,7 @@ enum PropertySubType {
/* Make sure enums are updated with these */
/* HIGHEST FLAG IN USE: 1 << 31
* FREE FLAGS: 9, 11, 13, 14, 15. */
* FREE FLAGS: 11, 13, 14, 15. */
enum PropertyFlag {
/**
* Editable means the property is editable in the user
@ -300,6 +300,12 @@ enum PropertyFlag {
*/
PROP_NO_DEG_UPDATE = (1 << 30),
/**
* Property needs to ensure evaluated data-blocks are in sync with their original counter-part
* but the property does not affect evaluation itself.
*/
PROP_DEG_SYNC_ONLY = (1 << 9),
/**
* File-paths that refer to output get a special treatment such
* as having the +/- operators available in the file browser.

View File

@ -1101,10 +1101,10 @@ static void rna_clamp_value(FILE *f, PropertyRNA *prop, int array)
if (iprop->hardmin != INT_MIN || iprop->hardmax != INT_MAX || iprop->range) {
if (array) {
fprintf(f, "CLAMPIS(values[i], ");
fprintf(f, "std::clamp(values[i], ");
}
else {
fprintf(f, "CLAMPIS(value, ");
fprintf(f, "std::clamp(value, ");
}
if (iprop->range) {
fprintf(f, "prop_clamp_min, prop_clamp_max);\n");
@ -1123,10 +1123,10 @@ static void rna_clamp_value(FILE *f, PropertyRNA *prop, int array)
if (fprop->hardmin != -FLT_MAX || fprop->hardmax != FLT_MAX || fprop->range) {
if (array) {
fprintf(f, "CLAMPIS(values[i], ");
fprintf(f, "std::clamp(values[i], ");
}
else {
fprintf(f, "CLAMPIS(value, ");
fprintf(f, "std::clamp(value, ");
}
if (fprop->range) {
fprintf(f, "prop_clamp_min, prop_clamp_max);\n");
@ -1466,7 +1466,7 @@ static char *rna_def_property_set_func(
/* C++ may require casting to an enum type. */
fprintf(f, "#ifdef __cplusplus\n");
fprintf(f,
/* If #rna_clamp_value() adds an expression like `CLAMPIS(...)`
/* If #rna_clamp_value() adds an expression like `std::clamp(...)`
* (instead of an `lvalue`), #decltype() yields a reference,
* so that has to be removed. */
" data->%s = %s(std::remove_reference_t<decltype(data->%s)>)",
@ -4848,6 +4848,7 @@ static void rna_generate(BlenderRNA *brna, FILE *f, const char *filename, const
fprintf(f, "#include <limits>\n");
fprintf(f, "#include <string.h>\n\n");
fprintf(f, "#include <stddef.h>\n\n");
fprintf(f, "#include <algorithm>\n\n");
fprintf(f, "#include \"MEM_guardedalloc.h\"\n\n");

View File

@ -2276,7 +2276,12 @@ static void rna_property_update(
if (ptr->owner_id != nullptr && ((prop->flag & PROP_NO_DEG_UPDATE) == 0)) {
const short id_type = GS(ptr->owner_id->name);
if (ID_TYPE_IS_COW(id_type)) {
DEG_id_tag_update(ptr->owner_id, ID_RECALC_COPY_ON_WRITE | ID_RECALC_PARAMETERS);
if (prop->flag & PROP_DEG_SYNC_ONLY) {
DEG_id_tag_update(ptr->owner_id, ID_RECALC_COPY_ON_WRITE);
}
else {
DEG_id_tag_update(ptr->owner_id, ID_RECALC_COPY_ON_WRITE | ID_RECALC_PARAMETERS);
}
}
}
/* End message bus. */

View File

@ -3409,6 +3409,19 @@ static void rna_def_brush(BlenderRNA *brna)
"Affect only vertices with a similar normal to where the stroke starts");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "automasking_start_normal_limit", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, nullptr, "automasking_start_normal_limit");
RNA_def_property_range(prop, 0.0001f, M_PI);
RNA_def_property_ui_text(prop, "Area Normal Limit", "The range of angles that will be affected");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "automasking_start_normal_falloff", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, nullptr, "automasking_start_normal_falloff");
RNA_def_property_range(prop, 0.0001f, 1.0f);
RNA_def_property_ui_text(
prop, "Area Normal Falloff", "Extend the angular range with a falloff gradient");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "use_automasking_view_normal", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, nullptr, "automasking_flags", BRUSH_AUTOMASKING_VIEW_NORMAL);
RNA_def_property_ui_text(
@ -3424,6 +3437,19 @@ static void rna_def_brush(BlenderRNA *brna)
"Only affect vertices that are not occluded by other faces. (Slower performance)");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "automasking_view_normal_limit", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, nullptr, "automasking_view_normal_limit");
RNA_def_property_range(prop, 0.0001f, M_PI);
RNA_def_property_ui_text(prop, "View Normal Limit", "The range of angles that will be affected");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "automasking_view_normal_falloff", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, nullptr, "automasking_view_normal_falloff");
RNA_def_property_range(prop, 0.0001f, 1.0f);
RNA_def_property_ui_text(
prop, "View Normal Falloff", "Extend the angular range with a falloff gradient");
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "use_scene_spacing", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, nullptr, "flag");
RNA_def_property_enum_items(prop, brush_spacing_unit_items);

View File

@ -183,6 +183,8 @@ static const EnumPropertyItem rna_enum_driver_target_context_property_items[] =
#ifdef RNA_RUNTIME
# include <algorithm>
# include "WM_api.hh"
static StructRNA *rna_FModifierType_refine(PointerRNA *ptr)
@ -1026,7 +1028,7 @@ static void rna_FModifierStepped_frame_start_set(PointerRNA *ptr, float value)
float prop_clamp_min = -FLT_MAX, prop_clamp_max = FLT_MAX, prop_soft_min, prop_soft_max;
rna_FModifierStepped_start_frame_range(
ptr, &prop_clamp_min, &prop_clamp_max, &prop_soft_min, &prop_soft_max);
value = CLAMPIS(value, prop_clamp_min, prop_clamp_max);
value = std::clamp(value, prop_clamp_min, prop_clamp_max);
/* Need to set both step-data's start/end and the start/end on the base-data,
* or else Restrict-Range doesn't work due to RNA-property shadowing (#52009)
@ -1043,7 +1045,7 @@ static void rna_FModifierStepped_frame_end_set(PointerRNA *ptr, float value)
float prop_clamp_min = -FLT_MAX, prop_clamp_max = FLT_MAX, prop_soft_min, prop_soft_max;
rna_FModifierStepped_end_frame_range(
ptr, &prop_clamp_min, &prop_clamp_max, &prop_soft_min, &prop_soft_max);
value = CLAMPIS(value, prop_clamp_min, prop_clamp_max);
value = std::clamp(value, prop_clamp_min, prop_clamp_max);
/* Need to set both step-data's start/end and the start/end on the base-data,
* or else Restrict-Range doesn't work due to RNA-property shadowing (#52009)

View File

@ -53,6 +53,8 @@ static const EnumPropertyItem image_source_items[] = {
#ifdef RNA_RUNTIME
# include <algorithm>
# include "BLI_math_base.h"
# include "BLI_math_vector.h"
@ -132,7 +134,7 @@ static void rna_Image_generated_width_set(PointerRNA *ptr, int value)
{
Image *ima = (Image *)ptr->data;
ImageTile *base_tile = BKE_image_get_tile(ima, 0);
base_tile->gen_x = CLAMPIS(value, 1, 65536);
base_tile->gen_x = std::clamp(value, 1, 65536);
}
static int rna_Image_generated_height_get(PointerRNA *ptr)
@ -146,7 +148,7 @@ static void rna_Image_generated_height_set(PointerRNA *ptr, int value)
{
Image *ima = (Image *)ptr->data;
ImageTile *base_tile = BKE_image_get_tile(ima, 0);
base_tile->gen_y = CLAMPIS(value, 1, 65536);
base_tile->gen_y = std::clamp(value, 1, 65536);
}
static bool rna_Image_generated_float_get(PointerRNA *ptr)
@ -180,7 +182,7 @@ void rna_Image_generated_color_set(PointerRNA *ptr, const float values[4])
Image *ima = (Image *)(ptr->data);
ImageTile *base_tile = BKE_image_get_tile(ima, 0);
for (uint i = 0; i < 4; i++) {
base_tile->gen_color[i] = CLAMPIS(values[i], 0.0f, FLT_MAX);
base_tile->gen_color[i] = std::clamp(values[i], 0.0f, FLT_MAX);
}
}

Some files were not shown because too many files have changed in this diff Show More