WIP: Brush assets project #106303
|
@ -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)) \
|
||||
{ \
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -512,8 +512,8 @@ static void updateGPUCurveMapping(OCIO_GPUCurveMappping &curvemap,
|
|||
curvemap.cache_id = curve_mapping_settings->cache_id;
|
||||
|
||||
/* Update texture. */
|
||||
int offset[3] = {0, 0, 0};
|
||||
int extent[3] = {curve_mapping_settings->lut_size, 0, 0};
|
||||
const int offset[3] = {0, 0, 0};
|
||||
const int extent[3] = {curve_mapping_settings->lut_size, 0, 0};
|
||||
const float *pixels = curve_mapping_settings->lut;
|
||||
GPU_texture_update_sub(
|
||||
curvemap.texture, GPU_DATA_FLOAT, pixels, UNPACK3(offset), UNPACK3(extent));
|
||||
|
|
|
@ -60,17 +60,17 @@ TEST(MeshTopology, TrivialFaceTopology)
|
|||
EXPECT_EQ(mesh_topology.getNumFaceVertices(2), 5);
|
||||
|
||||
{
|
||||
int vertex_indices[] = {0, 1, 2, 3};
|
||||
const int vertex_indices[] = {0, 1, 2, 3};
|
||||
mesh_topology.setFaceVertexIndices(0, 4, vertex_indices);
|
||||
}
|
||||
|
||||
{
|
||||
int vertex_indices[] = {4, 5, 6};
|
||||
const int vertex_indices[] = {4, 5, 6};
|
||||
mesh_topology.setFaceVertexIndices(1, 3, vertex_indices);
|
||||
}
|
||||
|
||||
{
|
||||
int vertex_indices[] = {7, 8, 9, 10, 11};
|
||||
const int vertex_indices[] = {7, 8, 9, 10, 11};
|
||||
mesh_topology.setFaceVertexIndices(2, 5, vertex_indices);
|
||||
}
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -6556,8 +6556,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':
|
||||
|
@ -6582,8 +6581,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
|
||||
|
||||
|
||||
|
|
|
@ -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). */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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` */
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -32,9 +32,7 @@ void legacy_gpencil_object(Main &bmain, Object &object);
|
|||
void legacy_main(Main &bmain, BlendFileReadReport &reports);
|
||||
|
||||
void thickness_factor_to_modifier(const bGPdata &src_object_data, Object &dst_object);
|
||||
void layer_adjustments_to_modifiers(Main &bmain,
|
||||
const bGPdata &src_object_data,
|
||||
Object &dst_object);
|
||||
void layer_adjustments_to_modifiers(Main &bmain, bGPdata &src_object_data, Object &dst_object);
|
||||
|
||||
void lineart_wrap_v3(const LineartGpencilModifierData *lmd_legacy,
|
||||
GreasePencilLineartModifierData *lmd);
|
||||
|
|
|
@ -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);
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -102,7 +102,7 @@ bool BKE_vfont_to_curve_ex(Object *ob,
|
|||
CharTrans **r_chartransdata);
|
||||
bool BKE_vfont_to_curve_nubase(Object *ob, eEditFontMode mode, ListBase *r_nubase);
|
||||
|
||||
int BKE_vfont_cursor_to_text_index(Object *ob, float cursor_location[2]);
|
||||
int BKE_vfont_cursor_to_text_index(Object *ob, const float cursor_location[2]);
|
||||
|
||||
/**
|
||||
* \warning Expects to have access to evaluated data (i.e. passed object should be evaluated one).
|
||||
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_anim_data.hh"
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_colorband.hh"
|
||||
|
@ -62,23 +63,51 @@ namespace blender::bke::greasepencil::convert {
|
|||
* (also includes drivers, and actions linked through the NLA).
|
||||
* \{ */
|
||||
|
||||
static bool legacy_fcurves_process(ListBase &fcurves,
|
||||
blender::FunctionRef<bool(FCurve *fcurve)> callback)
|
||||
using FCurveCallback = bool(bAction *owner_action, FCurve &fcurve);
|
||||
|
||||
/* Utils to move a list of fcurves from one container (Action or Drivers) to another. */
|
||||
static void legacy_fcurves_move(ListBase &fcurves_dst,
|
||||
ListBase &fcurves_src,
|
||||
const Span<FCurve *> fcurves)
|
||||
{
|
||||
for (FCurve *fcurve : fcurves) {
|
||||
BLI_assert(BLI_findindex(&fcurves_src, fcurve) >= 0);
|
||||
BLI_remlink(&fcurves_src, fcurve);
|
||||
BLI_addtail(&fcurves_dst, fcurve);
|
||||
}
|
||||
}
|
||||
|
||||
/* Basic common check to decide whether a legacy fcurve should be processed or not. */
|
||||
static bool legacy_fcurves_is_valid_for_root_path(FCurve &fcurve, StringRefNull legacy_root_path)
|
||||
{
|
||||
if (!fcurve.rna_path) {
|
||||
return false;
|
||||
}
|
||||
StringRefNull rna_path = fcurve.rna_path;
|
||||
if (!rna_path.startswith(legacy_root_path)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool legacy_fcurves_process(bAction *owner_action,
|
||||
ListBase &fcurves,
|
||||
blender::FunctionRef<FCurveCallback> callback)
|
||||
{
|
||||
bool is_changed = false;
|
||||
LISTBASE_FOREACH (FCurve *, fcurve, &fcurves) {
|
||||
const bool local_is_changed = callback(fcurve);
|
||||
const bool local_is_changed = callback(owner_action, *fcurve);
|
||||
is_changed = is_changed || local_is_changed;
|
||||
}
|
||||
return is_changed;
|
||||
}
|
||||
|
||||
static bool legacy_nla_strip_process(NlaStrip &nla_strip,
|
||||
blender::FunctionRef<bool(FCurve *fcurve)> callback)
|
||||
blender::FunctionRef<FCurveCallback> callback)
|
||||
{
|
||||
bool is_changed = false;
|
||||
if (nla_strip.act) {
|
||||
if (legacy_fcurves_process(nla_strip.act->curves, callback)) {
|
||||
if (legacy_fcurves_process(nla_strip.act, nla_strip.act->curves, callback)) {
|
||||
DEG_id_tag_update(&nla_strip.act->id, ID_RECALC_ANIMATION);
|
||||
is_changed = true;
|
||||
}
|
||||
|
@ -91,24 +120,24 @@ static bool legacy_nla_strip_process(NlaStrip &nla_strip,
|
|||
}
|
||||
|
||||
static bool legacy_animation_process(AnimData &anim_data,
|
||||
blender::FunctionRef<bool(FCurve *fcurve)> callback)
|
||||
blender::FunctionRef<FCurveCallback> callback)
|
||||
{
|
||||
bool is_changed = false;
|
||||
if (anim_data.action) {
|
||||
if (legacy_fcurves_process(anim_data.action->curves, callback)) {
|
||||
if (legacy_fcurves_process(anim_data.action, anim_data.action->curves, callback)) {
|
||||
DEG_id_tag_update(&anim_data.action->id, ID_RECALC_ANIMATION);
|
||||
is_changed = true;
|
||||
}
|
||||
}
|
||||
if (anim_data.tmpact) {
|
||||
if (legacy_fcurves_process(anim_data.tmpact->curves, callback)) {
|
||||
if (legacy_fcurves_process(anim_data.tmpact, anim_data.tmpact->curves, callback)) {
|
||||
DEG_id_tag_update(&anim_data.tmpact->id, ID_RECALC_ANIMATION);
|
||||
is_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const bool local_is_changed = legacy_fcurves_process(anim_data.drivers, callback);
|
||||
const bool local_is_changed = legacy_fcurves_process(nullptr, anim_data.drivers, callback);
|
||||
is_changed = is_changed || local_is_changed;
|
||||
}
|
||||
|
||||
|
@ -623,6 +652,15 @@ void legacy_gpencil_to_grease_pencil(Main &bmain, GreasePencil &grease_pencil, b
|
|||
copy_v3_v3(grease_pencil.onion_skinning_settings.color_after, gpd.gcolor_next);
|
||||
|
||||
BKE_id_materials_copy(&bmain, &gpd.id, &grease_pencil.id);
|
||||
|
||||
/* Copy animation data from legacy GP data.
|
||||
*
|
||||
* Note that currently, Actions IDs are not duplicated. They may be needed ultimately, but for
|
||||
* the time being, assuming invalid fcurves/drivers are fine here. */
|
||||
if (AnimData *gpd_animdata = BKE_animdata_from_id(&gpd.id)) {
|
||||
grease_pencil.adt = BKE_animdata_copy_in_lib(
|
||||
&bmain, gpd.id.lib, gpd_animdata, LIB_ID_COPY_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
static bNodeTree *add_offset_radius_node_tree(Main &bmain)
|
||||
|
@ -737,18 +775,115 @@ void thickness_factor_to_modifier(const bGPdata &src_object_data, Object &dst_ob
|
|||
BKE_modifiers_persistent_uid_init(dst_object, *md);
|
||||
}
|
||||
|
||||
void layer_adjustments_to_modifiers(Main &bmain,
|
||||
const bGPdata &src_object_data,
|
||||
Object &dst_object)
|
||||
void layer_adjustments_to_modifiers(Main &bmain, bGPdata &src_object_data, Object &dst_object)
|
||||
{
|
||||
bNodeTree *offset_radius_node_tree = nullptr;
|
||||
|
||||
/* Handling of animation here is a bit complex, since paths needs to be updated, but also
|
||||
* FCurves need to be transferred from legacy GPData animation to Object animation.
|
||||
*
|
||||
* NOTE: NLA animation in GPData that would control adjustment properties is not converted. This
|
||||
* would require (partially) re-creating a copy of the potential bGPData NLA into the Object NLA,
|
||||
* which is too complex for the few potential usecases.
|
||||
*
|
||||
* This is achieved in several steps, roughly:
|
||||
* * For each GP layer, chack if there is animation on the adjutment data.
|
||||
* * Rename relevant FCurves RNA paths from GP animation data, and store their reference in
|
||||
* temporary vectors.
|
||||
* * Once all layers have been processed, move all affected FCurves from GPData animation to
|
||||
* Object one. */
|
||||
|
||||
AnimData *gpd_animdata = BKE_animdata_from_id(&src_object_data.id);
|
||||
AnimData *dst_object_animdata = BKE_animdata_from_id(&dst_object.id);
|
||||
|
||||
/* Old 'adjutment' GPData RNA property path to new matching modifier property RNA path. */
|
||||
static const std::pair<const char *, const char *> fcurve_tint_valid_prop_paths[] = {
|
||||
{".tint_color", ".color"}, {".tint_factor", ".factor"}};
|
||||
static const std::pair<const char *, const char *> fcurve_thickness_valid_prop_paths[] = {
|
||||
{".line_change", "[\"Socket_1\"]"}};
|
||||
|
||||
/* Store all FCurves that need to be moved from GPData animation to Object animation,
|
||||
* respectively for the main action, the temp action, and the drivers. */
|
||||
blender::Vector<FCurve *> fcurves_from_gpd_main_action;
|
||||
blender::Vector<FCurve *> fcurves_from_gpd_tmp_action;
|
||||
blender::Vector<FCurve *> fcurves_from_gpd_drivers;
|
||||
|
||||
/* Common filtering of FCurve RNA path to decide whether they can/need to be processed here or
|
||||
* not. */
|
||||
auto adjustment_animation_fcurve_is_valid =
|
||||
[&](bAction *owner_action, FCurve &fcurve, blender::StringRefNull legacy_root_path) -> bool {
|
||||
/* Only take into account drivers (nullptr `action_owner`), and Actions directly assigned
|
||||
* to the animdata, not the NLA ones. */
|
||||
if (owner_action && !ELEM(owner_action, gpd_animdata->action, gpd_animdata->tmpact)) {
|
||||
return false;
|
||||
}
|
||||
if (!legacy_fcurves_is_valid_for_root_path(fcurve, legacy_root_path)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
/* Replace layer adjustments with modifiers. */
|
||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &src_object_data.layers) {
|
||||
const float3 tint_color = float3(gpl->tintcolor);
|
||||
const float tint_factor = gpl->tintcolor[3];
|
||||
const int thickness_px = gpl->line_change;
|
||||
|
||||
bool has_tint_adjustment = tint_factor > 0.0f;
|
||||
bool has_tint_adjustment_animation = false;
|
||||
bool has_thickness_adjustment = thickness_px != 0;
|
||||
bool has_thickness_adjustment_animation = false;
|
||||
|
||||
char layer_name_esc[sizeof(gpl->info) * 2];
|
||||
BLI_str_escape(layer_name_esc, gpl->info, sizeof(layer_name_esc));
|
||||
const std::string legacy_root_path = fmt::format("layers[\"{}\"]", layer_name_esc);
|
||||
|
||||
/* If tint or thickness are animated, relevamt modifiers also need to be created. */
|
||||
if (gpd_animdata) {
|
||||
auto adjustment_animation_detection = [&](bAction *owner_action, FCurve &fcurve) -> bool {
|
||||
/* Early out if we already know that both data are animated. */
|
||||
if (has_tint_adjustment_animation && has_thickness_adjustment_animation) {
|
||||
return false;
|
||||
}
|
||||
if (!adjustment_animation_fcurve_is_valid(owner_action, fcurve, legacy_root_path)) {
|
||||
return false;
|
||||
}
|
||||
StringRefNull rna_path = fcurve.rna_path;
|
||||
for (const auto &[from_prop_path, to_prop_path] : fcurve_tint_valid_prop_paths) {
|
||||
const char *rna_adjustment_prop_path = from_prop_path;
|
||||
const std::string old_rna_path = fmt::format(
|
||||
"{}{}", legacy_root_path, rna_adjustment_prop_path);
|
||||
if (rna_path == old_rna_path) {
|
||||
has_tint_adjustment_animation = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (const auto &[from_prop_path, to_prop_path] : fcurve_thickness_valid_prop_paths) {
|
||||
const char *rna_prop_rna_adjustment_prop_pathpath = from_prop_path;
|
||||
const std::string old_rna_path = fmt::format(
|
||||
"{}{}", legacy_root_path, rna_prop_rna_adjustment_prop_pathpath);
|
||||
if (rna_path == old_rna_path) {
|
||||
has_thickness_adjustment_animation = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
legacy_animation_process(*gpd_animdata, adjustment_animation_detection);
|
||||
has_tint_adjustment = has_tint_adjustment || has_tint_adjustment_animation;
|
||||
has_thickness_adjustment = has_thickness_adjustment || has_thickness_adjustment_animation;
|
||||
}
|
||||
|
||||
/* Create animdata in destination object if needed. */
|
||||
if ((has_tint_adjustment_animation || has_thickness_adjustment_animation) &&
|
||||
!dst_object_animdata)
|
||||
{
|
||||
dst_object_animdata = BKE_animdata_ensure_id(&dst_object.id);
|
||||
}
|
||||
|
||||
/* Tint adjustment. */
|
||||
if (tint_factor > 0.0f) {
|
||||
if (has_tint_adjustment) {
|
||||
ModifierData *md = BKE_modifier_new(eModifierType_GreasePencilTint);
|
||||
GreasePencilTintModifierData *tmd = reinterpret_cast<GreasePencilTintModifierData *>(md);
|
||||
|
||||
|
@ -756,16 +891,59 @@ void layer_adjustments_to_modifiers(Main &bmain,
|
|||
tmd->factor = tint_factor;
|
||||
STRNCPY(tmd->influence.layer_name, gpl->info);
|
||||
|
||||
char modifier_name[64];
|
||||
char modifier_name[MAX_NAME];
|
||||
SNPRINTF(modifier_name, "Tint %s", gpl->info);
|
||||
STRNCPY(md->name, modifier_name);
|
||||
BKE_modifier_unique_name(&dst_object.modifiers, md);
|
||||
|
||||
BLI_addtail(&dst_object.modifiers, md);
|
||||
BKE_modifiers_persistent_uid_init(dst_object, *md);
|
||||
|
||||
if (has_tint_adjustment_animation) {
|
||||
char modifier_name_esc[MAX_NAME * 2];
|
||||
BLI_str_escape(modifier_name_esc, md->name, sizeof(modifier_name_esc));
|
||||
|
||||
auto adjustment_tint_path_update = [&](bAction *owner_action, FCurve &fcurve) -> bool {
|
||||
if (!adjustment_animation_fcurve_is_valid(owner_action, fcurve, legacy_root_path)) {
|
||||
return false;
|
||||
}
|
||||
StringRefNull rna_path = fcurve.rna_path;
|
||||
for (const auto &[from_prop_path, to_prop_path] : fcurve_tint_valid_prop_paths) {
|
||||
const char *rna_adjustment_prop_path = from_prop_path;
|
||||
const char *rna_modifier_prop_path = to_prop_path;
|
||||
const std::string old_rna_path = fmt::format(
|
||||
"{}{}", legacy_root_path, rna_adjustment_prop_path);
|
||||
if (rna_path == old_rna_path) {
|
||||
const std::string new_rna_path = fmt::format(
|
||||
"modifiers[\"{}\"]{}", modifier_name_esc, rna_modifier_prop_path);
|
||||
MEM_freeN(fcurve.rna_path);
|
||||
fcurve.rna_path = BLI_strdupn(new_rna_path.c_str(), new_rna_path.size());
|
||||
if (owner_action) {
|
||||
if (owner_action == gpd_animdata->action) {
|
||||
fcurves_from_gpd_main_action.append(&fcurve);
|
||||
}
|
||||
else {
|
||||
BLI_assert(owner_action == gpd_animdata->tmpact);
|
||||
fcurves_from_gpd_tmp_action.append(&fcurve);
|
||||
}
|
||||
}
|
||||
else { /* Driver */
|
||||
fcurves_from_gpd_drivers.append(&fcurve);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const bool has_edits = legacy_animation_process(*gpd_animdata,
|
||||
adjustment_tint_path_update);
|
||||
BLI_assert(has_edits);
|
||||
UNUSED_VARS_NDEBUG(has_edits);
|
||||
}
|
||||
}
|
||||
/* Thickness adjustment. */
|
||||
if (thickness_px != 0) {
|
||||
if (has_thickness_adjustment) {
|
||||
/* Convert the "pixel" offset value into a radius value.
|
||||
* GPv2 used a conversion of 1 "px" = 0.001. */
|
||||
/* Note: this offset may be negative. */
|
||||
|
@ -776,7 +954,7 @@ void layer_adjustments_to_modifiers(Main &bmain,
|
|||
}
|
||||
auto *md = reinterpret_cast<NodesModifierData *>(BKE_modifier_new(eModifierType_Nodes));
|
||||
|
||||
char modifier_name[64];
|
||||
char modifier_name[MAX_NAME];
|
||||
SNPRINTF(modifier_name, "Thickness %s", gpl->info);
|
||||
STRNCPY(md->modifier.name, modifier_name);
|
||||
BKE_modifier_unique_name(&dst_object.modifiers, &md->modifier);
|
||||
|
@ -790,14 +968,85 @@ void layer_adjustments_to_modifiers(Main &bmain,
|
|||
bke::idprop::create(DATA_("Socket_2"), radius_offset).release();
|
||||
auto *ui_data = reinterpret_cast<IDPropertyUIDataFloat *>(
|
||||
IDP_ui_data_ensure(radius_offset_prop));
|
||||
ui_data->soft_min = 0.0f;
|
||||
ui_data->soft_min = 0.0;
|
||||
ui_data->base.rna_subtype = PROP_TRANSLATION;
|
||||
IDP_AddToGroup(md->settings.properties, radius_offset_prop);
|
||||
IDP_AddToGroup(md->settings.properties,
|
||||
bke::idprop::create(DATA_("Socket_3"), gpl->info).release());
|
||||
|
||||
if (has_thickness_adjustment_animation) {
|
||||
char modifier_name_esc[MAX_NAME * 2];
|
||||
BLI_str_escape(modifier_name_esc, md->modifier.name, sizeof(modifier_name_esc));
|
||||
|
||||
auto adjustment_thickness_path_update = [&](bAction *owner_action,
|
||||
FCurve &fcurve) -> bool {
|
||||
if (!adjustment_animation_fcurve_is_valid(owner_action, fcurve, legacy_root_path)) {
|
||||
return false;
|
||||
}
|
||||
StringRefNull rna_path = fcurve.rna_path;
|
||||
for (const auto &[from_prop_path, to_prop_path] : fcurve_thickness_valid_prop_paths) {
|
||||
const char *rna_adjustment_prop_path = from_prop_path;
|
||||
const char *rna_modifier_prop_path = to_prop_path;
|
||||
const std::string old_rna_path = fmt::format(
|
||||
"{}{}", legacy_root_path, rna_adjustment_prop_path);
|
||||
if (rna_path == old_rna_path) {
|
||||
const std::string new_rna_path = fmt::format(
|
||||
"modifiers[\"{}\"]{}", modifier_name_esc, rna_modifier_prop_path);
|
||||
MEM_freeN(fcurve.rna_path);
|
||||
fcurve.rna_path = BLI_strdupn(new_rna_path.c_str(), new_rna_path.size());
|
||||
if (owner_action) {
|
||||
if (owner_action == gpd_animdata->action) {
|
||||
fcurves_from_gpd_main_action.append(&fcurve);
|
||||
}
|
||||
else {
|
||||
BLI_assert(owner_action == gpd_animdata->tmpact);
|
||||
fcurves_from_gpd_tmp_action.append(&fcurve);
|
||||
}
|
||||
}
|
||||
else { /* Driver */
|
||||
fcurves_from_gpd_drivers.append(&fcurve);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const bool has_edits = legacy_animation_process(*gpd_animdata,
|
||||
adjustment_thickness_path_update);
|
||||
BLI_assert(has_edits);
|
||||
UNUSED_VARS_NDEBUG(has_edits);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!fcurves_from_gpd_main_action.is_empty()) {
|
||||
if (!dst_object_animdata->action) {
|
||||
dst_object_animdata->action = BKE_action_add(&bmain, gpd_animdata->action->id.name + 2);
|
||||
}
|
||||
legacy_fcurves_move(dst_object_animdata->action->curves,
|
||||
gpd_animdata->action->curves,
|
||||
fcurves_from_gpd_main_action);
|
||||
DEG_id_tag_update(&dst_object.id, ID_RECALC_ANIMATION);
|
||||
DEG_id_tag_update(&src_object_data.id, ID_RECALC_ANIMATION);
|
||||
}
|
||||
if (!fcurves_from_gpd_tmp_action.is_empty()) {
|
||||
if (!dst_object_animdata->tmpact) {
|
||||
dst_object_animdata->tmpact = BKE_action_add(&bmain, gpd_animdata->tmpact->id.name + 2);
|
||||
}
|
||||
legacy_fcurves_move(dst_object_animdata->tmpact->curves,
|
||||
gpd_animdata->tmpact->curves,
|
||||
fcurves_from_gpd_tmp_action);
|
||||
DEG_id_tag_update(&dst_object.id, ID_RECALC_ANIMATION);
|
||||
DEG_id_tag_update(&src_object_data.id, ID_RECALC_ANIMATION);
|
||||
}
|
||||
if (!fcurves_from_gpd_drivers.is_empty()) {
|
||||
legacy_fcurves_move(
|
||||
dst_object_animdata->drivers, gpd_animdata->drivers, fcurves_from_gpd_drivers);
|
||||
DEG_id_tag_update(&dst_object.id, ID_RECALC_ANIMATION);
|
||||
DEG_id_tag_update(&src_object_data.id, ID_RECALC_ANIMATION);
|
||||
}
|
||||
|
||||
DEG_relations_tag_update(&bmain);
|
||||
}
|
||||
|
||||
|
@ -805,7 +1054,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);
|
||||
|
||||
|
@ -838,8 +1087,7 @@ static ModifierData &legacy_object_modifier_common(Object &object,
|
|||
new_md.ui_expand_flag = legacy_md.ui_expand_flag;
|
||||
|
||||
/* Convert animation data if needed. */
|
||||
AnimData *anim_data = BKE_animdata_from_id(&object.id);
|
||||
if (anim_data) {
|
||||
if (AnimData *anim_data = BKE_animdata_from_id(&object.id)) {
|
||||
char legacy_name_esc[MAX_NAME * 2];
|
||||
BLI_str_escape(legacy_name_esc, legacy_md.name, sizeof(legacy_name_esc));
|
||||
const std::string legacy_root_path = fmt::format("grease_pencil_modifiers[\"{}\"]",
|
||||
|
@ -847,20 +1095,15 @@ static ModifierData &legacy_object_modifier_common(Object &object,
|
|||
char new_name_esc[MAX_NAME * 2];
|
||||
BLI_str_escape(new_name_esc, new_md.name, sizeof(new_name_esc));
|
||||
|
||||
auto modifier_path_update = [&](FCurve *fcurve) -> bool {
|
||||
/* NOTE: This logic will likely need to be re-used in other similar conditions for other
|
||||
* areas, should be put into its own util then. */
|
||||
if (!fcurve->rna_path) {
|
||||
return false;
|
||||
}
|
||||
StringRefNull rna_path = fcurve->rna_path;
|
||||
if (!rna_path.startswith(legacy_root_path)) {
|
||||
auto modifier_path_update = [&](bAction * /*owner_action*/, FCurve &fcurve) -> bool {
|
||||
if (!legacy_fcurves_is_valid_for_root_path(fcurve, legacy_root_path)) {
|
||||
return false;
|
||||
}
|
||||
StringRefNull rna_path = fcurve.rna_path;
|
||||
const std::string new_rna_path = fmt::format(
|
||||
"modifiers[\"{}\"]{}", new_name_esc, rna_path.substr(int64_t(legacy_root_path.size())));
|
||||
MEM_freeN(fcurve->rna_path);
|
||||
fcurve->rna_path = BLI_strdupn(new_rna_path.c_str(), new_rna_path.size());
|
||||
MEM_freeN(fcurve.rna_path);
|
||||
fcurve.rna_path = BLI_strdupn(new_rna_path.c_str(), new_rna_path.size());
|
||||
return true;
|
||||
};
|
||||
|
||||
|
|
|
@ -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))))
|
||||
|
||||
|
|
|
@ -1022,8 +1022,8 @@ static const char *particle_adrcodes_to_paths(int adrcode, int *r_array_index)
|
|||
static char *get_rna_access(ID *id,
|
||||
int blocktype,
|
||||
int adrcode,
|
||||
char actname[],
|
||||
char constname[],
|
||||
const char actname[],
|
||||
const char constname[],
|
||||
Sequence *seq,
|
||||
int *r_array_index)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -3137,7 +3137,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)
|
||||
{
|
||||
|
@ -3146,8 +3146,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;
|
||||
}
|
||||
|
@ -3158,9 +3158,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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
|
@ -2270,8 +2270,8 @@ int txt_setcurr_tab_spaces(Text *text, int space)
|
|||
int text_check_bracket(const char ch)
|
||||
{
|
||||
int a;
|
||||
char opens[] = "([{";
|
||||
char close[] = ")]}";
|
||||
const char opens[] = "([{";
|
||||
const char close[] = ")]}";
|
||||
|
||||
for (a = 0; a < (sizeof(opens) - 1); a++) {
|
||||
if (ch == opens[a]) {
|
||||
|
|
|
@ -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) {
|
||||
|
@ -2006,7 +2006,7 @@ bool BKE_vfont_to_curve_ex(Object *ob,
|
|||
return data.ok;
|
||||
}
|
||||
|
||||
int BKE_vfont_cursor_to_text_index(Object *ob, float cursor_location[2])
|
||||
int BKE_vfont_cursor_to_text_index(Object *ob, const float cursor_location[2])
|
||||
{
|
||||
Curve *cu = (Curve *)ob->data;
|
||||
ListBase *r_nubase = &cu->nurb;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -317,7 +317,7 @@ bool _bli_array_iter_spiral_square(const void *arr_v,
|
|||
}
|
||||
|
||||
/* For check_bounds. */
|
||||
int limits[2] = {(arr_shape[0] - 1) * stride[0], stride[0] - stride[1]};
|
||||
const int limits[2] = {(arr_shape[0] - 1) * stride[0], stride[0] - stride[1]};
|
||||
|
||||
int steps = 0;
|
||||
while (steps < steps_out) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -294,7 +294,7 @@ TEST(expr_pylike, Eval_Ternary1)
|
|||
TEST(expr_pylike, MultipleArgs)
|
||||
{
|
||||
const char *names[3] = {"x", "y", "x"};
|
||||
double values[3] = {1.0, 2.0, 3.0};
|
||||
const double values[3] = {1.0, 2.0, 3.0};
|
||||
|
||||
ExprPyLike_Parsed *expr = BLI_expr_pylike_parse("x*10 + y", names, ARRAY_SIZE(names));
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
TEST(math_color, RGBToHSVRoundtrip)
|
||||
{
|
||||
float orig_rgb[3] = {0.1f, 0.2f, 0.3f};
|
||||
const float orig_rgb[3] = {0.1f, 0.2f, 0.3f};
|
||||
float hsv[3], rgb[3];
|
||||
rgb_to_hsv_v(orig_rgb, hsv);
|
||||
hsv_to_rgb_v(hsv, rgb);
|
||||
|
@ -17,7 +17,7 @@ TEST(math_color, RGBToHSVRoundtrip)
|
|||
|
||||
TEST(math_color, RGBToHSLRoundtrip)
|
||||
{
|
||||
float orig_rgb[3] = {0.1f, 0.2f, 0.3f};
|
||||
const float orig_rgb[3] = {0.1f, 0.2f, 0.3f};
|
||||
float hsl[3], rgb[3];
|
||||
rgb_to_hsl_v(orig_rgb, hsl);
|
||||
hsl_to_rgb_v(hsl, rgb);
|
||||
|
@ -26,7 +26,7 @@ TEST(math_color, RGBToHSLRoundtrip)
|
|||
|
||||
TEST(math_color, RGBToYUVRoundtrip)
|
||||
{
|
||||
float orig_rgb[3] = {0.1f, 0.2f, 0.3f};
|
||||
const float orig_rgb[3] = {0.1f, 0.2f, 0.3f};
|
||||
float yuv[3], rgb[3];
|
||||
rgb_to_yuv(orig_rgb[0], orig_rgb[1], orig_rgb[2], &yuv[0], &yuv[1], &yuv[2], BLI_YUV_ITU_BT709);
|
||||
yuv_to_rgb(yuv[0], yuv[1], yuv[2], &rgb[0], &rgb[1], &rgb[2], BLI_YUV_ITU_BT709);
|
||||
|
@ -35,7 +35,7 @@ TEST(math_color, RGBToYUVRoundtrip)
|
|||
|
||||
TEST(math_color, RGBToYCCRoundtrip)
|
||||
{
|
||||
float orig_rgb[3] = {0.1f, 0.2f, 0.3f};
|
||||
const float orig_rgb[3] = {0.1f, 0.2f, 0.3f};
|
||||
float ycc[3], rgb[3];
|
||||
|
||||
rgb_to_ycc(orig_rgb[0], orig_rgb[1], orig_rgb[2], &ycc[0], &ycc[1], &ycc[2], BLI_YCC_ITU_BT601);
|
||||
|
|
|
@ -111,7 +111,7 @@ TEST(math_matrix, mul_m3_series)
|
|||
{0.0f, 0.0f, 5.0f},
|
||||
};
|
||||
mul_m3_series(matrix, matrix, matrix, matrix);
|
||||
float expect[3][3] = {
|
||||
float const expect[3][3] = {
|
||||
{8.0f, 0.0f, 0.0f},
|
||||
{0.0f, 27.0f, 0.0f},
|
||||
{0.0f, 0.0f, 125.0f},
|
||||
|
@ -128,7 +128,7 @@ TEST(math_matrix, mul_m4_series)
|
|||
{0.0f, 0.0f, 0.0f, 7.0f},
|
||||
};
|
||||
mul_m4_series(matrix, matrix, matrix, matrix);
|
||||
float expect[4][4] = {
|
||||
float const expect[4][4] = {
|
||||
{8.0f, 0.0f, 0.0f, 0.0f},
|
||||
{0.0f, 27.0f, 0.0f, 0.0f},
|
||||
{0.0f, 0.0f, 125.0f, 0.0f},
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
|
||||
TEST(math_solvers, Tridiagonal1)
|
||||
{
|
||||
float a[1] = {1}; // ignored
|
||||
float b[1] = {2};
|
||||
float c[1] = {1}; // ignored
|
||||
float d[1] = {4};
|
||||
const float a[1] = {1}; // ignored
|
||||
const float b[1] = {2};
|
||||
const float c[1] = {1}; // ignored
|
||||
const float d[1] = {4};
|
||||
float x[1];
|
||||
|
||||
EXPECT_TRUE(BLI_tridiagonal_solve(a, b, c, d, x, 1));
|
||||
|
@ -20,10 +20,10 @@ TEST(math_solvers, Tridiagonal1)
|
|||
|
||||
TEST(math_solvers, Tridiagonal3)
|
||||
{
|
||||
float a[3] = {1, 2, 3}; // 1 ignored
|
||||
float b[3] = {4, 5, 6};
|
||||
float c[3] = {7, 8, 9}; // 9 ignored
|
||||
float d[3] = {18, 36, 24};
|
||||
const float a[3] = {1, 2, 3}; // 1 ignored
|
||||
const float b[3] = {4, 5, 6};
|
||||
const float c[3] = {7, 8, 9}; // 9 ignored
|
||||
const float d[3] = {18, 36, 24};
|
||||
float x[3];
|
||||
|
||||
EXPECT_TRUE(BLI_tridiagonal_solve(a, b, c, d, x, 3));
|
||||
|
@ -34,10 +34,10 @@ TEST(math_solvers, Tridiagonal3)
|
|||
|
||||
TEST(math_solvers, CyclicTridiagonal1)
|
||||
{
|
||||
float a[1] = {1};
|
||||
float b[1] = {2};
|
||||
float c[1] = {1};
|
||||
float d[1] = {4};
|
||||
const float a[1] = {1};
|
||||
const float b[1] = {2};
|
||||
const float c[1] = {1};
|
||||
const float d[1] = {4};
|
||||
float x[1];
|
||||
|
||||
EXPECT_TRUE(BLI_tridiagonal_solve_cyclic(a, b, c, d, x, 1));
|
||||
|
@ -46,10 +46,10 @@ TEST(math_solvers, CyclicTridiagonal1)
|
|||
|
||||
TEST(math_solvers, CyclicTridiagonal2)
|
||||
{
|
||||
float a[2] = {1, 2};
|
||||
float b[2] = {3, 4};
|
||||
float c[2] = {5, 6};
|
||||
float d[2] = {15, 16};
|
||||
const float a[2] = {1, 2};
|
||||
const float b[2] = {3, 4};
|
||||
const float c[2] = {5, 6};
|
||||
const float d[2] = {15, 16};
|
||||
float x[2];
|
||||
|
||||
EXPECT_TRUE(BLI_tridiagonal_solve_cyclic(a, b, c, d, x, 2));
|
||||
|
@ -59,10 +59,10 @@ TEST(math_solvers, CyclicTridiagonal2)
|
|||
|
||||
TEST(math_solvers, CyclicTridiagonal3)
|
||||
{
|
||||
float a[3] = {1, 2, 3};
|
||||
float b[3] = {4, 5, 6};
|
||||
float c[3] = {7, 8, 9};
|
||||
float d[3] = {21, 36, 33};
|
||||
const float a[3] = {1, 2, 3};
|
||||
const float b[3] = {4, 5, 6};
|
||||
const float c[3] = {7, 8, 9};
|
||||
const float d[3] = {21, 36, 33};
|
||||
float x[3];
|
||||
|
||||
EXPECT_TRUE(BLI_tridiagonal_solve_cyclic(a, b, c, d, x, 3));
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -91,6 +91,7 @@ void DefocusNode::convert_to_operations(NodeConverter &converter,
|
|||
|
||||
BokehImageOperation *bokeh = new BokehImageOperation();
|
||||
bokeh->set_data(bokehdata);
|
||||
bokeh->set_resolution(math::ceil(data->maxblur) * 2 + 1);
|
||||
bokeh->delete_data_on_finish();
|
||||
converter.add_operation(bokeh);
|
||||
|
||||
|
@ -101,7 +102,7 @@ void DefocusNode::convert_to_operations(NodeConverter &converter,
|
|||
VariableSizeBokehBlurOperation *operation = new VariableSizeBokehBlurOperation();
|
||||
operation->set_quality(eCompositorQuality::High);
|
||||
operation->set_max_blur(data->maxblur);
|
||||
operation->set_threshold(data->bthresh);
|
||||
operation->set_threshold(0.0f);
|
||||
converter.add_operation(operation);
|
||||
|
||||
converter.add_link(bokeh->get_output_socket(), operation->get_input_socket(1));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -87,7 +87,6 @@ void VariableSizeBokehBlurOperation::update_memory_buffer_partial(MemoryBuffer *
|
|||
const float base_size = do_size_scale_ ? (max_dim / 100.0f) : 1.0f;
|
||||
const float maximum_size = size_buffer->get_max_value();
|
||||
const int search_radius = math::clamp(int(maximum_size * base_size), 0, max_blur_);
|
||||
const int2 bokeh_size = int2(bokeh_buffer->get_width(), bokeh_buffer->get_height());
|
||||
|
||||
BuffersIterator<float> it = output->iterate_with({}, area);
|
||||
for (; !it.is_end(); ++it) {
|
||||
|
@ -115,8 +114,8 @@ void VariableSizeBokehBlurOperation::update_memory_buffer_partial(MemoryBuffer *
|
|||
}
|
||||
|
||||
const float2 normalized_texel = (float2(xi, yi) + size + 0.5f) / (size * 2.0f + 1.0f);
|
||||
const float2 weight_texel = (1.0f - normalized_texel) * float2(bokeh_size - 1);
|
||||
const float4 weight = bokeh_buffer->get_elem(int(weight_texel.x), int(weight_texel.y));
|
||||
const float2 weight_texel = 1.0f - normalized_texel;
|
||||
const float4 weight = bokeh_buffer->texture_bilinear_extend(weight_texel);
|
||||
const float4 color = input_buffer->get_elem_clamped(it.x + xi, it.y + yi);
|
||||
accumulated_color += color * weight;
|
||||
accumulated_weight += weight;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -354,7 +354,7 @@ static void dof_bokeh_pass_init(EEVEE_FramebufferList *fbl,
|
|||
}
|
||||
|
||||
void *owner = (void *)&EEVEE_depth_of_field_init;
|
||||
int res[2] = {DOF_BOKEH_LUT_SIZE, DOF_BOKEH_LUT_SIZE};
|
||||
const int res[2] = {DOF_BOKEH_LUT_SIZE, DOF_BOKEH_LUT_SIZE};
|
||||
|
||||
DRW_PASS_CREATE(psl->dof_bokeh, DRW_STATE_WRITE_COLOR);
|
||||
|
||||
|
@ -393,7 +393,7 @@ static void dof_setup_pass_init(EEVEE_FramebufferList *fbl,
|
|||
|
||||
void *owner = (void *)&EEVEE_depth_of_field_init;
|
||||
const float *fullres = DRW_viewport_size_get();
|
||||
int res[2] = {int(divide_ceil_u(fullres[0], 2)), int(divide_ceil_u(fullres[1], 2))};
|
||||
const int res[2] = {int(divide_ceil_u(fullres[0], 2)), int(divide_ceil_u(fullres[1], 2))};
|
||||
|
||||
DRW_PASS_CREATE(psl->dof_setup, DRW_STATE_WRITE_COLOR);
|
||||
|
||||
|
@ -428,8 +428,8 @@ static void dof_flatten_tiles_pass_init(EEVEE_FramebufferList *fbl,
|
|||
{
|
||||
void *owner = (void *)&EEVEE_depth_of_field_init;
|
||||
const float *fullres = DRW_viewport_size_get();
|
||||
int res[2] = {int(divide_ceil_u(fullres[0], DOF_TILE_DIVISOR)),
|
||||
int(divide_ceil_u(fullres[1], DOF_TILE_DIVISOR))};
|
||||
const int res[2] = {int(divide_ceil_u(fullres[0], DOF_TILE_DIVISOR)),
|
||||
int(divide_ceil_u(fullres[1], DOF_TILE_DIVISOR))};
|
||||
|
||||
DRW_PASS_CREATE(psl->dof_flatten_tiles, DRW_STATE_WRITE_COLOR);
|
||||
|
||||
|
@ -464,8 +464,8 @@ static void dof_dilate_tiles_pass_init(EEVEE_FramebufferList *fbl,
|
|||
{
|
||||
void *owner = (void *)&EEVEE_depth_of_field_init;
|
||||
const float *fullres = DRW_viewport_size_get();
|
||||
int res[2] = {int(divide_ceil_u(fullres[0], DOF_TILE_DIVISOR)),
|
||||
int(divide_ceil_u(fullres[1], DOF_TILE_DIVISOR))};
|
||||
const int res[2] = {int(divide_ceil_u(fullres[0], DOF_TILE_DIVISOR)),
|
||||
int(divide_ceil_u(fullres[1], DOF_TILE_DIVISOR))};
|
||||
|
||||
DRW_PASS_CREATE(psl->dof_dilate_tiles_minmax, DRW_STATE_WRITE_COLOR);
|
||||
DRW_PASS_CREATE(psl->dof_dilate_tiles_minabs, DRW_STATE_WRITE_COLOR);
|
||||
|
@ -558,10 +558,12 @@ static void dof_reduce_pass_init(EEVEE_FramebufferList *fbl,
|
|||
/* This ensure the mipmaps are aligned for the needed 4 mip levels.
|
||||
* Starts at 2 because already at half resolution. */
|
||||
int multiple = 2 << (mip_count - 1);
|
||||
int res[2] = {(multiple * int(divide_ceil_u(fullres[0], multiple))) / 2,
|
||||
(multiple * int(divide_ceil_u(fullres[1], multiple))) / 2};
|
||||
const int res[2] = {
|
||||
(multiple * int(divide_ceil_u(fullres[0], multiple))) / 2,
|
||||
(multiple * int(divide_ceil_u(fullres[1], multiple))) / 2,
|
||||
};
|
||||
|
||||
int quater_res[2] = {int(divide_ceil_u(fullres[0], 4)), int(divide_ceil_u(fullres[1], 4))};
|
||||
const int quater_res[2] = {int(divide_ceil_u(fullres[0], 4)), int(divide_ceil_u(fullres[1], 4))};
|
||||
|
||||
/* TODO(fclem): Make this dependent of the quality of the gather pass. */
|
||||
fx->dof_scatter_coc_threshold = 4.0f;
|
||||
|
@ -676,11 +678,12 @@ static void dof_gather_pass_init(EEVEE_FramebufferList *fbl,
|
|||
{
|
||||
void *owner = (void *)&EEVEE_depth_of_field_init;
|
||||
const float *fullres = DRW_viewport_size_get();
|
||||
int res[2] = {int(divide_ceil_u(fullres[0], 2)), int(divide_ceil_u(fullres[1], 2))};
|
||||
const int res[2] = {int(divide_ceil_u(fullres[0], 2)), int(divide_ceil_u(fullres[1], 2))};
|
||||
int input_size[2];
|
||||
GPU_texture_get_mipmap_size(txl->dof_reduced_color, 0, input_size);
|
||||
float uv_correction_fac[2] = {res[0] / float(input_size[0]), res[1] / float(input_size[1])};
|
||||
float output_texel_size[2] = {1.0f / res[0], 1.0f / res[1]};
|
||||
const float uv_correction_fac[2] = {res[0] / float(input_size[0]),
|
||||
res[1] / float(input_size[1])};
|
||||
const float output_texel_size[2] = {1.0f / res[0], 1.0f / res[1]};
|
||||
const bool use_bokeh_tx = (fx->dof_bokeh_gather_lut_tx != nullptr);
|
||||
|
||||
{
|
||||
|
@ -845,7 +848,7 @@ static void dof_scatter_pass_init(EEVEE_FramebufferList *fbl,
|
|||
GPU_texture_get_mipmap_size(fx->dof_bg_color_tx, 0, target_size);
|
||||
/* Draw a sprite for every four half-res pixels. */
|
||||
int sprite_count = (input_size[0] / 2) * (input_size[1] / 2);
|
||||
float target_texel_size[2] = {1.0f / target_size[0], 1.0f / target_size[1]};
|
||||
const float target_texel_size[2] = {1.0f / target_size[0], 1.0f / target_size[1]};
|
||||
const bool use_bokeh_tx = (fx->dof_bokeh_gather_lut_tx != nullptr);
|
||||
|
||||
{
|
||||
|
|
|
@ -123,7 +123,7 @@ void EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
|||
common_data->vol_history_alpha = (txl->volume_prop_scattering == nullptr) ? 0.0f : 0.95f;
|
||||
|
||||
/* Temporal Super sampling jitter */
|
||||
uint ht_primes[3] = {3, 7, 2};
|
||||
const uint ht_primes[3] = {3, 7, 2};
|
||||
uint current_sample = 0;
|
||||
|
||||
/* If TAA is in use do not use the history buffer. */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -202,6 +202,7 @@ class LightProbeModule {
|
|||
friend class VolumeProbeModule;
|
||||
friend class PlanarProbeModule;
|
||||
friend class SphereProbeModule;
|
||||
friend class BackgroundPipeline;
|
||||
|
||||
private:
|
||||
Instance &inst_;
|
||||
|
|
|
@ -72,6 +72,11 @@ class LookdevWorld {
|
|||
{
|
||||
return parameters_.background_opacity;
|
||||
}
|
||||
|
||||
float background_blur_get()
|
||||
{
|
||||
return parameters_.blur;
|
||||
}
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -118,12 +118,14 @@ void ShadowTileMap::sync_cubeface(const float4x4 &object_mat_,
|
|||
void ShadowTileMap::debug_draw() const
|
||||
{
|
||||
/** Used for debug drawing. */
|
||||
float4 debug_color[6] = {{1.0f, 0.1f, 0.1f, 1.0f},
|
||||
{0.1f, 1.0f, 0.1f, 1.0f},
|
||||
{0.0f, 0.2f, 1.0f, 1.0f},
|
||||
{1.0f, 1.0f, 0.3f, 1.0f},
|
||||
{0.1f, 0.1f, 0.1f, 1.0f},
|
||||
{1.0f, 1.0f, 1.0f, 1.0f}};
|
||||
const float4 debug_color[6] = {
|
||||
{1.0f, 0.1f, 0.1f, 1.0f},
|
||||
{0.1f, 1.0f, 0.1f, 1.0f},
|
||||
{0.0f, 0.2f, 1.0f, 1.0f},
|
||||
{1.0f, 1.0f, 0.3f, 1.0f},
|
||||
{0.1f, 0.1f, 0.1f, 1.0f},
|
||||
{1.0f, 1.0f, 1.0f, 1.0f},
|
||||
};
|
||||
float4 color =
|
||||
debug_color[((projection_type == SHADOW_PROJECTION_CUBEFACE ? cubeface : level) + 9999) % 6];
|
||||
|
||||
|
@ -490,12 +492,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 +507,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 +538,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 +589,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 +598,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;
|
||||
|
@ -1333,7 +1335,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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -26,11 +26,11 @@ void ShaderCache::release()
|
|||
|
||||
ShaderCache::ShaderCache()
|
||||
{
|
||||
std::string geometries[] = {"_mesh", "_curves", "_ptcloud"};
|
||||
std::string pipelines[] = {"_opaque", "_transparent"};
|
||||
std::string lightings[] = {"_flat", "_studio", "_matcap"};
|
||||
std::string shaders[] = {"_material", "_texture"};
|
||||
std::string clip[] = {"_no_clip", "_clip"};
|
||||
const std::string geometries[] = {"_mesh", "_curves", "_ptcloud"};
|
||||
const std::string pipelines[] = {"_opaque", "_transparent"};
|
||||
const std::string lightings[] = {"_flat", "_studio", "_matcap"};
|
||||
const std::string shaders[] = {"_material", "_texture"};
|
||||
const std::string clip[] = {"_no_clip", "_clip"};
|
||||
static_assert(std::size(geometries) == geometry_type_len);
|
||||
static_assert(std::size(pipelines) == pipeline_type_len);
|
||||
static_assert(std::size(lightings) == lighting_type_len);
|
||||
|
@ -49,9 +49,9 @@ ShaderCache::ShaderCache()
|
|||
}
|
||||
}
|
||||
|
||||
std::string cavity[] = {"_no_cavity", "_cavity"};
|
||||
std::string curvature[] = {"_no_curvature", "_curvature"};
|
||||
std::string shadow[] = {"_no_shadow", "_shadow"};
|
||||
const std::string cavity[] = {"_no_cavity", "_cavity"};
|
||||
const std::string curvature[] = {"_no_curvature", "_curvature"};
|
||||
const std::string shadow[] = {"_no_shadow", "_shadow"};
|
||||
|
||||
for (auto l : IndexRange(lighting_type_len)) {
|
||||
for (auto ca : IndexRange(2) /*cavity*/) {
|
||||
|
@ -64,9 +64,9 @@ ShaderCache::ShaderCache()
|
|||
}
|
||||
}
|
||||
|
||||
std::string pass[] = {"_fail", "_pass"};
|
||||
std::string manifold[] = {"_no_manifold", "_manifold"};
|
||||
std::string caps[] = {"_no_caps", "_caps"};
|
||||
const std::string pass[] = {"_fail", "_pass"};
|
||||
const std::string manifold[] = {"_no_manifold", "_manifold"};
|
||||
const std::string caps[] = {"_no_caps", "_caps"};
|
||||
|
||||
for (auto p : IndexRange(2) /*pass*/) {
|
||||
for (auto m : IndexRange(2) /*manifold*/) {
|
||||
|
@ -77,10 +77,10 @@ ShaderCache::ShaderCache()
|
|||
}
|
||||
}
|
||||
|
||||
std::string smoke[] = {"_object", "_smoke"};
|
||||
std::string interpolation[] = {"_linear", "_cubic", "_closest"};
|
||||
std::string coba[] = {"_no_coba", "_coba"};
|
||||
std::string slice[] = {"_no_slice", "_slice"};
|
||||
const std::string smoke[] = {"_object", "_smoke"};
|
||||
const std::string interpolation[] = {"_linear", "_cubic", "_closest"};
|
||||
const std::string coba[] = {"_no_coba", "_coba"};
|
||||
const std::string slice[] = {"_no_slice", "_slice"};
|
||||
|
||||
for (auto sm : IndexRange(2) /*smoke*/) {
|
||||
for (auto i : IndexRange(3) /*interpolation*/) {
|
||||
|
|
|
@ -56,40 +56,46 @@ void ShadowPass::ShadowView::setup(View &view, float3 light_direction, bool forc
|
|||
const int z_pos = 4; /* Near */
|
||||
const int z_neg = 2; /* Far */
|
||||
|
||||
int3 corner_faces[8] = {{x_neg, y_neg, z_pos},
|
||||
{x_neg, y_neg, z_neg},
|
||||
{x_neg, y_pos, z_neg},
|
||||
{x_neg, y_pos, z_pos},
|
||||
{x_pos, y_neg, z_pos},
|
||||
{x_pos, y_neg, z_neg},
|
||||
{x_pos, y_pos, z_neg},
|
||||
{x_pos, y_pos, z_pos}};
|
||||
const int3 corner_faces[8] = {
|
||||
{x_neg, y_neg, z_pos},
|
||||
{x_neg, y_neg, z_neg},
|
||||
{x_neg, y_pos, z_neg},
|
||||
{x_neg, y_pos, z_pos},
|
||||
{x_pos, y_neg, z_pos},
|
||||
{x_pos, y_neg, z_neg},
|
||||
{x_pos, y_pos, z_neg},
|
||||
{x_pos, y_pos, z_pos},
|
||||
};
|
||||
|
||||
int2 edge_faces[12] = {{x_neg, y_neg},
|
||||
{x_neg, z_neg},
|
||||
{x_neg, y_pos},
|
||||
{x_neg, z_pos},
|
||||
{y_neg, x_pos},
|
||||
{z_neg, x_pos},
|
||||
{y_pos, x_pos},
|
||||
{z_pos, x_pos},
|
||||
{y_neg, z_pos},
|
||||
{z_neg, y_neg},
|
||||
{y_pos, z_neg},
|
||||
{z_pos, y_pos}};
|
||||
const int2 edge_faces[12] = {
|
||||
{x_neg, y_neg},
|
||||
{x_neg, z_neg},
|
||||
{x_neg, y_pos},
|
||||
{x_neg, z_pos},
|
||||
{y_neg, x_pos},
|
||||
{z_neg, x_pos},
|
||||
{y_pos, x_pos},
|
||||
{z_pos, x_pos},
|
||||
{y_neg, z_pos},
|
||||
{z_neg, y_neg},
|
||||
{y_pos, z_neg},
|
||||
{z_pos, y_pos},
|
||||
};
|
||||
|
||||
int2 edge_corners[12] = {{0, 1},
|
||||
{1, 2},
|
||||
{2, 3},
|
||||
{3, 0},
|
||||
{4, 5},
|
||||
{5, 6},
|
||||
{6, 7},
|
||||
{7, 4},
|
||||
{0, 4},
|
||||
{1, 5},
|
||||
{2, 6},
|
||||
{3, 7}};
|
||||
const int2 edge_corners[12] = {
|
||||
{0, 1},
|
||||
{1, 2},
|
||||
{2, 3},
|
||||
{3, 0},
|
||||
{4, 5},
|
||||
{5, 6},
|
||||
{6, 7},
|
||||
{7, 4},
|
||||
{0, 4},
|
||||
{1, 5},
|
||||
{2, 6},
|
||||
{3, 7},
|
||||
};
|
||||
|
||||
BoundBox frustum_corners;
|
||||
DRW_culling_frustum_corners_get(nullptr, &frustum_corners);
|
||||
|
|
|
@ -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_;
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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? */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
struct AssetLibraryReference;
|
||||
struct bContext;
|
||||
|
||||
namespace blender::asset_system {
|
||||
class AssetLibrary;
|
||||
class AssetRepresentation;
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
struct ID;
|
||||
struct Main;
|
||||
|
||||
namespace blender::asset_system {
|
||||
class AssetRepresentation;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -9,9 +9,9 @@
|
|||
#pragma once
|
||||
|
||||
struct AssetMetaData;
|
||||
struct bContext;
|
||||
struct ID;
|
||||
struct Main;
|
||||
struct bContext;
|
||||
|
||||
namespace blender::ed::asset {
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@ struct bContextDataResult;
|
|||
struct BlendDataReader;
|
||||
struct BlendWriter;
|
||||
struct Main;
|
||||
struct wmWindowManager;
|
||||
struct RegionPollParams;
|
||||
struct wmWindowManager;
|
||||
|
||||
namespace blender::ed::asset::shelf {
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue