Refactor: EEVEE-Next: Light-probe management and structure #117941

Merged
Clément Foucault merged 7 commits from fclem/blender:cleanup-eevee-next-lightprobe-classes into main 2024-02-08 19:48:37 +01:00
85 changed files with 1854 additions and 459 deletions
Showing only changes of commit f89141596f - Show all commits

View File

@ -32,6 +32,9 @@ if(POLICY CMP0135)
cmake_policy(SET CMP0135 NEW) # CMake 3.24+ Set the date/time for extracted files to time of extraction
endif()
include(ExternalProject)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake/Modules")
include(cmake/check_software.cmake)
include(cmake/options.cmake)
# `versions.cmake` needs to be included after `options.cmake`
@ -40,6 +43,7 @@ include(cmake/versions.cmake)
include(cmake/boost_build_options.cmake)
include(cmake/download.cmake)
include(cmake/macros.cmake)
include(cmake/check_compilers.cmake)
if(ENABLE_MSYS2)
include(cmake/setup_msys2.cmake)

View File

@ -0,0 +1,45 @@
# SPDX-FileCopyrightText: 2019-2023 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later
# Check against installed versions.
message(STATUS "Found C Compiler: ${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION}")
if(UNIX AND NOT APPLE)
if(NOT CMAKE_COMPILER_IS_GNUCC OR NOT (CMAKE_C_COMPILER_VERSION MATCHES ${RELEASE_GCC_VERSION}))
message(STATUS " NOTE: Official releases uses GCC ${RELEASE_GCC_VERSION}")
endif()
endif()
message(STATUS "Found C++ Compiler: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
if(UNIX AND NOT APPLE)
if(NOT CMAKE_COMPILER_IS_GNUCC OR NOT (CMAKE_CXX_COMPILER_VERSION MATCHES ${RELEASE_GCC_VERSION}))
message(STATUS " NOTE: Official releases uses GCC ${RELEASE_GCC_VERSION}")
endif()
endif()
if(NOT APPLE)
include(CheckLanguage)
check_language(CUDA)
if (NOT CMAKE_CUDA_COMPILER)
message(STATUS "Missing CUDA compiler")
else()
enable_language(CUDA)
message(STATUS "Found CUDA Compiler: ${CMAKE_CUDA_COMPILER_ID} ${CMAKE_CUDA_COMPILER_VERSION}")
if(NOT CMAKE_CUDA_COMPILER_VERSION MATCHES ${RELEASE_CUDA_VERSION})
message(STATUS " NOTE: Official releases uses CUDA ${RELEASE_CUDA_VERSION}")
endif()
endif()
unset(HIP_VERSION)
find_package(HIP QUIET)
if (NOT HIP_FOUND)
message(STATUS "Missing HIP compiler")
else()
message(STATUS "Found HIP Compiler: ${HIP_HIPCC_EXECUTABLE} ${HIP_VERSION}")
if(NOT HIP_VERSION MATCHES ${RELEASE_HIP_VERSION})
message(STATUS " NOTE: Official releases uses HIP ${RELEASE_HIP_VERSION}")
endif()
endif()
endif()

View File

@ -2,6 +2,18 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
# Compilers
#
# Version used for precompiled library builds used for official releases.
# For anyone making their own library build, matching these exactly is not
# needed but it can be a useful reference.
set(RELEASE_GCC_VERSION 11.2.*)
set(RELEASE_CUDA_VERSION 12.3.*)
set(RELEASE_HIP_VERSION 5.7.*)
# Libraries
#
# CPE's are used to identify dependencies, for more information on what they
# are please see https://nvd.nist.gov/products/cpe
#

View File

@ -888,17 +888,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
unit='LENGTH'
)
motion_blur_position: EnumProperty(
name="Motion Blur Position",
default='CENTER',
description="Offset for the shutter's time interval, allows to change the motion blur trails",
items=(
('START', "Start on Frame", "The shutter opens at the current frame"),
('CENTER', "Center on Frame", "The shutter is open during the current frame"),
('END', "End on Frame", "The shutter closes at the current frame"),
),
)
rolling_shutter_type: EnumProperty(
name="Shutter Type",
default='NONE',

View File

@ -653,7 +653,7 @@ class CYCLES_RENDER_PT_motion_blur(CyclesButtonsPanel, Panel):
layout.active = rd.use_motion_blur
col = layout.column()
col.prop(cscene, "motion_blur_position", text="Position")
col.prop(rd, "motion_blur_position", text="Position")
col.prop(rd, "motion_blur_shutter")
col.separator()
col.prop(cscene, "rolling_shutter_type", text="Rolling Shutter")

View File

@ -577,6 +577,21 @@ static void blender_camera_sync(Camera *cam,
/* Sync Render Camera */
static MotionPosition blender_motion_blur_position_type_to_cycles(
const BL::RenderSettings::motion_blur_position_enum type)
{
switch (type) {
case BL::RenderSettings::motion_blur_position_START:
return MOTION_POSITION_START;
case BL::RenderSettings::motion_blur_position_CENTER:
return MOTION_POSITION_CENTER;
case BL::RenderSettings::motion_blur_position_END:
return MOTION_POSITION_END;
}
/* Could happen if loading a newer file that has an unsupported type. */
return MOTION_POSITION_CENTER;
}
void BlenderSync::sync_camera(BL::RenderSettings &b_render,
BL::Object &b_override,
int width,
@ -590,13 +605,13 @@ void BlenderSync::sync_camera(BL::RenderSettings &b_render,
bcam.pixelaspect.x = b_render.pixel_aspect_x();
bcam.pixelaspect.y = b_render.pixel_aspect_y();
bcam.shuttertime = b_render.motion_blur_shutter();
bcam.motion_position = blender_motion_blur_position_type_to_cycles(
b_render.motion_blur_position());
BL::CurveMapping b_shutter_curve(b_render.motion_blur_shutter_curve());
curvemapping_to_array(b_shutter_curve, bcam.shutter_curve, RAMP_TABLE_SIZE);
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
bcam.motion_position = (MotionPosition)get_enum(
cscene, "motion_blur_position", MOTION_NUM_POSITIONS, MOTION_POSITION_CENTER);
bcam.rolling_shutter_type = (Camera::RollingShutterType)get_enum(
cscene,
"rolling_shutter_type",

View File

@ -27,11 +27,13 @@ enum MetalGPUVendor {
};
enum AppleGPUArchitecture {
APPLE_UNKNOWN,
APPLE_M1,
APPLE_M2,
APPLE_M2_BIG,
APPLE_M3,
/* Keep APPLE_UNKNOWN at the end of this enum to ensure that unknown future architectures get
the most recent defaults when using comparison operators. */
APPLE_UNKNOWN,
};
/* Contains static Metal helper functions. */

View File

@ -492,7 +492,12 @@ void PathTrace::set_denoiser_params(const DenoiseParams &params)
if (denoiser_) {
const DenoiseParams old_denoiser_params = denoiser_->get_params();
if (old_denoiser_params.type == params.type) {
const bool is_same_denoising_device_type = old_denoiser_params.use_gpu == params.use_gpu;
/* Optix Denoiser is not supporting CPU devices, so use_gpu option is not
* shown in the UI and changes in the option value should not be checked. */
if (old_denoiser_params.type == params.type &&
(is_same_denoising_device_type || params.type == DENOISER_OPTIX))
{
denoiser_->set_params(params);
return;
}

View File

@ -119,6 +119,9 @@ def bake_action_objects(
:return: A sequence of Action or None types (aligned with `object_action_pairs`)
:rtype: sequence of :class:`bpy.types.Action`
"""
if not (bake_options.do_pose or bake_options.do_object):
return []
iter = bake_action_objects_iter(object_action_pairs, bake_options=bake_options)
iter.send(None)
for frame in frames:

View File

@ -1299,6 +1299,7 @@ def km_outliner(params):
("outliner.show_one_level", {"type": 'NUMPAD_MINUS', "value": 'PRESS'},
{"properties": [("open", False)]}),
*_template_items_select_actions(params, "outliner.select_all"),
("outliner.expanded_toggle", {"type": 'A', "value": 'PRESS', "shift": True}, None),
("outliner.keyingset_add_selected", {"type": 'K', "value": 'PRESS'}, None),
("outliner.keyingset_remove_selected", {"type": 'K', "value": 'PRESS', "alt": True}, None),
("anim.keyframe_insert", {"type": 'I', "value": 'PRESS'}, None),
@ -1317,11 +1318,6 @@ def km_outliner(params):
# Copy/paste.
("outliner.id_copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None),
("outliner.id_paste", {"type": 'V', "value": 'PRESS', "ctrl": True}, None),
op_menu("VIEW3D_MT_add", {"type": 'A', "value": 'PRESS', "shift": True}),
("object.duplicate", {"type": 'D', "value": 'PRESS', "shift": True}, None),
("object.duplicate", {"type": 'D', "value": 'PRESS', "alt": True},
{"properties": [("linked", True)]}),
])
return keymap

View File

@ -557,8 +557,6 @@ def km_outliner(params):
# Copy/paste.
("outliner.id_copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None),
("outliner.id_paste", {"type": 'V', "value": 'PRESS', "ctrl": True}, None),
("object.duplicate", {"type": 'D', "value": 'PRESS', "ctrl": True}, None),
])
return keymap

View File

@ -150,6 +150,7 @@ class OBJECT_MT_modifier_add_generate(ModifierAddMenu, Menu):
if ob_type == 'MESH':
self.operator_modifier_add(layout, 'WIREFRAME')
if ob_type == 'GREASEPENCIL':
self.operator_modifier_add(layout, 'GREASE_PENCIL_DASH')
self.operator_modifier_add(layout, 'GREASE_PENCIL_MIRROR')
self.operator_modifier_add(layout, 'GREASE_PENCIL_SUBDIV')
layout.template_modifier_asset_menu_items(catalog_path=self.bl_label)
@ -189,6 +190,7 @@ class OBJECT_MT_modifier_add_deform(ModifierAddMenu, Menu):
if ob_type == 'VOLUME':
self.operator_modifier_add(layout, 'VOLUME_DISPLACE')
if ob_type == 'GREASEPENCIL':
self.operator_modifier_add(layout, 'GREASE_PENCIL_LATTICE')
self.operator_modifier_add(layout, 'GREASE_PENCIL_NOISE')
self.operator_modifier_add(layout, 'GREASE_PENCIL_OFFSET')
self.operator_modifier_add(layout, 'GREASE_PENCIL_SMOOTH')

View File

@ -210,23 +210,24 @@ class RENDER_PT_eevee_motion_blur(RenderButtonsPanel, Panel):
def draw_header(self, context):
scene = context.scene
props = scene.eevee
props = scene.render
self.layout.prop(props, "use_motion_blur", text="")
def draw(self, context):
layout = self.layout
layout.use_property_split = True
scene = context.scene
props = scene.eevee
props = scene.render
eevee_props = scene.eevee
layout.active = props.use_motion_blur
col = layout.column()
col.prop(props, "motion_blur_position", text="Position")
col.prop(props, "motion_blur_shutter")
col.separator()
col.prop(props, "motion_blur_depth_scale")
col.prop(props, "motion_blur_max")
col.prop(props, "motion_blur_steps", text="Steps")
col.prop(eevee_props, "motion_blur_depth_scale")
col.prop(eevee_props, "motion_blur_max")
col.prop(eevee_props, "motion_blur_steps", text="Steps")
class RENDER_PT_eevee_next_motion_blur(RenderButtonsPanel, Panel):
@ -240,22 +241,24 @@ class RENDER_PT_eevee_next_motion_blur(RenderButtonsPanel, Panel):
def draw_header(self, context):
scene = context.scene
props = scene.eevee
props = scene.render
self.layout.prop(props, "use_motion_blur", text="")
def draw(self, context):
layout = self.layout
layout.use_property_split = True
scene = context.scene
props = scene.eevee
props = scene.render
eevee_props = scene.eevee
layout.active = props.use_motion_blur
col = layout.column()
col.prop(props, "motion_blur_position", text="Position")
col.prop(props, "motion_blur_shutter")
col.separator()
col.prop(props, "motion_blur_depth_scale")
col.prop(props, "motion_blur_steps", text="Steps")
col.prop(eevee_props, "motion_blur_depth_scale")
col.prop(eevee_props, "motion_blur_max")
col.prop(eevee_props, "motion_blur_steps", text="Steps")
class RENDER_PT_eevee_next_motion_blur_curve(RenderButtonsPanel, Panel):

View File

@ -155,7 +155,6 @@ class OUTLINER_MT_view_pie(Menu):
pie = layout.menu_pie()
pie.operator("outliner.show_hierarchy")
pie.operator("outliner.show_active", icon='ZOOM_SELECTED')
pie.operator("outliner.expanded_toggle")
class OUTLINER_MT_edit_datablocks(Menu):

View File

@ -5830,28 +5830,22 @@ class VIEW3D_MT_edit_greasepencil(Menu):
layout.separator()
layout.operator_menu_enum("grease_pencil.separate", "mode", text="Separate")
layout.separator()
layout.menu("GREASE_PENCIL_MT_layer_active", text="Active Layer")
layout.separator()
layout.operator("grease_pencil.duplicate_move")
layout.operator("grease_pencil.duplicate_move", text="Duplicate")
layout.separator()
layout.menu("VIEW3D_MT_edit_greasepencil_showhide")
layout.operator_menu_enum("grease_pencil.separate", "mode", text="Separate")
layout.operator("grease_pencil.clean_loose")
layout.separator()
layout.menu("VIEW3D_MT_edit_greasepencil_delete")
layout.separator()
layout.operator("grease_pencil.clean_loose")
class VIEW3D_MT_edit_greasepencil_stroke(Menu):
bl_label = "Stroke"
@ -5867,27 +5861,26 @@ class VIEW3D_MT_edit_greasepencil_stroke(Menu):
layout.menu("GREASE_PENCIL_MT_move_to_layer")
layout.menu("VIEW3D_MT_grease_pencil_assign_material")
layout.operator("grease_pencil.set_active_material")
layout.operator_menu_enum("grease_pencil.reorder", text="Arrange", property="direction")
layout.separator()
layout.operator("grease_pencil.cyclical_set", text="Toggle Cyclic").type = 'TOGGLE'
layout.operator("grease_pencil.stroke_switch_direction")
layout.operator_menu_enum("grease_pencil.caps_set", text="Set Caps", property="type")
layout.operator("grease_pencil.stroke_switch_direction")
layout.separator()
layout.operator("grease_pencil.set_uniform_thickness")
layout.operator("grease_pencil.set_uniform_opacity")
layout.operator_menu_enum("grease_pencil.reorder", text="Reorder", property="direction")
class VIEW3D_MT_edit_greasepencil_point(Menu):
bl_label = "Point"
def draw(self, _context):
layout = self.layout
layout.operator("grease_pencil.stroke_smooth", text="Smooth Points")
layout.operator("grease_pencil.stroke_smooth", text="Smooth")
class VIEW3D_MT_edit_curves(Menu):
@ -8232,7 +8225,11 @@ class VIEW3D_MT_greasepencil_edit_context_menu(Menu):
col.separator()
col.menu("VIEW3D_MT_mirror", text="Mirror Points")
col.menu("VIEW3D_MT_mirror", text="Mirror")
col.separator()
col.operator("grease_pencil.duplicate_move", text="Duplicate")
col.separator()
@ -8255,13 +8252,15 @@ class VIEW3D_MT_greasepencil_edit_context_menu(Menu):
col.separator()
# Deform Operators
col.operator("grease_pencil.stroke_smooth", text="Smooth Points")
col.operator("grease_pencil.stroke_smooth", text="Smooth")
col.operator("transform.transform", text="Radius").mode = 'CURVE_SHRINKFATTEN'
col.separator()
col.menu("GREASE_PENCIL_MT_move_to_layer")
col.menu("VIEW3D_MT_grease_pencil_assign_material")
col.operator("grease_pencil.set_active_material", text="Set as Active Material")
col.operator_menu_enum("grease_pencil.reorder", text="Arrange", property="direction")
col.separator()
@ -8269,6 +8268,10 @@ class VIEW3D_MT_greasepencil_edit_context_menu(Menu):
col.separator()
col.operator("grease_pencil.duplicate_move", text="Duplicate")
col.separator()
col.operator("grease_pencil.separate", text="Separate").mode = 'SELECTED'

View File

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

View File

@ -261,14 +261,17 @@ const void *CustomData_add_layer_with_data(CustomData *data,
/**
* Same as above but accepts a name.
*/
void *CustomData_add_layer_named(
CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem, const char *name);
void *CustomData_add_layer_named(CustomData *data,
eCustomDataType type,
eCDAllocType alloctype,
int totelem,
blender::StringRef name);
const void *CustomData_add_layer_named_with_data(CustomData *data,
eCustomDataType type,
void *layer_data,
int totelem,
const char *name,
blender::StringRef name,
const ImplicitSharingInfoHandle *sharing_info);
void *CustomData_add_layer_anonymous(CustomData *data,
@ -291,7 +294,7 @@ const void *CustomData_add_layer_anonymous_with_data(
* In edit-mode, use #EDBM_data_layer_free instead of this function.
*/
bool CustomData_free_layer(CustomData *data, eCustomDataType type, int totelem, int index);
bool CustomData_free_layer_named(CustomData *data, const char *name, const int totelem);
bool CustomData_free_layer_named(CustomData *data, blender::StringRef name, const int totelem);
/**
* Frees the layer index with the give type.
@ -310,7 +313,9 @@ void CustomData_free_layers(CustomData *data, eCustomDataType type, int totelem)
* Returns true if a layer with the specified type exists.
*/
bool CustomData_has_layer(const CustomData *data, eCustomDataType type);
bool CustomData_has_layer_named(const CustomData *data, eCustomDataType type, const char *name);
bool CustomData_has_layer_named(const CustomData *data,
eCustomDataType type,
blender::StringRef name);
/**
* Returns the number of layers with this type.
@ -490,7 +495,10 @@ void *CustomData_bmesh_get_n(const CustomData *data, void *block, eCustomDataTyp
*/
void *CustomData_bmesh_get_layer_n(const CustomData *data, void *block, int n);
bool CustomData_set_layer_name(CustomData *data, eCustomDataType type, int n, const char *name);
bool CustomData_set_layer_name(CustomData *data,
eCustomDataType type,
int n,
blender::StringRef name);
const char *CustomData_get_layer_name(const CustomData *data, eCustomDataType type, int n);
/**
@ -513,27 +521,31 @@ void *CustomData_get_layer_n_for_write(CustomData *data, eCustomDataType type, i
*/
const void *CustomData_get_layer_named(const CustomData *data,
eCustomDataType type,
const char *name);
blender::StringRef name);
void *CustomData_get_layer_named_for_write(CustomData *data,
eCustomDataType type,
const char *name,
blender::StringRef name,
int totelem);
int CustomData_get_offset(const CustomData *data, eCustomDataType type);
int CustomData_get_offset_named(const CustomData *data, eCustomDataType type, const char *name);
int CustomData_get_offset_named(const CustomData *data,
eCustomDataType type,
blender::StringRef name);
int CustomData_get_n_offset(const CustomData *data, eCustomDataType type, int n);
int CustomData_get_layer_index(const CustomData *data, eCustomDataType type);
int CustomData_get_layer_index_n(const CustomData *data, eCustomDataType type, int n);
int CustomData_get_named_layer_index(const CustomData *data,
eCustomDataType type,
const char *name);
int CustomData_get_named_layer_index_notype(const CustomData *data, const char *name);
blender::StringRef name);
int CustomData_get_named_layer_index_notype(const CustomData *data, blender::StringRef name);
int CustomData_get_active_layer_index(const CustomData *data, eCustomDataType type);
int CustomData_get_render_layer_index(const CustomData *data, eCustomDataType type);
int CustomData_get_clone_layer_index(const CustomData *data, eCustomDataType type);
int CustomData_get_stencil_layer_index(const CustomData *data, eCustomDataType type);
int CustomData_get_named_layer(const CustomData *data, eCustomDataType type, const char *name);
int CustomData_get_named_layer(const CustomData *data,
eCustomDataType type,
blender::StringRef name);
int CustomData_get_active_layer(const CustomData *data, eCustomDataType type);
int CustomData_get_render_layer(const CustomData *data, eCustomDataType type);
int CustomData_get_clone_layer(const CustomData *data, eCustomDataType type);
@ -631,7 +643,7 @@ void CustomData_set_layer_unique_name(CustomData *data, int index);
void CustomData_validate_layer_name(const CustomData *data,
eCustomDataType type,
const char *name,
blender::StringRef name,
char *outname);
/**

View File

@ -165,15 +165,15 @@ struct ModifierEvalContext {
struct ModifierTypeInfo {
/* A unique identifier for this modifier. Used to generate the panel id type name.
* See #BKE_modifier_type_panel_id. */
char idname[32];
char idname[64];
/* The user visible name for this modifier */
char name[32];
char name[64];
/* The DNA struct name for the modifier data type, used to
* write the DNA data out.
*/
char struct_name[32];
char struct_name[64];
/* The size of the modifier data type, used by allocation. */
int struct_size;

View File

@ -0,0 +1,15 @@
/* SPDX-FileCopyrightText: 2024 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "BLI_utility_mixins.hh"
namespace blender::bke {
class SceneRuntime : NonCopyable, NonMovable {
public:
};
} // namespace blender::bke

View File

@ -487,6 +487,7 @@ set(SRC
BKE_report.h
BKE_rigidbody.h
BKE_scene.h
BKE_scene_runtime.hh
BKE_screen.hh
BKE_sequencer_offscreen.h
BKE_shader_fx.h

View File

@ -287,7 +287,7 @@ CustomDataLayer *BKE_id_attribute_new(ID *id,
Mesh *mesh = reinterpret_cast<Mesh *>(id);
if (BMEditMesh *em = mesh->edit_mesh) {
BM_data_layer_add_named(em->bm, customdata, type, uniquename.c_str());
const int index = CustomData_get_named_layer_index(customdata, type, uniquename.c_str());
const int index = CustomData_get_named_layer_index(customdata, type, uniquename);
return (index == -1) ? nullptr : &(customdata->layers[index]);
}
}
@ -299,7 +299,7 @@ CustomDataLayer *BKE_id_attribute_new(ID *id,
attributes->add(uniquename, domain, eCustomDataType(type), AttributeInitDefaultValue());
const int index = CustomData_get_named_layer_index(customdata, type, uniquename.c_str());
const int index = CustomData_get_named_layer_index(customdata, type, uniquename);
if (index == -1) {
BKE_reportf(reports, RPT_WARNING, "Layer '%s' could not be created", uniquename.c_str());
}
@ -417,7 +417,7 @@ bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports)
for (const int domain : IndexRange(ATTR_DOMAIN_NUM)) {
if (CustomData *data = info[domain].customdata) {
const std::string name_copy = name;
const int layer_index = CustomData_get_named_layer_index_notype(data, name_copy.c_str());
const int layer_index = CustomData_get_named_layer_index_notype(data, name_copy);
if (layer_index == -1) {
continue;
}

View File

@ -321,10 +321,8 @@ static const void *add_generic_custom_data_layer_with_existing_data(
return CustomData_add_layer_anonymous_with_data(
&custom_data, data_type, &anonymous_id, domain_size, layer_data, sharing_info);
}
char attribute_name_c[MAX_CUSTOMDATA_LAYER_NAME];
attribute_id.name().copy(attribute_name_c);
return CustomData_add_layer_named_with_data(
&custom_data, data_type, layer_data, domain_size, attribute_name_c, sharing_info);
&custom_data, data_type, layer_data, domain_size, attribute_id.name(), sharing_info);
}
static bool add_custom_data_layer_from_attribute_init(const AttributeIDRef &attribute_id,
@ -386,7 +384,7 @@ static bool custom_data_layer_matches_attribute_id(const CustomDataLayer &layer,
bool BuiltinCustomDataLayerProvider::layer_exists(const CustomData &custom_data) const
{
if (stored_as_named_attribute_) {
return CustomData_get_named_layer_index(&custom_data, stored_type_, name_.c_str()) != -1;
return CustomData_get_named_layer_index(&custom_data, stored_type_, name_) != -1;
}
return CustomData_has_layer(&custom_data, stored_type_);
}
@ -410,7 +408,7 @@ GAttributeReader BuiltinCustomDataLayerProvider::try_get_for_read(const void *ow
int index;
if (stored_as_named_attribute_) {
index = CustomData_get_named_layer_index(custom_data, stored_type_, name_.c_str());
index = CustomData_get_named_layer_index(custom_data, stored_type_, name_);
}
else {
index = CustomData_get_layer_index(custom_data, stored_type_);
@ -446,8 +444,7 @@ GAttributeWriter BuiltinCustomDataLayerProvider::try_get_for_write(void *owner)
void *data = nullptr;
if (stored_as_named_attribute_) {
data = CustomData_get_layer_named_for_write(
custom_data, stored_type_, name_.c_str(), element_num);
data = CustomData_get_layer_named_for_write(custom_data, stored_type_, name_, element_num);
}
else {
data = CustomData_get_layer_for_write(custom_data, stored_type_, element_num);
@ -476,7 +473,7 @@ bool BuiltinCustomDataLayerProvider::try_delete(void *owner) const
const int element_num = custom_data_access_.get_element_num(owner);
if (stored_as_named_attribute_) {
if (CustomData_free_layer_named(custom_data, name_.c_str(), element_num)) {
if (CustomData_free_layer_named(custom_data, name_, element_num)) {
update();
return true;
}
@ -505,7 +502,7 @@ bool BuiltinCustomDataLayerProvider::try_create(void *owner,
const int element_num = custom_data_access_.get_element_num(owner);
if (stored_as_named_attribute_) {
if (CustomData_has_layer_named(custom_data, data_type_, name_.c_str())) {
if (CustomData_has_layer_named(custom_data, data_type_, name_)) {
/* Exists already. */
return false;
}
@ -528,7 +525,7 @@ bool BuiltinCustomDataLayerProvider::exists(const void *owner) const
return false;
}
if (stored_as_named_attribute_) {
return CustomData_has_layer_named(custom_data, stored_type_, name_.c_str());
return CustomData_has_layer_named(custom_data, stored_type_, name_);
}
return CustomData_get_layer(custom_data, stored_type_) != nullptr;
}

View File

@ -207,14 +207,14 @@ static const CustomData &domain_custom_data(const CurvesGeometry &curves, const
template<typename T>
static VArray<T> get_varray_attribute(const CurvesGeometry &curves,
const AttrDomain domain,
const StringRefNull name,
const StringRef name,
const T default_value)
{
const int num = domain_num(curves, domain);
const eCustomDataType type = cpp_type_to_custom_data_type(CPPType::get<T>());
const CustomData &custom_data = domain_custom_data(curves, domain);
const T *data = (const T *)CustomData_get_layer_named(&custom_data, type, name.c_str());
const T *data = (const T *)CustomData_get_layer_named(&custom_data, type, name);
if (data != nullptr) {
return VArray<T>::ForSpan(Span<T>(data, num));
}
@ -224,13 +224,13 @@ static VArray<T> get_varray_attribute(const CurvesGeometry &curves,
template<typename T>
static Span<T> get_span_attribute(const CurvesGeometry &curves,
const AttrDomain domain,
const StringRefNull name)
const StringRef name)
{
const int num = domain_num(curves, domain);
const CustomData &custom_data = domain_custom_data(curves, domain);
const eCustomDataType type = cpp_type_to_custom_data_type(CPPType::get<T>());
T *data = (T *)CustomData_get_layer_named(&custom_data, type, name.c_str());
T *data = (T *)CustomData_get_layer_named(&custom_data, type, name);
if (data == nullptr) {
return {};
}
@ -240,18 +240,18 @@ static Span<T> get_span_attribute(const CurvesGeometry &curves,
template<typename T>
static MutableSpan<T> get_mutable_attribute(CurvesGeometry &curves,
const AttrDomain domain,
const StringRefNull name,
const StringRef name,
const T default_value = T())
{
const int num = domain_num(curves, domain);
const eCustomDataType type = cpp_type_to_custom_data_type(CPPType::get<T>());
CustomData &custom_data = domain_custom_data(curves, domain);
T *data = (T *)CustomData_get_layer_named_for_write(&custom_data, type, name.c_str(), num);
T *data = (T *)CustomData_get_layer_named_for_write(&custom_data, type, name, num);
if (data != nullptr) {
return {data, num};
}
data = (T *)CustomData_add_layer_named(&custom_data, type, CD_SET_DEFAULT, num, name.c_str());
data = (T *)CustomData_add_layer_named(&custom_data, type, CD_SET_DEFAULT, num, name);
MutableSpan<T> span = {data, num};
if (num > 0 && span.first() != default_value) {
span.fill(default_value);

View File

@ -2102,7 +2102,7 @@ static CustomDataLayer *customData_add_layer__internal(
void *layer_data_to_assign,
const ImplicitSharingInfo *sharing_info_to_assign,
int totelem,
const char *name);
const StringRef name);
void CustomData_update_typemap(CustomData *data)
{
@ -2580,11 +2580,11 @@ int CustomData_get_layer_index_n(const CustomData *data, const eCustomDataType t
int CustomData_get_named_layer_index(const CustomData *data,
const eCustomDataType type,
const char *name)
const StringRef name)
{
for (int i = 0; i < data->totlayer; i++) {
if (data->layers[i].type == type) {
if (STREQ(data->layers[i].name, name)) {
if (data->layers[i].name == name) {
return i;
}
}
@ -2593,10 +2593,10 @@ int CustomData_get_named_layer_index(const CustomData *data,
return -1;
}
int CustomData_get_named_layer_index_notype(const CustomData *data, const char *name)
int CustomData_get_named_layer_index_notype(const CustomData *data, const StringRef name)
{
for (int i = 0; i < data->totlayer; i++) {
if (STREQ(data->layers[i].name, name)) {
if (data->layers[i].name == name) {
return i;
}
}
@ -2637,7 +2637,7 @@ int CustomData_get_stencil_layer_index(const CustomData *data, const eCustomData
int CustomData_get_named_layer(const CustomData *data,
const eCustomDataType type,
const char *name)
const StringRef name)
{
const int named_index = CustomData_get_named_layer_index(data, type, name);
const int layer_index = data->typemap[type];
@ -2845,7 +2845,7 @@ static CustomDataLayer *customData_add_layer__internal(
void *layer_data_to_assign,
const ImplicitSharingInfo *sharing_info_to_assign,
const int totelem,
const char *name)
StringRef name)
{
const LayerTypeInfo &type_info = *layerType_getInfo(type);
int flag = 0;
@ -2926,12 +2926,12 @@ static CustomDataLayer *customData_add_layer__internal(
/* Set default name if none exists. Note we only call DATA_() once
* we know there is a default name, to avoid overhead of locale lookups
* in the depsgraph. */
if (!name && type_info.defaultname) {
if (name.is_empty() && type_info.defaultname) {
name = DATA_(type_info.defaultname);
}
if (name) {
STRNCPY(new_layer.name, name);
if (!name.is_empty()) {
name.copy(new_layer.name);
CustomData_set_layer_unique_name(data, index);
}
else {
@ -2997,7 +2997,7 @@ void *CustomData_add_layer_named(CustomData *data,
const eCustomDataType type,
const eCDAllocType alloctype,
const int totelem,
const char *name)
const StringRef name)
{
CustomDataLayer *layer = customData_add_layer__internal(
data, type, alloctype, nullptr, nullptr, totelem, name);
@ -3013,7 +3013,7 @@ const void *CustomData_add_layer_named_with_data(CustomData *data,
eCustomDataType type,
void *layer_data,
int totelem,
const char *name,
const StringRef name,
const ImplicitSharingInfo *sharing_info)
{
CustomDataLayer *layer = customData_add_layer__internal(
@ -3032,7 +3032,7 @@ void *CustomData_add_layer_anonymous(CustomData *data,
const int totelem,
const AnonymousAttributeIDHandle *anonymous_id)
{
const char *name = anonymous_id->name().c_str();
const StringRef name = anonymous_id->name().c_str();
CustomDataLayer *layer = customData_add_layer__internal(
data, type, alloctype, nullptr, nullptr, totelem, name);
CustomData_update_typemap(data);
@ -3054,7 +3054,7 @@ const void *CustomData_add_layer_anonymous_with_data(
void *layer_data,
const ImplicitSharingInfo *sharing_info)
{
const char *name = anonymous_id->name().c_str();
const StringRef name = anonymous_id->name().c_str();
CustomDataLayer *layer = customData_add_layer__internal(
data, type, std::nullopt, layer_data, sharing_info, totelem, name);
CustomData_update_typemap(data);
@ -3122,7 +3122,7 @@ bool CustomData_free_layer(CustomData *data,
return true;
}
bool CustomData_free_layer_named(CustomData *data, const char *name, const int totelem)
bool CustomData_free_layer_named(CustomData *data, const StringRef name, const int totelem)
{
for (const int i : IndexRange(data->totlayer)) {
const CustomDataLayer &layer = data->layers[i];
@ -3153,7 +3153,7 @@ void CustomData_free_layers(CustomData *data, const eCustomDataType type, const
bool CustomData_has_layer_named(const CustomData *data,
const eCustomDataType type,
const char *name)
const StringRef name)
{
return CustomData_get_named_layer_index(data, type, name) != -1;
}
@ -3531,7 +3531,7 @@ void *CustomData_get_layer_n_for_write(CustomData *data,
const void *CustomData_get_layer_named(const CustomData *data,
const eCustomDataType type,
const char *name)
const StringRef name)
{
int layer_index = CustomData_get_named_layer_index(data, type, name);
if (layer_index == -1) {
@ -3542,7 +3542,7 @@ const void *CustomData_get_layer_named(const CustomData *data,
void *CustomData_get_layer_named_for_write(CustomData *data,
const eCustomDataType type,
const char *name,
const StringRef name,
const int totelem)
{
const int layer_index = CustomData_get_named_layer_index(data, type, name);
@ -3575,7 +3575,7 @@ int CustomData_get_n_offset(const CustomData *data, const eCustomDataType type,
int CustomData_get_offset_named(const CustomData *data,
const eCustomDataType type,
const char *name)
const StringRef name)
{
int layer_index = CustomData_get_named_layer_index(data, type, name);
if (layer_index == -1) {
@ -3588,15 +3588,14 @@ int CustomData_get_offset_named(const CustomData *data,
bool CustomData_set_layer_name(CustomData *data,
const eCustomDataType type,
const int n,
const char *name)
const StringRef name)
{
const int layer_index = CustomData_get_layer_index_n(data, type, n);
if ((layer_index == -1) || !name) {
if (layer_index == -1) {
return false;
}
STRNCPY(data->layers[layer_index].name, name);
name.copy(data->layers[layer_index].name);
return true;
}
@ -4281,7 +4280,7 @@ int CustomData_layertype_layers_max(const eCustomDataType type)
}
static bool cd_layer_find_dupe(CustomData *data,
const char *name,
const StringRef name,
const eCustomDataType type,
const int index)
{
@ -4291,12 +4290,12 @@ static bool cd_layer_find_dupe(CustomData *data,
CustomDataLayer *layer = &data->layers[i];
if (CD_TYPE_AS_MASK(type) & CD_MASK_PROP_ALL) {
if ((CD_TYPE_AS_MASK(layer->type) & CD_MASK_PROP_ALL) && STREQ(layer->name, name)) {
if ((CD_TYPE_AS_MASK(layer->type) & CD_MASK_PROP_ALL) && layer->name == name) {
return true;
}
}
else {
if (i != index && layer->type == type && STREQ(layer->name, name)) {
if (i != index && layer->type == type && layer->name == name) {
return true;
}
}
@ -4358,7 +4357,7 @@ void CustomData_set_layer_unique_name(CustomData *data, const int index)
void CustomData_validate_layer_name(const CustomData *data,
const eCustomDataType type,
const char *name,
const StringRef name,
char *outname)
{
int index = -1;
@ -4376,7 +4375,9 @@ void CustomData_validate_layer_name(const CustomData *data,
BLI_strncpy_utf8(outname, data->layers[index].name, MAX_CUSTOMDATA_LAYER_NAME);
}
else {
BLI_strncpy_utf8(outname, name, MAX_CUSTOMDATA_LAYER_NAME);
char name_c_str[MAX_CUSTOMDATA_LAYER_NAME];
name.copy(name_c_str);
BLI_strncpy_utf8(outname, name_c_str, MAX_CUSTOMDATA_LAYER_NAME);
}
}

View File

@ -259,18 +259,18 @@ static CustomData &domain_custom_data(CurvesGeometry &curves, const AttrDomain d
template<typename T>
static MutableSpan<T> get_mutable_attribute(CurvesGeometry &curves,
const AttrDomain domain,
const StringRefNull name,
const StringRef name,
const T default_value = T())
{
const int num = domain_num(curves, domain);
const eCustomDataType type = cpp_type_to_custom_data_type(CPPType::get<T>());
CustomData &custom_data = domain_custom_data(curves, domain);
T *data = (T *)CustomData_get_layer_named_for_write(&custom_data, type, name.c_str(), num);
T *data = (T *)CustomData_get_layer_named_for_write(&custom_data, type, name, num);
if (data != nullptr) {
return {data, num};
}
data = (T *)CustomData_add_layer_named(&custom_data, type, CD_SET_DEFAULT, num, name.c_str());
data = (T *)CustomData_add_layer_named(&custom_data, type, CD_SET_DEFAULT, num, name);
MutableSpan<T> span = {data, num};
if (num > 0 && span.first() != default_value) {
span.fill(default_value);

View File

@ -1712,7 +1712,7 @@ void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh)
for (const int i : uv_names.index_range()) {
const MLoopUV *mloopuv = static_cast<const MLoopUV *>(
CustomData_get_layer_named(&mesh->corner_data, CD_MLOOPUV, uv_names[i].c_str()));
CustomData_get_layer_named(&mesh->corner_data, CD_MLOOPUV, uv_names[i]));
const uint32_t needed_boolean_attributes = threading::parallel_reduce(
IndexRange(mesh->corners_num),
4096,
@ -1763,13 +1763,13 @@ void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh)
}
});
CustomData_free_layer_named(&mesh->corner_data, uv_names[i].c_str(), mesh->corners_num);
CustomData_free_layer_named(&mesh->corner_data, uv_names[i], mesh->corners_num);
const std::string new_name = BKE_id_attribute_calc_unique_name(mesh->id, uv_names[i].c_str());
uv_names[i] = new_name;
CustomData_add_layer_named_with_data(
&mesh->corner_data, CD_PROP_FLOAT2, coords, mesh->corners_num, new_name.c_str(), nullptr);
&mesh->corner_data, CD_PROP_FLOAT2, coords, mesh->corners_num, new_name, nullptr);
char buffer[MAX_CUSTOMDATA_LAYER_NAME];
if (vert_selection) {
CustomData_add_layer_named_with_data(
@ -1800,18 +1800,18 @@ void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh)
}
if (active_name_i != -1) {
CustomData_set_layer_active_index(
&mesh->corner_data,
CD_PROP_FLOAT2,
CustomData_get_named_layer_index(
&mesh->corner_data, CD_PROP_FLOAT2, uv_names[active_name_i].c_str()));
CustomData_set_layer_active_index(&mesh->corner_data,
CD_PROP_FLOAT2,
CustomData_get_named_layer_index(&mesh->corner_data,
CD_PROP_FLOAT2,
uv_names[active_name_i]));
}
if (default_name_i != -1) {
CustomData_set_layer_render_index(
&mesh->corner_data,
CD_PROP_FLOAT2,
CustomData_get_named_layer_index(
&mesh->corner_data, CD_PROP_FLOAT2, uv_names[default_name_i].c_str()));
CustomData_set_layer_render_index(&mesh->corner_data,
CD_PROP_FLOAT2,
CustomData_get_named_layer_index(&mesh->corner_data,
CD_PROP_FLOAT2,
uv_names[default_name_i]));
}
}

View File

@ -89,6 +89,7 @@
#include "BKE_preview_image.hh"
#include "BKE_rigidbody.h"
#include "BKE_scene.h"
#include "BKE_scene_runtime.hh"
#include "BKE_screen.hh"
#include "BKE_sound.h"
#include "BKE_unit.hh"
@ -120,6 +121,8 @@
#include "bmesh.hh"
using blender::bke::SceneRuntime;
CurveMapping *BKE_sculpt_default_cavity_curve()
{
@ -249,6 +252,8 @@ static void scene_init_data(ID *id)
scene->master_collection = BKE_collection_master_add(scene);
BKE_view_layer_add(scene, DATA_("ViewLayer"), nullptr, VIEWLAYER_ADD_NEW);
scene->runtime = MEM_new<SceneRuntime>(__func__);
}
static void scene_copy_markers(Scene *scene_dst, const Scene *scene_src, const int flag)
@ -369,6 +374,8 @@ static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
}
BKE_scene_copy_data_eevee(scene_dst, scene_src);
scene_dst->runtime = MEM_new<SceneRuntime>(__func__);
}
static void scene_free_markers(Scene *scene, bool do_id_user)
@ -464,6 +471,8 @@ static void scene_free_data(ID *id)
/* These are freed on `do_versions`. */
BLI_assert(scene->layer_properties == nullptr);
MEM_delete(scene->runtime);
}
static void scene_foreach_rigidbodyworldSceneLooper(RigidBodyWorld * /*rbw*/,
@ -1259,6 +1268,8 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
/* set users to one by default, not in lib-link, this will increase it for compo nodes */
id_us_ensure_real(&sce->id);
sce->runtime = MEM_new<SceneRuntime>(__func__);
BLO_read_list(reader, &(sce->base));
BLO_read_list(reader, &sce->keyingsets);

View File

@ -3467,7 +3467,7 @@ void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain)
scene->eevee.bloom_clamp = 0.0f;
scene->eevee.motion_blur_samples = 8;
scene->eevee.motion_blur_shutter = 0.5f;
scene->eevee.motion_blur_shutter_deprecated = 0.5f;
scene->eevee.shadow_method = SHADOW_ESM;
scene->eevee.shadow_cube_size = 512;
@ -3538,7 +3538,7 @@ void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain)
EEVEE_GET_BOOL(props, gtao_bounce, SCE_EEVEE_GTAO_BOUNCE);
EEVEE_GET_BOOL(props, dof_enable, SCE_EEVEE_DOF_ENABLED);
EEVEE_GET_BOOL(props, bloom_enable, SCE_EEVEE_BLOOM_ENABLED);
EEVEE_GET_BOOL(props, motion_blur_enable, SCE_EEVEE_MOTION_BLUR_ENABLED);
EEVEE_GET_BOOL(props, motion_blur_enable, SCE_EEVEE_MOTION_BLUR_ENABLED_DEPRECATED);
EEVEE_GET_BOOL(props, shadow_high_bitdepth, SCE_EEVEE_SHADOW_HIGH_BITDEPTH);
EEVEE_GET_BOOL(props, taa_reprojection, SCE_EEVEE_TAA_REPROJECTION);
// EEVEE_GET_BOOL(props, sss_enable, SCE_EEVEE_SSS_ENABLED);
@ -3587,7 +3587,7 @@ void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain)
EEVEE_GET_FLOAT(props, bloom_clamp);
EEVEE_GET_INT(props, motion_blur_samples);
EEVEE_GET_FLOAT(props, motion_blur_shutter);
EEVEE_GET_FLOAT(props, motion_blur_shutter_deprecated);
EEVEE_GET_INT(props, shadow_method);
EEVEE_GET_INT(props, shadow_cube_size);

View File

@ -2906,6 +2906,26 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
}
}
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 2)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
bool is_cycles = scene && STREQ(scene->r.engine, RE_engine_id_CYCLES);
if (is_cycles) {
if (IDProperty *cscene = version_cycles_properties_from_ID(&scene->id)) {
int cposition = version_cycles_property_int(cscene, "motion_blur_position", 1);
BLI_assert(cposition >= 0 && cposition < 3);
int order_conversion[3] = {SCE_MB_START, SCE_MB_CENTER, SCE_MB_END};
scene->r.motion_blur_position = order_conversion[std::clamp(cposition, 0, 2)];
}
}
else {
SET_FLAG_FROM_TEST(
scene->r.mode, scene->eevee.flag & SCE_EEVEE_MOTION_BLUR_ENABLED_DEPRECATED, R_MBLUR);
scene->r.motion_blur_position = scene->eevee.motion_blur_position_deprecated;
scene->r.motion_blur_shutter = scene->eevee.motion_blur_shutter_deprecated;
}
}
}
/**
* Always bump subversion in BKE_blender_version.h when adding versioning
* code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check.

View File

@ -320,7 +320,7 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
/* New EEVEE defaults. */
scene->eevee.bloom_intensity = 0.05f;
scene->eevee.bloom_clamp = 0.0f;
scene->eevee.motion_blur_shutter = 0.5f;
scene->eevee.motion_blur_shutter_deprecated = 0.5f;
copy_v3_v3(scene->display.light_direction, blender::float3(M_SQRT1_3));
copy_v2_fl2(scene->safe_areas.title, 0.1f, 0.05f);

View File

@ -618,8 +618,8 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain)
if (bmain->versionfile <= 153) {
Scene *sce = static_cast<Scene *>(bmain->scenes.first);
while (sce) {
if (sce->r.blurfac == 0.0f) {
sce->r.blurfac = 1.0f;
if (sce->r.motion_blur_shutter == 0.0f) {
sce->r.motion_blur_shutter = 1.0f;
}
sce = static_cast<Scene *>(sce->id.next);
}

View File

@ -265,7 +265,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *mesh, const BMeshFromMeshParams *
BLI_SCOPED_DEFER([&]() {
for (const std::string &name : temporary_layers_to_delete) {
CustomData_free_layer_named(&mesh_ldata, name.c_str(), mesh->corners_num);
CustomData_free_layer_named(&mesh_ldata, name, mesh->corners_num);
}
MEM_SAFE_FREE(mesh_vdata.layers);

View File

@ -472,7 +472,7 @@ static void eevee_render_to_image(void *vedata,
Depsgraph *depsgraph = draw_ctx->depsgraph;
Scene *scene = DEG_get_evaluated_scene(depsgraph);
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
const bool do_motion_blur = (scene->eevee.flag & SCE_EEVEE_MOTION_BLUR_ENABLED) != 0;
const bool do_motion_blur = (scene->r.mode & R_MBLUR) != 0;
const bool do_motion_blur_fx = do_motion_blur && (scene->eevee.motion_blur_max > 0);
if (!EEVEE_render_init(static_cast<EEVEE_Data *>(vedata), engine, depsgraph)) {
@ -482,7 +482,7 @@ static void eevee_render_to_image(void *vedata,
int initial_frame = scene->r.cfra;
float initial_subframe = scene->r.subframe;
float shuttertime = (do_motion_blur) ? scene->eevee.motion_blur_shutter : 0.0f;
float shuttertime = (do_motion_blur) ? scene->r.motion_blur_shutter : 0.0f;
int time_steps_tot = (do_motion_blur) ? max_ii(1, scene->eevee.motion_blur_steps) : 1;
g_data->render_timesteps = time_steps_tot;
@ -496,14 +496,14 @@ static void eevee_render_to_image(void *vedata,
/* Compute start time. The motion blur will cover `[time ...time + shuttertime]`. */
float time = initial_frame + initial_subframe;
switch (scene->eevee.motion_blur_position) {
case SCE_EEVEE_MB_START:
switch (scene->r.motion_blur_position) {
case SCE_MB_START:
/* No offset. */
break;
case SCE_EEVEE_MB_CENTER:
case SCE_MB_CENTER:
time -= shuttertime * 0.5f;
break;
case SCE_EEVEE_MB_END:
case SCE_MB_END:
time -= shuttertime;
break;
default:

View File

@ -52,7 +52,7 @@ int EEVEE_motion_blur_init(EEVEE_ViewLayerData * /*sldata*/, EEVEE_Data *vedata)
effects->motion_blur_max = max_ii(0, scene->eevee.motion_blur_max);
if ((effects->motion_blur_max > 0) && (scene->eevee.flag & SCE_EEVEE_MOTION_BLUR_ENABLED)) {
if ((effects->motion_blur_max > 0) && (scene->r.mode & R_MBLUR)) {
if (DRW_state_is_scene_render()) {
int mb_step = effects->motion_blur_step;
DRW_view_viewmat_get(nullptr, effects->motion_blur.camera[mb_step].viewmat, false);

View File

@ -231,7 +231,7 @@ void Film::init(const int2 &extent, const rcti *output_rect)
/* Filter obsolete passes. */
enabled_passes_ &= ~(EEVEE_RENDER_PASS_UNUSED_8 | EEVEE_RENDER_PASS_BLOOM);
if (scene_eevee.flag & SCE_EEVEE_MOTION_BLUR_ENABLED) {
if (scene.r.mode & R_MBLUR) {
/* Disable motion vector pass if motion blur is enabled. */
enabled_passes_ &= ~EEVEE_RENDER_PASS_VECTOR;
}

View File

@ -28,7 +28,7 @@ void MotionBlurModule::init()
const Scene *scene = inst_.scene;
const ViewLayer *view_layer = inst_.view_layer;
enabled_ = (scene->eevee.flag & SCE_EEVEE_MOTION_BLUR_ENABLED) != 0;
enabled_ = (scene->r.mode & R_MBLUR) != 0;
if (enabled_) {
enabled_ = (view_layer->layflag & SCE_LAY_MOTION_BLUR) != 0;
}
@ -46,8 +46,8 @@ void MotionBlurModule::init()
initial_frame_ = scene->r.cfra;
initial_subframe_ = scene->r.subframe;
frame_time_ = initial_frame_ + initial_subframe_;
shutter_position_ = scene->eevee.motion_blur_position;
shutter_time_ = scene->eevee.motion_blur_shutter;
shutter_position_ = scene->r.motion_blur_position;
shutter_time_ = scene->r.motion_blur_shutter;
data_.depth_scale = scene->eevee.motion_blur_depth_scale;
motion_blur_fx_enabled_ = true; /* TODO(fclem): UI option. */
@ -108,13 +108,13 @@ void MotionBlurModule::step()
float MotionBlurModule::shutter_time_to_scene_time(float time)
{
switch (shutter_position_) {
case SCE_EEVEE_MB_START:
case SCE_MB_START:
/* No offset. */
break;
case SCE_EEVEE_MB_CENTER:
case SCE_MB_CENTER:
time -= 0.5f;
break;
case SCE_EEVEE_MB_END:
case SCE_MB_END:
time -= 1.0;
break;
default:

View File

@ -75,7 +75,7 @@ class MotionBlurModule {
float initial_subframe_;
/** Time of the frame we are rendering. */
float frame_time_;
/** Enum controlling when the shutter opens. See SceneEEVEE.motion_blur_position. */
/** Enum controlling when the shutter opens. See RenderData.motion_blur_position. */
int shutter_position_;
/** Time in scene frame the shutter is open. Controls the amount of blur. */
float shutter_time_;

View File

@ -914,11 +914,10 @@ struct PBVHBatches {
}
else {
const GenericRequest &request = std::get<GenericRequest>(vbo.request);
const StringRefNull name = request.name;
const bke::AttrDomain domain = request.domain;
const eCustomDataType data_type = request.type;
const CustomData &custom_data = *get_cdata(domain, args);
const int cd_offset = CustomData_get_offset_named(&custom_data, data_type, name.c_str());
const int cd_offset = CustomData_get_offset_named(&custom_data, data_type, request.name);
bke::attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
switch (domain) {

View File

@ -183,6 +183,13 @@ void ED_time_scrub_draw(const ARegion *region,
GPU_matrix_pop_projection();
}
rcti ED_time_scrub_clamp_scroller_mask(const rcti &scroller_mask)
{
rcti clamped_mask = scroller_mask;
clamped_mask.ymax -= UI_TIME_SCRUB_MARGIN_Y;
return clamped_mask;
}
bool ED_time_scrub_event_in_region(const ARegion *region, const wmEvent *event)
{
rcti rect = region->winrct;

View File

@ -21,6 +21,14 @@ void ED_time_scrub_draw(const ARegion *region,
const Scene *scene,
bool display_seconds,
bool discrete_frames);
/**
* Scroll-bars shouldn't overlap the time scrub UI. So this returns a mask adjusted to exclude it,
* which can be passed to #UI_view2d_scrollers_draw().
*
* \param scroller_mask: Typically #View2D.mask (or something smaller, if further parts have been
* masked out already).
*/
rcti ED_time_scrub_clamp_scroller_mask(const rcti &scroller_mask);
bool ED_time_scrub_event_in_region(const ARegion *region, const wmEvent *event);

View File

@ -1104,21 +1104,17 @@ void UI_but_execute(const bContext *C, ARegion *region, uiBut *but)
* returns false if undo needs to be disabled. */
static bool ui_but_is_rna_undo(const uiBut *but)
{
if (but->rnapoin.owner_id) {
/* avoid undo push for buttons who's ID are screen or wm level
* we could disable undo for buttons with no ID too but may have
* unforeseen consequences, so best check for ID's we _know_ are not
* handled by undo - campbell */
ID *id = but->rnapoin.owner_id;
if (ID_CHECK_UNDO(id) == false) {
return false;
}
if (but->rnaprop == nullptr) {
return true;
}
if (but->rnapoin.type && !RNA_struct_undo_check(but->rnapoin.type)) {
/* No owner or type known. Assume we do not undo push as it may be a property from
* the preferences stored outside datablocks. */
if (but->rnapoin.owner_id == nullptr || but->rnapoin.type == nullptr) {
return false;
}
return true;
return ID_CHECK_UNDO(but->rnapoin.owner_id) && RNA_struct_undo_check(but->rnapoin.type);
}
/* assigns automatic keybindings to menu items for fast access

View File

@ -181,13 +181,6 @@ static void view2d_masks(View2D *v2d, const rcti *mask_scroll)
v2d->vert.xmin = v2d->vert.xmax - scroll_width;
}
/* Currently, all regions that have vertical scale handles,
* also have the scrubbing area at the top.
* So the scroll-bar has to move down a bit. */
if (scroll & V2D_SCROLL_VERTICAL_HANDLES) {
v2d->vert.ymax -= UI_TIME_SCRUB_MARGIN_Y;
}
/* horizontal scroller */
if (scroll & V2D_SCROLL_BOTTOM) {
/* on bottom edge of region */

View File

@ -1908,11 +1908,17 @@ static void scroller_activate_init(bContext *C,
* - zooming must be allowed on this axis, otherwise, default to pan
*/
View2DScrollers scrollers;
/* Some Editors like the File-browser or Spreadsheet already set up custom masks for scroll-bars
* (they don't cover the whole region width or height), these need to be considered, otherwise
* coords for `mouse_in_scroller_handle` later are not compatible. */
/* Reconstruct the custom scroller mask passed to #UI_view2d_scrollers_draw().
*
* Some editors like the File Browser, Spreadsheet or scrubbing UI already set up custom masks
* for scroll-bars (they don't cover the whole region width or height), these need to be
* considered, otherwise coords for `mouse_in_scroller_handle` later are not compatible. This
* should be a reliable way to do it. Otherwise the custom scroller mask could also be stored in
* #View2D.
*/
rcti scroller_mask = v2d->hor;
BLI_rcti_union(&scroller_mask, &v2d->vert);
view2d_scrollers_calc(v2d, &scroller_mask, &scrollers);
/* Use a union of 'cur' & 'tot' in case the current view is far outside 'tot'. In this cases

View File

@ -274,17 +274,14 @@ int ED_mesh_uv_add(
CD_PROP_FLOAT2,
MEM_dupallocN(CustomData_get_layer(&mesh->corner_data, CD_PROP_FLOAT2)),
mesh->corners_num,
unique_name.c_str(),
unique_name,
nullptr);
is_init = true;
}
else {
CustomData_add_layer_named(&mesh->corner_data,
CD_PROP_FLOAT2,
CD_SET_DEFAULT,
mesh->corners_num,
unique_name.c_str());
CustomData_add_layer_named(
&mesh->corner_data, CD_PROP_FLOAT2, CD_SET_DEFAULT, mesh->corners_num, unique_name);
}
if (active_set || layernum_dst == 0) {
@ -341,10 +338,10 @@ const bool *ED_mesh_uv_map_pin_layer_get(const Mesh *mesh, const int uv_index)
static bool *ensure_corner_boolean_attribute(Mesh &mesh, const blender::StringRefNull name)
{
bool *data = static_cast<bool *>(CustomData_get_layer_named_for_write(
&mesh.corner_data, CD_PROP_BOOL, name.c_str(), mesh.corners_num));
&mesh.corner_data, CD_PROP_BOOL, name, mesh.corners_num));
if (!data) {
data = static_cast<bool *>(CustomData_add_layer_named(
&mesh.corner_data, CD_PROP_BOOL, CD_SET_DEFAULT, mesh.faces_num, name.c_str()));
&mesh.corner_data, CD_PROP_BOOL, CD_SET_DEFAULT, mesh.faces_num, name));
}
return data;
}

View File

@ -225,6 +225,9 @@ void OBJECT_OT_laplaciandeform_bind(struct wmOperatorType *ot);
void OBJECT_OT_surfacedeform_bind(struct wmOperatorType *ot);
void OBJECT_OT_geometry_nodes_input_attribute_toggle(struct wmOperatorType *ot);
void OBJECT_OT_geometry_node_tree_copy_assign(struct wmOperatorType *ot);
void OBJECT_OT_grease_pencil_dash_modifier_segment_add(struct wmOperatorType *ot);
void OBJECT_OT_grease_pencil_dash_modifier_segment_remove(struct wmOperatorType *ot);
void OBJECT_OT_grease_pencil_dash_modifier_segment_move(struct wmOperatorType *ot);
/* object_gpencil_modifiers.c */

View File

@ -18,6 +18,7 @@
#include "DNA_armature_types.h"
#include "DNA_array_utils.hh"
#include "DNA_curve_types.h"
#include "DNA_defaults.h"
#include "DNA_dynamicpaint_types.h"
#include "DNA_fluid_types.h"
#include "DNA_key_types.h"
@ -34,6 +35,7 @@
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_string_utf8.h"
#include "BLI_string_utils.hh"
#include "BLI_utildefines.h"
#include "BKE_DerivedMesh.hh"
@ -740,8 +742,8 @@ static void add_shapekey_layers(Mesh &mesh_dest, const Mesh &mesh_src)
memcpy(array, kb->data, sizeof(float[3]) * size_t(mesh_src.verts_num));
}
CustomData_add_layer_named_with_data(
&mesh_dest.vert_data, CD_SHAPEKEY, array, mesh_dest.verts_num, kb->name, nullptr);
CustomData_add_layer_with_data(
&mesh_dest.vert_data, CD_SHAPEKEY, array, mesh_dest.verts_num, nullptr);
const int ci = CustomData_get_layer_index_n(&mesh_dest.vert_data, CD_SHAPEKEY, i);
mesh_dest.vert_data.layers[ci].uid = kb->uid;
@ -3728,3 +3730,251 @@ void OBJECT_OT_geometry_node_tree_copy_assign(wmOperatorType *ot)
}
/** \} */
/* ------------------------------------------------------------------- */
/** \name Dash Modifier
* \{ */
namespace blender::ed::greasepencil {
static bool dash_modifier_segment_poll(bContext *C)
{
return edit_modifier_poll_generic(C, &RNA_GreasePencilDashModifierData, 0, false, false);
}
static int dash_modifier_segment_add_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_active_context(C);
auto *dmd = reinterpret_cast<GreasePencilDashModifierData *>(
edit_modifier_property_get(op, ob, eModifierType_GreasePencilDash));
if (dmd == nullptr) {
return OPERATOR_CANCELLED;
}
GreasePencilDashModifierSegment *new_segments = static_cast<GreasePencilDashModifierSegment *>(
MEM_malloc_arrayN(dmd->segments_num + 1, sizeof(GreasePencilDashModifierSegment), __func__));
const int new_active_index = dmd->segment_active_index + 1;
if (dmd->segments_num != 0) {
/* Copy the segments before the new segment. */
memcpy(new_segments,
dmd->segments_array,
sizeof(GreasePencilDashModifierSegment) * new_active_index);
/* Copy the segments after the new segment. */
memcpy(new_segments + new_active_index + 1,
dmd->segments_array + new_active_index,
sizeof(GreasePencilDashModifierSegment) * (dmd->segments_num - new_active_index));
}
/* Create the new segment. */
GreasePencilDashModifierSegment *ds = &new_segments[new_active_index];
memcpy(ds,
DNA_struct_default_get(GreasePencilDashModifierSegment),
sizeof(GreasePencilDashModifierSegment));
BLI_uniquename_cb(
[&](const blender::StringRef name) {
for (const GreasePencilDashModifierSegment &ds : dmd->segments()) {
if (STREQ(ds.name, name.data())) {
return true;
}
}
return false;
},
'.',
ds->name);
MEM_SAFE_FREE(dmd->segments_array);
dmd->segments_array = new_segments;
dmd->segments_num++;
dmd->segment_active_index++;
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
return OPERATOR_FINISHED;
}
static int dash_modifier_segment_add_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
{
if (edit_modifier_invoke_properties(C, op)) {
return dash_modifier_segment_add_exec(C, op);
}
return OPERATOR_CANCELLED;
}
} // namespace blender::ed::greasepencil
void OBJECT_OT_grease_pencil_dash_modifier_segment_add(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Add Segment";
ot->description = "Add a segment to the dash modifier";
ot->idname = "OBJECT_OT_grease_pencil_dash_modifier_segment_add";
/* api callbacks */
ot->poll = blender::ed::greasepencil::dash_modifier_segment_poll;
ot->invoke = blender::ed::greasepencil::dash_modifier_segment_add_invoke;
ot->exec = blender::ed::greasepencil::dash_modifier_segment_add_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_modifier_properties(ot);
}
namespace blender::ed::greasepencil {
static void dash_modifier_segment_free(GreasePencilDashModifierSegment * /*ds*/) {}
static int dash_modifier_segment_remove_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_active_context(C);
auto *dmd = reinterpret_cast<GreasePencilDashModifierData *>(
edit_modifier_property_get(op, ob, eModifierType_GreasePencilDash));
if (dmd == nullptr) {
return OPERATOR_CANCELLED;
}
if (!dmd->segments().index_range().contains(dmd->segment_active_index)) {
return OPERATOR_CANCELLED;
}
blender::dna::array::remove_index(&dmd->segments_array,
&dmd->segments_num,
&dmd->segment_active_index,
dmd->segment_active_index,
dash_modifier_segment_free);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
return OPERATOR_FINISHED;
}
static int dash_modifier_segment_remove_invoke(bContext *C,
wmOperator *op,
const wmEvent * /*event*/)
{
if (edit_modifier_invoke_properties(C, op)) {
return dash_modifier_segment_remove_exec(C, op);
}
return OPERATOR_CANCELLED;
}
} // namespace blender::ed::greasepencil
void OBJECT_OT_grease_pencil_dash_modifier_segment_remove(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Remove Dash Segment";
ot->description = "Remove the active segment from the dash modifier";
ot->idname = "OBJECT_OT_grease_pencil_dash_modifier_segment_remove";
/* api callbacks */
ot->poll = blender::ed::greasepencil::dash_modifier_segment_poll;
ot->invoke = blender::ed::greasepencil::dash_modifier_segment_remove_invoke;
ot->exec = blender::ed::greasepencil::dash_modifier_segment_remove_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_modifier_properties(ot);
RNA_def_int(
ot->srna, "index", 0, 0, INT_MAX, "Index", "Index of the segment to remove", 0, INT_MAX);
}
namespace blender::ed::greasepencil {
enum class DashSegmentMoveDirection {
Up = -1,
Down = 1,
};
static int dash_modifier_segment_move_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_active_context(C);
auto *dmd = reinterpret_cast<GreasePencilDashModifierData *>(
edit_modifier_property_get(op, ob, eModifierType_GreasePencilDash));
if (dmd == nullptr) {
return OPERATOR_CANCELLED;
}
if (dmd->segments_num < 2) {
return OPERATOR_CANCELLED;
}
const DashSegmentMoveDirection direction = DashSegmentMoveDirection(
RNA_enum_get(op->ptr, "type"));
switch (direction) {
case DashSegmentMoveDirection::Up:
if (dmd->segment_active_index == 0) {
return OPERATOR_CANCELLED;
}
std::swap(dmd->segments_array[dmd->segment_active_index],
dmd->segments_array[dmd->segment_active_index - 1]);
dmd->segment_active_index--;
break;
case DashSegmentMoveDirection::Down:
if (dmd->segment_active_index == dmd->segments_num - 1) {
return OPERATOR_CANCELLED;
}
std::swap(dmd->segments_array[dmd->segment_active_index],
dmd->segments_array[dmd->segment_active_index + 1]);
dmd->segment_active_index++;
break;
default:
return OPERATOR_CANCELLED;
}
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
return OPERATOR_FINISHED;
}
static int dash_modifier_segment_move_invoke(bContext *C,
wmOperator *op,
const wmEvent * /*event*/)
{
if (edit_modifier_invoke_properties(C, op)) {
return dash_modifier_segment_move_exec(C, op);
}
return OPERATOR_CANCELLED;
}
} // namespace blender::ed::greasepencil
void OBJECT_OT_grease_pencil_dash_modifier_segment_move(wmOperatorType *ot)
{
using blender::ed::greasepencil::DashSegmentMoveDirection;
static const EnumPropertyItem segment_move[] = {
{int(DashSegmentMoveDirection::Up), "UP", 0, "Up", ""},
{int(DashSegmentMoveDirection::Down), "DOWN", 0, "Down", ""},
{0, nullptr, 0, nullptr, nullptr},
};
/* identifiers */
ot->name = "Move Dash Segment";
ot->description = "Move the active dash segment up or down";
ot->idname = "OBJECT_OT_grease_pencil_dash_modifier_segment_move";
/* api callbacks */
ot->poll = blender::ed::greasepencil::dash_modifier_segment_poll;
ot->invoke = blender::ed::greasepencil::dash_modifier_segment_move_invoke;
ot->exec = blender::ed::greasepencil::dash_modifier_segment_move_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
edit_modifier_properties(ot);
ot->prop = RNA_def_enum(ot->srna, "type", segment_move, 0, "Type", "");
}
/** \} */

View File

@ -141,6 +141,9 @@ void ED_operatortypes_object()
WM_operatortype_append(OBJECT_OT_skin_armature_create);
WM_operatortype_append(OBJECT_OT_geometry_nodes_input_attribute_toggle);
WM_operatortype_append(OBJECT_OT_geometry_node_tree_copy_assign);
WM_operatortype_append(OBJECT_OT_grease_pencil_dash_modifier_segment_add);
WM_operatortype_append(OBJECT_OT_grease_pencil_dash_modifier_segment_remove);
WM_operatortype_append(OBJECT_OT_grease_pencil_dash_modifier_segment_move);
/* grease pencil modifiers */
WM_operatortype_append(OBJECT_OT_gpencil_modifier_add);

View File

@ -260,7 +260,7 @@ struct PuffOperationExecutor {
brush_, dist_to_brush_cu, brush_radius_cu);
math::max_inplace(max_weight, radius_falloff);
}
r_curve_weights[curve_i] = max_weight;
math::max_inplace(r_curve_weights[curve_i], max_weight);
});
}

View File

@ -146,6 +146,7 @@ struct PaintOperationExecutor {
BrushGpencilSettings *settings_;
float4 vertex_color_;
float hardness_;
bke::greasepencil::Drawing *drawing_;
@ -170,6 +171,8 @@ struct PaintOperationExecutor {
settings_->vertex_factor) :
float4(0.0f);
srgb_to_linearrgb_v4(vertex_color_, vertex_color_);
/* TODO: UI setting. */
hardness_ = 1.0f;
// const bool use_vertex_color_fill = use_vertex_color && ELEM(
// brush->gpencil_settings->vertex_mode, GPPAINT_MODE_STROKE, GPPAINT_MODE_BOTH);
@ -233,11 +236,17 @@ struct PaintOperationExecutor {
"material_index", bke::AttrDomain::Curve);
bke::SpanAttributeWriter<bool> cyclic = attributes.lookup_or_add_for_write_span<bool>(
"cyclic", bke::AttrDomain::Curve);
bke::SpanAttributeWriter<float> hardnesses = attributes.lookup_or_add_for_write_span<float>(
"hardness",
bke::AttrDomain::Curve,
bke::AttributeInitVArray(VArray<float>::ForSingle(1.0f, curves.curves_num())));
cyclic.span.last() = false;
materials.span.last() = material_index;
hardnesses.span.last() = hardness_;
cyclic.finish();
materials.finish();
hardnesses.finish();
curves.curve_types_for_write().last() = CURVE_TYPE_POLY;
curves.update_curve_types();

View File

@ -44,6 +44,7 @@
#include "BKE_customdata.hh"
#include "BKE_image.h"
#include "BKE_key.hh"
#include "BKE_layer.hh"
#include "BKE_lib_id.hh"
#include "BKE_main.hh"
#include "BKE_mesh.hh"
@ -4894,7 +4895,10 @@ bool SCULPT_cursor_geometry_info_update(bContext *C,
ob = vc.obact;
ss = ob->sculpt;
if (!ss->pbvh || !vc.rv3d) {
const View3D *v3d = CTX_wm_view3d(C);
const Base *base = CTX_data_active_base(C);
if (!ss->pbvh || !vc.rv3d || !BKE_base_is_visible(v3d, base)) {
zero_v3(out->location);
zero_v3(out->normal);
zero_v3(out->active_vertex_co);
@ -5635,16 +5639,13 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent
int retval;
Object *ob = CTX_data_active_object(C);
const View3D *v3d = CTX_wm_view3d(C);
const Base *base = CTX_data_active_base(C);
/* Test that ob is visible; otherwise we won't be able to get evaluated data
* from the depsgraph. We do this here instead of SCULPT_mode_poll
* to avoid falling through to the translate operator in the
* global view3d keymap.
*
* NOTE: #BKE_object_is_visible_in_viewport is not working here (it returns false
* if the object is in local view); instead, test for OB_HIDE_VIEWPORT directly.
*/
if (ob->visibility_flag & OB_HIDE_VIEWPORT) {
* global view3d keymap. */
if (!BKE_base_is_visible(v3d, base)) {
return OPERATOR_CANCELLED;
}

View File

@ -595,7 +595,8 @@ static bool restore_color(Object *ob, Node &unode, MutableSpan<bool> modified_ve
/* NOTE: even with loop colors we still store derived
* vertex colors for original data lookup. */
if (!unode.col.is_empty() && unode.loop_col.is_empty()) {
BKE_pbvh_swap_colors(ss->pbvh, unode.vert_indices, unode.col);
BKE_pbvh_swap_colors(
ss->pbvh, unode.vert_indices.as_span().take_front(unode.unique_verts_num), unode.col);
modified = true;
}
@ -1404,7 +1405,8 @@ static void store_color(Object *ob, Node *unode)
/* NOTE: even with loop colors we still store (derived)
* vertex colors for original data lookup. */
BKE_pbvh_store_colors_vertex(ss->pbvh, unode->vert_indices, unode->col);
BKE_pbvh_store_colors_vertex(
ss->pbvh, unode->vert_indices.as_span().take_front(unode->unique_verts_num), unode->col);
if (!unode->loop_col.is_empty() && !unode->corner_indices.is_empty()) {
BKE_pbvh_store_colors(ss->pbvh, unode->corner_indices, unode->loop_col);

View File

@ -874,7 +874,8 @@ static void graph_region_draw(const bContext *C, ARegion *region)
ED_time_scrub_draw_current_frame(region, scene, sc->flag & SC_SHOW_SECONDS);
/* scrollers */
UI_view2d_scrollers_draw(v2d, nullptr);
const rcti scroller_mask = ED_time_scrub_clamp_scroller_mask(v2d->mask);
UI_view2d_scrollers_draw(v2d, &scroller_mask);
/* scale indicators */
{

View File

@ -333,8 +333,9 @@ static void graph_main_region_draw_overlay(const bContext *C, ARegion *region)
}
/* scrollers */
const rcti scroller_mask = ED_time_scrub_clamp_scroller_mask(v2d->mask);
/* FIXME: args for scrollers depend on the type of data being shown. */
UI_view2d_scrollers_draw(v2d, nullptr);
UI_view2d_scrollers_draw(v2d, &scroller_mask);
/* scale numbers */
{

View File

@ -1925,5 +1925,6 @@ void draw_timeline_seq_display(const bContext *C, ARegion *region)
const ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene));
SEQ_timeline_boundbox(scene, seqbase, &v2d->tot);
UI_view2d_scrollers_draw(v2d, nullptr);
const rcti scroller_mask = ED_time_scrub_clamp_scroller_mask(v2d->mask);
UI_view2d_scrollers_draw(v2d, &scroller_mask);
}

View File

@ -59,6 +59,32 @@ PyObject *PyBool_from_bool(bool b)
return PyBool_FromLong(b ? 1 : 0);
}
PyObject *PyLong_subtype_new(PyTypeObject *ty, long value)
{
BLI_assert(ty->tp_basicsize == sizeof(PyLongObject));
PyLongObject *result = PyObject_NewVar(PyLongObject, ty, 1);
#if PY_VERSION_HEX >= 0x030c0000
{
/* Account for change in `PyLongObject` in Python 3.12+.
* The values of longs are no longer accessible via public API's, copy the value instead. */
PyLongObject *value_py = (PyLongObject *)PyLong_FromLong(value);
memcpy(&result->long_value, &value_py->long_value, sizeof(result->long_value));
Py_DECREF(value_py);
}
#else
result->ob_digit[0] = value;
#endif
return (PyObject *)result;
}
void PyLong_subtype_add_to_dict(PyObject *dict, PyTypeObject *ty, const char *attr, long value)
{
PyObject *result = PyLong_subtype_new(ty, value);
PyDict_SetItemString(dict, attr, result);
/* Owned by the dictionary. */
Py_DECREF(result);
}
PyObject *Vector_from_Vec2f(Vec2f &vec)
{
float vec_data[2]; // because vec->_coord is protected

View File

@ -74,6 +74,9 @@ extern "C" {
// C++ => Python
//==============================
PyObject *PyLong_subtype_new(PyTypeObject *ty, long value);
void PyLong_subtype_add_to_dict(PyObject *dict, PyTypeObject *ty, const char *attr, long value);
PyObject *PyBool_from_bool(bool b);
PyObject *Vector_from_Vec2f(Freestyle::Geometry::Vec2f &v);
PyObject *Vector_from_Vec3f(Freestyle::Geometry::Vec3f &v);

View File

@ -196,21 +196,6 @@ PyTypeObject IntegrationType_Type = {
/*-----------------------BPy_IntegrationType instance definitions -------------------------*/
static PyLongObject _IntegrationType_MEAN = {
PyVarObject_HEAD_INIT(&IntegrationType_Type, 1){MEAN}};
static PyLongObject _IntegrationType_MIN = {PyVarObject_HEAD_INIT(&IntegrationType_Type, 1){MIN}};
static PyLongObject _IntegrationType_MAX = {PyVarObject_HEAD_INIT(&IntegrationType_Type, 1){MAX}};
static PyLongObject _IntegrationType_FIRST = {
PyVarObject_HEAD_INIT(&IntegrationType_Type, 1){FIRST}};
static PyLongObject _IntegrationType_LAST = {
PyVarObject_HEAD_INIT(&IntegrationType_Type, 1){LAST}};
#define BPy_IntegrationType_MEAN ((PyObject *)&_IntegrationType_MEAN)
#define BPy_IntegrationType_MIN ((PyObject *)&_IntegrationType_MIN)
#define BPy_IntegrationType_MAX ((PyObject *)&_IntegrationType_MAX)
#define BPy_IntegrationType_FIRST ((PyObject *)&_IntegrationType_FIRST)
#define BPy_IntegrationType_LAST ((PyObject *)&_IntegrationType_LAST)
//-------------------MODULE INITIALIZATION--------------------------------
int IntegrationType_Init(PyObject *module)
{
@ -226,11 +211,17 @@ int IntegrationType_Init(PyObject *module)
Py_INCREF(&IntegrationType_Type);
PyModule_AddObject(module, "IntegrationType", (PyObject *)&IntegrationType_Type);
PyDict_SetItemString(IntegrationType_Type.tp_dict, "MEAN", BPy_IntegrationType_MEAN);
PyDict_SetItemString(IntegrationType_Type.tp_dict, "MIN", BPy_IntegrationType_MIN);
PyDict_SetItemString(IntegrationType_Type.tp_dict, "MAX", BPy_IntegrationType_MAX);
PyDict_SetItemString(IntegrationType_Type.tp_dict, "FIRST", BPy_IntegrationType_FIRST);
PyDict_SetItemString(IntegrationType_Type.tp_dict, "LAST", BPy_IntegrationType_LAST);
#define ADD_TYPE_CONST(id) \
PyLong_subtype_add_to_dict( \
IntegrationType_Type.tp_dict, &IntegrationType_Type, STRINGIFY(id), id)
ADD_TYPE_CONST(MEAN);
ADD_TYPE_CONST(MIN);
ADD_TYPE_CONST(MAX);
ADD_TYPE_CONST(FIRST);
ADD_TYPE_CONST(LAST);
#undef ADD_TYPE_CONST
m = PyModule_Create(&module_definition);
if (m == nullptr) {

View File

@ -76,9 +76,12 @@ int Interface1D_Init(PyObject *module)
Py_INCREF(&Stroke_Type);
PyModule_AddObject(module, "Stroke", (PyObject *)&Stroke_Type);
PyDict_SetItemString(Stroke_Type.tp_dict, "DRY_MEDIUM", BPy_MediumType_DRY_MEDIUM);
PyDict_SetItemString(Stroke_Type.tp_dict, "HUMID_MEDIUM", BPy_MediumType_HUMID_MEDIUM);
PyDict_SetItemString(Stroke_Type.tp_dict, "OPAQUE_MEDIUM", BPy_MediumType_OPAQUE_MEDIUM);
#define ADD_TYPE_CONST(id) \
PyLong_subtype_add_to_dict(Stroke_Type.tp_dict, &MediumType_Type, STRINGIFY(id), Stroke::id)
ADD_TYPE_CONST(DRY_MEDIUM);
ADD_TYPE_CONST(HUMID_MEDIUM);
ADD_TYPE_CONST(OPAQUE_MEDIUM);
#undef ADD_TYPE_CONST
if (PyType_Ready(&ViewEdge_Type) < 0) {
return -1;

View File

@ -75,16 +75,6 @@ PyTypeObject MediumType_Type = {
/*-----------------------BPy_IntegrationType instance definitions -------------------------*/
PyLongObject _BPy_MediumType_DRY_MEDIUM = {
PyVarObject_HEAD_INIT(&MediumType_Type, 1){Stroke::DRY_MEDIUM},
};
PyLongObject _BPy_MediumType_HUMID_MEDIUM = {
PyVarObject_HEAD_INIT(&MediumType_Type, 1){Stroke::HUMID_MEDIUM},
};
PyLongObject _BPy_MediumType_OPAQUE_MEDIUM = {
PyVarObject_HEAD_INIT(&MediumType_Type, 1){Stroke::OPAQUE_MEDIUM},
};
//-------------------MODULE INITIALIZATION--------------------------------
int MediumType_Init(PyObject *module)

View File

@ -33,15 +33,6 @@ typedef struct {
int MediumType_Init(PyObject *module);
// internal constants
extern PyLongObject _BPy_MediumType_DRY_MEDIUM;
extern PyLongObject _BPy_MediumType_HUMID_MEDIUM;
extern PyLongObject _BPy_MediumType_OPAQUE_MEDIUM;
// public constants
#define BPy_MediumType_DRY_MEDIUM ((PyObject *)&_BPy_MediumType_DRY_MEDIUM)
#define BPy_MediumType_HUMID_MEDIUM ((PyObject *)&_BPy_MediumType_HUMID_MEDIUM)
#define BPy_MediumType_OPAQUE_MEDIUM ((PyObject *)&_BPy_MediumType_OPAQUE_MEDIUM)
///////////////////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus

View File

@ -139,45 +139,6 @@ PyTypeObject Nature_Type = {
/*-----------------------BPy_Nature instance definitions ----------------------------------*/
static PyLongObject _Nature_POINT = {PyVarObject_HEAD_INIT(&Nature_Type, 0){Nature::POINT}};
static PyLongObject _Nature_S_VERTEX = {PyVarObject_HEAD_INIT(&Nature_Type, 1){Nature::S_VERTEX}};
static PyLongObject _Nature_VIEW_VERTEX = {
PyVarObject_HEAD_INIT(&Nature_Type, 1){Nature::VIEW_VERTEX}};
static PyLongObject _Nature_NON_T_VERTEX = {
PyVarObject_HEAD_INIT(&Nature_Type, 1){Nature::NON_T_VERTEX}};
static PyLongObject _Nature_T_VERTEX = {PyVarObject_HEAD_INIT(&Nature_Type, 1){Nature::T_VERTEX}};
static PyLongObject _Nature_CUSP = {PyVarObject_HEAD_INIT(&Nature_Type, 1){Nature::CUSP}};
static PyLongObject _Nature_NO_FEATURE = {
PyVarObject_HEAD_INIT(&Nature_Type, 0){Nature::NO_FEATURE}};
static PyLongObject _Nature_SILHOUETTE = {
PyVarObject_HEAD_INIT(&Nature_Type, 1){Nature::SILHOUETTE}};
static PyLongObject _Nature_BORDER = {PyVarObject_HEAD_INIT(&Nature_Type, 1){Nature::BORDER}};
static PyLongObject _Nature_CREASE = {PyVarObject_HEAD_INIT(&Nature_Type, 1){Nature::CREASE}};
static PyLongObject _Nature_RIDGE = {PyVarObject_HEAD_INIT(&Nature_Type, 1){Nature::RIDGE}};
static PyLongObject _Nature_VALLEY = {PyVarObject_HEAD_INIT(&Nature_Type, 1){Nature::VALLEY}};
static PyLongObject _Nature_SUGGESTIVE_CONTOUR = {
PyVarObject_HEAD_INIT(&Nature_Type, 1){Nature::SUGGESTIVE_CONTOUR}};
static PyLongObject _Nature_MATERIAL_BOUNDARY = {
PyVarObject_HEAD_INIT(&Nature_Type, 1){Nature::MATERIAL_BOUNDARY}};
static PyLongObject _Nature_EDGE_MARK = {
PyVarObject_HEAD_INIT(&Nature_Type, 1){Nature::EDGE_MARK}};
#define BPy_Nature_POINT ((PyObject *)&_Nature_POINT)
#define BPy_Nature_S_VERTEX ((PyObject *)&_Nature_S_VERTEX)
#define BPy_Nature_VIEW_VERTEX ((PyObject *)&_Nature_VIEW_VERTEX)
#define BPy_Nature_NON_T_VERTEX ((PyObject *)&_Nature_NON_T_VERTEX)
#define BPy_Nature_T_VERTEX ((PyObject *)&_Nature_T_VERTEX)
#define BPy_Nature_CUSP ((PyObject *)&_Nature_CUSP)
#define BPy_Nature_NO_FEATURE ((PyObject *)&_Nature_NO_FEATURE)
#define BPy_Nature_SILHOUETTE ((PyObject *)&_Nature_SILHOUETTE)
#define BPy_Nature_BORDER ((PyObject *)&_Nature_BORDER)
#define BPy_Nature_CREASE ((PyObject *)&_Nature_CREASE)
#define BPy_Nature_RIDGE ((PyObject *)&_Nature_RIDGE)
#define BPy_Nature_VALLEY ((PyObject *)&_Nature_VALLEY)
#define BPy_Nature_SUGGESTIVE_CONTOUR ((PyObject *)&_Nature_SUGGESTIVE_CONTOUR)
#define BPy_Nature_MATERIAL_BOUNDARY ((PyObject *)&_Nature_MATERIAL_BOUNDARY)
#define BPy_Nature_EDGE_MARK ((PyObject *)&_Nature_EDGE_MARK)
//-------------------MODULE INITIALIZATION--------------------------------
int Nature_Init(PyObject *module)
{
@ -191,24 +152,29 @@ int Nature_Init(PyObject *module)
Py_INCREF(&Nature_Type);
PyModule_AddObject(module, "Nature", (PyObject *)&Nature_Type);
#define ADD_TYPE_CONST(id) \
PyLong_subtype_add_to_dict(Nature_Type.tp_dict, &Nature_Type, STRINGIFY(id), Nature::id)
// VertexNature
PyDict_SetItemString(Nature_Type.tp_dict, "POINT", BPy_Nature_POINT);
PyDict_SetItemString(Nature_Type.tp_dict, "S_VERTEX", BPy_Nature_S_VERTEX);
PyDict_SetItemString(Nature_Type.tp_dict, "VIEW_VERTEX", BPy_Nature_VIEW_VERTEX);
PyDict_SetItemString(Nature_Type.tp_dict, "NON_T_VERTEX", BPy_Nature_NON_T_VERTEX);
PyDict_SetItemString(Nature_Type.tp_dict, "T_VERTEX", BPy_Nature_T_VERTEX);
PyDict_SetItemString(Nature_Type.tp_dict, "CUSP", BPy_Nature_CUSP);
ADD_TYPE_CONST(POINT);
ADD_TYPE_CONST(S_VERTEX);
ADD_TYPE_CONST(VIEW_VERTEX);
ADD_TYPE_CONST(NON_T_VERTEX);
ADD_TYPE_CONST(T_VERTEX);
ADD_TYPE_CONST(CUSP);
// EdgeNature
PyDict_SetItemString(Nature_Type.tp_dict, "NO_FEATURE", BPy_Nature_NO_FEATURE);
PyDict_SetItemString(Nature_Type.tp_dict, "SILHOUETTE", BPy_Nature_SILHOUETTE);
PyDict_SetItemString(Nature_Type.tp_dict, "BORDER", BPy_Nature_BORDER);
PyDict_SetItemString(Nature_Type.tp_dict, "CREASE", BPy_Nature_CREASE);
PyDict_SetItemString(Nature_Type.tp_dict, "RIDGE", BPy_Nature_RIDGE);
PyDict_SetItemString(Nature_Type.tp_dict, "VALLEY", BPy_Nature_VALLEY);
PyDict_SetItemString(Nature_Type.tp_dict, "SUGGESTIVE_CONTOUR", BPy_Nature_SUGGESTIVE_CONTOUR);
PyDict_SetItemString(Nature_Type.tp_dict, "MATERIAL_BOUNDARY", BPy_Nature_MATERIAL_BOUNDARY);
PyDict_SetItemString(Nature_Type.tp_dict, "EDGE_MARK", BPy_Nature_EDGE_MARK);
ADD_TYPE_CONST(NO_FEATURE);
ADD_TYPE_CONST(SILHOUETTE);
ADD_TYPE_CONST(BORDER);
ADD_TYPE_CONST(CREASE);
ADD_TYPE_CONST(RIDGE);
ADD_TYPE_CONST(VALLEY);
ADD_TYPE_CONST(SUGGESTIVE_CONTOUR);
ADD_TYPE_CONST(MATERIAL_BOUNDARY);
ADD_TYPE_CONST(EDGE_MARK);
#undef ADD_TYPE_CONST
return 0;
}
@ -249,10 +215,7 @@ static PyObject *BPy_Nature_bitwise(PyObject *a, int op, PyObject *b)
result = PyObject_NewVar(BPy_Nature, &Nature_Type, 0);
}
else {
result = PyObject_NewVar(BPy_Nature, &Nature_Type, 1);
if (result) {
result->i.ob_digit[0] = v;
}
result = (BPy_Nature *)PyLong_subtype_new(&Nature_Type, v);
}
return (PyObject *)result;
}

View File

@ -249,8 +249,7 @@ void separate_geometry(bke::GeometrySet &geometry_set,
continue;
}
const bke::CurvesGeometry &src_curves = drawing->strokes();
const bke::GreasePencilLayerFieldContext field_context(
grease_pencil, AttrDomain::Curve, layer_index);
const bke::GreasePencilLayerFieldContext field_context(grease_pencil, domain, layer_index);
std::optional<bke::CurvesGeometry> dst_curves = separate_curves_selection(
src_curves, field_context, selection, domain, propagation_info);
if (!dst_curves) {

View File

@ -155,13 +155,6 @@ int CustomData_get_offset(const struct CustomData * /*data*/, eCustomDataType /*
return 0;
}
int CustomData_get_named_layer_index(const struct CustomData * /*data*/,
eCustomDataType /*type*/,
const char * /*name*/)
{
return -1;
}
int CustomData_get_active_layer_index(const struct CustomData * /*data*/, eCustomDataType /*type*/)
{
return -1;

View File

@ -476,7 +476,7 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *mesh)
COLLADAFW::String &uvname = info->mName;
/* Allocate space for UV_data */
CustomData_add_layer_named(
&mesh->corner_data, CD_PROP_FLOAT2, CD_SET_DEFAULT, mesh->corners_num, uvname.c_str());
&mesh->corner_data, CD_PROP_FLOAT2, CD_SET_DEFAULT, mesh->corners_num, uvname);
}
/* activate the first uv map */
CustomData_set_layer_active(&mesh->corner_data, CD_PROP_FLOAT2, 0);
@ -488,11 +488,8 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *mesh)
COLLADAFW::MeshVertexData::InputInfos *info =
collada_mesh->getColors().getInputInfosArray()[i];
COLLADAFW::String colname = extract_vcolname(info->mName);
CustomData_add_layer_named(&mesh->corner_data,
CD_PROP_BYTE_COLOR,
CD_SET_DEFAULT,
mesh->corners_num,
colname.c_str());
CustomData_add_layer_named(
&mesh->corner_data, CD_PROP_BYTE_COLOR, CD_SET_DEFAULT, mesh->corners_num, colname);
}
BKE_id_attributes_active_color_set(
&mesh->id, CustomData_get_layer_name(&mesh->corner_data, CD_PROP_BYTE_COLOR, 0));
@ -726,10 +723,8 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh,
{
COLLADAFW::IndexList &index_list = *index_list_array_uvcoord[uvset_index];
blender::float2 *mloopuv = static_cast<blender::float2 *>(
CustomData_get_layer_named_for_write(&mesh->corner_data,
CD_PROP_FLOAT2,
index_list.getName().c_str(),
mesh->corners_num));
CustomData_get_layer_named_for_write(
&mesh->corner_data, CD_PROP_FLOAT2, index_list.getName(), mesh->corners_num));
if (mloopuv == nullptr) {
fprintf(stderr,
"Collada import: Mesh [%s] : Unknown reference to TEXCOORD [#%s].\n",
@ -770,7 +765,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh,
COLLADAFW::IndexList &color_index_list = *mp->getColorIndices(vcolor_index);
COLLADAFW::String colname = extract_vcolname(color_index_list.getName());
MLoopCol *mloopcol = (MLoopCol *)CustomData_get_layer_named_for_write(
&mesh->corner_data, CD_PROP_BYTE_COLOR, colname.c_str(), mesh->corners_num);
&mesh->corner_data, CD_PROP_BYTE_COLOR, colname, mesh->corners_num);
if (mloopcol == nullptr) {
fprintf(stderr,
"Collada import: Mesh [%s] : Unknown reference to VCOLOR [#%s].\n",

View File

@ -858,7 +858,8 @@ bool USDMaterialReader::follow_connection(const pxr::UsdShadeInput &usd_input,
}
/* Create a Separate Color node if necessary. */
IntermediateNode separate_color = add_separate_color(source_name, ntree, column + shift, r_ctx);
IntermediateNode separate_color = add_separate_color(
source_name, ntree, column + shift, r_ctx);
if (separate_color.node) {
shift++;
}
@ -900,18 +901,31 @@ bool USDMaterialReader::follow_connection(const pxr::UsdShadeInput &usd_input,
}
else if (scale_bias.node) {
if (separate_color.node) {
link_nodes(ntree, separate_color.node, separate_color.sock_output_name, dest_node, dest_socket_name);
link_nodes(ntree, scale_bias.node, scale_bias.sock_output_name, separate_color.node, separate_color.sock_input_name);
link_nodes(ntree,
separate_color.node,
separate_color.sock_output_name,
dest_node,
dest_socket_name);
link_nodes(ntree,
scale_bias.node,
scale_bias.sock_output_name,
separate_color.node,
separate_color.sock_input_name);
}
else {
link_nodes(ntree, scale_bias.node, scale_bias.sock_output_name, dest_node, dest_socket_name);
link_nodes(
ntree, scale_bias.node, scale_bias.sock_output_name, dest_node, dest_socket_name);
}
target_node = scale_bias.node;
target_sock_name = scale_bias.sock_input_name;
shift++;
}
else if (separate_color.node) {
link_nodes(ntree, separate_color.node, separate_color.sock_output_name, dest_node, dest_socket_name);
link_nodes(ntree,
separate_color.node,
separate_color.sock_output_name,
dest_node,
dest_socket_name);
target_node = separate_color.node;
target_sock_name = separate_color.sock_input_name;
}

View File

@ -872,4 +872,28 @@
.thickness = 0.02, \
}
#define _DNA_DEFAULT_GreasePencilLatticeModifierData \
{ \
.object = NULL, \
.strength = 1.0f, \
}
#define _DNA_DEFAULT_GreasePencilDashModifierData \
{ \
.dash_offset = 0, \
.segments_array = NULL, \
.segments_num = 0, \
.segment_active_index = 0, \
}
#define _DNA_DEFAULT_GreasePencilDashModifierSegment \
{ \
.name = "", \
.dash = 2, \
.gap = 1, \
.radius = 1.0f, \
.opacity = 1.0f, \
.mat_nr = -1, \
}
/* clang-format off */

View File

@ -15,6 +15,8 @@
#include "DNA_session_uid_types.h"
#ifdef __cplusplus
# include "BLI_span.hh"
namespace blender {
struct NodesModifierRuntime;
}
@ -102,6 +104,8 @@ typedef enum ModifierType {
eModifierType_GreasePencilNoise = 67,
eModifierType_GreasePencilMirror = 68,
eModifierType_GreasePencilThickness = 69,
eModifierType_GreasePencilLattice = 70,
eModifierType_GreasePencilDash = 71,
NUM_MODIFIER_TYPES,
} ModifierType;
@ -2772,3 +2776,43 @@ typedef enum GreasePencilThicknessModifierFlag {
MOD_GREASE_PENCIL_THICK_NORMALIZE = (1 << 0),
MOD_GREASE_PENCIL_THICK_WEIGHT_FACTOR = (1 << 1),
} GreasePencilThicknessModifierFlag;
typedef struct GreasePencilLatticeModifierData {
ModifierData modifier;
GreasePencilModifierInfluenceData influence;
struct Object *object;
float strength;
char _pad[4];
} GreasePencilLatticeModifierData;
typedef struct GreasePencilDashModifierSegment {
char name[64];
int dash;
int gap;
float radius;
float opacity;
int mat_nr;
/** #GreasePencilDashModifierFlag */
int flag;
} GreasePencilDashModifierSegment;
typedef struct GreasePencilDashModifierData {
ModifierData modifier;
GreasePencilModifierInfluenceData influence;
GreasePencilDashModifierSegment *segments_array;
int segments_num;
int segment_active_index;
int dash_offset;
char _pad[4];
#ifdef __cplusplus
blender::Span<GreasePencilDashModifierSegment> segments() const;
blender::MutableSpan<GreasePencilDashModifierSegment> segments();
#endif
} GreasePencilDashModifierData;
typedef enum GreasePencilDashModifierFlag {
MOD_GREASE_PENCIL_DASH_USE_CYCLIC = (1 << 0),
} GreasePencilDashModifierFlag;

View File

@ -76,7 +76,6 @@
.framapto = 100, \
.images = 100, \
.framelen = 1.0, \
.blurfac = 0.5, \
.frs_sec = 24, \
.frs_sec_base = 1, \
\
@ -129,6 +128,8 @@
.unit_line_thickness = 1.0f, \
\
.ffcodecdata = _DNA_DEFAULT_FFMpegCodecData, \
\
.motion_blur_shutter = 0.5f, \
}
#define _DNA_DEFAULT_AudioData \
@ -226,7 +227,6 @@
.bloom_radius = 6.5f, \
.bloom_clamp = 0.0f, \
\
.motion_blur_shutter = 0.5f, \
.motion_blur_depth_scale = 100.0f, \
.motion_blur_max = 32, \
.motion_blur_steps = 1, \

View File

@ -44,6 +44,16 @@ struct World;
struct bGPdata;
struct bNodeTree;
/** Workaround to forward-declare C++ type in C header. */
#ifdef __cplusplus
namespace blender::bke {
class SceneRuntime;
}
using SceneRuntimeHandle = blender::bke::SceneRuntime;
#else // __cplusplus
typedef struct SceneRuntimeHandle SceneRuntimeHandle;
#endif // __cplusplus
/* -------------------------------------------------------------------- */
/** \name FFMPEG
* \{ */
@ -686,21 +696,17 @@ typedef struct RenderData {
int images, framapto;
short flag, threads;
float framelen, blurfac;
float framelen;
/** Frames to jump during render/playback. */
int frame_step;
char _pad10[2];
/** For the dimensions presets menu. */
short dimensionspreset;
/** Size in %. */
short size;
char _pad6[2];
/* From buttons: */
/**
* The desired number of pixels in the x direction
@ -845,7 +851,9 @@ typedef struct RenderData {
/* Hair Display. */
short hair_type, hair_subdiv;
/** Motion blur shutter. */
/** Motion blur */
float motion_blur_shutter;
int motion_blur_position;
struct CurveMapping mblur_shutter_curve;
} RenderData;
@ -860,6 +868,13 @@ typedef enum eHairType {
SCE_HAIR_SHAPE_STRIP = 1,
} eHairType;
/** #RenderData::motion_blur_position */
enum {
SCE_MB_CENTER = 0,
SCE_MB_START = 1,
SCE_MB_END = 2,
};
/** \} */
/* -------------------------------------------------------------------- */
@ -1890,8 +1905,8 @@ typedef struct SceneEEVEE {
int motion_blur_samples DNA_DEPRECATED;
int motion_blur_max;
int motion_blur_steps;
int motion_blur_position;
float motion_blur_shutter;
int motion_blur_position_deprecated DNA_DEPRECATED;
float motion_blur_shutter_deprecated DNA_DEPRECATED;
float motion_blur_depth_scale;
int shadow_method DNA_DEPRECATED;
@ -2081,6 +2096,9 @@ typedef struct Scene {
struct SceneEEVEE eevee;
struct SceneGpencil grease_pencil_settings;
struct SceneHydra hydra;
SceneRuntimeHandle *runtime;
void *_pad9;
} Scene;
/** \} */
@ -2845,7 +2863,7 @@ enum {
SCE_EEVEE_GTAO_BOUNCE = (1 << 6),
// SCE_EEVEE_DOF_ENABLED = (1 << 7), /* Moved to camera->dof.flag */
SCE_EEVEE_BLOOM_ENABLED = (1 << 8),
SCE_EEVEE_MOTION_BLUR_ENABLED = (1 << 9),
SCE_EEVEE_MOTION_BLUR_ENABLED_DEPRECATED = (1 << 9), /* Moved to scene->r.mode */
SCE_EEVEE_SHADOW_HIGH_BITDEPTH = (1 << 10),
SCE_EEVEE_TAA_REPROJECTION = (1 << 11),
// SCE_EEVEE_SSS_ENABLED = (1 << 12), /* Unused */
@ -2888,13 +2906,6 @@ enum {
/* SHADOW_METHOD_MAX = 3, */ /* UNUSED */
};
/** #SceneEEVEE::motion_blur_position */
enum {
SCE_EEVEE_MB_CENTER = 0,
SCE_EEVEE_MB_START = 1,
SCE_EEVEE_MB_END = 2,
};
/** #SceneDisplay->render_aa and #SceneDisplay->viewport_aa */
enum {
SCE_DISPLAY_AA_OFF = 0,

View File

@ -333,6 +333,9 @@ SDNA_DEFAULT_DECL_STRUCT(GreasePencilTintModifierData);
SDNA_DEFAULT_DECL_STRUCT(GreasePencilOffsetModifierData);
SDNA_DEFAULT_DECL_STRUCT(GreasePencilMirrorModifierData);
SDNA_DEFAULT_DECL_STRUCT(GreasePencilThickModifierData);
SDNA_DEFAULT_DECL_STRUCT(GreasePencilLatticeModifierData);
SDNA_DEFAULT_DECL_STRUCT(GreasePencilDashModifierSegment);
SDNA_DEFAULT_DECL_STRUCT(GreasePencilDashModifierData);
#undef SDNA_DEFAULT_DECL_STRUCT
@ -588,6 +591,9 @@ const void *DNA_default_table[SDNA_TYPE_MAX] = {
SDNA_DEFAULT_DECL(GreasePencilOffsetModifierData),
SDNA_DEFAULT_DECL(GreasePencilMirrorModifierData),
SDNA_DEFAULT_DECL(GreasePencilThickModifierData),
SDNA_DEFAULT_DECL(GreasePencilLatticeModifierData),
SDNA_DEFAULT_DECL(GreasePencilDashModifierSegment),
SDNA_DEFAULT_DECL(GreasePencilDashModifierData),
};
#undef SDNA_DEFAULT_DECL
#undef SDNA_DEFAULT_DECL_EX

View File

@ -161,7 +161,10 @@ DNA_STRUCT_RENAME_ELEM(ParticleSettings, dup_ob, instance_object)
DNA_STRUCT_RENAME_ELEM(ParticleSettings, dupliweights, instance_weights)
DNA_STRUCT_RENAME_ELEM(ParticleSettings, ren_child_nbr, child_render_percent)
DNA_STRUCT_RENAME_ELEM(RenderData, bake_filter, bake_margin)
DNA_STRUCT_RENAME_ELEM(RenderData, blurfac, motion_blur_shutter)
DNA_STRUCT_RENAME_ELEM(RigidBodyWorld, steps_per_second, substeps_per_frame)
DNA_STRUCT_RENAME_ELEM(SceneEEVEE, motion_blur_position, motion_blur_position_deprecated)
DNA_STRUCT_RENAME_ELEM(SceneEEVEE, motion_blur_shutter, motion_blur_shutter_deprecated)
DNA_STRUCT_RENAME_ELEM(SDefBind, numverts, verts_num)
DNA_STRUCT_RENAME_ELEM(SDefVert, numbinds, binds_num)
DNA_STRUCT_RENAME_ELEM(Sequence, retiming_handle_num, retiming_keys_num)

View File

@ -321,6 +321,16 @@ const EnumPropertyItem rna_enum_object_modifier_type_items[] = {
ICON_MOD_THICKNESS,
"Thickness",
"Change stroke thickness"},
{eModifierType_GreasePencilLattice,
"GREASE_PENCIL_LATTICE",
ICON_MOD_LATTICE,
"Lattice",
"Deform strokes using a lattice object"},
{eModifierType_GreasePencilDash,
"GREASE_PENCIL_DASH",
ICON_MOD_DASH,
"Dot Dash",
"Generate dot-dash styled strokes"},
RNA_ENUM_ITEM_HEADING(N_("Physics"), nullptr),
{eModifierType_Cloth, "CLOTH", ICON_MOD_CLOTH, "Cloth", ""},
@ -731,6 +741,7 @@ const EnumPropertyItem rna_enum_subdivision_boundary_smooth_items[] = {
# include "BKE_particle.h"
# include "BLI_sort_utils.h"
# include "BLI_string_utils.hh"
# include "DEG_depsgraph.hh"
# include "DEG_depsgraph_build.hh"
@ -943,6 +954,9 @@ RNA_MOD_OBJECT_SET(NormalEdit, target, OB_EMPTY);
RNA_MOD_OBJECT_SET(Shrinkwrap, target, OB_MESH);
RNA_MOD_OBJECT_SET(Shrinkwrap, auxTarget, OB_MESH);
RNA_MOD_OBJECT_SET(SurfaceDeform, target, OB_MESH);
RNA_MOD_OBJECT_SET(GreasePencilMirror, object, OB_EMPTY);
RNA_MOD_OBJECT_SET(GreasePencilTint, object, OB_EMPTY);
RNA_MOD_OBJECT_SET(GreasePencilLattice, object, OB_LATTICE);
static void rna_HookModifier_object_set(PointerRNA *ptr,
PointerRNA value,
@ -1854,6 +1868,8 @@ RNA_MOD_GREASE_PENCIL_MATERIAL_FILTER_SET(GreasePencilTint);
RNA_MOD_GREASE_PENCIL_MATERIAL_FILTER_SET(GreasePencilSmooth);
RNA_MOD_GREASE_PENCIL_MATERIAL_FILTER_SET(GreasePencilNoise);
RNA_MOD_GREASE_PENCIL_MATERIAL_FILTER_SET(GreasePencilThick);
RNA_MOD_GREASE_PENCIL_MATERIAL_FILTER_SET(GreasePencilLattice);
RNA_MOD_GREASE_PENCIL_MATERIAL_FILTER_SET(GreasePencilDash);
RNA_MOD_GREASE_PENCIL_VERTEX_GROUP_SET(GreasePencilOffset);
RNA_MOD_GREASE_PENCIL_VERTEX_GROUP_SET(GreasePencilOpacity);
@ -1862,6 +1878,7 @@ RNA_MOD_GREASE_PENCIL_VERTEX_GROUP_SET(GreasePencilTint);
RNA_MOD_GREASE_PENCIL_VERTEX_GROUP_SET(GreasePencilSmooth);
RNA_MOD_GREASE_PENCIL_VERTEX_GROUP_SET(GreasePencilNoise);
RNA_MOD_GREASE_PENCIL_VERTEX_GROUP_SET(GreasePencilThick);
RNA_MOD_GREASE_PENCIL_VERTEX_GROUP_SET(GreasePencilLattice);
static void rna_GreasePencilOpacityModifier_opacity_factor_range(
PointerRNA *ptr, float *min, float *max, float *softmin, float *softmax)
@ -1883,26 +1900,78 @@ static void rna_GreasePencilOpacityModifier_opacity_factor_max_set(PointerRNA *p
value;
}
static void rna_GreasePencilTintModifier_object_set(PointerRNA *ptr,
PointerRNA value,
ReportList * /*reports*/)
static const GreasePencilDashModifierData *find_grease_pencil_dash_modifier_of_segment(
const Object &ob, const GreasePencilDashModifierSegment &dash_segment)
{
GreasePencilTintModifierData *tmd = static_cast<GreasePencilTintModifierData *>(ptr->data);
Object *ob = static_cast<Object *>(value.data);
tmd->object = ob;
id_lib_extern(&ob->id);
LISTBASE_FOREACH (const ModifierData *, md, &ob.modifiers) {
if (md->type == eModifierType_GreasePencilDash) {
const auto *dmd = reinterpret_cast<const GreasePencilDashModifierData *>(md);
if (dmd->segments().contains_ptr(&dash_segment)) {
return dmd;
}
}
}
return nullptr;
}
static void rna_GreasePencilMirrorModifier_object_set(PointerRNA *ptr,
PointerRNA value,
ReportList * /*reports*/)
{
GreasePencilMirrorModifierData *mmd = static_cast<GreasePencilMirrorModifierData *>(ptr->data);
Object *ob = static_cast<Object *>(value.data);
static std::optional<std::string> rna_GreasePencilDashModifierSegment_path(const PointerRNA *ptr)
mmd->object = ob;
id_lib_extern(&ob->id);
{
const Object *ob = reinterpret_cast<Object *>(ptr->owner_id);
const auto *dash_segment = static_cast<GreasePencilDashModifierSegment *>(ptr->data);
const GreasePencilDashModifierData *dmd = find_grease_pencil_dash_modifier_of_segment(
*ob, *dash_segment);
BLI_assert(dmd != nullptr);
char name_esc[sizeof(dmd->modifier.name) * 2];
BLI_str_escape(name_esc, dmd->modifier.name, sizeof(name_esc));
char ds_name_esc[sizeof(dash_segment->name) * 2];
BLI_str_escape(ds_name_esc, dash_segment->name, sizeof(ds_name_esc));
return fmt::format("modifiers[\"{}\"].segments[\"{}\"]", name_esc, ds_name_esc);
}
static void rna_GreasePencilDashModifierSegment_name_set(PointerRNA *ptr, const char *value)
{
const Object *ob = reinterpret_cast<Object *>(ptr->owner_id);
auto *dash_segment = static_cast<GreasePencilDashModifierSegment *>(ptr->data);
const GreasePencilDashModifierData *dmd = find_grease_pencil_dash_modifier_of_segment(
*ob, *dash_segment);
BLI_assert(dmd != nullptr);
const std::string oldname = dash_segment->name;
STRNCPY_UTF8(dash_segment->name, value);
BLI_uniquename_cb(
[dmd, dash_segment](const blender::StringRef name) {
for (const GreasePencilDashModifierSegment &ds : dmd->segments()) {
if (&ds != dash_segment && ds.name == name) {
return true;
}
}
return false;
},
'.',
dash_segment->name);
/* Fix all the animation data which may link to this. */
char name_esc[sizeof(dmd->modifier.name) * 2];
BLI_str_escape(name_esc, dmd->modifier.name, sizeof(name_esc));
char rna_path_prefix[36 + sizeof(name_esc) + 1];
SNPRINTF(rna_path_prefix, "modifiers[\"%s\"].segments", name_esc);
BKE_animdata_fix_paths_rename_all(nullptr, rna_path_prefix, oldname.c_str(), dash_segment->name);
}
static void rna_GreasePencilDashModifier_segments_begin(CollectionPropertyIterator *iter,
PointerRNA *ptr)
{
auto *dmd = static_cast<GreasePencilDashModifierData *>(ptr->data);
rna_iterator_array_begin(iter,
dmd->segments_array,
sizeof(GreasePencilDashModifierSegment),
dmd->segments_num,
false,
nullptr);
}
#else
@ -8421,6 +8490,151 @@ static void rna_def_modifier_grease_pencil_thickness(BlenderRNA *brna)
RNA_define_lib_overridable(false);
}
static void rna_def_modifier_grease_pencil_lattice(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "GreasePencilLatticeModifier", "Modifier");
RNA_def_struct_ui_text(
srna, "Grease Pencil Lattice Modifier", "Deform strokes using a lattice object");
RNA_def_struct_sdna(srna, "GreasePencilLatticeModifierData");
RNA_def_struct_ui_icon(srna, ICON_MOD_LATTICE);
rna_def_modifier_grease_pencil_layer_filter(srna);
rna_def_modifier_grease_pencil_material_filter(
srna, "rna_GreasePencilLatticeModifier_material_filter_set");
rna_def_modifier_grease_pencil_vertex_group(
srna, "rna_GreasePencilLatticeModifier_vertex_group_name_set");
rna_def_modifier_panel_open_prop(srna, "open_influence_panel", 0);
RNA_define_lib_overridable(true);
prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
RNA_def_property_ui_text(prop, "Object", "Lattice object to deform with");
RNA_def_property_pointer_funcs(prop,
nullptr,
"rna_GreasePencilLatticeModifier_object_set",
nullptr,
"rna_Lattice_object_poll");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
RNA_def_property_ui_range(prop, 0, 1, 10, 2);
RNA_def_property_ui_text(prop, "Strength", "Strength of modifier effect");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
RNA_define_lib_overridable(false);
}
static void rna_def_modifier_grease_pencil_dash_segment(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "GreasePencilDashModifierSegment", nullptr);
RNA_def_struct_ui_text(srna, "Dash Modifier Segment", "Configuration for a single dash segment");
RNA_def_struct_sdna(srna, "GreasePencilDashModifierSegment");
RNA_def_struct_path_func(srna, "rna_GreasePencilDashModifierSegment_path");
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Name", "Name of the dash segment");
RNA_def_property_string_funcs(
prop, nullptr, nullptr, "rna_GreasePencilDashModifierSegment_name_set");
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER | NA_RENAME, nullptr);
RNA_def_struct_name_property(srna, prop);
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "dash", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, 1, INT16_MAX);
RNA_def_property_ui_text(
prop,
"Dash",
"The number of consecutive points from the original stroke to include in this segment");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "gap", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, 0, INT16_MAX);
RNA_def_property_ui_text(prop, "Gap", "The number of points skipped after this segment");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "radius", PROP_FLOAT, PROP_FACTOR | PROP_UNSIGNED);
RNA_def_property_ui_range(prop, 0, 1, 0.1, 2);
RNA_def_property_ui_text(
prop, "Radius", "The factor to apply to the original point's radius for the new points");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "opacity", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_ui_range(prop, 0, 1, 0.1, 2);
RNA_def_property_ui_text(
prop, "Opacity", "The factor to apply to the original point's opacity for the new points");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "material_index", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, nullptr, "mat_nr");
RNA_def_property_range(prop, -1, INT16_MAX);
RNA_def_property_ui_text(
prop,
"Material Index",
"Use this index on generated segment. -1 means using the existing material");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "use_cyclic", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, nullptr, "flag", MOD_GREASE_PENCIL_DASH_USE_CYCLIC);
RNA_def_property_ui_text(prop, "Cyclic", "Enable cyclic on individual stroke dashes");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
static void rna_def_modifier_grease_pencil_dash(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "GreasePencilDashModifierData", "Modifier");
RNA_def_struct_ui_text(
srna, "Grease Pencil Dash Modifier", "Create dot-dash effect for strokes");
RNA_def_struct_sdna(srna, "GreasePencilDashModifierData");
RNA_def_struct_ui_icon(srna, ICON_MOD_DASH);
rna_def_modifier_grease_pencil_layer_filter(srna);
rna_def_modifier_grease_pencil_material_filter(
srna, "rna_GreasePencilDashModifier_material_filter_set");
rna_def_modifier_panel_open_prop(srna, "open_influence_panel", 0);
RNA_define_lib_overridable(true);
prop = RNA_def_property(srna, "segments", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "GreasePencilDashModifierSegment");
RNA_def_property_collection_sdna(prop, nullptr, "segments_array", nullptr);
RNA_def_property_collection_funcs(prop,
"rna_GreasePencilDashModifier_segments_begin",
"rna_iterator_array_next",
"rna_iterator_array_end",
"rna_iterator_array_get",
nullptr,
nullptr,
nullptr,
nullptr);
RNA_def_property_ui_text(prop, "Segments", "");
prop = RNA_def_property(srna, "segment_active_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Active Dash Segment Index", "Active index in the segment list");
prop = RNA_def_property(srna, "dash_offset", PROP_INT, PROP_NONE);
RNA_def_property_ui_text(
prop,
"Offset",
"Offset into each stroke before the beginning of the dashed segment generation");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
RNA_define_lib_overridable(false);
}
void RNA_def_modifier(BlenderRNA *brna)
{
StructRNA *srna;
@ -8597,6 +8811,9 @@ void RNA_def_modifier(BlenderRNA *brna)
rna_def_modifier_grease_pencil_noise(brna);
rna_def_modifier_grease_pencil_mirror(brna);
rna_def_modifier_grease_pencil_thickness(brna);
rna_def_modifier_grease_pencil_lattice(brna);
rna_def_modifier_grease_pencil_dash_segment(brna);
rna_def_modifier_grease_pencil_dash(brna);
}
#endif

View File

@ -6025,7 +6025,6 @@ static void rna_def_image_format_stereo3d_format(BlenderRNA *brna)
srna = RNA_def_struct(brna, "Stereo3dFormat", nullptr);
RNA_def_struct_sdna(srna, "Stereo3dFormat");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Stereo Output", "Settings for stereo output");
prop = RNA_def_property(srna, "display_mode", PROP_ENUM, PROP_NONE);
@ -6606,6 +6605,17 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
{0, nullptr, 0, nullptr, nullptr},
};
static const EnumPropertyItem motion_blur_position_items[] = {
{SCE_MB_START, "START", 0, "Start on Frame", "The shutter opens at the current frame"},
{SCE_MB_CENTER,
"CENTER",
0,
"Center on Frame",
"The shutter is open during the current frame"},
{SCE_MB_END, "END", 0, "End on Frame", "The shutter closes at the current frame"},
{0, nullptr, 0, nullptr, nullptr},
};
static const EnumPropertyItem hair_shape_type_items[] = {
{SCE_HAIR_SHAPE_STRAND, "STRAND", 0, "Strand", ""},
{SCE_HAIR_SHAPE_STRIP, "STRIP", 0, "Strip", ""},
@ -6784,12 +6794,20 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_render_update");
prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, nullptr, "blurfac");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 0.01f, 1.0f, 1, 2);
RNA_def_property_ui_text(prop, "Shutter", "Time taken in frames between shutter open and close");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_render_update");
prop = RNA_def_property(srna, "motion_blur_position", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, motion_blur_position_items);
RNA_def_property_ui_text(prop,
"Motion Blur Position",
"Offset for the shutter's time interval, "
"allows to change the motion blur trails");
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, nullptr);
prop = RNA_def_property(srna, "motion_blur_shutter_curve", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, nullptr, "mblur_shutter_curve");
RNA_def_property_struct_type(prop, "CurveMapping");
@ -7757,17 +7775,6 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
{0, nullptr, 0, nullptr, nullptr},
};
static const EnumPropertyItem eevee_motion_blur_position_items[] = {
{SCE_EEVEE_MB_START, "START", 0, "Start on Frame", "The shutter opens at the current frame"},
{SCE_EEVEE_MB_CENTER,
"CENTER",
0,
"Center on Frame",
"The shutter is open during the current frame"},
{SCE_EEVEE_MB_END, "END", 0, "End on Frame", "The shutter closes at the current frame"},
{0, nullptr, 0, nullptr, nullptr},
};
static const EnumPropertyItem ray_tracing_method_items[] = {
{RAYTRACE_EEVEE_METHOD_NONE, "NONE", 0, "None", "No intersection with scene geometry"},
{RAYTRACE_EEVEE_METHOD_SCREEN,
@ -8232,19 +8239,6 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, nullptr);
/* Motion blur */
prop = RNA_def_property(srna, "use_motion_blur", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, nullptr, "flag", SCE_EEVEE_MOTION_BLUR_ENABLED);
RNA_def_property_ui_text(prop, "Motion Blur", "Enable motion blur effect (only in camera view)");
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, nullptr);
prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_ui_text(prop, "Shutter", "Time taken in frames between shutter open and close");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 0.01f, 1.0f, 1, 2);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, nullptr);
prop = RNA_def_property(srna, "motion_blur_depth_scale", PROP_FLOAT, PROP_NONE);
RNA_def_property_ui_text(prop,
"Background Separation",
@ -8272,15 +8266,6 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, nullptr);
prop = RNA_def_property(srna, "motion_blur_position", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, eevee_motion_blur_position_items);
RNA_def_property_ui_text(prop,
"Motion Blur Position",
"Offset for the shutter's time interval, "
"allows to change the motion blur trails");
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, nullptr);
/* Shadows */
prop = RNA_def_property(srna, "use_shadows", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, nullptr, "flag", SCE_EEVEE_SHADOW_ENABLED);

View File

@ -827,6 +827,7 @@ static void rna_def_sculpt(BlenderRNA *brna)
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Sculpt_update");
prop = RNA_def_property(srna, "detail_size", PROP_FLOAT, PROP_PIXEL);
RNA_def_property_range(prop, 0.5, 40.0);
RNA_def_property_ui_range(prop, 0.5, 40.0, 0.1, 2);
RNA_def_property_ui_scale_type(prop, PROP_SCALE_CUBIC);
RNA_def_property_ui_text(
@ -834,6 +835,7 @@ static void rna_def_sculpt(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr);
prop = RNA_def_property(srna, "detail_percent", PROP_FLOAT, PROP_PERCENTAGE);
RNA_def_property_range(prop, 0.5, 100.0);
RNA_def_property_ui_range(prop, 0.5, 100.0, 10, 2);
RNA_def_property_ui_text(
prop,

View File

@ -1340,7 +1340,6 @@ static void rna_def_userdef_theme_ui_font_style(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeFontStyle", nullptr);
RNA_def_struct_sdna(srna, "uiFontStyle");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Font Style", "Theme settings for Font");
prop = RNA_def_property(srna, "points", PROP_FLOAT, PROP_UNSIGNED);
@ -1396,7 +1395,6 @@ static void rna_def_userdef_theme_ui_style(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeStyle", nullptr);
RNA_def_struct_sdna(srna, "uiStyle");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Style", "Theme settings for style sets");
prop = RNA_def_property(srna, "panel_title", PROP_POINTER, PROP_NONE);
@ -1428,7 +1426,6 @@ static void rna_def_userdef_theme_ui_wcol(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeWidgetColors", nullptr);
RNA_def_struct_sdna(srna, "uiWidgetColors");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Widget Color Set", "Theme settings for widget color sets");
prop = RNA_def_property(srna, "outline", PROP_FLOAT, PROP_COLOR_GAMMA);
@ -1490,7 +1487,6 @@ static void rna_def_userdef_theme_ui_wcol_state(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeWidgetStateColors", nullptr);
RNA_def_struct_sdna(srna, "uiWidgetStateColors");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(
srna, "Theme Widget State Color", "Theme settings for widget state colors");
@ -1556,7 +1552,6 @@ static void rna_def_userdef_theme_ui_panel(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemePanelColors", nullptr);
RNA_def_struct_sdna(srna, "uiPanelColors");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Panel Color", "Theme settings for panel colors");
prop = RNA_def_property(srna, "header", PROP_FLOAT, PROP_COLOR_GAMMA);
@ -1599,7 +1594,6 @@ static void rna_def_userdef_theme_ui_gradient(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeGradientColors", nullptr);
RNA_def_struct_sdna(srna, "ThemeSpace");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(
srna, "Theme Background Color", "Theme settings for background colors and gradient");
@ -1634,7 +1628,6 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeUserInterface", nullptr);
RNA_def_struct_sdna(srna, "ThemeUI");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(
srna, "Theme User Interface", "Theme settings for user interface elements");
@ -2124,7 +2117,6 @@ static void rna_def_userdef_theme_asset_shelf(BlenderRNA *brna)
PropertyRNA *prop;
srna = RNA_def_struct(brna, "ThemeAssetShelf", nullptr);
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Asset Shelf Color", "Theme settings for asset shelves");
prop = RNA_def_property(srna, "header_back", PROP_FLOAT, PROP_COLOR_GAMMA);
@ -2449,7 +2441,6 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeView3D", nullptr);
RNA_def_struct_sdna(srna, "ThemeSpace");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme 3D Viewport", "Theme settings for the 3D viewport");
rna_def_userdef_theme_spaces_gradient(srna);
@ -2679,7 +2670,6 @@ static void rna_def_userdef_theme_space_graph(BlenderRNA *brna)
/* space_graph */
srna = RNA_def_struct(brna, "ThemeGraphEditor", nullptr);
RNA_def_struct_sdna(srna, "ThemeSpace");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Graph Editor", "Theme settings for the graph editor");
rna_def_userdef_theme_spaces_main(srna);
@ -2766,7 +2756,6 @@ static void rna_def_userdef_theme_space_file(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeFileBrowser", nullptr);
RNA_def_struct_sdna(srna, "ThemeSpace");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme File Browser", "Theme settings for the File Browser");
rna_def_userdef_theme_spaces_main(srna);
@ -2792,7 +2781,6 @@ static void rna_def_userdef_theme_space_outliner(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeOutliner", nullptr);
RNA_def_struct_sdna(srna, "ThemeSpace");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Outliner", "Theme settings for the Outliner");
rna_def_userdef_theme_spaces_main(srna);
@ -2841,7 +2829,6 @@ static void rna_def_userdef_theme_space_userpref(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemePreferences", nullptr);
RNA_def_struct_sdna(srna, "ThemeSpace");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Preferences", "Theme settings for the Blender Preferences");
rna_def_userdef_theme_spaces_main(srna);
@ -2856,7 +2843,6 @@ static void rna_def_userdef_theme_space_console(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeConsole", nullptr);
RNA_def_struct_sdna(srna, "ThemeSpace");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Console", "Theme settings for the Console");
rna_def_userdef_theme_spaces_main(srna);
@ -2907,7 +2893,6 @@ static void rna_def_userdef_theme_space_info(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeInfo", nullptr);
RNA_def_struct_sdna(srna, "ThemeSpace");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Info", "Theme settings for Info");
rna_def_userdef_theme_spaces_main(srna);
@ -2992,7 +2977,6 @@ static void rna_def_userdef_theme_space_text(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeTextEditor", nullptr);
RNA_def_struct_sdna(srna, "ThemeSpace");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Text Editor", "Theme settings for the Text Editor");
rna_def_userdef_theme_spaces_main(srna);
@ -3088,7 +3072,6 @@ static void rna_def_userdef_theme_space_node(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeNodeEditor", nullptr);
RNA_def_struct_sdna(srna, "ThemeSpace");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Node Editor", "Theme settings for the Node Editor");
rna_def_userdef_theme_spaces_main(srna);
@ -3292,7 +3275,6 @@ static void rna_def_userdef_theme_space_buts(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeProperties", nullptr);
RNA_def_struct_sdna(srna, "ThemeSpace");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Properties", "Theme settings for the Properties");
prop = RNA_def_property(srna, "match", PROP_FLOAT, PROP_COLOR_GAMMA);
@ -3318,7 +3300,6 @@ static void rna_def_userdef_theme_space_image(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeImageEditor", nullptr);
RNA_def_struct_sdna(srna, "ThemeSpace");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Image Editor", "Theme settings for the Image Editor");
rna_def_userdef_theme_spaces_main(srna);
@ -3431,7 +3412,6 @@ static void rna_def_userdef_theme_space_seq(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeSequenceEditor", nullptr);
RNA_def_struct_sdna(srna, "ThemeSpace");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Sequence Editor", "Theme settings for the Sequence Editor");
rna_def_userdef_theme_spaces_main(srna);
@ -3638,7 +3618,6 @@ static void rna_def_userdef_theme_space_action(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeDopeSheet", nullptr);
RNA_def_struct_sdna(srna, "ThemeSpace");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Dope Sheet", "Theme settings for the Dope Sheet");
rna_def_userdef_theme_spaces_main(srna);
@ -3848,7 +3827,6 @@ static void rna_def_userdef_theme_space_nla(BlenderRNA *brna)
/* space_nla */
srna = RNA_def_struct(brna, "ThemeNLAEditor", nullptr);
RNA_def_struct_sdna(srna, "ThemeSpace");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Nonlinear Animation", "Theme settings for the NLA Editor");
rna_def_userdef_theme_spaces_main(srna);
@ -4011,7 +3989,6 @@ static void rna_def_userdef_theme_colorset(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeBoneColorSet", nullptr);
RNA_def_struct_sdna(srna, "ThemeWireColor");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Bone Color Set", "Theme settings for bone color sets");
prop = RNA_def_property(srna, "normal", PROP_FLOAT, PROP_COLOR_GAMMA);
@ -4048,7 +4025,6 @@ static void rna_def_userdef_theme_collection_color(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeCollectionColor", nullptr);
RNA_def_struct_sdna(srna, "ThemeCollectionColor");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Collection Color", "Theme settings for collection colors");
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA);
@ -4065,7 +4041,6 @@ static void rna_def_userdef_theme_strip_color(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeStripColor", nullptr);
RNA_def_struct_sdna(srna, "ThemeStripColor");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Strip Color", "Theme settings for strip colors");
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA);
@ -4084,7 +4059,6 @@ static void rna_def_userdef_theme_space_clip(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeClipEditor", nullptr);
RNA_def_struct_sdna(srna, "ThemeSpace");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Clip Editor", "Theme settings for the Movie Clip Editor");
rna_def_userdef_theme_spaces_main(srna);
@ -4209,7 +4183,6 @@ static void rna_def_userdef_theme_space_topbar(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeTopBar", nullptr);
RNA_def_struct_sdna(srna, "ThemeSpace");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Top Bar", "Theme settings for the Top Bar");
rna_def_userdef_theme_spaces_main(srna);
@ -4223,7 +4196,6 @@ static void rna_def_userdef_theme_space_statusbar(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeStatusBar", nullptr);
RNA_def_struct_sdna(srna, "ThemeSpace");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Status Bar", "Theme settings for the Status Bar");
rna_def_userdef_theme_spaces_main(srna);
@ -4238,7 +4210,6 @@ static void rna_def_userdef_theme_space_spreadsheet(BlenderRNA *brna)
srna = RNA_def_struct(brna, "ThemeSpreadsheet", nullptr);
RNA_def_struct_sdna(srna, "ThemeSpace");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme Spreadsheet", "Theme settings for the Spreadsheet");
prop = RNA_def_property(srna, "row_alternate", PROP_FLOAT, PROP_COLOR_GAMMA);
@ -4282,7 +4253,6 @@ static void rna_def_userdef_themes(BlenderRNA *brna)
srna = RNA_def_struct(brna, "Theme", nullptr);
RNA_def_struct_sdna(srna, "bTheme");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Theme", "User interface styling and color settings");
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
@ -4439,7 +4409,6 @@ static void rna_def_userdef_addon(BlenderRNA *brna)
srna = RNA_def_struct(brna, "Addon", nullptr);
RNA_def_struct_sdna(srna, "bAddon");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Add-on", "Python add-ons to be loaded automatically");
prop = RNA_def_property(srna, "module", PROP_STRING, PROP_NONE);
@ -4508,7 +4477,6 @@ static void rna_def_userdef_studiolight(BlenderRNA *brna)
RNA_define_verify_sdna(false);
srna = RNA_def_struct(brna, "StudioLight", nullptr);
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Studio Light", "Studio light");
prop = RNA_def_property(srna, "index", PROP_INT, PROP_NONE);
@ -4584,7 +4552,6 @@ static void rna_def_userdef_pathcompare(BlenderRNA *brna)
srna = RNA_def_struct(brna, "PathCompare", nullptr);
RNA_def_struct_sdna(srna, "bPathCompare");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Path Compare", "Match paths against this value");
prop = RNA_def_property(srna, "path", PROP_STRING, PROP_DIRPATH);
@ -4668,7 +4635,6 @@ static void rna_def_userdef_solidlight(BlenderRNA *brna)
srna = RNA_def_struct(brna, "UserSolidLight", nullptr);
RNA_def_struct_sdna(srna, "SolidLight");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(
srna, "Solid Light", "Light used for Studio lighting in solid shading mode");
@ -4714,7 +4680,6 @@ static void rna_def_userdef_walk_navigation(BlenderRNA *brna)
srna = RNA_def_struct(brna, "WalkNavigation", nullptr);
RNA_def_struct_sdna(srna, "WalkNavigation");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Walk Navigation", "Walk navigation settings");
prop = RNA_def_property(srna, "mouse_speed", PROP_FLOAT, PROP_NONE);
@ -4879,7 +4844,6 @@ static void rna_def_userdef_view(BlenderRNA *brna)
srna = RNA_def_struct(brna, "PreferencesView", nullptr);
RNA_def_struct_sdna(srna, "UserDef");
RNA_def_struct_nested(brna, srna, "Preferences");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "View & Controls", "Preferences related to viewing data");
/* View. */
@ -5369,7 +5333,6 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
srna = RNA_def_struct(brna, "PreferencesEdit", nullptr);
RNA_def_struct_sdna(srna, "UserDef");
RNA_def_struct_nested(brna, srna, "Preferences");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Edit Methods", "Settings for interacting with Blender data");
/* Edit Methods */
@ -5876,7 +5839,6 @@ static void rna_def_userdef_system(BlenderRNA *brna)
srna = RNA_def_struct(brna, "PreferencesSystem", nullptr);
RNA_def_struct_sdna(srna, "UserDef");
RNA_def_struct_nested(brna, srna, "Preferences");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "System & OpenGL", "Graphics driver and operating system settings");
/* UI settings. */
@ -6243,7 +6205,6 @@ static void rna_def_userdef_input(BlenderRNA *brna)
srna = RNA_def_struct(brna, "PreferencesInput", nullptr);
RNA_def_struct_sdna(srna, "UserDef");
RNA_def_struct_nested(brna, srna, "Preferences");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Input", "Settings for input devices");
prop = RNA_def_property(srna, "view_zoom_method", PROP_ENUM, PROP_NONE);
@ -6549,7 +6510,6 @@ static void rna_def_userdef_keymap(BlenderRNA *brna)
StructRNA *srna = RNA_def_struct(brna, "PreferencesKeymap", nullptr);
RNA_def_struct_sdna(srna, "UserDef");
RNA_def_struct_nested(brna, srna, "Preferences");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Keymap", "Shortcut setup for keyboards and other input devices");
prop = RNA_def_property(srna, "show_ui_keyconfig", PROP_BOOLEAN, PROP_NONE);
@ -6569,7 +6529,6 @@ static void rna_def_userdef_filepaths_asset_library(BlenderRNA *brna)
srna = RNA_def_struct(brna, "UserAssetLibrary", nullptr);
RNA_def_struct_sdna(srna, "bUserAssetLibrary");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(
srna, "Asset Library", "Settings to define a reusable library for Asset Browsers to use");
@ -6626,7 +6585,6 @@ static void rna_def_userdef_filepaths_extension_repo(BlenderRNA *brna)
srna = RNA_def_struct(brna, "UserExtensionRepo", nullptr);
RNA_def_struct_sdna(srna, "bUserExtensionRepo");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(
srna, "Extension Repository", "Settings to define an extension repository");
@ -6690,7 +6648,6 @@ static void rna_def_userdef_script_directory(BlenderRNA *brna)
{
StructRNA *srna = RNA_def_struct(brna, "ScriptDirectory", nullptr);
RNA_def_struct_sdna(srna, "bUserScriptDirectory");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Python Scripts Directory", "");
PropertyRNA *prop;
@ -6734,7 +6691,6 @@ static void rna_def_userdef_script_directory_collection(BlenderRNA *brna, Proper
RNA_def_property_srna(cprop, "ScriptDirectoryCollection");
srna = RNA_def_struct(brna, "ScriptDirectoryCollection", nullptr);
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Python Scripts Directories", "");
func = RNA_def_function(srna, "new", "rna_userdef_script_directory_new");
@ -6760,7 +6716,6 @@ static void rna_def_userdef_asset_library_collection(BlenderRNA *brna, PropertyR
RNA_def_property_srna(cprop, "AssetLibraryCollection");
srna = RNA_def_struct(brna, "AssetLibraryCollection", nullptr);
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "User Asset Libraries", "Collection of user asset libraries");
func = RNA_def_function(srna, "new", "rna_userdef_asset_library_new");
@ -6788,7 +6743,6 @@ static void rna_def_userdef_extension_repos_collection(BlenderRNA *brna, Propert
RNA_def_property_srna(cprop, "UserExtensionRepoCollection");
srna = RNA_def_struct(brna, "UserExtensionRepoCollection", nullptr);
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(
srna, "User Extension Repositories", "Collection of user extension repositories");
@ -6845,7 +6799,6 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna)
srna = RNA_def_struct(brna, "PreferencesFilePaths", nullptr);
RNA_def_struct_sdna(srna, "UserDef");
RNA_def_struct_nested(brna, srna, "Preferences");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "File Paths", "Default paths for external files");
prop = RNA_def_property(srna, "show_hidden_files_datablocks", PROP_BOOLEAN, PROP_NONE);
@ -7057,7 +7010,6 @@ static void rna_def_userdef_apps(BlenderRNA *brna)
srna = RNA_def_struct(brna, "PreferencesApps", nullptr);
RNA_def_struct_sdna(srna, "UserDef");
RNA_def_struct_nested(brna, srna, "Preferences");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Apps", "Preferences that work only for apps");
prop = RNA_def_property(srna, "show_corner_split", PROP_BOOLEAN, PROP_NONE);
@ -7086,7 +7038,6 @@ static void rna_def_userdef_experimental(BlenderRNA *brna)
srna = RNA_def_struct(brna, "PreferencesExperimental", nullptr);
RNA_def_struct_sdna(srna, "UserDef_Experimental");
RNA_def_struct_nested(brna, srna, "Preferences");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Experimental", "Experimental features");
prop = RNA_def_property(srna, "use_undo_legacy", PROP_BOOLEAN, PROP_NONE);
@ -7218,7 +7169,6 @@ static void rna_def_userdef_addon_collection(BlenderRNA *brna, PropertyRNA *cpro
RNA_def_property_srna(cprop, "Addons");
srna = RNA_def_struct(brna, "Addons", nullptr);
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "User Add-ons", "Collection of add-ons");
func = RNA_def_function(srna, "new", "rna_userdef_addon_new");
@ -7244,7 +7194,6 @@ static void rna_def_userdef_autoexec_path_collection(BlenderRNA *brna, PropertyR
RNA_def_property_srna(cprop, "PathCompareCollection");
srna = RNA_def_struct(brna, "PathCompareCollection", nullptr);
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Paths Compare", "Collection of paths");
func = RNA_def_function(srna, "new", "rna_userdef_pathcompare_new");
@ -7275,7 +7224,6 @@ void RNA_def_userdef(BlenderRNA *brna)
srna = RNA_def_struct(brna, "Preferences", nullptr);
RNA_def_struct_sdna(srna, "UserDef");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Preferences", "Global preferences");
prop = RNA_def_property(srna, "active_section", PROP_ENUM, PROP_NONE);

View File

@ -565,14 +565,16 @@ const EnumPropertyItem rna_enum_wm_report_items[] = {
static wmOperator *rna_OperatorProperties_find_operator(PointerRNA *ptr)
{
if (ptr->owner_id == nullptr || GS(ptr->owner_id->name) != ID_WM) {
return nullptr;
}
wmWindowManager *wm = (wmWindowManager *)ptr->owner_id;
if (wm) {
IDProperty *properties = (IDProperty *)ptr->data;
for (wmOperator *op = static_cast<wmOperator *>(wm->operators.last); op; op = op->prev) {
if (op->properties == properties) {
return op;
}
IDProperty *properties = (IDProperty *)ptr->data;
for (wmOperator *op = static_cast<wmOperator *>(wm->operators.last); op; op = op->prev) {
if (op->properties == properties) {
return op;
}
}
@ -2041,7 +2043,6 @@ static void rna_def_operator(BlenderRNA *brna)
RNA_def_struct_idprops_func(srna, "rna_OperatorProperties_idprops");
RNA_def_struct_property_tags(srna, rna_enum_operator_property_tag_items);
RNA_def_struct_flag(srna, STRUCT_NO_DATABLOCK_IDPROPERTIES | STRUCT_NO_CONTEXT_WITHOUT_OWNER_ID);
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
}
static void rna_def_macro_operator(BlenderRNA *brna)
@ -2378,7 +2379,6 @@ static void rna_def_window_stereo3d(BlenderRNA *brna)
srna = RNA_def_struct(brna, "Stereo3dDisplay", nullptr);
RNA_def_struct_sdna(srna, "Stereo3dFormat");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Stereo 3D Display", "Settings for stereo 3D display");
prop = RNA_def_property(srna, "display_mode", PROP_ENUM, PROP_NONE);

View File

@ -212,7 +212,6 @@ static void rna_def_workspace_owner(BlenderRNA *brna)
srna = RNA_def_struct(brna, "wmOwnerID", nullptr);
RNA_def_struct_sdna(srna, "wmOwnerID");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Work Space UI Tag", "");
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
@ -262,7 +261,6 @@ static void rna_def_workspace_tool(BlenderRNA *brna)
srna = RNA_def_struct(brna, "WorkSpaceTool", nullptr);
RNA_def_struct_sdna(srna, "bToolRef");
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Work Space Tool", "");
prop = RNA_def_property(srna, "idname", PROP_STRING, PROP_NONE);

View File

@ -2088,7 +2088,6 @@ static void rna_def_xr_session_state(BlenderRNA *brna)
PropertyRNA *parm, *prop;
srna = RNA_def_struct(brna, "XrSessionState", nullptr);
RNA_def_struct_clear_flag(srna, STRUCT_UNDO);
RNA_def_struct_ui_text(srna, "Session State", "Runtime state information about the VR session");
func = RNA_def_function(srna, "is_running", "rna_XrSessionState_is_running");

View File

@ -45,6 +45,8 @@ set(SRC
intern/MOD_explode.cc
intern/MOD_fluid.cc
intern/MOD_grease_pencil_color.cc
intern/MOD_grease_pencil_dash.cc
intern/MOD_grease_pencil_lattice.cc
intern/MOD_grease_pencil_mirror.cc
intern/MOD_grease_pencil_noise.cc
intern/MOD_grease_pencil_offset.cc

View File

@ -82,6 +82,8 @@ extern ModifierTypeInfo modifierType_GreasePencilOffset;
extern ModifierTypeInfo modifierType_GreasePencilNoise;
extern ModifierTypeInfo modifierType_GreasePencilMirror;
extern ModifierTypeInfo modifierType_GreasePencilThickness;
extern ModifierTypeInfo modifierType_GreasePencilLattice;
extern ModifierTypeInfo modifierType_GreasePencilDash;
/* MOD_util.cc */

View File

@ -0,0 +1,535 @@
/* SPDX-FileCopyrightText: 2024 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup modifiers
*/
#include "BLI_index_range.hh"
#include "BLI_span.hh"
#include "BLI_string.h"
#include "BLI_string_utf8.h"
#include "DNA_defaults.h"
#include "DNA_modifier_types.h"
#include "BKE_curves.hh"
#include "BKE_geometry_set.hh"
#include "BKE_grease_pencil.hh"
#include "BKE_instances.hh"
#include "BKE_lib_query.hh"
#include "BKE_material.h"
#include "BKE_modifier.hh"
#include "BKE_screen.hh"
#include "BLO_read_write.hh"
#include "UI_interface.hh"
#include "UI_resources.hh"
#include "BLT_translation.h"
#include "WM_api.hh"
#include "WM_types.hh"
#include "RNA_access.hh"
#include "RNA_prototypes.h"
#include "MOD_grease_pencil_util.hh"
#include "MOD_modifiertypes.hh"
#include "MOD_ui_common.hh"
namespace blender {
static void init_data(ModifierData *md)
{
auto *dmd = reinterpret_cast<GreasePencilDashModifierData *>(md);
BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(dmd, modifier));
MEMCPY_STRUCT_AFTER(dmd, DNA_struct_default_get(GreasePencilDashModifierData), modifier);
modifier::greasepencil::init_influence_data(&dmd->influence, false);
GreasePencilDashModifierSegment *ds = DNA_struct_default_alloc(GreasePencilDashModifierSegment);
STRNCPY_UTF8(ds->name, DATA_("Segment"));
dmd->segments_array = ds;
dmd->segments_num = 1;
}
static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
{
const auto *dmd = reinterpret_cast<const GreasePencilDashModifierData *>(md);
auto *tmmd = reinterpret_cast<GreasePencilDashModifierData *>(target);
modifier::greasepencil::free_influence_data(&tmmd->influence);
BKE_modifier_copydata_generic(md, target, flag);
modifier::greasepencil::copy_influence_data(&dmd->influence, &tmmd->influence, flag);
tmmd->segments_array = static_cast<GreasePencilDashModifierSegment *>(
MEM_dupallocN(dmd->segments_array));
}
static void free_data(ModifierData *md)
{
auto *dmd = reinterpret_cast<GreasePencilDashModifierData *>(md);
modifier::greasepencil::free_influence_data(&dmd->influence);
MEM_SAFE_FREE(dmd->segments_array);
}
static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
{
auto *dmd = reinterpret_cast<GreasePencilDashModifierData *>(md);
modifier::greasepencil::foreach_influence_ID_link(&dmd->influence, ob, walk, user_data);
}
static bool is_disabled(const Scene * /*scene*/, ModifierData *md, bool /*use_render_params*/)
{
const auto *dmd = reinterpret_cast<GreasePencilDashModifierData *>(md);
/* Enable if at least one segment has non-zero length. */
for (const GreasePencilDashModifierSegment &dash_segment : dmd->segments()) {
if (dash_segment.dash + dash_segment.gap - 1 > 0) {
return false;
}
}
return true;
}
static int floored_modulo(const int a, const int b)
{
return a - math::floor(float(a) / float(b)) * b;
}
/* Combined segment info used by all strokes. */
struct PatternInfo {
int offset = 0;
int length = 0;
Array<IndexRange> segments;
Array<bool> cyclic;
Array<int> material;
Array<float> radius;
Array<float> opacity;
};
static PatternInfo get_pattern_info(const GreasePencilDashModifierData &dmd)
{
PatternInfo info;
for (const GreasePencilDashModifierSegment &dash_segment : dmd.segments()) {
info.length += dash_segment.dash + dash_segment.gap;
}
info.segments.reinitialize(dmd.segments().size());
info.cyclic.reinitialize(dmd.segments().size());
info.material.reinitialize(dmd.segments().size());
info.radius.reinitialize(dmd.segments().size());
info.opacity.reinitialize(dmd.segments().size());
info.offset = floored_modulo(dmd.dash_offset, info.length);
/* Store segments as ranges. */
IndexRange dash_range(0);
IndexRange gap_range(0);
for (const int i : dmd.segments().index_range()) {
const GreasePencilDashModifierSegment &dash_segment = dmd.segments()[i];
dash_range = gap_range.after(dash_segment.dash);
gap_range = dash_range.after(dash_segment.gap);
info.segments[i] = dash_range;
info.cyclic[i] = dash_segment.flag & MOD_GREASE_PENCIL_DASH_USE_CYCLIC;
info.material[i] = dash_segment.mat_nr;
info.radius[i] = dash_segment.radius;
info.opacity[i] = dash_segment.opacity;
}
return info;
}
/* Returns the segment covering the given index, including repetitions.*/
static int find_dash_segment(const PatternInfo &pattern_info, const int index)
{
const int repeat = index / pattern_info.length;
const int segments_num = pattern_info.segments.size();
const int local_index = index - repeat * pattern_info.length;
for (const int i : pattern_info.segments.index_range().drop_back(1)) {
const IndexRange segment = pattern_info.segments[i];
const IndexRange next_segment = pattern_info.segments[i + 1];
if (local_index >= segment.start() && local_index < next_segment.start()) {
return i + repeat * segments_num;
}
}
return segments_num - 1 + repeat * segments_num;
}
/**
* Iterate over all dash curves.
* \param fn: Function taking an index range of source points describing new curves.
* \note Point range can be larger than the source point range in case of cyclic curves.
*/
static void foreach_dash(const PatternInfo &pattern_info,
const IndexRange src_points,
const bool cyclic,
FunctionRef<void(IndexRange, bool, int, float, float)> fn)
{
const int points_num = src_points.size();
const int segments_num = pattern_info.segments.size();
const int first_segment = find_dash_segment(pattern_info, pattern_info.offset);
const int last_segment = find_dash_segment(pattern_info, pattern_info.offset + points_num - 1);
BLI_assert(first_segment < segments_num);
BLI_assert(last_segment >= first_segment);
const IndexRange all_segments = IndexRange(first_segment, last_segment - first_segment + 1);
for (const int i : all_segments) {
const int repeat = i / segments_num;
const int segment_index = i - repeat * segments_num;
const IndexRange range = pattern_info.segments[segment_index].shift(repeat *
pattern_info.length);
const int64_t point_shift = src_points.start() - pattern_info.offset;
const int64_t min_point = src_points.start();
const int64_t max_point = cyclic ? src_points.one_after_last() : src_points.last();
const int64_t start = std::clamp(range.start() + point_shift, min_point, max_point);
const int64_t end = std::clamp(range.one_after_last() + point_shift, min_point, max_point + 1);
IndexRange points(start, end - start);
if (!points.is_empty()) {
fn(points,
pattern_info.cyclic[segment_index],
pattern_info.material[segment_index],
pattern_info.radius[segment_index],
pattern_info.opacity[segment_index]);
}
}
}
static bke::CurvesGeometry create_dashes(const PatternInfo &pattern_info,
const bke::CurvesGeometry &src_curves,
const IndexMask &curves_mask)
{
const bke::AttributeAccessor src_attributes = src_curves.attributes();
const VArray<bool> src_cyclic = *src_attributes.lookup_or_default(
"cyclic", bke::AttrDomain::Curve, false);
const VArray<int> src_material = *src_attributes.lookup_or_default(
"material_index", bke::AttrDomain::Curve, 0);
const VArray<float> src_radius = *src_attributes.lookup<float>("radius", bke::AttrDomain::Point);
const VArray<float> src_opacity = *src_attributes.lookup<float>("opacity",
bke::AttrDomain::Point);
/* Count new curves and points. */
int dst_point_num = 0;
int dst_curve_num = 0;
curves_mask.foreach_index([&](const int64_t src_curve_i) {
const IndexRange src_points = src_curves.points_by_curve()[src_curve_i];
foreach_dash(pattern_info,
src_points,
src_cyclic[src_curve_i],
[&](const IndexRange copy_points,
bool /*cyclic*/,
int /*material*/,
float /*radius*/,
float /*opacity*/) {
dst_point_num += copy_points.size();
dst_curve_num += 1;
});
});
bke::CurvesGeometry dst_curves(dst_point_num, dst_curve_num);
bke::MutableAttributeAccessor dst_attributes = dst_curves.attributes_for_write();
bke::SpanAttributeWriter<bool> dst_cyclic = dst_attributes.lookup_or_add_for_write_span<bool>(
"cyclic", bke::AttrDomain::Curve);
bke::SpanAttributeWriter<int> dst_material = dst_attributes.lookup_or_add_for_write_span<int>(
"material_index", bke::AttrDomain::Curve);
bke::SpanAttributeWriter<float> dst_radius = dst_attributes.lookup_or_add_for_write_span<float>(
"radius", bke::AttrDomain::Point);
bke::SpanAttributeWriter<float> dst_opacity = dst_attributes.lookup_or_add_for_write_span<float>(
"opacity", bke::AttrDomain::Point);
/* Map each destination point and curve to its source. */
Array<int> src_point_indices(dst_point_num);
Array<int> src_curve_indices(dst_curve_num);
{
/* Start at curve offset and add points for each dash. */
IndexRange dst_point_range(0);
int dst_curve_i = 0;
auto add_dash_curve = [&](const int src_curve,
const IndexRange src_points,
const IndexRange copy_points,
bool cyclic,
int material,
float radius,
float opacity) {
dst_point_range = dst_point_range.after(copy_points.size());
dst_curves.offsets_for_write()[dst_curve_i] = dst_point_range.start();
if (src_points.contains(copy_points.last())) {
array_utils::fill_index_range(src_point_indices.as_mutable_span().slice(dst_point_range),
int(copy_points.start()));
}
else {
/* Cyclic curve. */
array_utils::fill_index_range(
src_point_indices.as_mutable_span().slice(dst_point_range.drop_back(1)),
int(copy_points.start()));
src_point_indices[dst_point_range.last()] = src_points.first();
}
src_curve_indices[dst_curve_i] = src_curve;
dst_cyclic.span[dst_curve_i] = cyclic;
dst_material.span[dst_curve_i] = material >= 0 ? material : src_material[src_curve];
for (const int i : dst_point_range) {
dst_radius.span[i] = src_radius[src_point_indices[i]] * radius;
dst_opacity.span[i] = src_opacity[src_point_indices[i]] * opacity;
}
++dst_curve_i;
};
curves_mask.foreach_index([&](const int64_t src_curve_i) {
const IndexRange src_points = src_curves.points_by_curve()[src_curve_i];
foreach_dash(pattern_info,
src_points,
src_cyclic[src_curve_i],
[&](const IndexRange copy_points,
bool cyclic,
int material,
float radius,
float opacity) {
add_dash_curve(
src_curve_i, src_points, copy_points, cyclic, material, radius, opacity);
});
});
if (dst_curve_i > 0) {
/* Last offset entry is total point count. */
dst_curves.offsets_for_write()[dst_curve_i] = dst_point_range.one_after_last();
}
}
bke::gather_attributes(src_attributes,
bke::AttrDomain::Point,
{},
{"radius", "opacity"},
src_point_indices,
dst_attributes);
bke::gather_attributes(src_attributes,
bke::AttrDomain::Curve,
{},
{"cyclic", "material_index"},
src_curve_indices,
dst_attributes);
dst_cyclic.finish();
dst_material.finish();
dst_radius.finish();
dst_opacity.finish();
dst_curves.update_curve_types();
return dst_curves;
}
static void modify_drawing(const GreasePencilDashModifierData &dmd,
const ModifierEvalContext &ctx,
const PatternInfo &pattern_info,
bke::greasepencil::Drawing &drawing)
{
const bke::CurvesGeometry &src_curves = drawing.strokes();
if (src_curves.curve_num == 0) {
return;
}
/* Selected source curves. */
IndexMaskMemory curve_mask_memory;
const IndexMask curves_mask = modifier::greasepencil::get_filtered_stroke_mask(
ctx.object, src_curves, dmd.influence, curve_mask_memory);
drawing.strokes_for_write() = create_dashes(pattern_info, src_curves, curves_mask);
drawing.tag_topology_changed();
}
static void modify_geometry_set(ModifierData *md,
const ModifierEvalContext *ctx,
bke::GeometrySet *geometry_set)
{
using bke::greasepencil::Drawing;
auto *dmd = reinterpret_cast<GreasePencilDashModifierData *>(md);
if (!geometry_set->has_grease_pencil()) {
return;
}
GreasePencil &grease_pencil = *geometry_set->get_grease_pencil_for_write();
const int frame = grease_pencil.runtime->eval_frame;
const PatternInfo pattern_info = get_pattern_info(*dmd);
IndexMaskMemory mask_memory;
const IndexMask layer_mask = modifier::greasepencil::get_filtered_layer_mask(
grease_pencil, dmd->influence, mask_memory);
const Vector<Drawing *> drawings = modifier::greasepencil::get_drawings_for_write(
grease_pencil, layer_mask, frame);
threading::parallel_for_each(
drawings, [&](Drawing *drawing) { modify_drawing(*dmd, *ctx, pattern_info, *drawing); });
}
static void panel_draw(const bContext *C, Panel *panel)
{
uiLayout *layout = panel->layout;
PointerRNA ob_ptr;
PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr);
auto *dmd = static_cast<GreasePencilDashModifierData *>(ptr->data);
uiLayoutSetPropSep(layout, true);
uiItemR(layout, ptr, "dash_offset", UI_ITEM_NONE, nullptr, ICON_NONE);
uiLayout *row = uiLayoutRow(layout, false);
uiLayoutSetPropSep(row, false);
uiTemplateList(row,
(bContext *)C,
"MOD_UL_grease_pencil_dash_modifier_segments",
"",
ptr,
"segments",
ptr,
"segment_active_index",
nullptr,
3,
10,
0,
1,
UI_TEMPLATE_LIST_FLAG_NONE);
uiLayout *col = uiLayoutColumn(row, false);
uiLayout *sub = uiLayoutColumn(col, true);
uiItemO(sub, "", ICON_ADD, "OBJECT_OT_grease_pencil_dash_modifier_segment_add");
uiItemO(sub, "", ICON_REMOVE, "OBJECT_OT_grease_pencil_dash_modifier_segment_remove");
uiItemS(col);
sub = uiLayoutColumn(col, true);
uiItemEnumO_string(
sub, "", ICON_TRIA_UP, "OBJECT_OT_grease_pencil_dash_modifier_segment_move", "type", "UP");
uiItemEnumO_string(sub,
"",
ICON_TRIA_DOWN,
"OBJECT_OT_grease_pencil_dash_modifier_segment_move",
"type",
"DOWN");
if (dmd->segment_active_index >= 0 && dmd->segment_active_index < dmd->segments_num) {
PointerRNA ds_ptr = RNA_pointer_create(ptr->owner_id,
&RNA_GreasePencilDashModifierSegment,
&dmd->segments()[dmd->segment_active_index]);
sub = uiLayoutColumn(layout, true);
uiItemR(sub, &ds_ptr, "dash", UI_ITEM_NONE, nullptr, ICON_NONE);
uiItemR(sub, &ds_ptr, "gap", UI_ITEM_NONE, nullptr, ICON_NONE);
sub = uiLayoutColumn(layout, false);
uiItemR(sub, &ds_ptr, "radius", UI_ITEM_NONE, nullptr, ICON_NONE);
uiItemR(sub, &ds_ptr, "opacity", UI_ITEM_NONE, nullptr, ICON_NONE);
uiItemR(sub, &ds_ptr, "material_index", UI_ITEM_NONE, nullptr, ICON_NONE);
uiItemR(sub, &ds_ptr, "use_cyclic", UI_ITEM_NONE, nullptr, ICON_NONE);
}
if (uiLayout *influence_panel = uiLayoutPanelProp(
C, layout, ptr, "open_influence_panel", "Influence"))
{
modifier::greasepencil::draw_layer_filter_settings(C, influence_panel, ptr);
modifier::greasepencil::draw_material_filter_settings(C, influence_panel, ptr);
}
modifier_panel_end(layout, ptr);
}
static void segment_list_item_draw(uiList * /*ui_list*/,
const bContext * /*C*/,
uiLayout *layout,
PointerRNA * /*idataptr*/,
PointerRNA *itemptr,
int /*icon*/,
PointerRNA * /*active_dataptr*/,
const char * /*active_propname*/,
int /*index*/,
int /*flt_flag*/)
{
uiLayout *row = uiLayoutRow(layout, true);
uiItemR(row, itemptr, "name", UI_ITEM_R_NO_BG, "", ICON_NONE);
}
static void panel_register(ARegionType *region_type)
{
modifier_panel_register(region_type, eModifierType_GreasePencilDash, panel_draw);
uiListType *list_type = static_cast<uiListType *>(
MEM_callocN(sizeof(uiListType), "Grease Pencil Dash modifier segments"));
STRNCPY(list_type->idname, "MOD_UL_grease_pencil_dash_modifier_segments");
list_type->draw_item = segment_list_item_draw;
WM_uilisttype_add(list_type);
}
static void blend_write(BlendWriter *writer, const ID * /*id_owner*/, const ModifierData *md)
{
const auto *dmd = reinterpret_cast<const GreasePencilDashModifierData *>(md);
BLO_write_struct(writer, GreasePencilDashModifierData, dmd);
modifier::greasepencil::write_influence_data(writer, &dmd->influence);
BLO_write_struct_array(
writer, GreasePencilDashModifierSegment, dmd->segments_num, dmd->segments_array);
}
static void blend_read(BlendDataReader *reader, ModifierData *md)
{
auto *dmd = reinterpret_cast<GreasePencilDashModifierData *>(md);
modifier::greasepencil::read_influence_data(reader, &dmd->influence);
BLO_read_data_address(reader, &dmd->segments_array);
}
} // namespace blender
ModifierTypeInfo modifierType_GreasePencilDash = {
/*idname*/ "GreasePencilDash",
/*name*/ N_("Dot Dash"),
/*struct_name*/ "GreasePencilDashModifierData",
/*struct_size*/ sizeof(GreasePencilDashModifierData),
/*srna*/ &RNA_GreasePencilDashModifierData,
/*type*/ ModifierTypeType::Nonconstructive,
/*flags*/ eModifierTypeFlag_AcceptsGreasePencil | eModifierTypeFlag_SupportsEditmode |
eModifierTypeFlag_EnableInEditmode | eModifierTypeFlag_SupportsMapping,
/*icon*/ ICON_MOD_DASH,
/*copy_data*/ blender::copy_data,
/*deform_verts*/ nullptr,
/*deform_matrices*/ nullptr,
/*deform_verts_EM*/ nullptr,
/*deform_matrices_EM*/ nullptr,
/*modify_mesh*/ nullptr,
/*modify_geometry_set*/ blender::modify_geometry_set,
/*init_data*/ blender::init_data,
/*required_data_mask*/ nullptr,
/*free_data*/ blender::free_data,
/*is_disabled*/ blender::is_disabled,
/*update_depsgraph*/ nullptr,
/*depends_on_time*/ nullptr,
/*depends_on_normals*/ nullptr,
/*foreach_ID_link*/ blender::foreach_ID_link,
/*foreach_tex_link*/ nullptr,
/*free_runtime_data*/ nullptr,
/*panel_register*/ blender::panel_register,
/*blend_write*/ blender::blend_write,
/*blend_read*/ blender::blend_read,
};
blender::Span<GreasePencilDashModifierSegment> GreasePencilDashModifierData::segments() const
{
return {this->segments_array, this->segments_num};
}
blender::MutableSpan<GreasePencilDashModifierSegment> GreasePencilDashModifierData::segments()
{
return {this->segments_array, this->segments_num};
}

View File

@ -0,0 +1,238 @@
/* SPDX-FileCopyrightText: 2024 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup modifiers
*/
#include "DNA_defaults.h"
#include "DNA_modifier_types.h"
#include "DNA_scene_types.h"
#include "BKE_colortools.hh"
#include "BKE_curves.hh"
#include "BKE_geometry_set.hh"
#include "BKE_grease_pencil.hh"
#include "BKE_lattice.hh"
#include "BKE_lib_query.hh"
#include "BKE_modifier.hh"
#include "BKE_screen.hh"
#include "BLO_read_write.hh"
#include "UI_interface.hh"
#include "UI_resources.hh"
#include "BLT_translation.h"
#include "WM_types.hh"
#include "RNA_access.hh"
#include "RNA_enum_types.hh"
#include "RNA_prototypes.h"
#include "MOD_grease_pencil_util.hh"
#include "MOD_modifiertypes.hh"
#include "MOD_ui_common.hh"
namespace blender {
using bke::greasepencil::Drawing;
using bke::greasepencil::FramesMapKey;
using bke::greasepencil::Layer;
static void init_data(ModifierData *md)
{
auto *lmd = reinterpret_cast<GreasePencilLatticeModifierData *>(md);
BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(lmd, modifier));
MEMCPY_STRUCT_AFTER(lmd, DNA_struct_default_get(GreasePencilLatticeModifierData), modifier);
modifier::greasepencil::init_influence_data(&lmd->influence, false);
}
static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
{
const auto *lmd = reinterpret_cast<const GreasePencilLatticeModifierData *>(md);
auto *tlmd = reinterpret_cast<GreasePencilLatticeModifierData *>(target);
modifier::greasepencil::free_influence_data(&tlmd->influence);
BKE_modifier_copydata_generic(md, target, flag);
modifier::greasepencil::copy_influence_data(&lmd->influence, &tlmd->influence, flag);
}
static void free_data(ModifierData *md)
{
auto *lmd = reinterpret_cast<GreasePencilLatticeModifierData *>(md);
modifier::greasepencil::free_influence_data(&lmd->influence);
}
static void foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
{
auto *lmd = reinterpret_cast<GreasePencilLatticeModifierData *>(md);
modifier::greasepencil::foreach_influence_ID_link(&lmd->influence, ob, walk, user_data);
walk(user_data, ob, (ID **)&lmd->object, IDWALK_CB_NOP);
}
static void update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
auto *lmd = reinterpret_cast<GreasePencilLatticeModifierData *>(md);
if (lmd->object != nullptr) {
DEG_add_object_relation(
ctx->node, lmd->object, DEG_OB_COMP_TRANSFORM, "Grease Pencil Lattice Modifier");
DEG_add_object_relation(
ctx->node, lmd->object, DEG_OB_COMP_GEOMETRY, "Grease Pencil Lattice Modifier");
}
DEG_add_depends_on_transform_relation(ctx->node, "Grease Pencil Lattice Modifier");
}
static bool is_disabled(const Scene * /*scene*/, ModifierData *md, bool /*use_render_params*/)
{
auto *lmd = reinterpret_cast<GreasePencilLatticeModifierData *>(md);
/* The object type check is only needed here in case we have a placeholder
* object assigned (because the library containing the lattice is missing).
*
* In other cases it should be impossible to have a type mismatch.
*/
return lmd->object == nullptr || lmd->object->type != OB_LATTICE;
}
static void modify_curves(ModifierData *md,
const ModifierEvalContext *ctx,
const LatticeDeformData &cache_data,
Drawing &drawing)
{
const auto *lmd = reinterpret_cast<GreasePencilLatticeModifierData *>(md);
bke::CurvesGeometry &curves = drawing.strokes_for_write();
IndexMaskMemory mask_memory;
const IndexMask curves_mask = modifier::greasepencil::get_filtered_stroke_mask(
ctx->object, curves, lmd->influence, mask_memory);
const OffsetIndices<int> points_by_curve = curves.points_by_curve();
MutableSpan<float3> positions = curves.positions_for_write();
const VArray<float> vgroup_weights = modifier::greasepencil::get_influence_vertex_weights(
curves, lmd->influence);
curves_mask.foreach_index(GrainSize(512), [&](const int64_t curve_i) {
const IndexRange points = points_by_curve[curve_i];
for (const int64_t point_i : points) {
const float weight = vgroup_weights[point_i];
BKE_lattice_deform_data_eval_co(const_cast<LatticeDeformData *>(&cache_data),
positions[point_i],
lmd->strength * weight);
}
});
drawing.tag_positions_changed();
}
static void modify_geometry_set(ModifierData *md,
const ModifierEvalContext *ctx,
bke::GeometrySet *geometry_set)
{
const auto *lmd = reinterpret_cast<GreasePencilLatticeModifierData *>(md);
BLI_assert(lmd->object != nullptr && lmd->object->type == OB_LATTICE);
LatticeDeformData *cache_data = BKE_lattice_deform_data_create(lmd->object, ctx->object);
if (!geometry_set->has_grease_pencil()) {
return;
}
GreasePencil &grease_pencil = *geometry_set->get_grease_pencil_for_write();
IndexMaskMemory mask_memory;
const IndexMask layer_mask = modifier::greasepencil::get_filtered_layer_mask(
grease_pencil, lmd->influence, mask_memory);
const int frame = grease_pencil.runtime->eval_frame;
const Vector<Drawing *> drawings = modifier::greasepencil::get_drawings_for_write(
grease_pencil, layer_mask, frame);
threading::parallel_for_each(
drawings, [&](Drawing *drawing) { modify_curves(md, ctx, *cache_data, *drawing); });
BKE_lattice_deform_data_destroy(cache_data);
}
static void panel_draw(const bContext *C, Panel *panel)
{
uiLayout *layout = panel->layout;
PointerRNA ob_ptr;
PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr);
uiLayoutSetPropSep(layout, true);
uiItemR(layout, ptr, "object", UI_ITEM_NONE, nullptr, ICON_NONE);
uiItemR(layout, ptr, "strength", UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
if (uiLayout *influence_panel = uiLayoutPanelProp(
C, layout, ptr, "open_influence_panel", "Influence"))
{
modifier::greasepencil::draw_layer_filter_settings(C, influence_panel, ptr);
modifier::greasepencil::draw_material_filter_settings(C, influence_panel, ptr);
modifier::greasepencil::draw_vertex_group_settings(C, influence_panel, ptr);
}
modifier_panel_end(layout, ptr);
}
static void panel_register(ARegionType *region_type)
{
modifier_panel_register(region_type, eModifierType_GreasePencilLattice, panel_draw);
}
static void blend_write(BlendWriter *writer, const ID * /*id_owner*/, const ModifierData *md)
{
const auto *lmd = reinterpret_cast<const GreasePencilLatticeModifierData *>(md);
BLO_write_struct(writer, GreasePencilLatticeModifierData, lmd);
modifier::greasepencil::write_influence_data(writer, &lmd->influence);
}
static void blend_read(BlendDataReader *reader, ModifierData *md)
{
auto *lmd = reinterpret_cast<GreasePencilLatticeModifierData *>(md);
modifier::greasepencil::read_influence_data(reader, &lmd->influence);
}
} // namespace blender
ModifierTypeInfo modifierType_GreasePencilLattice = {
/*idname*/ "GreasePencilLattice",
/*name*/ N_("Lattice"),
/*struct_name*/ "GreasePencilLatticeModifierData",
/*struct_size*/ sizeof(GreasePencilLatticeModifierData),
/*srna*/ &RNA_GreasePencilLatticeModifier,
/*type*/ ModifierTypeType::OnlyDeform,
/*flags*/ eModifierTypeFlag_AcceptsGreasePencil | eModifierTypeFlag_SupportsEditmode |
eModifierTypeFlag_EnableInEditmode | eModifierTypeFlag_SupportsMapping,
/*icon*/ ICON_MOD_LATTICE,
/*copy_data*/ blender::copy_data,
/*deform_verts*/ nullptr,
/*deform_matrices*/ nullptr,
/*deform_verts_EM*/ nullptr,
/*deform_matrices_EM*/ nullptr,
/*modify_mesh*/ nullptr,
/*modify_geometry_set*/ blender::modify_geometry_set,
/*init_data*/ blender::init_data,
/*required_data_mask*/ nullptr,
/*free_data*/ blender::free_data,
/*is_disabled*/ blender::is_disabled,
/*update_depsgraph*/ blender::update_depsgraph,
/*depends_on_time*/ nullptr,
/*depends_on_normals*/ nullptr,
/*foreach_ID_link*/ blender::foreach_ID_link,
/*foreach_tex_link*/ nullptr,
/*free_runtime_data*/ nullptr,
/*panel_register*/ blender::panel_register,
/*blend_write*/ blender::blend_write,
/*blend_read*/ blender::blend_read,
/*foreach_cache*/ nullptr,
};

View File

@ -161,10 +161,10 @@ static void modify_hardness(const GreasePencilOpacityModifierData &omd,
const IndexMask &curves_mask)
{
bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
bke::SpanAttributeWriter<float> hardnesses = attributes.lookup_for_write_span<float>("hardness");
if (!hardnesses) {
return;
}
bke::SpanAttributeWriter<float> hardnesses = attributes.lookup_or_add_for_write_span<float>(
"hardness",
bke::AttrDomain::Curve,
bke::AttributeInitVArray(VArray<float>::ForSingle(1.0f, curves.curve_num)));
curves_mask.foreach_index(GrainSize(512), [&](int64_t curve_i) {
hardnesses.span[curve_i] = std::clamp(

View File

@ -407,6 +407,7 @@ static void update_bakes_from_node_group(NodesModifierData &nmd)
new_bake.id = id;
new_bake.frame_start = 1;
new_bake.frame_end = 100;
new_bake.bake_mode = NODES_MODIFIER_BAKE_MODE_STILL;
}
}

View File

@ -279,5 +279,7 @@ void modifier_type_init(ModifierTypeInfo *types[])
INIT_TYPE(GreasePencilNoise);
INIT_TYPE(GreasePencilMirror);
INIT_TYPE(GreasePencilThickness);
INIT_TYPE(GreasePencilLattice);
INIT_TYPE(GreasePencilDash);
#undef INIT_TYPE
}