Eevee-Next: World Reflective Light #108149

Merged
Jeroen Bakker merged 33 commits from Jeroen-Bakker/blender:eevee-next-world-shader into main 2023-06-29 15:25:04 +02:00
190 changed files with 2815 additions and 1688 deletions
Showing only changes of commit a72e1430b2 - Show all commits

View File

@ -10,9 +10,9 @@ CCL_NAMESPACE_BEGIN
ccl_device float spot_light_attenuation(const ccl_global KernelSpotLight *spot, float3 ray)
{
const float3 scaled_ray = safe_normalize(
make_float3(dot(ray, spot->axis_u), dot(ray, spot->axis_v), dot(ray, spot->dir)) /
spot->len);
const float3 scaled_ray = safe_normalize(make_float3(dot(ray, spot->scaled_axis_u),
dot(ray, spot->scaled_axis_v),
dot(ray, spot->dir * spot->inv_len_z)));
return smoothstepf((scaled_ray.z - spot->cos_half_spot_angle) * spot->spot_smooth);
}

View File

@ -24,14 +24,14 @@
\
for (int i = 0; i <= ceil(params.detail); ++i) { \
VoronoiOutput octave; \
if (params.feature == "f1") { \
octave = voronoi_f1(params, coord * scale); \
if (params.feature == "f2") { \
octave = voronoi_f2(params, coord * scale); \
} \
else if (params.feature == "smooth_f1") { \
else if (params.feature == "smooth_f1" && params.smoothness != 0.0) { \
octave = voronoi_smooth_f1(params, coord * scale); \
} \
else { \
octave = voronoi_f2(params, coord * scale); \
octave = voronoi_f1(params, coord * scale); \
} \
\
if (zero_input) { \

View File

@ -878,11 +878,12 @@ ccl_device VoronoiOutput fractal_voronoi_x_fx(ccl_private const VoronoiParams &p
params.lacunarity == 0.0f;
for (int i = 0; i <= ceilf(params.detail); ++i) {
VoronoiOutput octave = (params.feature == NODE_VORONOI_F1) ?
voronoi_f1(params, coord * scale) :
(params.feature == NODE_VORONOI_SMOOTH_F1) ?
VoronoiOutput octave = (params.feature == NODE_VORONOI_F2) ?
voronoi_f2(params, coord * scale) :
(params.feature == NODE_VORONOI_SMOOTH_F1 &&
params.smoothness != 0.0f) ?
voronoi_smooth_f1(params, coord * scale) :
voronoi_f2(params, coord * scale);
voronoi_f1(params, coord * scale);
if (zero_input) {
max_amplitude = 1.0f;

View File

@ -1350,14 +1350,15 @@ typedef struct KernelCurveSegment {
static_assert_align(KernelCurveSegment, 8);
typedef struct KernelSpotLight {
packed_float3 axis_u;
packed_float3 scaled_axis_u;
float radius;
packed_float3 axis_v;
packed_float3 scaled_axis_v;
float invarea;
packed_float3 dir;
float cos_half_spot_angle;
packed_float3 len;
float inv_len_z;
float spot_smooth;
float pad[2];
} KernelSpotLight;
/* PointLight is SpotLight with only radius and invarea being used. */

View File

@ -1309,13 +1309,12 @@ void LightManager::device_update_lights(Device *device, DeviceScene *dscene, Sce
else if (light->light_type == LIGHT_SPOT) {
shader_id &= ~SHADER_AREA_LIGHT;
float3 len;
float3 axis_u = normalize_len(light->axisu, &len.x);
float3 axis_v = normalize_len(light->axisv, &len.y);
float3 dir = normalize_len(light->dir, &len.z);
if (len.z == 0.0f) {
dir = zero_float3();
}
/* Scale axes to accommodate non-uniform scaling. */
float3 scaled_axis_u = light->axisu / len_squared(light->axisu);
float3 scaled_axis_v = light->axisv / len_squared(light->axisv);
float len_z;
/* Keep direction normalized. */
float3 dir = safe_normalize_len(light->dir, &len_z);
float radius = light->size;
float invarea = (light->normalize && radius > 0.0f) ? 1.0f / (M_PI_F * radius * radius) :
@ -1327,13 +1326,13 @@ void LightManager::device_update_lights(Device *device, DeviceScene *dscene, Sce
shader_id |= SHADER_USE_MIS;
klights[light_index].co = co;
klights[light_index].spot.axis_u = axis_u;
klights[light_index].spot.scaled_axis_u = scaled_axis_u;
klights[light_index].spot.radius = radius;
klights[light_index].spot.axis_v = axis_v;
klights[light_index].spot.scaled_axis_v = scaled_axis_v;
klights[light_index].spot.invarea = invarea;
klights[light_index].spot.dir = dir;
klights[light_index].spot.cos_half_spot_angle = cos_half_spot_angle;
klights[light_index].spot.len = len;
klights[light_index].spot.inv_len_z = 1.0f / len_z;
klights[light_index].spot.spot_smooth = spot_smooth;
}

View File

@ -1157,7 +1157,6 @@ classes = (
NODE_PT_node_color_presets,
NODE_PT_active_node_generic,
NODE_PT_active_node_color,
NODE_PT_active_node_properties,
NODE_PT_texture_mapping,
NODE_PT_active_tool,
NODE_PT_backdrop,
@ -1171,6 +1170,7 @@ classes = (
NODE_PT_panels,
NODE_UL_simulation_zone_items,
NODE_PT_simulation_zone_items,
NODE_PT_active_node_properties,
node_panel(EEVEE_MATERIAL_PT_settings),
node_panel(MATERIAL_PT_viewport),

View File

@ -68,6 +68,20 @@ typedef struct EditFont {
} EditFont;
typedef enum eEditFontMode {
FO_EDIT = 0,
FO_CURS = 1,
FO_CURSUP = 2,
FO_CURSDOWN = 3,
FO_DUPLI = 4,
FO_PAGEUP = 8,
FO_PAGEDOWN = 9,
FO_SELCHANGE = 10,
} eEditFontMode;
/* BKE_vfont_to_curve will move the cursor in these cases */
#define FO_CURS_IS_MOTION(mode) (ELEM(mode, FO_CURSUP, FO_CURSDOWN, FO_PAGEUP, FO_PAGEDOWN))
bool BKE_vfont_is_builtin(const struct VFont *vfont);
void BKE_vfont_builtin_register(const void *mem, int size);
@ -83,20 +97,20 @@ struct VFont *BKE_vfont_load_exists(struct Main *bmain, const char *filepath);
bool BKE_vfont_to_curve_ex(struct Object *ob,
struct Curve *cu,
int mode,
eEditFontMode mode,
struct ListBase *r_nubase,
const char32_t **r_text,
int *r_text_len,
bool *r_text_free,
struct CharTrans **r_chartransdata);
bool BKE_vfont_to_curve_nubase(struct Object *ob, int mode, struct ListBase *r_nubase);
bool BKE_vfont_to_curve_nubase(struct Object *ob, eEditFontMode mode, struct ListBase *r_nubase);
int BKE_vfont_cursor_to_text_index(struct Object *ob, float cursor_location[2]);
/**
* \warning Expects to have access to evaluated data (i.e. passed object should be evaluated one).
*/
bool BKE_vfont_to_curve(struct Object *ob, int mode);
bool BKE_vfont_to_curve(struct Object *ob, eEditFontMode mode);
void BKE_vfont_build_char(struct Curve *cu,
struct ListBase *nubase,
unsigned int character,

View File

@ -151,8 +151,8 @@ set(SRC
intern/gpencil_legacy.c
intern/gpencil_modifier_legacy.c
intern/gpencil_update_cache_legacy.c
intern/grease_pencil_convert_legacy.cc
intern/grease_pencil.cc
intern/grease_pencil_convert_legacy.cc
intern/icons.cc
intern/icons_rasterize.c
intern/idprop.c
@ -833,6 +833,7 @@ if(WITH_GTESTS)
intern/cryptomatte_test.cc
intern/curves_geometry_test.cc
intern/fcurve_test.cc
intern/grease_pencil_test.cc
intern/idprop_serialize_test.cc
intern/image_partial_update_test.cc
intern/image_test.cc
@ -843,7 +844,6 @@ if(WITH_GTESTS)
intern/lib_remap_test.cc
intern/nla_test.cc
intern/tracking_test.cc
intern/grease_pencil_test.cc
)
set(TEST_INC
../editors/include

View File

@ -1165,7 +1165,7 @@ static ImBuf *add_ibuf_for_tile(Image *ima, ImageTile *tile)
if (ibuf != nullptr) {
rect = ibuf->byte_buffer.data;
IMB_colormanagement_assign_rect_colorspace(ibuf, ima->colorspace_settings.name);
IMB_colormanagement_assign_byte_colorspace(ibuf, ima->colorspace_settings.name);
}
copy_v4_v4(fill_color, tile->gen_color);
@ -1264,8 +1264,8 @@ static void image_colorspace_from_imbuf(Image *image, const ImBuf *ibuf)
const char *colorspace_name = nullptr;
if (ibuf->float_buffer.data) {
if (ibuf->float_colorspace) {
colorspace_name = IMB_colormanagement_colorspace_get_name(ibuf->float_colorspace);
if (ibuf->float_buffer.colorspace) {
colorspace_name = IMB_colormanagement_colorspace_get_name(ibuf->float_buffer.colorspace);
}
else {
colorspace_name = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_FLOAT);
@ -1273,8 +1273,8 @@ static void image_colorspace_from_imbuf(Image *image, const ImBuf *ibuf)
}
if (ibuf->byte_buffer.data && !colorspace_name) {
if (ibuf->rect_colorspace) {
colorspace_name = IMB_colormanagement_colorspace_get_name(ibuf->rect_colorspace);
if (ibuf->byte_buffer.colorspace) {
colorspace_name = IMB_colormanagement_colorspace_get_name(ibuf->byte_buffer.colorspace);
}
else {
colorspace_name = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_BYTE);
@ -3635,12 +3635,12 @@ void BKE_image_set_filepath_from_tile_number(char *filepath,
}
if (tile_format == UDIM_TILE_FORMAT_UDIM) {
BLI_sprintf(filepath, pattern, tile_number);
BLI_snprintf(filepath, FILE_MAX, pattern, tile_number);
}
else if (tile_format == UDIM_TILE_FORMAT_UVTILE) {
int u = ((tile_number - 1001) % 10);
int v = ((tile_number - 1001) / 10);
BLI_sprintf(filepath, pattern, u + 1, v + 1);
BLI_snprintf(filepath, FILE_MAX, pattern, u + 1, v + 1);
}
}
@ -4442,7 +4442,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **r_loc
*/
if (ibuf->byte_buffer.data != byte_buffer->data) {
const char *colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_BYTE);
IMB_colormanagement_assign_rect_colorspace(ibuf, colorspace);
IMB_colormanagement_assign_byte_colorspace(ibuf, colorspace);
}
/* invalidate color managed buffers if render result changed */

View File

@ -769,11 +769,11 @@ static void gpu_texture_update_from_ibuf(
}
else {
/* Byte image is in original colorspace from the file, and may need conversion. */
if (IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) {
if (IMB_colormanagement_space_is_data(ibuf->byte_buffer.colorspace)) {
/* Non-color data, just store buffer as is. */
}
else if (IMB_colormanagement_space_is_srgb(ibuf->rect_colorspace) ||
IMB_colormanagement_space_is_scene_linear(ibuf->rect_colorspace))
else if (IMB_colormanagement_space_is_srgb(ibuf->byte_buffer.colorspace) ||
IMB_colormanagement_space_is_scene_linear(ibuf->byte_buffer.colorspace))
{
/* sRGB or scene linear, store as byte texture that the GPU can decode directly. */
rect = (uchar *)MEM_mallocN(sizeof(uchar[4]) * w * h, __func__);

View File

@ -78,7 +78,7 @@
#include "NOD_common.h"
#include "NOD_composite.h"
#include "NOD_geometry.h"
#include "NOD_geometry.hh"
#include "NOD_geometry_nodes_lazy_function.hh"
#include "NOD_node_declaration.hh"
#include "NOD_register.hh"

View File

@ -200,8 +200,9 @@ static void find_logical_origins_for_socket_recursive(
sockets_in_current_chain.pop_last();
}
static void update_logical_origins(const bNodeTree &ntree)
static void update_logically_linked_sockets(const bNodeTree &ntree)
{
/* Compute logically linked sockets to inputs. */
bNodeTreeRuntime &tree_runtime = *ntree.runtime;
Span<bNode *> nodes = tree_runtime.nodes_by_id;
threading::parallel_for(nodes.index_range(), 128, [&](const IndexRange range) {
@ -220,6 +221,26 @@ static void update_logical_origins(const bNodeTree &ntree)
}
}
});
/* Clear logically linked sockets to outputs. */
threading::parallel_for(nodes.index_range(), 128, [&](const IndexRange range) {
for (const int i : range) {
bNode &node = *nodes[i];
for (bNodeSocket *socket : node.runtime->outputs) {
socket->runtime->logically_linked_sockets.clear();
}
}
});
/* Compute logically linked sockets to outputs using the previously computed logically linked
* sockets to inputs. */
for (const bNode *node : nodes) {
for (bNodeSocket *input_socket : node->runtime->inputs) {
for (bNodeSocket *output_socket : input_socket->runtime->logically_linked_sockets) {
output_socket->runtime->logically_linked_sockets.append(input_socket);
}
}
}
}
static void update_nodes_by_type(const bNodeTree &ntree)
@ -499,7 +520,7 @@ static void ensure_topology_cache(const bNodeTree &ntree)
update_nodes_by_type(ntree);
threading::parallel_invoke(
tree_runtime.nodes_by_id.size() > 32,
[&]() { update_logical_origins(ntree); },
[&]() { update_logically_linked_sockets(ntree); },
[&]() { update_sockets_by_identifier(ntree); },
[&]() {
update_toposort(ntree,

View File

@ -3133,19 +3133,23 @@ void BKE_ptcache_quick_cache_all(Main *bmain, Scene *scene, ViewLayer *view_laye
BKE_ptcache_bake(&baker);
}
static void ptcache_dt_to_str(char *str, double dtime)
static void ptcache_dt_to_str(char *str, size_t str_maxncpy, double dtime)
{
if (dtime > 60.0) {
if (dtime > 3600.0) {
BLI_sprintf(
str, "%ih %im %is", (int)(dtime / 3600), (int)(dtime / 60) % 60, ((int)dtime) % 60);
BLI_snprintf(str,
str_maxncpy,
"%ih %im %is",
(int)(dtime / 3600),
(int)(dtime / 60) % 60,
((int)dtime) % 60);
}
else {
BLI_sprintf(str, "%im %is", (int)(dtime / 60) % 60, ((int)dtime) % 60);
BLI_snprintf(str, str_maxncpy, "%im %is", (int)(dtime / 60) % 60, ((int)dtime) % 60);
}
}
else {
BLI_sprintf(str, "%is", ((int)dtime) % 60);
BLI_snprintf(str, str_maxncpy, "%is", ((int)dtime) % 60);
}
}
@ -3300,9 +3304,9 @@ void BKE_ptcache_bake(PTCacheBaker *baker)
if (use_timer || fetd > 60.0) {
use_timer = true;
ptcache_dt_to_str(cur, ctime - ptime);
ptcache_dt_to_str(run, ctime - stime);
ptcache_dt_to_str(etd, fetd);
ptcache_dt_to_str(cur, sizeof(cur), ctime - ptime);
ptcache_dt_to_str(run, sizeof(run), ctime - stime);
ptcache_dt_to_str(etd, sizeof(etd), fetd);
printf("Baked for %s, current frame: %i/%i (%.3fs), ETC: %s\r",
run,
@ -3325,7 +3329,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker)
if (use_timer) {
/* start with newline because of \r above */
ptcache_dt_to_str(run, PIL_check_seconds_timer() - stime);
ptcache_dt_to_str(run, sizeof(run), PIL_check_seconds_timer() - stime);
printf("\nBake %s %s (%i frames simulated).\n",
(cancel ? "canceled after" : "finished in"),
run,

View File

@ -40,7 +40,7 @@
#include "BKE_simulation.h"
#include "BKE_simulation_state.hh"
#include "NOD_geometry.h"
#include "NOD_geometry.hh"
#include "BLI_map.hh"
#include "BLT_translation.h"

View File

@ -1730,8 +1730,11 @@ static void txt_combine_lines(Text *text, TextLine *linea, TextLine *lineb)
tmp = MEM_mallocN(linea->len + lineb->len + 1, "textline_string");
s = tmp;
s += BLI_strcpy_rlen(s, linea->line);
s += BLI_strcpy_rlen(s, lineb->line);
memcpy(s, linea->line, linea->len);
s += linea->len;
memcpy(s, lineb->line, lineb->len);
s += lineb->len;
*s = '\0';
(void)s;
make_new_line(linea, tmp);

View File

@ -2872,8 +2872,8 @@ ImBuf *BKE_tracking_get_plane_imbuf(const ImBuf *frame_ibuf,
&warped_position_y);
}
plane_ibuf->rect_colorspace = frame_ibuf->rect_colorspace;
plane_ibuf->float_colorspace = frame_ibuf->float_colorspace;
plane_ibuf->byte_buffer.colorspace = frame_ibuf->byte_buffer.colorspace;
plane_ibuf->float_buffer.colorspace = frame_ibuf->float_buffer.colorspace;
return plane_ibuf;
}

View File

@ -792,7 +792,7 @@ static float vfont_descent(const VFontData *vfd)
static bool vfont_to_curve(Object *ob,
Curve *cu,
int mode,
const eEditFontMode mode,
VFontToCurveIter *iter_data,
VFontCursor_Params *cursor_params,
ListBase *r_nubase,
@ -1501,6 +1501,12 @@ static bool vfont_to_curve(Object *ob,
case FO_PAGEDOWN:
lnr = ct->linenr + 10;
break;
/* Ignored. */
case FO_EDIT:
case FO_CURS:
case FO_DUPLI:
case FO_SELCHANGE:
break;
}
cnr = ct->charnr;
/* Seek for char with `lnr` & `cnr`. */
@ -1826,7 +1832,7 @@ finally:
bool BKE_vfont_to_curve_ex(Object *ob,
Curve *cu,
int mode,
const eEditFontMode mode,
ListBase *r_nubase,
const char32_t **r_text,
int *r_text_len,
@ -1880,14 +1886,14 @@ int BKE_vfont_cursor_to_text_index(Object *ob, float cursor_location[2])
#undef FONT_TO_CURVE_SCALE_ITERATIONS
#undef FONT_TO_CURVE_SCALE_THRESHOLD
bool BKE_vfont_to_curve_nubase(Object *ob, int mode, ListBase *r_nubase)
bool BKE_vfont_to_curve_nubase(Object *ob, const eEditFontMode mode, ListBase *r_nubase)
{
BLI_assert(ob->type == OB_FONT);
return BKE_vfont_to_curve_ex(ob, ob->data, mode, r_nubase, NULL, NULL, NULL, NULL);
}
bool BKE_vfont_to_curve(Object *ob, int mode)
bool BKE_vfont_to_curve(Object *ob, const eEditFontMode mode)
{
Curve *cu = ob->data;

View File

@ -108,9 +108,6 @@ size_t BLI_strncpy_rlen(char *__restrict dst,
const char *__restrict src,
size_t dst_maxncpy) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2);
size_t BLI_strcpy_rlen(char *__restrict dst, const char *__restrict src) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL(1, 2);
char *BLI_strncat(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy)
ATTR_NONNULL(1, 2);
@ -246,14 +243,6 @@ size_t BLI_vsnprintf_rlen(char *__restrict dst,
char *BLI_sprintfN(const char *__restrict format, ...) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1, 2);
/**
* A wrapper around `::sprintf()` which does not generate security warnings.
*
* \note Use #BLI_snprintf for cases when the string size is known.
*/
int BLI_sprintf(char *__restrict str, const char *__restrict format, ...) ATTR_NONNULL(1, 2)
ATTR_PRINTF_FORMAT(2, 3);
/**
* This roughly matches C and Python's string escaping with double quotes - `"`.
*

View File

@ -0,0 +1,44 @@
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
/** \file
* \ingroup bli
*/
#ifdef __cplusplus
extern "C" {
#endif
/* Unicode characters as UTF-8 strings. Last portion should include the official assigned name.
* Please do not add defines here that are not actually in use. */
#define BLI_STR_UTF8_MULTIPLICATION_SIGN u8"\u00D7" /* × */
#define BLI_STR_UTF8_EM_DASH u8"\u2014" /* — */
#define BLI_STR_UTF8_BULLET u8"\u2022" /* • */
#define BLI_STR_UTF8_HORIZONTAL_ELLIPSIS u8"\u2026" /* … */
#define BLI_STR_UTF8_LEFTWARDS_ARROW u8"\u2190" /* ← */
#define BLI_STR_UTF8_UPWARDS_ARROW u8"\u2191" /* ↑ */
#define BLI_STR_UTF8_RIGHTWARDS_ARROW u8"\u2192" /* → */
#define BLI_STR_UTF8_DOWNWARDS_ARROW u8"\u2193" /* ↓ */
#define BLI_STR_UTF8_UPWARDS_WHITE_ARROW u8"\u21E7" /* ⇧ */
#define BLI_STR_UTF8_UP_ARROWHEAD u8"\u2303" /* ⌃ */
#define BLI_STR_UTF8_PLACE_OF_INTEREST_SIGN u8"\u2318" /* ⌘ */
#define BLI_STR_UTF8_OPTION_KEY u8"\u2325" /* ⌥ */
#define BLI_STR_UTF8_ERASE_TO_THE_LEFT u8"\u232B" /* ⌫ */
#define BLI_STR_UTF8_BROKEN_CIRCLE_WITH_NORTHWEST_ARROW u8"\u238B" /* ⎋ */
#define BLI_STR_UTF8_RETURN_SYMBOL u8"\u23CE" /* ⏎ */
#define BLI_STR_UTF8_BLACK_RIGHT_POINTING_DOUBLE_TRIANGLE_WITH_VERTICAL_BAR u8"\u23ED" /* ⏭ */
#define BLI_STR_UTF8_BLACK_LEFT_POINTING_DOUBLE_TRIANGLE_WITH_VERTICAL_BAR u8"\u23EE" /* ⏮ */
#define BLI_STR_UTF8_BLACK_RIGHT_POINTING_TRIANGLE_WITH_DOUBLE_VERTICAL_BAR u8"\u23EF" /* ⏯ */
#define BLI_STR_UTF8_BLACK_SQUARE_FOR_STOP u8"\u23F9" /* ⏹ */
#define BLI_STR_UTF8_OPEN_BOX u8"\u2423" /* ␣ */
#define BLI_STR_UTF8_BLACK_RIGHT_POINTING_SMALL_TRIANGLE u8"\u25B8" /* ▸ */
#define BLI_STR_UTF8_HORIZONTAL_TAB_KEY u8"\u2B7E" /* ⭾ */
#define BLI_STR_UTF8_BLACK_DIAMOND_MINUS_WHITE_X u8"\u2756" /* ❖ */
#ifdef __cplusplus
}
#endif

View File

@ -118,6 +118,9 @@ bool BLI_uniquename(struct ListBase *list,
/* Expand array functions. */
size_t BLI_string_len_array(const char *strings[], uint strings_num) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL();
/* Intentionally no comma after `_BLI_STRING_ARGS_0` to allow it to be empty. */
#define _BLI_STRING_ARGS_1 _BLI_STRING_ARGS_0 const char *a
#define _BLI_STRING_ARGS_2 _BLI_STRING_ARGS_1, const char *b

View File

@ -39,7 +39,7 @@ bool BLI_uuid_equal(bUUID uuid1, bUUID uuid2);
/**
* Format UUID as string.
* The buffer must be at least 37 bytes (36 bytes for the UUID + terminating 0).
* Use `UUID_STRING_LEN` from DNA_uuid_types.h if you want to use a constant for this.
* Use `UUID_STRING_SIZE` from DNA_uuid_types.h if you want to use a constant for this.
*/
void BLI_uuid_format(char *buffer, bUUID uuid) ATTR_NONNULL();

View File

@ -354,6 +354,7 @@ set(SRC
BLI_string_ref.hh
BLI_string_search.h
BLI_string_utf8.h
BLI_string_utf8_symbols.h
BLI_string_utils.h
BLI_sub_frame.hh
BLI_sys_types.h

View File

@ -2262,11 +2262,12 @@ VoronoiOutput fractal_voronoi_x_fx(const VoronoiParams &params,
params.lacunarity == 0.0f;
for (int i = 0; i <= ceilf(params.detail); ++i) {
VoronoiOutput octave = (params.feature == NOISE_SHD_VORONOI_F1) ?
voronoi_f1(params, coord * scale) :
(params.feature == NOISE_SHD_VORONOI_SMOOTH_F1) ?
VoronoiOutput octave = (params.feature == NOISE_SHD_VORONOI_F2) ?
voronoi_f2(params, coord * scale) :
(params.feature == NOISE_SHD_VORONOI_SMOOTH_F1 &&
params.smoothness != 0.0f) ?
voronoi_smooth_f1(params, coord * scale, calc_color) :
voronoi_f2(params, coord * scale);
voronoi_f1(params, coord * scale);
if (zero_input) {
max_amplitude = 1.0f;

View File

@ -666,7 +666,6 @@ void BLI_path_rel(char path[FILE_MAX], const char *basepath)
const char *lslash;
char temp[FILE_MAX];
char res[FILE_MAX];
/* If path is already relative, bail out. */
if (BLI_path_is_rel(path)) {
@ -739,7 +738,6 @@ void BLI_path_rel(char path[FILE_MAX], const char *basepath)
* This is replaced by the two slashes at the beginning. */
const char *p = temp;
const char *q = path;
char *r = res;
#ifdef WIN32
while (tolower(*p) == tolower(*q))
@ -771,7 +769,8 @@ void BLI_path_rel(char path[FILE_MAX], const char *basepath)
}
}
r += BLI_strcpy_rlen(r, "//");
char res[FILE_MAX] = "//";
char *r = res + 2;
/* `p` now points to the slash that is at the beginning of the part
* where the path is different from the relative path.
@ -782,13 +781,13 @@ void BLI_path_rel(char path[FILE_MAX], const char *basepath)
}
while (p && p < lslash) {
if (*p == '/') {
r += BLI_strcpy_rlen(r, "../");
r += BLI_strncpy_rlen(r, "../", sizeof(res) - (r - res));
}
p++;
}
/* Don't copy the slash at the beginning. */
r += BLI_strncpy_rlen(r, q + 1, FILE_MAX - (r - res));
r += BLI_strncpy_rlen(r, q + 1, sizeof(res) - (r - res));
#ifdef WIN32
BLI_str_replace_char(res + 2, '/', '\\');

View File

@ -123,13 +123,6 @@ size_t BLI_strncpy_rlen(char *__restrict dst, const char *__restrict src, const
return srclen;
}
size_t BLI_strcpy_rlen(char *__restrict dst, const char *__restrict src)
{
size_t srclen = strlen(src);
memcpy(dst, src, srclen + 1);
return srclen;
}
/* -------------------------------------------------------------------- */
/** \name String Append
* \{ */
@ -251,17 +244,6 @@ char *BLI_sprintfN(const char *__restrict format, ...)
return n;
}
int BLI_sprintf(char *__restrict str, const char *__restrict format, ...)
{
va_list arg;
va_start(arg, format);
const int result = vsprintf(str, format, arg);
va_end(arg);
return result;
}
/** \} */
/* -------------------------------------------------------------------- */

View File

@ -10,10 +10,11 @@
#include "BLI_string_ref.hh"
#include "BLI_string_search.h"
#include "BLI_string_utf8.h"
#include "BLI_string_utf8_symbols.h"
#include "BLI_timeit.hh"
/* Right arrow, keep in sync with #UI_MENU_ARROW_SEP in `UI_interface.h`. */
#define UI_MENU_ARROW_SEP "\xe2\x96\xb8"
#define UI_MENU_ARROW_SEP BLI_STR_UTF8_BLACK_RIGHT_POINTING_SMALL_TRIANGLE
#define UI_MENU_ARROW_SEP_UNICODE 0x25b8
namespace blender::string_search {

View File

@ -357,6 +357,15 @@ bool BLI_uniquename(ListBase *list,
name_maxncpy);
}
size_t BLI_string_len_array(const char *strings[], uint strings_num)
{
size_t total_len = 0;
for (uint i = 0; i < strings_num; i++) {
total_len += strlen(strings[i]);
}
return total_len;
}
/* ------------------------------------------------------------------------- */
/** \name Join Strings
*
@ -379,7 +388,11 @@ size_t BLI_string_join_array(char *result,
char *c_end = &result[result_maxncpy - 1];
for (uint i = 0; i < strings_num; i++) {
const char *p = strings[i];
while (*p && (c < c_end)) {
while (*p) {
if (UNLIKELY(!(c < c_end))) {
i = strings_num; /* Break outer loop. */
break;
}
*c++ = *p++;
}
}
@ -396,12 +409,17 @@ size_t BLI_string_join_array_by_sep_char(
char *c_end = &result[result_maxncpy - 1];
for (uint i = 0; i < strings_num; i++) {
if (i != 0) {
if (c < c_end) {
*c++ = sep;
if (UNLIKELY(!(c < c_end))) {
break;
}
*c++ = sep;
}
const char *p = strings[i];
while (*p && (c < c_end)) {
while (*p) {
if (UNLIKELY(!(c < c_end))) {
i = strings_num; /* Break outer loop. */
break;
}
*c++ = *p++;
}
}
@ -411,41 +429,38 @@ size_t BLI_string_join_array_by_sep_char(
char *BLI_string_join_arrayN(const char *strings[], uint strings_num)
{
uint total_len = 1;
for (uint i = 0; i < strings_num; i++) {
total_len += strlen(strings[i]);
}
char *result = MEM_mallocN(sizeof(char) * total_len, __func__);
const uint result_size = BLI_string_len_array(strings, strings_num) + 1;
char *result = MEM_mallocN(sizeof(char) * result_size, __func__);
char *c = result;
for (uint i = 0; i < strings_num; i++) {
c += BLI_strcpy_rlen(c, strings[i]);
const size_t string_len = strlen(strings[i]);
memcpy(c, strings[i], string_len);
c += string_len;
}
/* Only needed when `strings_num == 0`. */
*c = '\0';
BLI_assert(result + result_size == c + 1);
return result;
}
char *BLI_string_join_array_by_sep_charN(char sep, const char *strings[], uint strings_num)
{
uint total_len = 0;
for (uint i = 0; i < strings_num; i++) {
total_len += strlen(strings[i]) + 1;
}
if (total_len == 0) {
total_len = 1;
}
char *result = MEM_mallocN(sizeof(char) * total_len, __func__);
const uint result_size = BLI_string_len_array(strings, strings_num) +
(strings_num ? strings_num - 1 : 0) + 1;
char *result = MEM_mallocN(sizeof(char) * result_size, __func__);
char *c = result;
if (strings_num != 0) {
for (uint i = 0; i < strings_num; i++) {
c += BLI_strcpy_rlen(c, strings[i]);
const size_t string_len = strlen(strings[i]);
memcpy(c, strings[i], string_len);
c += string_len;
*c = sep;
c++;
}
c--;
}
*c = '\0';
BLI_assert(result + result_size == c + 1);
return result;
}
@ -454,26 +469,30 @@ char *BLI_string_join_array_by_sep_char_with_tableN(char sep,
const char *strings[],
uint strings_num)
{
uint total_len = 0;
uint result_size = 0;
for (uint i = 0; i < strings_num; i++) {
total_len += strlen(strings[i]) + 1;
result_size += strlen(strings[i]) + 1;
}
if (total_len == 0) {
total_len = 1;
if (result_size == 0) {
result_size = 1;
}
char *result = MEM_mallocN(sizeof(char) * total_len, __func__);
char *result = MEM_mallocN(sizeof(char) * result_size, __func__);
char *c = result;
if (strings_num != 0) {
for (uint i = 0; i < strings_num; i++) {
const size_t string_len = strlen(strings[i]);
memcpy(c, strings[i], string_len);
table[i] = c; /* <-- only difference to BLI_string_join_array_by_sep_charN. */
c += BLI_strcpy_rlen(c, strings[i]);
memcpy(c, strings[i], string_len);
c += string_len;
*c = sep;
c++;
}
c--;
}
*c = '\0';
BLI_assert(result + result_size == c + 1);
return result;
}

View File

@ -88,19 +88,25 @@ bool BLI_uuid_equal(const bUUID uuid1, const bUUID uuid2)
void BLI_uuid_format(char *buffer, const bUUID uuid)
{
BLI_sprintf(buffer,
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
uuid.time_low,
uuid.time_mid,
uuid.time_hi_and_version,
uuid.clock_seq_hi_and_reserved,
uuid.clock_seq_low,
uuid.node[0],
uuid.node[1],
uuid.node[2],
uuid.node[3],
uuid.node[4],
uuid.node[5]);
const size_t buffer_len_unclamped = BLI_snprintf(
buffer,
UUID_STRING_SIZE,
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
uuid.time_low,
uuid.time_mid,
uuid.time_hi_and_version,
uuid.clock_seq_hi_and_reserved,
uuid.clock_seq_low,
uuid.node[0],
uuid.node[1],
uuid.node[2],
uuid.node[3],
uuid.node[4],
uuid.node[5]);
/* Assert the string length is not clamped. */
BLI_assert(buffer_len_unclamped == UUID_STRING_SIZE - 1);
UNUSED_VARS_NDEBUG(buffer_len_unclamped);
}
bool BLI_uuid_parse_string(bUUID *uuid, const char *buffer)

View File

@ -11,6 +11,8 @@
#include <utility>
#include <vector>
#include "MEM_guardedalloc.h"
#include "BLI_string.h"
#include "BLI_string_utf8.h"
#include "BLI_string_utils.h"
@ -859,6 +861,104 @@ TEST(string, StringNLen)
/** \} */
/* -------------------------------------------------------------------- */
/** \name String Join
* \{ */
#define BUFFER_SIZE 128
static void string_join_array_test_truncate(const char *strings[],
int strings_num,
char buffer[BUFFER_SIZE])
{
const int buffer_len = BLI_string_join_array(buffer, BUFFER_SIZE, strings, strings_num);
{ /* Ensure the allocated version is the same. */
char *buffer_alloc = BLI_string_join_arrayN(strings, strings_num);
EXPECT_STREQ(buffer_alloc, buffer);
MEM_freeN(buffer_alloc);
}
for (int dst_size = buffer_len + 1; dst_size > 0; dst_size--) {
char dst_tmp[BUFFER_SIZE];
int dst_tmp_len = BLI_string_join_array(dst_tmp, dst_size, strings, strings_num);
EXPECT_EQ(dst_tmp_len + 1, dst_size);
EXPECT_EQ(strncmp(dst_tmp, buffer, dst_tmp_len), 0);
}
}
static void string_join_array_with_sep_char_test_truncate(const char *strings[],
int strings_num,
char buffer[BUFFER_SIZE])
{
const int buffer_len = BLI_string_join_array_by_sep_char(
buffer, BUFFER_SIZE, '|', strings, strings_num);
{ /* Ensure the allocated version is the same. */
char *buffer_alloc = BLI_string_join_array_by_sep_charN('|', strings, strings_num);
EXPECT_STREQ(buffer_alloc, buffer);
MEM_freeN(buffer_alloc);
}
for (int dst_size = buffer_len + 1; dst_size > 0; dst_size--) {
char dst_tmp[BUFFER_SIZE];
int dst_tmp_len = BLI_string_join_array_by_sep_char(
dst_tmp, dst_size, '|', strings, strings_num);
EXPECT_EQ(dst_tmp_len + 1, dst_size);
EXPECT_EQ(strncmp(dst_tmp, buffer, dst_tmp_len), 0);
}
}
TEST(string, StrJoin_Truncate)
{
char buffer[BUFFER_SIZE];
{ /* Multiple single char words. */
const char *strings[] = {"a", "b", "c", "d", "e", "f"};
string_join_array_test_truncate(strings, ARRAY_SIZE(strings), buffer);
EXPECT_STREQ(buffer, "abcdef");
string_join_array_with_sep_char_test_truncate(strings, ARRAY_SIZE(strings), buffer);
EXPECT_STREQ(buffer, "a|b|c|d|e|f");
}
{ /* Multiple char pair words. */
const char *strings[] = {"aa", "bb", "cc", "dd", "ee", "ff"};
string_join_array_test_truncate(strings, ARRAY_SIZE(strings), buffer);
EXPECT_STREQ(buffer, "aabbccddeeff");
string_join_array_with_sep_char_test_truncate(strings, ARRAY_SIZE(strings), buffer);
EXPECT_STREQ(buffer, "aa|bb|cc|dd|ee|ff");
}
{ /* Multiple empty words. */
const char *strings[] = {"", "", "", "", "", ""};
string_join_array_test_truncate(strings, ARRAY_SIZE(strings), buffer);
EXPECT_STREQ(buffer, "");
string_join_array_with_sep_char_test_truncate(strings, ARRAY_SIZE(strings), buffer);
EXPECT_STREQ(buffer, "|||||");
}
{ /* Single word. */
const char *strings[] = {"test"};
string_join_array_test_truncate(strings, ARRAY_SIZE(strings), buffer);
EXPECT_STREQ(buffer, "test");
string_join_array_with_sep_char_test_truncate(strings, ARRAY_SIZE(strings), buffer);
EXPECT_STREQ(buffer, "test");
}
{ /* Empty item. */
const char *strings[] = {""};
string_join_array_test_truncate(strings, ARRAY_SIZE(strings), buffer);
EXPECT_STREQ(buffer, "");
string_join_array_with_sep_char_test_truncate(strings, ARRAY_SIZE(strings), buffer);
EXPECT_STREQ(buffer, "");
}
{ /* Empty array. */
string_join_array_test_truncate(nullptr, 0, buffer);
EXPECT_STREQ(buffer, "");
string_join_array_with_sep_char_test_truncate(nullptr, 0, buffer);
EXPECT_STREQ(buffer, "");
}
}
#undef BUFFER_SIZE
/** \} */
/* -------------------------------------------------------------------- */
/** \name String Find Split Words
* \{ */

View File

@ -2133,8 +2133,8 @@ if (!MAIN_VERSION_ATLEAST(bmain, 269, 3)) {
}
/* 'Increment' mode disabled for nodes, use true grid snapping instead */
if (scene->toolsettings->snap_node_mode == 0) { /* SCE_SNAP_MODE_INCREMENT */
scene->toolsettings->snap_node_mode = 8; /* SCE_SNAP_MODE_GRID */
if (scene->toolsettings->snap_node_mode == 0) { /* SCE_SNAP_TO_INCREMENT */
scene->toolsettings->snap_node_mode = 8; /* SCE_SNAP_TO_GRID */
}
#ifdef WITH_FFMPEG

View File

@ -3818,42 +3818,42 @@ void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain)
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
switch (scene->toolsettings->snap_mode) {
case 0:
scene->toolsettings->snap_mode = (1 << 4); /* SCE_SNAP_MODE_INCREMENT */
scene->toolsettings->snap_mode = (1 << 4); /* SCE_SNAP_TO_INCREMENT */
break;
case 1:
scene->toolsettings->snap_mode = (1 << 0); /* SCE_SNAP_MODE_VERTEX */
scene->toolsettings->snap_mode = (1 << 0); /* SCE_SNAP_TO_VERTEX */
break;
case 2:
scene->toolsettings->snap_mode = (1 << 1); /* SCE_SNAP_MODE_EDGE */
scene->toolsettings->snap_mode = (1 << 1); /* SCE_SNAP_TO_EDGE */
break;
case 3:
scene->toolsettings->snap_mode = (1 << 2); /* SCE_SNAP_MODE_FACE_RAYCAST */
scene->toolsettings->snap_mode = (1 << 2); /* SCE_SNAP_INDIVIDUAL_PROJECT */
break;
case 4:
scene->toolsettings->snap_mode = (1 << 3); /* SCE_SNAP_MODE_VOLUME */
scene->toolsettings->snap_mode = (1 << 3); /* SCE_SNAP_TO_VOLUME */
break;
}
switch (scene->toolsettings->snap_node_mode) {
case 5:
scene->toolsettings->snap_node_mode = (1 << 5); /* SCE_SNAP_MODE_NODE_X */
scene->toolsettings->snap_node_mode = (1 << 5); /* SCE_SNAP_TO_NODE_X */
break;
case 6:
scene->toolsettings->snap_node_mode = (1 << 6); /* SCE_SNAP_MODE_NODE_Y */
scene->toolsettings->snap_node_mode = (1 << 6); /* SCE_SNAP_TO_NODE_Y */
break;
case 7:
scene->toolsettings->snap_node_mode =
(1 << 5) | (1 << 6); /* SCE_SNAP_MODE_NODE_X | SCE_SNAP_MODE_NODE_Y */
(1 << 5) | (1 << 6); /* SCE_SNAP_TO_NODE_X | SCE_SNAP_TO_NODE_Y */
break;
case 8:
scene->toolsettings->snap_node_mode = (1 << 7); /* SCE_SNAP_MODE_GRID */
scene->toolsettings->snap_node_mode = (1 << 7); /* SCE_SNAP_TO_GRID */
break;
}
switch (scene->toolsettings->snap_uv_mode) {
case 0:
scene->toolsettings->snap_uv_mode = (1 << 4); /* SCE_SNAP_MODE_INCREMENT */
scene->toolsettings->snap_uv_mode = (1 << 4); /* SCE_SNAP_TO_INCREMENT */
break;
case 1:
scene->toolsettings->snap_uv_mode = (1 << 0); /* SCE_SNAP_MODE_VERTEX */
scene->toolsettings->snap_uv_mode = (1 << 0); /* SCE_SNAP_TO_VERTEX */
break;
}
}
@ -5749,8 +5749,8 @@ void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain)
if (!MAIN_VERSION_ATLEAST(bmain, 281, 15)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
if (scene->toolsettings->snap_node_mode == SCE_SNAP_MODE_NODE_X) {
scene->toolsettings->snap_node_mode = SCE_SNAP_MODE_GRID;
if (scene->toolsettings->snap_node_mode == SCE_SNAP_TO_NODE_X) {
scene->toolsettings->snap_node_mode = SCE_SNAP_TO_GRID;
}
}

View File

@ -2523,22 +2523,22 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
tool_settings->snap_node_mode &= ~((1 << 5) | (1 << 6));
tool_settings->snap_uv_mode &= ~(1 << 4);
if (snap_mode & (1 << 4)) {
tool_settings->snap_mode |= (1 << 6); /* SCE_SNAP_MODE_INCREMENT */
tool_settings->snap_mode |= (1 << 6); /* SCE_SNAP_TO_INCREMENT */
}
if (snap_mode & (1 << 5)) {
tool_settings->snap_mode |= (1 << 4); /* SCE_SNAP_MODE_EDGE_MIDPOINT */
tool_settings->snap_mode |= (1 << 4); /* SCE_SNAP_TO_EDGE_MIDPOINT */
}
if (snap_mode & (1 << 6)) {
tool_settings->snap_mode |= (1 << 5); /* SCE_SNAP_MODE_EDGE_PERPENDICULAR */
tool_settings->snap_mode |= (1 << 5); /* SCE_SNAP_TO_EDGE_PERPENDICULAR */
}
if (snap_node_mode & (1 << 5)) {
tool_settings->snap_node_mode |= (1 << 0); /* SCE_SNAP_MODE_NODE_X */
tool_settings->snap_node_mode |= (1 << 0); /* SCE_SNAP_TO_NODE_X */
}
if (snap_node_mode & (1 << 6)) {
tool_settings->snap_node_mode |= (1 << 1); /* SCE_SNAP_MODE_NODE_Y */
tool_settings->snap_node_mode |= (1 << 1); /* SCE_SNAP_TO_NODE_Y */
}
if (snap_uv_mode & (1 << 4)) {
tool_settings->snap_uv_mode |= (1 << 6); /* SCE_SNAP_MODE_INCREMENT */
tool_settings->snap_uv_mode |= (1 << 6); /* SCE_SNAP_TO_INCREMENT */
}
SequencerToolSettings *sequencer_tool_settings = SEQ_tool_settings_ensure(scene);
@ -2582,7 +2582,7 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
ToolSettings *tool_settings = scene->toolsettings;
if (tool_settings->snap_uv_mode & (1 << 4)) {
tool_settings->snap_uv_mode |= (1 << 6); /* SCE_SNAP_MODE_INCREMENT */
tool_settings->snap_uv_mode |= (1 << 6); /* SCE_SNAP_TO_INCREMENT */
tool_settings->snap_uv_mode &= ~(1 << 4);
}
}
@ -4472,7 +4472,7 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
if (!MAIN_VERSION_ATLEAST(bmain, 306, 10)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
/* Set default values for new members. */
scene->toolsettings->snap_mode_tools = SCE_SNAP_MODE_GEOM;
scene->toolsettings->snap_mode_tools = SCE_SNAP_TO_GEOM;
scene->toolsettings->plane_axis = 2;
}
}

View File

@ -43,8 +43,6 @@ void do_versions_after_linking_400(FileData * /*fd*/, Main * /*bmain*/)
*
* \note Be sure to check when bumping the version:
* - #blo_do_versions_400 in this file.
* - "versioning_cycles.cc", #blo_do_versions_cycles
* - "versioning_cycles.cc", #do_versions_after_linking_cycles
* - "versioning_userdef.c", #blo_do_versions_userdef
* - "versioning_userdef.c", #do_versions_theme
*
@ -229,13 +227,13 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
if (!MAIN_VERSION_ATLEAST(bmain, 400, 5)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
ToolSettings *ts = scene->toolsettings;
if (ts->snap_mode_tools != SCE_SNAP_MODE_NONE) {
ts->snap_mode_tools = SCE_SNAP_MODE_GEOM;
if (ts->snap_mode_tools != SCE_SNAP_TO_NONE) {
ts->snap_mode_tools = SCE_SNAP_TO_GEOM;
}
#define SCE_SNAP_PROJECT (1 << 3)
if (ts->snap_flag & SCE_SNAP_PROJECT) {
ts->snap_mode |= SCE_SNAP_MODE_FACE_RAYCAST;
ts->snap_mode |= SCE_SNAP_INDIVIDUAL_PROJECT;
}
#undef SCE_SNAP_PROJECT
}
@ -263,8 +261,6 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
*
* \note Be sure to check when bumping the version:
* - #do_versions_after_linking_400 in this file.
* - "versioning_cycles.cc", #blo_do_versions_cycles
* - "versioning_cycles.cc", #do_versions_after_linking_cycles
* - "versioning_userdef.c", #blo_do_versions_userdef
* - "versioning_userdef.c", #do_versions_theme
*

View File

@ -322,8 +322,8 @@ if(WITH_COMPOSITOR_CPU)
nodes/COM_FilterNode.h
nodes/COM_InpaintNode.cc
nodes/COM_InpaintNode.h
nodes/COM_KuwaharaNode.h
nodes/COM_KuwaharaNode.cc
nodes/COM_KuwaharaNode.h
nodes/COM_PosterizeNode.cc
nodes/COM_PosterizeNode.h
@ -351,10 +351,10 @@ if(WITH_COMPOSITOR_CPU)
operations/COM_GaussianXBlurOperation.h
operations/COM_GaussianYBlurOperation.cc
operations/COM_GaussianYBlurOperation.h
operations/COM_KuwaharaClassicOperation.h
operations/COM_KuwaharaClassicOperation.cc
operations/COM_KuwaharaAnisotropicOperation.h
operations/COM_KuwaharaAnisotropicOperation.cc
operations/COM_KuwaharaAnisotropicOperation.h
operations/COM_KuwaharaClassicOperation.cc
operations/COM_KuwaharaClassicOperation.h
operations/COM_MovieClipAttributeOperation.cc
operations/COM_MovieClipAttributeOperation.h
operations/COM_MovieDistortionOperation.cc

View File

@ -361,7 +361,7 @@ void MemoryBuffer::copy_from(const ImBuf *src,
to_y,
to_channel_offset);
if (ensure_linear_space) {
colorspace_to_scene_linear(this, area, src->rect_colorspace);
colorspace_to_scene_linear(this, area, src->byte_buffer.colorspace);
}
}
else {

View File

@ -80,11 +80,7 @@ void COM_execute(Render *render,
node_tree->execution_mode == NTREE_EXECUTION_MODE_REALTIME)
{
/* Realtime GPU compositor. */
/* TODO: add persistence and depsgraph updates for better performance. */
blender::render::RealtimeCompositor compositor(
*render, *scene, *render_data, *node_tree, rendering, view_name);
compositor.execute();
RE_compositor_execute(*render, *scene, *render_data, *node_tree, rendering, view_name);
}
else {
/* Tiled and Full Frame compositors. */

View File

@ -4,6 +4,7 @@
#include "COM_KuwaharaNode.h"
#include "COM_ConvertOperation.h"
#include "COM_ConvolutionFilterOperation.h"
#include "COM_FastGaussianBlurOperation.h"
#include "COM_KuwaharaAnisotropicOperation.h"
@ -31,7 +32,11 @@ void KuwaharaNode::convert_to_operations(NodeConverter &converter,
}
case CMP_NODE_KUWAHARA_ANISOTROPIC: {
/* Edge detection */
/* Edge detection on luminance. */
auto rgb_to_lum = new ConvertColorToBWOperation();
converter.add_operation(rgb_to_lum);
converter.map_input_socket(get_input_socket(0), rgb_to_lum->get_input_socket(0));
auto const_fact = new SetValueOperation();
const_fact->set_value(1.0f);
converter.add_operation(const_fact);
@ -39,16 +44,16 @@ void KuwaharaNode::convert_to_operations(NodeConverter &converter,
auto sobel_x = new ConvolutionFilterOperation();
sobel_x->set3x3Filter(1, 0, -1, 2, 0, -2, 1, 0, -1);
converter.add_operation(sobel_x);
converter.map_input_socket(get_input_socket(0), sobel_x->get_input_socket(0));
converter.add_link(rgb_to_lum->get_output_socket(0), sobel_x->get_input_socket(0));
converter.add_link(const_fact->get_output_socket(0), sobel_x->get_input_socket(1));
auto sobel_y = new ConvolutionFilterOperation();
sobel_y->set3x3Filter(1, 2, 1, 0, 0, 0, -1, -2, -1);
converter.add_operation(sobel_y);
converter.map_input_socket(get_input_socket(0), sobel_y->get_input_socket(0));
converter.add_link(rgb_to_lum->get_output_socket(0), sobel_y->get_input_socket(0));
converter.add_link(const_fact->get_output_socket(0), sobel_y->get_input_socket(1));
/* Compute intensity of edges */
/* Compute intensity of edges. */
auto sobel_xx = new MathMultiplyOperation();
auto sobel_yy = new MathMultiplyOperation();
auto sobel_xy = new MathMultiplyOperation();

View File

@ -136,7 +136,8 @@ static void sample_image_at_location(
}
rgba_uchar_to_float(color, byte_color);
if (make_linear_rgb) {
IMB_colormanagement_colorspace_to_scene_linear_v4(color, false, ibuf->rect_colorspace);
IMB_colormanagement_colorspace_to_scene_linear_v4(
color, false, ibuf->byte_buffer.colorspace);
}
}
}

View File

@ -202,11 +202,10 @@ void KuwaharaAnisotropicOperation::update_memory_buffer_partial(MemoryBuffer *ou
const int x = it.x;
const int y = it.y;
/* For now use green channel to compute orientation. */
/* TODO: convert to HSV and compute orientation and strength on luminance channel. */
const float a = s_xx->get_value(x, y, 1);
const float b = s_xy->get_value(x, y, 1);
const float c = s_yy->get_value(x, y, 1);
/* All channels are identical. Take first channel for simplicity. */
const float a = s_xx->get_value(x, y, 0);
const float b = s_xy->get_value(x, y, 0);
const float c = s_yy->get_value(x, y, 0);
/* Compute egenvalues of structure tensor */
const double tr = a + c;

View File

@ -68,10 +68,14 @@ set(SRC
COM_texture_pool.hh
COM_utilities.hh
algorithms/intern/algorithm_parallel_reduction.cc
algorithms/intern/morphological_distance.cc
algorithms/intern/morphological_distance_feather.cc
algorithms/intern/parallel_reduction.cc
algorithms/intern/smaa.cc
algorithms/intern/symmetric_separable_blur.cc
algorithms/COM_algorithm_morphological_distance.hh
algorithms/COM_algorithm_morphological_distance_feather.hh
algorithms/COM_algorithm_parallel_reduction.hh
algorithms/COM_algorithm_smaa.hh
algorithms/COM_algorithm_symmetric_separable_blur.hh
@ -135,6 +139,11 @@ set(GLSL_SRC
shaders/compositor_glare_streaks_filter.glsl
shaders/compositor_id_mask.glsl
shaders/compositor_image_crop.glsl
shaders/compositor_keying_compute_image.glsl
shaders/compositor_keying_compute_matte.glsl
shaders/compositor_keying_extract_chroma.glsl
shaders/compositor_keying_replace_chroma.glsl
shaders/compositor_keying_tweak_matte.glsl
shaders/compositor_map_uv.glsl
shaders/compositor_morphological_distance.glsl
shaders/compositor_morphological_distance_feather.glsl
@ -239,6 +248,7 @@ set(SRC_SHADER_CREATE_INFOS
shaders/infos/compositor_glare_info.hh
shaders/infos/compositor_id_mask_info.hh
shaders/infos/compositor_image_crop_info.hh
shaders/infos/compositor_keying_info.hh
shaders/infos/compositor_map_uv_info.hh
shaders/infos/compositor_morphological_distance_feather_info.hh
shaders/infos/compositor_morphological_distance_info.hh

View File

@ -84,7 +84,9 @@ class Context {
/* Get the texture where the given render pass is stored. This should be called by the Render
* Layer node to populate its outputs. */
virtual GPUTexture *get_input_texture(int view_layer, const char *pass_name) = 0;
virtual GPUTexture *get_input_texture(const Scene *scene,
int view_layer,
const char *pass_name) = 0;
/* Get the name of the view currently being rendered. */
virtual StringRef get_view_name() = 0;

View File

@ -45,10 +45,7 @@ class NodeOperation : public Operation {
void compute_results_reference_counts(const Schedule &schedule);
protected:
/* Compute a preview for the operation and set to the bNodePreview of the node. This is only done
* for nodes which enables previews, are not hidden, and are part of the active node context. The
* preview is computed as a lower resolution version of the output of the get_preview_result
* method. */
/* Compute a node preview using the result returned from the get_preview_result method. */
void compute_preview() override;
/* Returns a reference to the derived node that this operation represents. */
@ -67,10 +64,6 @@ class NodeOperation : public Operation {
* guaranteed not to be returned, since the node will always either have a linked output or an
* allocated input. */
Result *get_preview_result();
/* Resize the give input result to the given preview size and set it to the preview buffer after
* applying the necessary color management processor.*/
void write_preview_from_result(bNodePreview &preview, Result &input_result);
};
} // namespace blender::realtime_compositor

View File

@ -164,6 +164,20 @@ class Result {
* the discussion above for more information. */
void pass_through(Result &target);
/* Steal the allocated data from the given source result and assign it to this result, then
* remove any references to the data from the source result. It is assumed that:
*
* - Both results are of the same type.
* - This result is not allocated but the source result is allocated.
* - Neither of the results is a proxy one, that is, has a master result.
*
* This is different from proxy results and the pass_through mechanism in that it can be used on
* temporary results. This is most useful in multi-step compositor operations where some steps
* can be optional, in that case, intermediate results can be temporary results that can
* eventually be stolen by the actual output of the operation. See the uses of the method for
* a practical example of use. */
void steal_data(Result &source);
/* Transform the result by the given transformation. This effectively pre-multiply the given
* transformation by the current transformation of the domain of the result. */
void transform(const float3x3 &transformation);

View File

@ -112,6 +112,9 @@ class ShaderOperation : public Operation {
* the attribute that was created for it. This is used to share the same attribute with all
* inputs that are linked to the same output socket. */
Map<DOutputSocket, GPUNodeLink *> output_to_material_attribute_map_;
/* A vector set that stores all output sockets that are used as previews for nodes inside the
* shader operation. */
VectorSet<DOutputSocket> preview_outputs_;
public:
/* Construct and compile a GPU material from the given shader compile unit by calling
@ -125,6 +128,13 @@ class ShaderOperation : public Operation {
* shader. */
void execute() override;
/* Compute a node preview for all nodes in the shader operations if the node requires a preview.
*
* Previews are computed from results that are populated for outputs that are used to compute
* previews even if they are internally linked, and those outputs are stored and tracked in the
* preview_outputs_ vector set, see the populate_results_for_node method for more information. */
void compute_preview() override;
/* Get the identifier of the operation output corresponding to the given output socket. This is
* called by the compiler to identify the operation output that provides the result for an input
* by providing the output socket that the input is linked to. See
@ -138,9 +148,14 @@ class ShaderOperation : public Operation {
/* Compute and set the initial reference counts of all the results of the operation. The
* reference counts of the results are the number of operations that use those results, which is
* computed as the number of inputs whose node is part of the schedule and is linked to the
* output corresponding to each of the results of the operation. The node execution schedule is
* given as an input. */
* computed as the number of inputs linked to the output corresponding to each of the results of
* the operation, but only the linked inputs whose node is part of the schedule but not part of
* the shader operation, since inputs that are part of the shader operations are internal links.
*
* Additionally, results that are used as node previews gets an extra reference count because
* they are referenced and released by the compute_preview method.
*
* The node execution schedule is given as an input. */
void compute_results_reference_counts(const Schedule &schedule);
private:
@ -209,7 +224,8 @@ class ShaderOperation : public Operation {
GPUMaterial *material);
/* Populate the output results of the shader operation for output sockets of the given node that
* are linked to nodes outside of the shader operation. */
* are linked to nodes outside of the shader operation or are used to compute a preview for the
* node. */
void populate_results_for_node(DNode node, GPUMaterial *material);
/* Given the output socket of a node that is part of the shader operation which is linked to an

View File

@ -70,4 +70,11 @@ void compute_dispatch_threads_at_least(GPUShader *shader,
int2 threads_range,
int2 local_size = int2(16));
/* Returns true if a node preview needs to be computed for the give node. */
bool is_node_preview_needed(const DNode &node);
/* Computes a lower resolution version of the given result and sets it as a preview for the given
* node after applying the appropriate color management specified in the given context. */
void compute_preview_from_result(Context &context, const DNode &node, Result &input_result);
} // namespace blender::realtime_compositor

View File

@ -0,0 +1,18 @@
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "COM_context.hh"
#include "COM_result.hh"
namespace blender::realtime_compositor {
/* Dilate or erode the given input using a morphological operator with a circular structuring
* element of radius equivalent to the absolute value of the given distance parameter. A positive
* distance corresponds to dilate operator, while a negative distance corresponds to an erode
* operator. */
void morphological_distance(Context &context, Result &input, Result &output, int distance);
} // namespace blender::realtime_compositor

View File

@ -0,0 +1,22 @@
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "DNA_scene_types.h"
#include "COM_context.hh"
#include "COM_result.hh"
namespace blender::realtime_compositor {
/* Dilate or erode the given input using a morphological inverse distance operation evaluated at
* the given falloff. The radius of the structuring element is equivalent to the absolute value of
* the given distance parameter. A positive distance corresponds to a dilate operator, while a
* negative distance corresponds to an erode operator. See the implementation and shader for more
* information. */
void morphological_distance_feather(
Context &context, Result &input, Result &output, int distance, int falloff_type = PROP_SMOOTH);
} // namespace blender::realtime_compositor

View File

@ -6,6 +6,8 @@
#include "BLI_math_vector_types.hh"
#include "DNA_scene_types.h"
#include "COM_context.hh"
#include "COM_result.hh"
@ -22,8 +24,8 @@ void symmetric_separable_blur(Context &context,
Result &input,
Result &output,
float2 radius,
int filter_type,
bool extend_bounds,
bool gamma_correct);
int filter_type = R_FILTER_GAUSS,
bool extend_bounds = false,
bool gamma_correct = false);
} // namespace blender::realtime_compositor

View File

@ -0,0 +1,46 @@
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_math_base.hh"
#include "GPU_shader.h"
#include "GPU_texture.h"
#include "COM_context.hh"
#include "COM_result.hh"
#include "COM_utilities.hh"
#include "COM_algorithm_morphological_distance.hh"
namespace blender::realtime_compositor {
static const char *get_shader_name(int distance)
{
if (distance > 0) {
return "compositor_morphological_distance_dilate";
}
return "compositor_morphological_distance_erode";
}
void morphological_distance(Context &context, Result &input, Result &output, int distance)
{
GPUShader *shader = context.shader_manager().get(get_shader_name(distance));
GPU_shader_bind(shader);
/* Pass the absolute value of the distance. We have specialized shaders for each sign. */
GPU_shader_uniform_1i(shader, "radius", math::abs(distance));
input.bind_as_texture(shader, "input_tx");
output.allocate_texture(input.domain());
output.bind_as_image(shader, "output_img");
compute_dispatch_threads_at_least(shader, input.domain().size);
GPU_shader_unbind();
output.unbind_as_image();
input.unbind_as_texture();
}
} // namespace blender::realtime_compositor

View File

@ -0,0 +1,108 @@
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_math_base.hh"
#include "BLI_math_vector_types.hh"
#include "GPU_shader.h"
#include "GPU_texture.h"
#include "COM_algorithm_morphological_distance_feather.hh" /* Own include. */
#include "COM_algorithm_symmetric_separable_blur.hh"
#include "COM_context.hh"
#include "COM_morphological_distance_feather_weights.hh"
#include "COM_result.hh"
#include "COM_utilities.hh"
namespace blender::realtime_compositor {
static const char *get_shader_name(int distance)
{
if (distance > 0) {
return "compositor_morphological_distance_feather_dilate";
}
return "compositor_morphological_distance_feather_erode";
}
static Result horizontal_pass(Context &context, Result &input, int distance, int falloff_type)
{
GPUShader *shader = context.shader_manager().get(get_shader_name(distance));
GPU_shader_bind(shader);
input.bind_as_texture(shader, "input_tx");
const MorphologicalDistanceFeatherWeights &weights =
context.cache_manager().morphological_distance_feather_weights.get(falloff_type,
math::abs(distance));
weights.bind_weights_as_texture(shader, "weights_tx");
weights.bind_distance_falloffs_as_texture(shader, "falloffs_tx");
/* We allocate an output image of a transposed size, that is, with a height equivalent to the
* width of the input and vice versa. This is done as a performance optimization. The shader
* will process the image horizontally and write it to the intermediate output transposed. Then
* the vertical pass will execute the same horizontal pass shader, but since its input is
* transposed, it will effectively do a vertical pass and write to the output transposed,
* effectively undoing the transposition in the horizontal pass. This is done to improve
* spatial cache locality in the shader and to avoid having two separate shaders for each of
* the passes. */
const Domain domain = input.domain();
const int2 transposed_domain = int2(domain.size.y, domain.size.x);
Result output = Result::Temporary(ResultType::Float, context.texture_pool());
output.allocate_texture(transposed_domain);
output.bind_as_image(shader, "output_img");
compute_dispatch_threads_at_least(shader, domain.size);
GPU_shader_unbind();
input.unbind_as_texture();
weights.unbind_weights_as_texture();
weights.unbind_distance_falloffs_as_texture();
output.unbind_as_image();
return output;
}
static void vertical_pass(Context &context,
Result &original_input,
Result &horizontal_pass_result,
Result &output,
int distance,
int falloff_type)
{
GPUShader *shader = context.shader_manager().get(get_shader_name(distance));
GPU_shader_bind(shader);
horizontal_pass_result.bind_as_texture(shader, "input_tx");
const MorphologicalDistanceFeatherWeights &weights =
context.cache_manager().morphological_distance_feather_weights.get(falloff_type,
math::abs(distance));
weights.bind_weights_as_texture(shader, "weights_tx");
weights.bind_distance_falloffs_as_texture(shader, "falloffs_tx");
const Domain domain = original_input.domain();
output.allocate_texture(domain);
output.bind_as_image(shader, "output_img");
/* Notice that the domain is transposed, see the note on the horizontal pass function for more
* information on the reasoning behind this. */
compute_dispatch_threads_at_least(shader, int2(domain.size.y, domain.size.x));
GPU_shader_unbind();
horizontal_pass_result.unbind_as_texture();
weights.unbind_weights_as_texture();
weights.unbind_distance_falloffs_as_texture();
output.unbind_as_image();
}
void morphological_distance_feather(
Context &context, Result &input, Result &output, int distance, int falloff_type)
{
Result horizontal_pass_result = horizontal_pass(context, input, distance, falloff_type);
vertical_pass(context, input, horizontal_pass_result, output, distance, falloff_type);
horizontal_pass_result.release();
}
} // namespace blender::realtime_compositor

View File

@ -10,6 +10,7 @@
#include "GPU_texture.h"
#include "COM_context.hh"
#include "COM_result.hh"
#include "COM_utilities.hh"
#include "COM_algorithm_symmetric_separable_blur.hh"
@ -18,6 +19,15 @@
namespace blender::realtime_compositor {
static const char *get_blur_shader(ResultType type)
{
if (type == ResultType::Float) {
return "compositor_symmetric_separable_blur_float";
}
return "compositor_symmetric_separable_blur_color";
}
static Result horizontal_pass(Context &context,
Result &input,
float radius,
@ -25,7 +35,7 @@ static Result horizontal_pass(Context &context,
bool extend_bounds,
bool gamma_correct)
{
GPUShader *shader = context.shader_manager().get("compositor_symmetric_separable_blur");
GPUShader *shader = context.shader_manager().get(get_blur_shader(input.type()));
GPU_shader_bind(shader);
GPU_shader_uniform_1b(shader, "extend_bounds", extend_bounds);
@ -53,7 +63,7 @@ static Result horizontal_pass(Context &context,
* pass. */
const int2 transposed_domain = int2(domain.size.y, domain.size.x);
Result output = Result::Temporary(ResultType::Color, context.texture_pool());
Result output = Result::Temporary(input.type(), context.texture_pool());
output.allocate_texture(transposed_domain);
output.bind_as_image(shader, "output_img");
@ -76,7 +86,7 @@ static void vertical_pass(Context &context,
bool extend_bounds,
bool gamma_correct)
{
GPUShader *shader = context.shader_manager().get("compositor_symmetric_separable_blur");
GPUShader *shader = context.shader_manager().get(get_blur_shader(original_input.type()));
GPU_shader_bind(shader);
GPU_shader_uniform_1b(shader, "extend_bounds", extend_bounds);

View File

@ -5,21 +5,16 @@
#include <memory>
#include "BLI_assert.h"
#include "BLI_index_range.hh"
#include "BLI_map.hh"
#include "BLI_math_base.h"
#include "BLI_math_base.hh"
#include "BLI_math_color.h"
#include "BLI_math_vector_types.hh"
#include "BLI_string_ref.hh"
#include "BLI_task.hh"
#include "BLI_vector.hh"
#include "GPU_shader.h"
#include "GPU_texture.h"
#include "IMB_colormanagement.h"
#include "DNA_node_types.h"
#include "NOD_derived_node_tree.hh"
@ -53,53 +48,11 @@ NodeOperation::NodeOperation(Context &context, DNode node) : Operation(context),
}
}
/* Given the size of a result, compute a lower resolution size for a preview. The greater dimension
* will be assigned an arbitrarily chosen size of 128, while the other dimension will get the size
* that maintains the same aspect ratio. */
static int2 compute_preview_size(int2 size)
{
const int greater_dimension_size = 128;
if (size.x > size.y) {
return int2(greater_dimension_size, int(greater_dimension_size * (float(size.y) / size.x)));
}
else {
return int2(int(greater_dimension_size * (float(size.x) / size.y)), greater_dimension_size);
}
}
void NodeOperation::compute_preview()
{
if (!(node()->flag & NODE_PREVIEW)) {
return;
if (is_node_preview_needed(node())) {
compute_preview_from_result(context(), node(), *get_preview_result());
}
if (node()->flag & NODE_HIDDEN) {
return;
}
/* Only compute previews for nodes in the active context. */
if (node().context()->instance_key().value !=
node().context()->derived_tree().active_context().instance_key().value)
{
return;
}
/* Initialize node tree previews if not already initialized. */
bNodeTree *root_tree = const_cast<bNodeTree *>(
&node().context()->derived_tree().root_context().btree());
if (!root_tree->previews) {
root_tree->previews = BKE_node_instance_hash_new("node previews");
}
Result *preview_result = get_preview_result();
const int2 preview_size = compute_preview_size(preview_result->domain().size);
node()->runtime->preview_xsize = preview_size.x;
node()->runtime->preview_ysize = preview_size.y;
bNodePreview *preview = bke::node_preview_verify(
root_tree->previews, node().instance_key(), preview_size.x, preview_size.y, true);
write_preview_from_result(*preview, *preview_result);
}
Result *NodeOperation::get_preview_result()
@ -124,55 +77,6 @@ Result *NodeOperation::get_preview_result()
return nullptr;
}
void NodeOperation::write_preview_from_result(bNodePreview &preview, Result &input_result)
{
GPUShader *shader = shader_manager().get("compositor_compute_preview");
GPU_shader_bind(shader);
if (input_result.type() == ResultType::Float) {
GPU_texture_swizzle_set(input_result.texture(), "rrr1");
}
input_result.bind_as_texture(shader, "input_tx");
const int2 preview_size = int2(preview.xsize, preview.ysize);
Result preview_result = Result::Temporary(ResultType::Color, texture_pool());
preview_result.allocate_texture(Domain(preview_size));
preview_result.bind_as_image(shader, "preview_img");
compute_dispatch_threads_at_least(shader, preview_size);
input_result.unbind_as_texture();
preview_result.unbind_as_image();
GPU_shader_unbind();
GPU_memory_barrier(GPU_BARRIER_TEXTURE_FETCH);
float *preview_pixels = static_cast<float *>(
GPU_texture_read(preview_result.texture(), GPU_DATA_FLOAT, 0));
preview_result.release();
ColormanageProcessor *color_processor = IMB_colormanagement_display_processor_new(
&context().get_scene().view_settings, &context().get_scene().display_settings);
threading::parallel_for(IndexRange(preview_size.y), 1, [&](const IndexRange sub_y_range) {
for (const int64_t y : sub_y_range) {
for (const int64_t x : IndexRange(preview_size.x)) {
const int index = (y * preview_size.x + x) * 4;
IMB_colormanagement_processor_apply_v4(color_processor, preview_pixels + index);
rgba_float_to_uchar(preview.rect + index, preview_pixels + index);
}
}
});
/* Restore original swizzle mask set above. */
if (input_result.type() == ResultType::Float) {
GPU_texture_swizzle_set(input_result.texture(), "rgba");
}
IMB_colormanagement_processor_free(color_processor);
MEM_freeN(preview_pixels);
}
void NodeOperation::compute_results_reference_counts(const Schedule &schedule)
{
for (const bNodeSocket *output : this->node()->output_sockets()) {

View File

@ -2,6 +2,7 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_assert.h"
#include "BLI_math_matrix_types.hh"
#include "BLI_math_vector_types.hh"
@ -133,6 +134,33 @@ void Result::pass_through(Result &target)
target.master_ = this;
}
void Result::steal_data(Result &source)
{
BLI_assert(type_ == source.type_);
BLI_assert(!is_allocated() && source.is_allocated());
BLI_assert(master_ == nullptr && source.master_ == nullptr);
is_single_value_ = source.is_single_value_;
texture_ = source.texture_;
texture_pool_ = source.texture_pool_;
domain_ = source.domain_;
switch (type_) {
case ResultType::Float:
float_value_ = source.float_value_;
break;
case ResultType::Vector:
vector_value_ = source.vector_value_;
break;
case ResultType::Color:
color_value_ = source.color_value_;
break;
}
source.texture_ = nullptr;
source.texture_pool_ = nullptr;
}
void Result::transform(const float3x3 &transformation)
{
domain_.transform(transformation);
@ -235,6 +263,7 @@ void Result::release()
reference_count_--;
if (reference_count_ == 0) {
texture_pool_->release(texture_);
texture_ = nullptr;
}
}

View File

@ -71,6 +71,15 @@ void ShaderOperation::execute()
GPU_shader_unbind();
}
void ShaderOperation::compute_preview()
{
for (const DOutputSocket &output : preview_outputs_) {
Result &result = get_result(get_output_identifier_from_output_socket(output));
compute_preview_from_result(context(), output.node(), result);
result.release();
}
}
StringRef ShaderOperation::get_output_identifier_from_output_socket(DOutputSocket output_socket)
{
return output_sockets_to_output_identifiers_map_.lookup(output_socket);
@ -84,7 +93,7 @@ Map<std::string, DOutputSocket> &ShaderOperation::get_inputs_to_linked_outputs_m
void ShaderOperation::compute_results_reference_counts(const Schedule &schedule)
{
for (const auto item : output_sockets_to_output_identifiers_map_.items()) {
const int reference_count = number_of_inputs_linked_to_output_conditioned(
int reference_count = number_of_inputs_linked_to_output_conditioned(
item.key, [&](DInputSocket input) {
/* We only consider inputs that are not part of the shader operations, because inputs
* that are part of the shader operations are internal and do not deal with the result
@ -92,6 +101,10 @@ void ShaderOperation::compute_results_reference_counts(const Schedule &schedule)
return schedule.contains(input.node()) && !compile_unit_.contains(input.node());
});
if (preview_outputs_.contains(item.key)) {
reference_count++;
}
get_result(item.value).set_initial_reference_count(reference_count);
}
}
@ -248,17 +261,41 @@ void ShaderOperation::declare_operation_input(DInputSocket input_socket,
inputs_to_linked_outputs_map_.add_new(input_identifier, output_socket);
}
static DOutputSocket find_preview_output_socket(const DNode &node)
{
if (!is_node_preview_needed(node)) {
return DOutputSocket();
}
for (const bNodeSocket *output : node->output_sockets()) {
if (output->is_logically_linked()) {
return DOutputSocket(node.context(), output);
}
}
return DOutputSocket();
}
void ShaderOperation::populate_results_for_node(DNode node, GPUMaterial *material)
{
const DOutputSocket preview_output = find_preview_output_socket(node);
for (const bNodeSocket *output : node->output_sockets()) {
const DOutputSocket doutput{node.context(), output};
/* If any of the nodes linked to the output are not part of the shader operation, then an
* output result needs to be populated for it. */
const bool need_to_populate_result = is_output_linked_to_node_conditioned(
const bool is_operation_output = is_output_linked_to_node_conditioned(
doutput, [&](DNode node) { return !compile_unit_.contains(node); });
if (need_to_populate_result) {
/* If the output is used as the node preview, then an output result needs to be populated for
* it, and we additionally keep track of that output to later compute the previes from. */
const bool is_preview_output = doutput == preview_output;
if (is_preview_output) {
preview_outputs_.add(doutput);
}
if (is_operation_output || is_preview_output) {
populate_operation_result(doutput, material);
}
}

View File

@ -4,10 +4,15 @@
#include "BLI_assert.h"
#include "BLI_function_ref.hh"
#include "BLI_index_range.hh"
#include "BLI_math_color.h"
#include "BLI_math_vector.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_task.hh"
#include "BLI_utildefines.h"
#include "IMB_colormanagement.h"
#include "DNA_node_types.h"
#include "NOD_derived_node_tree.hh"
@ -133,4 +138,100 @@ void compute_dispatch_threads_at_least(GPUShader *shader, int2 threads_range, in
GPU_compute_dispatch(shader, groups_to_dispatch.x, groups_to_dispatch.y, 1);
}
bool is_node_preview_needed(const DNode &node)
{
if (!(node->flag & NODE_PREVIEW)) {
return false;
}
if (node->flag & NODE_HIDDEN) {
return false;
}
/* Only compute previews for nodes in the active context. */
if (node.context()->instance_key().value !=
node.context()->derived_tree().active_context().instance_key().value)
{
return false;
}
return true;
}
/* Given the size of a result, compute a lower resolution size for a preview. The greater dimension
* will be assigned an arbitrarily chosen size of 128, while the other dimension will get the size
* that maintains the same aspect ratio. */
static int2 compute_preview_size(int2 size)
{
const int greater_dimension_size = 128;
if (size.x > size.y) {
return int2(greater_dimension_size, int(greater_dimension_size * (float(size.y) / size.x)));
}
else {
return int2(int(greater_dimension_size * (float(size.x) / size.y)), greater_dimension_size);
}
}
void compute_preview_from_result(Context &context, const DNode &node, Result &input_result)
{
/* Initialize node tree previews if not already initialized. */
bNodeTree *root_tree = const_cast<bNodeTree *>(
&node.context()->derived_tree().root_context().btree());
if (!root_tree->previews) {
root_tree->previews = BKE_node_instance_hash_new("node previews");
}
const int2 preview_size = compute_preview_size(input_result.domain().size);
node->runtime->preview_xsize = preview_size.x;
node->runtime->preview_ysize = preview_size.y;
bNodePreview *preview = bke::node_preview_verify(
root_tree->previews, node.instance_key(), preview_size.x, preview_size.y, true);
GPUShader *shader = context.shader_manager().get("compositor_compute_preview");
GPU_shader_bind(shader);
if (input_result.type() == ResultType::Float) {
GPU_texture_swizzle_set(input_result.texture(), "rrr1");
}
input_result.bind_as_texture(shader, "input_tx");
Result preview_result = Result::Temporary(ResultType::Color, context.texture_pool());
preview_result.allocate_texture(Domain(preview_size));
preview_result.bind_as_image(shader, "preview_img");
compute_dispatch_threads_at_least(shader, preview_size);
input_result.unbind_as_texture();
preview_result.unbind_as_image();
GPU_shader_unbind();
GPU_memory_barrier(GPU_BARRIER_TEXTURE_FETCH);
float *preview_pixels = static_cast<float *>(
GPU_texture_read(preview_result.texture(), GPU_DATA_FLOAT, 0));
preview_result.release();
ColormanageProcessor *color_processor = IMB_colormanagement_display_processor_new(
&context.get_scene().view_settings, &context.get_scene().display_settings);
threading::parallel_for(IndexRange(preview_size.y), 1, [&](const IndexRange sub_y_range) {
for (const int64_t y : sub_y_range) {
for (const int64_t x : IndexRange(preview_size.x)) {
const int index = (y * preview_size.x + x) * 4;
IMB_colormanagement_processor_apply_v4(color_processor, preview_pixels + index);
rgba_float_to_uchar(preview->rect + index, preview_pixels + index);
}
}
});
/* Restore original swizzle mask set above. */
if (input_result.type() == ResultType::Float) {
GPU_texture_swizzle_set(input_result.texture(), "rgba");
}
IMB_colormanagement_processor_free(color_processor);
MEM_freeN(preview_pixels);
}
} // namespace blender::realtime_compositor

View File

@ -0,0 +1,21 @@
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
void main()
{
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
vec4 key = texture_load(key_tx, texel);
vec4 color = texture_load(input_tx, texel);
float matte = texture_load(matte_tx, texel).x;
/* Alpha multiply the matte to the image. */
color *= matte;
/* Color despill. */
ivec3 key_argmax = argmax(key.rgb);
float weighted_average = mix(color[key_argmax.y], color[key_argmax.z], despill_balance);
color[key_argmax.x] -= (color[key_argmax.x] - weighted_average) * despill_factor;
imageStore(output_img, texel, color);
}

View File

@ -0,0 +1,32 @@
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
float compute_saturation(vec4 color, ivec3 argmax)
{
float weighted_average = mix(color[argmax.y], color[argmax.z], key_balance);
return (color[argmax.x] - weighted_average) * abs(1.0 - weighted_average);
}
void main()
{
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
vec4 input_color = texture_load(input_tx, texel);
/* We assume that the keying screen will not be overexposed in the image, so if the input
* brightness is high, we assume the pixel is opaque. */
if (min_v3(input_color) > 1.0f) {
imageStore(output_img, texel, vec4(1.0));
return;
}
vec4 key_color = texture_load(key_tx, texel);
ivec3 key_argmax = argmax(key_color.rgb);
float input_saturation = compute_saturation(input_color, key_argmax);
float key_saturation = compute_saturation(key_color, key_argmax);
float matte = 1.0f - clamp(input_saturation / key_saturation, 0.0, 1.0);
imageStore(output_img, texel, vec4(matte));
}

View File

@ -0,0 +1,12 @@
#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
void main()
{
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
vec4 color_ycca;
rgba_to_ycca_itu_709(texture_load(input_tx, texel), color_ycca);
imageStore(output_img, texel, color_ycca);
}

View File

@ -0,0 +1,17 @@
#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
void main()
{
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
vec4 color_ycca;
rgba_to_ycca_itu_709(texture_load(input_tx, texel), color_ycca);
color_ycca.yz = texture_load(new_chroma_tx, texel).yz;
vec4 color_rgba;
ycca_to_rgba_itu_709(color_ycca, color_rgba);
imageStore(output_img, texel, color_rgba);
}

View File

@ -0,0 +1,54 @@
#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
void main()
{
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
float matte = texture_load(input_matte_tx, texel).x;
/* Search the neighbourhood around the current matte value and identify if it lies along the
* edges of the matte. This is needs to be computed only when we need to compute the edges output
* or tweak the levels of the matte. */
bool is_edge = false;
if (compute_edges || black_level != 0.0 || white_level != 1.0) {
/* Count the number of neighbours whose matte is sufficiently similar to the current matte,
* as controlled by the edge_tolerance factor. */
int count = 0;
for (int j = -edge_search_radius; j <= edge_search_radius; j++) {
for (int i = -edge_search_radius; i <= edge_search_radius; i++) {
float neighbour_matte = texture_load(input_matte_tx, texel + ivec2(i, j)).x;
count += int(distance(matte, neighbour_matte) < edge_tolerance);
}
}
/* If the number of neighbours that are sufficiently similar to the center matte is less that
* 90% of the total number of neighbours, then that means the variance is high in that areas
* and it is considered an edge. */
is_edge = count < ((edge_search_radius * 2 + 1) * (edge_search_radius * 2 + 1)) * 0.9;
}
float tweaked_matte = matte;
/* Remap the matte using the black and white levels, but only for areas that are not on the edge
* of the matte to preserve details. Also check for equality between levels to avoid zero
* division. */
if (!is_edge && white_level != black_level) {
tweaked_matte = clamp((matte - black_level) / (white_level - black_level), 0.0, 1.0);
}
/* Exclude unwanted areas using the provided garbage matte, 1 means unwanted, so invert the
* garbage matte and take the minimum. */
if (apply_garbage_matte) {
float garbage_matte = texture_load(garbage_matte_tx, texel).x;
tweaked_matte = min(tweaked_matte, 1.0 - garbage_matte);
}
/* Include wanted areas that were incorrectly keyed using the provided core matte. */
if (apply_core_matte) {
float core_matte = texture_load(core_matte_tx, texel).x;
tweaked_matte = max(tweaked_matte, core_matte);
}
imageStore(output_matte_img, texel, vec4(tweaked_matte));
imageStore(output_edges_img, texel, vec4(is_edge ? 1.0 : 0.0));
}

View File

@ -0,0 +1,57 @@
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "gpu_shader_create_info.hh"
GPU_SHADER_CREATE_INFO(compositor_keying_extract_chroma)
.local_group_size(16, 16)
.sampler(0, ImageType::FLOAT_2D, "input_tx")
.image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
.compute_source("compositor_keying_extract_chroma.glsl")
.do_static_compilation(true);
GPU_SHADER_CREATE_INFO(compositor_keying_replace_chroma)
.local_group_size(16, 16)
.sampler(0, ImageType::FLOAT_2D, "input_tx")
.sampler(1, ImageType::FLOAT_2D, "new_chroma_tx")
.image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
.compute_source("compositor_keying_replace_chroma.glsl")
.do_static_compilation(true);
GPU_SHADER_CREATE_INFO(compositor_keying_compute_matte)
.local_group_size(16, 16)
.push_constant(Type::FLOAT, "key_balance")
.sampler(0, ImageType::FLOAT_2D, "input_tx")
.sampler(1, ImageType::FLOAT_2D, "key_tx")
.image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
.compute_source("compositor_keying_compute_matte.glsl")
.do_static_compilation(true);
GPU_SHADER_CREATE_INFO(compositor_keying_tweak_matte)
.local_group_size(16, 16)
.push_constant(Type::BOOL, "compute_edges")
.push_constant(Type::BOOL, "apply_core_matte")
.push_constant(Type::BOOL, "apply_garbage_matte")
.push_constant(Type::INT, "edge_search_radius")
.push_constant(Type::FLOAT, "edge_tolerance")
.push_constant(Type::FLOAT, "black_level")
.push_constant(Type::FLOAT, "white_level")
.sampler(0, ImageType::FLOAT_2D, "input_matte_tx")
.sampler(1, ImageType::FLOAT_2D, "garbage_matte_tx")
.sampler(2, ImageType::FLOAT_2D, "core_matte_tx")
.image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_matte_img")
.image(1, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_edges_img")
.compute_source("compositor_keying_tweak_matte.glsl")
.do_static_compilation(true);
GPU_SHADER_CREATE_INFO(compositor_keying_compute_image)
.local_group_size(16, 16)
.push_constant(Type::FLOAT, "despill_factor")
.push_constant(Type::FLOAT, "despill_balance")
.sampler(0, ImageType::FLOAT_2D, "input_tx")
.sampler(1, ImageType::FLOAT_2D, "matte_tx")
.sampler(2, ImageType::FLOAT_2D, "key_tx")
.image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
.compute_source("compositor_keying_compute_image.glsl")
.do_static_compilation(true);

View File

@ -4,13 +4,21 @@
#include "gpu_shader_create_info.hh"
GPU_SHADER_CREATE_INFO(compositor_symmetric_separable_blur)
GPU_SHADER_CREATE_INFO(compositor_symmetric_separable_blur_shared)
.local_group_size(16, 16)
.push_constant(Type::BOOL, "extend_bounds")
.push_constant(Type::BOOL, "gamma_correct_input")
.push_constant(Type::BOOL, "gamma_uncorrect_output")
.sampler(0, ImageType::FLOAT_2D, "input_tx")
.sampler(1, ImageType::FLOAT_1D, "weights_tx")
.image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
.compute_source("compositor_symmetric_separable_blur.glsl")
.compute_source("compositor_symmetric_separable_blur.glsl");
GPU_SHADER_CREATE_INFO(compositor_symmetric_separable_blur_float)
.additional_info("compositor_symmetric_separable_blur_shared")
.image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
.do_static_compilation(true);
GPU_SHADER_CREATE_INFO(compositor_symmetric_separable_blur_color)
.additional_info("compositor_symmetric_separable_blur_shared")
.image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
.do_static_compilation(true);

View File

@ -149,8 +149,8 @@ set(SRC
engines/eevee_next/eevee_instance.cc
engines/eevee_next/eevee_irradiance_cache.cc
engines/eevee_next/eevee_light.cc
engines/eevee_next/eevee_lightprobe.cc
engines/eevee_next/eevee_lightcache.cc
engines/eevee_next/eevee_lightprobe.cc
engines/eevee_next/eevee_material.cc
engines/eevee_next/eevee_motion_blur.cc
engines/eevee_next/eevee_pipeline.cc
@ -159,8 +159,8 @@ set(SRC
engines/eevee_next/eevee_sampling.cc
engines/eevee_next/eevee_shader.cc
engines/eevee_next/eevee_shadow.cc
engines/eevee_next/eevee_sync.cc
engines/eevee_next/eevee_subsurface.cc
engines/eevee_next/eevee_sync.cc
engines/eevee_next/eevee_velocity.cc
engines/eevee_next/eevee_view.cc
engines/eevee_next/eevee_world.cc
@ -292,6 +292,7 @@ set(SRC
engines/eevee_next/eevee_irradiance_cache.hh
engines/eevee_next/eevee_light.hh
engines/eevee_next/eevee_lightcache.hh
engines/eevee_next/eevee_lightprobe.hh
engines/eevee_next/eevee_material.hh
engines/eevee_next/eevee_motion_blur.hh
engines/eevee_next/eevee_pipeline.hh
@ -300,8 +301,8 @@ set(SRC
engines/eevee_next/eevee_sampling.hh
engines/eevee_next/eevee_shader.hh
engines/eevee_next/eevee_shadow.hh
engines/eevee_next/eevee_sync.hh
engines/eevee_next/eevee_subsurface.hh
engines/eevee_next/eevee_sync.hh
engines/eevee_next/eevee_velocity.hh
engines/eevee_next/eevee_view.hh
engines/eevee_next/eevee_world.hh

View File

@ -163,9 +163,12 @@ class Context : public realtime_compositor::Context {
return DRW_viewport_texture_list_get()->color;
}
GPUTexture *get_input_texture(int view_layer, const char *pass_name) override
GPUTexture *get_input_texture(const Scene *scene, int view_layer, const char *pass_name) override
{
if (view_layer == 0 && STREQ(pass_name, RE_PASSNAME_COMBINED)) {
if ((DEG_get_original_id(const_cast<ID *>(&scene->id)) ==
DEG_get_original_id(&DRW_context_state_get()->scene->id)) &&
view_layer == 0 && STREQ(pass_name, RE_PASSNAME_COMBINED))
{
return get_output_texture();
}
else {

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -1,4 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee

View File

@ -2130,7 +2130,7 @@ void DRW_custom_pipeline_begin(DrawEngineType *draw_engine_type, Depsgraph *deps
DRW_view_data_engine_data_get_ensure(DST.view_data_active, draw_engine_type);
}
void DRW_custom_pipeline_end()
void DRW_custom_pipeline_end(void)
{
DST.buffer_finish_called = false;
@ -3187,8 +3187,7 @@ void DRW_render_context_enable(Render *render)
if (re_system_gpu_context != NULL) {
DRW_system_gpu_render_context_enable(re_system_gpu_context);
/* We need to query gpu context after a gl context has been bound. */
void *re_blender_gpu_context = NULL;
re_blender_gpu_context = RE_blender_gpu_context_get(render);
void *re_blender_gpu_context = RE_blender_gpu_context_ensure(render);
DRW_blender_gpu_render_context_enable(re_blender_gpu_context);
}
else {
@ -3208,8 +3207,7 @@ void DRW_render_context_disable(Render *render)
void *re_system_gpu_context = RE_system_gpu_context_get(render);
if (re_system_gpu_context != NULL) {
void *re_blender_gpu_context = NULL;
re_blender_gpu_context = RE_blender_gpu_context_get(render);
void *re_blender_gpu_context = RE_blender_gpu_context_ensure(render);
/* GPU rendering may occur during context disable. */
DRW_blender_gpu_render_context_disable(re_blender_gpu_context);
GPU_render_end();

View File

@ -264,6 +264,13 @@ static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred)
deferred = false;
}
/* Avoid crashes with RenderDoc on Windows + Nvidia. */
if (G.debug & G_DEBUG_GPU_RENDERDOC &&
GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_OFFICIAL))
{
deferred = false;
}
if (!deferred) {
DRW_deferred_shader_remove(mat);
/* Shaders could already be compiling. Have to wait for compilation to finish. */

View File

@ -54,6 +54,20 @@ mat2 rot2_from_angle(float a)
return mat2(c, -s, s, c);
}
/* Computes the full argmax of the given vector, that is, the index of the greatest component will
* be in the returned x component, the index of the smallest component will be in the returned z
* component, and the index of the middle component will be in the returned y component.
*
* This is computed by utilizing the fact that booleans are converted to the integers 0 and 1 for
* false and true respectively. So if we compare every component to all other components using the
* greaterThan comparator, we get 0 for the greatest component, because no other component is
* greater, 1 for the middle component, and 2 for the smallest component. */
ivec3 argmax(vec3 v)
{
return ivec3(greaterThan(v, v.xxx)) + ivec3(greaterThan(v, v.yyy)) +
ivec3(greaterThan(v, v.zzz));
}
#define min3(a, b, c) min(a, min(b, c))
#define min4(a, b, c, d) min(a, min3(b, c, d))
#define min5(a, b, c, d, e) min(a, min4(b, c, d, e))

View File

@ -268,7 +268,7 @@ struct AssetEntryWriter {
void add_catalog_id(const CatalogID &catalog_id)
{
char catalog_id_str[UUID_STRING_LEN];
char catalog_id_str[UUID_STRING_SIZE];
BLI_uuid_format(catalog_id_str, catalog_id);
attributes.append_as(std::pair(ATTRIBUTE_ENTRIES_CATALOG_ID, new StringValue(catalog_id_str)));
}

View File

@ -5609,7 +5609,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Curve *cu;
float location[3];
const bool use_proj = ((vc.scene->toolsettings->snap_flag & SCE_SNAP) &&
(vc.scene->toolsettings->snap_mode == SCE_SNAP_MODE_FACE));
(vc.scene->toolsettings->snap_mode == SCE_SNAP_TO_FACE));
Nurb *nu;
BezTriple *bezt;
@ -5641,7 +5641,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
vc.depsgraph,
vc.region,
vc.v3d,
SCE_SNAP_MODE_FACE,
SCE_SNAP_TO_FACE,
&(const struct SnapObjectParams){
.snap_target_select = (vc.obedit != NULL) ? SCE_SNAP_TARGET_NOT_ACTIVE :
SCE_SNAP_TARGET_ALL,

View File

@ -394,7 +394,7 @@ static int insert_into_textbuf(Object *obedit, uintptr_t c)
return 0;
}
static void text_update_edited(bContext *C, Object *obedit, int mode)
static void text_update_edited(bContext *C, Object *obedit, const eEditFontMode mode)
{
Curve *cu = obedit->data;
EditFont *ef = cu->editfont;

View File

@ -280,7 +280,7 @@ static int gizmo_move_modal(bContext *C,
CTX_data_ensure_evaluated_depsgraph(C),
region,
CTX_wm_view3d(C),
(SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE),
(SCE_SNAP_TO_VERTEX | SCE_SNAP_TO_EDGE | SCE_SNAP_TO_FACE),
&(const struct SnapObjectParams){
.snap_target_select = SCE_SNAP_TARGET_ALL,
.edit_mode_type = SNAP_GEOM_EDIT,

View File

@ -266,7 +266,7 @@ static int snap_gizmo_test_select(bContext *C, wmGizmo *gz, const int mval[2])
ED_view3d_cursor_snap_data_update(snap_gizmo->snap_state, C, x, y);
V3DSnapCursorData *snap_data = ED_view3d_cursor_snap_data_get();
if (snap_data->snap_elem != SCE_SNAP_MODE_NONE) {
if (snap_data->snap_elem != SCE_SNAP_TO_NONE) {
return 0;
}
return -1;

View File

@ -201,7 +201,6 @@ static int select_alternate_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
Object *object = CTX_data_active_object(C);
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
eAttrDomain selection_domain = ED_grease_pencil_selection_domain_get(C);
grease_pencil.foreach_editable_drawing(
scene->r.cfra, [&](int /*drawing_index*/, GreasePencilDrawing &drawing) {
@ -223,7 +222,7 @@ static void GREASE_PENCIL_OT_select_alternate(wmOperatorType *ot)
ot->description = "Select alternated points in strokes with already selected points";
ot->exec = select_alternate_exec;
ot->poll = editable_grease_pencil_poll;
ot->poll = editable_grease_pencil_point_selection_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;

View File

@ -9,6 +9,7 @@
#pragma once
#include "BLI_compiler_attrs.h"
#include "BLI_string_utf8_symbols.h"
#include "BLI_sys_types.h" /* size_t */
#include "BLI_utildefines.h"
#include "UI_interface_icons.h"
@ -87,7 +88,7 @@ typedef struct uiViewItemHandle uiViewItemHandle;
/* Separator for text in search menus (right pointing arrow).
* keep in sync with `string_search.cc`. */
#define UI_MENU_ARROW_SEP "\xe2\x96\xb8"
#define UI_MENU_ARROW_SEP BLI_STR_UTF8_BLACK_RIGHT_POINTING_SMALL_TRIANGLE
/* names */
#define UI_MAX_DRAW_STR 400
@ -1937,7 +1938,7 @@ struct Panel *UI_panel_add_instanced(const struct bContext *C,
*/
void UI_panels_free_instanced(const struct bContext *C, struct ARegion *region);
#define INSTANCED_PANEL_UNIQUE_STR_LEN 16
#define INSTANCED_PANEL_UNIQUE_STR_SIZE 16
/**
* Find a unique key to append to the #PanelType.idname for the lookup to the panel's #uiBlock.
* Needed for instanced panels, where there can be multiple with the same type and identifier.

View File

@ -69,8 +69,8 @@ set(SRC
interface_style.cc
interface_template_asset_view.cc
interface_template_attribute_search.cc
interface_template_light_linking.cc
interface_template_grease_pencil_layer_tree.cc
interface_template_light_linking.cc
interface_template_list.cc
interface_template_search_menu.cc
interface_template_search_operator.cc

View File

@ -79,12 +79,12 @@ void icon_draw_rect_input(
icon_draw_rect_input_text(&rect, color, str, event_type > EVT_F9KEY ? 8.5f : 11.5f, 0.0f);
}
else if (event_type == EVT_LEFTSHIFTKEY) { /* Right Shift has already been converted to left. */
const char str[] = {0xe2, 0x87, 0xa7, 0x0};
const char str[] = BLI_STR_UTF8_UPWARDS_WHITE_ARROW;
icon_draw_rect_input_text(&rect, color, str, 16.0f, 0.0f);
}
else if (event_type == EVT_LEFTCTRLKEY) { /* Right Shift has already been converted to left. */
if (platform == MACOS) {
const char str[] = {0xe2, 0x8c, 0x83, 0x0};
const char str[] = BLI_STR_UTF8_UP_ARROWHEAD;
icon_draw_rect_input_text(&rect, color, str, 21.0f, -8.0f);
}
else {
@ -93,7 +93,7 @@ void icon_draw_rect_input(
}
else if (event_type == EVT_LEFTALTKEY) { /* Right Alt has already been converted to left. */
if (platform == MACOS) {
const char str[] = {0xe2, 0x8c, 0xa5, 0x0};
const char str[] = BLI_STR_UTF8_OPTION_KEY;
icon_draw_rect_input_text(&rect, color, str, 13.0f, 0.0f);
}
else {
@ -102,11 +102,11 @@ void icon_draw_rect_input(
}
else if (event_type == EVT_OSKEY) {
if (platform == MACOS) {
const char str[] = {0xe2, 0x8c, 0x98, 0x0};
const char str[] = BLI_STR_UTF8_PLACE_OF_INTEREST_SIGN;
icon_draw_rect_input_text(&rect, color, str, 16.0f, 0.0f);
}
else if (platform == MSWIN) {
const char str[] = {0xe2, 0x9d, 0x96, 0x0};
const char str[] = BLI_STR_UTF8_BLACK_DIAMOND_MINUS_WHITE_X;
icon_draw_rect_input_text(&rect, color, str, 16.0f, 0.0f);
}
else {
@ -117,7 +117,7 @@ void icon_draw_rect_input(
icon_draw_rect_input_text(&rect, color, "Del", 9.0f, 0.0f);
}
else if (event_type == EVT_TABKEY) {
const char str[] = {0xe2, 0xad, 0xbe, 0x0};
const char str[] = BLI_STR_UTF8_HORIZONTAL_TAB_KEY;
icon_draw_rect_input_text(&rect, color, str, 18.0f, -1.5f);
}
else if (event_type == EVT_HOMEKEY) {
@ -127,12 +127,12 @@ void icon_draw_rect_input(
icon_draw_rect_input_text(&rect, color, "End", 8.0f, 0.0f);
}
else if (event_type == EVT_RETKEY) {
const char str[] = {0xe2, 0x8f, 0x8e, 0x0};
const char str[] = BLI_STR_UTF8_RETURN_SYMBOL;
icon_draw_rect_input_text(&rect, color, str, 17.0f, -1.0f);
}
else if (event_type == EVT_ESCKEY) {
if (platform == MACOS) {
const char str[] = {0xe2, 0x8e, 0x8b, 0x0};
const char str[] = BLI_STR_UTF8_BROKEN_CIRCLE_WITH_NORTHWEST_ARROW;
icon_draw_rect_input_text(&rect, color, str, 21.0f, -1.0f);
}
else {
@ -140,31 +140,31 @@ void icon_draw_rect_input(
}
}
else if (event_type == EVT_PAGEUPKEY) {
const char str[] = {'P', 0xe2, 0x86, 0x91, 0x0};
const char str[] = "P" BLI_STR_UTF8_UPWARDS_ARROW;
icon_draw_rect_input_text(&rect, color, str, 12.0f, 0.0f);
}
else if (event_type == EVT_PAGEDOWNKEY) {
const char str[] = {'P', 0xe2, 0x86, 0x93, 0x0};
const char str[] = "P" BLI_STR_UTF8_DOWNWARDS_ARROW;
icon_draw_rect_input_text(&rect, color, str, 12.0f, 0.0f);
}
else if (event_type == EVT_LEFTARROWKEY) {
const char str[] = {0xe2, 0x86, 0x90, 0x0};
const char str[] = BLI_STR_UTF8_LEFTWARDS_ARROW;
icon_draw_rect_input_text(&rect, color, str, 18.0f, -1.5f);
}
else if (event_type == EVT_UPARROWKEY) {
const char str[] = {0xe2, 0x86, 0x91, 0x0};
const char str[] = BLI_STR_UTF8_UPWARDS_ARROW;
icon_draw_rect_input_text(&rect, color, str, 16.0f, 0.0f);
}
else if (event_type == EVT_RIGHTARROWKEY) {
const char str[] = {0xe2, 0x86, 0x92, 0x0};
const char str[] = BLI_STR_UTF8_RIGHTWARDS_ARROW;
icon_draw_rect_input_text(&rect, color, str, 18.0f, -1.5f);
}
else if (event_type == EVT_DOWNARROWKEY) {
const char str[] = {0xe2, 0x86, 0x93, 0x0};
const char str[] = BLI_STR_UTF8_DOWNWARDS_ARROW;
icon_draw_rect_input_text(&rect, color, str, 16.0f, 0.0f);
}
else if (event_type == EVT_SPACEKEY) {
const char str[] = {0xe2, 0x90, 0xa3, 0x0};
const char str[] = BLI_STR_UTF8_OPEN_BOX;
icon_draw_rect_input_text(&rect, color, str, 20.0f, 2.0f);
}
}

View File

@ -283,7 +283,7 @@ void UI_list_panel_unique_str(Panel *panel, char *r_name)
{
/* The panel sort-order will be unique for a specific panel type because the instanced
* panel list is regenerated for every change in the data order / length. */
BLI_snprintf(r_name, INSTANCED_PANEL_UNIQUE_STR_LEN, "%d", panel->sortorder);
BLI_snprintf(r_name, INSTANCED_PANEL_UNIQUE_STR_SIZE, "%d", panel->sortorder);
}
/**

View File

@ -1538,8 +1538,7 @@ float UI_text_clip_middle_ex(const uiFontStyle *fstyle,
float strwidth = BLF_width(fstyle->uifont_id, str, max_len);
if ((okwidth > 0.0f) && (strwidth > okwidth)) {
/* Ellipsis. Some compilers complain with real literal string. */
const char sep[] = {0xe2, 0x80, 0xA6, 0x0};
const char sep[] = BLI_STR_UTF8_HORIZONTAL_ELLIPSIS;
const int sep_len = sizeof(sep) - 1;
const float sep_strwidth = BLF_width(fstyle->uifont_id, sep, sep_len + 1);

View File

@ -230,7 +230,7 @@ static int wm_ply_import_invoke(bContext *C, wmOperator *op, const wmEvent *even
return WM_operator_filesel(C, op, event);
}
static int wm_ply_import_execute(bContext *C, wmOperator *op)
static int wm_ply_import_exec(bContext *C, wmOperator *op)
{
PLYImportParams params{};
params.forward_axis = eIOAxis(RNA_enum_get(op->ptr, "forward_axis"));
@ -283,7 +283,7 @@ void WM_OT_ply_import(wmOperatorType *ot)
ot->idname = "WM_OT_ply_import";
ot->invoke = wm_ply_import_invoke;
ot->exec = wm_ply_import_execute;
ot->exec = wm_ply_import_exec;
ot->poll = WM_operator_winactive;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_PRESET;

View File

@ -29,7 +29,7 @@ static int wm_stl_import_invoke(bContext *C, wmOperator *op, const wmEvent *even
return WM_operator_filesel(C, op, event);
}
static int wm_stl_import_execute(bContext *C, wmOperator *op)
static int wm_stl_import_exec(bContext *C, wmOperator *op)
{
STLImportParams params{};
params.forward_axis = eIOAxis(RNA_enum_get(op->ptr, "forward_axis"));
@ -95,7 +95,7 @@ void WM_OT_stl_import(wmOperatorType *ot)
ot->idname = "WM_OT_stl_import";
ot->invoke = wm_stl_import_invoke;
ot->exec = wm_stl_import_execute;
ot->exec = wm_stl_import_exec;
ot->poll = WM_operator_winactive;
ot->check = wm_stl_import_check;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_PRESET;

View File

@ -710,7 +710,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w
const bool rot_src = RNA_boolean_get(op->ptr, "rotate_source");
const bool use_proj = ((vc.scene->toolsettings->snap_flag & SCE_SNAP) &&
(vc.scene->toolsettings->snap_mode == SCE_SNAP_MODE_FACE));
(vc.scene->toolsettings->snap_mode == SCE_SNAP_TO_FACE));
/* First calculate the center of transformation. */
zero_v3(center);

View File

@ -1951,7 +1951,7 @@ void EDBM_project_snap_verts(
depsgraph,
region,
CTX_wm_view3d(C),
SCE_SNAP_MODE_FACE,
SCE_SNAP_TO_FACE,
&params,
nullptr,
mval,

View File

@ -362,7 +362,7 @@ static void bake_simulation_job_endjob(void *customdata)
WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, nullptr);
}
static int bake_simulation_execute(bContext *C, wmOperator *op)
static int bake_simulation_exec(bContext *C, wmOperator *op)
{
wmWindowManager *wm = CTX_wm_manager(C);
Scene *scene = CTX_data_scene(C);
@ -556,7 +556,7 @@ static int bake_simulation_invoke(bContext *C, wmOperator *op, const wmEvent * /
if (has_existing_bake_data) {
return WM_operator_confirm_message(C, op, "Overwrite existing bake data");
}
return bake_simulation_execute(C, op);
return bake_simulation_exec(C, op);
}
static int bake_simulation_modal(bContext *C, wmOperator * /*op*/, const wmEvent * /*event*/)
@ -647,7 +647,7 @@ void OBJECT_OT_simulation_nodes_cache_bake(wmOperatorType *ot)
ot->description = "Bake simulations in geometry nodes modifiers";
ot->idname = __func__;
ot->exec = bake_simulation_execute;
ot->exec = bake_simulation_exec;
ot->invoke = bake_simulation_invoke;
ot->modal = bake_simulation_modal;
ot->poll = bake_simulation_poll;

View File

@ -15,6 +15,7 @@
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_rect.h"
#include "BLI_string_utils.h"
#include "BLI_threads.h"
#include "BLI_timecode.h"
#include "BLI_utildefines.h"
@ -402,17 +403,25 @@ static void render_freejob(void *rjv)
MEM_freeN(rj);
}
/* str is IMA_MAX_RENDER_TEXT in size */
static void make_renderinfo_string(const RenderStats *rs,
const Scene *scene,
const bool v3d_override,
const char *error,
char *str)
char ret[IMA_MAX_RENDER_TEXT])
{
char info_time_str[32]; /* used to be extern to header_info.c */
const char *info_space = " ";
const char *info_sep = "| ";
struct {
char time_last[32];
char time_elapsed[32];
char frame[16];
char statistics[64];
} info_buffers;
uintptr_t mem_in_use, peak_memory;
float megs_used_memory, megs_peak_memory;
char *spos = str;
const char *ret_array[32];
int i = 0;
mem_in_use = MEM_get_memory_in_use();
peak_memory = MEM_get_peak_memory();
@ -422,65 +431,96 @@ static void make_renderinfo_string(const RenderStats *rs,
/* local view */
if (rs->localview) {
spos += BLI_sprintf(spos, "%s | ", TIP_("3D Local View"));
ret_array[i++] = TIP_("3D Local View ");
ret_array[i++] = info_sep;
}
else if (v3d_override) {
spos += BLI_sprintf(spos, "%s | ", TIP_("3D View"));
ret_array[i++] = TIP_("3D View ");
ret_array[i++] = info_sep;
}
/* frame number */
spos += BLI_sprintf(spos, TIP_("Frame:%d "), (scene->r.cfra));
SNPRINTF(info_buffers.frame, "%d ", scene->r.cfra);
ret_array[i++] = TIP_("Frame:");
ret_array[i++] = info_buffers.frame;
/* previous and elapsed time */
BLI_timecode_string_from_time_simple(info_time_str, sizeof(info_time_str), rs->lastframetime);
/* Previous and elapsed time. */
const char *info_time = info_buffers.time_last;
BLI_timecode_string_from_time_simple(
info_buffers.time_last, sizeof(info_buffers.time_last), rs->lastframetime);
ret_array[i++] = info_sep;
if (rs->infostr && rs->infostr[0]) {
if (rs->lastframetime != 0.0) {
spos += BLI_sprintf(spos, TIP_("| Last:%s "), info_time_str);
ret_array[i++] = "Last:";
ret_array[i++] = info_buffers.time_last;
ret_array[i++] = info_space;
}
info_time = info_buffers.time_elapsed;
BLI_timecode_string_from_time_simple(info_buffers.time_elapsed,
sizeof(info_buffers.time_elapsed),
PIL_check_seconds_timer() - rs->starttime);
}
ret_array[i++] = TIP_("Time:");
ret_array[i++] = info_time;
ret_array[i++] = info_space;
/* Statistics. */
{
const char *info_statistics = nullptr;
if (rs->statstr) {
if (rs->statstr[0]) {
info_statistics = rs->statstr;
}
}
else {
spos += BLI_sprintf(spos, "| ");
if (rs->mem_peak == 0.0f) {
SNPRINTF(info_buffers.statistics,
TIP_("Mem:%.2fM (Peak %.2fM)"),
megs_used_memory,
megs_peak_memory);
}
else {
SNPRINTF(
info_buffers.statistics, TIP_("Mem:%.2fM, Peak: %.2fM"), rs->mem_used, rs->mem_peak);
}
info_statistics = info_buffers.statistics;
}
BLI_timecode_string_from_time_simple(
info_time_str, sizeof(info_time_str), PIL_check_seconds_timer() - rs->starttime);
}
else {
spos += BLI_sprintf(spos, "| ");
}
spos += BLI_sprintf(spos, TIP_("Time:%s "), info_time_str);
/* statistics */
if (rs->statstr) {
if (rs->statstr[0]) {
spos += BLI_sprintf(spos, "| %s ", rs->statstr);
}
}
else {
if (rs->mem_peak == 0.0f) {
spos += BLI_sprintf(
spos, TIP_("| Mem:%.2fM (Peak %.2fM) "), megs_used_memory, megs_peak_memory);
}
else {
spos += BLI_sprintf(spos, TIP_("| Mem:%.2fM, Peak: %.2fM "), rs->mem_used, rs->mem_peak);
if (info_statistics) {
ret_array[i++] = info_sep;
ret_array[i++] = info_statistics;
ret_array[i++] = info_space;
}
}
/* extra info */
if (rs->infostr && rs->infostr[0]) {
spos += BLI_sprintf(spos, "| %s ", rs->infostr);
}
else if (error && error[0]) {
spos += BLI_sprintf(spos, "| %s ", error);
/* Extra info. */
{
const char *info_extra = nullptr;
if (rs->infostr && rs->infostr[0]) {
info_extra = rs->infostr;
}
else if (error && error[0]) {
info_extra = error;
}
if (info_extra) {
ret_array[i++] = info_sep;
ret_array[i++] = info_extra;
ret_array[i++] = info_space;
}
}
/* very weak... but 512 characters is quite safe */
if (spos >= str + IMA_MAX_RENDER_TEXT) {
if (G.debug & G_DEBUG) {
if (G.debug & G_DEBUG) {
if (BLI_string_len_array(ret_array, i) >= IMA_MAX_RENDER_TEXT) {
printf("WARNING! renderwin text beyond limit\n");
}
}
BLI_assert(i < int(BOUNDED_ARRAY_TYPE_SIZE<decltype(ret_array)>()));
BLI_string_join_array(ret, IMA_MAX_RENDER_TEXT, ret_array, i);
}
static void image_renderinfo_cb(void *rjv, RenderStats *rs)
@ -1088,7 +1128,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
RE_current_scene_update_cb(re, rj, current_scene_update);
RE_stats_draw_cb(re, rj, image_renderinfo_cb);
RE_progress_cb(re, rj, render_progress_update);
RE_system_gpu_context_create(re);
RE_system_gpu_context_ensure(re);
rj->re = re;
G.is_break = false;

View File

@ -2695,7 +2695,7 @@ static void ed_panel_draw(const bContext *C,
const uiStyle *style = UI_style_get_dpi();
/* Draw panel. */
char block_name[BKE_ST_MAXNAME + INSTANCED_PANEL_UNIQUE_STR_LEN];
char block_name[BKE_ST_MAXNAME + INSTANCED_PANEL_UNIQUE_STR_SIZE];
if (unique_panel_str) {
/* Instanced panels should have already been added at this point. */
BLI_string_join(block_name, sizeof(block_name), pt->idname, unique_panel_str);
@ -3019,7 +3019,7 @@ void ED_region_panels_layout_ex(const bContext *C,
/* Use a unique identifier for instanced panels, otherwise an old block for a different
* panel of the same type might be found. */
char unique_panel_str[INSTANCED_PANEL_UNIQUE_STR_LEN];
char unique_panel_str[INSTANCED_PANEL_UNIQUE_STR_SIZE];
UI_list_panel_unique_str(panel, unique_panel_str);
ed_panel_draw(C,
region,

View File

@ -451,9 +451,13 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
immDrawPixelsTexSetupAttributes(&state);
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);
if (ibuf->float_buffer.colorspace) {
ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings,
display_settings,
ibuf->float_buffer.colorspace,
ibuf->dither,
true,
false);
}
else {
ok = IMB_colormanagement_setup_glsl_draw(
@ -461,8 +465,12 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
}
}
else {
ok = IMB_colormanagement_setup_glsl_draw_from_space(
view_settings, display_settings, ibuf->rect_colorspace, ibuf->dither, false, false);
ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings,
display_settings,
ibuf->byte_buffer.colorspace,
ibuf->dither,
false,
false);
}
if (ok) {

View File

@ -167,7 +167,7 @@ static void load_tex_task_cb_ex(void *__restrict userdata,
/* For consistency, sampling always returns color in linear space. */
if (tex_ibuf && tex_ibuf->float_buffer.data == nullptr) {
convert_to_linear = true;
colorspace = tex_ibuf->rect_colorspace;
colorspace = tex_ibuf->byte_buffer.colorspace;
}
BKE_image_pool_release_ibuf(mtex->tex->ima, tex_ibuf, pool);
}

View File

@ -327,7 +327,7 @@ static bool paint_brush_update(bContext *C,
brush->mtex.tex->ima, &brush->mtex.tex->iuser, nullptr);
if (tex_ibuf && tex_ibuf->float_buffer.data == nullptr) {
ups->do_linear_conversion = true;
ups->colorspace = tex_ibuf->rect_colorspace;
ups->colorspace = tex_ibuf->byte_buffer.colorspace;
}
BKE_image_pool_release_ibuf(brush->mtex.tex->ima, tex_ibuf, nullptr);
}

View File

@ -332,7 +332,7 @@ bool ED_space_clip_color_sample(const SpaceClip *sc,
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);
IMB_colormanagement_colorspace_to_scene_linear_v3(r_col, ibuf->byte_buffer.colorspace);
ret = true;
}
}

View File

@ -301,7 +301,7 @@ void AssetCatalogTreeViewItem::build_context_menu(bContext &C, uiLayout &column)
&props);
RNA_string_set(&props, "parent_path", catalog_item_.catalog_path().c_str());
char catalog_id_str_buffer[UUID_STRING_LEN] = "";
char catalog_id_str_buffer[UUID_STRING_SIZE] = "";
BLI_uuid_format(catalog_id_str_buffer, catalog_item_.get_catalog_id());
uiItemFullO(&column,
"ASSET_OT_catalog_delete",

View File

@ -3377,7 +3377,7 @@ bool ED_space_image_color_sample(
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);
IMB_colormanagement_colorspace_to_scene_linear_v3(r_col, ibuf->byte_buffer.colorspace);
ret = true;
}
}

View File

@ -61,7 +61,7 @@
#include "IMB_imbuf_types.h"
#include "NOD_composite.h"
#include "NOD_geometry.h"
#include "NOD_geometry.hh"
#include "NOD_node_declaration.hh"
#include "NOD_shader.h"
#include "NOD_texture.h"

View File

@ -66,7 +66,7 @@
#include "IMB_imbuf_types.h"
#include "NOD_composite.h"
#include "NOD_geometry.h"
#include "NOD_geometry.hh"
#include "NOD_shader.h"
#include "NOD_socket.h"
#include "NOD_texture.h"
@ -250,7 +250,7 @@ static void compo_initjob(void *cjv)
}
cj->re = RE_NewSceneRender(scene);
RE_system_gpu_context_create(cj->re);
RE_system_gpu_context_ensure(cj->re);
}
/* Called before redraw notifiers, it moves finished previews over. */
@ -309,8 +309,6 @@ static void compo_startjob(void *cjv,
}
}
RE_system_gpu_context_destroy(cj->re);
ntree->runtime->test_break = nullptr;
ntree->runtime->stats_draw = nullptr;
ntree->runtime->progress = nullptr;

View File

@ -51,7 +51,7 @@
#include "NOD_common.h"
#include "NOD_composite.h"
#include "NOD_geometry.h"
#include "NOD_geometry.hh"
#include "NOD_shader.h"
#include "NOD_socket.h"
#include "NOD_texture.h"

View File

@ -520,7 +520,7 @@ bool ED_space_node_color_sample(
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);
IMB_colormanagement_colorspace_to_scene_linear_v3(r_col, ibuf->byte_buffer.colorspace);
ret = true;
}
}
@ -593,7 +593,7 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
copy_v4_v4(info->linearcol, info->colf);
IMB_colormanagement_colorspace_to_scene_linear_v4(
info->linearcol, false, ibuf->rect_colorspace);
info->linearcol, false, ibuf->byte_buffer.colorspace);
info->color_manage = true;
}

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