Mesh: Replace MLoop struct with generic attributes #104424

Merged
Hans Goudey merged 261 commits from refactor-mesh-corners-generic into main 2023-03-20 15:55:25 +01:00
196 changed files with 2389 additions and 1839 deletions
Showing only changes of commit d97ec1a320 - Show all commits

View File

@ -524,7 +524,7 @@ endif()
if(NOT APPLE)
option(WITH_CYCLES_DEVICE_HIP "Enable Cycles AMD HIP support" ON)
option(WITH_CYCLES_HIP_BINARIES "Build Cycles AMD HIP binaries" OFF)
set(CYCLES_HIP_BINARIES_ARCH gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 gfx1035 gfx1100 gfx1101 gfx1102 CACHE STRING "AMD HIP architectures to build binaries for")
set(CYCLES_HIP_BINARIES_ARCH gfx900 gfx906 gfx90c gfx902 gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 gfx1035 gfx1100 gfx1101 gfx1102 CACHE STRING "AMD HIP architectures to build binaries for")
mark_as_advanced(WITH_CYCLES_DEVICE_HIP)
mark_as_advanced(CYCLES_HIP_BINARIES_ARCH)
endif()
@ -625,8 +625,10 @@ mark_as_advanced(
# Vulkan
option(WITH_VULKAN_BACKEND "Enable Vulkan as graphics backend (only for development)" OFF)
option(WITH_VULKAN_GUARDEDALLOC "Use guardedalloc for host allocations done inside Vulkan (development option)" OFF)
mark_as_advanced(
WITH_VULKAN_BACKEND
WITH_VULKAN_GUARDEDALLOC
)
# Metal

View File

@ -398,7 +398,7 @@ endif
deps: .FORCE
@echo
@echo Configuring dependencies in \"$(DEPS_BUILD_DIR)\"
@echo Configuring dependencies in \"$(DEPS_BUILD_DIR)\", install to \"$(DEPS_INSTALL_DIR)\"
@cmake -H"$(DEPS_SOURCE_DIR)" \
-B"$(DEPS_BUILD_DIR)" \

View File

@ -487,7 +487,7 @@ BLENDER_VERSION_DOTS = "%d.%d" % (bpy.app.version[0], bpy.app.version[1])
if BLENDER_REVISION != "Unknown":
# SHA1 Git hash
BLENDER_VERSION_HASH = BLENDER_REVISION
BLENDER_VERSION_HASH_HTML_LINK = "<a href=https://developer.blender.org/rB%s>%s</a>" % (
BLENDER_VERSION_HASH_HTML_LINK = "<a href=https://projects.blender.org/blender/blender/commit/%s>%s</a>" % (
BLENDER_VERSION_HASH, BLENDER_VERSION_HASH,
)
BLENDER_VERSION_DATE = time.strftime("%d/%m/%Y", time.localtime(BLENDER_REVISION_TIMESTAMP))
@ -647,7 +647,7 @@ def undocumented_message(module_name, type_name, identifier):
module_name, type_name, identifier,
)
return "Undocumented, consider `contributing <https://developer.blender.org/T51061>`__."
return "Undocumented, consider `contributing <https://developer.blender.org/>`__."
def range_str(val):

View File

@ -1679,12 +1679,12 @@ class CyclesPreferences(bpy.types.AddonPreferences):
import sys
if sys.platform[:3] == "win":
driver_version = "21.Q4"
col.label(text="Requires AMD GPU with RDNA architecture", icon='BLANK1')
col.label(text="Requires AMD GPU with Vega or RDNA architecture", icon='BLANK1')
col.label(text=iface_("and AMD Radeon Pro %s driver or newer") % driver_version,
icon='BLANK1', translate=False)
elif sys.platform.startswith("linux"):
driver_version = "22.10"
col.label(text="Requires AMD GPU with RDNA architecture", icon='BLANK1')
col.label(text="Requires AMD GPU with Vega or RDNA architecture", icon='BLANK1')
col.label(text=iface_("and AMD driver version %s or newer") % driver_version, icon='BLANK1',
translate=False)
elif device_type == 'ONEAPI':

View File

@ -105,11 +105,12 @@ GPUShader *BlenderFallbackDisplayShader::bind(int width, int height)
/* Bind shader now to enable uniform assignment. */
GPU_shader_bind(shader_program_);
GPU_shader_uniform_int(shader_program_, image_texture_location_, 0);
int slot = 0;
GPU_shader_uniform_int_ex(shader_program_, image_texture_location_, 1, 1, &slot);
float size[2];
size[0] = width;
size[1] = height;
GPU_shader_uniform_vector(shader_program_, fullscreen_location_, 2, 1, size);
GPU_shader_uniform_float_ex(shader_program_, fullscreen_location_, 2, 1, size);
return shader_program_;
}

View File

@ -51,7 +51,7 @@ static inline bool hipSupportsDevice(const int hipDevId)
hipDeviceGetAttribute(&major, hipDeviceAttributeComputeCapabilityMajor, hipDevId);
hipDeviceGetAttribute(&minor, hipDeviceAttributeComputeCapabilityMinor, hipDevId);
return (major >= 10);
return (major >= 9);
}
CCL_NAMESPACE_END

View File

@ -886,7 +886,7 @@ int RenderScheduler::get_num_samples_during_navigation(int resolution_divider) c
{
/* Special trick for fast navigation: schedule multiple samples during fast navigation
* (which will prefer to use lower resolution to keep up with refresh rate). This gives more
* usable visual feedback for artists. There are a couple of tricks though. */
* usable visual feedback for artists. */
if (is_denoise_active_during_update()) {
/* When denoising is used during navigation prefer using a higher resolution with less samples
@ -896,25 +896,12 @@ int RenderScheduler::get_num_samples_during_navigation(int resolution_divider) c
return 1;
}
if (resolution_divider <= pixel_size_) {
/* When resolution divider is at or below pixel size, schedule one sample. This doesn't effect
* the sample count at this resolution division, but instead assists in the calculation of
* the resolution divider. */
return 1;
}
if (resolution_divider == pixel_size_ * 2) {
/* When resolution divider is the previous step to the final resolution, schedule two samples.
* This is so that rendering on lower resolution does not exceed time that it takes to render
* first sample at the full resolution. */
return 2;
}
/* Always render 4 samples, even if scene is configured for less.
* The idea here is to have enough information on the screen. Resolution divider of 2 allows us
* to have 4 time extra samples, so overall worst case timing is the same as the final resolution
* at one sample. */
return 4;
/* Schedule samples equal to the resolution divider up to a maximum of 4.
* The idea is to have enough information on the screen by increasing the sample count as the
* resolution is decreased. */
/* NOTE: Changing this formula will change the formula in
* `RenderScheduler::calculate_resolution_divider_for_time()`. */
return min(max(1, resolution_divider / pixel_size_), 4);
}
bool RenderScheduler::work_need_adaptive_filter() const
@ -1100,9 +1087,10 @@ void RenderScheduler::update_start_resolution_divider()
/* TODO(sergey): Need to add hysteresis to avoid resolution divider bouncing around when actual
* render time is somewhere on a boundary between two resolutions. */
/* Never increase resolution to higher than the pixel size (which is possible if the scene is
* simple and compute device is fast). */
start_resolution_divider_ = max(resolution_divider_for_update, pixel_size_);
/* Don't let resolution drop below the desired one. It's better to be slow than provide an
* unreadable viewport render. */
start_resolution_divider_ = min(resolution_divider_for_update,
default_start_resolution_divider_);
VLOG_WORK << "Calculated resolution divider is " << start_resolution_divider_;
}
@ -1187,24 +1175,24 @@ void RenderScheduler::check_time_limit_reached()
int RenderScheduler::calculate_resolution_divider_for_time(double desired_time, double actual_time)
{
/* TODO(sergey): There should a non-iterative analytical formula here. */
const double ratio_between_times = actual_time / desired_time;
int resolution_divider = 1;
/* We can pass `ratio_between_times` to `get_num_samples_during_navigation()` to get our
* navigation samples because the equation for calculating the resolution divider is as follows:
* `actual_time / desired_time = sqr(resolution_divider) / sample_count`.
* While `resolution_divider` is less than or equal to 4, `resolution_divider = sample_count`
* (This relationship is determined in `get_num_samples_during_navigation()`). With some
* substitution we end up with `actual_time / desired_time = resolution_divider` while the
* resolution divider is less than or equal to 4. Once the resolution divider increases above 4,
* the relationship of `actual_time / desired_time = resolution_divider` is no longer true,
* however the sample count retrieved from `get_num_samples_during_navigation()` is still
* accurate if we continue using this assumption. It should be noted that the interaction between
* `pixel_size`, sample count, and resolution divider are automatically accounted for and that's
* why `pixel_size` isn't included in any of the equations. */
const int navigation_samples = get_num_samples_during_navigation(
ceil_to_int(ratio_between_times));
/* This algorithm iterates through resolution dividers until a divider is found that achieves
* the desired render time. A limit of default_start_resolution_divider_ is put in place as the
* maximum resolution divider to avoid an unreadable viewport due to a low resolution.
* pre_resolution_division_samples and post_resolution_division_samples are used in this
* calculation to better predict the performance impact of changing resolution divisions as
* the sample count can also change between resolution divisions. */
while (actual_time > desired_time && resolution_divider < default_start_resolution_divider_) {
int pre_resolution_division_samples = get_num_samples_during_navigation(resolution_divider);
resolution_divider = resolution_divider * 2;
int post_resolution_division_samples = get_num_samples_during_navigation(resolution_divider);
actual_time /= 4.0 * pre_resolution_division_samples / post_resolution_division_samples;
}
return resolution_divider;
return ceil_to_int(sqrt(navigation_samples * ratio_between_times));
}
int calculate_resolution_divider_for_resolution(int width, int height, int resolution)

View File

@ -412,11 +412,12 @@ if(WITH_CYCLES_CUDA_BINARIES)
# warn for other versions
if((CUDA_VERSION STREQUAL "101") OR
(CUDA_VERSION STREQUAL "102") OR
(CUDA_VERSION_MAJOR STREQUAL "11"))
(CUDA_VERSION_MAJOR STREQUAL "11") OR
(CUDA_VERSION_MAJOR STREQUAL "12"))
else()
message(WARNING
"CUDA version ${CUDA_VERSION_MAJOR}.${CUDA_VERSION_MINOR} detected, "
"build may succeed but only CUDA 11, 10.2 and 10.1 have been tested")
"build may succeed but only CUDA 12, 11, 10.2 and 10.1 have been tested")
endif()
# build for each arch
@ -514,6 +515,16 @@ if(WITH_CYCLES_CUDA_BINARIES)
else()
message(STATUS "CUDA binaries for ${arch} require CUDA 10 or earlier, skipped.")
endif()
elseif(${arch} MATCHES ".*_3.")
if(DEFINED CUDA11_NVCC_EXECUTABLE)
set(cuda_nvcc_executable ${CUDA11_NVCC_EXECUTABLE})
set(cuda_toolkit_root_dir ${CUDA11_TOOLKIT_ROOT_DIR})
elseif("${CUDA_VERSION}" LESS 120) # Support for sm_35, sm_37 was removed in CUDA 12
set(cuda_nvcc_executable ${CUDA_NVCC_EXECUTABLE})
set(cuda_toolkit_root_dir ${CUDA_TOOLKIT_ROOT_DIR})
else()
message(STATUS "CUDA binaries for ${arch} require CUDA 11 or earlier, skipped.")
endif()
elseif(${arch} MATCHES ".*_7." AND "${CUDA_VERSION}" LESS 100)
message(STATUS "CUDA binaries for ${arch} require CUDA 10.0+, skipped.")
elseif(${arch} MATCHES ".*_8.")

View File

@ -573,7 +573,7 @@ void ShaderManager::device_update_common(Device * /*device*/,
kfilm->is_rec709 = is_rec709;
}
void ShaderManager::device_free_common(Device *, DeviceScene *dscene, Scene *scene)
void ShaderManager::device_free_common(Device * /*device*/, DeviceScene *dscene, Scene * /*scene*/)
{
dscene->shaders.free();
}

View File

