EEVEE-Next: Shadow: Add LOD system to directional clipmap shadows #120031

Merged
Clément Foucault merged 16 commits from fclem/blender:eevee-next-shadow-directional-lod into main 2024-03-29 16:23:06 +01:00
321 changed files with 2823 additions and 2811 deletions
Showing only changes of commit 25f370c17b - Show all commits

View File

@ -109,12 +109,12 @@ typedef struct CLG_LogRef {
struct CLG_LogRef *next;
} CLG_LogRef;
void CLG_log_str(CLG_LogType *lg,
void CLG_log_str(const CLG_LogType *lg,
enum CLG_Severity severity,
const char *file_line,
const char *fn,
const char *message) _CLOG_ATTR_NONNULL(1, 3, 4, 5);
void CLG_logf(CLG_LogType *lg,
void CLG_logf(const CLG_LogType *lg,
enum CLG_Severity severity,
const char *file_line,
const char *fn,
@ -156,7 +156,7 @@ int CLG_color_support_get(CLG_LogRef *clg_ref);
#define CLOG_AT_SEVERITY(clg_ref, severity, verbose_level, ...) \
{ \
CLG_LogType *_lg_ty = CLOG_ENSURE(clg_ref); \
const CLG_LogType *_lg_ty = CLOG_ENSURE(clg_ref); \
if (((_lg_ty->flag & CLG_FLAG_USE) && (_lg_ty->level >= verbose_level)) || \
(severity >= CLG_SEVERITY_WARN)) \
{ \
@ -167,7 +167,7 @@ int CLG_color_support_get(CLG_LogRef *clg_ref);
#define CLOG_STR_AT_SEVERITY(clg_ref, severity, verbose_level, str) \
{ \
CLG_LogType *_lg_ty = CLOG_ENSURE(clg_ref); \
const CLG_LogType *_lg_ty = CLOG_ENSURE(clg_ref); \
if (((_lg_ty->flag & CLG_FLAG_USE) && (_lg_ty->level >= verbose_level)) || \
(severity >= CLG_SEVERITY_WARN)) \
{ \

View File

@ -429,7 +429,7 @@ static void write_severity(CLogStringBuf *cstr, enum CLG_Severity severity, bool
}
}
static void write_type(CLogStringBuf *cstr, CLG_LogType *lg)
static void write_type(CLogStringBuf *cstr, const CLG_LogType *lg)
{
clg_str_append(cstr, " (");
clg_str_append(cstr, lg->identifier);
@ -460,7 +460,7 @@ static void write_file_line_fn(CLogStringBuf *cstr,
clg_str_append(cstr, ": ");
}
void CLG_log_str(CLG_LogType *lg,
void CLG_log_str(const CLG_LogType *lg,
enum CLG_Severity severity,
const char *file_line,
const char *fn,
@ -498,7 +498,7 @@ void CLG_log_str(CLG_LogType *lg,
}
}
void CLG_logf(CLG_LogType *lg,
void CLG_logf(const CLG_LogType *lg,
enum CLG_Severity severity,
const char *file_line,
const char *fn,

View File

@ -235,8 +235,8 @@ def enum_preview_denoiser(self, context):
items = [
('AUTO',
"Automatic",
("Use the fastest available denoiser for viewport rendering "
"(OptiX if available, OpenImageDenoise otherwise)"),
("Use GPU accelerated denoising if supported, for the best performance. "
"Prefer OpenImageDenoise over OptiX"),
0)]
else:
items = [('AUTO', "None", "Blender was compiled without a viewport denoiser", 0)]

View File

@ -124,7 +124,8 @@ class DeviceInfo {
/* Multiple Devices with the same ID would be very bad. */
assert(id != info.id ||
(type == info.type && num == info.num && description == info.description));
return id == info.id;
return id == info.id && use_hardware_raytracing == info.use_hardware_raytracing &&
kernel_optimization_level == info.kernel_optimization_level;
}
};

View File

@ -492,13 +492,11 @@ ccl_device_forceinline bool area_light_tree_parameters(const ccl_global KernelLi
ccl_private float2 &distance,
ccl_private float3 &point_to_centroid)
{
if (!in_volume_segment) {
/* TODO: a cheap substitute for minimal distance between point and primitive. Does it
* worth the overhead to compute the accurate minimal distance? */
float min_distance;
point_to_centroid = safe_normalize_len(centroid - P, &min_distance);
distance = make_float2(min_distance, min_distance);
}
/* TODO: a cheap substitute for minimal distance between point and primitive. Does it worth the
* overhead to compute the accurate minimal distance? */
float min_distance;
point_to_centroid = safe_normalize_len(centroid - P, &min_distance);
distance = make_float2(min_distance, min_distance);
cos_theta_u = FLT_MAX;

View File

@ -196,21 +196,22 @@ ccl_device_forceinline bool point_light_tree_parameters(const ccl_global KernelL
ccl_private float2 &distance,
ccl_private float3 &point_to_centroid)
{
float min_distance;
point_to_centroid = safe_normalize_len(centroid - P, &min_distance);
distance = min_distance * one_float2();
if (in_volume_segment) {
cos_theta_u = 1.0f; /* Any value in [-1, 1], irrelevant since theta = 0 */
return true;
}
float dist_point_to_centroid;
point_to_centroid = safe_normalize_len(centroid - P, &dist_point_to_centroid);
const float radius = klight->spot.radius;
if (klight->spot.is_sphere) {
if (dist_point_to_centroid > radius) {
if (min_distance > radius) {
/* Equivalent to a disk light with the same angular span. */
cos_theta_u = cos_from_sin(radius / dist_point_to_centroid);
distance = dist_point_to_centroid * make_float2(1.0f / cos_theta_u, 1.0f);
cos_theta_u = cos_from_sin(radius / min_distance);
distance.x = min_distance / cos_theta_u;
}
else {
/* Similar to background light. */
@ -220,10 +221,10 @@ ccl_device_forceinline bool point_light_tree_parameters(const ccl_global KernelL
}
}
else {
const float hypotenus = sqrtf(sqr(radius) + sqr(dist_point_to_centroid));
cos_theta_u = dist_point_to_centroid / hypotenus;
const float hypotenus = sqrtf(sqr(radius) + sqr(min_distance));
cos_theta_u = min_distance / hypotenus;
distance = make_float2(hypotenus, dist_point_to_centroid);
distance.x = hypotenus;
}
return true;

View File

@ -291,35 +291,32 @@ ccl_device_forceinline bool spot_light_tree_parameters(const ccl_global KernelLi
ccl_private float2 &distance,
ccl_private float3 &point_to_centroid)
{
float dist_point_to_centroid;
const float3 point_to_centroid_ = safe_normalize_len(centroid - P, &dist_point_to_centroid);
float min_distance;
point_to_centroid = safe_normalize_len(centroid - P, &min_distance);
distance = min_distance * one_float2();
const float radius = klight->spot.radius;
if (klight->spot.is_sphere) {
cos_theta_u = (dist_point_to_centroid > radius) ?
cos_from_sin(radius / dist_point_to_centroid) :
-1.0f;
cos_theta_u = (min_distance > radius) ? cos_from_sin(radius / min_distance) : -1.0f;
if (in_volume_segment) {
return true;
}
distance = (dist_point_to_centroid > radius) ?
dist_point_to_centroid * make_float2(1.0f / cos_theta_u, 1.0f) :
one_float2() * radius / M_SQRT2_F;
distance = (min_distance > radius) ? min_distance * make_float2(1.0f / cos_theta_u, 1.0f) :
one_float2() * radius / M_SQRT2_F;
}
else {
const float hypotenus = sqrtf(sqr(radius) + sqr(dist_point_to_centroid));
cos_theta_u = dist_point_to_centroid / hypotenus;
const float hypotenus = sqrtf(sqr(radius) + sqr(min_distance));
cos_theta_u = min_distance / hypotenus;
if (in_volume_segment) {
return true;
}
distance = make_float2(hypotenus, dist_point_to_centroid);
distance.x = hypotenus;
}
point_to_centroid = point_to_centroid_;
return true;
}

View File

@ -333,14 +333,14 @@ ccl_device void light_tree_node_importance(KernelGlobals kg,
if (in_volume_segment) {
const float3 D = N_or_D;
const float3 closest_point = P + dot(centroid - P, D) * D;
const float closest_t = clamp(dot(centroid - P, D), 0.0f, t);
const float3 closest_point = P + D * closest_t;
/* Minimal distance of the ray to the cluster. */
distance = len(centroid - closest_point);
/* Vector that forms a minimal angle with the emitter centroid. */
point_to_centroid = -compute_v(centroid, P, D, bcone.axis, t);
/* FIXME(weizhen): it is not clear from which point the `cos_theta_u` should be computed in
* volume segment. We could use `closest_point` as a conservative measure, but then
* `point_to_centroid` should also use `closest_point`. */
cos_theta_u = light_tree_cos_bounding_box_angle(bbox, closest_point, point_to_centroid);
cos_theta_u = light_tree_cos_bounding_box_angle(
bbox, closest_point, normalize(centroid - closest_point));
}
else {
const float3 N = N_or_D;
@ -405,8 +405,8 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg,
bcone.theta_o = kemitter->theta_o;
bcone.theta_e = kemitter->theta_e;
float cos_theta_u;
float2 distance; /* distance.x = max_distance, distance.y = mix_distance */
float3 centroid, point_to_centroid, P_c;
float2 distance; /* distance.x = max_distance, distance.y = min_distance */
float3 centroid, point_to_centroid, P_c = P;
if (!compute_emitter_centroid_and_dir<in_volume_segment>(kg, kemitter, P, centroid, bcone.axis))
{
@ -415,15 +415,9 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg,
if (in_volume_segment) {
const float3 D = N_or_D;
/* Closest point. */
P_c = P + dot(centroid - P, D) * D;
/* Minimal distance of the ray to the cluster. */
distance.x = len(centroid - P_c);
distance.y = distance.x;
point_to_centroid = -compute_v(centroid, P, D, bcone.axis, t);
}
else {
P_c = P;
/* Closest point from ray to the emitter centroid. */
const float closest_t = clamp(dot(centroid - P, D), 0.0f, t);
P_c += D * closest_t;
}
/* Early out if the emitter is guaranteed to be invisible. */
@ -457,6 +451,9 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg,
case LIGHT_DISTANT:
is_visible = distant_light_tree_parameters(
centroid, bcone.theta_e, cos_theta_u, distance, point_to_centroid);
if (in_volume_segment) {
centroid = P - bcone.axis;
}
break;
default:
return;
@ -468,6 +465,11 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg,
return;
}
if (in_volume_segment) {
/* Vector that forms a minimal angle with the emitter centroid. */
point_to_centroid = -compute_v(centroid, P, N_or_D, bcone.axis, t);
}
light_tree_importance<in_volume_segment>(N_or_D,
has_transmission,
point_to_centroid,

View File

@ -301,13 +301,11 @@ ccl_device_forceinline bool triangle_light_tree_parameters(
ccl_private float2 &distance,
ccl_private float3 &point_to_centroid)
{
if (!in_volume_segment) {
/* TODO: a cheap substitute for minimal distance between point and primitive. Does it
* worth the overhead to compute the accurate minimal distance? */
float min_distance;
point_to_centroid = safe_normalize_len(centroid - P, &min_distance);
distance = make_float2(min_distance, min_distance);
}
/* TODO: a cheap substitute for minimal distance between point and primitive. Does it worth the
* overhead to compute the accurate minimal distance? */
float min_distance;
point_to_centroid = safe_normalize_len(centroid - P, &min_distance);
distance = make_float2(min_distance, min_distance);
cos_theta_u = FLT_MAX;

View File

@ -417,7 +417,13 @@ class AnnotationDataPanel:
bl_options = {'DEFAULT_CLOSED'}
def draw_header(self, context):
if context.space_data.type not in {'VIEW_3D', 'TOPBAR', 'SEQUENCE_EDITOR'}:
if context.space_data.type not in {
'VIEW_3D',
'TOPBAR',
'SEQUENCE_EDITOR',
'IMAGE_EDITOR',
'NODE_EDITOR',
'PROPERTIES'}:
self.layout.prop(context.space_data, "show_annotation", text="")
def draw(self, context):

View File

@ -171,8 +171,8 @@ class _defs_annotate:
gpl = context.active_annotation_layer
if gpl is not None:
layout.label(text="Annotation:")
if context.space_data.type in {'VIEW_3D', 'SEQUENCE_EDITOR'}:
if context.space_data.type in {'VIEW_3D', 'SEQUENCE_EDITOR', 'IMAGE_EDITOR', 'NODE_EDITOR'}:
layout.label(text="Annotation:")
if region_type == 'TOOL_HEADER':
sub = layout.split(align=True, factor=0.5)
sub.ui_units_x = 6.5
@ -184,7 +184,15 @@ class _defs_annotate:
panel="TOPBAR_PT_annotation_layers",
text=text,
)
elif context.space_data.type == 'PROPERTIES':
row = layout.row(align=True)
row.prop(gpl, "color", text="Annotation")
row.popover(
panel="TOPBAR_PT_annotation_layers",
text=text,
)
else:
layout.label(text="Annotation:")
layout.prop(gpl, "color", text="")
space_type = tool.space_type

View File

@ -6573,8 +6573,7 @@ class VIEW3D_PT_shading_lighting(Panel):
col.prop(shading, "studiolight_intensity")
col.prop(shading, "studiolight_background_alpha")
if engine != 'BLENDER_EEVEE_NEXT':
col.prop(shading, "studiolight_background_blur")
col.prop(shading, "studiolight_background_blur")
col = split.column() # to align properly with above
elif shading.type == 'RENDERED':
@ -6599,8 +6598,7 @@ class VIEW3D_PT_shading_lighting(Panel):
col.prop(shading, "studiolight_intensity")
col.prop(shading, "studiolight_background_alpha")
engine = context.scene.render.engine
if engine != 'BLENDER_EEVEE_NEXT':
col.prop(shading, "studiolight_background_blur")
col.prop(shading, "studiolight_background_blur")
col = split.column() # to align properly with above

View File

@ -223,7 +223,7 @@ bool AssetCatalogDefinitionFile::write_to_disk_unsafe(const CatalogFilePath &des
}
bool AssetCatalogDefinitionFile::ensure_directory_exists(
const CatalogFilePath directory_path) const
const CatalogFilePath &directory_path) const
{
/* TODO(@sybren): design a way to get such errors presented to users (or ensure that they never
* occur). */

View File

@ -81,7 +81,7 @@ class AssetCatalogDefinitionFile {
* Return true when the file was written correctly, false when there was a problem.
*/
bool write_to_disk_unsafe(const CatalogFilePath &dest_file_path) const;
bool ensure_directory_exists(const CatalogFilePath directory_path) const;
bool ensure_directory_exists(const CatalogFilePath &directory_path) const;
};
} // namespace blender::asset_system

View File

@ -20,7 +20,8 @@ namespace blender::asset_system {
AssetIdentifier::AssetIdentifier(std::shared_ptr<std::string> library_root_path,
std::string relative_asset_path)
: library_root_path_(library_root_path), relative_asset_path_(relative_asset_path)
: library_root_path_(std::move(library_root_path)),
relative_asset_path_(std::move(relative_asset_path))
{
}

View File

@ -22,7 +22,7 @@ AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier,
const int id_type,
std::unique_ptr<AssetMetaData> metadata,
const AssetLibrary &owner_asset_library)
: identifier_(identifier),
: identifier_(std::move(identifier)),
is_local_id_(false),
owner_asset_library_(owner_asset_library),
external_asset_()
@ -35,7 +35,7 @@ AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier,
AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier,
ID &id,
const AssetLibrary &owner_asset_library)
: identifier_(identifier),
: identifier_(std::move(identifier)),
is_local_id_(true),
owner_asset_library_(owner_asset_library),
local_asset_id_(&id)

View File

@ -144,8 +144,8 @@ void BLF_batch_draw_end();
/**
* Draw the string using the current font.
*/
void BLF_draw_ex(int fontid, const char *str, size_t str_len, ResultBLF *r_info) ATTR_NONNULL(2);
void BLF_draw(int fontid, const char *str, size_t str_len) ATTR_NONNULL(2);
void BLF_draw(int fontid, const char *str, size_t str_len, ResultBLF *r_info = nullptr)
ATTR_NONNULL(2);
int BLF_draw_mono(int fontid, const char *str, size_t str_len, int cwidth, int tab_columns)
ATTR_NONNULL(2);
@ -205,23 +205,21 @@ size_t BLF_width_to_rstrlen(int fontid,
* This function return the bounding box of the string
* and are not multiplied by the aspect.
*/
void BLF_boundbox_ex(int fontid, const char *str, size_t str_len, rcti *box, ResultBLF *r_info)
ATTR_NONNULL(2);
void BLF_boundbox(int fontid, const char *str, size_t str_len, rcti *box) ATTR_NONNULL();
void BLF_boundbox(int fontid,
const char *str,
size_t str_len,
rcti *box,
ResultBLF *r_info = nullptr) ATTR_NONNULL(2);
/**
* The next both function return the width and height
* of the string, using the current font and both value
* are multiplied by the aspect of the font.
*/
float BLF_width_ex(int fontid, const char *str, size_t str_len, ResultBLF *r_info)
float BLF_width(int fontid, const char *str, size_t str_len, ResultBLF *r_info = nullptr)
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(2);
float BLF_width(int fontid, const char *str, size_t str_len) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL();
float BLF_height_ex(int fontid, const char *str, size_t str_len, ResultBLF *r_info)
float BLF_height(int fontid, const char *str, size_t str_len, ResultBLF *r_info = nullptr)
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(2);
float BLF_height(int fontid, const char *str, size_t str_len) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL();
/**
* Return dimensions of the font without any sample text.
@ -306,9 +304,8 @@ void BLF_buffer_col(int fontid, const float rgba[4]) ATTR_NONNULL(2);
* Draw the string into the buffer, this function draw in both buffer,
* float and unsigned char _BUT_ it's not necessary set both buffer, NULL is valid here.
*/
void BLF_draw_buffer_ex(int fontid, const char *str, size_t str_len, ResultBLF *r_info)
void BLF_draw_buffer(int fontid, const char *str, size_t str_len, ResultBLF *r_info = nullptr)
ATTR_NONNULL(2);
void BLF_draw_buffer(int fontid, const char *str, size_t str_len) ATTR_NONNULL(2);
/* `blf_thumbs.cc` */

View File

@ -567,13 +567,21 @@ static void blf_draw_gpu__end(const FontBLF *font)
}
}
void BLF_draw_ex(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
void BLF_draw(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
{
FontBLF *font = blf_get(fontid);
BLF_RESULT_CHECK_INIT(r_info);
if (str_len == 0 || str[0] == '\0') {
return;
}
FontBLF *font = blf_get(fontid);
if (font) {
/* Avoid bgl usage to corrupt BLF drawing. */
GPU_bgl_end();
blf_draw_gpu__start(font);
if (font->flags & BLF_WORD_WRAP) {
blf_font_draw__wrap(font, str, str_len, r_info);
@ -584,17 +592,6 @@ void BLF_draw_ex(int fontid, const char *str, const size_t str_len, ResultBLF *r
blf_draw_gpu__end(font);
}
}
void BLF_draw(int fontid, const char *str, const size_t str_len)
{
if (str_len == 0 || str[0] == '\0') {
return;
}
/* Avoid bgl usage to corrupt BLF drawing. */
GPU_bgl_end();
BLF_draw_ex(fontid, str, str_len, nullptr);
}
int BLF_draw_mono(int fontid, const char *str, const size_t str_len, int cwidth, int tab_columns)
{
@ -699,7 +696,7 @@ size_t BLF_width_to_rstrlen(
return 0;
}
void BLF_boundbox_ex(
void BLF_boundbox(
int fontid, const char *str, const size_t str_len, rcti *r_box, ResultBLF *r_info)
{
FontBLF *font = blf_get(fontid);
@ -716,11 +713,6 @@ void BLF_boundbox_ex(
}
}
void BLF_boundbox(int fontid, const char *str, const size_t str_len, rcti *r_box)
{
BLF_boundbox_ex(fontid, str, str_len, r_box, nullptr);
}
void BLF_width_and_height(
int fontid, const char *str, const size_t str_len, float *r_width, float *r_height)
{
@ -734,7 +726,7 @@ void BLF_width_and_height(
}
}
float BLF_width_ex(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
float BLF_width(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
{
FontBLF *font = blf_get(fontid);
@ -747,11 +739,6 @@ float BLF_width_ex(int fontid, const char *str, const size_t str_len, ResultBLF
return 0.0f;
}
float BLF_width(int fontid, const char *str, const size_t str_len)
{
return BLF_width_ex(fontid, str, str_len, nullptr);
}
float BLF_fixed_width(int fontid)
{
FontBLF *font = blf_get(fontid);
@ -763,7 +750,7 @@ float BLF_fixed_width(int fontid)
return 0.0f;
}
float BLF_height_ex(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
float BLF_height(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
{
FontBLF *font = blf_get(fontid);
@ -776,11 +763,6 @@ float BLF_height_ex(int fontid, const char *str, const size_t str_len, ResultBLF
return 0.0f;
}
float BLF_height(int fontid, const char *str, const size_t str_len)
{
return BLF_height_ex(fontid, str, str_len, nullptr);
}
int BLF_height_max(int fontid)
{
FontBLF *font = blf_get(fontid);
@ -915,7 +897,7 @@ void blf_draw_buffer__start(FontBLF *font)
}
void blf_draw_buffer__end() {}
void BLF_draw_buffer_ex(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
void BLF_draw_buffer(int fontid, const char *str, const size_t str_len, ResultBLF *r_info)
{
FontBLF *font = blf_get(fontid);
@ -930,10 +912,6 @@ void BLF_draw_buffer_ex(int fontid, const char *str, const size_t str_len, Resul
blf_draw_buffer__end();
}
}
void BLF_draw_buffer(int fontid, const char *str, const size_t str_len)
{
BLF_draw_buffer_ex(fontid, str, str_len, nullptr);
}
blender::Vector<blender::StringRef> BLF_string_wrap(int fontid,
blender::StringRef str,

View File

@ -12,14 +12,14 @@
#include "BLI_bounds_types.hh"
#include "BLI_generic_virtual_array.hh"
#include "BLI_implicit_sharing.hh"
#include "BLI_index_mask.hh"
#include "BLI_index_mask_fwd.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_offset_indices.hh"
#include "BLI_shared_cache.hh"
#include "BLI_span.hh"
#include "BLI_vector.hh"
#include "BLI_virtual_array.hh"
#include "BLI_virtual_array_fwd.hh"
#include "BKE_attribute_math.hh"
#include "BKE_curves.h"

View File

@ -28,13 +28,13 @@ void cdf_free(CDataFile *cdf);
/* File read/write/remove */
bool cdf_read_open(CDataFile *cdf, const char *filepath);
bool cdf_read_layer(CDataFile *cdf, CDataFileLayer *blay);
bool cdf_read_layer(CDataFile *cdf, const CDataFileLayer *blay);
bool cdf_read_data(CDataFile *cdf, unsigned int size, void *data);
void cdf_read_close(CDataFile *cdf);
bool cdf_write_open(CDataFile *cdf, const char *filepath);
bool cdf_write_layer(CDataFile *cdf, CDataFileLayer *blay);
bool cdf_write_data(CDataFile *cdf, unsigned int size, void *data);
bool cdf_write_data(CDataFile *cdf, unsigned int size, const void *data);
void cdf_write_close(CDataFile *cdf);
void cdf_remove(const char *filepath);

View File

@ -6,7 +6,7 @@
#include "BLI_math_vector_types.hh"
#include "BLI_offset_indices.hh"
#include "BLI_virtual_array.hh"
#include "BLI_virtual_array_fwd.hh"
/** \file
* \ingroup bke

View File

@ -16,6 +16,7 @@ extern "C" {
struct Collection;
struct Depsgraph;
struct ListBase;
struct RNG;
struct Object;
struct ParticleData;
struct ParticleKey;
@ -78,6 +79,9 @@ typedef struct EffectorCache {
struct PartDeflect *pd;
/** Random noise generator for e.g. wind. */
struct RNG *rng;
/* precalculated for guides */
struct GuideEffectorData *guide_data;
float guide_loc[4], guide_dir[3], guide_radius;

View File

@ -140,7 +140,7 @@ Mesh *BKE_mesh_new_nomain_from_curve_displist(const Object *ob, const ListBase *
bool BKE_mesh_attribute_required(const char *name);
float (*BKE_mesh_orco_verts_get(Object *ob))[3];
float (*BKE_mesh_orco_verts_get(const Object *ob))[3];
void BKE_mesh_orco_verts_transform(Mesh *mesh, float (*orco)[3], int totvert, bool invert);
/**

View File

@ -140,9 +140,6 @@ struct MeshRuntime {
/** Cache for BVH trees generated for the mesh. Defined in 'BKE_bvhutil.c' */
BVHCache *bvh_cache = nullptr;
/** Cache of non-manifold boundary data for Shrink-wrap Target Project. */
std::unique_ptr<ShrinkwrapBoundaryData> shrinkwrap_data;
/** Needed in case we need to lazily initialize the mesh. */
CustomData_MeshMasks cd_mask_extra = {};
@ -204,6 +201,9 @@ struct MeshRuntime {
/** Cache of data about vertices not used by faces. See #Mesh::verts_no_face(). */
SharedCache<LooseVertCache> verts_no_face_cache;
/** Cache of non-manifold boundary data for shrinkwrap target Project. */
SharedCache<ShrinkwrapBoundaryData> shrinkwrap_boundary_cache;
/**
* A bit vector the size of the number of vertices, set to true for the center vertices of
* subdivided faces. The values are set by the subdivision surface modifier and used by

View File

@ -16,7 +16,7 @@
#include "BLI_bounds_types.hh"
#include "BLI_compiler_compat.h"
#include "BLI_function_ref.hh"
#include "BLI_index_mask.hh"
#include "BLI_index_mask_fwd.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_offset_indices.hh"
#include "BLI_span.hh"

View File

@ -283,7 +283,7 @@ void BKE_scene_multiview_view_filepath_get(const RenderData *rd,
const char *BKE_scene_multiview_view_suffix_get(const RenderData *rd, const char *viewname);
const char *BKE_scene_multiview_view_id_suffix_get(const RenderData *rd, int view_id);
void BKE_scene_multiview_view_prefix_get(Scene *scene,
const char *name,
const char *filepath,
char *r_prefix,
const char **r_ext);
void BKE_scene_multiview_videos_dimensions_get(

View File

@ -60,10 +60,11 @@ struct ShrinkwrapBoundaryData {
blender::Array<ShrinkwrapBoundaryVertData> boundary_verts;
};
/**
* Free boundary data for target project.
*/
void BKE_shrinkwrap_compute_boundary_data(Mesh *mesh);
namespace blender::bke::shrinkwrap {
const ShrinkwrapBoundaryData &boundary_cache_ensure(const Mesh &mesh);
} // namespace blender::bke::shrinkwrap
/* Information about a mesh and BVH tree. */
struct ShrinkwrapTreeData {
@ -79,7 +80,7 @@ struct ShrinkwrapTreeData {
blender::Span<blender::float3> vert_normals;
blender::Span<blender::float3> corner_normals;
const bool *sharp_faces;
ShrinkwrapBoundaryData *boundary;
const ShrinkwrapBoundaryData *boundary;
};
/**

View File

@ -65,7 +65,7 @@ void txt_clean_text(struct Text *text);
void txt_order_cursors(struct Text *text, bool reverse);
int txt_find_string(struct Text *text, const char *findstr, int wrap, int match_case);
bool txt_has_sel(const struct Text *text);
int txt_get_span(struct TextLine *from, struct TextLine *to);
int txt_get_span(struct TextLine *from, const struct TextLine *to);
void txt_move_up(struct Text *text, bool sel);
void txt_move_down(struct Text *text, bool sel);
void txt_move_left(struct Text *text, bool sel);
@ -116,8 +116,8 @@ int txt_setcurr_tab_spaces(struct Text *text, int space);
bool txt_cursor_is_line_start(const struct Text *text);
bool txt_cursor_is_line_end(const struct Text *text);
int txt_calc_tab_left(struct TextLine *tl, int ch);
int txt_calc_tab_right(struct TextLine *tl, int ch);
int txt_calc_tab_left(const struct TextLine *tl, int ch);
int txt_calc_tab_right(const struct TextLine *tl, int ch);
/**
* Utility functions, could be moved somewhere more generic but are python/text related.

View File

@ -111,7 +111,7 @@ bool BKE_vfont_to_curve(Object *ob, eEditFontMode mode);
void BKE_vfont_build_char(Curve *cu,
ListBase *nubase,
unsigned int character,
CharInfo *info,
const CharInfo *info,
float ofsx,
float ofsy,
float rot,

View File

@ -318,7 +318,7 @@ void DM_interp_vert_data(const DerivedMesh *source,
&source->vertData, &dest->vertData, src_indices, weights, nullptr, count, dest_index);
}
static float (*get_editbmesh_orco_verts(BMEditMesh *em))[3]
static float (*get_editbmesh_orco_verts(const BMEditMesh *em))[3]
{
BMIter iter;
BMVert *eve;
@ -338,7 +338,7 @@ static float (*get_editbmesh_orco_verts(BMEditMesh *em))[3]
}
/* orco custom data layer */
static float (*get_orco_coords(Object *ob, BMEditMesh *em, int layer, int *free))[3]
static float (*get_orco_coords(const Object *ob, const BMEditMesh *em, int layer, int *free))[3]
{
*free = 0;
@ -355,11 +355,11 @@ static float (*get_orco_coords(Object *ob, BMEditMesh *em, int layer, int *free)
/* apply shape key for cloth, this should really be solved
* by a more flexible customdata system, but not simple */
if (!em) {
ClothModifierData *clmd = (ClothModifierData *)BKE_modifiers_findby_type(
const ClothModifierData *clmd = (const ClothModifierData *)BKE_modifiers_findby_type(
ob, eModifierType_Cloth);
if (clmd && clmd->sim_parms->shapekey_rest) {
KeyBlock *kb = BKE_keyblock_find_by_index(BKE_key_from_object(ob),
clmd->sim_parms->shapekey_rest);
const KeyBlock *kb = BKE_keyblock_find_by_index(
BKE_key_from_object(const_cast<Object *>(ob)), clmd->sim_parms->shapekey_rest);
if (kb && kb->data) {
return (float(*)[3])kb->data;
@ -373,7 +373,7 @@ static float (*get_orco_coords(Object *ob, BMEditMesh *em, int layer, int *free)
return nullptr;
}
static Mesh *create_orco_mesh(Object *ob, Mesh *mesh, BMEditMesh *em, int layer)
static Mesh *create_orco_mesh(const Object *ob, const Mesh *mesh, const BMEditMesh *em, int layer)
{
Mesh *orco_mesh;
float(*orco)[3];
@ -410,8 +410,11 @@ static MutableSpan<float3> orco_coord_layer_ensure(Mesh *mesh, const eCustomData
return MutableSpan(reinterpret_cast<float3 *>(data), mesh->verts_num);
}
static void add_orco_mesh(
Object *ob, BMEditMesh *em, Mesh *mesh, Mesh *mesh_orco, const eCustomDataType layer)
static void add_orco_mesh(Object *ob,
const BMEditMesh *em,
Mesh *mesh,
const Mesh *mesh_orco,
const eCustomDataType layer)
{
const int totvert = mesh->verts_num;
@ -1269,12 +1272,14 @@ static void editbmesh_calc_modifiers(Depsgraph *depsgraph,
}
}
static void mesh_build_extra_data(Depsgraph *depsgraph, Object *ob, Mesh *mesh_eval)
static void mesh_build_extra_data(const Depsgraph *depsgraph,
const Object *ob,
const Mesh *mesh_eval)
{
uint32_t eval_flags = DEG_get_eval_flags_for_id(depsgraph, &ob->id);
if (eval_flags & DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY) {
BKE_shrinkwrap_compute_boundary_data(mesh_eval);
blender::bke::shrinkwrap::boundary_cache_ensure(*mesh_eval);
}
}

View File

@ -4799,7 +4799,7 @@ void CustomData_external_read(CustomData *data, ID *id, eCustomDataMask mask, co
/* pass */
}
else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) {
CDataFileLayer *blay = cdf_layer_find(cdf, layer->type, layer->name);
const CDataFileLayer *blay = cdf_layer_find(cdf, layer->type, layer->name);
if (blay) {
if (cdf_read_layer(cdf, blay)) {

View File

@ -295,7 +295,7 @@ bool cdf_read_open(CDataFile *cdf, const char *filepath)
return true;
}
bool cdf_read_layer(CDataFile *cdf, CDataFileLayer *blay)
bool cdf_read_layer(CDataFile *cdf, const CDataFileLayer *blay)
{
size_t offset;
int a;
@ -387,7 +387,7 @@ bool cdf_write_layer(CDataFile * /*cdf*/, CDataFileLayer * /*blay*/)
return true;
}
bool cdf_write_data(CDataFile *cdf, uint size, void *data)
bool cdf_write_data(CDataFile *cdf, uint size, const void *data)
{
/* write data */
if (!fwrite(data, size, 1, cdf->writef)) {

View File

@ -113,9 +113,6 @@ PartDeflect *BKE_partdeflect_copy(const PartDeflect *pd_src)
return nullptr;
}
PartDeflect *pd_dst = static_cast<PartDeflect *>(MEM_dupallocN(pd_src));
if (pd_dst->rng != nullptr) {
pd_dst->rng = BLI_rng_copy(pd_dst->rng);
}
return pd_dst;
}
@ -124,9 +121,6 @@ void BKE_partdeflect_free(PartDeflect *pd)
if (!pd) {
return;
}
if (pd->rng) {
BLI_rng_free(pd->rng);
}
MEM_freeN(pd);
}
@ -136,12 +130,8 @@ static void precalculate_effector(Depsgraph *depsgraph, EffectorCache *eff)
{
float ctime = DEG_get_ctime(depsgraph);
uint cfra = uint(ctime >= 0 ? ctime : -ctime);
if (!eff->pd->rng) {
eff->pd->rng = BLI_rng_new(eff->pd->seed + cfra);
}
else {
BLI_rng_srandom(eff->pd->rng, eff->pd->seed + cfra);
}
eff->rng = BLI_rng_new(eff->pd->seed + cfra);
if (eff->pd->forcefield == PFIELD_GUIDE && eff->ob->type == OB_CURVES_LEGACY) {
Curve *cu = static_cast<Curve *>(eff->ob->data);
@ -375,6 +365,9 @@ void BKE_effectors_free(ListBase *lb)
{
if (lb) {
LISTBASE_FOREACH (EffectorCache *, eff, lb) {
if (eff->rng) {
BLI_rng_free(eff->rng);
}
if (eff->guide_data) {
MEM_freeN(eff->guide_data);
}
@ -960,7 +953,7 @@ static void do_physical_effector(EffectorCache *eff,
float *total_force)
{
PartDeflect *pd = eff->pd;
RNG *rng = pd->rng;
RNG *rng = eff->rng;
float force[3] = {0, 0, 0};
float temp[3];
float fac;

View File

@ -805,7 +805,7 @@ static ModifierData &legacy_object_modifier_common(Object &object,
const ModifierType type,
GpencilModifierData &legacy_md)
{
/* TODO: Copy of most of #ED_object_modifier_add, this should be a BKE_modifiers function
/* TODO: Copy of most of #ed::object::modifier_add, this should be a BKE_modifiers function
* actually. */
const ModifierTypeInfo *mti = BKE_modifier_get_info(type);

View File

@ -2003,7 +2003,7 @@ void BKE_image_stamp_buf(Scene *scene,
/* must enable BLF_WORD_WRAP before using */
#define TEXT_SIZE_CHECK_WORD_WRAP(str, w, h) \
((str[0]) && (BLF_boundbox_ex(mono, str, sizeof(str), &wrap.rect, &wrap.info), \
((str[0]) && (BLF_boundbox(mono, str, sizeof(str), &wrap.rect, &wrap.info), \
(void)(h = h_fixed * wrap.info.lines), \
(w = BLI_rcti_size_x(&wrap.rect))))

View File

@ -4228,9 +4228,48 @@ bool BKE_lib_override_library_property_operation_operands_validate(
return true;
}
static bool override_library_is_valid(const ID &id,
const IDOverrideLibrary &liboverride,
ReportList *reports)
{
if (liboverride.reference == nullptr) {
/* This (probably) used to be a template ID, could be linked or local, not an override. */
BKE_reportf(reports,
RPT_WARNING,
"Library override templates have been removed: removing all override data from "
"the data-block '%s'",
id.name);
return false;
}
if (liboverride.reference == &id) {
/* Very serious data corruption, cannot do much about it besides removing the liboverride data.
*/
BKE_reportf(reports,
RPT_ERROR,
"Data corruption: data-block '%s' is using itself as library override reference, "
"removing all override data",
id.name);
return false;
}
if (!ID_IS_LINKED(liboverride.reference)) {
/* Very serious data corruption, cannot do much about it besides removing the liboverride data.
*/
BKE_reportf(reports,
RPT_ERROR,
"Data corruption: data-block '%s' is using another local data-block ('%s') as "
"library override reference, removing all override data",
id.name,
liboverride.reference->name);
return false;
}
return true;
}
void BKE_lib_override_library_validate(Main *bmain, ID *id, ReportList *reports)
{
if (!ID_IS_OVERRIDE_LIBRARY(id)) {
/* Do NOT use `ID_IS_OVERRIDE_LIBRARY` here, since this code also needs to fix broken cases (like
* null reference pointer), which would be skipped by that macro. */
if (id->override_library == nullptr && !ID_IS_OVERRIDE_LIBRARY_VIRTUAL(id)) {
return;
}
@ -4238,7 +4277,7 @@ void BKE_lib_override_library_validate(Main *bmain, ID *id, ReportList *reports)
IDOverrideLibrary *liboverride = id->override_library;
if (ID_IS_OVERRIDE_LIBRARY_VIRTUAL(id)) {
liboverride = BKE_lib_override_library_get(bmain, id, nullptr, &liboverride_id);
if (!liboverride) {
if (!liboverride || !override_library_is_valid(*liboverride_id, *liboverride, reports)) {
/* Happens in case the given ID is a liboverride-embedded one (actual embedded ID like
* NodeTree or master collection, or shape-keys), used by a totally not-liboverride owner ID.
* Just clear the relevant ID flag.
@ -4252,39 +4291,8 @@ void BKE_lib_override_library_validate(Main *bmain, ID *id, ReportList *reports)
/* NOTE: In code deleting liboverride data below, #BKE_lib_override_library_make_local is used
* instead of directly calling #BKE_lib_override_library_free, because the former also handles
* properly 'liboverride embedded' IDs, like root node-trees, or shape-keys. */
if (liboverride->reference == nullptr) {
/* This (probably) used to be a template ID, could be linked or local, not an override. */
BKE_reportf(reports,
RPT_WARNING,
"Library override templates have been removed: removing all override data from "
"the data-block '%s'",
liboverride_id->name);
if (!override_library_is_valid(*liboverride_id, *liboverride, reports)) {
BKE_lib_override_library_make_local(nullptr, liboverride_id);
return;
}
if (liboverride->reference == liboverride_id) {
/* Very serious data corruption, cannot do much about it besides removing the liboverride data.
*/
BKE_reportf(reports,
RPT_ERROR,
"Data corruption: data-block '%s' is using itself as library override reference, "
"removing all override data",
liboverride_id->name);
BKE_lib_override_library_make_local(nullptr, liboverride_id);
return;
}
if (!ID_IS_LINKED(liboverride->reference)) {
/* Very serious data corruption, cannot do much about it besides removing the liboverride data.
*/
BKE_reportf(reports,
RPT_ERROR,
"Data corruption: data-block '%s' is using another local data-block ('%s') as "
"library override reference, removing all override data",
liboverride_id->name,
liboverride->reference->name);
BKE_lib_override_library_make_local(nullptr, liboverride_id);
return;
}
}
@ -4293,9 +4301,7 @@ void BKE_lib_override_library_main_validate(Main *bmain, ReportList *reports)
ID *id;
FOREACH_MAIN_ID_BEGIN (bmain, id) {
if (ID_IS_OVERRIDE_LIBRARY(id)) {
BKE_lib_override_library_validate(bmain, id, reports);
}
BKE_lib_override_library_validate(bmain, id, reports);
}
FOREACH_MAIN_ID_END;
}

View File

@ -136,7 +136,6 @@ static void mask_blend_write(BlendWriter *writer, ID *id, const void *id_address
static void mask_blend_read_data(BlendDataReader *reader, ID *id)
{
Mask *mask = (Mask *)id;
BLO_read_data_address(reader, &mask->adt);
BLO_read_list(reader, &mask->masklayers);

View File

@ -1005,10 +1005,10 @@ void BKE_mesh_texspace_get_reference(Mesh *mesh,
}
}
float (*BKE_mesh_orco_verts_get(Object *ob))[3]
float (*BKE_mesh_orco_verts_get(const Object *ob))[3]
{
Mesh *mesh = static_cast<Mesh *>(ob->data);
Mesh *tme = mesh->texcomesh ? mesh->texcomesh : mesh;
const Mesh *mesh = static_cast<const Mesh *>(ob->data);
const Mesh *tme = mesh->texcomesh ? mesh->texcomesh : mesh;
/* Get appropriate vertex coordinates */
float(*vcos)[3] = (float(*)[3])MEM_calloc_arrayN(mesh->verts_num, sizeof(*vcos), "orco mesh");

View File

@ -299,9 +299,9 @@ void BKE_mesh_runtime_clear_geometry(Mesh *mesh)
mesh->runtime->verts_no_face_cache.tag_dirty();
mesh->runtime->corner_tris_cache.tag_dirty();
mesh->runtime->corner_tri_faces_cache.tag_dirty();
mesh->runtime->shrinkwrap_boundary_cache.tag_dirty();
mesh->runtime->subsurf_face_dot_tags.clear_and_shrink();
mesh->runtime->subsurf_optimal_display_edges.clear_and_shrink();
mesh->runtime->shrinkwrap_data.reset();
mesh->flag &= ~ME_NO_OVERLAPPING_TOPOLOGY;
}
@ -331,7 +331,7 @@ void Mesh::tag_edges_split()
}
this->runtime->subsurf_face_dot_tags.clear_and_shrink();
this->runtime->subsurf_optimal_display_edges.clear_and_shrink();
this->runtime->shrinkwrap_data.reset();
this->runtime->shrinkwrap_boundary_cache.tag_dirty();
}
void Mesh::tag_sharpness_changed()
@ -350,6 +350,7 @@ void Mesh::tag_face_winding_changed()
this->runtime->face_normals_cache.tag_dirty();
this->runtime->corner_normals_cache.tag_dirty();
this->runtime->vert_to_corner_map_cache.tag_dirty();
this->runtime->shrinkwrap_boundary_cache.tag_dirty();
}
void Mesh::tag_positions_changed()
@ -357,6 +358,7 @@ void Mesh::tag_positions_changed()
this->runtime->vert_normals_cache.tag_dirty();
this->runtime->face_normals_cache.tag_dirty();
this->runtime->corner_normals_cache.tag_dirty();
this->runtime->shrinkwrap_boundary_cache.tag_dirty();
this->tag_positions_changed_no_normals();
}
@ -365,6 +367,7 @@ void Mesh::tag_positions_changed_no_normals()
free_bvh_cache(*this->runtime);
this->runtime->corner_tris_cache.tag_dirty();
this->runtime->bounds_cache.tag_dirty();
this->runtime->shrinkwrap_boundary_cache.tag_dirty();
}
void Mesh::tag_positions_changed_uniformly()

View File

@ -245,9 +245,6 @@ static void object_copy_data(Main *bmain,
if (ob_src->pd) {
ob_dst->pd = (PartDeflect *)MEM_dupallocN(ob_src->pd);
if (ob_dst->pd->rng) {
ob_dst->pd->rng = (RNG *)MEM_dupallocN(ob_src->pd->rng);
}
}
BKE_rigidbody_object_copy(bmain, ob_dst, ob_src, flag_subdata);

View File

@ -313,11 +313,8 @@ static void particle_settings_blend_write(BlendWriter *writer, ID *id, const voi
}
}
void BKE_particle_partdeflect_blend_read_data(BlendDataReader * /*reader*/, PartDeflect *pd)
void BKE_particle_partdeflect_blend_read_data(BlendDataReader * /*reader*/, PartDeflect * /*pd*/)
{
if (pd) {
pd->rng = nullptr;
}
}
static void particle_settings_blend_read_data(BlendDataReader *reader, ID *id)

View File

@ -3154,7 +3154,7 @@ const char *BKE_scene_multiview_view_id_suffix_get(const RenderData *rd, const i
}
void BKE_scene_multiview_view_prefix_get(Scene *scene,
const char *name,
const char *filepath,
char *r_prefix,
const char **r_ext)
{
@ -3163,8 +3163,8 @@ void BKE_scene_multiview_view_prefix_get(Scene *scene,
r_prefix[0] = '\0';
/* Split filename into base name and extension. */
const size_t basename_len = BLI_str_rpartition(name, delims, r_ext, &unused);
/* Split `filepath` into base name and extension. */
const size_t basename_len = BLI_str_rpartition(filepath, delims, r_ext, &unused);
if (*r_ext == nullptr) {
return;
}
@ -3175,9 +3175,9 @@ void BKE_scene_multiview_view_prefix_get(Scene *scene,
if (BKE_scene_multiview_is_render_view_active(&scene->r, srv)) {
const size_t suffix_len = strlen(srv->suffix);
if (basename_len >= suffix_len &&
STREQLEN(name + basename_len - suffix_len, srv->suffix, suffix_len))
STREQLEN(filepath + basename_len - suffix_len, srv->suffix, suffix_len))
{
BLI_strncpy(r_prefix, name, basename_len - suffix_len + 1);
BLI_strncpy(r_prefix, filepath, basename_len - suffix_len + 1);
break;
}
}

View File

@ -142,7 +142,7 @@ bool BKE_shrinkwrap_init_tree(
}
if (shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) {
data->boundary = mesh->runtime->shrinkwrap_data.get();
data->boundary = &blender::bke::shrinkwrap::boundary_cache_ensure(*mesh);
}
return true;
@ -153,9 +153,11 @@ void BKE_shrinkwrap_free_tree(ShrinkwrapTreeData *data)
free_bvhtree_from_mesh(&data->treeData);
}
namespace blender::bke::shrinkwrap {
/* Accumulate edge for average boundary edge direction. */
static void merge_vert_dir(ShrinkwrapBoundaryVertData *vdata,
signed char *status,
MutableSpan<int8_t> status,
int index,
const float edge_dir[3],
signed char side)
@ -177,34 +179,28 @@ static void merge_vert_dir(ShrinkwrapBoundaryVertData *vdata,
status[index] = (status[index] == 0) ? side : -1;
}
static std::unique_ptr<ShrinkwrapBoundaryData> shrinkwrap_build_boundary_data(Mesh *mesh)
static ShrinkwrapBoundaryData shrinkwrap_build_boundary_data(const Mesh &mesh)
{
using namespace blender;
const blender::Span<float3> positions = mesh->vert_positions();
const blender::Span<int2> edges = mesh->edges();
const Span<int> corner_verts = mesh->corner_verts();
const Span<int> corner_edges = mesh->corner_edges();
const Span<float3> positions = mesh.vert_positions();
const Span<int2> edges = mesh.edges();
const Span<int> corner_verts = mesh.corner_verts();
const Span<int> corner_edges = mesh.corner_edges();
/* Count faces per edge (up to 2). */
char *edge_mode = static_cast<char *>(
MEM_calloc_arrayN(size_t(mesh->edges_num), sizeof(char), __func__));
Array<int8_t> edge_mode(edges.size(), 0);
for (int i = 0; i < mesh->corners_num; i++) {
const int eidx = corner_edges[i];
if (edge_mode[eidx] < 2) {
edge_mode[eidx]++;
for (const int edge : corner_edges) {
if (edge_mode[edge] < 2) {
edge_mode[edge]++;
}
}
/* Build the boundary edge bitmask. */
blender::BitVector<> edge_is_boundary(mesh->edges_num, false);
uint num_boundary_edges = 0;
BitVector<> edge_is_boundary(mesh.edges_num, false);
for (int i = 0; i < mesh->edges_num; i++) {
edge_mode[i] = (edge_mode[i] == 1);
if (edge_mode[i]) {
int num_boundary_edges = 0;
for (const int64_t i : edges.index_range()) {
if (edge_mode[i] == 1) {
edge_is_boundary[i].set();
num_boundary_edges++;
}
@ -212,63 +208,52 @@ static std::unique_ptr<ShrinkwrapBoundaryData> shrinkwrap_build_boundary_data(Me
/* If no boundary, return nullptr. */
if (num_boundary_edges == 0) {
MEM_freeN(edge_mode);
return {};
}
/* Allocate the data object. */
std::unique_ptr<ShrinkwrapBoundaryData> data = std::make_unique<ShrinkwrapBoundaryData>();
data->edge_is_boundary = std::move(edge_is_boundary);
ShrinkwrapBoundaryData data;
/* Build the boundary corner_tris bit-mask. */
const blender::Span<int3> corner_tris = mesh->corner_tris();
const Span<int3> corner_tris = mesh.corner_tris();
blender::BitVector<> tri_has_boundary(corner_tris.size(), false);
BitVector<> tri_has_boundary(corner_tris.size(), false);
for (const int64_t i : corner_tris.index_range()) {
const int3 real_edges = bke::mesh::corner_tri_get_real_edges(
edges, corner_verts, corner_edges, corner_tris[i]);
for (int j = 0; j < 3; j++) {
if (real_edges[j] >= 0 && edge_mode[real_edges[j]]) {
if (real_edges[j] >= 0 && edge_is_boundary[real_edges[j]]) {
tri_has_boundary[i].set();
break;
}
}
}
data->tri_has_boundary = std::move(tri_has_boundary);
/* Find boundary vertices and build a mapping table for compact storage of data. */
Array<int> vert_boundary_id(mesh->verts_num, 0);
for (int i = 0; i < mesh->edges_num; i++) {
if (edge_mode[i]) {
const blender::int2 &edge = edges[i];
Array<int> vert_boundary_id(mesh.verts_num, 0);
for (const int64_t i : edges.index_range()) {
if (edge_is_boundary[i]) {
const int2 &edge = edges[i];
vert_boundary_id[edge[0]] = 1;
vert_boundary_id[edge[1]] = 1;
}
}
uint num_boundary_verts = 0;
for (int i = 0; i < mesh->verts_num; i++) {
vert_boundary_id[i] = (vert_boundary_id[i] != 0) ? int(num_boundary_verts++) : -1;
int boundary_verts_num = 0;
for (const int64_t i : positions.index_range()) {
vert_boundary_id[i] = (vert_boundary_id[i] != 0) ? boundary_verts_num++ : -1;
}
data->vert_boundary_id = vert_boundary_id;
/* Compute average directions. */
Array<ShrinkwrapBoundaryVertData> boundary_verts(num_boundary_verts);
Array<ShrinkwrapBoundaryVertData> boundary_verts(boundary_verts_num);
signed char *vert_status = static_cast<signed char *>(
MEM_calloc_arrayN(num_boundary_verts, sizeof(char), __func__));
for (int i = 0; i < mesh->edges_num; i++) {
if (edge_mode[i]) {
const blender::int2 &edge = edges[i];
Array<int8_t> vert_status(boundary_verts_num);
for (const int64_t i : edges.index_range()) {
if (edge_is_boundary[i]) {
const int2 &edge = edges[i];
float dir[3];
sub_v3_v3v3(dir, positions[edge[1]], positions[edge[0]]);
@ -279,11 +264,9 @@ static std::unique_ptr<ShrinkwrapBoundaryData> shrinkwrap_build_boundary_data(Me
}
}
MEM_freeN(vert_status);
/* Finalize average direction and compute normal. */
const blender::Span<blender::float3> vert_normals = mesh->vert_normals();
for (int i = 0; i < mesh->verts_num; i++) {
const Span<float3> vert_normals = mesh.vert_normals();
for (const int64_t i : positions.index_range()) {
int bidx = vert_boundary_id[i];
if (bidx >= 0) {
@ -298,17 +281,23 @@ static std::unique_ptr<ShrinkwrapBoundaryData> shrinkwrap_build_boundary_data(Me
}
}
data->boundary_verts = std::move(boundary_verts);
data.edge_is_boundary = std::move(edge_is_boundary);
data.tri_has_boundary = std::move(tri_has_boundary);
data.vert_boundary_id = std::move(vert_boundary_id);
data.boundary_verts = std::move(boundary_verts);
MEM_freeN(edge_mode);
return data;
}
void BKE_shrinkwrap_compute_boundary_data(Mesh *mesh)
const ShrinkwrapBoundaryData &boundary_cache_ensure(const Mesh &mesh)
{
mesh->runtime->shrinkwrap_data = shrinkwrap_build_boundary_data(mesh);
mesh.runtime->shrinkwrap_boundary_cache.ensure(
[&](ShrinkwrapBoundaryData &r_data) { r_data = shrinkwrap_build_boundary_data(mesh); });
return mesh.runtime->shrinkwrap_boundary_cache.data();
}
} // namespace blender::bke::shrinkwrap
/**
* Shrink-wrap to the nearest vertex
*

View File

@ -673,7 +673,7 @@ void txt_clean_text(Text *text)
}
}
int txt_get_span(TextLine *from, TextLine *to)
int txt_get_span(TextLine *from, const TextLine *to)
{
int ret = 0;
TextLine *tmp = from;
@ -825,7 +825,7 @@ void txt_move_down(Text *text, const bool sel)
}
}
int txt_calc_tab_left(TextLine *tl, int ch)
int txt_calc_tab_left(const TextLine *tl, int ch)
{
/* do nice left only if there are only spaces */
@ -845,7 +845,7 @@ int txt_calc_tab_left(TextLine *tl, int ch)
return tabsize;
}
int txt_calc_tab_right(TextLine *tl, int ch)
int txt_calc_tab_right(const TextLine *tl, int ch)
{
if (tl->line[ch] == ' ') {
int i;

View File

@ -405,7 +405,7 @@ VFont *BKE_vfont_load_exists(Main *bmain, const char *filepath)
return BKE_vfont_load_exists_ex(bmain, filepath, nullptr);
}
static VFont *which_vfont(Curve *cu, CharInfo *info)
static VFont *which_vfont(Curve *cu, const CharInfo *info)
{
switch (info->flag & (CU_CHINFO_BOLD | CU_CHINFO_ITALIC)) {
case CU_CHINFO_BOLD:
@ -435,7 +435,7 @@ VFont *BKE_vfont_builtin_get()
return vfont;
}
static VChar *find_vfont_char(VFontData *vfd, uint character)
static VChar *find_vfont_char(const VFontData *vfd, uint character)
{
return static_cast<VChar *>(BLI_ghash_lookup(vfd->characters, POINTER_FROM_UINT(character)));
}
@ -507,7 +507,7 @@ static void build_underline(Curve *cu,
void BKE_vfont_build_char(Curve *cu,
ListBase *nubase,
uint character,
CharInfo *info,
const CharInfo *info,
float ofsx,
float ofsy,
float rot,
@ -679,7 +679,7 @@ void BKE_vfont_select_clamp(Object *ob)
CLAMP_MAX(ef->selend, ef->len);
}
static float char_width(Curve *cu, VChar *che, CharInfo *info)
static float char_width(Curve *cu, VChar *che, const CharInfo *info)
{
/* The character wasn't found, probably ascii = 0, then the width shall be 0 as well */
if (che == nullptr) {

View File

@ -383,8 +383,8 @@ VolumeGridType get_type(const VolumeGridData &volume_grid)
return volume_grid.grid_type();
#else
UNUSED_VARS(volume_grid);
#endif
return VOLUME_GRID_UNKNOWN;
#endif
}
int get_channels_num(const VolumeGridType type)

View File

@ -69,7 +69,7 @@ void BLI_args_print_other_doc(struct bArgs *ba);
bool BLI_args_has_other_doc(const struct bArgs *ba);
void BLI_args_print(struct bArgs *ba);
void BLI_args_print(const struct bArgs *ba);
#ifdef __cplusplus
}

View File

@ -32,7 +32,7 @@ struct RNG *BLI_rng_new(unsigned int seed);
* A version of #BLI_rng_new that hashes the seed.
*/
struct RNG *BLI_rng_new_srandom(unsigned int seed);
struct RNG *BLI_rng_copy(struct RNG *rng) ATTR_NONNULL(1);
struct RNG *BLI_rng_copy(const struct RNG *rng) ATTR_NONNULL(1);
void BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1);
void BLI_rng_seed(struct RNG *rng, unsigned int seed) ATTR_NONNULL(1);

View File

@ -152,7 +152,7 @@ void BLI_args_pass_set(bArgs *ba, int current_pass)
ba->current_pass = current_pass;
}
void BLI_args_print(bArgs *ba)
void BLI_args_print(const bArgs *ba)
{
int i;
for (i = 0; i < ba->argc; i++) {

View File

@ -258,7 +258,7 @@ static void bvh_insertionsort(BVHNode **a, int lo, int hi, int axis)
}
}
static int bvh_partition(BVHNode **a, int lo, int hi, BVHNode *x, int axis)
static int bvh_partition(BVHNode **a, int lo, int hi, const BVHNode *x, int axis)
{
int i = lo, j = hi;
while (1) {

View File

@ -191,8 +191,7 @@ void BLI_memarena_merge(MemArena *ma_dst, MemArena *ma_src)
/* Loop over `ma_src` instead of `ma_dst` since it's likely the destination is larger
* when used for accumulating from multiple sources. */
struct MemBuf *mb_src = ma_src->bufs;
mb_src = ma_src->bufs;
while (mb_src && mb_src->next) {
while (mb_src->next) {
mb_src = mb_src->next;
}
mb_src->next = ma_dst->bufs->next;

View File

@ -50,7 +50,7 @@ RNG *BLI_rng_new_srandom(uint seed)
return rng;
}
RNG *BLI_rng_copy(RNG *rng)
RNG *BLI_rng_copy(const RNG *rng)
{
return new RNG(*rng);
}

View File

@ -155,7 +155,7 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme)
/** #UserDef.flag */
#define USER_LMOUSESELECT (1 << 14) /* deprecated */
static void do_version_select_mouse(UserDef *userdef, wmKeyMapItem *kmi)
static void do_version_select_mouse(const UserDef *userdef, wmKeyMapItem *kmi)
{
/* Remove select/action mouse from user defined keymaps. */
enum {

View File

@ -580,10 +580,6 @@ if(WITH_COMPOSITOR_CPU)
PRIVATE bf::intern::atomic
)
list(APPEND INC
${CMAKE_CURRENT_BINARY_DIR}/operations
)
if(WITH_OPENIMAGEDENOISE)
add_definitions(-DWITH_OPENIMAGEDENOISE)
add_definitions(-DOIDN_STATIC_LIB)

View File

@ -4,7 +4,10 @@
#include "COM_BokehImageOperation.h"
#include "BLI_math_geom.h"
#include "BLI_math_base.h"
#include "BLI_math_base.hh"
#include "BLI_math_numbers.hh"
#include "BLI_math_vector.hh"
namespace blender::compositor {
@ -13,91 +16,151 @@ BokehImageOperation::BokehImageOperation()
this->add_output_socket(DataType::Color);
delete_data_ = false;
}
/* The exterior angle is the angle between each two consecutive vertices of the regular polygon
* from its center. */
static float compute_exterior_angle(int sides)
{
return (math::numbers::pi * 2.0f) / sides;
}
static float compute_rotation(float angle, int sides)
{
/* Offset the rotation such that the second vertex of the regular polygon lies on the positive
* y axis, which is 90 degrees minus the angle that it makes with the positive x axis assuming
* the first vertex lies on the positive x axis. */
const float offset = math::numbers::pi / 2.0f - compute_exterior_angle(sides);
return angle - offset;
}
void BokehImageOperation::init_execution()
{
center_[0] = get_width() / 2;
center_[1] = get_height() / 2;
inverse_rounding_ = 1.0f - data_->rounding;
circular_distance_ = get_width() / 2;
flap_rad_ = float(M_PI * 2) / data_->flaps;
flap_rad_add_ = data_->angle;
while (flap_rad_add_ < 0.0f) {
flap_rad_add_ += float(M_PI * 2.0);
}
while (flap_rad_add_ > float(M_PI)) {
flap_rad_add_ -= float(M_PI * 2.0);
}
exterior_angle_ = compute_exterior_angle(data_->flaps);
rotation_ = compute_rotation(data_->angle, data_->flaps);
roundness_ = data_->rounding;
catadioptric_ = data_->catadioptric;
lens_shift_ = data_->lensshift;
}
void BokehImageOperation::detemine_start_point_of_flap(float r[2], int flap_number, float distance)
/* Get the 2D vertex position of the vertex with the given index in the regular polygon
* representing this bokeh. The polygon is rotated by the rotation amount and have a unit
* circumradius. The regular polygon is one whose vertices' exterior angles are given by
* exterior_angle. See the bokeh function for more information. */
float2 BokehImageOperation::get_regular_polygon_vertex_position(int vertex_index)
{
r[0] = sinf(flap_rad_ * flap_number + flap_rad_add_) * distance + center_[0];
r[1] = cosf(flap_rad_ * flap_number + flap_rad_add_) * distance + center_[1];
float angle = exterior_angle_ * vertex_index - rotation_;
return float2(math::cos(angle), math::sin(angle));
}
float BokehImageOperation::is_inside_bokeh(float distance, float x, float y)
/* Find the closest point to the given point on the given line. This assumes the length of the
* given line is not zero. */
float2 BokehImageOperation::closest_point_on_line(float2 point, float2 line_start, float2 line_end)
{
float inside_bokeh = 0.0f;
const float deltaX = x - center_[0];
const float deltaY = y - center_[1];
float closest_point[2];
float line_p1[2];
float line_p2[2];
float point[2];
point[0] = x;
point[1] = y;
const float distance_to_center = len_v2v2(point, center_);
const float bearing = (atan2f(deltaX, deltaY) + float(M_PI * 2.0));
int flap_number = int((bearing - flap_rad_add_) / flap_rad_);
detemine_start_point_of_flap(line_p1, flap_number, distance);
detemine_start_point_of_flap(line_p2, flap_number + 1, distance);
closest_to_line_v2(closest_point, point, line_p1, line_p2);
const float distance_line_to_center = len_v2v2(center_, closest_point);
const float distance_rounding_to_center = inverse_rounding_ * distance_line_to_center +
data_->rounding * distance;
const float catadioptric_distance_to_center = distance_rounding_to_center * data_->catadioptric;
if (distance_rounding_to_center >= distance_to_center &&
catadioptric_distance_to_center <= distance_to_center)
{
if (distance_rounding_to_center - distance_to_center < 1.0f) {
inside_bokeh = (distance_rounding_to_center - distance_to_center);
}
else if (data_->catadioptric != 0.0f &&
distance_to_center - catadioptric_distance_to_center < 1.0f)
{
inside_bokeh = (distance_to_center - catadioptric_distance_to_center);
}
else {
inside_bokeh = 1.0f;
}
}
return inside_bokeh;
float2 line_vector = line_end - line_start;
float2 point_vector = point - line_start;
float line_length_squared = math::dot(line_vector, line_vector);
float parameter = math::dot(point_vector, line_vector) / line_length_squared;
return line_start + line_vector * parameter;
}
/* Compute the value of the bokeh at the given point. The computed bokeh is essentially a regular
* polygon centered in space having the given circumradius. The regular polygon is one whose
* vertices' exterior angles are given by "exterior_angle", which relates to the number of vertices
* n through the equation "exterior angle = 2 pi / n". The regular polygon may additionally morph
* into a shape with the given properties:
*
* - The regular polygon may have a circular hole in its center whose radius is controlled by the
* "catadioptric" value.
* - The regular polygon is rotated by the "rotation" value.
* - The regular polygon can morph into a circle controlled by the "roundness" value, such that it
* becomes a full circle at unit roundness.
*
* The function returns 0 when the point lies inside the regular polygon and 1 otherwise. However,
* at the edges, it returns a narrow band gradient as a form of anti-aliasing. */
float BokehImageOperation::bokeh(float2 point, float circumradius)
{
/* Get the index of the vertex of the regular polygon whose polar angle is maximum but less than
* the polar angle of the given point, taking rotation into account. This essentially finds the
* vertex closest to the given point in the clock-wise direction. */
float angle = floored_fmod(math::atan2(point.y, point.x) + rotation_,
math::numbers::pi_v<float> * 2.0f);
int vertex_index = int(angle / exterior_angle_);
/* Compute the shortest distance between the origin and the polygon edge composed from the
* previously selected vertex and the one following it. */
float2 first_vertex = this->get_regular_polygon_vertex_position(vertex_index) * circumradius;
float2 second_vertex = this->get_regular_polygon_vertex_position(vertex_index + 1) *
circumradius;
float2 closest_point = this->closest_point_on_line(point, first_vertex, second_vertex);
float distance_to_edge = math::length(closest_point);
/* Mix the distance to the edge with the circumradius, making it tend to the distance to a
* circle when roundness tends to 1. */
float distance_to_edge_round = math::interpolate(distance_to_edge, circumradius, roundness_);
/* The point is outside of the bokeh, so we return 0. */
float distance = math::length(point);
if (distance > distance_to_edge_round) {
return 0.0f;
}
/* The point is inside the catadioptric hole and is not part of the bokeh, so we return 0. */
float catadioptric_distance = distance_to_edge_round * catadioptric_;
if (distance < catadioptric_distance) {
return 0.0f;
}
/* The point is very close to the edge of the bokeh, so we return the difference between the
* distance to the edge and the distance as a form of anti-aliasing. */
if (distance_to_edge_round - distance < 1.0f) {
return distance_to_edge_round - distance;
}
/* The point is very close to the edge of the catadioptric hole, so we return the difference
* between the distance to the hole and the distance as a form of anti-aliasing. */
if (catadioptric_ != 0.0f && distance - catadioptric_distance < 1.0f) {
return distance - catadioptric_distance;
}
/* Otherwise, the point is part of the bokeh and we return 1. */
return 1.0f;
}
void BokehImageOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> /*inputs*/)
{
const float shift = data_->lensshift;
const float shift2 = shift / 2.0f;
const float distance = circular_distance_;
/* Since we need the regular polygon to occupy the entirety of the output image, the circumradius
* of the regular polygon is half the width of the output image. */
float circumradius = float(resolution_) / 2.0f;
for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
const float inside_bokeh_max = is_inside_bokeh(distance, it.x, it.y);
const float inside_bokeh_med = is_inside_bokeh(
distance - fabsf(shift2 * distance), it.x, it.y);
const float inside_bokeh_min = is_inside_bokeh(distance - fabsf(shift * distance), it.x, it.y);
if (shift < 0) {
it.out[0] = inside_bokeh_max;
it.out[1] = inside_bokeh_med;
it.out[2] = inside_bokeh_min;
int2 texel = int2(it.x, it.y);
/* Move the texel coordinates such that the regular polygon is centered. */
float2 point = float2(texel) + float2(0.5f) - circumradius;
/* Each of the color channels of the output image contains a bokeh with a different
* circumradius. The largest one occupies the whole image as stated above, while the other two
* have circumradii that are shifted by an amount that is proportional to the "lens_shift"
* value. The alpha channel of the output is the average of all three values. */
float min_shift = math::abs(lens_shift_ * circumradius);
float min = min_shift == circumradius ? 0.0f : this->bokeh(point, circumradius - min_shift);
float median_shift = min_shift / 2.0f;
float median = this->bokeh(point, circumradius - median_shift);
float max = this->bokeh(point, circumradius);
float4 bokeh = float4(min, median, max, (max + median + min) / 3.0f);
/* If the lens shift is negative, swap the min and max bokeh values, which are stored in the
* red and blue channels respectively. Note that we take the absolute value of the lens shift
* above, so the sign of the lens shift only controls this swap. */
if (lens_shift_ < 0.0f) {
std::swap(bokeh.x, bokeh.z);
}
else {
it.out[0] = inside_bokeh_min;
it.out[1] = inside_bokeh_med;
it.out[2] = inside_bokeh_max;
}
it.out[3] = (inside_bokeh_max + inside_bokeh_med + inside_bokeh_min) / 3.0f;
copy_v4_v4(it.out, bokeh);
}
}
@ -111,13 +174,9 @@ void BokehImageOperation::deinit_execution()
}
}
void BokehImageOperation::determine_canvas(const rcti &preferred_area, rcti &r_area)
void BokehImageOperation::determine_canvas(const rcti & /*preferred_area*/, rcti &r_area)
{
BLI_rcti_init(&r_area,
preferred_area.xmin,
preferred_area.xmin + COM_BLUR_BOKEH_PIXELS,
preferred_area.ymin,
preferred_area.ymin + COM_BLUR_BOKEH_PIXELS);
BLI_rcti_init(&r_area, 0, resolution_, 0, resolution_);
}
} // namespace blender::compositor

View File

@ -4,93 +4,30 @@
#pragma once
#include "BLI_math_vector_types.hh"
#include "COM_MultiThreadedOperation.h"
namespace blender::compositor {
/**
* \brief The #BokehImageOperation class is an operation that creates an image useful to mimic the
* internals of a camera.
*
* features:
* - number of flaps
* - angle offset of the flaps
* - rounding of the flaps (also used to make a circular lens)
* - simulate catadioptric
* - simulate lens-shift
*
* Per pixel the algorithm determines the edge of the bokeh on the same line as the center of the
* image and the pixel is evaluating.
*
* The edge is detected by finding the closest point on the direct line between the two nearest
* flap-corners. this edge is interpolated with a full circle. Result of this edge detection is
* stored as the distance between the center of the image and the edge.
*
* catadioptric lenses are simulated to interpolate between the center of the image and the
* distance of the edge. We now have three distances:
* - Distance between the center of the image and the pixel to be evaluated.
* - Distance between the center of the image and the outer-edge.
* - Distance between the center of the image and the inner-edge.
*
* With a simple compare it can be detected if the evaluated pixel is between the outer and inner
* edge.
*/
class BokehImageOperation : public MultiThreadedOperation {
private:
/**
* \brief Settings of the bokeh image
*/
const NodeBokehImage *data_;
/**
* \brief precalculate center of the image
*/
float center_[2];
int resolution_ = COM_BLUR_BOKEH_PIXELS;
/**
* \brief 1.0-rounding
*/
float inverse_rounding_;
float exterior_angle_;
float rotation_;
float roundness_;
float catadioptric_;
float lens_shift_;
/**
* \brief distance of a full circle lens
*/
float circular_distance_;
/**
* \brief radius when the first flap starts
*/
float flap_rad_;
/**
* \brief radians of a single flap
*/
float flap_rad_add_;
/**
* \brief should the data_ field by deleted when this operation is finished
*/
/* See the delete_data_on_finish method. */
bool delete_data_;
/**
* \brief determine the coordinate of a flap corner.
*
* \param r: result in bokeh-image space are stored [x,y]
* \param flap_number: the flap number to calculate
* \param distance: the lens distance is used to simulate lens shifts
*/
void detemine_start_point_of_flap(float r[2], int flap_number, float distance);
/**
* \brief Determine if a coordinate is inside the bokeh image
*
* \param distance: the distance that will be used.
* This parameter is modified a bit to mimic lens shifts.
* \param x: the x coordinate of the pixel to evaluate
* \param y: the y coordinate of the pixel to evaluate
* \return float range 0..1 0 is completely outside
*/
float is_inside_bokeh(float distance, float x, float y);
float2 get_regular_polygon_vertex_position(int vertex_index);
float2 closest_point_on_line(float2 point, float2 line_start, float2 line_end);
float bokeh(float2 point, float circumradius);
public:
BokehImageOperation();
@ -98,21 +35,18 @@ class BokehImageOperation : public MultiThreadedOperation {
void init_execution() override;
void deinit_execution() override;
/**
* \brief determine the resolution of this operation. currently fixed at [COM_BLUR_BOKEH_PIXELS,
* COM_BLUR_BOKEH_PIXELS] \param resolution: \param preferred_resolution:
*/
void determine_canvas(const rcti &preferred_area, rcti &r_area) override;
/**
* \brief set the node data
* \param data:
*/
void set_data(const NodeBokehImage *data)
{
data_ = data;
}
void set_resolution(int resolution)
{
resolution_ = resolution;
}
/**
* \brief delete_data_on_finish
*

View File

@ -96,7 +96,7 @@ void main()
float circumradius = float(imageSize(output_img).x) / 2.0;
/* Move the texel coordinates such that the regular polygon is centered. */
vec2 point = vec2(texel) - circumradius;
vec2 point = vec2(texel) + vec2(0.5) - circumradius;
/* Each of the color channels of the output image contains a bokeh with a different circumradius.
* The largest one occupies the whole image as stated above, while the other two have circumradii

View File

@ -250,7 +250,7 @@ class Instance {
bool is_transforming() const
{
BLI_assert_msg(is_image_render(), "Need to be checked first otherwise this is unsafe");
BLI_assert_msg(!is_image_render(), "Caller need to check, otherwise this is unsafe");
return (G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT)) != 0;
}

View File

@ -202,6 +202,7 @@ class LightProbeModule {
friend class VolumeProbeModule;
friend class PlanarProbeModule;
friend class SphereProbeModule;
friend class BackgroundPipeline;
private:
Instance &inst_;

View File

@ -72,6 +72,11 @@ class LookdevWorld {
{
return parameters_.background_opacity;
}
float background_blur_get()
{
return parameters_.blur;
}
};
/** \} */

View File

@ -24,7 +24,9 @@ namespace blender::eevee {
* Used to draw background.
* \{ */
void BackgroundPipeline::sync(GPUMaterial *gpumat, const float background_opacity)
void BackgroundPipeline::sync(GPUMaterial *gpumat,
const float background_opacity,
const float background_blur)
{
Manager &manager = *inst_.manager;
RenderBuffers &rbufs = inst_.render_buffers;
@ -33,6 +35,9 @@ void BackgroundPipeline::sync(GPUMaterial *gpumat, const float background_opacit
world_ps_.state_set(DRW_STATE_WRITE_COLOR);
world_ps_.material_set(manager, gpumat);
world_ps_.push_constant("world_opacity_fade", background_opacity);
world_ps_.push_constant("world_background_blur", square_f(background_blur));
SphereProbeData &world_data = *static_cast<SphereProbeData *>(&inst_.light_probes.world_sphere_);
world_ps_.push_constant("world_coord_packed", reinterpret_cast<int4 *>(&world_data.atlas_coord));
world_ps_.bind_texture("utility_tx", inst_.pipelines.utility_tx);
/* RenderPasses & AOVs. Cleared by background (even if bad practice). */
world_ps_.bind_image("rp_color_img", &rbufs.rp_color_tx);
@ -41,6 +46,9 @@ void BackgroundPipeline::sync(GPUMaterial *gpumat, const float background_opacit
/* Required by validation layers. */
world_ps_.bind_resources(inst_.cryptomatte);
world_ps_.bind_resources(inst_.uniform_data);
world_ps_.bind_resources(inst_.sampling);
world_ps_.bind_resources(inst_.sphere_probes);
world_ps_.bind_resources(inst_.volume_probes);
world_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
/* To allow opaque pass rendering over it. */
world_ps_.barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS);
@ -74,6 +82,8 @@ void WorldPipeline::sync(GPUMaterial *gpumat)
Manager &manager = *inst_.manager;
pass.material_set(manager, gpumat);
pass.push_constant("world_opacity_fade", 1.0f);
pass.push_constant("world_background_blur", 0.0f);
pass.push_constant("world_coord_packed", int4(0.0f));
pass.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
pass.bind_image("rp_normal_img", dummy_renderpass_tx_);
pass.bind_image("rp_light_img", dummy_renderpass_tx_);
@ -89,6 +99,9 @@ void WorldPipeline::sync(GPUMaterial *gpumat)
/* Required by validation layers. */
pass.bind_resources(inst_.cryptomatte);
pass.bind_resources(inst_.uniform_data);
pass.bind_resources(inst_.sampling);
pass.bind_resources(inst_.sphere_probes);
pass.bind_resources(inst_.volume_probes);
pass.draw_procedural(GPU_PRIM_TRIS, 1, 3);
}

View File

@ -40,7 +40,7 @@ class BackgroundPipeline {
public:
BackgroundPipeline(Instance &inst) : inst_(inst){};
void sync(GPUMaterial *gpumat, float background_opacity);
void sync(GPUMaterial *gpumat, float background_opacity, float background_blur);
void render(View &view);
};

View File

@ -28,6 +28,10 @@ void Sampling::init(const Scene *scene)
{
sample_count_ = inst_.is_viewport() ? scene->eevee.taa_samples : scene->eevee.taa_render_samples;
if (inst_.is_image_render()) {
sample_count_ = math::max(uint64_t(1), sample_count_);
}
if (sample_count_ == 0) {
BLI_assert(inst_.is_viewport());
sample_count_ = infinite_sample_count_;

View File

@ -793,12 +793,12 @@ static inline bool is_local_light(eLightType type)
/** --- Shadow Data --- */ \
/** Other parts of the perspective matrix. Assumes symmetric frustum. */ \
float clip_side; \
/** Number of allocated tilemap for this local light. */ \
int tilemaps_count; \
/** Scaling factor to the light shape for shadow ray casting. */ \
float shadow_scale; \
/** Shift to apply to the light origin to get the shadow projection origin. */ \
float shadow_projection_shift; \
/** Number of allocated tilemap for this local light. */ \
int tilemaps_count;
float shadow_projection_shift;
/* Untyped local light data. Gets reinterpreted to LightSpotData and LightAreaData.
* Allow access to local light common data without casting. */
@ -861,12 +861,11 @@ struct LightSunData {
float _pad3;
float _pad4;
float _pad5;
float _pad6;
/** --- Shadow Data --- */
/** Offset of the LOD min in LOD min tile units. */
int2 clipmap_base_offset;
/** Offset of the LOD min in LOD min tile units. Split positive and negative for bit-shift. */
int2 clipmap_base_offset_neg;
int2 clipmap_base_offset_pos;
/** Angle covered by the light shape for shadow ray casting. */
float shadow_angle;
/** Trace distance around the shading point. */
@ -1073,7 +1072,8 @@ static inline LightSunData light_sun_data_get(LightData light)
{
SAFE_BEGIN(LightSunData, is_sun_light(light.type))
SAFE_ASSIGN_FLOAT(radius, radius_squared)
SAFE_ASSIGN_FLOAT_AS_INT2_COMBINE(clipmap_base_offset, _pad0_reserved, _pad1_reserved)
SAFE_ASSIGN_FLOAT_AS_INT2_COMBINE(clipmap_base_offset_neg, shadow_scale, shadow_projection_shift)
SAFE_ASSIGN_FLOAT_AS_INT2_COMBINE(clipmap_base_offset_pos, _pad0_reserved, _pad1_reserved)
SAFE_ASSIGN_FLOAT(shadow_angle, _pad1)
SAFE_ASSIGN_FLOAT(shadow_trace_distance, _pad2)
SAFE_ASSIGN_FLOAT2(clipmap_origin, _pad3)

View File

@ -490,12 +490,13 @@ void ShadowDirectional::cascade_tilemaps_distribution(Light &light, const Camera
/* Offset for smooth level transitions. */
light.object_mat.location() = near_point;
/* Offset in tiles from the origin to the center of the first tile-maps. */
/* Offset in tiles from the scene origin to the center of the first tile-maps. */
int2 origin_offset = int2(round(float2(near_point) / tile_size));
/* Offset in tiles between the first and the last tile-maps. */
int2 offset_vector = int2(round(farthest_tilemap_center / tile_size));
light.sun.clipmap_base_offset = (offset_vector * (1 << 16)) / max_ii(levels_range.size() - 1, 1);
light.sun.clipmap_base_offset_pos = (offset_vector * (1 << 16)) /
max_ii(levels_range.size() - 1, 1);
/* \note: cascade_level_range starts the range at the unique LOD to apply to all tile-maps. */
int level = levels_range.first();
@ -504,7 +505,7 @@ void ShadowDirectional::cascade_tilemaps_distribution(Light &light, const Camera
/* Equal spacing between cascades layers since we want uniform shadow density. */
int2 level_offset = origin_offset +
shadow_cascade_grid_offset(light.sun.clipmap_base_offset, i);
shadow_cascade_grid_offset(light.sun.clipmap_base_offset_pos, i);
tilemap->sync_orthographic(object_mat_, level_offset, level, 0.0f, SHADOW_PROJECTION_CASCADE);
/* Add shadow tile-maps grouped by lights to the GPU buffer. */
@ -535,8 +536,8 @@ IndexRange ShadowDirectional::clipmap_level_range(const Camera &camera)
{
using namespace blender::math;
/* Take 16 to be able to pack offset into a single int2. */
const int max_tilemap_per_shadows = 16;
/* 32 to be able to pack offset into two single int2. */
const int max_tilemap_per_shadows = 32;
int user_min_level = floorf(log2(min_resolution_));
/* Covers the farthest points of the view. */
@ -586,8 +587,7 @@ void ShadowDirectional::clipmap_tilemaps_distribution(Light &light,
* single integer where one bit contains offset between 2 levels. Then a single bit shift in
* the shader gives the number of tile to offset in the given tile-map space. However we need
* also the sign of the offset for each level offset. To this end, we split the negative
* offsets to a separate int.
* Recovering the offset with: (pos_offset >> lod) - (neg_offset >> lod). */
* offsets to a separate int. */
int2 lvl_offset_next = tilemaps_[lod + 1]->grid_offset;
int2 lvl_offset = tilemaps_[lod]->grid_offset;
int2 lvl_delta = lvl_offset - (lvl_offset_next << 1);
@ -596,9 +596,9 @@ void ShadowDirectional::clipmap_tilemaps_distribution(Light &light,
neg_offset |= math::max(-lvl_delta, int2(0)) << lod;
}
/* Compressing to a single value to save up storage in light data. Number of levels is limited to
* 16 by `clipmap_level_range()` for this reason. */
light.sun.clipmap_base_offset = pos_offset | (neg_offset << 16);
/* Number of levels is limited to 32 by `clipmap_level_range()` for this reason. */
light.sun.clipmap_base_offset_pos = pos_offset;
light.sun.clipmap_base_offset_neg = neg_offset;
float tile_size_max = ShadowDirectional::tile_size_get(levels_range.last());
int2 level_offset_max = tilemaps_[levels_range.size() - 1]->grid_offset;
@ -1342,7 +1342,7 @@ int ShadowModule::max_view_per_tilemap()
potential_view_count += 1;
}
}
int max_view_count = divide_ceil_u(SHADOW_VIEW_MAX, potential_view_count);
int max_view_count = divide_ceil_u(SHADOW_VIEW_MAX, math::max(potential_view_count, 1));
/* For viewport interactivity, have a hard maximum. This allows smoother experience. */
if (inst_.is_transforming() || inst_.is_navigating()) {
max_view_count = math::min(2, max_view_count);

View File

@ -133,8 +133,9 @@ void World::sync()
float opacity = inst_.use_studio_light() ? lookdev_world_.background_opacity_get() :
inst_.film.background_opacity_get();
float background_blur = inst_.use_studio_light() ? lookdev_world_.background_blur_get() : 0.0;
inst_.pipelines.background.sync(gpumat, opacity);
inst_.pipelines.background.sync(gpumat, opacity, background_blur);
inst_.pipelines.world.sync(gpumat);
}

View File

@ -25,6 +25,6 @@ void main()
vec3 P = transform_point(display_data_buf[display_index].plane_to_world, vec3(lP, 0.0));
gl_Position = drw_point_world_to_homogenous(P);
/* Small bias to let the icon draw without Z-fighting. */
gl_Position.z += 0.0001;
/* Small bias to let the probe draw without Z-fighting. */
gl_Position.z -= 0.0001;
}

View File

@ -210,7 +210,10 @@ ShadowDirectionalSampleInfo shadow_directional_sample_info_get(LightData light,
level;
info.clipmap_offset = shadow_decompress_grid_offset(
light.type, light_sun_data_get(light).clipmap_base_offset, info.level_relative);
light.type,
light_sun_data_get(light).clipmap_base_offset_neg,
light_sun_data_get(light).clipmap_base_offset_pos,
info.level_relative);
info.clipmap_origin = light_sun_data_get(light).clipmap_origin;
return info;

View File

@ -30,6 +30,8 @@ void set_clipmap_data(inout LightData light,
void set_clipmap_base_offset(inout LightData light, ivec2 clipmap_base_offset)
{
/* WATCH: Can get out of sync with light_sun_data_get(). */
light.do_not_access_directly.shadow_scale = intBitsToFloat(0);
light.do_not_access_directly.shadow_projection_shift = intBitsToFloat(0);
light.do_not_access_directly._pad0_reserved = intBitsToFloat(clipmap_base_offset.x);
light.do_not_access_directly._pad1_reserved = intBitsToFloat(clipmap_base_offset.y);
}
@ -47,7 +49,7 @@ void main()
EXPECT_EQ(light_sun_data_get(light).clipmap_lod_min, 1);
EXPECT_EQ(light_sun_data_get(light).clipmap_lod_max, 2);
EXPECT_EQ(light_sun_data_get(light).clipmap_origin, vec2(3.0, 4.0));
EXPECT_EQ(light_sun_data_get(light).clipmap_base_offset, ivec2(5, 6));
EXPECT_EQ(light_sun_data_get(light).clipmap_base_offset_pos, ivec2(5, 6));
}
TEST(eevee_shadow, DirectionalClipmapLevel)
@ -119,7 +121,7 @@ void main()
camera_lP = vec3(0.0, 0.0, 0.0);
/* Follows ShadowDirectional::end_sync(). */
set_clipmap_base_offset(light, ivec2(round(camera_lP.xy / lod_min_tile_size)));
EXPECT_EQ(light_sun_data_get(light).clipmap_base_offset, ivec2(0));
EXPECT_EQ(light_sun_data_get(light).clipmap_base_offset_pos, ivec2(0));
/* Test UVs and tile mapping. */
@ -152,7 +154,7 @@ void main()
camera_lP = vec3(2.0, 2.0, 0.0);
/* Follows ShadowDirectional::end_sync(). */
set_clipmap_base_offset(light, ivec2(round(camera_lP.xy / lod_min_tile_size)));
EXPECT_EQ(light_sun_data_get(light).clipmap_base_offset, ivec2(32));
EXPECT_EQ(light_sun_data_get(light).clipmap_base_offset_pos, ivec2(32));
lP = vec3(2.00001, 2.00001, 0.0);
coords = shadow_directional_coordinates(light, lP);
@ -278,7 +280,7 @@ void main()
// camera_lP = vec3(2.0, 2.0, 0.0);
/* Follows ShadowDirectional::end_sync(). */
// set_clipmap_base_offset(light, ivec2(round(camera_lP.xy / lod_min_tile_size)));
// EXPECT_EQ(light_sun_data_get(light).clipmap_base_offset, ivec2(32));
// EXPECT_EQ(light_sun_data_get(light).clipmap_base_offset_pos, ivec2(32));
// lP = vec3(2.00001, 2.00001, 0.0);
// coords = shadow_directional_coordinates(light, lP);

View File

@ -176,13 +176,16 @@ struct ShadowCoordinates {
};
/* Retain sign bit and avoid costly int division. */
ivec2 shadow_decompress_grid_offset(eLightType light_type, ivec2 offset, int level_relative)
ivec2 shadow_decompress_grid_offset(eLightType light_type,
ivec2 offset_neg,
ivec2 offset_pos,
int level_relative)
{
if (light_type == LIGHT_SUN_ORTHO) {
return shadow_cascade_grid_offset(offset, level_relative);
return shadow_cascade_grid_offset(offset_pos, level_relative);
}
else {
return ((offset & 0xFFFF) >> level_relative) - ((offset >> 16) >> level_relative);
return (offset_pos >> level_relative) - (offset_neg >> level_relative);
}
}
@ -203,7 +206,10 @@ ShadowCoordinates shadow_directional_coordinates_at_level(LightData light, vec3
/* Compute offset in tile. */
ivec2 clipmap_offset = shadow_decompress_grid_offset(
light.type, light_sun_data_get(light).clipmap_base_offset, level_relative);
light.type,
light_sun_data_get(light).clipmap_base_offset_neg,
light_sun_data_get(light).clipmap_base_offset_pos,
level_relative);
ret.uv = lP.xy - light_sun_data_get(light).clipmap_origin;
ret.uv /= exp2(float(ret.lod_relative));

View File

@ -252,7 +252,10 @@ ShadowTracingSample shadow_map_trace_sample(ShadowMapTracingState state,
/* Compute offset in tile. */
ivec2 clipmap_offset = shadow_decompress_grid_offset(
ray.light.type, light_sun_data_get(ray.light).clipmap_base_offset, level_relative);
ray.light.type,
light_sun_data_get(ray.light).clipmap_base_offset_neg,
light_sun_data_get(ray.light).clipmap_base_offset_pos,
level_relative);
/* Translate tilemap UVs to its origin. */
tilemap_uv -= vec2(clipmap_offset) / float(SHADOW_TILEMAP_RES);
/* Clamp to avoid out of tilemap access. */

View File

@ -63,8 +63,7 @@ void init_globals_curves()
/* Random cosine normal distribution on the hair surface. */
float noise = utility_tx_fetch(utility_tx, gl_FragCoord.xy, UTIL_BLUE_NOISE_LAYER).x;
# ifdef EEVEE_SAMPLING_DATA
/* Needs to check for SAMPLING_DATA,
* otherwise Surfel and World (?!?!) shader validation fails. */
/* Needs to check for SAMPLING_DATA, otherwise surfel shader validation fails. */
noise = fract(noise + sampling_rng_1D_get(SAMPLING_CURVES_U));
# endif
cos_theta = noise * 2.0 - 1.0;

View File

@ -13,6 +13,9 @@
#pragma BLENDER_REQUIRE(eevee_surf_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_nodetree_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_colorspace_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_reflection_probe_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_lightprobe_volume_eval_lib.glsl)
vec4 closure_to_rgba(Closure cl)
{
@ -38,6 +41,23 @@ void main()
out_background.rgb = colorspace_safe_color(g_emission) * (1.0 - g_holdout);
out_background.a = saturate(average(g_transmittance)) * g_holdout;
if (g_data.ray_type == RAY_TYPE_CAMERA && world_background_blur != 0.0 &&
world_opacity_fade != 0.0)
{
float base_lod = sphere_probe_roughness_to_lod(world_background_blur);
float lod = max(1.0, base_lod);
float mix_factor = min(1.0, base_lod);
SphereProbeUvArea world_atlas_coord = reinterpret_as_atlas_coord(world_coord_packed);
vec4 probe_color = reflection_probes_sample(-g_data.N, lod, world_atlas_coord);
out_background.rgb = mix(out_background.rgb, probe_color.rgb, mix_factor);
SphericalHarmonicL1 volume_irradiance = lightprobe_irradiance_sample(
g_data.P, vec3(0.0), g_data.Ng);
vec3 radiance_sh = spherical_harmonics_evaluate_lambert(-g_data.N, volume_irradiance);
float radiance_mix_factor = sphere_probe_roughness_to_mix_fac(world_background_blur);
out_background.rgb = mix(out_background.rgb, radiance_sh, radiance_mix_factor);
}
/* World opacity. */
out_background = mix(vec4(0.0, 0.0, 0.0, 1.0), out_background, world_opacity_fade);

View File

@ -218,9 +218,14 @@ GPU_SHADER_CREATE_INFO(eevee_surf_depth)
GPU_SHADER_CREATE_INFO(eevee_surf_world)
.push_constant(Type::FLOAT, "world_opacity_fade")
.push_constant(Type::FLOAT, "world_background_blur")
.push_constant(Type::IVEC4, "world_coord_packed")
.fragment_out(0, Type::VEC4, "out_background")
.fragment_source("eevee_surf_world_frag.glsl")
.additional_info("eevee_global_ubo",
"eevee_reflection_probe_data",
"eevee_volume_probe_data",
"eevee_sampling_data",
/* Optionally added depending on the material. */
// "eevee_render_pass_out",
// "eevee_cryptomatte_out",

View File

@ -701,7 +701,7 @@ static GPENCIL_tObject *grease_pencil_object_cache_populate(GPENCIL_PrivateData
visible_strokes.foreach_index([&](const int stroke_i) {
const IndexRange points = points_by_curve[stroke_i];
const int material_index = stroke_materials[stroke_i];
MaterialGPencilStyle *gp_style = BKE_object_material_get(ob, material_index + 1)->gp_style;
MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, material_index + 1);
const bool hide_material = (gp_style->flag & GP_MATERIAL_HIDE) != 0;
const bool show_stroke = ((gp_style->flag & GP_MATERIAL_STROKE_SHOW) != 0);

View File

@ -330,7 +330,7 @@ static void OVERLAY_outline_grease_pencil(OVERLAY_PrivateData *pd, Scene *scene,
visible_strokes.foreach_index([&](const int stroke_i) {
const IndexRange points = points_by_curve[stroke_i];
const int material_index = stroke_materials[stroke_i];
MaterialGPencilStyle *gp_style = BKE_object_material_get(ob, material_index + 1)->gp_style;
MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, material_index + 1);
const bool hide_material = (gp_style->flag & GP_MATERIAL_HIDE) != 0;
if (hide_material) {

View File

@ -501,7 +501,7 @@ std::string Draw::serialize() const
")";
}
std::string DrawMulti::serialize(std::string line_prefix) const
std::string DrawMulti::serialize(const std::string &line_prefix) const
{
DrawMultiBuf::DrawGroupBuf &groups = multi_draw_buf->group_buf_;

View File

@ -371,7 +371,7 @@ struct DrawMulti {
uint uuid;
void execute(RecordingState &state) const;
std::string serialize(std::string line_prefix) const;
std::string serialize(const std::string &line_prefix) const;
};
struct DrawIndirect {

View File

@ -3365,6 +3365,7 @@ static int click_select_channel_object(bContext *C,
bAnimListElem *ale,
const short /* eEditKeyframes_Select or -1 */ selectmode)
{
using namespace blender::ed;
Scene *scene = ac->scene;
ViewLayer *view_layer = ac->view_layer;
Base *base = (Base *)ale->data;
@ -3377,7 +3378,7 @@ static int click_select_channel_object(bContext *C,
if (selectmode == SELECT_INVERT) {
/* swap select */
ED_object_base_select(base, BA_INVERT);
object::base_select(base, object::BA_INVERT);
if (adt) {
adt->flag ^= ADT_UI_SELECTED;
@ -3393,14 +3394,14 @@ static int click_select_channel_object(bContext *C,
BKE_view_layer_synced_ensure(scene, view_layer);
/* TODO: should this deselect all other types of channels too? */
LISTBASE_FOREACH (Base *, b, BKE_view_layer_object_bases_get(view_layer)) {
ED_object_base_select(b, BA_DESELECT);
object::base_select(b, object::BA_DESELECT);
if (b->object->adt) {
b->object->adt->flag &= ~(ADT_UI_SELECTED | ADT_UI_ACTIVE);
}
}
/* select object now */
ED_object_base_select(base, BA_SELECT);
object::base_select(base, object::BA_SELECT);
if (adt) {
adt->flag |= ADT_UI_SELECTED;
}
@ -3410,7 +3411,7 @@ static int click_select_channel_object(bContext *C,
*
* Ensure we exit edit-mode on whatever object was active before
* to avoid getting stuck there, see: #48747. */
ED_object_base_activate_with_mode_exit_if_needed(C, base); /* adds notifier */
object::base_activate_with_mode_exit_if_needed(C, base); /* adds notifier */
/* Similar to outliner, do not change active element when selecting elements in range. */
if ((adt) && (adt->flag & ADT_UI_SELECTED) && (selectmode != SELECT_EXTEND_RANGE)) {

View File

@ -509,7 +509,7 @@ static void draw_marker(const uiFontStyle *fstyle,
draw_marker_name(text_color, fstyle, marker, xpos, xmax, name_y);
}
static void draw_markers_background(rctf *rect)
static void draw_markers_background(const rctf *rect)
{
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
@ -1304,6 +1304,7 @@ static int select_timeline_marker_frame(ListBase *markers,
static void select_marker_camera_switch(
bContext *C, bool camera, bool extend, ListBase *markers, int cfra)
{
using namespace blender::ed;
#ifdef DURIAN_CAMERA_SWITCH
if (camera) {
BLI_assert(CTX_data_mode_enum(C) == CTX_MODE_OBJECT);
@ -1329,9 +1330,9 @@ static void select_marker_camera_switch(
if (marker->frame == cfra) {
base = BKE_view_layer_base_find(view_layer, marker->camera);
if (base) {
ED_object_base_select(base, eObjectSelect_Mode(sel));
object::base_select(base, object::eObjectSelect_Mode(sel));
if (sel) {
ED_object_base_activate(C, base);
object::base_activate(C, base);
}
}
}

View File

@ -198,7 +198,7 @@ static int insert_key_with_keyingset(bContext *C, wmOperator *op, KeyingSet *ks)
* updated since the last switching to the edit mode will be keyframed correctly
*/
if (obedit && ANIM_keyingset_find_id(ks, (ID *)obedit->data)) {
ED_object_mode_set(C, OB_MODE_OBJECT);
blender::ed::object::mode_set(C, OB_MODE_OBJECT);
ob_edit_mode = true;
}
@ -214,7 +214,7 @@ static int insert_key_with_keyingset(bContext *C, wmOperator *op, KeyingSet *ks)
/* restore the edit mode if necessary */
if (ob_edit_mode) {
ED_object_mode_set(C, OB_MODE_EDIT);
blender::ed::object::mode_set(C, OB_MODE_EDIT);
}
/* report failure or do updates? */

View File

@ -66,7 +66,7 @@ bArmature *ED_armature_context(const bContext *C)
CTX_data_pointer_get_type(C, "armature", &RNA_Armature).data);
if (armature == nullptr) {
Object *object = ED_object_active_context(C);
Object *object = blender::ed::object::context_active_object(C);
if (object && object->type == OB_ARMATURE) {
armature = static_cast<bArmature *>(object->data);
}

View File

@ -493,7 +493,7 @@ int ED_armature_join_objects_exec(bContext *C, wmOperator *op)
}
/* Free the old object data */
ED_object_base_free_and_unlink(bmain, scene, ob_iter);
blender::ed::object::base_free_and_unlink(bmain, scene, ob_iter);
}
}
CTX_DATA_END;
@ -735,7 +735,7 @@ static int separate_armature_exec(bContext *C, wmOperator *op)
/* Only duplicate linked armature but take into account
* user preferences for duplicating actions. */
short dupflag = USER_DUP_ARM | (U.dupflag & USER_DUP_ACT);
Base *base_new = ED_object_add_duplicate(
Base *base_new = blender::ed::object::add_duplicate(
bmain, scene, view_layer, base_old, eDupli_ID_Flags(dupflag));
Object *ob_new = base_new->object;

View File

@ -1092,7 +1092,7 @@ bool ED_armature_edit_select_pick_bone(
BKE_view_layer_synced_ensure(scene, view_layer);
if (BKE_view_layer_active_base_get(view_layer) != basact) {
ED_object_base_activate(C, basact);
blender::ed::object::base_activate(C, basact);
}
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, basact->object);

View File

@ -243,19 +243,19 @@ static void envelope_bone_weighting(Object *ob,
/* add the vert to the deform group if (weight != 0.0) */
if (distance != 0.0f) {
ED_vgroup_vert_add(ob, dgroup, i, distance, WEIGHT_REPLACE);
blender::ed::object::vgroup_vert_add(ob, dgroup, i, distance, WEIGHT_REPLACE);
}
else {
ED_vgroup_vert_remove(ob, dgroup, i);
blender::ed::object::vgroup_vert_remove(ob, dgroup, i);
}
/* do same for mirror */
if (dgroupflip && dgroupflip[j] && iflip != -1) {
if (distance != 0.0f) {
ED_vgroup_vert_add(ob, dgroupflip[j], iflip, distance, WEIGHT_REPLACE);
blender::ed::object::vgroup_vert_add(ob, dgroupflip[j], iflip, distance, WEIGHT_REPLACE);
}
else {
ED_vgroup_vert_remove(ob, dgroupflip[j], iflip);
blender::ed::object::vgroup_vert_remove(ob, dgroupflip[j], iflip);
}
}
}
@ -492,7 +492,7 @@ void ED_object_vgroup_calc_from_armature(ReportList *reports,
if (defbase_add) {
/* It's possible there are DWeights outside the range of the current
* object's deform groups. In this case the new groups won't be empty #33889. */
ED_vgroup_data_clamp_range(static_cast<ID *>(ob->data), defbase_tot);
blender::ed::object::vgroup_data_clamp_range(static_cast<ID *>(ob->data), defbase_tot);
}
}
else if (ELEM(mode, ARM_GROUPS_ENVELOPE, ARM_GROUPS_AUTO)) {

View File

@ -366,7 +366,7 @@ static bool bone_collection_assign_named_mode_specific(bContext *C,
static bool bone_collection_assign_poll(bContext *C)
{
Object *ob = ED_object_context(C);
Object *ob = blender::ed::object::context_object(C);
if (ob == nullptr) {
return false;
}
@ -399,7 +399,7 @@ static bool bone_collection_assign_poll(bContext *C)
/* Assign selected pchans to the bone collection that the user selects */
static int bone_collection_assign_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
Object *ob = blender::ed::object::context_object(C);
if (ob == nullptr) {
return OPERATOR_CANCELLED;
}
@ -469,7 +469,7 @@ void ARMATURE_OT_collection_assign(wmOperatorType *ot)
static bool bone_collection_create_and_assign_poll(bContext *C)
{
Object *ob = ED_object_context(C);
Object *ob = blender::ed::object::context_object(C);
if (ob == nullptr) {
return false;
}
@ -498,7 +498,7 @@ static bool bone_collection_create_and_assign_poll(bContext *C)
/* Assign selected pchans to the bone collection that the user selects */
static int bone_collection_create_and_assign_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
Object *ob = blender::ed::object::context_object(C);
if (ob == nullptr) {
return OPERATOR_CANCELLED;
}
@ -565,7 +565,7 @@ void ARMATURE_OT_collection_create_and_assign(wmOperatorType *ot)
static int bone_collection_unassign_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
Object *ob = blender::ed::object::context_object(C);
if (ob == nullptr) {
return OPERATOR_CANCELLED;
}
@ -626,7 +626,7 @@ void ARMATURE_OT_collection_unassign(wmOperatorType *ot)
static int bone_collection_unassign_named_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
Object *ob = blender::ed::object::context_object(C);
if (ob == nullptr) {
return OPERATOR_CANCELLED;
}
@ -712,7 +712,7 @@ static bool editbone_is_member(const EditBone *ebone, const BoneCollection *bcol
static bool armature_bone_select_poll(bContext *C)
{
Object *ob = ED_object_context(C);
Object *ob = blender::ed::object::context_object(C);
if (ob == nullptr || ob->type != OB_ARMATURE) {
return false;
}
@ -784,7 +784,7 @@ static void bone_collection_select(bContext *C,
static int bone_collection_select_exec(bContext *C, wmOperator * /*op*/)
{
Object *ob = ED_object_context(C);
Object *ob = blender::ed::object::context_object(C);
if (ob == nullptr) {
return OPERATOR_CANCELLED;
}
@ -816,7 +816,7 @@ void ARMATURE_OT_collection_select(wmOperatorType *ot)
static int bone_collection_deselect_exec(bContext *C, wmOperator * /*op*/)
{
Object *ob = ED_object_context(C);
Object *ob = blender::ed::object::context_object(C);
if (ob == nullptr) {
return OPERATOR_CANCELLED;
}
@ -891,7 +891,7 @@ static int add_or_move_to_collection_exec(bContext *C,
const assign_bone_func assign_func_bone,
const assign_ebone_func assign_func_ebone)
{
Object *ob = ED_object_context(C);
Object *ob = blender::ed::object::context_object(C);
if (ob->mode == OB_MODE_POSE) {
ob = ED_pose_object_from_context(C);
}
@ -953,7 +953,7 @@ static int assign_to_collection_exec(bContext *C, wmOperator *op)
static bool move_to_collection_poll(bContext *C)
{
Object *ob = ED_object_context(C);
Object *ob = blender::ed::object::context_object(C);
if (ob == nullptr) {
return false;
}
@ -1062,7 +1062,7 @@ static void move_to_collection_menu_create(bContext *C, uiLayout *layout, void *
bool is_move_operation;
std::tie(parent_bcoll_index, is_move_operation) = menu_custom_data_decode(menu_custom_data);
const Object *ob = ED_object_context(C);
const Object *ob = blender::ed::object::context_object(C);
const bArmature *arm = static_cast<bArmature *>(ob->data);
/* The "Create a new collection" mode of this operator has its own menu, and should thus be

View File

@ -737,9 +737,9 @@ void heat_bone_weighting(Object *ob,
continue;
}
ED_vgroup_vert_remove(ob, dgrouplist[j], a);
blender::ed::object::vgroup_vert_remove(ob, dgrouplist[j], a);
if (vertsflipped && dgroupflip[j] && vertsflipped[a] >= 0) {
ED_vgroup_vert_remove(ob, dgroupflip[j], vertsflipped[a]);
blender::ed::object::vgroup_vert_remove(ob, dgroupflip[j], vertsflipped[a]);
}
}
}
@ -765,16 +765,16 @@ void heat_bone_weighting(Object *ob,
if (bbone) {
if (solution > 0.0f) {
ED_vgroup_vert_add(ob, dgrouplist[j], a, solution, WEIGHT_ADD);
blender::ed::object::vgroup_vert_add(ob, dgrouplist[j], a, solution, WEIGHT_ADD);
}
}
else {
weight = heat_limit_weight(solution);
if (weight > 0.0f) {
ED_vgroup_vert_add(ob, dgrouplist[j], a, weight, WEIGHT_REPLACE);
blender::ed::object::vgroup_vert_add(ob, dgrouplist[j], a, weight, WEIGHT_REPLACE);
}
else {
ED_vgroup_vert_remove(ob, dgrouplist[j], a);
blender::ed::object::vgroup_vert_remove(ob, dgrouplist[j], a);
}
}
@ -782,16 +782,18 @@ void heat_bone_weighting(Object *ob,
if (vertsflipped && dgroupflip[j] && vertsflipped[a] >= 0) {
if (bbone) {
if (solution > 0.0f) {
ED_vgroup_vert_add(ob, dgroupflip[j], vertsflipped[a], solution, WEIGHT_ADD);
blender::ed::object::vgroup_vert_add(
ob, dgroupflip[j], vertsflipped[a], solution, WEIGHT_ADD);
}
}
else {
weight = heat_limit_weight(solution);
if (weight > 0.0f) {
ED_vgroup_vert_add(ob, dgroupflip[j], vertsflipped[a], weight, WEIGHT_REPLACE);
blender::ed::object::vgroup_vert_add(
ob, dgroupflip[j], vertsflipped[a], weight, WEIGHT_REPLACE);
}
else {
ED_vgroup_vert_remove(ob, dgroupflip[j], vertsflipped[a]);
blender::ed::object::vgroup_vert_remove(ob, dgroupflip[j], vertsflipped[a]);
}
}
}
@ -809,17 +811,17 @@ void heat_bone_weighting(Object *ob,
continue;
}
weight = ED_vgroup_vert_weight(ob, dgrouplist[j], a);
weight = blender::ed::object::vgroup_vert_weight(ob, dgrouplist[j], a);
weight = heat_limit_weight(weight);
if (weight <= 0.0f) {
ED_vgroup_vert_remove(ob, dgrouplist[j], a);
blender::ed::object::vgroup_vert_remove(ob, dgrouplist[j], a);
}
if (vertsflipped && dgroupflip[j] && vertsflipped[a] >= 0) {
weight = ED_vgroup_vert_weight(ob, dgroupflip[j], vertsflipped[a]);
weight = blender::ed::object::vgroup_vert_weight(ob, dgroupflip[j], vertsflipped[a]);
weight = heat_limit_weight(weight);
if (weight <= 0.0f) {
ED_vgroup_vert_remove(ob, dgroupflip[j], vertsflipped[a]);
blender::ed::object::vgroup_vert_remove(ob, dgroupflip[j], vertsflipped[a]);
}
}
}

View File

@ -66,7 +66,7 @@ Object *ED_pose_object_from_context(bContext *C)
/* Since this call may also be used from the buttons window,
* we need to check for where to get the object. */
if (area && area->spacetype == SPACE_PROPERTIES) {
ob = ED_object_active_context(C);
ob = blender::ed::object::context_active_object(C);
}
else {
ob = BKE_object_pose_armature_get(CTX_data_active_object(C));

View File

@ -234,7 +234,7 @@ bool ED_armature_pose_select_pick_bone(const Scene *scene,
/* In weight-paint we select the associated vertex group too. */
if (ob_act->mode & OB_MODE_ALL_WEIGHT_PAINT) {
if (bone == arm->act_bone) {
ED_vgroup_select_by_name(ob_act, bone->name);
blender::ed::object::vgroup_select_by_name(ob_act, bone->name);
DEG_id_tag_update(&ob_act->id, ID_RECALC_GEOMETRY);
}
}
@ -304,7 +304,7 @@ void ED_armature_pose_select_in_wpaint_mode(const Scene *scene,
if ((base_arm != nullptr) && (base_arm != base_select) &&
(base_arm->flag & BASE_SELECTED))
{
ED_object_base_select(base_arm, BA_DESELECT);
blender::ed::object::base_select(base_arm, blender::ed::object::BA_DESELECT);
}
}
}
@ -322,14 +322,14 @@ void ED_armature_pose_select_in_wpaint_mode(const Scene *scene,
if ((base_arm != nullptr) && (base_arm != base_select) &&
(base_arm->flag & BASE_SELECTED))
{
ED_object_base_select(base_arm, BA_DESELECT);
blender::ed::object::base_select(base_arm, blender::ed::object::BA_DESELECT);
}
}
}
}
}
if ((base_select->flag & BASE_SELECTED) == 0) {
ED_object_base_select(base_select, BA_SELECT);
blender::ed::object::base_select(base_select, blender::ed::object::BA_SELECT);
}
}
@ -1181,7 +1181,7 @@ static int pose_select_mirror_exec(bContext *C, wmOperator *op)
/* In weight-paint we select the associated vertex group too. */
if (is_weight_paint) {
ED_vgroup_select_by_name(ob_active, pchan_mirror_act->name);
blender::ed::object::vgroup_select_by_name(ob_active, pchan_mirror_act->name);
DEG_id_tag_update(&ob_active->id, ID_RECALC_GEOMETRY);
}
}

View File

@ -19,7 +19,6 @@
struct AssetLibraryReference;
struct bContext;
namespace blender::asset_system {
class AssetLibrary;
class AssetRepresentation;

View File

@ -12,7 +12,6 @@
struct ID;
struct Main;
namespace blender::asset_system {
class AssetRepresentation;
}

View File

@ -14,10 +14,9 @@
struct AssetHandle;
struct AssetLibraryReference;
struct AssetLibraryReference;
struct bContext;
struct ID;
struct ImBuf;
struct bContext;
struct wmNotifier;
struct wmRegionListenerParams;
namespace blender::asset_system {
@ -84,7 +83,7 @@ void storage_exit();
AssetHandle asset_handle_get_by_index(const AssetLibraryReference *library_reference,
int asset_index);
blender::asset_system::AssetRepresentation *asset_get_by_index(
asset_system::AssetRepresentation *asset_get_by_index(
const AssetLibraryReference &library_reference, int asset_index);
bool asset_image_is_loading(const AssetLibraryReference *library_reference,

View File

@ -9,9 +9,9 @@
#pragma once
struct AssetMetaData;
struct bContext;
struct ID;
struct Main;
struct bContext;
namespace blender::ed::asset {

View File

@ -17,8 +17,8 @@ struct bContextDataResult;
struct BlendDataReader;
struct BlendWriter;
struct Main;
struct wmWindowManager;
struct RegionPollParams;
struct wmWindowManager;
namespace blender::ed::asset::shelf {

View File

@ -16,8 +16,6 @@
#include "ED_asset_import.hh"
using namespace blender;
namespace blender::ed::asset {
ID *asset_local_id_ensure_imported(Main &bmain, const asset_system::AssetRepresentation &asset)

View File

@ -632,8 +632,8 @@ int AssetLibraryIndex::remove_broken_index_files()
}
int num_files_deleted = 0;
for (StringRef files_to_remove : files_to_remove) {
if (delete_file_index(files_to_remove)) {
for (StringRef filepath : files_to_remove) {
if (delete_file_index(filepath)) {
num_files_deleted++;
}
}

View File

@ -1391,7 +1391,7 @@ static int separate_exec(bContext *C, wmOperator *op)
/* Take into account user preferences for duplicating actions. */
const eDupli_ID_Flags dupflag = eDupli_ID_Flags(U.dupflag & USER_DUP_ACT);
newbase = ED_object_add_duplicate(bmain, scene, view_layer, oldbase, dupflag);
newbase = blender::ed::object::add_duplicate(bmain, scene, view_layer, oldbase, dupflag);
DEG_relations_tag_update(bmain);
newob = newbase->object;
@ -2714,7 +2714,7 @@ static int set_radius_exec(bContext *C, wmOperator *op)
for (Object *obedit : objects) {
if (ED_object_edit_report_if_shape_key_is_locked(obedit, op->reports)) {
if (blender::ed::object::shape_key_report_if_locked(obedit, op->reports)) {
continue;
}
@ -2831,7 +2831,7 @@ static int smooth_exec(bContext *C, wmOperator *op)
for (Object *obedit : objects) {
if (ED_object_edit_report_if_shape_key_is_locked(obedit, op->reports)) {
if (blender::ed::object::shape_key_report_if_locked(obedit, op->reports)) {
continue;
}
@ -3174,7 +3174,7 @@ static int curve_smooth_radius_exec(bContext *C, wmOperator *op)
for (Object *obedit : objects) {
if (ED_object_edit_report_if_shape_key_is_locked(obedit, op->reports)) {
if (blender::ed::object::shape_key_report_if_locked(obedit, op->reports)) {
continue;
}
@ -3223,7 +3223,7 @@ static int curve_smooth_tilt_exec(bContext *C, wmOperator *op)
for (Object *obedit : objects) {
if (ED_object_edit_report_if_shape_key_is_locked(obedit, op->reports)) {
if (blender::ed::object::shape_key_report_if_locked(obedit, op->reports)) {
continue;
}
@ -4067,7 +4067,7 @@ static int curve_normals_make_consistent_exec(bContext *C, wmOperator *op)
continue;
}
if (ED_object_edit_report_if_shape_key_is_locked(obedit, op->reports)) {
if (blender::ed::object::shape_key_report_if_locked(obedit, op->reports)) {
continue;
}
@ -4997,7 +4997,7 @@ bool ED_curve_editnurb_select_pick(bContext *C,
BKE_view_layer_synced_ensure(vc.scene, vc.view_layer);
if (BKE_view_layer_active_base_get(vc.view_layer) != basact) {
ED_object_base_activate(C, basact);
blender::ed::object::base_activate(C, basact);
}
DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_SELECT | ID_RECALC_SYNC_TO_EVAL);
@ -6994,7 +6994,7 @@ int ED_curve_join_objects_exec(bContext *C, wmOperator *op)
}
}
ED_object_base_free_and_unlink(bmain, scene, ob_iter);
blender::ed::object::base_free_and_unlink(bmain, scene, ob_iter);
}
}
}
@ -7043,7 +7043,7 @@ static int clear_tilt_exec(bContext *C, wmOperator *op)
continue;
}
if (ED_object_edit_report_if_shape_key_is_locked(obedit, op->reports)) {
if (blender::ed::object::shape_key_report_if_locked(obedit, op->reports)) {
continue;
}

View File

@ -509,7 +509,7 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf)
WM_operator_view3d_unit_defaults(C, op);
ED_object_add_generic_get_opts(
blender::ed::object::add_generic_get_opts(
C, op, 'Z', loc, rot, nullptr, &enter_editmode, &local_view_bits, nullptr);
if (!isSurf) { /* adding curve */
@ -517,7 +517,8 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf)
const char *name = get_curve_defname(type);
Curve *cu;
obedit = ED_object_add_type(C, OB_CURVES_LEGACY, name, loc, rot, true, local_view_bits);
obedit = blender::ed::object::add_type(
C, OB_CURVES_LEGACY, name, loc, rot, true, local_view_bits);
newob = true;
cu = (Curve *)obedit->data;
@ -533,7 +534,7 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf)
else { /* adding surface */
if (obedit == nullptr || obedit->type != OB_SURF) {
const char *name = get_surf_defname(type);
obedit = ED_object_add_type(C, OB_SURF, name, loc, rot, true, local_view_bits);
obedit = blender::ed::object::add_type(C, OB_SURF, name, loc, rot, true, local_view_bits);
newob = true;
}
else {
@ -544,7 +545,7 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf)
float radius = RNA_float_get(op->ptr, "radius");
float scale[3];
copy_v3_fl(scale, radius);
ED_object_new_primitive_matrix(C, obedit, loc, rot, scale, mat);
blender::ed::object::new_primitive_matrix(C, obedit, loc, rot, scale, mat);
nu = ED_curve_add_nurbs_primitive(C, obedit, mat, type, newob);
editnurb = object_editcurve_get(obedit);
@ -552,7 +553,7 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf)
/* userdef */
if (newob && !enter_editmode) {
ED_object_editmode_exit_ex(bmain, scene, obedit, EM_FREEDATA);
blender::ed::object::editmode_exit_ex(bmain, scene, obedit, blender::ed::object::EM_FREEDATA);
}
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit);
@ -591,8 +592,8 @@ void CURVE_OT_primitive_bezier_curve_add(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
ED_object_add_unit_props_radius(ot);
ED_object_add_generic_props(ot, true);
blender::ed::object::add_unit_props_radius(ot);
blender::ed::object::add_generic_props(ot, true);
}
static int add_primitive_bezier_circle_exec(bContext *C, wmOperator *op)
@ -614,8 +615,8 @@ void CURVE_OT_primitive_bezier_circle_add(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
ED_object_add_unit_props_radius(ot);
ED_object_add_generic_props(ot, true);
blender::ed::object::add_unit_props_radius(ot);
blender::ed::object::add_generic_props(ot, true);
}
static int add_primitive_nurbs_curve_exec(bContext *C, wmOperator *op)
@ -637,8 +638,8 @@ void CURVE_OT_primitive_nurbs_curve_add(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
ED_object_add_unit_props_radius(ot);
ED_object_add_generic_props(ot, true);
blender::ed::object::add_unit_props_radius(ot);
blender::ed::object::add_generic_props(ot, true);
}
static int add_primitive_nurbs_circle_exec(bContext *C, wmOperator *op)
@ -660,8 +661,8 @@ void CURVE_OT_primitive_nurbs_circle_add(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
ED_object_add_unit_props_radius(ot);
ED_object_add_generic_props(ot, true);
blender::ed::object::add_unit_props_radius(ot);
blender::ed::object::add_generic_props(ot, true);
}
static int add_primitive_curve_path_exec(bContext *C, wmOperator *op)
@ -683,8 +684,8 @@ void CURVE_OT_primitive_nurbs_path_add(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
ED_object_add_unit_props_radius(ot);
ED_object_add_generic_props(ot, true);
blender::ed::object::add_unit_props_radius(ot);
blender::ed::object::add_generic_props(ot, true);
}
/* **************** NURBS surfaces ********************** */
@ -707,8 +708,8 @@ void SURFACE_OT_primitive_nurbs_surface_curve_add(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
ED_object_add_unit_props_radius(ot);
ED_object_add_generic_props(ot, true);
blender::ed::object::add_unit_props_radius(ot);
blender::ed::object::add_generic_props(ot, true);
}
static int add_primitive_nurbs_surface_circle_exec(bContext *C, wmOperator *op)
@ -730,8 +731,8 @@ void SURFACE_OT_primitive_nurbs_surface_circle_add(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
ED_object_add_unit_props_radius(ot);
ED_object_add_generic_props(ot, true);
blender::ed::object::add_unit_props_radius(ot);
blender::ed::object::add_generic_props(ot, true);
}
static int add_primitive_nurbs_surface_surface_exec(bContext *C, wmOperator *op)
@ -753,8 +754,8 @@ void SURFACE_OT_primitive_nurbs_surface_surface_add(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
ED_object_add_unit_props_radius(ot);
ED_object_add_generic_props(ot, true);
blender::ed::object::add_unit_props_radius(ot);
blender::ed::object::add_generic_props(ot, true);
}
static int add_primitive_nurbs_surface_cylinder_exec(bContext *C, wmOperator *op)
@ -776,8 +777,8 @@ void SURFACE_OT_primitive_nurbs_surface_cylinder_add(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
ED_object_add_unit_props_radius(ot);
ED_object_add_generic_props(ot, true);
blender::ed::object::add_unit_props_radius(ot);
blender::ed::object::add_generic_props(ot, true);
}
static int add_primitive_nurbs_surface_sphere_exec(bContext *C, wmOperator *op)
@ -799,8 +800,8 @@ void SURFACE_OT_primitive_nurbs_surface_sphere_add(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
ED_object_add_unit_props_radius(ot);
ED_object_add_generic_props(ot, true);
blender::ed::object::add_unit_props_radius(ot);
blender::ed::object::add_generic_props(ot, true);
}
static int add_primitive_nurbs_surface_torus_exec(bContext *C, wmOperator *op)
@ -822,6 +823,6 @@ void SURFACE_OT_primitive_nurbs_surface_torus_add(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
ED_object_add_unit_props_radius(ot);
ED_object_add_generic_props(ot, true);
blender::ed::object::add_unit_props_radius(ot);
blender::ed::object::add_generic_props(ot, true);
}

View File

@ -2043,7 +2043,7 @@ static int edcu_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmE
BKE_view_layer_synced_ensure(vc.scene, vc.view_layer);
if (BKE_view_layer_active_base_get(vc.view_layer) != basact) {
ED_object_base_activate(C, basact);
blender::ed::object::base_activate(C, basact);
}
DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_SELECT | ID_RECALC_SYNC_TO_EVAL);

View File

@ -809,7 +809,7 @@ static void txt_add_object(bContext *C,
object = BKE_view_layer_active_object_get(view_layer);
/* seems to assume view align ? TODO: look into this, could be an operator option. */
ED_object_base_init_transform_on_add(object, nullptr, rot);
blender::ed::object::init_transform_on_add(object, nullptr, rot);
BKE_object_where_is_calc(depsgraph, scene, obedit);

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