WIP: Vulkan: Workbench #107886

Closed
Jeroen Bakker wants to merge 88 commits from Jeroen-Bakker:vulkan-draw-manager-workbench into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
81 changed files with 642 additions and 297 deletions
Showing only changes of commit 068baff31a - Show all commits

View File

@ -689,7 +689,7 @@ PACKAGES_ALL = (
DISTRO_ID_ARCH: "clang", # clang-format is part of the main clang package.
},
),
Package(name="Python", is_mandatory=True, version="3.10.9", version_short="3.10", version_min="3.10", version_mex="3.12",
Package(name="Python", is_mandatory=True, version="3.10.11", version_short="3.10", version_min="3.10", version_mex="3.12",
sub_packages=PYTHON_SUBPACKAGES,
distro_package_names={DISTRO_ID_DEBIAN: "python3-dev",
DISTRO_ID_FEDORA: "python3-devel",
@ -721,7 +721,7 @@ PACKAGES_ALL = (
DISTRO_ID_ARCH: "opencolorio",
},
),
Package(name="IMath Library", is_mandatory=False, version="3.1.5", version_short="3.1", version_min="3.0", version_mex="4.0",
Package(name="IMath Library", is_mandatory=False, version="3.1.7", version_short="3.1", version_min="3.0", version_mex="4.0",
sub_packages=(),
distro_package_names={DISTRO_ID_DEBIAN: "libimath-dev",
DISTRO_ID_FEDORA: "imath-devel",
@ -729,7 +729,7 @@ PACKAGES_ALL = (
DISTRO_ID_ARCH: "imath",
},
),
Package(name="OpenEXR Library", is_mandatory=False, version="3.1.5", version_short="3.1", version_min="3.0", version_mex="4.0",
Package(name="OpenEXR Library", is_mandatory=False, version="3.1.7", version_short="3.1", version_min="3.0", version_mex="4.0",
sub_packages=(),
distro_package_names={DISTRO_ID_DEBIAN: "libopenexr-dev",
DISTRO_ID_FEDORA: "openexr-devel",
@ -737,7 +737,7 @@ PACKAGES_ALL = (
DISTRO_ID_ARCH: "openexr",
},
),
Package(name="OpenImageIO Library", is_mandatory=True, version="2.4.9.0", version_short="2.4", version_min="2.2.0", version_mex="2.5.0",
Package(name="OpenImageIO Library", is_mandatory=True, version="2.4.11.0", version_short="2.4", version_min="2.2.0", version_mex="2.5.0",
sub_packages=(
Package(name="OpenImageIO Tools", is_mandatory=False,
distro_package_names={DISTRO_ID_DEBIAN: "openimageio-tools",
@ -836,7 +836,7 @@ PACKAGES_ALL = (
DISTRO_ID_ARCH: "materialx-git",
},
),
Package(name="USD Library", is_mandatory=False, version="22.11", version_short="22.11", version_min="20.05", version_mex="23.00",
Package(name="USD Library", is_mandatory=False, version="23.05", version_short="23.05", version_min="20.05", version_mex="24.00",
sub_packages=(),
distro_package_names={DISTRO_ID_DEBIAN: None,
DISTRO_ID_FEDORA: "usd-devel",
@ -851,7 +851,7 @@ PACKAGES_ALL = (
DISTRO_ID_ARCH: "opencollada",
},
),
Package(name="Embree Library", is_mandatory=False, version="3.13.4", version_short="3.13", version_min="3.13", version_mex="5.0",
Package(name="Embree Library", is_mandatory=False, version="4.1.0", version_short="4.1", version_min="3.13", version_mex="5.0",
sub_packages=(),
distro_package_names={DISTRO_ID_DEBIAN: "libembree-dev",
DISTRO_ID_FEDORA: "embree-devel",
@ -867,7 +867,7 @@ PACKAGES_ALL = (
DISTRO_ID_ARCH: "openimagedenoise",
},
),
Package(name="Level Zero Library", is_mandatory=False, version="1.7.15", version_short="1.7", version_min="1.7", version_mex="2.0",
Package(name="Level Zero Library", is_mandatory=False, version="1.8.8", version_short="1.8", version_min="1.7", version_mex="2.0",
sub_packages=(),
distro_package_names={DISTRO_ID_DEBIAN: None,
DISTRO_ID_FEDORA: "oneapi-level-zero-devel",
@ -875,7 +875,7 @@ PACKAGES_ALL = (
DISTRO_ID_ARCH: "level-zero-headers", # ???
},
),
Package(name="OpenPGL Library", is_mandatory=False, version="0.4.1", version_short="0.4", version_min="0.4.1", version_mex="0.5",
Package(name="OpenPGL Library", is_mandatory=False, version="0.5.0", version_short="0.5", version_min="0.5.0", version_mex="0.6",
sub_packages=(),
distro_package_names={DISTRO_ID_DEBIAN: None,
DISTRO_ID_FEDORA: "openpgl-devel",
@ -891,7 +891,7 @@ PACKAGES_ALL = (
DISTRO_ID_ARCH: "openxr",
},
),
Package(name="FFMPEG Library", is_mandatory=False, version="5.1.2", version_short="5.1", version_min="4.0", version_mex="7.0",
Package(name="FFMPEG Library", is_mandatory=False, version="6.0", version_short="6.0", version_min="4.0", version_mex="7.0",
sub_packages=(
Package(name="AVDevice FFMPEG Library", is_mandatory=False,
distro_package_names={DISTRO_ID_DEBIAN: "libavdevice-dev",

View File

@ -122,7 +122,8 @@ bool OneapiDevice::check_peer_access(Device * /*peer_device*/)
bool OneapiDevice::can_use_hardware_raytracing_for_features(uint requested_features) const
{
/* MNEE and Raytrace kernels work correctly with Hardware Raytracing starting with Embree 4.1. */
/* MNEE and Ray-trace kernels work correctly with Hardware Ray-tracing starting with Embree 4.1.
*/
# if defined(RTC_VERSION) && RTC_VERSION < 40100
return !(requested_features & (KERNEL_FEATURE_MNEE | KERNEL_FEATURE_NODE_RAYTRACE));
# else

View File

@ -432,7 +432,7 @@ ccl_gpu_kernel_threads(GPU_PARALLEL_SORTED_INDEX_DEFAULT_BLOCK_SIZE)
}
ccl_gpu_kernel_postfix
/* oneAPI verion needs the local_mem accessor in the arguments. */
/* oneAPI Verizon needs the local_mem accessor in the arguments. */
#ifdef __KERNEL_ONEAPI__
ccl_gpu_kernel_threads(GPU_PARALLEL_SORT_BLOCK_SIZE)
ccl_gpu_kernel_signature(integrator_sort_bucket_pass,
@ -489,7 +489,7 @@ ccl_gpu_kernel_threads(GPU_PARALLEL_SORT_BLOCK_SIZE)
}
ccl_gpu_kernel_postfix
/* oneAPI verion needs the local_mem accessor in the arguments. */
/* oneAPI version needs the local_mem accessor in the arguments. */
#ifdef __KERNEL_ONEAPI__
ccl_gpu_kernel_threads(GPU_PARALLEL_SORT_BLOCK_SIZE)
ccl_gpu_kernel_signature(integrator_sort_write_pass,

View File

@ -109,7 +109,7 @@ size_t oneapi_kernel_preferred_local_size(SyclQueue *queue,
assert(queue);
(void)kernel_global_size;
const static size_t preferred_work_group_size_intersect_shading = 32;
/* Shader evalutation kernels seems to use some amount of shared memory, so better
/* Shader evaluation kernels seems to use some amount of shared memory, so better
* to avoid usage of maximum work group sizes for them. */
const static size_t preferred_work_group_size_shader_evaluation = 256;
const static size_t preferred_work_group_size_default = 1024;
@ -196,7 +196,7 @@ bool oneapi_kernel_is_required_for_features(const std::string &kernel_name,
bool oneapi_kernel_is_compatible_with_hardware_raytracing(const std::string &kernel_name)
{
/* MNEE and Raytrace kernels work correctly with Hardware Raytracing starting with Embree 4.1.
/* MNEE and Ray-trace kernels work correctly with Hardware Ray-tracing starting with Embree 4.1.
*/
# if defined(RTC_VERSION) && RTC_VERSION < 40100
return (kernel_name.find(device_kernel_as_string(DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_MNEE)) ==

View File

@ -73,6 +73,17 @@ struct WGL_XDG_Decor_Window {
struct zxdg_toplevel_decoration_v1 *toplevel_decor = nullptr;
struct xdg_toplevel *toplevel = nullptr;
enum zxdg_toplevel_decoration_v1_mode mode = (enum zxdg_toplevel_decoration_v1_mode)0;
/**
* Defer calling #xdg_surface_ack_configure.
* \note Accessing the members must lock on `win->frame_pending_mutex`.
*/
struct {
/** When set, ACK configure is expected. */
bool ack_configure = false;
/** The serial to pass to ACK configure. */
uint32_t ack_configure_serial = 0;
} pending;
};
static void gwl_xdg_decor_window_destroy(WGL_XDG_Decor_Window *decor)
@ -745,6 +756,18 @@ static void gwl_window_frame_update_from_pending_no_lock(GWL_Window *win)
wl_surface_set_buffer_scale(win->wl_surface, win->frame.buffer_scale);
}
if (win->xdg_decor) {
WGL_XDG_Decor_Window &decor = *win->xdg_decor;
if (decor.pending.ack_configure) {
xdg_surface_ack_configure(decor.surface, decor.pending.ack_configure_serial);
/* The XDG spec states a commit event is required after ACK configure. */
surface_needs_commit = true;
decor.pending.ack_configure = false;
decor.pending.ack_configure_serial = 0;
}
}
if (surface_needs_commit) {
#ifdef USE_EVENT_BACKGROUND_THREAD
/* Postponing the commit avoids flickering when moving between monitors of different scale. */
@ -1179,6 +1202,12 @@ static void xdg_surface_handle_configure(void *data,
}
CLOG_INFO(LOG, 2, "configure");
#ifdef USE_EVENT_BACKGROUND_THREAD
std::lock_guard lock_frame_guard{static_cast<GWL_Window *>(data)->frame_pending_mutex};
#endif
win->xdg_decor->pending.ack_configure = true;
win->xdg_decor->pending.ack_configure_serial = serial;
#ifdef USE_EVENT_BACKGROUND_THREAD
GHOST_SystemWayland *system = win->ghost_system;
const bool is_main_thread = system->main_thread_id == std::this_thread::get_id();
@ -1190,10 +1219,8 @@ static void xdg_surface_handle_configure(void *data,
else
#endif
{
gwl_window_frame_update_from_pending(win);
gwl_window_frame_update_from_pending_no_lock(win);
}
xdg_surface_ack_configure(xdg_surface, serial);
}
static const xdg_surface_listener xdg_surface_listener = {

View File

@ -250,6 +250,15 @@ class Prefs(bpy.types.KeyConfigPreferences):
update=update_fn,
)
use_transform_navigation: BoolProperty(
name="Navigate during Transform",
description=(
"Enable view navigation while using transform operators. "
"Proportional Influence, Automatic Constraints and Auto IK Chain Length shortcuts will require holding Alt key"),
default=False,
update=update_fn,
)
def draw(self, layout):
from bpy import context
@ -313,6 +322,7 @@ class Prefs(bpy.types.KeyConfigPreferences):
sub.prop(self, "use_v3d_tab_menu")
sub.prop(self, "use_pie_click_drag")
sub.prop(self, "use_v3d_shade_ex_pie")
sub.prop(self, "use_transform_navigation")
# File Browser settings.
col = layout.column()
@ -365,6 +375,7 @@ def load():
use_alt_click_leader=kc_prefs.use_alt_click_leader,
use_pie_click_drag=kc_prefs.use_pie_click_drag,
use_file_single_click=kc_prefs.use_file_single_click,
use_transform_navigation=kc_prefs.use_transform_navigation,
),
)

View File

@ -93,6 +93,8 @@ class Params:
# Since this means with RMB select enabled in edit-mode for e.g.
# `Ctrl-LMB` would be caught by box-select instead of add/extrude.
"tool_maybe_tweak_event",
# Changes some transformers modal key-map items to avoid conflicts with navigation operations
"use_transform_navigation",
)
def __init__(
@ -119,6 +121,7 @@ class Params:
use_file_single_click=False,
v3d_tilde_action='VIEW',
v3d_alt_mmb_drag_action='RELATIVE',
use_transform_navigation=False,
):
from sys import platform
self.apple = (platform == 'darwin')
@ -209,6 +212,7 @@ class Params:
self.pie_value = 'CLICK_DRAG' if use_pie_click_drag else 'PRESS'
self.tool_tweak_event = {"type": self.tool_mouse, "value": 'CLICK_DRAG'}
self.tool_maybe_tweak_event = {"type": self.tool_mouse, "value": self.tool_maybe_tweak_value}
self.use_transform_navigation = use_transform_navigation
# ------------------------------------------------------------------------------
@ -1312,7 +1316,7 @@ def km_uv_editor(params):
{"properties": [("extend", True)]}),
])
# 3D cursor
# 2D cursor
if params.cursor_tweak_event:
items.extend([
("uv.cursor_set", params.cursor_set_event, None),
@ -1581,13 +1585,16 @@ def km_view3d(params):
# Transform.
("transform.translate", {"type": params.select_mouse, "value": 'CLICK_DRAG'}, None),
op_tool_optional(
("transform.translate", {"type": 'G', "value": 'PRESS'}, None),
("transform.translate", {"type": 'G', "value": 'PRESS'},
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
(op_tool_cycle, "builtin.move"), params),
op_tool_optional(
("transform.rotate", {"type": 'R', "value": 'PRESS'}, None),
("transform.rotate", {"type": 'R', "value": 'PRESS'},
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
(op_tool_cycle, "builtin.rotate"), params),
op_tool_optional(
("transform.resize", {"type": 'S', "value": 'PRESS'}, None),
("transform.resize", {"type": 'S', "value": 'PRESS'},
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
(op_tool_cycle, "builtin.scale"), params),
op_tool_optional(
("transform.tosphere", {"type": 'S', "value": 'PRESS', "shift": True, "alt": True}, None),
@ -3470,7 +3477,6 @@ def km_animation_channels(params):
("anim.channels_click", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True, "ctrl": True},
{"properties": [("children_only", True)]}),
# Rename.
("anim.channels_rename", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, None),
("anim.channels_rename", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None),
# Select keys.
("anim.channel_select_keys", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None),
@ -4681,10 +4687,13 @@ def km_paint_curve(params):
("paintcurve.delete_point", {"type": 'DEL', "value": 'PRESS'}, None),
("paintcurve.draw", {"type": 'RET', "value": 'PRESS'}, None),
("paintcurve.draw", {"type": 'NUMPAD_ENTER', "value": 'PRESS'}, None),
("transform.translate", {"type": 'G', "value": 'PRESS'}, None),
("transform.translate", {"type": 'G', "value": 'PRESS'},
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
("transform.translate", {"type": params.select_mouse, "value": 'CLICK_DRAG'}, None),
("transform.rotate", {"type": 'R', "value": 'PRESS'}, None),
("transform.resize", {"type": 'S', "value": 'PRESS'}, None),
("transform.rotate", {"type": 'R', "value": 'PRESS'},
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
("transform.resize", {"type": 'S', "value": 'PRESS'},
{"properties": [("allow_navigation", params.use_transform_navigation)]}),
])
return keymap
@ -5844,7 +5853,7 @@ def km_eyedropper_colorramp_pointsampling_map(_params):
return keymap
def km_transform_modal_map(_params):
def km_transform_modal_map(params):
items = []
keymap = (
"Transform Modal Map",
@ -5884,24 +5893,24 @@ def km_transform_modal_map(_params):
("PROPORTIONAL_SIZE_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, None),
("PROPORTIONAL_SIZE_UP", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True, "repeat": True}, None),
("PROPORTIONAL_SIZE_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True, "repeat": True}, None),
("PROPORTIONAL_SIZE_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS'}, None),
("PROPORTIONAL_SIZE_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS'}, None),
("PROPORTIONAL_SIZE_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "alt": params.use_transform_navigation}, None),
("PROPORTIONAL_SIZE_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "alt": params.use_transform_navigation}, None),
("PROPORTIONAL_SIZE_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "shift": True}, None),
("PROPORTIONAL_SIZE_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "shift": True}, None),
("PROPORTIONAL_SIZE", {"type": 'TRACKPADPAN', "value": 'ANY'}, None),
("PROPORTIONAL_SIZE", {"type": 'TRACKPADPAN', "value": 'ANY', "alt": params.use_transform_navigation}, None),
("AUTOIK_CHAIN_LEN_UP", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, None),
("AUTOIK_CHAIN_LEN_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, None),
("AUTOIK_CHAIN_LEN_UP", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True, "repeat": True}, None),
("AUTOIK_CHAIN_LEN_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True, "repeat": True}, None),
("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS'}, None),
("AUTOIK_CHAIN_LEN_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS'}, None),
("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "alt": params.use_transform_navigation}, None),
("AUTOIK_CHAIN_LEN_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "alt": params.use_transform_navigation}, None),
("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "shift": True}, None),
("AUTOIK_CHAIN_LEN_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "shift": True}, None),
("INSERTOFS_TOGGLE_DIR", {"type": 'T', "value": 'PRESS'}, None),
("NODE_ATTACH_ON", {"type": 'LEFT_ALT', "value": 'RELEASE', "any": True}, None),
("NODE_ATTACH_OFF", {"type": 'LEFT_ALT', "value": 'PRESS', "any": True}, None),
("AUTOCONSTRAIN", {"type": 'MIDDLEMOUSE', "value": 'ANY'}, None),
("AUTOCONSTRAINPLANE", {"type": 'MIDDLEMOUSE', "value": 'ANY', "shift": True}, None),
("AUTOCONSTRAIN", {"type": 'MIDDLEMOUSE', "value": 'ANY', "alt": params.use_transform_navigation}, None),
("AUTOCONSTRAINPLANE", {"type": 'MIDDLEMOUSE', "value": 'ANY', "shift": True, "alt": params.use_transform_navigation}, None),
("PRECISION", {"type": 'LEFT_SHIFT', "value": 'ANY', "any": True}, None),
("PRECISION", {"type": 'RIGHT_SHIFT', "value": 'ANY', "any": True}, None),
])

View File

@ -1038,10 +1038,22 @@ class VIEW3D_MT_transform_base:
# TODO: get rid of the custom text strings?
def draw(self, context):
layout = self.layout
allow_navigation = getattr(
context.window_manager.keyconfigs.active.preferences,
"use_transform_navigation",
False)
layout.operator("transform.translate")
layout.operator("transform.rotate")
layout.operator("transform.resize", text="Scale")
props = layout.operator("transform.translate")
props.release_confirm = False
props.allow_navigation = allow_navigation
props = layout.operator("transform.rotate")
props.release_confirm = False
props.allow_navigation = allow_navigation
props = layout.operator("transform.resize", text="Scale")
props.release_confirm = False
props.allow_navigation = allow_navigation
layout.separator()

View File

@ -155,6 +155,17 @@ class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel):
bl_options = {'DEFAULT_CLOSED'}
bl_ui_units_x = 12
def draw(self, _context):
# layout = self.layout
pass
class VIEW3D_PT_tools_meshedit_options_transform(View3DPanel, Panel):
bl_category = "Tool"
bl_context = ".mesh_edit" # dot on purpose (access from topbar)
bl_label = "Transform"
bl_parent_id = "VIEW3D_PT_tools_meshedit_options"
@classmethod
def poll(cls, context):
return context.active_object
@ -169,56 +180,47 @@ class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel):
ob = context.active_object
mesh = ob.data
row = layout.row(align=True, heading="Transform")
row.prop(tool_settings, "use_transform_correct_face_attributes")
col = layout.column(align=True)
col.prop(tool_settings, "use_transform_correct_face_attributes")
sub = col.column(align=True)
sub.active = tool_settings.use_transform_correct_face_attributes
sub.prop(tool_settings, "use_transform_correct_keep_connected")
col.separator()
row = layout.row(align=True)
row.active = tool_settings.use_transform_correct_face_attributes
row.prop(tool_settings, "use_transform_correct_keep_connected")
row = layout.row(align=True, heading="UVs")
row.prop(tool_settings, "use_edge_path_live_unwrap")
row = layout.row(heading="Mirror")
sub = row.row(align=True)
col = layout.column(heading="Mirror")
sub = col.row(align=True)
sub.prop(mesh, "use_mirror_x", text="X", toggle=True)
sub.prop(mesh, "use_mirror_y", text="Y", toggle=True)
sub.prop(mesh, "use_mirror_z", text="Z", toggle=True)
row = layout.row(align=True)
row.active = ob.data.use_mirror_x or ob.data.use_mirror_y or ob.data.use_mirror_z
row.prop(mesh, "use_mirror_topology")
col = layout.column(align=True)
col.active = mesh.use_mirror_x or mesh.use_mirror_y or mesh.use_mirror_z
col.prop(mesh, "use_mirror_topology")
col.separator()
col = layout.column(align=True)
col.prop(tool_settings, "use_mesh_automerge", text="Auto Merge", toggle=False)
sub = col.column(align=True)
sub.active = tool_settings.use_mesh_automerge
sub.prop(tool_settings, "use_mesh_automerge_and_split", toggle=False)
sub.prop(tool_settings, "double_threshold", text="Threshold")
class VIEW3D_PT_tools_meshedit_options_automerge(View3DPanel, Panel):
class VIEW3D_PT_tools_meshedit_options_uvs(View3DPanel, Panel):
bl_category = "Tool"
bl_context = ".mesh_edit" # dot on purpose (access from topbar)
bl_label = "Auto Merge"
bl_label = "UVs"
bl_parent_id = "VIEW3D_PT_tools_meshedit_options"
bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
return context.active_object
def draw_header(self, context):
tool_settings = context.tool_settings
self.layout.use_property_split = False
self.layout.prop(tool_settings, "use_mesh_automerge",
text=self.bl_label if self.is_popover else "", toggle=False)
def draw(self, context):
layout = self.layout
layout.use_property_decorate = False
layout.use_property_split = True
tool_settings = context.tool_settings
layout.use_property_split = True
layout.use_property_decorate = False
col = layout.column(align=True)
col.active = tool_settings.use_mesh_automerge
col.prop(tool_settings, "use_mesh_automerge_and_split", toggle=False)
col.prop(tool_settings, "double_threshold", text="Threshold")
layout.prop(tool_settings, "use_edge_path_live_unwrap")
# ********** default tools for editmode_armature ****************
@ -2368,7 +2370,8 @@ classes = (
VIEW3D_PT_tools_object_options,
VIEW3D_PT_tools_object_options_transform,
VIEW3D_PT_tools_meshedit_options,
VIEW3D_PT_tools_meshedit_options_automerge,
VIEW3D_PT_tools_meshedit_options_transform,
VIEW3D_PT_tools_meshedit_options_uvs,
VIEW3D_PT_tools_armatureedit_options,
VIEW3D_PT_tools_posemode_options,

View File

@ -480,7 +480,7 @@ bool BKE_fcurve_bezt_subdivide_handles(struct BezTriple *bezt,
/**
* Resize the FCurve 'bezt' array to fit the given length.
*
* \param new_totvert new number of elements in the FCurve's `bezt` array.
* \param new_totvert: new number of elements in the FCurve's `bezt` array.
* Constraint: `0 <= new_totvert <= fcu->totvert`
*/
void BKE_fcurve_bezt_shrink(struct FCurve *fcu, int new_totvert);

View File

@ -311,10 +311,11 @@ void BKE_id_delete(struct Main *bmain, void *idv) ATTR_NONNULL();
/**
* Like BKE_id_delete, but with extra corner-case options.
*
* \param extra_remapping_flags Additional `ID_REMAP_` flags to pass to remapping code when
* \param extra_remapping_flags: Additional `ID_REMAP_` flags to pass to remapping code when
* ensuring that deleted IDs are not used by any other ID in given `bmain`. Typical example would
* be e.g. `ID_REMAP_FORCE_UI_POINTERS`, required when default UI-handling callbacks of remapping
* code won't be working (e.g. from readfile code). */
* code won't be working (e.g. from readfile code).
*/
void BKE_id_delete_ex(struct Main *bmain, void *idv, const int extra_remapping_flags)
ATTR_NONNULL(1, 2);
/**

View File

@ -86,7 +86,7 @@ void normals_calc_poly_vert(Span<float3> vert_positions,
* \{ */
/**
* Combined with the automatically calculated face corner normal, this gives a dimentional
* Combined with the automatically calculated face corner normal, this gives a dimensional
* coordinate space used to convert normals between the "custom normal" #short2 representation and
* a regular #float3 format.
*/

View File

@ -19,7 +19,7 @@ struct CustomData_MeshMasks;
struct MemArena;
struct Mesh;
/* Generic ways to map some geometry elements from a source mesh to a dest one. */
/* Generic ways to map some geometry elements from a source mesh to a destination one. */
typedef struct MeshPairRemapItem {
int sources_num;
@ -33,7 +33,7 @@ typedef struct MeshPairRemapItem {
/* All mapping computing func return this. */
typedef struct MeshPairRemap {
int items_num;
MeshPairRemapItem *items; /* array, one item per dest element. */
MeshPairRemapItem *items; /* Array, one item per destination element. */
struct MemArena *mem; /* memory arena, internal use only. */
} MeshPairRemap;
@ -89,7 +89,7 @@ enum {
/* ***** Target's edges ***** */
MREMAP_MODE_EDGE = 1 << 25,
/* Source edge which both vertices are nearest of dest ones. */
/* Source edge which both vertices are nearest of destination ones. */
MREMAP_MODE_EDGE_VERT_NEAREST = MREMAP_MODE_EDGE | MREMAP_USE_VERT | MREMAP_USE_NEAREST,
/* Nearest source edge (using mid-point). */
@ -98,7 +98,7 @@ enum {
/* Nearest edge of nearest poly (using mid-point). */
MREMAP_MODE_EDGE_POLY_NEAREST = MREMAP_MODE_EDGE | MREMAP_USE_POLY | MREMAP_USE_NEAREST,
/* Cast a set of rays from along dest edge,
/* Cast a set of rays from along destination edge,
* interpolating its vertices' normals, and use hit source edges. */
MREMAP_MODE_EDGE_EDGEINTERP_VNORPROJ = MREMAP_MODE_EDGE | MREMAP_USE_VERT | MREMAP_USE_NORPROJ |
MREMAP_USE_INTERP,
@ -131,10 +131,10 @@ enum {
/* Nearest source poly. */
MREMAP_MODE_POLY_NEAREST = MREMAP_MODE_POLY | MREMAP_USE_POLY | MREMAP_USE_NEAREST,
/* Source poly from best normal-matching dest poly. */
/* Source poly from best normal-matching destination poly. */
MREMAP_MODE_POLY_NOR = MREMAP_MODE_POLY | MREMAP_USE_POLY | MREMAP_USE_NORMAL,
/* Project dest poly onto source mesh using its normal,
/* Project destination poly onto source mesh using its normal,
* and use interpolation of all intersecting source polys. */
MREMAP_MODE_POLY_POLYINTERP_PNORPROJ = MREMAP_MODE_POLY | MREMAP_USE_POLY | MREMAP_USE_NORPROJ |
MREMAP_USE_INTERP,

View File

@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2005 Blender Foundation */
* Copyright 2023 Blender Foundation */
#pragma once

View File

@ -334,7 +334,7 @@ static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss,
0, numEffectedF, &data, ccgSubSurf__calcVertNormals_faces_accumulate_cb, &settings);
}
/* XXX can I reduce the number of normalisations here? */
/* XXX can I reduce the number of normalization calls here? */
for (ptrIdx = 0; ptrIdx < numEffectedV; ptrIdx++) {
CCGVert *v = (CCGVert *)effectedV[ptrIdx];
float *no = VERT_getNo(v, lvl);

View File

@ -641,8 +641,8 @@ static int animsys_quaternion_evaluate_fcurves(PathResolvedRNA quat_rna,
}
if (fcurve_offset < 4) {
/* This quaternion was incompletely keyed, so the result is a mixture of the unit quaterion and
* values from FCurves. This means that it's almost certainly no longer of unit length. */
/* This quaternion was incompletely keyed, so the result is a mixture of the unit quaternion
* and values from FCurves. This means that it's almost certainly no longer of unit length. */
normalize_qt(r_quaternion);
}

View File

@ -611,7 +611,7 @@ static bool data_transfer_layersmapping_cdlayers_multisrc_to_dst(ListBase *r_map
bool *data_dst_to_delete = nullptr;
if (!use_layers_src) {
/* No source at all, we can only delete all dest if requested... */
/* No source at all, we can only delete all destination if requested. */
if (use_delete) {
idx_dst = tot_dst;
while (idx_dst--) {
@ -1421,7 +1421,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
}
/* Check all possible data types.
* Note item mappings and dest mix weights are cached. */
* Note item mappings and destination mix weights are cached. */
for (int i = 0; i < DT_TYPE_MAX; i++) {
const int dtdata_type = 1 << i;
int cddata_type;

View File

@ -1006,7 +1006,7 @@ void BKE_main_view_layers_synced_ensure(const Main *bmain)
BKE_scene_view_layers_synced_ensure(scene);
}
/* NOTE: This is not (yet?) covered by the dirty tag and deffered re-sync system. */
/* NOTE: This is not (yet?) covered by the dirty tag and deferred re-sync system. */
BKE_layer_collection_local_sync_all(bmain);
}

View File

@ -198,8 +198,9 @@ void BKE_lib_override_library_copy(ID *dst_id, const ID *src_id, const bool do_f
BKE_lib_override_library_init(dst_id, nullptr);
}
/* If source is already overriding data, we copy it but reuse its reference for dest ID.
* Otherwise, source is only an override template, it then becomes reference of dest ID. */
/* If source is already overriding data, we copy it but reuse its reference for destination ID.
* Otherwise, source is only an override template, it then becomes reference of destination ID.
*/
dst_id->override_library->reference = src_id->override_library->reference ?
src_id->override_library->reference :
const_cast<ID *>(src_id);
@ -1776,7 +1777,7 @@ static void lib_override_library_remap(Main *bmain,
*
* In case linked data keep being modified, these conditions may fail and the mapping may start to
* return 'wrong' results. However, this is considered as an acceptable limitation here, since this
* is mainly a 'best effort' to recover from situations that should not be hapenning in the first
* is mainly a 'best effort' to recover from situations that should not be happening in the first
* place.
*/
@ -2061,7 +2062,7 @@ static bool lib_override_library_resync(Main *bmain,
}
/* Get a mapping of all missing linked IDs that were liboverrides, to search for 'old
* liboverrides' for newly created ones that do not alredy have one, in next step. */
* liboverrides' for newly created ones that do not already have one, in next step. */
LibOverrideMissingIDsData missing_ids_data = lib_override_library_resync_build_missing_ids_data(
bmain);
@ -2638,7 +2639,8 @@ static bool lib_override_library_main_resync_id_skip_check(ID *id,
return false;
}
/* Clear 'unreachable' tag of existing liboverrides if they are using another reachable liboverride
/**
* Clear 'unreachable' tag of existing liboverrides if they are using another reachable liboverride
* (typical case: Mesh object which only relationship to the rest of the liboverride hierarchy is
* though its 'parent' pointer (i.e. rest of the hierarchy has no actual relationship to this mesh
* object). Sadge.
@ -2646,7 +2648,8 @@ static bool lib_override_library_main_resync_id_skip_check(ID *id,
* Logic and rational of this function are very similar to these of
* #lib_override_hierarchy_dependencies_recursive_tag_from, but withing specific resync context.
*
* \returns True if it finds a non-isolated 'parent' ID, false otherwise. */
* \returns True if it finds a non-isolated 'parent' ID, false otherwise.
*/
static bool lib_override_resync_tagging_finalize_recursive_check_from(
Main *bmain, ID *id, const int library_indirect_level)
{

View File

@ -257,7 +257,7 @@ static void object_defgroup_remove_common(Object *ob, bDeformGroup *dg, const in
BKE_object_defgroup_active_index_set(ob, active_index - 1);
}
/* remove all dverts */
/* Remove all deform-verts. */
if (BLI_listbase_is_empty(defbase)) {
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
@ -404,8 +404,8 @@ void BKE_object_defgroup_remove_all_ex(struct Object *ob, bool only_unlocked)
dg = next_dg;
}
}
else { /* defbase is empty... */
/* remove all dverts */
else { /* `defbase` is empty. */
/* Remove all deform-verts. */
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);

View File

@ -111,7 +111,8 @@ template<typename Ret, typename... Params> class FunctionRef<Ret(Params...)> {
*/
template<typename Callable,
BLI_ENABLE_IF((
!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Callable>>, FunctionRef>))>
!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Callable>>, FunctionRef>)),
BLI_ENABLE_IF((std::is_invocable_r_v<Ret, Callable, Params...>))>
FunctionRef(Callable &&callable)
: callback_(callback_fn<typename std::remove_reference_t<Callable>>),
callable_(intptr_t(&callable))

View File

@ -105,6 +105,11 @@ class IndexRange {
return a.current_ == b.current_;
}
constexpr friend int64_t operator-(const Iterator &a, const Iterator &b)
{
return a.current_ - b.current_;
}
constexpr int64_t operator*() const
{
return current_;
@ -151,6 +156,11 @@ class IndexRange {
return size_;
}
constexpr IndexRange index_range() const
{
return IndexRange(size_);
}
/**
* Returns true if the size is zero.
*/

View File

@ -285,7 +285,8 @@ BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
lb->first = lb->last = (void *)0;
}
/** Validate the integrity of a given ListBase, returns `true` if evrything is OK, false otherwise.
/** Validate the integrity of a given ListBase, returns `true` if everything is OK, false
* otherwise.
*/
bool BLI_listbase_validate(struct ListBase *lb);

View File

@ -621,7 +621,7 @@ bool BLI_path_frame_check_chars(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUS
/** \} */
/* -------------------------------------------------------------------- */
/** \name Blender Spesific File Relative Paths
/** \name Blender Specific File Relative Paths
* \{ */
/**

View File

@ -30,6 +30,7 @@
# endif
#endif
#include "BLI_function_ref.hh"
#include "BLI_index_range.hh"
#include "BLI_lazy_threading.hh"
#include "BLI_utildefines.h"
@ -48,27 +49,23 @@ void parallel_for_each(Range &&range, const Function &function)
#endif
}
namespace detail {
void parallel_for_impl(IndexRange range,
int64_t grain_size,
FunctionRef<void(IndexRange)> function);
} // namespace detail
template<typename Function>
void parallel_for(IndexRange range, int64_t grain_size, const Function &function)
inline void parallel_for(IndexRange range, int64_t grain_size, const Function &function)
{
if (range.size() == 0) {
if (range.is_empty()) {
return;
}
#ifdef WITH_TBB
/* Invoking tbb for small workloads has a large overhead. */
if (range.size() >= grain_size) {
lazy_threading::send_hint();
tbb::parallel_for(
tbb::blocked_range<int64_t>(range.first(), range.one_after_last(), grain_size),
[&](const tbb::blocked_range<int64_t> &subrange) {
function(IndexRange(subrange.begin(), subrange.size()));
});
if (range.size() <= grain_size) {
function(range);
return;
}
#else
UNUSED_VARS(grain_size);
#endif
function(range);
detail::parallel_for_impl(range, grain_size, function);
}
/**

View File

@ -403,7 +403,7 @@ int BLI_rename_overwrite(const char *from, const char *to)
* Support for checking the files aren't the same could be added, however path comparison
* alone is *not* a guarantee the files are different (given the possibility of accessing
* the same file through different paths via symbolic-links), we could instead support a
* verizon of Python's * `os.path.samefile(..)` which compares the I-node & device.
* version of Python's `os.path.samefile(..)` which compares the I-node & device.
* In this particular case we would not want to follow symbolic-links as well.
* Since this functionality isn't required at the moment, leave this as-is.
* Noting it as a potential improvement. */

View File

@ -352,7 +352,7 @@ void mat3_normalized_to_quat_fast(float q[4], const float mat[3][3])
BLI_assert(!(q[0] < 0.0f));
/* Sometimes normalisation is necessary due to round-off errors in the above
/* Sometimes normalization is necessary due to round-off errors in the above
* calculations. The comparison here uses tighter tolerances than
* BLI_ASSERT_UNIT_QUAT(), so it's likely that even after a few more
* transformations the quaternion will still be considered unit-ish. */

View File

@ -344,7 +344,7 @@ void BLI_str_cursor_step_bounds_utf8(
BLI_str_cursor_step_utf8(str, str_maxlen, r_start, STRCUR_DIR_PREV, STRCUR_JUMP_DELIM, false);
}
if ((prev >= next) && (next != STRCUR_DELIM_NONE)) {
/* Expand forward if we are between similar content, after whitespace, or at beginning. */
/* Expand forward if we are between similar content. */
BLI_str_cursor_step_utf8(str, str_maxlen, r_end, STRCUR_DIR_NEXT, STRCUR_JUMP_DELIM, false);
}
}
@ -361,11 +361,11 @@ void BLI_str_cursor_step_bounds_utf32(
*r_end = pos;
if ((prev <= next) && (prev != STRCUR_DELIM_NONE)) {
/* Expand backward if we are between similar content, before whitespace, or at end. */
/* Expand backward if we are between similar content. */
BLI_str_cursor_step_utf32(str, str_maxlen, r_start, STRCUR_DIR_PREV, STRCUR_JUMP_DELIM, false);
}
if ((prev >= next) && (next != STRCUR_DELIM_NONE)) {
/* Expand forward if we are between similar content, after whitespace, or at beginning. */
/* Expand forward if we are between similar content. */
BLI_str_cursor_step_utf32(str, str_maxlen, r_end, STRCUR_DIR_NEXT, STRCUR_JUMP_DELIM, false);
}
}

View File

@ -14,6 +14,7 @@
#include "BLI_lazy_threading.hh"
#include "BLI_task.h"
#include "BLI_task.hh"
#include "BLI_threads.h"
#include "atomic_ops.h"
@ -154,3 +155,28 @@ int BLI_task_parallel_thread_id(const TaskParallelTLS * /*tls*/)
return 0;
#endif
}
namespace blender::threading::detail {
void parallel_for_impl(const IndexRange range,
const int64_t grain_size,
const FunctionRef<void(IndexRange)> function)
{
#ifdef WITH_TBB
/* Invoking tbb for small workloads has a large overhead. */
if (range.size() >= grain_size) {
lazy_threading::send_hint();
tbb::parallel_for(
tbb::blocked_range<int64_t>(range.first(), range.one_after_last(), grain_size),
[function](const tbb::blocked_range<int64_t> &subrange) {
function(IndexRange(subrange.begin(), subrange.size()));
});
return;
}
#else
UNUSED_VARS(grain_size);
#endif
function(range);
}
} // namespace blender::threading::detail

View File

@ -130,4 +130,23 @@ TEST(function_ref, InitializeWithNull)
EXPECT_FALSE(f);
}
static int overload_test(const FunctionRef<void(std::string)> /*fn*/)
{
return 1;
}
static int overload_test(const FunctionRef<void(int)> /*fn*/)
{
return 2;
}
TEST(function_ref, OverloadSelection)
{
const auto fn_1 = [](std::string /*x*/) {};
const auto fn_2 = [](int /*x*/) {};
EXPECT_EQ(overload_test(fn_1), 1);
EXPECT_EQ(overload_test(fn_2), 2);
}
} // namespace blender::tests

View File

@ -271,12 +271,15 @@ struct BlendFileReadReport *BLO_read_data_reports(BlendDataReader *reader);
* However, now only pointers to ID data blocks are updated.
* \{ */
/** Search for the new address of given `id`, during liblinking part of blendfile reading process.
/**
* Search for the new address of given `id`,
* during library linking part of blend-file reading process.
*
* \param self_id the ID owner of the given `id` pointer. Note that it may be an embedded ID.
* \param do_linked_only If `true`, only return found pointer if it is a linked ID. Used to
* preventlinked data to point to local IDs.
* \return the new address of the given ID pointer, or null if not found. */
* \param self_id: the ID owner of the given `id` pointer. Note that it may be an embedded ID.
* \param do_linked_only: If `true`, only return found pointer if it is a linked ID. Used to
* prevent linked data to point to local IDs.
* \return the new address of the given ID pointer, or null if not found.
*/
ID *BLO_read_get_new_id_address(BlendLibReader *reader,
struct ID *self_id,
const bool do_linked_only,

View File

@ -199,7 +199,7 @@ bool BLO_main_validate_shapekeys(Main *bmain, ReportList *reports)
shapekey->from);
/* NOTE: also need to remap UI data ID pointers here, since `bmain` is not the current
* `G_MAIN`, default UI-handling remapping callback (defined by call to
* `BKE_library_callback_remap_editor_id_reference_set`) won't work on exoected data here. */
* `BKE_library_callback_remap_editor_id_reference_set`) won't work on expected data here. */
BKE_id_delete_ex(bmain, shapekey, ID_REMAP_FORCE_UI_POINTERS);
}

View File

@ -98,7 +98,7 @@ typedef struct FileData {
/**
* Store mapping from old ID pointers (the values they have in the .blend file) to new ones,
* typically from value in `bhead->old` to address in memory where the ID was read.
* Used during liblinking process (see #lib_link_all).
* Used during library-linking process (see #lib_link_all).
*/
struct OldNewMap *libmap;
@ -115,7 +115,7 @@ typedef struct FileData {
/** Used for undo. */
ListBase *old_mainlist;
/**
* IDMap using uuids as keys of all the old IDs in the old bmain. Used during undo to find a
* IDMap using UUID's as keys of all the old IDs in the old bmain. Used during undo to find a
* matching old data when reading a new ID. */
struct IDNameLib_Map *old_idmap_uuid;

View File

@ -996,8 +996,8 @@ void blo_do_versions_250(FileData *fd, Library *UNUSED(lib), Main *bmain)
* to the evaluated #Mesh, so here we ensure that the basis
* shape key is always set in the mesh coordinates. */
for (me = bmain->meshes.first; me; me = me->id.next) {
if ((key = blo_do_versions_newlibadr(fd, &me->id, ID_IS_LINKED(me), me->key)) &&
key->refkey) {
if ((key = blo_do_versions_newlibadr(fd, &me->id, ID_IS_LINKED(me), me->key)) && key->refkey)
{
data = key->refkey->data;
tot = MIN2(me->totvert, key->refkey->totelem);
MVert *verts = (MVert *)CustomData_get_layer_for_write(&me->vdata, CD_MVERT, me->totvert);
@ -1008,8 +1008,8 @@ void blo_do_versions_250(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
for (lt = bmain->lattices.first; lt; lt = lt->id.next) {
if ((key = blo_do_versions_newlibadr(fd, &lt->id, ID_IS_LINKED(lt), lt->key)) &&
key->refkey) {
if ((key = blo_do_versions_newlibadr(fd, &lt->id, ID_IS_LINKED(lt), lt->key)) && key->refkey)
{
data = key->refkey->data;
tot = MIN2(lt->pntsu * lt->pntsv * lt->pntsw, key->refkey->totelem);
@ -1020,8 +1020,8 @@ void blo_do_versions_250(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
for (cu = bmain->curves.first; cu; cu = cu->id.next) {
if ((key = blo_do_versions_newlibadr(fd, &cu->id, ID_IS_LINKED(cu), cu->key)) &&
key->refkey) {
if ((key = blo_do_versions_newlibadr(fd, &cu->id, ID_IS_LINKED(cu), cu->key)) && key->refkey)
{
data = key->refkey->data;
for (nu = cu->nurb.first; nu; nu = nu->next) {

View File

@ -644,6 +644,11 @@ static bool seq_speed_factor_set(Sequence *seq, void *user_data)
seq_speed_factor_fix_rna_path(seq, &scene->adt->drivers);
}
/* Pitch value of 0 has been found in some files. This would cause problems. */
if (seq->pitch <= 0.0f) {
seq->pitch = 1.0f;
}
seq->speed_factor = seq->pitch;
}
else {
@ -1136,7 +1141,8 @@ void do_versions_after_linking_300(FileData * /*fd*/, Main *bmain)
SOCK_OBJECT,
SOCK_COLLECTION,
SOCK_TEXTURE,
SOCK_MATERIAL)) {
SOCK_MATERIAL))
{
link->tosock = link->tosock->next;
}
}
@ -2647,7 +2653,8 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
if (!MAIN_VERSION_ATLEAST(bmain, 300, 17)) {
if (!DNA_struct_elem_find(
fd->filesdna, "View3DOverlay", "float", "normals_constant_screen_size")) {
fd->filesdna, "View3DOverlay", "float", "normals_constant_screen_size"))
{
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
@ -2675,7 +2682,8 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
if (!MAIN_VERSION_ATLEAST(bmain, 300, 18)) {
if (!DNA_struct_elem_find(
fd->filesdna, "WorkSpace", "AssetLibraryReference", "asset_library_ref")) {
fd->filesdna, "WorkSpace", "AssetLibraryReference", "asset_library_ref"))
{
LISTBASE_FOREACH (WorkSpace *, workspace, &bmain->workspaces) {
BKE_asset_library_reference_init_default(&workspace->asset_library_ref);
}
@ -3251,20 +3259,6 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
}
}
if (!MAIN_VERSION_ATLEAST(bmain, 301, 5)) {
LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
if (ntree->type != NTREE_GEOMETRY) {
continue;
}
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->type != GEO_NODE_REALIZE_INSTANCES) {
continue;
}
node->custom1 |= GEO_NODE_REALIZE_INSTANCES_LEGACY_BEHAVIOR;
}
}
}
if (!MAIN_VERSION_ATLEAST(bmain, 301, 6)) {
/* Add node storage for map range node. */
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {

View File

@ -234,7 +234,7 @@ void _bmo_slot_copy(BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS],
slot_dst->data.buf = NULL;
slot_dst->len = slot_src->len;
if (slot_dst->len) {
/* check dest has all flags enabled that the source has */
/* Check destination has all flags enabled that the source has. */
const eBMOpSlotSubType_Elem src_elem_flag = (slot_src->slot_subtype.elem & BM_ALL_NOLOOP);
const eBMOpSlotSubType_Elem dst_elem_flag = (slot_dst->slot_subtype.elem & BM_ALL_NOLOOP);

View File

@ -293,7 +293,7 @@ void DeferredLayer::begin_sync()
/* Textures. */
prepass_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
/* Uniform Buf. */
/* Uniform Buffer. */
prepass_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get());
inst_.velocity.bind_resources(&prepass_ps_);
@ -338,11 +338,11 @@ void DeferredLayer::begin_sync()
gbuffer_ps_.bind_image(RBUFS_AOV_VALUE_SLOT, &inst_.render_buffers.aov_value_tx);
/* Cryptomatte. */
gbuffer_ps_.bind_image(RBUFS_CRYPTOMATTE_SLOT, &inst_.render_buffers.cryptomatte_tx);
/* Storage Buf. */
/* Storage Buffer. */
gbuffer_ps_.bind_ssbo(RBUFS_AOV_BUF_SLOT, &inst_.film.aovs_info);
/* Textures. */
gbuffer_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
/* Uniform Buf. */
/* Uniform Buffer. */
gbuffer_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get());
inst_.sampling.bind_resources(&gbuffer_ps_);

View File

@ -89,7 +89,7 @@ class Sampling {
template<typename T> void bind_resources(draw::detail::PassBase<T> *pass)
{
/* Storage Buf. */
/* Storage Buffer. */
pass->bind_ssbo(SAMPLING_BUF_SLOT, &data_);
}

View File

@ -120,13 +120,13 @@ class VelocityModule {
template<typename T> void bind_resources(draw::detail::Pass<T> *pass)
{
/* Storage Buf. */
/* Storage Buffer. */
pass->bind_ssbo(VELOCITY_OBJ_PREV_BUF_SLOT, &(*object_steps[STEP_PREVIOUS]));
pass->bind_ssbo(VELOCITY_OBJ_NEXT_BUF_SLOT, &(*object_steps[next_step_]));
pass->bind_ssbo(VELOCITY_GEO_PREV_BUF_SLOT, &(*geometry_steps[STEP_PREVIOUS]));
pass->bind_ssbo(VELOCITY_GEO_NEXT_BUF_SLOT, &(*geometry_steps[next_step_]));
pass->bind_ssbo(VELOCITY_INDIRECTION_BUF_SLOT, &indirection_buf);
/* Uniform Buf. */
/* Uniform Buffer. */
pass->bind_ubo(VELOCITY_CAMERA_PREV_BUF, &(*camera_steps[STEP_PREVIOUS]));
pass->bind_ubo(VELOCITY_CAMERA_CURR_BUF, &(*camera_steps[STEP_CURRENT]));
pass->bind_ubo(VELOCITY_CAMERA_NEXT_BUF, &(*camera_steps[next_step_]));

View File

@ -1142,7 +1142,7 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op)
* A symmetrizable selection contains selected ebones of the input direction
* and unique selected bones with an unique flippable name.
*
* Storing temp ptrs to mirrored unselected ebones. */
* Storing temp pointers to mirrored unselected ebones. */
for (ebone_iter = arm->edbo->first; ebone_iter; ebone_iter = ebone_iter->next) {
if (!(EBONE_VISIBLE(arm, ebone_iter) && (ebone_iter->flag & BONE_SELECTED))) {
/* Skipping invisible selected bones. */

View File

@ -419,8 +419,9 @@ void paintface_select_linked(struct bContext *C,
struct Object *ob,
const int mval[2],
bool select);
/** Grow the selection of faces.
* \param face_step If true will also select faces that only touch on the corner.
/**
* Grow the selection of faces.
* \param face_step: If true will also select faces that only touch on the corner.
*/
void paintface_select_more(struct Mesh *mesh, bool face_step);
void paintface_select_less(struct Mesh *mesh, bool face_step);

View File

@ -125,8 +125,9 @@ int BIF_countTransformOrientation(const struct bContext *C);
#define P_CURSOR_EDIT (1 << 16)
#define P_CLNOR_INVALIDATE (1 << 17)
#define P_VIEW2D_EDGE_PAN (1 << 18)
#define P_VIEW3D_NAVIGATION (1 << 19)
/* For properties performed when confirming the transformation. */
#define P_POST_TRANSFORM (1 << 19)
#define P_POST_TRANSFORM (1 << 20)
void Transform_Properties(struct wmOperatorType *ot, int flags);

View File

@ -43,6 +43,7 @@ struct SnapObjectContext;
struct View3D;
struct ViewContext;
struct ViewLayer;
struct ViewOpsData;
struct bContext;
struct bPoseChannel;
struct bScreen;
@ -210,6 +211,19 @@ bool ED_view3d_depth_unproject_v3(const struct ARegion *region,
double depth,
float r_location_world[3]);
/**
* Utilities to perform navigation.
* Call `ED_view3d_navigation_init` to create a context and `ED_view3d_navigation_do` to perform
* navigation in modal operators.
*
* \note modal map events can also be used in `ED_view3d_navigation_do`.
*/
struct ViewOpsData *ED_view3d_navigation_init(struct bContext *C);
bool ED_view3d_navigation_do(struct bContext *C,
struct ViewOpsData *vod,
const struct wmEvent *event);
void ED_view3d_navigation_free(struct bContext *C, struct ViewOpsData *vod);
/* Projection */
#define IS_CLIPPED 12000

View File

@ -191,11 +191,11 @@ static void ui_popup_menu_create_block(bContext *C,
if (!pup->but) {
pup->block->flag |= UI_BLOCK_NO_FLIP;
}
/* A title is only provided when a Menu has a label, this is not alwas the case, see e.g.
/* A title is only provided when a Menu has a label, this is not always the case, see e.g.
* `VIEW3D_MT_edit_mesh_context_menu` -- this specifies its own label inside the draw function
* depending on vertex/edge/face mode. We still want to flag the uiBlock (but only insert into
* the puphash if we have a title provided). Choosing an entry in a menu will still handle
* puphash later (see `button_activate_exit`) though multiple menus without a label might fight
* the `puphash` if we have a title provided). Choosing an entry in a menu will still handle
* `puphash` later (see `button_activate_exit`) though multiple menus without a label might fight
* for the same storage of the menu memory. Using idname instead (or in combination with the
* label) for the hash could be looked at to solve this. */
pup->block->flag |= UI_BLOCK_POPUP_MEMORY;

View File

@ -71,8 +71,8 @@ static void undolatt_to_editlatt(UndoLattice *ult, EditLatt *editlatt)
memcpy(editlatt->latt->def, ult->def, sizeof(BPoint) * len_src);
}
/* Even for the same amount of points we dont just copy memory for MDeformVert, relations to
* MDeformWeight might have changed. */
/* Even for the same amount of points we don't just copy memory for MDeformVert,
* relations to #MDeformWeight might have changed. */
if (editlatt->latt->dvert && ult->dvert) {
BKE_defvert_array_free(editlatt->latt->dvert, len_dst);
editlatt->latt->dvert = MEM_mallocN(sizeof(MDeformVert) * len_src, "Lattice MDeformVert");

View File

@ -2796,7 +2796,7 @@ static int vertex_group_copy_exec(bContext *C, wmOperator * /*op*/)
void OBJECT_OT_vertex_group_copy(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Copy Vertex Group";
ot->name = "Duplicate Vertex Group";
ot->idname = "OBJECT_OT_vertex_group_copy";
ot->description = "Make a copy of the active vertex group";

View File

@ -235,8 +235,8 @@ static void imapaint_tri_weights(float matrix[4][4],
h[1] = (co[1] - view[1]) * 2.0f / view[3] - 1.0f;
h[2] = 1.0f;
/* solve for (w1,w2,w3)/perspdiv in:
* h * perspdiv = Project * Model * (w1 * v1 + w2 * v2 + w3 * v3) */
/* Solve for `(w1,w2,w3)/perspdiv` in:
* `h * perspdiv = Project * Model * (w1 * v1 + w2 * v2 + w3 * v3)`. */
wmat[0][0] = pv1[0];
wmat[1][0] = pv2[0];
@ -253,7 +253,7 @@ static void imapaint_tri_weights(float matrix[4][4],
copy_v3_v3(w, h);
/* w is still divided by perspdiv, make it sum to one */
/* w is still divided by `perspdiv`, make it sum to one */
divw = w[0] + w[1] + w[2];
if (divw != 0.0f) {
mul_v3_fl(w, 1.0f / divw);

View File

@ -58,7 +58,7 @@ bool ED_wpaint_ensure_data(bContext *C,
return false;
}
/* if nothing was added yet, we make dverts and a vertex deform group */
/* If nothing was added yet, we make deform-verts and a vertex deform group. */
if (BKE_mesh_deform_verts(me) == nullptr) {
BKE_object_defgroup_data_create(&me->id);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
@ -136,8 +136,7 @@ int ED_wpaint_mirror_vgroup_ensure(Object *ob, const int vgroup_active)
}
}
/* curdef should never be nullptr unless this is
* a light and BKE_object_defgroup_add_name fails */
/* `mirrdef` shouldn't be -1 unless the object is a light & #BKE_object_defgroup_new fails. */
return mirrdef;
}

View File

@ -445,9 +445,9 @@ static void gizmo_retime_handle_draw(const bContext *C, wmGizmo *gz)
RetimeHandleMoveGizmo *gizmo = (RetimeHandleMoveGizmo *)gz;
const View2D *v2d = UI_view2d_fromcontext(C);
/* TODO: This is hardcoded behavior, same as preselect gizmos in 3D view.
/* TODO: This is hard-coded behavior, same as pre-select gizmos in 3D view.
* Better solution would be to check operator keymap and display this information in status bar
* and tooltip. */
* and tool-tip. */
wmEvent *event = CTX_wm_window(C)->eventstate;
gizmo->create_transition_operation = (event->modifier & KM_SHIFT) != 0;

View File

@ -216,7 +216,7 @@ static int sequencer_retiming_handle_move_modal(bContext *C, wmOperator *op, con
const bool handle_is_transition = SEQ_retiming_handle_is_transition_type(handle);
const bool prev_handle_is_transition = SEQ_retiming_handle_is_transition_type(handle - 1);
/* When working with transiton, change handles when moving past pivot point. */
/* When working with transition, change handles when moving past pivot point. */
if (handle_is_transition || prev_handle_is_transition) {
SeqRetimingHandle *transition_start, *transition_end;
if (handle_is_transition) {

View File

@ -74,6 +74,8 @@ const char *viewops_operator_idname_get(eV3D_OpMode nav_type)
case V3D_OP_MODE_NDOF_ORBIT_ZOOM:
return "VIEW3D_OT_ndof_orbit_zoom";
#endif
case V3D_OP_MODE_NONE:
break;
}
BLI_assert(false);
return nullptr;
@ -1942,3 +1944,142 @@ void VIEW3D_OT_view_pan(wmOperatorType *ot)
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Navigation Utilities
* \{ */
/* Detect the navigation operation, by the name of the navigation operator (obtained by
* `wmKeyMapItem::idname`) */
static eV3D_OpMode view3d_navigation_type_from_idname(const char *idname)
{
const char *op_name = idname + sizeof("VIEW3D_OT_");
for (int i = 0; i < V3D_OP_MODE_LEN; i++) {
if (STREQ(op_name, viewops_operator_idname_get((eV3D_OpMode)i) + sizeof("VIEW3D_OT_"))) {
return (eV3D_OpMode)i;
}
}
return V3D_OP_MODE_NONE;
}
/* Unlike `viewops_data_create`, `ED_view3d_navigation_init` creates a navigation context along
* with an array of `wmKeyMapItem`s used for navigation. */
ViewOpsData *ED_view3d_navigation_init(bContext *C)
{
if (!CTX_wm_region_view3d(C)) {
return NULL;
}
ViewOpsData *vod = MEM_cnew<ViewOpsData>(__func__);
viewops_data_init_context(C, vod);
vod->keymap = WM_keymap_find_all(CTX_wm_manager(C), "3D View", SPACE_VIEW3D, 0);
return vod;
}
/* Checks and initializes the navigation modal operation. */
static int view3d_navigation_invoke(bContext *C,
ViewOpsData *vod,
const wmEvent *event,
struct wmKeyMapItem *kmi,
eV3D_OpMode nav_type)
{
switch (nav_type) {
case V3D_OP_MODE_ZOOM:
if (!view3d_zoom_or_dolly_poll(C)) {
return OPERATOR_CANCELLED;
}
break;
case V3D_OP_MODE_MOVE:
case V3D_OP_MODE_VIEW_PAN:
if (!view3d_location_poll(C)) {
return OPERATOR_CANCELLED;
}
break;
case V3D_OP_MODE_ROTATE:
if (!view3d_rotation_poll(C)) {
return OPERATOR_CANCELLED;
}
break;
case V3D_OP_MODE_VIEW_ROLL:
case V3D_OP_MODE_DOLLY:
#ifdef WITH_INPUT_NDOF
case V3D_OP_MODE_NDOF_ORBIT:
case V3D_OP_MODE_NDOF_ORBIT_ZOOM:
#endif
case V3D_OP_MODE_NONE:
break;
}
return view3d_navigation_invoke_generic(C, vod, event, kmi->ptr, nav_type);
}
bool ED_view3d_navigation_do(bContext *C, ViewOpsData *vod, const wmEvent *event)
{
if (!vod) {
return false;
}
wmEvent event_tmp;
if (event->type == EVT_MODAL_MAP) {
/* Workaround to use the original event values. */
event_tmp = *event;
event_tmp.type = event->prev_type;
event_tmp.val = event->prev_val;
event = &event_tmp;
}
int op_return = OPERATOR_CANCELLED;
if (vod->is_modal_event) {
const eV3D_OpEvent event_code = view3d_navigate_event(vod, event);
op_return = view3d_navigation_modal(C, vod, event_code, event->xy);
if (op_return != OPERATOR_RUNNING_MODAL) {
viewops_data_end_navigation(C, vod);
vod->is_modal_event = false;
}
}
else {
eV3D_OpMode nav_type;
LISTBASE_FOREACH (wmKeyMapItem *, kmi, &vod->keymap->items) {
if (!STRPREFIX(kmi->idname, "VIEW3D")) {
continue;
}
if (kmi->flag & KMI_INACTIVE) {
continue;
}
if ((nav_type = view3d_navigation_type_from_idname(kmi->idname)) == V3D_OP_MODE_NONE) {
continue;
}
if (!WM_event_match(event, kmi)) {
continue;
}
op_return = view3d_navigation_invoke(C, vod, event, kmi, nav_type);
if (op_return == OPERATOR_RUNNING_MODAL) {
vod->is_modal_event = true;
}
else {
viewops_data_end_navigation(C, vod);
}
break;
}
}
if (op_return != OPERATOR_CANCELLED) {
/* Although #ED_view3d_update_viewmat is already called when redrawing the 3D View, do it here
* as well, so the updated matrix values can be accessed by the operator. */
ED_view3d_update_viewmat(
vod->depsgraph, vod->scene, vod->v3d, vod->region, NULL, NULL, NULL, false);
return true;
}
return false;
}
void ED_view3d_navigation_free(bContext *C, ViewOpsData *vod)
{
viewops_data_free(C, vod);
}
/** \} */

View File

@ -33,6 +33,7 @@ struct wmEvent;
struct wmOperator;
typedef enum eV3D_OpMode {
V3D_OP_MODE_NONE = -1,
V3D_OP_MODE_ZOOM = 0,
V3D_OP_MODE_ROTATE,
V3D_OP_MODE_MOVE,
@ -44,6 +45,11 @@ typedef enum eV3D_OpMode {
V3D_OP_MODE_NDOF_ORBIT_ZOOM,
#endif
} eV3D_OpMode;
#ifndef WITH_INPUT_NDOF
# define V3D_OP_MODE_LEN V3D_OP_MODE_DOLLY + 1
#else
# define V3D_OP_MODE_LEN V3D_OP_MODE_NDOF_ORBIT_ZOOM + 1
#endif
enum eV3D_OpPropFlag {
V3D_OP_PROP_MOUSE_CO = (1 << 0),
@ -179,6 +185,10 @@ typedef struct ViewOpsData {
* See #view3d_orbit_apply_dyn_ofs code-comments for an example, also see: #104385.
*/
bool use_dyn_ofs_ortho_correction;
/** Used for navigation on non view3d operators. */
wmKeyMap *keymap;
bool is_modal_event;
} ViewOpsData;
/* view3d_navigate.cc */

View File

@ -891,7 +891,7 @@ static void view3d_boxview_sync_axis(RegionView3D *rv3d_dst, RegionView3D *rv3d_
mul_qt_v3(viewinv, view_dst_x);
mul_qt_v3(viewinv, view_dst_y);
/* check source and dest have a matching axis */
/* Check source and destination have a matching axis. */
for (i = 0; i < 3; i++) {
if (((fabsf(view_src_x[i]) > axis_eps) || (fabsf(view_src_y[i]) > axis_eps)) &&
((fabsf(view_dst_x[i]) > axis_eps) || (fabsf(view_dst_y[i]) > axis_eps)))

View File

@ -92,9 +92,6 @@ void setTransformViewMatrices(TransInfo *t)
unit_m4(t->persinv);
t->persp = RV3D_ORTHO;
}
calculateCenter2D(t);
calculateCenterLocal(t, t->center_global);
}
void setTransformViewAspect(TransInfo *t, float r_aspect[3])
@ -926,15 +923,17 @@ static bool transform_event_modal_constraint(TransInfo *t, short modal_type)
int transformEvent(TransInfo *t, const wmEvent *event)
{
bool handled = false;
bool is_navigating = t->vod ? ((RegionView3D *)t->region->regiondata)->rflag & RV3D_NAVIGATING :
false;
/* Handle modal numinput events first, if already activated. */
if (((event->val == KM_PRESS) || (event->type == EVT_MODAL_MAP)) && hasNumInput(&t->num) &&
handleNumInput(t->context, &(t->num), event))
if (!is_navigating && ((event->val == KM_PRESS) || (event->type == EVT_MODAL_MAP)) &&
hasNumInput(&t->num) && handleNumInput(t->context, &(t->num), event))
{
t->redraw |= TREDRAW_HARD;
handled = true;
}
else if (event->type == MOUSEMOVE) {
else if (!is_navigating && event->type == MOUSEMOVE) {
copy_v2_v2_int(t->mval, event->mval);
/* Use this for soft redraw. Might cause flicker in object mode */

View File

@ -41,6 +41,7 @@ struct TransDataContainer;
struct TransInfo;
struct TransSnap;
struct ViewLayer;
struct ViewOpsData;
struct bContext;
struct wmEvent;
struct wmKeyConfig;
@ -673,6 +674,8 @@ typedef struct TransInfo {
/** Currently only used for random curve of proportional editing. */
struct RNG *rng;
struct ViewOpsData *vod;
/** Typically for mode settings. */
TransCustomDataContainer custom;

View File

@ -660,7 +660,16 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
t->flag |= T_NO_CURSOR_WRAP;
}
if (op && (t->flag & T_MODAL) && !(t->flag & T_RELEASE_CONFIRM) &&
(prop = RNA_struct_find_property(op->ptr, "allow_navigation")) &&
RNA_property_boolean_get(op->ptr, prop))
{
t->vod = ED_view3d_navigation_init(C);
}
setTransformViewMatrices(t);
calculateCenter2D(t);
calculateCenterLocal(t, t->center_global);
initNumInput(&t->num);
transform_gizmo_3d_model_from_constraint_and_mode_init(t);
@ -770,6 +779,10 @@ void postTrans(bContext *C, TransInfo *t)
}
freeSnapping(t);
if (t->vod) {
ED_view3d_navigation_free(C, t->vod);
}
}
void applyTransObjects(TransInfo *t)

View File

@ -474,6 +474,23 @@ static void protectflag_to_drawflags(short protectflag, short *drawflags)
}
}
/* Similar to #transform_object_deform_pose_armature_get but does not check visibility. */
static Object *gizmo_3d_transform_space_object_get(Scene *scene, ViewLayer *view_layer)
{
BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
if (ob && ob->mode & OB_MODE_WEIGHT_PAINT) {
/* It is assumed that when the object is in Weight Paint mode, it is not in Edit mode. So we
* don't need to check the #OB_MODE_EDIT flag. */
BLI_assert(!(ob->mode & OB_MODE_EDIT));
Object *obpose = BKE_object_pose_armature_get(ob);
if (obpose != nullptr) {
ob = obpose;
}
}
return ob;
}
/**
* Run \a user_fn for each coordinate of elements selected in View3D (vertices, particles...).
* \note Each coordinate has the space matrix of the active object.
@ -519,15 +536,7 @@ static int gizmo_3d_foreach_selected(const bContext *C,
const bool is_curve_edit = GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd);
int a, totsel = 0;
BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
Object *obedit = OBEDIT_FROM_OBACT(ob);
if (ob && ob->mode & OB_MODE_WEIGHT_PAINT) {
Object *obpose = BKE_object_pose_armature_get(ob);
if (obpose != nullptr) {
ob = obpose;
}
}
Object *ob = gizmo_3d_transform_space_object_get(scene, view_layer);
if (is_gp_edit) {
float diff_mat[4][4];
@ -586,7 +595,7 @@ static int gizmo_3d_foreach_selected(const bContext *C,
}
}
}
else if (obedit) {
else if (Object *obedit = OBEDIT_FROM_OBACT(ob)) {
#define FOREACH_EDIT_OBJECT_BEGIN(ob_iter, use_mat_local) \
{ \
@ -937,15 +946,8 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
(params->orientation_index - 1) :
BKE_scene_orientation_get_index(scene, SCE_ORIENT_DEFAULT);
BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
Object *ob = gizmo_3d_transform_space_object_get(scene, view_layer);
Object *obedit = OBEDIT_FROM_OBACT(ob);
if (ob && ob->mode & OB_MODE_WEIGHT_PAINT) {
Object *obpose = BKE_object_pose_armature_get(ob);
if (obpose != nullptr) {
ob = obpose;
}
}
tbounds->use_matrix_space = false;
unit_m3(tbounds->axis);
@ -972,7 +974,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
copy_m3_m4(diff_mat, ob->object_to_world);
normalize_m3(diff_mat);
invert_m3(diff_mat);
mul_m3_m3m3(tbounds->axis, tbounds->axis, diff_mat);
mul_m3_m3_pre(tbounds->axis, diff_mat);
normalize_m3(tbounds->axis);
tbounds->use_matrix_space = true;
@ -997,7 +999,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
bGPdata *gpd = CTX_data_gpencil_data(C);
const bool is_gp_edit = GPENCIL_ANY_MODE(gpd);
if (!is_gp_edit && (obedit || (ob && (ob->mode & (OB_MODE_POSE | OB_MODE_SCULPT))))) {
if (ob && (ob->mode & OB_MODE_POSE)) {
if (ob->mode & OB_MODE_POSE) {
invert_m4_m4(ob->world_to_object, ob->object_to_world);
}
mul_m4_v3(ob->object_to_world, tbounds->center);

View File

@ -399,7 +399,7 @@ static int transformops_data(bContext *C, wmOperator *op, const wmEvent *event)
static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
int exit_code;
int exit_code = OPERATOR_PASS_THROUGH;
TransInfo *t = op->customdata;
const eTfmMode mode_prev = t->mode;
@ -419,6 +419,31 @@ static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
exit_code = transformEvent(t, event);
t->context = NULL;
/* Allow navigation while transforming. */
if (t->vod && (exit_code & OPERATOR_PASS_THROUGH) && ED_view3d_navigation_do(C, t->vod, event)) {
RegionView3D *rv3d = t->region->regiondata;
if (rv3d->rflag & RV3D_NAVIGATING) {
/* Do not update transform while navigating. This can be distracting. */
return OPERATOR_RUNNING_MODAL;
}
if (t->modifiers & MOD_PRECISION) {
/* Remove Precision modifier, it may have be unintentionally enabled. */
t->modifiers &= ~MOD_PRECISION;
t->mouse.precision = 0;
}
/* Make sure `t->mval` is up to date before calling #transformViewUpdate. */
copy_v2_v2_int(t->mval, event->mval);
/* Call before #applyMouseInput. */
tranformViewUpdate(t);
/* Mouse input is outdated. */
applyMouseInput(t, &t->mouse, t->mval, t->values);
t->redraw |= TREDRAW_HARD;
}
transformApply(C, t);
exit_code |= transformEnd(C, t);
@ -752,6 +777,15 @@ void Transform_Properties(struct wmOperatorType *ot, int flags)
RNA_def_property_flag(prop, PROP_HIDDEN);
}
if (flags & P_VIEW3D_NAVIGATION) {
prop = RNA_def_boolean(ot->srna,
"allow_navigation",
0,
"Allow Navigation",
"Allow navigation while transforming");
RNA_def_property_flag(prop, PROP_HIDDEN);
}
if (flags & P_POST_TRANSFORM) {
prop = RNA_def_boolean(ot->srna,
"use_automerge_and_split",
@ -786,7 +820,7 @@ static void TRANSFORM_OT_translate(struct wmOperatorType *ot)
Transform_Properties(ot,
P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_ALIGN_SNAP |
P_OPTIONS | P_GPENCIL_EDIT | P_CURSOR_EDIT | P_VIEW2D_EDGE_PAN |
P_POST_TRANSFORM);
P_VIEW3D_NAVIGATION | P_POST_TRANSFORM);
}
static void TRANSFORM_OT_resize(struct wmOperatorType *ot)
@ -825,7 +859,7 @@ static void TRANSFORM_OT_resize(struct wmOperatorType *ot)
Transform_Properties(ot,
P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP |
P_OPTIONS | P_GPENCIL_EDIT | P_CENTER);
P_OPTIONS | P_GPENCIL_EDIT | P_CENTER | P_VIEW3D_NAVIGATION);
}
static void TRANSFORM_OT_skin_resize(struct wmOperatorType *ot)
@ -902,7 +936,7 @@ static void TRANSFORM_OT_rotate(struct wmOperatorType *ot)
Transform_Properties(ot,
P_ORIENT_AXIS | P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR |
P_GEO_SNAP | P_GPENCIL_EDIT | P_CENTER);
P_GEO_SNAP | P_GPENCIL_EDIT | P_CENTER | P_VIEW3D_NAVIGATION);
}
static void TRANSFORM_OT_tilt(struct wmOperatorType *ot)
@ -1147,7 +1181,7 @@ static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot)
"When Even mode is active, flips between the two adjacent edge loops");
RNA_def_boolean(ot->srna, "use_clamp", true, "Clamp", "Clamp within the edge extents");
Transform_Properties(ot, P_MIRROR | P_GEO_SNAP | P_CORRECT_UV);
Transform_Properties(ot, P_MIRROR | P_GEO_SNAP | P_CORRECT_UV | P_VIEW3D_NAVIGATION);
}
static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot)
@ -1182,7 +1216,7 @@ static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot)
"When Even mode is active, flips between the two adjacent edge loops");
RNA_def_boolean(ot->srna, "use_clamp", true, "Clamp", "Clamp within the edge extents");
Transform_Properties(ot, P_MIRROR | P_GEO_SNAP | P_CORRECT_UV);
Transform_Properties(ot, P_MIRROR | P_GEO_SNAP | P_CORRECT_UV | P_VIEW3D_NAVIGATION);
}
static void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot)
@ -1330,7 +1364,7 @@ static void TRANSFORM_OT_transform(struct wmOperatorType *ot)
Transform_Properties(ot,
P_ORIENT_AXIS | P_ORIENT_MATRIX | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR |
P_ALIGN_SNAP | P_GPENCIL_EDIT | P_CENTER);
P_ALIGN_SNAP | P_GPENCIL_EDIT | P_CENTER | P_VIEW3D_NAVIGATION);
}
static int transform_from_gizmo_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)

View File

@ -715,6 +715,10 @@ static eSnapTargetOP snap_target_select_from_spacetype(TransInfo *t)
/* Exclude editmesh when using proportional edit */
ret |= SCE_SNAP_TARGET_NOT_EDITED;
}
/* UV editing must never snap to the selection as this is what is transformed. */
if (t->spacetype == SPACE_IMAGE) {
ret |= SCE_SNAP_TARGET_NOT_SELECTED;
}
}
else if (ELEM(obedit_type, OB_ARMATURE, OB_CURVES_LEGACY, OB_SURF, OB_LATTICE, OB_MBALL)) {
/* Temporary limited to edit mode armature, curves, surfaces, lattices, and metaballs. */

View File

@ -1150,12 +1150,12 @@ static bool rotate_inside_square(const Span<UVAABBIsland *> island_indices,
return false; /* Nothing to do. */
}
/* Transform phis. */
/* Transform phis, rotate by best_angle, then translate back to the origin. No scale. */
for (const int64_t j : island_indices.index_range()) {
const int64_t i = island_indices[j]->index;
const PackIsland *island = islands[i];
const float island_scale = island->can_scale_(params) ? scale : 1.0f;
island->build_transformation(island_scale, square_finder.best_angle, matrix);
const float identity_scale = 1.0f; /* Don't rescale the placement, just rotate. */
island->build_transformation(identity_scale, square_finder.best_angle, matrix);
r_phis[i].rotation += square_finder.best_angle;
mul_m2_v2(matrix, r_phis[i].translation);
r_phis[i].translation.x -= square_finder.best_bounds.xmin;
@ -1777,17 +1777,25 @@ class OverlapMerger {
sub_params.merge_overlap = false;
const float result = pack_islands(sub_islands, sub_params);
/* Must loop backwards! */
/* Must loop backwards, or we will miss sub-sub-islands. */
for (int64_t i = merge_trace.size() - 3; i >= 0; i -= 3) {
PackIsland *sub_a = merge_trace[i];
PackIsland *sub_b = merge_trace[i + 1];
PackIsland *merge = merge_trace[i + 2];
/* Copy `angle`, `pre_translate` and `pre_rotate` from merged island to sub islands. */
sub_a->angle = merge->angle;
sub_b->angle = merge->angle;
sub_a->pre_translate = merge->pre_translate;
sub_b->pre_translate = merge->pre_translate;
sub_a->pre_rotate_ = merge->pre_rotate_;
sub_b->pre_rotate_ = merge->pre_rotate_;
/* If the merged island is pinned, the sub-islands are also pinned to correct scaling. */
if (merge->pinned) {
sub_a->pinned = true;
sub_b->pinned = true;
}
delete merge;
}
@ -1823,8 +1831,24 @@ float pack_islands(const Span<PackIsland *> &islands, const UVPackIsland_Params
finalize_geometry(islands, params);
/* Count the number of islands which can scale and which can translate. */
int64_t can_scale_count = 0;
int64_t can_translate_count = 0;
for (const int64_t i : islands.index_range()) {
if (islands[i]->can_scale_(params)) {
can_scale_count++;
}
if (islands[i]->can_translate_(params)) {
can_translate_count++;
}
}
if (can_translate_count == 0) {
return 1.0f; /* Nothing to do, all islands are locked. */
}
if (params.margin_method == ED_UVPACK_MARGIN_FRACTION && params.margin > 0.0f &&
params.scale_to_fit)
can_scale_count > 0)
{
/* Uses a line search on scale. ~10x slower than other method. */
return pack_islands_margin_fraction(islands, params.margin, false, params);
@ -1837,28 +1861,24 @@ float pack_islands(const Span<PackIsland *> &islands, const UVPackIsland_Params
case ED_UVPACK_MARGIN_SCALED: /* Default for Blender 3.3 and later. */
margin = calc_margin_from_aabb_length_sum(islands, params);
break;
case ED_UVPACK_MARGIN_FRACTION: /* Added as an option in Blender 3.4. */
BLI_assert(params.margin == 0.0f); /* Other (slower) cases are handled above. */
case ED_UVPACK_MARGIN_FRACTION: /* Added as an option in Blender 3.4. */
/* Most other cases are handled above, unless pinning is involved. */
break;
default:
BLI_assert_unreachable();
}
/* TODO: Only line-search if *some* islands can scale and *some* are locked. */
switch (params.pin_method) {
case ED_UVPACK_PIN_LOCK_ALL:
case ED_UVPACK_PIN_LOCK_SCALE:
case ED_UVPACK_PIN_LOCK_ROTATION_SCALE:
return pack_islands_margin_fraction(islands, margin, true, params);
default:
break;
if (can_scale_count > 0 && can_scale_count != islands.size()) {
/* Search for the best scale parameter. (slow) */
return pack_islands_margin_fraction(islands, margin, true, params);
}
/* Either all of the islands can scale, or none of them can.
* In either case, we pack them all tight to the origin. */
blender::Array<uv_phi> phis(islands.size());
const float scale = 1.0f;
const float max_uv = pack_islands_scale_margin(islands, scale, margin, params, phis);
const float result = params.scale_to_fit ? 1.0f / max_uv : 1.0f;
const float result = can_scale_count > 0 ? 1.0f / max_uv : 1.0f;
for (const int64_t i : islands.index_range()) {
BLI_assert(result == 1.0f || islands[i]->can_scale_(params));
islands[i]->place_(scale, phis[i]);

View File

@ -87,7 +87,7 @@ void *GPU_debug_capture_scope_create(const char *name);
/**
* Used to declare the region within which GPU calls are captured when the scope is triggered.
*
* \param scope Pointer to capture scope object created with GPU_debug_capture_scope_create.
* \param scope: Pointer to capture scope object created with GPU_debug_capture_scope_create.
* \return True if the capture tool is actively capturing this scope when function is executed.
* Otherwise, False.
*/

View File

@ -178,6 +178,9 @@ bool Texture::init_view(GPUTexture *src_,
void Texture::usage_set(eGPUTextureUsage usage_flags)
{
gpu_image_usage_flags_ = usage_flags;
/* Metal: Texture clearing is done using frame-buffer clear. This has no performance impact. */
/* TODO(fclem): Move this to metal backend instead to avoid side effects in other back-ends. */
gpu_image_usage_flags_ |= GPU_TEXTURE_USAGE_ATTACHMENT;
}
/** \} */

View File

@ -1390,9 +1390,15 @@ bool MTLShader::bake_compute_pipeline_state(MTLContext *ctx)
}
/* Compile PSO. */
MTLComputePipelineDescriptor *desc = [[MTLComputePipelineDescriptor alloc] init];
desc.maxTotalThreadsPerThreadgroup = 1024;
desc.computeFunction = compute_function;
id<MTLComputePipelineState> pso = [ctx->device
newComputePipelineStateWithFunction:compute_function
error:&error];
newComputePipelineStateWithDescriptor:desc
options:MTLPipelineOptionNone
reflection:nullptr
error:&error];
if (error) {
NSLog(@"Failed to create PSO for compute shader: %s error %@\n", this->name, error);

View File

@ -142,7 +142,7 @@ VKStateManager &VKContext::state_manager_get()
/** \} */
/* -------------------------------------------------------------------- */
/** \name Framebuffer
/** \name Frame-buffer
* \{ */
void VKContext::activate_framebuffer(VKFrameBuffer &framebuffer)

View File

@ -33,9 +33,9 @@ class VKFrameBuffer : public FrameBuffer {
/**
* Should we flip the viewport to match Blenders coordinate system. We flip the viewport for
* offscreen framebuffers.
* off-screen frame-buffers.
*
* When two framebuffers are blitted we also check if the coordinate system should be flipped
* When two frame-buffers are blitted we also check if the coordinate system should be flipped
* during blitting.
*/
bool flip_viewport_ = false;

View File

@ -169,7 +169,7 @@ void VKPipeline::finalize(VKContext &context,
viewport_state.scissorCount = 1;
pipeline_create_info.pViewportState = &viewport_state;
/* Multisample state. */
/* Multi-sample state. */
VkPipelineMultisampleStateCreateInfo multisample_state = {};
multisample_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
multisample_state.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;

View File

@ -392,4 +392,4 @@ void VKPipelineStateManager::set_shadow_bias(const bool enable)
}
}
} // namespace blender::gpu
} // namespace blender::gpu

View File

@ -65,7 +65,7 @@ void path_reference_copy(const Set<std::pair<std::string, std::string>> &copy_se
continue;
}
if (0 == BLI_path_cmp_normalized(src, dst)) {
continue; /* Source and dest are the same. */
continue; /* Source and destination are the same. */
}
if (!BLI_file_ensure_parent_dir_exists(dst)) {
fprintf(stderr, "Can't make directory for '%s', not copying\n", dst);

View File

@ -103,8 +103,10 @@ static bool prim_path_valid(const char *path)
return true;
}
/* Perform validation of export parameter settings. Returns
* true if the paramters are valid; returns false otherwise. */
/**
* Perform validation of export parameter settings.
* \return true if the parameters are valid; returns false otherwise.
*/
static bool export_params_valid(const USDExportParams &params)
{
bool valid = true;

View File

@ -296,7 +296,7 @@ static void populate_curve_props_for_nurbs(const bke::CurvesGeometry &geometry,
Array<float> temp_knots(knots_num);
bke::curves::nurbs::calculate_knots(tot_points, mode, order, is_cyclic, temp_knots);
/* Knots should be the concatentation of all batched curves.
/* Knots should be the concatenation of all batched curves.
* https://graphics.pixar.com/usd/dev/api/class_usd_geom_nurbs_curves.html#details */
for (int i_knot = 0; i_knot < knots_num; i_knot++) {
knots.push_back(double(temp_knots[i_knot]));

View File

@ -567,9 +567,10 @@ typedef enum eItasc_Flags {
ITASC_INITIAL_REITERATION = (1 << 1),
ITASC_REITERATION = (1 << 2),
ITASC_SIMULATION = (1 << 3),
/* Set this flag to always translate root bones (i.e. bones without a parent) to (0, 0, 0).
* This was the pre-3.6 behaviour, and this flag was introduced for backward compatibility. */
/**
* Set this flag to always translate root bones (i.e. bones without a parent) to (0, 0, 0).
* This was the pre-3.6 behavior, and this flag was introduced for backward compatibility.
*/
ITASC_TRANSLATE_ROOT_BONES = (1 << 4),
} eItasc_Flags;

View File

@ -1518,11 +1518,6 @@ typedef struct NodeGeometryRaycast {
/* eCustomDataType. */
int8_t data_type;
/* Deprecated input types in new Ray-cast node. Can be removed when legacy nodes are no longer
* supported. */
uint8_t input_type_ray_direction;
uint8_t input_type_ray_length;
} NodeGeometryRaycast;
typedef struct NodeGeometryCurveFill {
@ -2437,10 +2432,6 @@ typedef enum GeometryNodeDeleteGeometryMode {
GEO_NODE_DELETE_GEOMETRY_MODE_ONLY_FACE = 2,
} GeometryNodeDeleteGeometryMode;
typedef enum GeometryNodeRealizeInstancesFlag {
GEO_NODE_REALIZE_INSTANCES_LEGACY_BEHAVIOR = (1 << 0),
} GeometryNodeRealizeInstancesFlag;
typedef enum GeometryNodeScaleElementsMode {
GEO_NODE_SCALE_ELEMENTS_UNIFORM = 0,
GEO_NODE_SCALE_ELEMENTS_SINGLE_AXIS = 1,

View File

@ -11238,17 +11238,6 @@ static void def_geo_viewer(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void def_geo_realize_instances(StructRNA *srna)
{
PropertyRNA *prop;
prop = RNA_def_property(srna, "legacy_behavior", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", GEO_NODE_REALIZE_INSTANCES_LEGACY_BEHAVIOR);
RNA_def_property_ui_text(
prop, "Legacy Behavior", "Behave like before instance attributes existed");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update");
}
static void def_geo_evaluate_at_index(StructRNA *srna)
{
PropertyRNA *prop;

View File

@ -212,7 +212,7 @@ void weightvg_do_mask(const ModifierEvalContext *ctx,
/* Get vgroup idx from its name. */
/* Proceed only if vgroup is valid, else use constant factor. */
/* Get actual dverts (ie vertex group data). */
/* Get actual deform-verts (ie vertex group data). */
const MDeformVert *dvert = static_cast<const MDeformVert *>(
CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT));
/* Proceed only if vgroup is valid, else assume factor = O. */

View File

@ -281,10 +281,10 @@ DefNode(FunctionNode, FN_NODE_VALUE_TO_STRING, 0, "VALUE_TO_STRING", ValueToStri
DefNode(GeometryNode, GEO_NODE_ACCUMULATE_FIELD, def_geo_accumulate_field, "ACCUMULATE_FIELD", AccumulateField, "Accumulate Field", "Add the values of an evaluated field together and output the running total for each element")
DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_DOMAIN_SIZE, def_geo_attribute_domain_size, "ATTRIBUTE_DOMAIN_SIZE", AttributeDomainSize, "Domain Size", "Retrieve the number of elements in a geometry for each attribute domain")
DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_STATISTIC, def_geo_attribute_statistic, "ATTRIBUTE_STATISTIC",AttributeStatistic, "Attribute Statistic","Calculate statistics about a data set from a field evaluated on a geometry")
DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_STATISTIC, def_geo_attribute_statistic, "ATTRIBUTE_STATISTIC",AttributeStatistic, "Attribute Statistic", "Calculate statistics about a data set from a field evaluated on a geometry")
DefNode(GeometryNode, GEO_NODE_BLUR_ATTRIBUTE, def_geo_blur_attribute, "BLUR_ATTRIBUTE", BlurAttribute, "Blur Attribute", "Mix attribute values of neighboring elements")
DefNode(GeometryNode, GEO_NODE_BOUNDING_BOX, 0, "BOUNDING_BOX", BoundBox, "Bounding Box", "Calculate the limits of a geometry's positions and generate a box mesh with those dimensions")
DefNode(GeometryNode, GEO_NODE_CAPTURE_ATTRIBUTE, def_geo_attribute_capture,"CAPTURE_ATTRIBUTE", CaptureAttribute, "Capture Attribute", "Store the result of a field on a geometry and output the data as a node socket. Allows remembering or interpolating data as the geometry changes, such as positions before deformation")
DefNode(GeometryNode, GEO_NODE_CAPTURE_ATTRIBUTE, def_geo_attribute_capture, "CAPTURE_ATTRIBUTE", CaptureAttribute, "Capture Attribute", "Store the result of a field on a geometry and output the data as a node socket. Allows remembering or interpolating data as the geometry changes, such as positions before deformation")
DefNode(GeometryNode, GEO_NODE_COLLECTION_INFO, def_geo_collection_info, "COLLECTION_INFO", CollectionInfo, "Collection Info", "Retrieve geometry instances from a collection")
DefNode(GeometryNode, GEO_NODE_CONVEX_HULL, 0, "CONVEX_HULL", ConvexHull, "Convex Hull", "Create a mesh that encloses all points in the input geometry with the smallest number of points")
DefNode(GeometryNode, GEO_NODE_CURVE_ENDPOINT_SELECTION, 0, "CURVE_ENDPOINT_SELECTION", CurveEndpointSelection, "Endpoint Selection", "Provide a selection for an arbitrary number of endpoints in each spline")
@ -300,7 +300,7 @@ DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_SPIRAL,0, "CURVE_PRIMITIVE_SPIRAL
DefNode(GeometryNode, GEO_NODE_CURVE_PRIMITIVE_STAR, 0, "CURVE_PRIMITIVE_STAR", CurveStar, "Star", "Generate a poly spline in a star pattern by connecting alternating points of two circles")
DefNode(GeometryNode, GEO_NODE_CURVE_SET_HANDLE_TYPE, def_geo_curve_set_handle_type, "CURVE_SET_HANDLES", CurveSetHandles, "Set Handle Type", "Set the handle type for the control points of a Bézier curve")
DefNode(GeometryNode, GEO_NODE_CURVE_SPLINE_PARAMETER,0, "SPLINE_PARAMETER", SplineParameter, "Spline Parameter", "Retrieve how far along each spline a control point is")
DefNode(GeometryNode, GEO_NODE_CURVE_SPLINE_TYPE, def_geo_curve_spline_type,"CURVE_SPLINE_TYPE", CurveSplineType, "Set Spline Type", "Change the type of curves")
DefNode(GeometryNode, GEO_NODE_CURVE_SPLINE_TYPE, def_geo_curve_spline_type, "CURVE_SPLINE_TYPE", CurveSplineType, "Set Spline Type", "Change the type of curves")
DefNode(GeometryNode, GEO_NODE_CURVE_TO_MESH, 0, "CURVE_TO_MESH", CurveToMesh, "Curve to Mesh", "Convert curves into a mesh, optionally with a custom profile shape defined by curves")
DefNode(GeometryNode, GEO_NODE_CURVE_TO_POINTS, def_geo_curve_to_points, "CURVE_TO_POINTS", CurveToPoints, "Curve to Points", "Generate a point cloud by sampling positions along curves")
DefNode(GeometryNode, GEO_NODE_CURVE_TOPOLOGY_CURVE_OF_POINT, 0, "CURVE_OF_POINT", CurveOfPoint, "Curve of Point", "Retrieve the curve a control point is part of")
@ -325,7 +325,7 @@ DefNode(GeometryNode, GEO_NODE_IMAGE_INFO, 0, "IMAGE_INFO", ImageInfo, "Image In
DefNode(GeometryNode, GEO_NODE_IMAGE_TEXTURE, def_geo_image_texture, "IMAGE_TEXTURE", ImageTexture, "Image Texture", "Sample values from an image texture")
DefNode(GeometryNode, GEO_NODE_INDEX_OF_NEAREST, 0, "INDEX_OF_NEAREST", IndexOfNearest, "Index of Nearest", "Find the nearest element in a group. Similar to the \"Sample Nearest\" node")
DefNode(GeometryNode, GEO_NODE_IMAGE, def_geo_image, "IMAGE", InputImage, "Image", "Input image")
DefNode(GeometryNode, GEO_NODE_INPUT_CURVE_HANDLES, 0, "INPUT_CURVE_HANDLES", InputCurveHandlePositions,"Curve Handle Positions", "Retrieve the position of each Bézier control point's handles")
DefNode(GeometryNode, GEO_NODE_INPUT_CURVE_HANDLES, 0, "INPUT_CURVE_HANDLES", InputCurveHandlePositions, "Curve Handle Positions", "Retrieve the position of each Bézier control point's handles")
DefNode(GeometryNode, GEO_NODE_INPUT_CURVE_TILT, 0, "INPUT_CURVE_TILT", InputCurveTilt, "Curve Tilt", "Retrieve the angle at each control point used to twist the curve's normal around its tangent")
DefNode(GeometryNode, GEO_NODE_INPUT_ID, 0, "INPUT_ID", InputID, "ID", "Retrieve a stable random identifier value from the \"id\" attribute on the point domain, or the index if the attribute does not exist")
DefNode(GeometryNode, GEO_NODE_INPUT_INDEX, 0, "INDEX", InputIndex, "Index", "Retrieve an integer value indicating the position of each element in the list, starting at zero")
@ -354,12 +354,12 @@ DefNode(GeometryNode, GEO_NODE_INPUT_SPLINE_LENGTH, 0, "SPLINE_LENGTH", SplineLe
DefNode(GeometryNode, GEO_NODE_INPUT_SPLINE_RESOLUTION, 0, "INPUT_SPLINE_RESOLUTION", InputSplineResolution, "Spline Resolution", "Retrieve the number of evaluated points that will be generated for every control point on curves")
DefNode(GeometryNode, GEO_NODE_INPUT_TANGENT, 0, "INPUT_TANGENT", InputTangent, "Curve Tangent", "Retrieve the direction of curves at each control point")
DefNode(GeometryNode, GEO_NODE_INSTANCE_ON_POINTS, 0, "INSTANCE_ON_POINTS", InstanceOnPoints, "Instance on Points", "Generate a reference to geometry at each of the input points, without duplicating its underlying data")
DefNode(GeometryNode, GEO_NODE_INSTANCES_TO_POINTS, 0, "INSTANCES_TO_POINTS",InstancesToPoints, "Instances to Points","Generate points at the origins of instances.\nNote: Nested instances are not affected by this node")
DefNode(GeometryNode, GEO_NODE_INSTANCES_TO_POINTS, 0, "INSTANCES_TO_POINTS",InstancesToPoints, "Instances to Points", "Generate points at the origins of instances.\nNote: Nested instances are not affected by this node")
DefNode(GeometryNode, GEO_NODE_IS_VIEWPORT, 0, "IS_VIEWPORT", IsViewport, "Is Viewport", "Retrieve whether the nodes are being evaluated for the viewport rather than the final render")
DefNode(GeometryNode, GEO_NODE_JOIN_GEOMETRY, 0, "JOIN_GEOMETRY", JoinGeometry, "Join Geometry", "Merge separately generated geometries into a single one")
DefNode(GeometryNode, GEO_NODE_MATERIAL_SELECTION, 0, "MATERIAL_SELECTION", MaterialSelection, "Material Selection", "Provide a selection of faces that use the specified material")
DefNode(GeometryNode, GEO_NODE_MEAN_FILTER_SDF_VOLUME, 0, "MEAN_FILTER_SDF_VOLUME", MeanFilterSDFVolume, "Mean Filter SDF Volume", "Smooth the surface of an SDF volume by applying a mean filter")
DefNode(GeometryNode, GEO_NODE_MERGE_BY_DISTANCE, def_geo_merge_by_distance,"MERGE_BY_DISTANCE", MergeByDistance, "Merge by Distance", "Merge vertices or points within a given distance")
DefNode(GeometryNode, GEO_NODE_MERGE_BY_DISTANCE, def_geo_merge_by_distance, "MERGE_BY_DISTANCE", MergeByDistance, "Merge by Distance", "Merge vertices or points within a given distance")
DefNode(GeometryNode, GEO_NODE_MESH_BOOLEAN, def_geo_boolean, "MESH_BOOLEAN", MeshBoolean, "Mesh Boolean", "Cut, subtract, or join multiple mesh inputs")
DefNode(GeometryNode, GEO_NODE_MESH_FACE_GROUP_BOUNDARIES, 0, "MESH_FACE_SET_BOUNDARIES", MeshFaceSetBoundaries, "Face Group Boundaries", "Find edges on the boundaries between groups of faces with the same ID value")
DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CIRCLE, def_geo_mesh_circle, "MESH_PRIMITIVE_CIRCLE", MeshCircle, "Mesh Circle", "Generate a circular ring of edges")
@ -390,7 +390,7 @@ DefNode(GeometryNode, GEO_NODE_POINTS_TO_VOLUME, def_geo_points_to_volume, "POIN
DefNode(GeometryNode, GEO_NODE_POINTS, 0, "POINTS", Points, "Points", "Generate a point cloud with positions and radii defined by fields")
DefNode(GeometryNode, GEO_NODE_PROXIMITY, def_geo_proximity, "PROXIMITY", Proximity, "Geometry Proximity", "Compute the closest location on the target geometry")
DefNode(GeometryNode, GEO_NODE_RAYCAST, def_geo_raycast, "RAYCAST", Raycast, "Raycast", "Cast rays from the context geometry onto a target geometry, and retrieve information from each hit point")
DefNode(GeometryNode, GEO_NODE_REALIZE_INSTANCES, def_geo_realize_instances,"REALIZE_INSTANCES", RealizeInstances, "Realize Instances", "Convert instances into real geometry data")
DefNode(GeometryNode, GEO_NODE_REALIZE_INSTANCES, 0, "REALIZE_INSTANCES", RealizeInstances, "Realize Instances", "Convert instances into real geometry data")
DefNode(GeometryNode, GEO_NODE_REMOVE_ATTRIBUTE, 0, "REMOVE_ATTRIBUTE", RemoveAttribute, "Remove Named Attribute", "Delete an attribute with a specified name from a geometry. Typically used to optimize performance")
DefNode(GeometryNode, GEO_NODE_REPLACE_MATERIAL, 0, "REPLACE_MATERIAL", ReplaceMaterial, "Replace Material", "Swap one material with another")
DefNode(GeometryNode, GEO_NODE_RESAMPLE_CURVE, def_geo_curve_resample, "RESAMPLE_CURVE", ResampleCurve, "Resample Curve", "Generate a poly spline for each input spline")
@ -406,8 +406,8 @@ DefNode(GeometryNode, GEO_NODE_SCALE_ELEMENTS, def_geo_scale_elements, "SCALE_EL
DefNode(GeometryNode, GEO_NODE_SCALE_INSTANCES, 0, "SCALE_INSTANCES", ScaleInstances, "Scale Instances", "Scale geometry instances in local or global space")
DefNode(GeometryNode, GEO_NODE_SDF_VOLUME_SPHERE, 0, "SDF_VOLUME_SPHERE", SDFVolumeSphere, "SDF Volume Sphere", "Generate an SDF Volume Sphere")
DefNode(GeometryNode, GEO_NODE_SELF_OBJECT, 0, "SELF_OBJECT", SelfObject, "Self Object", "Retrieve the object that contains the geometry nodes modifier currently being executed")
DefNode(GeometryNode, GEO_NODE_SEPARATE_COMPONENTS, 0, "SEPARATE_COMPONENTS",SeparateComponents, "Separate Components","Split a geometry into a separate output for each type of data in the geometry")
DefNode(GeometryNode, GEO_NODE_SEPARATE_GEOMETRY, def_geo_separate_geometry,"SEPARATE_GEOMETRY", SeparateGeometry, "Separate Geometry", "Split a geometry into two geometry outputs based on a selection")
DefNode(GeometryNode, GEO_NODE_SEPARATE_COMPONENTS, 0, "SEPARATE_COMPONENTS",SeparateComponents, "Separate Components", "Split a geometry into a separate output for each type of data in the geometry")
DefNode(GeometryNode, GEO_NODE_SEPARATE_GEOMETRY, def_geo_separate_geometry, "SEPARATE_GEOMETRY", SeparateGeometry, "Separate Geometry", "Split a geometry into two geometry outputs based on a selection")
DefNode(GeometryNode, GEO_NODE_SET_CURVE_HANDLES, def_geo_curve_set_handle_positions, "SET_CURVE_HANDLES", SetCurveHandlePositions, "Set Handle Positions", "Set the positions for the handles of Bézier curves")
DefNode(GeometryNode, GEO_NODE_SET_CURVE_NORMAL, def_geo_set_curve_normal, "SET_CURVE_NORMAL", SetCurveNormal, "Set Curve Normal", "Set the evaluation mode for curve normals")
DefNode(GeometryNode, GEO_NODE_SET_CURVE_RADIUS, 0, "SET_CURVE_RADIUS", SetCurveRadius, "Set Curve Radius", "Set the radius of the curve at each control point")
@ -428,10 +428,10 @@ DefNode(GeometryNode, GEO_NODE_STRING_JOIN, 0, "STRING_JOIN", StringJoin, "Join
DefNode(GeometryNode, GEO_NODE_STRING_TO_CURVES, def_geo_string_to_curves, "STRING_TO_CURVES", StringToCurves, "String to Curves", "Generate a paragraph of text with a specific font, using a curve instance to store each character")
DefNode(GeometryNode, GEO_NODE_SUBDIVIDE_CURVE, 0, "SUBDIVIDE_CURVE", SubdivideCurve, "Subdivide Curve", "Dividing each curve segment into a specified number of pieces")
DefNode(GeometryNode, GEO_NODE_SUBDIVIDE_MESH, 0, "SUBDIVIDE_MESH", SubdivideMesh, "Subdivide Mesh", "Divide mesh faces into smaller ones without changing the shape or volume, using linear interpolation to place the new vertices")
DefNode(GeometryNode, GEO_NODE_SUBDIVISION_SURFACE, def_geo_subdivision_surface, "SUBDIVISION_SURFACE",SubdivisionSurface, "Subdivision Surface","Divide mesh faces to form a smooth surface, using the Catmull-Clark subdivision method")
DefNode(GeometryNode, GEO_NODE_SUBDIVISION_SURFACE, def_geo_subdivision_surface, "SUBDIVISION_SURFACE",SubdivisionSurface, "Subdivision Surface", "Divide mesh faces to form a smooth surface, using the Catmull-Clark subdivision method")
DefNode(GeometryNode, GEO_NODE_SWITCH, def_geo_switch, "SWITCH", Switch, "Switch", "Switch between two inputs")
DefNode(GeometryNode, GEO_NODE_TRANSFORM_GEOMETRY, 0, "TRANSFORM_GEOMETRY", Transform, "Transform Geometry", "Translate, rotate or scale the geometry")
DefNode(GeometryNode, GEO_NODE_TRANSLATE_INSTANCES, 0, "TRANSLATE_INSTANCES",TranslateInstances, "Translate Instances","Move top-level geometry instances in local or global space")
DefNode(GeometryNode, GEO_NODE_TRANSLATE_INSTANCES, 0, "TRANSLATE_INSTANCES",TranslateInstances, "Translate Instances", "Move top-level geometry instances in local or global space")
DefNode(GeometryNode, GEO_NODE_TRIANGULATE, def_geo_triangulate, "TRIANGULATE", Triangulate, "Triangulate", "Convert all faces in a mesh to triangular faces")
DefNode(GeometryNode, GEO_NODE_TRIM_CURVE, def_geo_curve_trim, "TRIM_CURVE", TrimCurve, "Trim Curve", "Shorten curves by removing portions at the start or end")
DefNode(GeometryNode, GEO_NODE_UV_PACK_ISLANDS, 0, "UV_PACK_ISLANDS", UVPackIslands, "Pack UV Islands", "Scale islands of a UV map and move them so they fill the UV space as much as possible")

View File

@ -15,29 +15,13 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>("Geometry").propagate_all();
}
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "legacy_behavior", 0, nullptr, ICON_NONE);
}
static void node_geo_exec(GeoNodeExecParams params)
{
const bool legacy_behavior = params.node().custom1 & GEO_NODE_REALIZE_INSTANCES_LEGACY_BEHAVIOR;
if (legacy_behavior) {
params.error_message_add(
NodeWarningType::Info,
TIP_("This node uses legacy behavior with regards to attributes on "
"instances. The behavior can be changed in the node properties in "
"the side bar. In most cases the new behavior is the same for files created in "
"Blender 3.0"));
}
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry_set);
geometry::RealizeInstancesOptions options;
options.keep_original_ids = legacy_behavior;
options.realize_instance_attributes = !legacy_behavior;
options.keep_original_ids = false;
options.realize_instance_attributes = true;
options.propagation_info = params.get_output_propagation_info("Geometry");
geometry_set = geometry::realize_instances(geometry_set, options);
params.set_output("Geometry", std::move(geometry_set));
@ -53,7 +37,6 @@ void register_node_type_geo_realize_instances()
geo_node_type_base(&ntype, GEO_NODE_REALIZE_INSTANCES, "Realize Instances", NODE_CLASS_GEOMETRY);
ntype.declare = file_ns::node_declare;
ntype.draw_buttons_ex = file_ns::node_layout;
ntype.geometry_node_execute = file_ns::node_geo_exec;
nodeRegisterType(&ntype);
}

View File

@ -2640,7 +2640,7 @@ static PyObject *Vector_swizzle_get(VectorObject *self, void *closure)
* Set the items of this vector using a swizzle.
* - If value is a vector or list this operates like an array copy, except that
* the destination is effectively re-ordered as defined by the swizzle. At
* most min(len(source), len(dest)) values will be copied.
* most `min(len(source), len(destination))` values will be copied.
* - If the value is scalar, it is copied to all axes listed in the swizzle.
* - If an axis appears more than once in the swizzle, the final occurrence is
* the one that determines its value.

View File

@ -489,6 +489,8 @@ wmKeyMapItem *WM_event_match_keymap_item_from_handlers(struct bContext *C,
struct ListBase *handlers,
const struct wmEvent *event);
bool WM_event_match(const struct wmEvent *winevent, const struct wmKeyMapItem *kmi);
typedef int (*wmUIHandlerFunc)(struct bContext *C, const struct wmEvent *event, void *userdata);
typedef void (*wmUIHandlerRemoveFunc)(struct bContext *C, void *userdata);

View File

@ -2205,7 +2205,7 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers)
}
}
static bool wm_eventmatch(const wmEvent *winevent, const wmKeyMapItem *kmi)
BLI_INLINE bool wm_eventmatch(const wmEvent *winevent, const wmKeyMapItem *kmi)
{
if (kmi->flag & KMI_INACTIVE) {
return false;
@ -6019,6 +6019,11 @@ wmKeyMapItem *WM_event_match_keymap_item_from_handlers(
return nullptr;
}
bool WM_event_match(const wmEvent *winevent, const wmKeyMapItem *kmi)
{
return wm_eventmatch(winevent, kmi);
}
/** \} */
/* -------------------------------------------------------------------- */

View File

@ -140,8 +140,11 @@ def main():
report.set_compare_engine('cycles', 'CPU')
# Increase threshold for motion blur, see #78777.
#
# underwater_caustics.blend gives quite different results on Linux and Intel macOS compared to
# Windows and Arm macOS.
test_dir_name = Path(test_dir).name
if test_dir_name == 'motion_blur':
if test_dir_name in ('motion_blur', 'integrator', ):
report.set_fail_threshold(0.032)
ok = report.run(test_dir, blender, get_arguments, batch=True)

View File

@ -302,6 +302,7 @@ dict_custom = {
"subdirectories",
"subdirectory",
"suboptimally",
"subrange",
"subtractive",
"superset",
"symmetrize",