@ -370,6 +370,7 @@ const bTheme U_theme_default = {
.clipping_border_3d = RGBA(0x3f3f3fff),
.bundle_solid = RGBA(0xc8c8c8ff),
.camera_path = RGBA(0x000000ff),
.camera_passepartout = RGBA(0x000000),
.gp_vertex_size = 3,
.gp_vertex = RGBA(0x000000ff),
.gp_vertex_select = RGBA(0xff8500ff),

View File

@ -30,7 +30,7 @@ def url_prefill_from_blender(*, addon_info=None):
"**Blender Version**\n"
)
fh.write(
"Broken: version: %s, branch: %s, commit date: %s %s, hash: `rB%s`\n" % (
"Broken: version: %s, branch: %s, commit date: %s %s, hash: `%s`\n" % (
bpy.app.version_string,
bpy.app.build_branch.decode('utf-8', 'replace'),
bpy.app.build_commit_date.decode('utf-8', 'replace'),

View File

@ -991,6 +991,7 @@ url_manual_mapping = (
("bpy.types.geometrynodeinputmeshfacearea*", "modeling/geometry_nodes/mesh/read/face_area.html#bpy-types-geometrynodeinputmeshfacearea"),
("bpy.types.geometrynodeinputsplinecyclic*", "modeling/geometry_nodes/curve/read/is_spline_cyclic.html#bpy-types-geometrynodeinputsplinecyclic"),
("bpy.types.geometrynodeinstancestopoints*", "modeling/geometry_nodes/instances/instances_to_points.html#bpy-types-geometrynodeinstancestopoints"),
("bpy.types.geometrynodematerialselection*", "modeling/geometry_nodes/material/material_selection.html#bpy-types-geometrynodematerialselection"),
("bpy.types.gpencillayer.viewlayer_render*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-viewlayer-render"),
("bpy.types.imagepaint.use_normal_falloff*", "sculpt_paint/brush/falloff.html#bpy-types-imagepaint-use-normal-falloff"),
("bpy.types.layercollection.hide_viewport*", "editors/outliner/interface.html#bpy-types-layercollection-hide-viewport"),
@ -2027,6 +2028,7 @@ url_manual_mapping = (
("bpy.ops.graph.equalize_handles*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-equalize-handles"),
("bpy.ops.mball.delete_metaelems*", "modeling/metas/editing.html#bpy-ops-mball-delete-metaelems"),
("bpy.ops.mball.reveal_metaelems*", "modeling/metas/properties.html#bpy-ops-mball-reveal-metaelems"),
("bpy.ops.mesh.bridge_edge_loops*", "modeling/meshes/editing/edge/bridge_edge_loops.html#bpy-ops-mesh-bridge-edge-loops"),
("bpy.ops.mesh.intersect_boolean*", "modeling/meshes/editing/face/intersect_boolean.html#bpy-ops-mesh-intersect-boolean"),
("bpy.ops.mesh.loop_multi_select*", "modeling/meshes/selecting/loops.html#bpy-ops-mesh-loop-multi-select"),
("bpy.ops.mesh.vert_connect_path*", "modeling/meshes/editing/vertex/connect_vertex_path.html#bpy-ops-mesh-vert-connect-path"),
@ -3021,6 +3023,7 @@ url_manual_mapping = (
("bpy.types.bakesettings*", "render/cycles/baking.html#bpy-types-bakesettings"),
("bpy.types.blendtexture*", "render/materials/legacy_textures/types/blend.html#bpy-types-blendtexture"),
("bpy.types.brush.height*", "sculpt_paint/sculpting/tools/layer.html#bpy-types-brush-height"),
("bpy.types.brush.jitter*", "sculpt_paint/brush/stroke.html#bpy-types-brush-jitter"),
("bpy.types.castmodifier*", "modeling/modifiers/deform/cast.html#bpy-types-castmodifier"),
("bpy.types.curve.offset*", "modeling/curves/properties/geometry.html#bpy-types-curve-offset"),
("bpy.types.geometrynode*", "modeling/geometry_nodes/index.html#bpy-types-geometrynode"),

View File

@ -6345,9 +6345,8 @@ def km_node_link_modal_map(_params):
return keymap
# Fallback for gizmos that don't have custom a custom key-map.
def km_generic_gizmo(_params):
keymap = (
"Generic Gizmo",

View File

@ -1249,7 +1249,31 @@ class WM_OT_doc_view_manual(Operator):
# XXX, for some reason all RNA ID's are stored lowercase
# Adding case into all ID's isn't worth the hassle so force lowercase.
rna_id = rna_id.lower()
# NOTE: `fnmatch` in Python is slow as it translate the string to a regular-expression
# which needs to be compiled (as of Python 3.11), this is slow enough to cause a noticeable
# delay when opening manual links (approaching half a second).
#
# Resolve by matching characters that have a special meaning to `fnmatch`.
# The characters that can occur as the first special character are `*?[`.
# If any of these are used we must let `fnmatch` run its own matching logic.
# However, in most cases a literal prefix is used making it considerably faster
# to do a simple `startswith` check before performing a full match.
# An alternative solution could be to use `fnmatch` from C which is significantly
# faster than Python's, see !104581 for details.
import re
re_match_non_special = re.compile(r"^[^?\*\[]+").match
for pattern, url_suffix in url_mapping:
# Simple optimization, makes a big difference (over 50x speedup).
# Even when `non_special.end()` is zero (resulting in an empty-string),
# the `startswith` check succeeds so there is no need to check for an empty match.
non_special = re_match_non_special(pattern)
if non_special is None or not rna_id.startswith(pattern[:non_special.end()]):
continue
# End simple optimization.
if fnmatchcase(rna_id, pattern):
if verbose:
print(" match found: '%s' --> '%s'" % (pattern, url_suffix))

View File

@ -2319,21 +2319,15 @@ class USERPREF_PT_experimental_new_features(ExperimentalPanel, Panel):
bl_label = "New Features"
def draw(self, context):
self._draw_items(context,
(({"property": "use_sculpt_tools_tilt"},
("blender/blender/issues/82877",
"#82877")),
({"property": "use_extended_asset_browser"},
("blender/blender/projects/10",
"Pipeline, Assets & IO Project Page")),
({"property": "use_override_templates"},
("blender/blender/issues/73318",
"Milestone 4")),
({"property": "use_new_volume_nodes"},
("blender/blender/issues/103248",
"#103248")),
),
)
self._draw_items(
context, (
({"property": "use_sculpt_tools_tilt"}, ("blender/blender/issues/82877", "#82877")),
({"property": "use_extended_asset_browser"},
("blender/blender/projects/10", "Pipeline, Assets & IO Project Page")),
({"property": "use_override_templates"}, ("blender/blender/issues/73318", "Milestone 4")),
({"property": "use_new_volume_nodes"}, ("blender/blender/issues/103248", "#103248")),
),
)
class USERPREF_PT_experimental_prototypes(ExperimentalPanel, Panel):

View File

@ -23,11 +23,15 @@ struct ID;
namespace blender::asset_system {
class AssetLibrary;
class AssetRepresentation {
AssetIdentifier identifier_;
/** Indicate if this is a local or external asset, and as such, which of the union members below
* should be used. */
const bool is_local_id_ = false;
/** Asset library that owns this asset representation. */
const AssetLibrary *owner_asset_library_;
struct ExternalAsset {
std::string name;
@ -44,10 +48,13 @@ class AssetRepresentation {
/** Constructs an asset representation for an external ID. The asset will not be editable. */
AssetRepresentation(AssetIdentifier &&identifier,
StringRef name,
std::unique_ptr<AssetMetaData> metadata);
std::unique_ptr<AssetMetaData> metadata,
const AssetLibrary &owner_asset_library);
/** Constructs an asset representation for an ID stored in the current file. This makes the asset
* local and fully editable. */
AssetRepresentation(AssetIdentifier &&identifier, ID &id);
AssetRepresentation(AssetIdentifier &&identifier,
ID &id,
const AssetLibrary &owner_asset_library);
AssetRepresentation(AssetRepresentation &&other);
/* Non-copyable type. */
AssetRepresentation(const AssetRepresentation &other) = delete;
@ -65,6 +72,7 @@ class AssetRepresentation {
AssetMetaData &get_metadata() const;
/** Returns if this asset is stored inside this current file, and as such fully editable. */
bool is_local_id() const;
const AssetLibrary &owner_asset_library() const;
};
} // namespace blender::asset_system

View File

@ -169,13 +169,14 @@ AssetRepresentation &AssetLibrary::add_external_asset(StringRef relative_asset_p
std::unique_ptr<AssetMetaData> metadata)
{
AssetIdentifier identifier = asset_identifier_from_library(relative_asset_path);
return asset_storage_->add_external_asset(std::move(identifier), name, std::move(metadata));
return asset_storage_->add_external_asset(
std::move(identifier), name, std::move(metadata), *this);
}
AssetRepresentation &AssetLibrary::add_local_id_asset(StringRef relative_asset_path, ID &id)
{
AssetIdentifier identifier = asset_identifier_from_library(relative_asset_path);
return asset_storage_->add_local_id_asset(std::move(identifier), id);
return asset_storage_->add_local_id_asset(std::move(identifier), id, *this);
}
bool AssetLibrary::remove_asset(AssetRepresentation &asset)

View File

@ -17,15 +17,24 @@ namespace blender::asset_system {
AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier,
StringRef name,
std::unique_ptr<AssetMetaData> metadata)
: identifier_(identifier), is_local_id_(false), external_asset_()
std::unique_ptr<AssetMetaData> metadata,
const AssetLibrary &owner_asset_library)
: identifier_(identifier),
is_local_id_(false),
owner_asset_library_(&owner_asset_library),
external_asset_()
{
external_asset_.name = name;
external_asset_.metadata_ = std::move(metadata);
}
AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier, ID &id)
: identifier_(identifier), is_local_id_(true), local_asset_id_(&id)
AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier,
ID &id,
const AssetLibrary &owner_asset_library)
: identifier_(identifier),
is_local_id_(true),
owner_asset_library_(&owner_asset_library),
local_asset_id_(&id)
{
if (!id.asset_data) {
throw std::invalid_argument("Passed ID is not an asset");
@ -75,6 +84,11 @@ bool AssetRepresentation::is_local_id() const
return is_local_id_;
}
const AssetLibrary &AssetRepresentation::owner_asset_library() const
{
return *owner_asset_library_;
}
} // namespace blender::asset_system
using namespace blender;

View File

@ -15,18 +15,21 @@
namespace blender::asset_system {
AssetRepresentation &AssetStorage::add_local_id_asset(AssetIdentifier &&identifier, ID &id)
AssetRepresentation &AssetStorage::add_local_id_asset(AssetIdentifier &&identifier,
ID &id,
const AssetLibrary &owner_asset_library)
{
return *local_id_assets_.lookup_key_or_add(
std::make_unique<AssetRepresentation>(std::move(identifier), id));
std::make_unique<AssetRepresentation>(std::move(identifier), id, owner_asset_library));
}
AssetRepresentation &AssetStorage::add_external_asset(AssetIdentifier &&identifier,
StringRef name,
std::unique_ptr<AssetMetaData> metadata)
std::unique_ptr<AssetMetaData> metadata,
const AssetLibrary &owner_asset_library)
{
return *external_assets_.lookup_key_or_add(
std::make_unique<AssetRepresentation>(std::move(identifier), name, std::move(metadata)));
return *external_assets_.lookup_key_or_add(std::make_unique<AssetRepresentation>(
std::move(identifier), name, std::move(metadata), owner_asset_library));
}
bool AssetStorage::remove_asset(AssetRepresentation &asset)

View File

@ -35,9 +35,12 @@ class AssetStorage {
/** See #AssetLibrary::add_external_asset(). */
AssetRepresentation &add_external_asset(AssetIdentifier &&identifier,
StringRef name,
std::unique_ptr<AssetMetaData> metadata);
std::unique_ptr<AssetMetaData> metadata,
const AssetLibrary &owner_asset_library);
/** See #AssetLibrary::add_external_asset(). */
AssetRepresentation &add_local_id_asset(AssetIdentifier &&identifier, ID &id);
AssetRepresentation &add_local_id_asset(AssetIdentifier &&identifier,
ID &id,
const AssetLibrary &owner_asset_library);
/** See #AssetLibrary::remove_asset(). */
bool remove_asset(AssetRepresentation &asset);

View File

@ -137,6 +137,7 @@ bool CustomData_has_referenced(const struct CustomData *data);
* implemented for mloopuv/mloopcol, for now.
*/
void CustomData_data_copy_value(int type, const void *source, void *dest);
void CustomData_data_set_default_value(int type, void *elem);
/**
* Mixes the "value" (e.g. mloopuv uv or mloopcol colors) from one block into
@ -304,8 +305,8 @@ void CustomData_copy_data(const struct CustomData *source,
int source_index,
int dest_index,
int count);
void CustomData_copy_data_layer(const CustomData *source,
CustomData *dest,
void CustomData_copy_data_layer(const struct CustomData *source,
struct CustomData *dest,
int src_layer_index,
int dst_layer_index,
int src_index,
@ -444,7 +445,7 @@ void *CustomData_get_layer_named_for_write(CustomData *data,
int totelem);
int CustomData_get_offset(const struct CustomData *data, int type);
int CustomData_get_offset_named(const CustomData *data, int type, const char *name);
int CustomData_get_offset_named(const struct CustomData *data, int type, const char *name);
int CustomData_get_n_offset(const struct CustomData *data, int type, int n);
int CustomData_get_layer_index(const struct CustomData *data, int type);
@ -506,6 +507,8 @@ void CustomData_clear_layer_flag(struct CustomData *data, int type, int flag);
void CustomData_bmesh_set_default(struct CustomData *data, void **block);
void CustomData_bmesh_free_block(struct CustomData *data, void **block);
void CustomData_bmesh_alloc_block(struct CustomData *data, void **block);
/**
* Same as #CustomData_bmesh_free_block but zero the memory rather than freeing.
*/
@ -517,24 +520,6 @@ void CustomData_bmesh_free_block_data_exclude_by_type(struct CustomData *data,
void *block,
eCustomDataMask mask_exclude);
/**
* Copy custom data to/from layers as in mesh/derived-mesh, to edit-mesh
* blocks of data. the CustomData's must not be compatible.
*
* \param use_default_init: initializes data which can't be copied,
* typically you'll want to use this if the BM_xxx create function
* is called with BM_CREATE_SKIP_CD flag
*/
void CustomData_to_bmesh_block(const struct CustomData *source,
struct CustomData *dest,
int src_index,
void **dest_block,
bool use_default_init);
void CustomData_from_bmesh_block(const struct CustomData *source,
struct CustomData *dest,
void *src_block,
int dest_index);
/**
* Query info over types.
*/
@ -743,7 +728,7 @@ void CustomData_blend_write(BlendWriter *writer,
void CustomData_blend_read(struct BlendDataReader *reader, struct CustomData *data, int count);
size_t CustomData_get_elem_size(struct CustomDataLayer *layer);
size_t CustomData_get_elem_size(const struct CustomDataLayer *layer);
#ifndef NDEBUG
struct DynStr;

View File

@ -36,10 +36,10 @@ struct PropertyRNA;
/* Data Management */
/**
* Remove the given NLA strip from the NLA track it occupies, free the strip's data,
* and the strip itself.
* Frees the given NLA strip, and calls #BKE_nlastrip_remove_and_free to
* remove and free all children strips.
*/
void BKE_nlastrip_free(ListBase *strips, struct NlaStrip *strip, bool do_id_user);
void BKE_nlastrip_free(struct NlaStrip *strip, bool do_id_user);
/**
* Remove the given NLA track from the set of NLA tracks, free the track's data,
* and the track itself.
@ -94,10 +94,22 @@ void BKE_nla_tracks_copy_from_adt(struct Main *bmain,
struct NlaTrack *BKE_nlatrack_add(struct AnimData *adt,
struct NlaTrack *prev,
bool is_liboverride);
/**
* Create a NLA Strip referencing the given Action.
*/
struct NlaStrip *BKE_nlastrip_new(struct bAction *act);
/*
* Removes the given NLA strip from the list of strips provided.
*/
void BKE_nlastrip_remove(ListBase *strips, struct NlaStrip *strip);
/*
* Removes the given NLA strip from the list of strips provided, and frees it's memory.
*/
void BKE_nlastrip_remove_and_free(ListBase *strips, struct NlaStrip *strip, const bool do_id_user);
/**
* Add new NLA-strip to the top of the NLA stack - i.e.
* into the last track if space, or a new one otherwise.
@ -139,13 +151,9 @@ void BKE_nlastrips_sort_strips(ListBase *strips);
void BKE_nlastrips_add_strip_unsafe(ListBase *strips, struct NlaStrip *strip);
/**
* \brief NULL checks incoming strip and verifies no overlap / invalid
* configuration against other strips in NLA Track.
*
* \param strips:
* \param strip:
* \return true
* \return false
* NULL checks incoming strip and verifies no overlap / invalid
* configuration against other strips in NLA Track before calling
* #BKE_nlastrips_add_strip_unsafe.
*/
bool BKE_nlastrips_add_strip(ListBase *strips, struct NlaStrip *strip);
@ -215,11 +223,16 @@ bool BKE_nlatrack_has_space(struct NlaTrack *nlt, float start, float end);
void BKE_nlatrack_sort_strips(struct NlaTrack *nlt);
/**
* Add the given NLA-Strip to the given NLA-Track, assuming that it
* isn't currently attached to another one.
* Add the given NLA-Strip to the given NLA-Track.
* Calls #BKE_nlastrips_add_strip to check if strip can be added.
*/
bool BKE_nlatrack_add_strip(struct NlaTrack *nlt, struct NlaStrip *strip, bool is_liboverride);
/**
* Remove the NLA-Strip from the given NLA-Track.
*/
void BKE_nlatrack_remove_strip(struct NlaTrack *track, struct NlaStrip *strip);
/**
* Get the extents of the given NLA-Track including gaps between strips,
* returning whether this succeeded or not

View File

@ -249,8 +249,8 @@ set(SRC
intern/particle_distribute.c
intern/particle_system.c
intern/pbvh.cc
intern/pbvh_colors.cc
intern/pbvh_bmesh.cc
intern/pbvh_colors.cc
intern/pbvh_pixels.cc
intern/pbvh_uv_islands.cc
intern/pointcache.c

View File

@ -120,7 +120,7 @@ static void fill_mesh_topology(const int vert_offset,
}
}
const bool has_caps = fill_caps && !main_cyclic && profile_cyclic;
const bool has_caps = fill_caps && !main_cyclic && profile_cyclic && profile_point_num > 2;
if (has_caps) {
const int poly_num = main_segment_num * profile_segment_num;
const int cap_loop_offset = loop_offset + poly_num * 4;
@ -270,7 +270,7 @@ static ResultOffsets calculate_result_offsets(const CurvesInfo &info, const bool
const int profile_point_num = profile_offsets.size(i_profile);
const int profile_segment_num = curves::segments_num(profile_point_num, profile_cyclic);
const bool has_caps = fill_caps && !main_cyclic && profile_cyclic;
const bool has_caps = fill_caps && !main_cyclic && profile_cyclic && profile_point_num > 2;
const int tube_face_num = main_segment_num * profile_segment_num;
vert_offset += main_point_num * profile_point_num;

View File

@ -3653,7 +3653,7 @@ void CustomData_bmesh_free_block_data(CustomData *data, void *block)
}
}
static void CustomData_bmesh_alloc_block(CustomData *data, void **block)
void CustomData_bmesh_alloc_block(CustomData *data, void **block)
{
if (*block) {
CustomData_bmesh_free_block(data, block);
@ -3688,19 +3688,23 @@ void CustomData_bmesh_free_block_data_exclude_by_type(CustomData *data,
}
}
static void CustomData_bmesh_set_default_n(CustomData *data, void **block, const int n)
void CustomData_data_set_default_value(const int type, void *elem)
{
int offset = data->layers[n].offset;
const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[n].type);
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
if (typeInfo->set_default_value) {
typeInfo->set_default_value(POINTER_OFFSET(*block, offset), 1);
typeInfo->set_default_value(elem, 1);
}
else {
memset(POINTER_OFFSET(*block, offset), 0, typeInfo->size);
memset(elem, 0, typeInfo->size);
}
}
static void CustomData_bmesh_set_default_n(CustomData *data, void **block, const int n)
{
const int offset = data->layers[n].offset;
CustomData_data_set_default_value(data->layers[n].type, POINTER_OFFSET(*block, offset));
}
void CustomData_bmesh_set_default(CustomData *data, void **block)
{
if (*block == nullptr) {
@ -3890,8 +3894,8 @@ void CustomData_data_copy_value(int type, const void *source, void *dest)
return;
}
if (typeInfo->copyvalue) {
typeInfo->copyvalue(source, dest, CDT_MIX_NOMIX, 0.0f);
if (typeInfo->copy) {
typeInfo->copy(source, dest, 1);
}
else {
memcpy(dest, source, typeInfo->size);
@ -4066,115 +4070,6 @@ void CustomData_bmesh_interp(CustomData *data,
}
}
void CustomData_to_bmesh_block(const CustomData *source,
CustomData *dest,
int src_index,
void **dest_block,
bool use_default_init)
{
if (*dest_block == nullptr) {
CustomData_bmesh_alloc_block(dest, dest_block);
}
/* copies a layer at a time */
int dest_i = 0;
for (int src_i = 0; src_i < source->totlayer; src_i++) {
/* find the first dest layer with type >= the source type
* (this should work because layers are ordered by type)
*/
while (dest_i < dest->totlayer && dest->layers[dest_i].type < source->layers[src_i].type) {
if (use_default_init) {
CustomData_bmesh_set_default_n(dest, dest_block, dest_i);
}
dest_i++;
}
/* if there are no more dest layers, we're done */
if (dest_i >= dest->totlayer) {
break;
}
/* if we found a matching layer, copy the data */
if (dest->layers[dest_i].type == source->layers[src_i].type) {
int offset = dest->layers[dest_i].offset;
const void *src_data = source->layers[src_i].data;
void *dest_data = POINTER_OFFSET(*dest_block, offset);
const LayerTypeInfo *typeInfo = layerType_getInfo(dest->layers[dest_i].type);
const size_t src_offset = size_t(src_index) * typeInfo->size;
if (typeInfo->copy) {
typeInfo->copy(POINTER_OFFSET(src_data, src_offset), dest_data, 1);
}
else {
memcpy(dest_data, POINTER_OFFSET(src_data, src_offset), typeInfo->size);
}
/* if there are multiple source & dest layers of the same type,
* we don't want to copy all source layers to the same dest, so
* increment dest_i
*/
dest_i++;
}
}
if (use_default_init) {
while (dest_i < dest->totlayer) {
CustomData_bmesh_set_default_n(dest, dest_block, dest_i);
dest_i++;
}
}
}
void CustomData_from_bmesh_block(const CustomData *source,
CustomData *dest,
void *src_block,
int dest_index)
{
/* copies a layer at a time */
int dest_i = 0;
for (int src_i = 0; src_i < source->totlayer; src_i++) {
if (source->layers[src_i].flag & CD_FLAG_NOCOPY) {
continue;
}
/* find the first dest layer with type >= the source type
* (this should work because layers are ordered by type)
*/
while (dest_i < dest->totlayer && dest->layers[dest_i].type < source->layers[src_i].type) {
dest_i++;
}
/* if there are no more dest layers, we're done */
if (dest_i >= dest->totlayer) {
return;
}
/* if we found a matching layer, copy the data */
if (dest->layers[dest_i].type == source->layers[src_i].type) {
const LayerTypeInfo *typeInfo = layerType_getInfo(dest->layers[dest_i].type);
int offset = source->layers[src_i].offset;
const void *src_data = POINTER_OFFSET(src_block, offset);
void *dst_data = POINTER_OFFSET(dest->layers[dest_i].data,
size_t(dest_index) * typeInfo->size);
if (typeInfo->copy) {
typeInfo->copy(src_data, dst_data, 1);
}
else {
memcpy(dst_data, src_data, typeInfo->size);
}
/* if there are multiple source & dest layers of the same type,
* we don't want to copy all source layers to the same dest, so
* increment dest_i
*/
dest_i++;
}
}
}
void CustomData_file_write_info(int type, const char **r_struct_name, int *r_struct_num)
{
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
@ -5307,7 +5202,7 @@ eCustomDataType cpp_type_to_custom_data_type(const blender::CPPType &type)
} // namespace blender::bke
size_t CustomData_get_elem_size(CustomDataLayer *layer)
size_t CustomData_get_elem_size(const CustomDataLayer *layer)
{
return LAYERTYPEINFO[layer->type].size;
}

View File

@ -61,7 +61,7 @@ static void nla_tweakmode_find_active(const ListBase /* NlaTrack */ *nla_tracks,
/* Freeing ------------------------------------------- */
void BKE_nlastrip_free(ListBase *strips, NlaStrip *strip, bool do_id_user)
void BKE_nlastrip_free(NlaStrip *strip, const bool do_id_user)
{
NlaStrip *cs, *csn;
@ -73,7 +73,7 @@ void BKE_nlastrip_free(ListBase *strips, NlaStrip *strip, bool do_id_user)
/* free child-strips */
for (cs = strip->strips.first; cs; cs = csn) {
csn = cs->next;
BKE_nlastrip_free(&strip->strips, cs, do_id_user);
BKE_nlastrip_remove_and_free(&strip->strips, cs, do_id_user);
}
/* remove reference to action */
@ -81,10 +81,6 @@ void BKE_nlastrip_free(ListBase *strips, NlaStrip *strip, bool do_id_user)
id_us_min(&strip->act->id);
}
/* free remapping info */
// if (strip->remap)
// BKE_animremap_free();
/* free own F-Curves */
BKE_fcurves_free(&strip->fcurves);
@ -92,12 +88,7 @@ void BKE_nlastrip_free(ListBase *strips, NlaStrip *strip, bool do_id_user)
free_fmodifiers(&strip->modifiers);
/* free the strip itself */
if (strips) {
BLI_freelinkN(strips, strip);
}
else {
MEM_freeN(strip);
}
MEM_freeN(strip);
}
void BKE_nlatrack_free(ListBase *tracks, NlaTrack *nlt, bool do_id_user)
@ -112,7 +103,7 @@ void BKE_nlatrack_free(ListBase *tracks, NlaTrack *nlt, bool do_id_user)
/* free strips */
for (strip = nlt->strips.first; strip; strip = stripn) {
stripn = strip->next;
BKE_nlastrip_free(&nlt->strips, strip, do_id_user);
BKE_nlastrip_remove_and_free(&nlt->strips, strip, do_id_user);
}
/* free NLA track itself now */
@ -875,7 +866,7 @@ void BKE_nlastrips_clear_metastrip(ListBase *strips, NlaStrip *strip)
}
/* free the meta-strip now */
BKE_nlastrip_free(strips, strip, true);
BKE_nlastrip_remove_and_free(strips, strip, true);
}
void BKE_nlastrips_clear_metas(ListBase *strips, bool only_sel, bool only_temp)
@ -1190,6 +1181,12 @@ bool BKE_nlatrack_add_strip(NlaTrack *nlt, NlaStrip *strip, const bool is_libove
return BKE_nlastrips_add_strip(&nlt->strips, strip);
}
void BKE_nlatrack_remove_strip(NlaTrack *track, NlaStrip *strip)
{
BLI_assert(track);
BKE_nlastrip_remove(&track->strips, strip);
}
bool BKE_nlatrack_get_bounds(NlaTrack *nlt, float bounds[2])
{
NlaStrip *strip;
@ -1318,6 +1315,18 @@ NlaStrip *BKE_nlastrip_find_active(NlaTrack *nlt)
return nlastrip_find_active(&nlt->strips);
}
void BKE_nlastrip_remove(ListBase *strips, NlaStrip *strip)
{
BLI_assert(strips);
BLI_remlink(strips, strip);
}
void BKE_nlastrip_remove_and_free(ListBase *strips, NlaStrip *strip, const bool do_id_user)
{
BKE_nlastrip_remove(strips, strip);
BKE_nlastrip_free(strip, do_id_user);
}
void BKE_nlastrip_set_active(AnimData *adt, NlaStrip *strip)
{
NlaTrack *nlt;

View File

@ -1,6 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2023 Blender Foundation. All rights reserved. */
#include "BLI_listbase.h"
#include "BKE_nla.h"
#include "DNA_anim_types.h"
@ -20,19 +22,19 @@ TEST(nla_strip, BKE_nlastrip_recalculate_blend)
strip.start = 1;
strip.end = 10;
/* Scaling a strip up doesn't affect the blend in/out value */
/* Scaling a strip up doesn't affect the blend in/out value. */
strip.end = 20;
BKE_nlastrip_recalculate_blend(&strip);
EXPECT_FLOAT_EQ(strip.blendin, 4.0);
EXPECT_FLOAT_EQ(strip.blendout, 5.0);
/* Scaling a strip down affects the blend-in value before the blend-out value */
/* Scaling a strip down affects the blend-in value before the blend-out value. */
strip.end = 7;
BKE_nlastrip_recalculate_blend(&strip);
EXPECT_FLOAT_EQ(strip.blendin, 1.0);
EXPECT_FLOAT_EQ(strip.blendout, 5.0);
/* Scaling a strip down to nothing updates the blend in/out values accordingly */
/* Scaling a strip down to nothing updates the blend in/out values accordingly. */
strip.end = 1.1;
BKE_nlastrip_recalculate_blend(&strip);
EXPECT_FLOAT_EQ(strip.blendin, 0.0);
@ -63,4 +65,30 @@ TEST(nla_strip, BKE_nlastrips_add_strip)
EXPECT_TRUE(BKE_nlastrips_add_strip(&strips, &strip2));
}
TEST(nla_track, BKE_nlatrack_remove_strip)
{
NlaTrack track{};
ListBase strips{};
NlaStrip strip1{};
strip1.start = 0;
strip1.end = 10;
NlaStrip strip2{};
strip2.start = 11;
strip2.end = 20;
// Add NLA strips to the NLATrack.
BKE_nlastrips_add_strip(&strips, &strip1);
BKE_nlastrips_add_strip(&strips, &strip2);
track.strips = strips;
// ensure we have 2 strips in the track.
EXPECT_EQ(2, BLI_listbase_count(&track.strips));
BKE_nlatrack_remove_strip(&track, &strip2);
EXPECT_EQ(1, BLI_listbase_count(&track.strips));
// ensure the correct strip was removed.
EXPECT_EQ(-1, BLI_findindex(&track.strips, &strip2));
}
} // namespace blender::bke::tests

View File

@ -265,7 +265,7 @@ static DupliObject *make_dupli(const DupliContext *ctx,
/* Store geometry set data for attribute lookup in innermost to outermost
* order, copying only non-null entries to save space. */
const int max_instance = sizeof(dob->instance_data) / sizeof(void *);
const int max_instance = ARRAY_SIZE(dob->instance_data);
int next_instance = 0;
if (geometry != nullptr) {
dob->instance_idx[next_instance] = int(instance_index);
@ -1820,7 +1820,7 @@ static bool find_geonode_attribute_rgba(const DupliObject *dupli,
using namespace blender;
/* Loop over layers from innermost to outermost. */
for (const int i : IndexRange(sizeof(dupli->instance_data) / sizeof(void *))) {
for (const int i : IndexRange(ARRAY_SIZE(dupli->instance_data))) {
/* Skip non-geonode layers. */
if (dupli->instance_data[i] == nullptr) {
continue;

View File

@ -1704,7 +1704,7 @@ static void rigidbody_update_sim_ob(Depsgraph *depsgraph, Object *ob, RigidBodyO
}
}
/* Make transformed objects temporarily kinmatic
/* Make transformed objects temporarily kinematic
* so that they can be moved by the user during simulation. */
if (is_selected && (G.moving & G_TRANSFORM_OBJ)) {
RB_body_set_kinematic_state(rbo->shared->physics_object, true);

View File

@ -352,7 +352,7 @@ struct StaticOrHeapIntStorage {
static void static_or_heap_storage_init(StaticOrHeapIntStorage *storage)
{
storage->static_storage_len = sizeof(storage->static_storage) / sizeof(*storage->static_storage);
storage->static_storage_len = ARRAY_SIZE(storage->static_storage);
storage->heap_storage = nullptr;
storage->heap_storage_len = 0;
}

View File

@ -538,13 +538,14 @@ void tracking_cameraIntrinscisOptionsFromTracking(
void tracking_trackingCameraFromIntrinscisOptions(
MovieTracking *tracking, const libmv_CameraIntrinsicsOptions *camera_intrinsics_options)
{
float aspy = 1.0f / tracking->camera.pixel_aspect;
MovieTrackingCamera *camera = &tracking->camera;
camera->focal = camera_intrinsics_options->focal_length;
/* NOTE: The image size stored in the `camera_intrinsics_options` is aspect-ratio corrected,
* so there is no need to "un-apply" it from the principal point. */
const float principal_px[2] = {camera_intrinsics_options->principal_point_x,
camera_intrinsics_options->principal_point_y / (double)aspy};
camera_intrinsics_options->principal_point_y};
tracking_principal_point_pixel_to_normalized(principal_px,
camera_intrinsics_options->image_width,

View File

@ -97,8 +97,9 @@ MINLINE float saacos(float fac);
MINLINE float saasin(float fac);
MINLINE float sasqrt(float fac);
MINLINE float interpf(float a, float b, float t);
MINLINE double interpd(double a, double b, double t);
/* Compute linear interpolation (lerp) between origin and target. */
MINLINE float interpf(float target, float origin, float t);
MINLINE double interpd(double target, double origin, double t);
MINLINE float ratiof(float min, float max, float pos);
MINLINE double ratiod(double min, double max, double pos);

View File

@ -806,6 +806,10 @@ extern bool BLI_memory_is_zero(const void *arr, size_t arr_size);
{ \
return a = (_enum_type)(uint64_t(a) & uint64_t(b)); \
} \
inline _enum_type &operator^=(_enum_type &a, _enum_type b) \
{ \
return a = (_enum_type)(uint64_t(a) ^ uint64_t(b)); \
} \
} /* extern "C++" */
#else

View File

@ -281,10 +281,10 @@ set(SRC
BLI_math_solvers.h
BLI_math_statistics.h
BLI_math_time.h
BLI_math_vector_mpq_types.hh
BLI_math_vector_types.hh
BLI_math_vector.h
BLI_math_vector.hh
BLI_math_vector_mpq_types.hh
BLI_math_vector_types.hh
BLI_memarena.h
BLI_memblock.h
BLI_memiter.h
@ -490,13 +490,13 @@ if(WITH_GTESTS)
tests/BLI_math_bits_test.cc
tests/BLI_math_color_test.cc
tests/BLI_math_geom_test.cc
tests/BLI_math_matrix_types_test.cc
tests/BLI_math_matrix_test.cc
tests/BLI_math_matrix_types_test.cc
tests/BLI_math_rotation_test.cc
tests/BLI_math_solvers_test.cc
tests/BLI_math_time_test.cc
tests/BLI_math_vector_types_test.cc
tests/BLI_math_vector_test.cc
tests/BLI_math_vector_types_test.cc
tests/BLI_memiter_test.cc
tests/BLI_memory_utils_test.cc
tests/BLI_mesh_boolean_test.cc

View File

@ -612,6 +612,25 @@ TEST(string, StrFormatIntegerUnits)
EXPECT_STREQ("-2B", size_str);
}
TEST(string, StringNLen)
{
EXPECT_EQ(0, BLI_strnlen("", 0));
EXPECT_EQ(0, BLI_strnlen("", 1));
EXPECT_EQ(0, BLI_strnlen("", 100));
EXPECT_EQ(0, BLI_strnlen("x", 0));
EXPECT_EQ(1, BLI_strnlen("x", 1));
EXPECT_EQ(1, BLI_strnlen("x", 100));
// ü is \xc3\xbc
EXPECT_EQ(2, BLI_strnlen("ü", 100));
EXPECT_EQ(0, BLI_strnlen("this is a longer string", 0));
EXPECT_EQ(1, BLI_strnlen("this is a longer string", 1));
EXPECT_EQ(5, BLI_strnlen("this is a longer string", 5));
EXPECT_EQ(47, BLI_strnlen("This string writes about an agent without name.", 100));
}
struct WordInfo {
WordInfo() = default;
WordInfo(int start, int end) : start(start), end(end)

View File

@ -85,6 +85,7 @@
#include "BLI_span.hh"
#include "BLI_string_ref.hh"
#include "BLI_task.hh"
#include "BLI_vector.hh"
#include "BKE_attribute.hh"
#include "BKE_customdata.h"
@ -110,6 +111,7 @@ using blender::IndexRange;
using blender::MutableSpan;
using blender::Span;
using blender::StringRef;
using blender::Vector;
static char bm_edge_flag_from_mflag(const short mflag)
{
@ -168,6 +170,63 @@ static BMFace *bm_face_create_from_mpoly(BMesh &bm,
return BM_face_create(&bm, verts.data(), edges.data(), size, nullptr, BM_CREATE_SKIP_CD);
}
struct MeshToBMeshLayerInfo {
eCustomDataType type;
/** The layer's position in the BMesh element's data block. */
int bmesh_offset;
/** The mesh's #CustomDataLayer::data. When null, the BMesh block is set to its default value. */
const void *mesh_data;
/** The size of every custom data element. */
size_t elem_size;
};
/**
* Calculate the necessary information to copy every data layer from the Mesh to the BMesh.
*/
static Vector<MeshToBMeshLayerInfo> mesh_to_bm_copy_info_calc(const CustomData &mesh_data,
CustomData &bm_data)
{
Vector<MeshToBMeshLayerInfo> infos;
std::array<int, CD_NUMTYPES> per_type_index;
per_type_index.fill(0);
for (const int i : IndexRange(bm_data.totlayer)) {
const CustomDataLayer &bm_layer = bm_data.layers[i];
const eCustomDataType type = eCustomDataType(bm_layer.type);
const int mesh_layer_index =
bm_layer.name[0] == '\0' ?
CustomData_get_layer_index_n(&mesh_data, type, per_type_index[type]) :
CustomData_get_named_layer_index(&mesh_data, type, bm_layer.name);
MeshToBMeshLayerInfo info{};
info.type = type;
info.bmesh_offset = bm_layer.offset;
info.mesh_data = (mesh_layer_index == -1) ? nullptr : mesh_data.layers[mesh_layer_index].data;
info.elem_size = CustomData_get_elem_size(&bm_layer);
infos.append(info);
per_type_index[type]++;
}
return infos;
}
static void mesh_attributes_copy_to_bmesh_block(CustomData &data,
const Span<MeshToBMeshLayerInfo> copy_info,
const int mesh_index,
BMHeader &header)
{
CustomData_bmesh_alloc_block(&data, &header.data);
for (const MeshToBMeshLayerInfo &info : copy_info) {
if (info.mesh_data) {
CustomData_data_copy_value(info.type,
POINTER_OFFSET(info.mesh_data, info.elem_size * mesh_index),
POINTER_OFFSET(header.data, info.bmesh_offset));
}
else {
CustomData_data_set_default_value(info.type, POINTER_OFFSET(header.data, info.bmesh_offset));
}
}
}
void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshParams *params)
{
if (!me) {
@ -263,6 +322,11 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
CustomData_bmesh_merge(&mesh_ldata, &bm->ldata, mask.lmask, CD_SET_DEFAULT, bm, BM_LOOP);
}
const Vector<MeshToBMeshLayerInfo> vert_info = mesh_to_bm_copy_info_calc(mesh_vdata, bm->vdata);
const Vector<MeshToBMeshLayerInfo> edge_info = mesh_to_bm_copy_info_calc(mesh_edata, bm->edata);
const Vector<MeshToBMeshLayerInfo> poly_info = mesh_to_bm_copy_info_calc(mesh_pdata, bm->pdata);
const Vector<MeshToBMeshLayerInfo> loop_info = mesh_to_bm_copy_info_calc(mesh_ldata, bm->ldata);
/* -------------------------------------------------------------------- */
/* Shape Key */
int tot_shape_keys = 0;
@ -397,8 +461,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
copy_v3_v3(v->no, vert_normals[i]);
}
/* Copy Custom Data */
CustomData_to_bmesh_block(&mesh_vdata, &bm->vdata, i, &v->head.data, true);
mesh_attributes_copy_to_bmesh_block(bm->vdata, vert_info, i, v->head);
/* Set shape key original index. */
if (cd_shape_keyindex_offset != -1) {
@ -436,8 +499,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
BM_elem_flag_enable(e, BM_ELEM_SMOOTH);
}
/* Copy Custom Data */
CustomData_to_bmesh_block(&mesh_edata, &bm->edata, i, &e->head.data, true);
mesh_attributes_copy_to_bmesh_block(bm->edata, edge_info, i, e->head);
}
if (is_new) {
bm->elem_index_dirty &= ~BM_EDGE; /* Added in order, clear dirty flag. */
@ -499,12 +561,11 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar
/* Don't use 'j' since we may have skipped some faces, hence some loops. */
BM_elem_index_set(l_iter, totloops++); /* set_ok */
/* Save index of corresponding corner. */
CustomData_to_bmesh_block(&mesh_ldata, &bm->ldata, j++, &l_iter->head.data, true);
mesh_attributes_copy_to_bmesh_block(bm->ldata, loop_info, j, l_iter->head);
j++;
} while ((l_iter = l_iter->next) != l_first);
/* Copy Custom Data */
CustomData_to_bmesh_block(&mesh_pdata, &bm->pdata, i, &f->head.data, true);
mesh_attributes_copy_to_bmesh_block(bm->pdata, poly_info, i, f->head);
if (params->calc_face_normal) {
BM_face_normal_update(f);
@ -1008,6 +1069,66 @@ static void convert_bmesh_selection_flags_to_mesh_attributes(BMesh &bm,
}
}
struct BMeshToMeshLayerInfo {
eCustomDataType type;
/** The layer's position in the BMesh element's data block. */
int bmesh_offset;
/** The mesh's #CustomDataLayer::data. When null, the BMesh block is set to its default value. */
void *mesh_data;
/** The size of every custom data element. */
size_t elem_size;
};
/**
* Calculate the necessary information to copy every data layer from the BMesh to the Mesh.
*/
static Vector<BMeshToMeshLayerInfo> bm_to_mesh_copy_info_calc(const CustomData &bm_data,
CustomData &mesh_data)
{
Vector<BMeshToMeshLayerInfo> infos;
std::array<int, CD_NUMTYPES> per_type_index;
per_type_index.fill(0);
for (const int i : IndexRange(mesh_data.totlayer)) {
const CustomDataLayer &mesh_layer = mesh_data.layers[i];
const eCustomDataType type = eCustomDataType(mesh_layer.type);
const int bm_layer_index =
mesh_layer.name[0] == '\0' ?
CustomData_get_layer_index_n(&bm_data, type, per_type_index[type]) :
CustomData_get_named_layer_index(&bm_data, type, mesh_layer.name);
/* Skip layers that don't exist in `bm_data` or are explicitly set to not be
* copied. The layers are either set separately or shouldn't exist on the mesh. */
if (bm_layer_index == -1) {
continue;
}
const CustomDataLayer &bm_layer = bm_data.layers[bm_layer_index];
if (bm_layer.flag & CD_FLAG_NOCOPY) {
continue;
}
BMeshToMeshLayerInfo info{};
info.type = type;
info.bmesh_offset = bm_layer.offset;
info.mesh_data = mesh_layer.data;
info.elem_size = CustomData_get_elem_size(&mesh_layer);
infos.append(info);
per_type_index[type]++;
}
return infos;
}
static void bmesh_block_copy_to_mesh_attributes(const Span<BMeshToMeshLayerInfo> copy_info,
const int mesh_index,
const void *block)
{
for (const BMeshToMeshLayerInfo &info : copy_info) {
CustomData_data_copy_value(info.type,
POINTER_OFFSET(block, info.bmesh_offset),
POINTER_OFFSET(info.mesh_data, info.elem_size * mesh_index));
}
}
void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params)
{
using namespace blender;
@ -1021,6 +1142,8 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
const int ototvert = me->totvert;
blender::Vector<int> ldata_layers_marked_nocopy;
/* Free custom data. */
CustomData_free(&me->vdata, me->totvert);
CustomData_free(&me->edata, me->totedge);
@ -1051,9 +1174,17 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
&bm->ldata, CD_PROP_BOOL, BKE_uv_map_edge_select_name_get(layer_name, sub_layer_name));
int pin_layer_index = CustomData_get_named_layer_index(
&bm->ldata, CD_PROP_BOOL, BKE_uv_map_pin_name_get(layer_name, sub_layer_name));
int vertsel_offset = bm->ldata.layers[vertsel_layer_index].offset;
int edgesel_offset = bm->ldata.layers[edgesel_layer_index].offset;
int pin_offset = bm->ldata.layers[pin_layer_index].offset;
/* If ever the uv map associated bool layers become optional in BMesh as well (like in Mesh)
* this assert needs to be removed. For now it is a bug if they don't exist. */
BLI_assert(vertsel_layer_index >= 0 && edgesel_layer_index >= 0 && pin_layer_index >= 0);
int vertsel_offset = vertsel_layer_index >= 0 ? bm->ldata.layers[vertsel_layer_index].offset :
-1;
int edgesel_offset = edgesel_layer_index >= 0 ? bm->ldata.layers[edgesel_layer_index].offset :
-1;
int pin_offset = pin_layer_index >= 0 ? bm->ldata.layers[pin_layer_index].offset : -1;
bool need_vertsel = false;
bool need_edgesel = false;
bool need_pin = false;
@ -1061,10 +1192,20 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
BMIter liter;
BMLoop *l;
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
need_vertsel |= BM_ELEM_CD_GET_BOOL(l, vertsel_offset);
need_edgesel |= BM_ELEM_CD_GET_BOOL(l, edgesel_offset);
need_pin |= BM_ELEM_CD_GET_BOOL(l, pin_offset);
if (vertsel_layer_index >= 0) {
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
need_vertsel |= BM_ELEM_CD_GET_BOOL(l, vertsel_offset);
}
}
if (edgesel_layer_index >= 0) {
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
need_edgesel |= BM_ELEM_CD_GET_BOOL(l, edgesel_offset);
}
}
if (pin_layer_index) {
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
need_pin |= BM_ELEM_CD_GET_BOOL(l, pin_offset);
}
}
}
@ -1073,18 +1214,21 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
}
else {
bm->ldata.layers[vertsel_layer_index].flag |= CD_FLAG_NOCOPY;
ldata_layers_marked_nocopy.append(vertsel_layer_index);
}
if (need_edgesel) {
bm->ldata.layers[edgesel_layer_index].flag &= ~CD_FLAG_NOCOPY;
}
else {
bm->ldata.layers[edgesel_layer_index].flag |= CD_FLAG_NOCOPY;
ldata_layers_marked_nocopy.append(edgesel_layer_index);
}
if (need_pin) {
bm->ldata.layers[pin_layer_index].flag &= ~CD_FLAG_NOCOPY;
}
else {
bm->ldata.layers[pin_layer_index].flag |= CD_FLAG_NOCOPY;
ldata_layers_marked_nocopy.append(pin_layer_index);
}
}
@ -1097,6 +1241,16 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
CustomData_copy(&bm->pdata, &me->pdata, mask.pmask, CD_SET_DEFAULT, me->totpoly);
}
const Vector<BMeshToMeshLayerInfo> vert_info = bm_to_mesh_copy_info_calc(bm->vdata, me->vdata);
const Vector<BMeshToMeshLayerInfo> edge_info = bm_to_mesh_copy_info_calc(bm->edata, me->edata);
const Vector<BMeshToMeshLayerInfo> poly_info = bm_to_mesh_copy_info_calc(bm->pdata, me->pdata);
const Vector<BMeshToMeshLayerInfo> loop_info = bm_to_mesh_copy_info_calc(bm->ldata, me->ldata);
/* Clear the CD_FLAG_NOCOPY flags for the layers they were temporarily set on */
for (const int i : ldata_layers_marked_nocopy) {
bm->ldata.layers[i].flag &= ~CD_FLAG_NOCOPY;
}
CustomData_add_layer_named(
&me->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, nullptr, me->totvert, "position");
CustomData_add_layer(&me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, me->totedge);
@ -1133,8 +1287,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
BM_elem_index_set(v, i); /* set_inline */
/* Copy over custom-data. */
CustomData_from_bmesh_block(&bm->vdata, &me->vdata, v->head.data, i);
bmesh_block_copy_to_mesh_attributes(vert_info, i, v->head.data);
i++;
@ -1160,8 +1313,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
BM_elem_index_set(e, i); /* set_inline */
/* Copy over custom-data. */
CustomData_from_bmesh_block(&bm->edata, &me->edata, e->head.data, i);
bmesh_block_copy_to_mesh_attributes(edge_info, i, e->head.data);
i++;
BM_CHECK_ELEMENT(e);
@ -1190,8 +1342,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
corner_verts[j] = BM_elem_index_get(l_iter->v);
corner_edges[j] = BM_elem_index_get(l_iter->e);
/* Copy over custom-data. */
CustomData_from_bmesh_block(&bm->ldata, &me->ldata, l_iter->head.data, j);
bmesh_block_copy_to_mesh_attributes(loop_info, j, l_iter->head.data);
j++;
BM_CHECK_ELEMENT(l_iter);
@ -1203,8 +1354,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
me->act_face = i;
}
/* Copy over custom-data. */
CustomData_from_bmesh_block(&bm->pdata, &me->pdata, f->head.data, i);
bmesh_block_copy_to_mesh_attributes(poly_info, i, f->head.data);
i++;
BM_CHECK_ELEMENT(f);
@ -1413,12 +1563,13 @@ static void bm_to_mesh_verts(const BMesh &bm,
MutableSpan<bool> select_vert,
MutableSpan<bool> hide_vert)
{
const Vector<BMeshToMeshLayerInfo> info = bm_to_mesh_copy_info_calc(bm.vdata, mesh.vdata);
MutableSpan<float3> dst_vert_positions = mesh.vert_positions_for_write();
threading::parallel_for(dst_vert_positions.index_range(), 1024, [&](const IndexRange range) {
for (const int vert_i : range) {
const BMVert &src_vert = *bm_verts[vert_i];
copy_v3_v3(dst_vert_positions[vert_i], src_vert.co);
CustomData_from_bmesh_block(&bm.vdata, &mesh.vdata, src_vert.head.data, vert_i);
bmesh_block_copy_to_mesh_attributes(info, vert_i, src_vert.head.data);
}
if (!select_vert.is_empty()) {
for (const int vert_i : range) {
@ -1440,6 +1591,7 @@ static void bm_to_mesh_edges(const BMesh &bm,
MutableSpan<bool> hide_edge,
MutableSpan<bool> sharp_edge)
{
const Vector<BMeshToMeshLayerInfo> info = bm_to_mesh_copy_info_calc(bm.edata, mesh.edata);
MutableSpan<MEdge> dst_edges = mesh.edges_for_write();
threading::parallel_for(dst_edges.index_range(), 512, [&](const IndexRange range) {
for (const int edge_i : range) {
@ -1448,7 +1600,7 @@ static void bm_to_mesh_edges(const BMesh &bm,
dst_edge.v1 = BM_elem_index_get(src_edge.v1);
dst_edge.v2 = BM_elem_index_get(src_edge.v2);
dst_edge.flag = bm_edge_flag_to_mflag(&src_edge);
CustomData_from_bmesh_block(&bm.edata, &mesh.edata, src_edge.head.data, edge_i);
bmesh_block_copy_to_mesh_attributes(info, edge_i, src_edge.head.data);
}
if (!select_edge.is_empty()) {
for (const int edge_i : range) {
@ -1475,6 +1627,7 @@ static void bm_to_mesh_faces(const BMesh &bm,
MutableSpan<bool> hide_poly,
MutableSpan<int> material_indices)
{
const Vector<BMeshToMeshLayerInfo> info = bm_to_mesh_copy_info_calc(bm.pdata, mesh.pdata);
MutableSpan<MPoly> dst_polys = mesh.polys_for_write();
threading::parallel_for(dst_polys.index_range(), 1024, [&](const IndexRange range) {
for (const int face_i : range) {
@ -1483,7 +1636,7 @@ static void bm_to_mesh_faces(const BMesh &bm,
dst_poly.totloop = src_face.len;
dst_poly.loopstart = BM_elem_index_get(BM_FACE_FIRST_LOOP(&src_face));
dst_poly.flag = bm_face_flag_to_mflag(&src_face);
CustomData_from_bmesh_block(&bm.pdata, &mesh.pdata, src_face.head.data, face_i);
bmesh_block_copy_to_mesh_attributes(info, face_i, src_face.head.data);
}
if (!select_poly.is_empty()) {
for (const int face_i : range) {
@ -1505,14 +1658,16 @@ static void bm_to_mesh_faces(const BMesh &bm,
static void bm_to_mesh_loops(const BMesh &bm, const Span<const BMLoop *> bm_loops, Mesh &mesh)
{
const Vector<BMeshToMeshLayerInfo> info = bm_to_mesh_copy_info_calc(bm.ldata, mesh.ldata);
MutableSpan<int> dst_corner_verts = mesh.corner_verts_for_write();
MutableSpan<int> dst_corner_edges = mesh.corner_edges_for_write();
threading::parallel_for(bm_loops.index_range(), 1024, [&](const IndexRange range) {
threading::parallel_for(dst_loops.index_range(), 1024, [&](const IndexRange range) {
for (const int loop_i : range) {
const BMLoop &src_loop = *bm_loops[loop_i];
MLoop &dst_loop = dst_loops[loop_i];
dst_corner_verts[loop_i] = BM_elem_index_get(src_loop.v);
dst_corner_edges[loop_i] = BM_elem_index_get(src_loop.e);
CustomData_from_bmesh_block(&bm.ldata, &mesh.ldata, src_loop.head.data, loop_i);
bmesh_block_copy_to_mesh_attributes(info, loop_i, src_loop.head.data);
}
});
}

View File

@ -1197,8 +1197,8 @@ static void bmw_FaceLoopWalker_begin(BMWalker *walker, void *data)
{
BMwFaceLoopWalker *lwalk, owalk, *owalk_pt;
BMEdge *e = data;
/* BMesh *bm = walker->bm; */ /* UNUSED */
/* int fcount = BM_edge_face_count(e); */ /* UNUSED */
// BMesh *bm = walker->bm; /* UNUSED */
// int fcount = BM_edge_face_count(e); /* UNUSED */
if (!bmw_FaceLoopWalker_edge_begins_loop(walker, e)) {
return;

View File

@ -1183,7 +1183,7 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
f = BM_face_create_verts(bm, varr, j, es->l->f, BM_CREATE_NOP, true);
BMO_face_flag_enable(bm, f, ELE_NEW);
/* Copy for loop data, otherwise UVs and vcols are no good.
/* Copy for loop data, otherwise UVs and vertex-colors are no good.
* tiny speedup here we could be more clever and copy from known adjacent data
* also - we could attempt to interpolate the loop data,
* this would be much slower but more useful too. */

View File

@ -41,10 +41,10 @@ static float *parallel_reduction_dispatch(Context &context,
GPUTexture *reduced_texture = context.texture_pool().acquire(reduced_size, format);
GPU_memory_barrier(GPU_BARRIER_TEXTURE_FETCH);
const int texture_image_unit = GPU_shader_get_texture_binding(shader, "input_tx");
const int texture_image_unit = GPU_shader_get_sampler_binding(shader, "input_tx");
GPU_texture_bind(texture_to_reduce, texture_image_unit);
const int image_unit = GPU_shader_get_texture_binding(shader, "output_img");
const int image_unit = GPU_shader_get_sampler_binding(shader, "output_img");
GPU_texture_image_bind(reduced_texture, image_unit);
GPU_compute_dispatch(shader, reduced_size.x, reduced_size.y, 1);

View File

@ -135,7 +135,7 @@ void MorphologicalDistanceFeatherWeights::compute_distance_falloffs(int type, in
void MorphologicalDistanceFeatherWeights::bind_weights_as_texture(GPUShader *shader,
const char *texture_name) const
{
const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name);
const int texture_image_unit = GPU_shader_get_sampler_binding(shader, texture_name);
GPU_texture_bind(weights_texture_, texture_image_unit);
}
@ -147,7 +147,7 @@ void MorphologicalDistanceFeatherWeights::unbind_weights_as_texture() const
void MorphologicalDistanceFeatherWeights::bind_distance_falloffs_as_texture(
GPUShader *shader, const char *texture_name) const
{
const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name);
const int texture_image_unit = GPU_shader_get_sampler_binding(shader, texture_name);
GPU_texture_bind(distance_falloffs_texture_, texture_image_unit);
}

View File

@ -103,7 +103,7 @@ SymmetricBlurWeights::~SymmetricBlurWeights()
void SymmetricBlurWeights::bind_as_texture(GPUShader *shader, const char *texture_name) const
{
const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name);
const int texture_image_unit = GPU_shader_get_sampler_binding(shader, texture_name);
GPU_texture_bind(texture_, texture_image_unit);
}

View File

@ -81,7 +81,7 @@ SymmetricSeparableBlurWeights::~SymmetricSeparableBlurWeights()
void SymmetricSeparableBlurWeights::bind_as_texture(GPUShader *shader,
const char *texture_name) const
{
const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name);
const int texture_image_unit = GPU_shader_get_sampler_binding(shader, texture_name);
GPU_texture_bind(texture_, texture_image_unit);
}

View File

@ -82,7 +82,7 @@ void Result::bind_as_texture(GPUShader *shader, const char *texture_name) const
/* Make sure any prior writes to the texture are reflected before reading from it. */
GPU_memory_barrier(GPU_BARRIER_TEXTURE_FETCH);
const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture_name);
const int texture_image_unit = GPU_shader_get_sampler_binding(shader, texture_name);
GPU_texture_bind(texture_, texture_image_unit);
}
@ -93,7 +93,7 @@ void Result::bind_as_image(GPUShader *shader, const char *image_name, bool read)
GPU_memory_barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS);
}
const int image_unit = GPU_shader_get_texture_binding(shader, image_name);
const int image_unit = GPU_shader_get_sampler_binding(shader, image_name);
GPU_texture_image_bind(texture_, image_unit);
}

View File

@ -95,14 +95,14 @@ void ShaderOperation::bind_material_resources(GPUShader *shader)
* no uniforms. */
GPUUniformBuf *ubo = GPU_material_uniform_buffer_get(material_);
if (ubo) {
GPU_uniformbuf_bind(ubo, GPU_shader_get_uniform_block_binding(shader, GPU_UBO_BLOCK_NAME));
GPU_uniformbuf_bind(ubo, GPU_shader_get_ubo_binding(shader, GPU_UBO_BLOCK_NAME));
}
/* Bind color band textures needed by curve and ramp nodes. */
ListBase textures = GPU_material_textures(material_);
LISTBASE_FOREACH (GPUMaterialTexture *, texture, &textures) {
if (texture->colorband) {
const int texture_image_unit = GPU_shader_get_texture_binding(shader, texture->sampler_name);
const int texture_image_unit = GPU_shader_get_sampler_binding(shader, texture->sampler_name);
GPU_texture_bind(*texture->colorband, texture_image_unit);
}
}

View File

@ -225,7 +225,7 @@ set(SRC
DRW_select_buffer.h
intern/DRW_gpu_wrapper.hh
intern/DRW_render.h
intern/draw_attributes.h
intern/draw_attributes.hh
intern/draw_cache.h
intern/draw_cache_extract.hh
intern/draw_cache_impl.h
@ -234,7 +234,7 @@ set(SRC
intern/draw_command.hh
intern/draw_common.h
intern/draw_common_shader_shared.h
intern/draw_curves_private.h
intern/draw_curves_private.hh
intern/draw_debug.h
intern/draw_debug.hh
intern/draw_hair_private.h

View File

@ -409,7 +409,7 @@ void ShadowDirectional::cascade_tilemaps_distribution(Light &light, const Camera
/* Offset in tiles from the origin to the center of the first tile-maps. */
int2 origin_offset = int2(round(float2(near_point) / tile_size));
/* Offset in tiles between the first andlod the last tile-maps. */
/* Offset in tiles between the first and the last tile-maps. */
int2 offset_vector = int2(round(farthest_tilemap_center / tile_size));
light.clipmap_base_offset = (offset_vector * (1 << 16)) / max_ii(levels_range.size() - 1, 1);

View File

@ -21,8 +21,7 @@ void main()
float light_count = 0.0;
uint light_cull = 0u;
vec2 px = gl_FragCoord.xy;
LIGHT_FOREACH_BEGIN_LOCAL(light_cull_buf, light_zbin_buf, light_tile_buf, px, vP_z, l_idx)
{
LIGHT_FOREACH_BEGIN_LOCAL (light_cull_buf, light_zbin_buf, light_tile_buf, px, vP_z, l_idx) {
LightData light = light_buf[l_idx];
light_cull |= 1u << l_idx;
light_count += 1.0;

View File

@ -192,4 +192,4 @@ void main()
break;
}
}
}
}

View File

@ -38,4 +38,4 @@ void main()
}
tile_start += lod_len;
}
}
}

View File

@ -126,4 +126,4 @@ void main()
clear_dispatch_buf.num_groups_x = pages_infos_buf.page_size / SHADOW_PAGE_CLEAR_GROUP_SIZE;
clear_dispatch_buf.num_groups_y = pages_infos_buf.page_size / SHADOW_PAGE_CLEAR_GROUP_SIZE;
clear_dispatch_buf.num_groups_z = 0;
}
}

View File

@ -51,4 +51,4 @@ void main()
}
tile_start += lod_len;
}
}
}

View File

@ -52,4 +52,4 @@ void main()
}
}
}
}
}

View File

@ -91,4 +91,4 @@ void main()
}
}
}
}
}

View File

@ -29,4 +29,4 @@ void main()
vec2 pixel = vec2(gl_GlobalInvocationID.xy);
shadow_tag_usage(vP, P, pixel);
}
}

View File

@ -12,4 +12,4 @@
void main()
{
shadow_tag_usage(interp.vP, interp.P, gl_FragCoord.xy);
}
}

View File

@ -101,4 +101,4 @@ void shadow_tag_usage(vec3 vP, vec3 P, vec2 pixel)
shadow_tag_usage_tilemap(l_idx, P, dist_to_cam, false);
}
LIGHT_FOREACH_END
}
}

View File

@ -19,4 +19,4 @@ void main()
interp.vP = point_world_to_view(interp.P);
gl_Position = point_world_to_ndc(interp.P);
}
}

View File

@ -395,4 +395,4 @@ void main()
EXPECT_NEAR(shadow_slope_bias_get(atlas_size, light, lNg, lP0, vec2(0.0), 2), 0.0, 1e-4);
}
}
}
}

View File

@ -74,4 +74,4 @@ void main()
* thread 0. */
}
LIGHT_FOREACH_END
}
}

View File

@ -178,4 +178,4 @@ void main()
/* Clamp it as it can underflow if there is too much tile present on screen. */
pages_infos_buf.page_free_count = max(pages_infos_buf.page_free_count, 0);
}
}
}

View File

@ -90,4 +90,4 @@ void main()
tiles_buf[tile_store] = tile;
}
}
}
}

View File

@ -1,3 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "eevee_defines.hh"

View File

@ -5,10 +5,14 @@
* \ingroup draw_engine
*/
#include "BKE_curves.h"
#include "DRW_render.h"
#include "ED_view3d.h"
#include "DEG_depsgraph_query.h"
#include "draw_cache_impl.h"
#include "overlay_private.hh"
@ -17,7 +21,10 @@ void OVERLAY_edit_curves_init(OVERLAY_Data *vedata)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
const DRWContextState *draw_ctx = DRW_context_state_get();
const Object *obact_orig = DEG_get_original_object(draw_ctx->obact);
const Curves &curves_id = *static_cast<const Curves *>(obact_orig->data);
pd->edit_curves.do_points = curves_id.selection_domain == ATTR_DOMAIN_POINT;
pd->edit_curves.do_zbufclip = XRAY_FLAG_ENABLED(draw_ctx->v3d);
/* Create view with depth offset. */
@ -39,10 +46,12 @@ void OVERLAY_edit_curves_cache_init(OVERLAY_Data *vedata)
/* Run Twice for in-front passes. */
for (int i = 0; i < 2; i++) {
DRW_PASS_CREATE(psl->edit_curves_points_ps[i], (state | pd->clipping_state));
sh = OVERLAY_shader_edit_particle_point();
grp = pd->edit_curves_points_grp[i] = DRW_shgroup_create(sh, psl->edit_curves_points_ps[i]);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
if (pd->edit_curves.do_points) {
DRW_PASS_CREATE(psl->edit_curves_points_ps[i], (state | pd->clipping_state));
sh = OVERLAY_shader_edit_particle_point();
grp = pd->edit_curves_points_grp[i] = DRW_shgroup_create(sh, psl->edit_curves_points_ps[i]);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
}
DRW_PASS_CREATE(psl->edit_curves_lines_ps[i], (state | pd->clipping_state));
sh = OVERLAY_shader_edit_particle_strand();
@ -56,9 +65,11 @@ static void overlay_edit_curves_add_ob_to_pass(OVERLAY_PrivateData *pd, Object *
{
Curves *curves = static_cast<Curves *>(ob->data);
DRWShadingGroup *point_shgrp = pd->edit_curves_points_grp[in_front];
struct GPUBatch *geom_points = DRW_curves_batch_cache_get_edit_points(curves);
DRW_shgroup_call_no_cull(point_shgrp, geom_points, ob);
if (pd->edit_curves.do_points) {
DRWShadingGroup *point_shgrp = pd->edit_curves_points_grp[in_front];
struct GPUBatch *geom_points = DRW_curves_batch_cache_get_edit_points(curves);
DRW_shgroup_call_no_cull(point_shgrp, geom_points, ob);
}
DRWShadingGroup *lines_shgrp = pd->edit_curves_lines_grp[in_front];
struct GPUBatch *geom_lines = DRW_curves_batch_cache_get_edit_lines(curves);
@ -89,12 +100,16 @@ void OVERLAY_edit_curves_draw(OVERLAY_Data *vedata)
if (pd->edit_curves.do_zbufclip) {
DRW_view_set_active(pd->view_edit_curves);
DRW_draw_pass(psl->edit_curves_points_ps[NOT_IN_FRONT]);
if (pd->edit_curves.do_points) {
DRW_draw_pass(psl->edit_curves_points_ps[NOT_IN_FRONT]);
}
DRW_draw_pass(psl->edit_curves_lines_ps[NOT_IN_FRONT]);
}
else {
DRW_view_set_active(pd->view_edit_curves);
DRW_draw_pass(psl->edit_curves_points_ps[IN_FRONT]);
if (pd->edit_curves.do_points) {
DRW_draw_pass(psl->edit_curves_points_ps[IN_FRONT]);
}
DRW_draw_pass(psl->edit_curves_lines_ps[IN_FRONT]);
}
}

View File

@ -362,6 +362,7 @@ typedef struct OVERLAY_PrivateData {
int flag; /** Copy of #v3d->overlay.edit_flag. */
} edit_mesh;
struct {
bool do_points;
bool do_zbufclip;
} edit_curves;
struct {

View File

@ -59,6 +59,6 @@ struct ExtrudedFrustum {
struct ShadowPassData {
float4 far_plane;
float3 light_direction_ws;
packed_float3 light_direction_ws;
int _padding;
};

View File

@ -259,17 +259,16 @@ void ShadowPass::ShadowView::compute_visibility(ObjectBoundsBuf &bounds,
GPU_shader_uniform_1i(shader, "visibility_word_per_draw", word_per_draw);
GPU_shader_uniform_1b(shader, "force_fail_method", force_fail_method_);
GPU_shader_uniform_3fv(shader, "shadow_direction", light_direction_);
GPU_uniformbuf_bind(extruded_frustum_,
GPU_shader_get_uniform_block_binding(shader, "extruded_frustum"));
GPU_storagebuf_bind(bounds, GPU_shader_get_ssbo(shader, "bounds_buf"));
GPU_uniformbuf_bind(extruded_frustum_, GPU_shader_get_ubo_binding(shader, "extruded_frustum"));
GPU_storagebuf_bind(bounds, GPU_shader_get_ssbo_binding(shader, "bounds_buf"));
if (current_pass_type_ == ShadowPass::FORCED_FAIL) {
GPU_storagebuf_bind(visibility_buf_, GPU_shader_get_ssbo(shader, "visibility_buf"));
GPU_storagebuf_bind(visibility_buf_, GPU_shader_get_ssbo_binding(shader, "visibility_buf"));
}
else {
GPU_storagebuf_bind(pass_visibility_buf_,
GPU_shader_get_ssbo(shader, "pass_visibility_buf"));
GPU_shader_get_ssbo_binding(shader, "pass_visibility_buf"));
GPU_storagebuf_bind(fail_visibility_buf_,
GPU_shader_get_ssbo(shader, "fail_visibility_buf"));
GPU_shader_get_ssbo_binding(shader, "fail_visibility_buf"));
}
GPU_uniformbuf_bind(data_, DRW_VIEW_UBO_SLOT);
GPU_compute_dispatch(shader, divide_ceil_u(resource_len, DRW_VISIBILITY_GROUP_SIZE), 1, 1);

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2022 Blender Foundation. All rights reserved. */
#include "draw_attributes.h"
#include "draw_attributes.hh"
/* Return true if the given DRW_AttributeRequest is already in the requests. */
static bool drw_attributes_has_request(const DRW_Attributes *requests, DRW_AttributeRequest req)

View File

@ -9,9 +9,7 @@
#pragma once
#ifdef __cplusplus
# include <mutex>
#endif
#include <mutex>
#include "DNA_customdata_types.h"
@ -24,23 +22,19 @@
#include "GPU_shader.h"
#include "GPU_vertex_format.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct DRW_AttributeRequest {
struct DRW_AttributeRequest {
eCustomDataType cd_type;
int layer_index;
eAttrDomain domain;
char attribute_name[64];
} DRW_AttributeRequest;
};
typedef struct DRW_Attributes {
struct DRW_Attributes {
DRW_AttributeRequest requests[GPU_MAX_ATTR];
int num_requests;
} DRW_Attributes;
};
typedef struct DRW_MeshCDMask {
struct DRW_MeshCDMask {
uint32_t uv : 8;
uint32_t tan : 8;
uint32_t orco : 1;
@ -50,7 +44,7 @@ typedef struct DRW_MeshCDMask {
* Edit uv layer is from the base edit mesh as modifiers could remove it. (see #68857)
*/
uint32_t edit_uv : 1;
} DRW_MeshCDMask;
};
/* Keep `DRW_MeshCDMask` struct within a `uint32_t`.
* bit-wise and atomic operations are used to compare and update the struct.
@ -59,11 +53,9 @@ BLI_STATIC_ASSERT(sizeof(DRW_MeshCDMask) <= sizeof(uint32_t), "DRW_MeshCDMask ex
void drw_attributes_clear(DRW_Attributes *attributes);
#ifdef __cplusplus
void drw_attributes_merge(DRW_Attributes *dst,
const DRW_Attributes *src,
std::mutex &render_mutex);
#endif
/* Return true if all requests in b are in a. */
bool drw_attributes_overlap(const DRW_Attributes *a, const DRW_Attributes *b);
@ -78,7 +70,3 @@ bool drw_custom_data_match_attribute(const CustomData *custom_data,
const char *name,
int *r_layer_index,
eCustomDataType *r_type);
#ifdef __cplusplus
}
#endif

View File

@ -22,7 +22,7 @@
#include "GPU_index_buffer.h"
#include "GPU_vertex_buffer.h"
#include "draw_attributes.h"
#include "draw_attributes.hh"
struct DRWSubdivCache;
struct MeshRenderData;

View File

@ -34,10 +34,10 @@
#include "DRW_render.h"
#include "draw_attributes.h"
#include "draw_attributes.hh"
#include "draw_cache_impl.h" /* own include */
#include "draw_cache_inline.h"
#include "draw_curves_private.h" /* own include */
#include "draw_curves_private.hh" /* own include */
#include "draw_shader.h"
using blender::ColorGeometry4f;

View File

@ -25,7 +25,7 @@
#include "GPU_batch.h"
#include "GPU_material.h"
#include "draw_attributes.h"
#include "draw_attributes.hh"
#include "draw_cache_impl.h"
#include "draw_cache_inline.h"
#include "draw_pointcloud_private.hh" /* own include */

View File

@ -1350,7 +1350,7 @@ static void draw_subdiv_ubo_update_and_bind(const DRWSubdivCache *cache,
GPU_uniformbuf_update(cache->ubo, &storage);
const int binding = GPU_shader_get_uniform_block_binding(shader, "shader_data");
const int binding = GPU_shader_get_ubo_binding(shader, "shader_data");
GPU_uniformbuf_bind(cache->ubo, binding);
}

View File

@ -76,16 +76,16 @@ void PushConstant::execute(RecordingState &state) const
}
switch (type) {
case PushConstant::Type::IntValue:
GPU_shader_uniform_vector_int(state.shader, location, comp_len, array_len, int4_value);
GPU_shader_uniform_int_ex(state.shader, location, comp_len, array_len, int4_value);
break;
case PushConstant::Type::IntReference:
GPU_shader_uniform_vector_int(state.shader, location, comp_len, array_len, int_ref);
GPU_shader_uniform_int_ex(state.shader, location, comp_len, array_len, int_ref);
break;
case PushConstant::Type::FloatValue:
GPU_shader_uniform_vector(state.shader, location, comp_len, array_len, float4_value);
GPU_shader_uniform_float_ex(state.shader, location, comp_len, array_len, float4_value);
break;
case PushConstant::Type::FloatReference:
GPU_shader_uniform_vector(state.shader, location, comp_len, array_len, float_ref);
GPU_shader_uniform_float_ex(state.shader, location, comp_len, array_len, float_ref);
break;
}
}
@ -646,10 +646,10 @@ void DrawMultiBuf::bind(RecordingState &state,
GPU_shader_uniform_1i(shader, "prototype_len", prototype_count_);
GPU_shader_uniform_1i(shader, "visibility_word_per_draw", visibility_word_per_draw);
GPU_shader_uniform_1i(shader, "view_shift", log2_ceil_u(view_len));
GPU_storagebuf_bind(group_buf_, GPU_shader_get_ssbo(shader, "group_buf"));
GPU_storagebuf_bind(visibility_buf, GPU_shader_get_ssbo(shader, "visibility_buf"));
GPU_storagebuf_bind(prototype_buf_, GPU_shader_get_ssbo(shader, "prototype_buf"));
GPU_storagebuf_bind(command_buf_, GPU_shader_get_ssbo(shader, "command_buf"));
GPU_storagebuf_bind(group_buf_, GPU_shader_get_ssbo_binding(shader, "group_buf"));
GPU_storagebuf_bind(visibility_buf, GPU_shader_get_ssbo_binding(shader, "visibility_buf"));
GPU_storagebuf_bind(prototype_buf_, GPU_shader_get_ssbo_binding(shader, "prototype_buf"));
GPU_storagebuf_bind(command_buf_, GPU_shader_get_ssbo_binding(shader, "command_buf"));
GPU_storagebuf_bind(resource_id_buf_, DRW_RESOURCE_ID_SLOT);
GPU_compute_dispatch(shader, divide_ceil_u(prototype_count_, DRW_COMMAND_GROUP_SIZE), 1, 1);
if (GPU_shader_draw_parameters_support() == false) {

View File

@ -26,7 +26,7 @@
#include "DRW_render.h"
#include "draw_cache_impl.h"
#include "draw_curves_private.h"
#include "draw_curves_private.hh"
#include "draw_hair_private.h"
#include "draw_manager.h"
#include "draw_shader.h"

View File

@ -10,26 +10,23 @@
#include "BKE_attribute.h"
#include "GPU_shader.h"
#include "draw_attributes.h"
#ifdef __cplusplus
extern "C" {
#endif
#include "draw_attributes.hh"
struct Curves;
struct GPUVertBuf;
struct GPUBatch;
struct GPUMaterial;
#define MAX_THICKRES 2 /* see eHairType */
#define MAX_HAIR_SUBDIV 4 /* see hair_subdiv rna */
typedef enum CurvesEvalShader {
enum CurvesEvalShader {
CURVES_EVAL_CATMULL_ROM = 0,
CURVES_EVAL_BEZIER = 1,
} CurvesEvalShader;
};
#define CURVES_EVAL_SHADER_NUM 3
typedef struct CurvesEvalFinalCache {
struct CurvesEvalFinalCache {
/* Output of the subdivision stage: vertex buffer sized to subdiv level. */
GPUVertBuf *proc_buf;
@ -58,10 +55,10 @@ typedef struct CurvesEvalFinalCache {
/* Output of the subdivision stage: vertex buffers sized to subdiv level. This is only attributes
* on point domain. */
GPUVertBuf *attributes_buf[GPU_MAX_ATTR];
} CurvesEvalFinalCache;
};
/* Curves procedural display: Evaluation is done on the GPU. */
typedef struct CurvesEvalCache {
struct CurvesEvalCache {
/* Control point positions on evaluated data-block combined with parameter data. */
GPUVertBuf *proc_point_buf;
@ -82,19 +79,15 @@ typedef struct CurvesEvalCache {
int strands_len;
int elems_len;
int point_len;
} CurvesEvalCache;
};
/**
* Ensure all necessary textures and buffers exist for GPU accelerated drawing.
*/
bool curves_ensure_procedural_data(struct Curves *curves,
struct CurvesEvalCache **r_hair_cache,
struct GPUMaterial *gpu_material,
bool curves_ensure_procedural_data(Curves *curves,
CurvesEvalCache **r_hair_cache,
GPUMaterial *gpu_material,
int subdiv,
int thickness_res);
void drw_curves_get_attribute_sampler_name(const char *layer_name, char r_sampler_name[32]);
#ifdef __cplusplus
}
#endif

View File

@ -523,19 +523,18 @@ void DebugDraw::display_lines()
GPUBatch *batch = drw_cache_procedural_lines_get();
GPUShader *shader = DRW_shader_debug_draw_display_get();
GPU_batch_set_shader(batch, shader);
int slot = GPU_shader_get_builtin_ssbo(shader, GPU_STORAGE_BUFFER_DEBUG_VERTS);
GPU_shader_uniform_mat4(shader, "persmat", persmat.ptr());
if (gpu_draw_buf_used) {
GPU_debug_group_begin("GPU");
GPU_storagebuf_bind(gpu_draw_buf_, slot);
GPU_storagebuf_bind(gpu_draw_buf_, DRW_DEBUG_DRAW_SLOT);
GPU_batch_draw_indirect(batch, gpu_draw_buf_, 0);
GPU_storagebuf_unbind(gpu_draw_buf_);
GPU_debug_group_end();
}
GPU_debug_group_begin("CPU");
GPU_storagebuf_bind(cpu_draw_buf_, slot);
GPU_storagebuf_bind(cpu_draw_buf_, DRW_DEBUG_DRAW_SLOT);
GPU_batch_draw_indirect(batch, cpu_draw_buf_, 0);
GPU_storagebuf_unbind(cpu_draw_buf_);
GPU_debug_group_end();
@ -556,21 +555,20 @@ void DebugDraw::display_prints()
GPUBatch *batch = drw_cache_procedural_points_get();
GPUShader *shader = DRW_shader_debug_print_display_get();
GPU_batch_set_shader(batch, shader);
int slot = GPU_shader_get_builtin_ssbo(shader, GPU_STORAGE_BUFFER_DEBUG_PRINT);
float f_viewport[4];
GPU_viewport_size_get_f(f_viewport);
GPU_shader_uniform_2fv(shader, "viewport_size", &f_viewport[2]);
if (gpu_print_buf_used) {
GPU_debug_group_begin("GPU");
GPU_storagebuf_bind(gpu_print_buf_, slot);
GPU_storagebuf_bind(gpu_print_buf_, DRW_DEBUG_PRINT_SLOT);
GPU_batch_draw_indirect(batch, gpu_print_buf_, 0);
GPU_storagebuf_unbind(gpu_print_buf_);
GPU_debug_group_end();
}
GPU_debug_group_begin("CPU");
GPU_storagebuf_bind(cpu_print_buf_, slot);
GPU_storagebuf_bind(cpu_print_buf_, DRW_DEBUG_PRINT_SLOT);
GPU_batch_draw_indirect(batch, cpu_print_buf_, 0);
GPU_storagebuf_unbind(cpu_print_buf_);
GPU_debug_group_end();

View File

@ -114,9 +114,9 @@ void Manager::end_sync()
GPUShader *shader = DRW_shader_draw_resource_finalize_get();
GPU_shader_bind(shader);
GPU_shader_uniform_1i(shader, "resource_len", resource_len_);
GPU_storagebuf_bind(matrix_buf.current(), GPU_shader_get_ssbo(shader, "matrix_buf"));
GPU_storagebuf_bind(bounds_buf.current(), GPU_shader_get_ssbo(shader, "bounds_buf"));
GPU_storagebuf_bind(infos_buf.current(), GPU_shader_get_ssbo(shader, "infos_buf"));
GPU_storagebuf_bind(matrix_buf.current(), GPU_shader_get_ssbo_binding(shader, "matrix_buf"));
GPU_storagebuf_bind(bounds_buf.current(), GPU_shader_get_ssbo_binding(shader, "bounds_buf"));
GPU_storagebuf_bind(infos_buf.current(), GPU_shader_get_ssbo_binding(shader, "infos_buf"));
GPU_compute_dispatch(shader, thread_groups, 1, 1);
GPU_memory_barrier(GPU_BARRIER_SHADER_STORAGE);

View File

@ -7,7 +7,7 @@
#include "DRW_pbvh.hh"
#include "draw_attributes.h"
#include "draw_attributes.hh"
#include "draw_manager.h"
#include "draw_pbvh.h"
@ -256,7 +256,7 @@ void DRW_shgroup_uniform_texture_ex(DRWShadingGroup *shgroup,
eGPUSamplerState sampler_state)
{
BLI_assert(tex != nullptr);
int loc = GPU_shader_get_texture_binding(shgroup->shader, name);
int loc = GPU_shader_get_sampler_binding(shgroup->shader, name);
drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_TEXTURE, tex, sampler_state, 0, 1);
}
@ -271,7 +271,7 @@ void DRW_shgroup_uniform_texture_ref_ex(DRWShadingGroup *shgroup,
eGPUSamplerState sampler_state)
{
BLI_assert(tex != nullptr);
int loc = GPU_shader_get_texture_binding(shgroup->shader, name);
int loc = GPU_shader_get_sampler_binding(shgroup->shader, name);
drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_TEXTURE_REF, tex, sampler_state, 0, 1);
}
@ -283,14 +283,14 @@ void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup, const char *name,
void DRW_shgroup_uniform_image(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
{
BLI_assert(tex != nullptr);
int loc = GPU_shader_get_texture_binding(shgroup->shader, name);
int loc = GPU_shader_get_sampler_binding(shgroup->shader, name);
drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_IMAGE, tex, GPU_SAMPLER_DEFAULT, 0, 1);
}
void DRW_shgroup_uniform_image_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex)
{
BLI_assert(tex != nullptr);
int loc = GPU_shader_get_texture_binding(shgroup->shader, name);
int loc = GPU_shader_get_sampler_binding(shgroup->shader, name);
drw_shgroup_uniform_create_ex(
shgroup, loc, DRW_UNIFORM_IMAGE_REF, tex, GPU_SAMPLER_DEFAULT, 0, 1);
}
@ -300,7 +300,7 @@ void DRW_shgroup_uniform_block_ex(DRWShadingGroup *shgroup,
const GPUUniformBuf *ubo DRW_DEBUG_FILE_LINE_ARGS)
{
BLI_assert(ubo != nullptr);
int loc = GPU_shader_get_uniform_block_binding(shgroup->shader, name);
int loc = GPU_shader_get_ubo_binding(shgroup->shader, name);
if (loc == -1) {
#ifdef DRW_UNUSED_RESOURCE_TRACKING
printf("%s:%d: Unable to locate binding of shader uniform buffer object: %s.\n",
@ -321,7 +321,7 @@ void DRW_shgroup_uniform_block_ref_ex(DRWShadingGroup *shgroup,
GPUUniformBuf **ubo DRW_DEBUG_FILE_LINE_ARGS)
{
BLI_assert(ubo != nullptr);
int loc = GPU_shader_get_uniform_block_binding(shgroup->shader, name);
int loc = GPU_shader_get_ubo_binding(shgroup->shader, name);
if (loc == -1) {
#ifdef DRW_UNUSED_RESOURCE_TRACKING
printf("%s:%d: Unable to locate binding of shader uniform buffer object: %s.\n",
@ -344,7 +344,7 @@ void DRW_shgroup_storage_block_ex(DRWShadingGroup *shgroup,
{
BLI_assert(ssbo != nullptr);
/* TODO(@fclem): Fix naming inconsistency. */
int loc = GPU_shader_get_ssbo(shgroup->shader, name);
int loc = GPU_shader_get_ssbo_binding(shgroup->shader, name);
if (loc == -1) {
#ifdef DRW_UNUSED_RESOURCE_TRACKING
printf("%s:%d: Unable to locate binding of shader storage buffer object: %s.\n",
@ -367,7 +367,7 @@ void DRW_shgroup_storage_block_ref_ex(DRWShadingGroup *shgroup,
{
BLI_assert(ssbo != nullptr);
/* TODO(@fclem): Fix naming inconsistency. */
int loc = GPU_shader_get_ssbo(shgroup->shader, name);
int loc = GPU_shader_get_ssbo_binding(shgroup->shader, name);
if (loc == -1) {
#ifdef DRW_UNUSED_RESOURCE_TRACKING
printf("%s:%d: Unable to locate binding of shader storage buffer object: %s.\n",
@ -539,7 +539,7 @@ void DRW_shgroup_vertex_buffer_ex(DRWShadingGroup *shgroup,
const char *name,
GPUVertBuf *vertex_buffer DRW_DEBUG_FILE_LINE_ARGS)
{
int location = GPU_shader_get_ssbo(shgroup->shader, name);
int location = GPU_shader_get_ssbo_binding(shgroup->shader, name);
if (location == -1) {
#ifdef DRW_UNUSED_RESOURCE_TRACKING
printf("%s:%d: Unable to locate binding of shader storage buffer object: %s.\n",
@ -564,7 +564,7 @@ void DRW_shgroup_vertex_buffer_ref_ex(DRWShadingGroup *shgroup,
const char *name,
GPUVertBuf **vertex_buffer DRW_DEBUG_FILE_LINE_ARGS)
{
int location = GPU_shader_get_ssbo(shgroup->shader, name);
int location = GPU_shader_get_ssbo_binding(shgroup->shader, name);
if (location == -1) {
#ifdef DRW_UNUSED_RESOURCE_TRACKING
printf("%s:%d: Unable to locate binding of shader storage buffer object: %s.\n",
@ -589,7 +589,7 @@ void DRW_shgroup_buffer_texture(DRWShadingGroup *shgroup,
const char *name,
GPUVertBuf *vertex_buffer)
{
int location = GPU_shader_get_texture_binding(shgroup->shader, name);
int location = GPU_shader_get_sampler_binding(shgroup->shader, name);
if (location == -1) {
return;
}
@ -606,7 +606,7 @@ void DRW_shgroup_buffer_texture_ref(DRWShadingGroup *shgroup,
const char *name,
GPUVertBuf **vertex_buffer)
{
int location = GPU_shader_get_texture_binding(shgroup->shader, name);
int location = GPU_shader_get_sampler_binding(shgroup->shader, name);
if (location == -1) {
return;
}
@ -1719,36 +1719,6 @@ static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader)
1);
}
#ifdef DEBUG
/* TODO(Metal): Support Shader debug print.
* This is not currently supported by Metal Backend. */
if (GPU_backend_get_type() != GPU_BACKEND_METAL) {
int debug_print_location = GPU_shader_get_builtin_ssbo(shader, GPU_STORAGE_BUFFER_DEBUG_PRINT);
if (debug_print_location != -1) {
GPUStorageBuf *buf = drw_debug_gpu_print_buf_get();
drw_shgroup_uniform_create_ex(shgroup,
debug_print_location,
DRW_UNIFORM_STORAGE_BLOCK,
buf,
GPU_SAMPLER_DEFAULT,
0,
1);
# ifndef DISABLE_DEBUG_SHADER_PRINT_BARRIER
/* Add a barrier to allow multiple shader writing to the same buffer. */
DRW_shgroup_barrier(shgroup, GPU_BARRIER_SHADER_STORAGE);
# endif
}
int debug_draw_location = GPU_shader_get_builtin_ssbo(shader, GPU_STORAGE_BUFFER_DEBUG_VERTS);
if (debug_draw_location != -1) {
GPUStorageBuf *buf = drw_debug_gpu_draw_buf_get();
drw_shgroup_uniform_create_ex(
shgroup, debug_draw_location, DRW_UNIFORM_STORAGE_BLOCK, buf, GPU_SAMPLER_DEFAULT, 0, 1);
/* NOTE(fclem): No barrier as ordering is not important. */
}
}
#endif
/* Not supported. */
BLI_assert(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MODELVIEW_INV) == -1);
BLI_assert(GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_MODELVIEW) == -1);
@ -1850,15 +1820,14 @@ void DRW_shgroup_add_material_resources(DRWShadingGroup *grp, GPUMaterial *mater
const GPUUniformAttrList *uattrs = GPU_material_uniform_attributes(material);
if (uattrs != nullptr) {
int loc = GPU_shader_get_uniform_block_binding(grp->shader, GPU_ATTRIBUTE_UBO_BLOCK_NAME);
int loc = GPU_shader_get_ubo_binding(grp->shader, GPU_ATTRIBUTE_UBO_BLOCK_NAME);
drw_shgroup_uniform_create_ex(
grp, loc, DRW_UNIFORM_BLOCK_OBATTRS, uattrs, GPU_SAMPLER_DEFAULT, 0, 1);
grp->uniform_attrs = uattrs;
}
if (GPU_material_layer_attributes(material) != nullptr) {
int loc = GPU_shader_get_uniform_block_binding(grp->shader,
GPU_LAYER_ATTRIBUTE_UBO_BLOCK_NAME);
int loc = GPU_shader_get_ubo_binding(grp->shader, GPU_LAYER_ATTRIBUTE_UBO_BLOCK_NAME);
drw_shgroup_uniform_create_ex(
grp, loc, DRW_UNIFORM_BLOCK_VLATTRS, nullptr, GPU_SAMPLER_DEFAULT, 0, 1);
}

View File

@ -522,10 +522,10 @@ BLI_INLINE void draw_legacy_matrix_update(DRWShadingGroup *shgroup,
/* Still supported for compatibility with gpu_shader_* but should be forbidden. */
DRWObjectMatrix *ob_mats = DRW_memblock_elem_from_handle(DST.vmempool->obmats, handle);
if (obmat_loc != -1) {
GPU_shader_uniform_vector(shgroup->shader, obmat_loc, 16, 1, (float *)ob_mats->model);
GPU_shader_uniform_float_ex(shgroup->shader, obmat_loc, 16, 1, (float *)ob_mats->model);
}
if (obinv_loc != -1) {
GPU_shader_uniform_vector(shgroup->shader, obinv_loc, 16, 1, (float *)ob_mats->modelinverse);
GPU_shader_uniform_float_ex(shgroup->shader, obinv_loc, 16, 1, (float *)ob_mats->modelinverse);
}
}
@ -549,7 +549,7 @@ BLI_INLINE void draw_geometry_execute(DRWShadingGroup *shgroup,
if (baseinst_loc != -1) {
/* Fallback when ARB_shader_draw_parameters is not supported. */
GPU_shader_uniform_vector_int(shgroup->shader, baseinst_loc, 1, 1, (int *)&inst_first);
GPU_shader_uniform_int_ex(shgroup->shader, baseinst_loc, 1, 1, (int *)&inst_first);
/* Avoids VAO reconfiguration on older hardware. (see GPU_batch_draw_advanced) */
inst_first = 0;
}
@ -615,7 +615,7 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup,
memcpy(&mat4_stack[array_index], uni->fvalue, sizeof(float) * uni->length);
/* Flush array data to shader. */
if (array_index <= 0) {
GPU_shader_uniform_vector(shgroup->shader, uni->location, 16, 1, mat4_stack);
GPU_shader_uniform_float_ex(shgroup->shader, uni->location, 16, 1, mat4_stack);
array_uniform_loc = -1;
}
continue;
@ -626,23 +626,23 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup,
case DRW_UNIFORM_INT_COPY:
BLI_assert(uni->arraysize == 1);
if (uni->arraysize == 1) {
GPU_shader_uniform_vector_int(
GPU_shader_uniform_int_ex(
shgroup->shader, uni->location, uni->length, uni->arraysize, uni->ivalue);
}
break;
case DRW_UNIFORM_INT:
GPU_shader_uniform_vector_int(
GPU_shader_uniform_int_ex(
shgroup->shader, uni->location, uni->length, uni->arraysize, uni->pvalue);
break;
case DRW_UNIFORM_FLOAT_COPY:
BLI_assert(uni->arraysize == 1);
if (uni->arraysize == 1) {
GPU_shader_uniform_vector(
GPU_shader_uniform_float_ex(
shgroup->shader, uni->location, uni->length, uni->arraysize, uni->fvalue);
}
break;
case DRW_UNIFORM_FLOAT:
GPU_shader_uniform_vector(
GPU_shader_uniform_float_ex(
shgroup->shader, uni->location, uni->length, uni->arraysize, uni->pvalue);
break;
case DRW_UNIFORM_TEXTURE:
@ -687,10 +687,12 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup,
state->vlattrs_loc = uni->location;
GPU_uniformbuf_bind(drw_ensure_layer_attribute_buffer(), uni->location);
break;
case DRW_UNIFORM_RESOURCE_CHUNK:
case DRW_UNIFORM_RESOURCE_CHUNK: {
state->chunkid_loc = uni->location;
GPU_shader_uniform_int(shgroup->shader, uni->location, 0);
int zero = 0;
GPU_shader_uniform_int_ex(shgroup->shader, uni->location, 1, 1, &zero);
break;
}
case DRW_UNIFORM_RESOURCE_ID:
state->resourceid_loc = uni->location;
break;
@ -807,7 +809,7 @@ static void draw_call_resource_bind(DRWCommandsState *state, const DRWResourceHa
int chunk = DRW_handle_chunk_get(handle);
if (state->resource_chunk != chunk) {
if (state->chunkid_loc != -1) {
GPU_shader_uniform_int(DST.shader, state->chunkid_loc, chunk);
GPU_shader_uniform_int_ex(DST.shader, state->chunkid_loc, 1, 1, &chunk);
}
if (state->obmats_loc != -1) {
GPU_uniformbuf_unbind(DST.vmempool->matrices_ubo[state->resource_chunk]);
@ -827,7 +829,7 @@ static void draw_call_resource_bind(DRWCommandsState *state, const DRWResourceHa
if (state->resourceid_loc != -1) {
int id = DRW_handle_id_get(handle);
if (state->resource_id != id) {
GPU_shader_uniform_int(DST.shader, state->resourceid_loc, id);
GPU_shader_uniform_int_ex(DST.shader, state->resourceid_loc, 1, 1, &id);
state->resource_id = id;
}
}

View File

@ -861,42 +861,42 @@ template<class T> inline int PassBase<T>::push_constant_offset(const char *name)
template<class T> inline void PassBase<T>::bind_ssbo(const char *name, GPUStorageBuf *buffer)
{
this->bind_ssbo(GPU_shader_get_ssbo(shader_, name), buffer);
this->bind_ssbo(GPU_shader_get_ssbo_binding(shader_, name), buffer);
}
template<class T> inline void PassBase<T>::bind_ssbo(const char *name, GPUUniformBuf *buffer)
{
this->bind_ssbo(GPU_shader_get_ssbo(shader_, name), buffer);
this->bind_ssbo(GPU_shader_get_ssbo_binding(shader_, name), buffer);
}
template<class T> inline void PassBase<T>::bind_ssbo(const char *name, GPUUniformBuf **buffer)
{
this->bind_ssbo(GPU_shader_get_ssbo(shader_, name), buffer);
this->bind_ssbo(GPU_shader_get_ssbo_binding(shader_, name), buffer);
}
template<class T> inline void PassBase<T>::bind_ssbo(const char *name, GPUVertBuf *buffer)
{
this->bind_ssbo(GPU_shader_get_ssbo(shader_, name), buffer);
this->bind_ssbo(GPU_shader_get_ssbo_binding(shader_, name), buffer);
}
template<class T> inline void PassBase<T>::bind_ssbo(const char *name, GPUVertBuf **buffer)
{
this->bind_ssbo(GPU_shader_get_ssbo(shader_, name), buffer);
this->bind_ssbo(GPU_shader_get_ssbo_binding(shader_, name), buffer);
}
template<class T> inline void PassBase<T>::bind_ssbo(const char *name, GPUIndexBuf *buffer)
{
this->bind_ssbo(GPU_shader_get_ssbo(shader_, name), buffer);
this->bind_ssbo(GPU_shader_get_ssbo_binding(shader_, name), buffer);
}
template<class T> inline void PassBase<T>::bind_ssbo(const char *name, GPUIndexBuf **buffer)
{
this->bind_ssbo(GPU_shader_get_ssbo(shader_, name), buffer);
this->bind_ssbo(GPU_shader_get_ssbo_binding(shader_, name), buffer);
}
template<class T> inline void PassBase<T>::bind_ubo(const char *name, GPUUniformBuf *buffer)
{
this->bind_ubo(GPU_shader_get_uniform_block_binding(shader_, name), buffer);
this->bind_ubo(GPU_shader_get_ubo_binding(shader_, name), buffer);
}
template<class T>
@ -904,22 +904,22 @@ inline void PassBase<T>::bind_texture(const char *name,
GPUTexture *texture,
eGPUSamplerState state)
{
this->bind_texture(GPU_shader_get_texture_binding(shader_, name), texture, state);
this->bind_texture(GPU_shader_get_sampler_binding(shader_, name), texture, state);
}
template<class T> inline void PassBase<T>::bind_texture(const char *name, GPUVertBuf *buffer)
{
this->bind_texture(GPU_shader_get_texture_binding(shader_, name), buffer);
this->bind_texture(GPU_shader_get_sampler_binding(shader_, name), buffer);
}
template<class T> inline void PassBase<T>::bind_texture(const char *name, GPUVertBuf **buffer)
{
this->bind_texture(GPU_shader_get_texture_binding(shader_, name), buffer);
this->bind_texture(GPU_shader_get_sampler_binding(shader_, name), buffer);
}
template<class T> inline void PassBase<T>::bind_image(const char *name, GPUTexture *image)
{
this->bind_image(GPU_shader_get_texture_binding(shader_, name), image);
this->bind_image(GPU_shader_get_sampler_binding(shader_, name), image);
}
template<class T> inline void PassBase<T>::bind_ssbo(int slot, GPUStorageBuf *buffer)
@ -991,12 +991,12 @@ template<class T> inline void PassBase<T>::bind_image(int slot, GPUTexture *imag
template<class T> inline void PassBase<T>::bind_ssbo(const char *name, GPUStorageBuf **buffer)
{
this->bind_ssbo(GPU_shader_get_ssbo(shader_, name), buffer);
this->bind_ssbo(GPU_shader_get_ssbo_binding(shader_, name), buffer);
}
template<class T> inline void PassBase<T>::bind_ubo(const char *name, GPUUniformBuf **buffer)
{
this->bind_ubo(GPU_shader_get_uniform_block_binding(shader_, name), buffer);
this->bind_ubo(GPU_shader_get_ubo_binding(shader_, name), buffer);
}
template<class T>
@ -1004,12 +1004,12 @@ inline void PassBase<T>::bind_texture(const char *name,
GPUTexture **texture,
eGPUSamplerState state)
{
this->bind_texture(GPU_shader_get_texture_binding(shader_, name), texture, state);
this->bind_texture(GPU_shader_get_sampler_binding(shader_, name), texture, state);
}
template<class T> inline void PassBase<T>::bind_image(const char *name, GPUTexture **image)
{
this->bind_image(GPU_shader_get_texture_binding(shader_, name), image);
this->bind_image(GPU_shader_get_sampler_binding(shader_, name), image);
}
template<class T> inline void PassBase<T>::bind_ssbo(int slot, GPUStorageBuf **buffer)

View File

@ -21,7 +21,7 @@
#include "DRW_gpu_wrapper.hh"
#include "DRW_render.h"
#include "draw_attributes.h"
#include "draw_attributes.hh"
#include "draw_cache_impl.h"
#include "draw_common.h"
#include "draw_manager.h"

View File

@ -7,36 +7,38 @@
#pragma once
#include "draw_curves_private.h"
#include "draw_hair_private.h"
#ifdef __cplusplus
# include "draw_curves_private.hh"
# include "draw_hair_private.h"
struct GPUShader;
enum eParticleRefineShaderType {
PART_REFINE_SHADER_TRANSFORM_FEEDBACK,
PART_REFINE_SHADER_TRANSFORM_FEEDBACK_WORKAROUND,
PART_REFINE_SHADER_COMPUTE,
};
/* draw_shader.cc */
GPUShader *DRW_shader_hair_refine_get(ParticleRefineShader refinement,
eParticleRefineShaderType sh_type);
GPUShader *DRW_shader_curves_refine_get(CurvesEvalShader type, eParticleRefineShaderType sh_type);
GPUShader *DRW_shader_debug_print_display_get();
GPUShader *DRW_shader_debug_draw_display_get();
GPUShader *DRW_shader_draw_visibility_compute_get();
GPUShader *DRW_shader_draw_view_finalize_get();
GPUShader *DRW_shader_draw_resource_finalize_get();
GPUShader *DRW_shader_draw_command_generate_get();
#endif
#ifdef __cplusplus
extern "C" {
#endif
struct GPUShader;
typedef enum eParticleRefineShaderType {
PART_REFINE_SHADER_TRANSFORM_FEEDBACK,
PART_REFINE_SHADER_TRANSFORM_FEEDBACK_WORKAROUND,
PART_REFINE_SHADER_COMPUTE,
} eParticleRefineShaderType;
/* draw_shader.cc */
struct GPUShader *DRW_shader_hair_refine_get(ParticleRefineShader refinement,
eParticleRefineShaderType sh_type);
struct GPUShader *DRW_shader_curves_refine_get(CurvesEvalShader type,
eParticleRefineShaderType sh_type);
struct GPUShader *DRW_shader_debug_print_display_get(void);
struct GPUShader *DRW_shader_debug_draw_display_get(void);
struct GPUShader *DRW_shader_draw_visibility_compute_get(void);
struct GPUShader *DRW_shader_draw_view_finalize_get(void);
struct GPUShader *DRW_shader_draw_resource_finalize_get(void);
struct GPUShader *DRW_shader_draw_command_generate_get(void);
void DRW_shaders_free(void);
#ifdef __cplusplus

View File

@ -244,7 +244,7 @@ void View::compute_procedural_bounds()
GPUShader *shader = DRW_shader_draw_view_finalize_get();
GPU_shader_bind(shader);
GPU_uniformbuf_bind_as_ssbo(culling_, GPU_shader_get_ssbo(shader, "view_culling_buf"));
GPU_uniformbuf_bind_as_ssbo(culling_, GPU_shader_get_ssbo_binding(shader, "view_culling_buf"));
GPU_uniformbuf_bind(data_, DRW_VIEW_UBO_SLOT);
GPU_compute_dispatch(shader, 1, 1, 1);
GPU_memory_barrier(GPU_BARRIER_UNIFORM);
@ -289,8 +289,8 @@ void View::compute_visibility(ObjectBoundsBuf &bounds, uint resource_len, bool d
GPU_shader_uniform_1i(shader, "resource_len", resource_len);
GPU_shader_uniform_1i(shader, "view_len", view_len_);
GPU_shader_uniform_1i(shader, "visibility_word_per_draw", word_per_draw);
GPU_storagebuf_bind(bounds, GPU_shader_get_ssbo(shader, "bounds_buf"));
GPU_storagebuf_bind(visibility_buf_, GPU_shader_get_ssbo(shader, "visibility_buf"));
GPU_storagebuf_bind(bounds, GPU_shader_get_ssbo_binding(shader, "bounds_buf"));
GPU_storagebuf_bind(visibility_buf_, GPU_shader_get_ssbo_binding(shader, "visibility_buf"));
GPU_uniformbuf_bind(frozen_ ? data_freeze_ : data_, DRW_VIEW_UBO_SLOT);
GPU_uniformbuf_bind(frozen_ ? culling_freeze_ : culling_, DRW_VIEW_CULLING_UBO_SLOT);
GPU_compute_dispatch(shader, divide_ceil_u(resource_len, DRW_VISIBILITY_GROUP_SIZE), 1, 1);

View File

@ -17,7 +17,7 @@
#include "BKE_attribute.hh"
#include "BKE_mesh.h"
#include "draw_attributes.h"
#include "draw_attributes.hh"
#include "draw_subdivision.h"
#include "extract_mesh.hh"

View File

@ -18,7 +18,7 @@ GPU_SHADER_INTERFACE_INFO(draw_debug_print_display_iface, "").flat(Type::UINT, "
GPU_SHADER_CREATE_INFO(draw_debug_print_display)
.do_static_compilation(true)
.typedef_source("draw_shader_shared.h")
.storage_buf(7, Qualifier::READ, "uint", "drw_debug_print_buf[]")
.storage_buf(DRW_DEBUG_PRINT_SLOT, Qualifier::READ, "uint", "drw_debug_print_buf[]")
.vertex_out(draw_debug_print_display_iface)
.fragment_out(0, Type::VEC4, "out_color")
.push_constant(Type::VEC2, "viewport_size")
@ -46,7 +46,7 @@ GPU_SHADER_INTERFACE_INFO(draw_debug_draw_display_iface, "interp").flat(Type::VE
GPU_SHADER_CREATE_INFO(draw_debug_draw_display)
.do_static_compilation(true)
.typedef_source("draw_shader_shared.h")
.storage_buf(6, Qualifier::READ, "DRWDebugVert", "drw_debug_verts_buf[]")
.storage_buf(DRW_DEBUG_DRAW_SLOT, Qualifier::READ, "DRWDebugVert", "drw_debug_verts_buf[]")
.vertex_out(draw_debug_draw_display_iface)
.fragment_out(0, Type::VEC4, "out_color")
.push_constant(Type::MAT4, "persmat")

View File

@ -22,6 +22,7 @@
#include "DNA_scene_types.h"
#include "GPU_immediate.h"
#include "GPU_shader_shared.h"
#include "GPU_state.h"
#include "UI_interface.h"

View File

@ -401,9 +401,9 @@ static void add_verts_to_dgroups(ReportList *reports,
vertsfilled = 1;
}
else if (BKE_modifiers_findby_type(ob, eModifierType_Subsurf)) {
/* is subsurf on? Lets use the verts on the limit surface then.
/* Is subdivision-surface on? Lets use the verts on the limit surface then.
* = same amount of vertices as mesh, but vertices moved to the
* subsurfed position, like for 'optimal'. */
* subdivision-surfaced position, like for 'optimal'. */
subsurf_calculate_limit_positions(mesh, verts);
vertsfilled = 1;
}

View File

@ -793,21 +793,19 @@ static int curves_set_selection_domain_exec(bContext *C, wmOperator *op)
if (curves.points_num() == 0) {
continue;
}
const GVArray src = attributes.lookup(".selection", domain);
if (src.is_empty()) {
continue;
}
const CPPType &type = src.type();
void *dst = MEM_malloc_arrayN(attributes.domain_size(domain), type.size(), __func__);
src.materialize(dst);
if (const GVArray src = attributes.lookup(".selection", domain)) {
const CPPType &type = src.type();
void *dst = MEM_malloc_arrayN(attributes.domain_size(domain), type.size(), __func__);
src.materialize(dst);
attributes.remove(".selection");
if (!attributes.add(".selection",
domain,
bke::cpp_type_to_custom_data_type(type),
bke::AttributeInitMoveArray(dst))) {
MEM_freeN(dst);
attributes.remove(".selection");
if (!attributes.add(".selection",
domain,
bke::cpp_type_to_custom_data_type(type),
bke::AttributeInitMoveArray(dst))) {
MEM_freeN(dst);
}
}
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic

View File

@ -357,9 +357,9 @@ static void apply_selection_operation_at_index(GMutableSpan selection,
}
/**
* Helper struct for `find_closest_point_to_screen_co`.
* Helper struct for `select_pick`.
*/
struct FindClosestPointData {
struct FindClosestData {
int index = -1;
float distance = FLT_MAX;
};
@ -371,7 +371,7 @@ static bool find_closest_point_to_screen_co(const Depsgraph &depsgraph,
const bke::CurvesGeometry &curves,
float2 mouse_pos,
float radius,
FindClosestPointData &closest_data)
FindClosestData &closest_data)
{
float4x4 projection;
ED_view3d_ob_project_mat_get(rv3d, &object, projection.ptr());
@ -380,12 +380,12 @@ static bool find_closest_point_to_screen_co(const Depsgraph &depsgraph,
bke::crazyspace::get_evaluated_curves_deformation(depsgraph, object);
const float radius_sq = pow2f(radius);
auto [min_point_index, min_distance] = threading::parallel_reduce(
closest_data = threading::parallel_reduce(
curves.points_range(),
1024,
FindClosestPointData(),
[&](const IndexRange point_range, const FindClosestPointData &init) {
FindClosestPointData best_match = init;
FindClosestData(),
[&](const IndexRange point_range, const FindClosestData &init) {
FindClosestData best_match = init;
for (const int point_i : point_range) {
const float3 pos = deformation.positions[point_i];
@ -400,7 +400,7 @@ static bool find_closest_point_to_screen_co(const Depsgraph &depsgraph,
continue;
}
FindClosestPointData better_candidate;
FindClosestData better_candidate;
better_candidate.index = point_i;
better_candidate.distance = std::sqrt(distance_proj_sq);
@ -408,18 +408,104 @@ static bool find_closest_point_to_screen_co(const Depsgraph &depsgraph,
}
return best_match;
},
[](const FindClosestPointData &a, const FindClosestPointData &b) {
[](const FindClosestData &a, const FindClosestData &b) {
if (a.distance < b.distance) {
return a;
}
return b;
});
if (closest_data.index > 0) {
return true;
}
return false;
}
static bool find_closest_curve_to_screen_co(const Depsgraph &depsgraph,
const ARegion *region,
const RegionView3D *rv3d,
const Object &object,
const bke::CurvesGeometry &curves,
float2 mouse_pos,
float radius,
FindClosestData &closest_data)
{
float4x4 projection;
ED_view3d_ob_project_mat_get(rv3d, &object, projection.ptr());
const bke::crazyspace::GeometryDeformation deformation =
bke::crazyspace::get_evaluated_curves_deformation(depsgraph, object);
const float radius_sq = pow2f(radius);
const OffsetIndices points_by_curve = curves.points_by_curve();
closest_data = threading::parallel_reduce(
curves.curves_range(),
256,
FindClosestData(),
[&](const IndexRange curves_range, const FindClosestData &init) {
FindClosestData best_match = init;
for (const int curve_i : curves_range) {
if (points_by_curve.size(curve_i) == 1) {
const float3 pos = deformation.positions[points_by_curve[curve_i].first()];
/* Find the position of the point in screen space. */
float2 pos_proj;
ED_view3d_project_float_v2_m4(region, pos, pos_proj, projection.ptr());
const float distance_proj_sq = math::distance_squared(pos_proj, mouse_pos);
if (distance_proj_sq > radius_sq ||
distance_proj_sq > best_match.distance * best_match.distance) {
/* Ignore the point because it's too far away or there is already a better point.
*/
continue;
}
FindClosestData better_candidate;
better_candidate.index = curve_i;
better_candidate.distance = std::sqrt(distance_proj_sq);
best_match = better_candidate;
continue;
}
for (const int segment_i : points_by_curve[curve_i].drop_back(1)) {
const float3 pos1 = deformation.positions[segment_i];
const float3 pos2 = deformation.positions[segment_i + 1];
float2 pos1_proj, pos2_proj;
ED_view3d_project_float_v2_m4(region, pos1, pos1_proj, projection.ptr());
ED_view3d_project_float_v2_m4(region, pos2, pos2_proj, projection.ptr());
const float distance_proj_sq = dist_squared_to_line_segment_v2(
mouse_pos, pos1_proj, pos2_proj);
if (distance_proj_sq > radius_sq ||
distance_proj_sq > best_match.distance * best_match.distance) {
/* Ignore the segment because it's too far away or there is already a better point.
*/
continue;
}
FindClosestData better_candidate;
better_candidate.index = curve_i;
better_candidate.distance = std::sqrt(distance_proj_sq);
best_match = better_candidate;
}
}
return best_match;
},
[](const FindClosestData &a, const FindClosestData &b) {
if (a.distance < b.distance) {
return a;
}
return b;
});
if (min_point_index > 0) {
closest_data.index = min_point_index;
closest_data.distance = min_distance;
if (closest_data.index > 0) {
return true;
}
return false;
}
@ -429,15 +515,28 @@ bool select_pick(const ViewContext &vc,
const SelectPick_Params &params,
const int2 coord)
{
FindClosestPointData closest_point;
bool found = find_closest_point_to_screen_co(*vc.depsgraph,
vc.region,
vc.rv3d,
*vc.obact,
curves,
float2(coord),
ED_view3d_select_dist_px(),
closest_point);
FindClosestData closest;
bool found = false;
if (selection_domain == ATTR_DOMAIN_POINT) {
found = find_closest_point_to_screen_co(*vc.depsgraph,
vc.region,
vc.rv3d,
*vc.obact,
curves,
float2(coord),
ED_view3d_select_dist_px(),
closest);
}
else if (selection_domain == ATTR_DOMAIN_CURVE) {
found = find_closest_curve_to_screen_co(*vc.depsgraph,
vc.region,
vc.rv3d,
*vc.obact,
curves,
float2(coord),
ED_view3d_select_dist_px(),
closest);
}
bool changed = false;
if (params.sel_op == SEL_OP_SET) {
@ -453,17 +552,7 @@ bool select_pick(const ViewContext &vc,
if (found) {
bke::GSpanAttributeWriter selection = ensure_selection_attribute(
curves, selection_domain, CD_PROP_BOOL);
int elem_index = closest_point.index;
if (selection_domain == ATTR_DOMAIN_CURVE) {
/* Find the curve index for the found point. */
auto it = std::upper_bound(
curves.offsets().begin(), curves.offsets().end(), closest_point.index);
BLI_assert(it != curves.offsets().end());
elem_index = std::distance(curves.offsets().begin(), it) - 1;
}
apply_selection_operation_at_index(selection.span, elem_index, params.sel_op);
apply_selection_operation_at_index(selection.span, closest.index, params.sel_op);
selection.finish();
}
@ -507,13 +596,29 @@ bool select_box(const ViewContext &vc,
else if (selection_domain == ATTR_DOMAIN_CURVE) {
threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange curves_range) {
for (const int curve_i : curves_range) {
for (const int point_i : points_by_curve[curve_i]) {
if (points_by_curve.size(curve_i) == 1) {
float2 pos_proj;
ED_view3d_project_float_v2_m4(
vc.region, deformation.positions[point_i], pos_proj, projection.ptr());
ED_view3d_project_float_v2_m4(vc.region,
deformation.positions[points_by_curve[curve_i].first()],
pos_proj,
projection.ptr());
if (BLI_rcti_isect_pt_v(&rect, int2(pos_proj))) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
changed = true;
}
continue;
}
for (const int segment_i : points_by_curve[curve_i].drop_back(1)) {
const float3 pos1 = deformation.positions[segment_i];
const float3 pos2 = deformation.positions[segment_i + 1];
float2 pos1_proj, pos2_proj;
ED_view3d_project_float_v2_m4(vc.region, pos1, pos1_proj, projection.ptr());
ED_view3d_project_float_v2_m4(vc.region, pos2, pos2_proj, projection.ptr());
if (BLI_rcti_isect_segment(&rect, int2(pos1_proj), int2(pos2_proj))) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
changed = true;
break;
}
}
@ -569,16 +674,40 @@ bool select_lasso(const ViewContext &vc,
else if (selection_domain == ATTR_DOMAIN_CURVE) {
threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange curves_range) {
for (const int curve_i : curves_range) {
for (const int point_i : points_by_curve[curve_i]) {
if (points_by_curve.size(curve_i) == 1) {
float2 pos_proj;
ED_view3d_project_float_v2_m4(
vc.region, deformation.positions[point_i], pos_proj, projection.ptr());
ED_view3d_project_float_v2_m4(vc.region,
deformation.positions[points_by_curve[curve_i].first()],
pos_proj,
projection.ptr());
/* Check the lasso bounding box first as an optimization. */
if (BLI_rcti_isect_pt_v(&bbox, int2(pos_proj)) &&
BLI_lasso_is_point_inside(
coord_array, coords.size(), int(pos_proj.x), int(pos_proj.y), IS_CLIPPED)) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
changed = true;
}
continue;
}
for (const int segment_i : points_by_curve[curve_i].drop_back(1)) {
const float3 pos1 = deformation.positions[segment_i];
const float3 pos2 = deformation.positions[segment_i + 1];
float2 pos1_proj, pos2_proj;
ED_view3d_project_float_v2_m4(vc.region, pos1, pos1_proj, projection.ptr());
ED_view3d_project_float_v2_m4(vc.region, pos2, pos2_proj, projection.ptr());
/* Check the lasso bounding box first as an optimization. */
if (BLI_rcti_isect_segment(&bbox, int2(pos1_proj), int2(pos2_proj)) &&
BLI_lasso_is_edge_inside(coord_array,
coords.size(),
int(pos1_proj.x),
int(pos1_proj.y),
int(pos2_proj.x),
int(pos2_proj.y),
IS_CLIPPED)) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
changed = true;
break;
}
}
@ -629,13 +758,31 @@ bool select_circle(const ViewContext &vc,
else if (selection_domain == ATTR_DOMAIN_CURVE) {
threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange curves_range) {
for (const int curve_i : curves_range) {
for (const int point_i : points_by_curve[curve_i]) {
if (points_by_curve.size(curve_i) == 1) {
float2 pos_proj;
ED_view3d_project_float_v2_m4(
vc.region, deformation.positions[point_i], pos_proj, projection.ptr());
ED_view3d_project_float_v2_m4(vc.region,
deformation.positions[points_by_curve[curve_i].first()],
pos_proj,
projection.ptr());
if (math::distance_squared(pos_proj, float2(coord)) <= radius_sq) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
changed = true;
}
continue;
}
for (const int segment_i : points_by_curve[curve_i].drop_back(1)) {
const float3 pos1 = deformation.positions[segment_i];
const float3 pos2 = deformation.positions[segment_i + 1];
float2 pos1_proj, pos2_proj;
ED_view3d_project_float_v2_m4(vc.region, pos1, pos1_proj, projection.ptr());
ED_view3d_project_float_v2_m4(vc.region, pos2, pos2_proj, projection.ptr());
const float distance_proj_sq = dist_squared_to_line_segment_v2(
float2(coord), pos1_proj, pos2_proj);
if (distance_proj_sq <= radius_sq) {
apply_selection_operation_at_index(selection.span, curve_i, sel_op);
changed = true;
break;
}
}

View File

@ -959,55 +959,60 @@ static int gizmo_cage2d_invoke(bContext *C, wmGizmo *gz, const wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
static void gizmo_rect_pivot_from_scale_part(int part, float r_pt[2], bool r_constrain_axis[2])
static void gizmo_constrain_from_scale_part(int part, bool r_constrain_axis[2])
{
r_constrain_axis[0] = (part > ED_GIZMO_CAGE2D_PART_SCALE_MAX_X &&
part < ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y) ?
true :
false;
r_constrain_axis[1] = (part > ED_GIZMO_CAGE2D_PART_SCALE &&
part < ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y) ?
true :
false;
}
static void gizmo_pivot_from_scale_part(int part, float r_pt[2])
{
bool x = true, y = true;
switch (part) {
case ED_GIZMO_CAGE2D_PART_SCALE: {
ARRAY_SET_ITEMS(r_pt, 0.0, 0.0);
break;
}
case ED_GIZMO_CAGE2D_PART_SCALE_MIN_X: {
ARRAY_SET_ITEMS(r_pt, 0.5, 0.0);
x = false;
break;
}
case ED_GIZMO_CAGE2D_PART_SCALE_MAX_X: {
ARRAY_SET_ITEMS(r_pt, -0.5, 0.0);
x = false;
break;
}
case ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y: {
ARRAY_SET_ITEMS(r_pt, 0.0, 0.5);
y = false;
break;
}
case ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y: {
ARRAY_SET_ITEMS(r_pt, 0.0, -0.5);
y = false;
break;
}
case ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y: {
ARRAY_SET_ITEMS(r_pt, 0.5, 0.5);
x = y = false;
break;
}
case ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MAX_Y: {
ARRAY_SET_ITEMS(r_pt, 0.5, -0.5);
x = y = false;
break;
}
case ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MIN_Y: {
ARRAY_SET_ITEMS(r_pt, -0.5, 0.5);
x = y = false;
break;
}
case ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MAX_Y: {
ARRAY_SET_ITEMS(r_pt, -0.5, -0.5);
x = y = false;
break;
}
default:
BLI_assert(0);
}
r_constrain_axis[0] = x;
r_constrain_axis[1] = y;
}
static int gizmo_cage2d_modal(bContext *C,
@ -1105,46 +1110,52 @@ static int gizmo_cage2d_modal(bContext *C,
else {
/* scale */
copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset);
float pivot[2];
bool constrain_axis[2] = {false};
const int draw_style = RNA_enum_get(gz->ptr, "draw_style");
float pivot[2];
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE) {
gizmo_rect_pivot_from_scale_part(gz->highlight_part, pivot, constrain_axis);
gizmo_pivot_from_scale_part(gz->highlight_part, pivot);
}
else {
zero_v2(pivot);
}
/* Cursor deltas scaled to (-0.5..0.5). */
float delta_orig[2], delta_curr[2];
for (int i = 0; i < 2; i++) {
delta_orig[i] = ((data->orig_mouse[i] - data->orig_matrix_offset[3][i]) / dims[i]) -
pivot[i];
delta_curr[i] = ((point_local[i] - data->orig_matrix_offset[3][i]) / dims[i]) - pivot[i];
}
bool constrain_axis[2] = {false};
gizmo_constrain_from_scale_part(gz->highlight_part, constrain_axis);
float scale[2] = {1.0f, 1.0f};
for (int i = 0; i < 2; i++) {
if (constrain_axis[i] == false) {
if (delta_orig[i] < 0.0f) {
delta_orig[i] *= -1.0f;
delta_curr[i] *= -1.0f;
}
const int sign = signum_i(scale[i]);
scale[i] = 1.0f + ((delta_curr[i] - delta_orig[i]) / len_v3(data->orig_matrix_offset[i]));
/* Original cursor position relative to pivot, remapped to [-1, 1] */
const float delta_orig = (data->orig_mouse[i] - data->orig_matrix_offset[3][i]) /
(dims[i] * len_v3(data->orig_matrix_offset[i])) -
pivot[i];
const float delta_curr = (point_local[i] - data->orig_matrix_offset[3][i]) /
(dims[i] * len_v3(data->orig_matrix_offset[i])) -
pivot[i];
if ((transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_SCALE_SIGNED) == 0) {
if (sign != signum_i(scale[i])) {
if (signum_i(delta_orig) != signum_i(delta_curr)) {
scale[i] = 0.0f;
continue;
}
}
/* Original cursor position does not exactly lie on the cage boundary due to margin. */
const float delta_boundary = signf(delta_orig) * 0.5f - pivot[i];
scale[i] = delta_curr / delta_boundary;
}
}
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM) {
if (constrain_axis[0] == false && constrain_axis[1] == false) {
scale[1] = scale[0] = (scale[1] + scale[0]) / 2.0f;
if (draw_style == ED_GIZMO_CAGE2D_STYLE_CIRCLE) {
/* So that the cursor lies on the circle. */
scale[1] = scale[0] = len_v2(scale);
}
else {
scale[1] = scale[0] = (scale[1] + scale[0]) / 2.0f;
}
}
else if (constrain_axis[0] == false) {
scale[1] = scale[0];

View File

@ -88,7 +88,10 @@ static void gizmo_calc_rect_view_margin(const wmGizmo *gz, const float dims[3],
/* -------------------------------------------------------------------- */
static void gizmo_rect_pivot_from_scale_part(int part, float r_pt[3], bool r_constrain_axis[3])
static void gizmo_rect_pivot_from_scale_part(int part,
float r_pt[3],
bool r_constrain_axis[3],
bool has_translation)
{
if (part >= ED_GIZMO_CAGE3D_PART_SCALE_MIN_X_MIN_Y_MIN_Z &&
part <= ED_GIZMO_CAGE3D_PART_SCALE_MAX_X_MAX_Y_MAX_Z) {
@ -102,7 +105,7 @@ static void gizmo_rect_pivot_from_scale_part(int part, float r_pt[3], bool r_con
const float sign[3] = {0.5f, 0.0f, -0.5f};
for (int i = 0; i < 3; i++) {
r_pt[i] = sign[range[i]];
r_pt[i] = has_translation ? sign[range[i]] : 0.0f;
r_constrain_axis[i] = (range[i] == 1);
}
}
@ -512,41 +515,33 @@ static int gizmo_cage3d_modal(bContext *C,
else {
/* scale */
copy_m4_m4(gz->matrix_offset, data->orig_matrix_offset);
float pivot[3];
bool constrain_axis[3] = {false};
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE) {
gizmo_rect_pivot_from_scale_part(gz->highlight_part, pivot, constrain_axis);
}
else {
zero_v3(pivot);
}
/* Cursor deltas scaled to (-0.5..0.5). */
float delta_orig[3], delta_curr[3];
for (int i = 0; i < 3; i++) {
delta_orig[i] = ((data->orig_mouse[i] - data->orig_matrix_offset[3][i]) / dims[i]) -
pivot[i];
delta_curr[i] = ((point_local[i] - data->orig_matrix_offset[3][i]) / dims[i]) - pivot[i];
}
bool has_translation = transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_TRANSLATE;
gizmo_rect_pivot_from_scale_part(gz->highlight_part, pivot, constrain_axis, has_translation);
float scale[3] = {1.0f, 1.0f, 1.0f};
for (int i = 0; i < 3; i++) {
if (constrain_axis[i] == false) {
if (delta_orig[i] < 0.0f) {
delta_orig[i] *= -1.0f;
delta_curr[i] *= -1.0f;
}
const int sign = signum_i(scale[i]);
scale[i] = 1.0f + ((delta_curr[i] - delta_orig[i]) / len_v3(data->orig_matrix_offset[i]));
/* Original cursor position relative to pivot, remapped to [-1, 1] */
const float delta_orig = (data->orig_mouse[i] - data->orig_matrix_offset[3][i]) /
(dims[i] * len_v3(data->orig_matrix_offset[i])) -
pivot[i];
const float delta_curr = (point_local[i] - data->orig_matrix_offset[3][i]) /
(dims[i] * len_v3(data->orig_matrix_offset[i])) -
pivot[i];
if ((transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_SCALE_SIGNED) == 0) {
if (sign != signum_i(scale[i])) {
if (signum_i(delta_orig) != signum_i(delta_curr)) {
scale[i] = 0.0f;
continue;
}
}
/* Original cursor position does not exactly lie on the cage boundary due to margin. */
const float delta_boundary = signf(delta_orig) * 0.5f - pivot[i];
scale[i] = delta_curr / delta_boundary;
}
}

View File

@ -528,7 +528,7 @@ static short annotation_stroke_addpoint(tGPsdata *p,
/* store settings */
copy_v2_v2(pt->m_xy, mval);
/* #44932 - Pressure vals are unreliable, so ignore for now */
/* Pressure values are unreliable, so ignore for now, see #44932. */
pt->pressure = 1.0f;
pt->strength = 1.0f;
pt->time = (float)(curtime - p->inittime);
@ -544,7 +544,7 @@ static short annotation_stroke_addpoint(tGPsdata *p,
/* store settings */
copy_v2_v2(pt->m_xy, mval);
/* #44932 - Pressure vals are unreliable, so ignore for now */
/* Pressure values are unreliable, so ignore for now, see #44932. */
pt->pressure = 1.0f;
pt->strength = 1.0f;
pt->time = (float)(curtime - p->inittime);
@ -620,7 +620,7 @@ static short annotation_stroke_addpoint(tGPsdata *p,
/* store settings */
copy_v2_v2(pt->m_xy, mval);
/* #44932 - Pressure vals are unreliable, so ignore for now */
/* Pressure values are unreliable, so ignore for now, see #44932. */
pt->pressure = 1.0f;
pt->strength = 1.0f;
pt->time = (float)(curtime - p->inittime);

View File

@ -4059,12 +4059,11 @@ void GPENCIL_OT_reproject(wmOperatorType *ot)
ot->prop = RNA_def_enum(
ot->srna, "type", reproject_type, GP_REPROJECT_VIEW, "Projection Type", "");
prop = RNA_def_boolean(
ot->srna,
"keep_original",
0,
"Keep Original",
"Keep original strokes and create a copy before reprojecting instead of reproject them");
prop = RNA_def_boolean(ot->srna,
"keep_original",
0,
"Keep Original",
"Keep original strokes and create a copy before reprojecting");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_MOVIECLIP);
RNA_def_float(ot->srna, "offset", 0.0f, 0.0f, 10.0f, "Surface Offset", "", 0.0f, 10.0f);
@ -4771,7 +4770,7 @@ void GPENCIL_OT_stroke_simplify(wmOperatorType *ot)
/* identifiers */
ot->name = "Simplify Stroke";
ot->idname = "GPENCIL_OT_stroke_simplify";
ot->description = "Simplify selected stroked reducing number of points";
ot->description = "Simplify selected strokes, reducing number of points";
/* api callbacks */
ot->exec = gpencil_stroke_simplify_exec;
@ -4832,7 +4831,7 @@ void GPENCIL_OT_stroke_simplify_fixed(wmOperatorType *ot)
/* identifiers */
ot->name = "Simplify Fixed Stroke";
ot->idname = "GPENCIL_OT_stroke_simplify_fixed";
ot->description = "Simplify selected stroked reducing number of points using fixed algorithm";
ot->description = "Simplify selected strokes, reducing number of points using fixed algorithm";
/* api callbacks */
ot->exec = gpencil_stroke_simplify_fixed_exec;

View File

@ -188,7 +188,7 @@ void GPENCIL_OT_stroke_editcurve_set_handle_type(wmOperatorType *ot)
/* identifiers */
ot->name = "Set handle type";
ot->idname = "GPENCIL_OT_stroke_editcurve_set_handle_type";
ot->description = "Set the type of a edit curve handle";
ot->description = "Set the type of an edit curve handle";
/* api callbacks */
ot->invoke = WM_menu_invoke;

View File

@ -1003,8 +1003,8 @@ static void draw_mouse_position(tGPDfill *tgpf)
uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
/* Draw mouse click position in Blue. */
immBindBuiltinProgram(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR);
GPU_point_size(point_size);
immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
immUniform1f("size", point_size * M_SQRT2);
immBegin(GPU_PRIM_POINTS, 1);
immAttr4ubv(col, mouse_color);
immVertex3fv(pos, &pt->x);

View File

@ -764,7 +764,7 @@ static short gpencil_stroke_addpoint(tGPsdata *p,
/* store settings */
copy_v2_v2(pt->m_xy, mval);
/* #44932 - Pressure vals are unreliable, so ignore for now */
/* Pressure values are unreliable, so ignore for now, see #44932. */
pt->pressure = 1.0f;
pt->strength = 1.0f;
pt->time = (float)(curtime - p->inittime);
@ -780,7 +780,7 @@ static short gpencil_stroke_addpoint(tGPsdata *p,
/* store settings */
copy_v2_v2(pt->m_xy, mval);
/* #44932 - Pressure vals are unreliable, so ignore for now */
/* Pressure values are unreliable, so ignore for now, see #44932. */
pt->pressure = 1.0f;
pt->strength = 1.0f;
pt->time = (float)(curtime - p->inittime);
@ -3685,7 +3685,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
/* We don't pass on key events, GP is used with key-modifiers -
* prevents Dkey to insert drivers. */
* prevents D-key to insert drivers. */
if (ISKEYBOARD(event->type)) {
if (ELEM(event->type, EVT_LEFTARROWKEY, EVT_DOWNARROWKEY, EVT_RIGHTARROWKEY, EVT_UPARROWKEY)) {
/* allow some keys:

View File

@ -34,7 +34,7 @@ typedef struct IMMDrawPixelsTexState {
* To be used before calling #immDrawPixelsTex
* Default shader is #GPU_SHADER_2D_IMAGE_COLOR
* You can still set uniforms with:
* `GPU_shader_uniform_int(shader, GPU_shader_get_uniform(shader, "name"), 0);`
* `GPU_shader_uniform_*(shader, "name", value);`
*/
IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin);

View File

@ -236,6 +236,7 @@ typedef enum ThemeColorID {
TH_PATH_KEYFRAME_BEFORE,
TH_PATH_KEYFRAME_AFTER,
TH_CAMERA_PATH,
TH_CAMERA_PASSEPARTOUT,
TH_LOCK_MARKER,
TH_STITCH_PREVIEW_FACE,

View File

@ -49,12 +49,17 @@
#include "eyedropper_intern.hh"
#include "interface_intern.hh"
typedef enum eGP_EyeMode {
GP_EYE_MATERIAL = 0,
GP_EYE_PALETTE = 1,
} eGP_EyeMode;
struct EyedropperGPencil {
struct ColorManagedDisplay *display;
/** color under cursor RGB */
float color[3];
/** Mode */
int mode;
eGP_EyeMode mode;
};
/* Helper: Draw status message while the user is running the operator */
@ -79,7 +84,7 @@ static bool eyedropper_gpencil_init(bContext *C, wmOperator *op)
display_device = scene->display_settings.display_device;
eye->display = IMB_colormanagement_display_get_named(display_device);
eye->mode = RNA_enum_get(op->ptr, "mode");
eye->mode = (eGP_EyeMode)RNA_enum_get(op->ptr, "mode");
return true;
}
@ -228,10 +233,10 @@ static void eyedropper_gpencil_color_set(bContext *C, const wmEvent *event, Eyed
float col_conv[4];
/* Convert from linear rgb space to display space because grease pencil colors are in display
/* Convert from linear rgb space to display space because palette colors are in display
* space, and this conversion is needed to undo the conversion to linear performed by
* eyedropper_color_sample_fl. */
if (eye->display) {
if ((eye->display) && (eye->mode == GP_EYE_PALETTE)) {
copy_v3_v3(col_conv, eye->color);
IMB_colormanagement_scene_linear_to_display_v3(col_conv, eye->display);
}
@ -240,7 +245,7 @@ static void eyedropper_gpencil_color_set(bContext *C, const wmEvent *event, Eyed
}
/* Add material or Palette color. */
if (eye->mode == 0) {
if (eye->mode == GP_EYE_MATERIAL) {
eyedropper_add_material(C, col_conv, only_stroke, only_fill, both);
}
else {
@ -348,8 +353,8 @@ static bool eyedropper_gpencil_poll(bContext *C)
void UI_OT_eyedropper_gpencil_color(wmOperatorType *ot)
{
static const EnumPropertyItem items_mode[] = {
{0, "MATERIAL", 0, "Material", ""},
{1, "PALETTE", 0, "Palette", ""},
{GP_EYE_MATERIAL, "MATERIAL", 0, "Material", ""},
{GP_EYE_PALETTE, "PALETTE", 0, "Palette", ""},
{0, nullptr, 0, nullptr, nullptr},
};
@ -369,5 +374,5 @@ void UI_OT_eyedropper_gpencil_color(wmOperatorType *ot)
ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING;
/* properties */
ot->prop = RNA_def_enum(ot->srna, "mode", items_mode, 0, "Mode", "");
ot->prop = RNA_def_enum(ot->srna, "mode", items_mode, GP_EYE_MATERIAL, "Mode", "");
}

View File

@ -9039,7 +9039,7 @@ static void ui_handle_button_activate(bContext *C,
*/
static bool ui_handle_button_activate_by_type(bContext *C, ARegion *region, uiBut *but)
{
if (but->type == UI_BTYPE_BUT_MENU) {
if (ELEM(but->type, UI_BTYPE_BUT_MENU, UI_BTYPE_ROW)) {
/* mainly for operator buttons */
ui_handle_button_activate(C, region, but, BUTTON_ACTIVATE_APPLY);
}

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