Cycles: new Microfacet-based Hair BSDF with elliptical cross-section support #105600

Merged
Weizhen Huang merged 114 commits from weizhen/blender:microfacet_hair into main 2023-08-18 12:46:20 +02:00
204 changed files with 2188 additions and 4757 deletions
Showing only changes of commit 6ea34518b9 - Show all commits

View File

@ -333,10 +333,7 @@ option(WITH_MOD_OCEANSIM "Enable Ocean Modifier" ON)
# Image format support
option(WITH_IMAGE_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" ON)
option(WITH_IMAGE_OPENJPEG "Enable OpenJpeg Support (http://www.openjpeg.org)" ON)
option(WITH_IMAGE_TIFF "Enable LibTIFF Support" ON)
option(WITH_IMAGE_DDS "Enable DDS Image Support" ON)
option(WITH_IMAGE_CINEON "Enable CINEON and DPX Image Support" ON)
option(WITH_IMAGE_HDR "Enable HDR Image Support" ON)
option(WITH_IMAGE_WEBP "Enable WebP Image Support" ON)
# Audio/Video format support
@ -648,15 +645,15 @@ if(WIN32)
endif()
# Compiler tool-chain.
if(UNIX AND NOT APPLE)
if(UNIX)
if(CMAKE_COMPILER_IS_GNUCC)
option(WITH_LINKER_GOLD "Use ld.gold linker which is usually faster than ld.bfd" ON)
mark_as_advanced(WITH_LINKER_GOLD)
option(WITH_LINKER_LLD "Use ld.lld linker which is usually faster than ld.gold" OFF)
mark_as_advanced(WITH_LINKER_LLD)
endif()
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
option(WITH_LINKER_MOLD "Use ld.mold linker which is usually faster than ld.gold & ld.lld." OFF)
option(WITH_LINKER_LLD "Use ld.lld linker which is usually faster than ld.gold" OFF)
mark_as_advanced(WITH_LINKER_LLD)
option(WITH_LINKER_MOLD "Use ld.mold linker which is usually faster than ld.gold & ld.lld. Needs \"sold\" subscription on macOS." OFF)
mark_as_advanced(WITH_LINKER_MOLD)
endif()
endif()
@ -896,9 +893,6 @@ set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_ALEMBIC OFF)
set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_VULKAN_BACKEND OFF)
set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_CYCLES_OSL OFF)
# Haru needs `TIFFFaxBlackCodes` & `TIFFFaxWhiteCodes` symbols from TIFF.
set_and_warn_dependency(WITH_IMAGE_TIFF WITH_HARU OFF)
# auto enable openimageio for cycles
if(WITH_CYCLES)
# auto enable llvm for cycles_osl
@ -1941,11 +1935,8 @@ if(FIRST_RUN)
info_cfg_text("Image Formats:")
info_cfg_option(WITH_IMAGE_CINEON)
info_cfg_option(WITH_IMAGE_DDS)
info_cfg_option(WITH_IMAGE_HDR)
info_cfg_option(WITH_IMAGE_OPENEXR)
info_cfg_option(WITH_IMAGE_OPENJPEG)
info_cfg_option(WITH_IMAGE_TIFF)
info_cfg_text("Audio:")
info_cfg_option(WITH_CODEC_AVI)

View File

@ -26,11 +26,8 @@ set(WITH_HARU ON CACHE BOOL "" FORCE)
set(WITH_IK_ITASC ON CACHE BOOL "" FORCE)
set(WITH_IK_SOLVER ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_DDS ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_HDR ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_OPENEXR ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_OPENJPEG ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_TIFF ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_WEBP ON CACHE BOOL "" FORCE)
set(WITH_INPUT_NDOF ON CACHE BOOL "" FORCE)
set(WITH_INPUT_IME ON CACHE BOOL "" FORCE)

View File

@ -27,11 +27,8 @@ set(WITH_HARU OFF CACHE BOOL "" FORCE)
set(WITH_IK_ITASC OFF CACHE BOOL "" FORCE)
set(WITH_IK_SOLVER OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_CINEON OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_DDS OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_HDR OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_OPENEXR OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_OPENJPEG OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_TIFF OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_WEBP OFF CACHE BOOL "" FORCE)
set(WITH_INPUT_IME OFF CACHE BOOL "" FORCE)
set(WITH_INPUT_NDOF OFF CACHE BOOL "" FORCE)

View File

@ -27,11 +27,8 @@ set(WITH_HARU ON CACHE BOOL "" FORCE)
set(WITH_IK_ITASC ON CACHE BOOL "" FORCE)
set(WITH_IK_SOLVER ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_DDS ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_HDR ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_OPENEXR ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_OPENJPEG ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_TIFF ON CACHE BOOL "" FORCE)
set(WITH_IMAGE_WEBP ON CACHE BOOL "" FORCE)
set(WITH_INPUT_NDOF ON CACHE BOOL "" FORCE)
set(WITH_INPUT_IME ON CACHE BOOL "" FORCE)

View File

@ -221,10 +221,8 @@ find_package(PNG REQUIRED)
set(JPEG_ROOT ${LIBDIR}/jpeg)
find_package(JPEG REQUIRED)
if(WITH_IMAGE_TIFF)
set(TIFF_ROOT ${LIBDIR}/tiff)
find_package(TIFF REQUIRED)
endif()
set(TIFF_ROOT ${LIBDIR}/tiff)
find_package(TIFF REQUIRED)
if(WITH_IMAGE_WEBP)
set(WEBP_ROOT_DIR ${LIBDIR}/webp)
@ -453,6 +451,31 @@ if(WITH_COMPILER_CCACHE)
endif()
endif()
unset(_custom_LINKER_FUSE_FLAG)
if(WITH_LINKER_LLD)
find_program(LLD_PROGRAM ld.lld)
if(LLD_PROGRAM)
set(_custom_LINKER_FUSE_FLAG "-fuse-ld=lld")
else()
message(WARNING "LLD linker NOT found, disabling WITH_LINKER_LLD")
set(WITH_LINKER_LLD OFF)
endif()
endif()
if(WITH_LINKER_MOLD)
find_program(MOLD_PROGRAM mold)
if(MOLD_PROGRAM)
set(_custom_LINKER_FUSE_FLAG "-fuse-ld=mold")
else()
message(WARNING "Mold linker NOT found, disabling WITH_LINKER_MOLD")
set(WITH_LINKER_MOLD OFF)
endif()
endif()
if(_custom_LINKER_FUSE_FLAG)
add_link_options(${_custom_LINKER_FUSE_FLAG})
endif()
if(WITH_COMPILER_ASAN)
list(APPEND PLATFORM_BUNDLED_LIBRARIES ${COMPILER_ASAN_LIBRARY})
endif()

View File

@ -109,6 +109,10 @@ find_package_wrapper(ZLIB REQUIRED)
find_package_wrapper(Zstd REQUIRED)
find_package_wrapper(Epoxy REQUIRED)
# XXX Linking errors with debian static tiff :/
# find_package_wrapper(TIFF REQUIRED)
find_package(TIFF)
if(WITH_VULKAN_BACKEND)
find_package_wrapper(Vulkan REQUIRED)
find_package_wrapper(ShaderC REQUIRED)
@ -190,13 +194,6 @@ if(WITH_IMAGE_OPENJPEG)
set_and_warn_library_found("OpenJPEG" OPENJPEG_FOUND WITH_IMAGE_OPENJPEG)
endif()
if(WITH_IMAGE_TIFF)
# XXX Linking errors with debian static tiff :/
# find_package_wrapper(TIFF)
find_package(TIFF)
set_and_warn_library_found("TIFF" TIFF_FOUND WITH_IMAGE_TIFF)
endif()
if(WITH_OPENAL)
find_package_wrapper(OpenAL)
set_and_warn_library_found("OpenAL" OPENAL_FOUND WITH_OPENAL)
@ -818,64 +815,49 @@ if(CMAKE_COMPILER_IS_GNUCC)
string(PREPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO "${GCC_EXTRA_FLAGS_RELEASE} ")
unset(GCC_EXTRA_FLAGS_RELEASE)
# NOTE(@campbellbarton): Eventually mold will be able to use `-fuse-ld=mold`,
# however at the moment this only works for GCC 12.1+ (unreleased at time of writing).
# So a workaround is used here "-B" which points to another path to find system commands
# such as `ld`.
if(WITH_LINKER_MOLD AND _IS_LINKER_DEFAULT)
find_program(MOLD_BIN "mold")
mark_as_advanced(MOLD_BIN)
if(NOT MOLD_BIN)
message(STATUS "The \"mold\" binary could not be found, using system linker.")
set(WITH_LINKER_MOLD OFF)
elseif(CMAKE_C_COMPILER_VERSION VERSION_LESS 12.1)
message(STATUS "GCC 12.1 or newer is required for th MOLD linker.")
set(WITH_LINKER_MOLD OFF)
else()
# By default mold installs the binary to:
# - `{PREFIX}/bin/mold` as well as a symbolic-link in...
# - `{PREFIX}/lib/mold/ld`.
# (where `PREFIX` is typically `/usr/`).
#
# This block of code finds `{PREFIX}/lib/mold` from the `mold` binary.
# Other methods of searching for the path could also be made to work,
# we could even make our own directory and symbolic-link, however it's more
# convenient to use the one provided by mold.
#
# Use the binary path to "mold", to find the common prefix which contains "lib/mold".
# The parent directory: e.g. `/usr/bin/mold` -> `/usr/bin/`.
get_filename_component(MOLD_PREFIX "${MOLD_BIN}" DIRECTORY)
# The common prefix path: e.g. `/usr/bin/` -> `/usr/` to use as a hint.
get_filename_component(MOLD_PREFIX "${MOLD_PREFIX}" DIRECTORY)
# Find `{PREFIX}/lib/mold/ld`, store the directory component (without the `ld`).
# Then pass `-B {PREFIX}/lib/mold` to GCC so the `ld` located there overrides the default.
find_path(
MOLD_BIN_DIR "ld"
HINTS "${MOLD_PREFIX}"
# The default path is `libexec`, Arch Linux for e.g.
# replaces this with `lib` so check both.
PATH_SUFFIXES "libexec/mold" "lib/mold" "lib64/mold"
NO_DEFAULT_PATH
NO_CACHE
get_filename_component(MOLD_BIN_DIR "${MOLD_BIN}" DIRECTORY)
# Check if the `-B` argument is required.
# This will happen when `MOLD_BIN` points to a non-standard location.
# Keep this option as mold is not yet a standard system component and
# users may have it installed in some unexpected place.
set(_mold_args "-fuse-ld=mold")
execute_process(
COMMAND ${CMAKE_C_COMPILER} -B ${MOLD_BIN_DIR} ${_mold_args} -Wl,--version
ERROR_QUIET OUTPUT_VARIABLE LD_VERSION_WITH_DIR
)
if(NOT MOLD_BIN_DIR)
message(STATUS
"The mold linker could not find the directory containing the linker command "
"(typically "
"\"${MOLD_PREFIX}/libexec/mold/ld\") or "
"\"${MOLD_PREFIX}/lib/mold/ld\") using system linker."
)
set(WITH_LINKER_MOLD OFF)
execute_process(
COMMAND ${CMAKE_C_COMPILER} ${_mold_args} -Wl,--version
ERROR_QUIET OUTPUT_VARIABLE LD_VERSION
)
if(NOT (LD_VERSION STREQUAL LD_VERSION_WITH_DIR))
string(PREPEND _mold_args "-B \"${MOLD_BIN_DIR}\" ")
set(LD_VERSION "${LD_VERSION_WITH_DIR}")
endif()
unset(MOLD_PREFIX)
endif()
if(WITH_LINKER_MOLD)
# GCC will search for `ld` in this directory first.
string(APPEND CMAKE_EXE_LINKER_FLAGS " -B \"${MOLD_BIN_DIR}\"")
string(APPEND CMAKE_SHARED_LINKER_FLAGS " -B \"${MOLD_BIN_DIR}\"")
string(APPEND CMAKE_MODULE_LINKER_FLAGS " -B \"${MOLD_BIN_DIR}\"")
set(_IS_LINKER_DEFAULT OFF)
if("${LD_VERSION}" MATCHES "mold ")
string(APPEND CMAKE_EXE_LINKER_FLAGS " ${_mold_args}")
string(APPEND CMAKE_SHARED_LINKER_FLAGS " ${_mold_args}")
string(APPEND CMAKE_MODULE_LINKER_FLAGS " ${_mold_args}")
set(_IS_LINKER_DEFAULT OFF)
else()
message(STATUS "GNU mold linker isn't available, using the default system linker.")
endif()
unset(_mold_args)
unset(MOLD_BIN_DIR)
unset(LD_VERSION)
endif()
unset(MOLD_BIN)
unset(MOLD_BIN_DIR)
endif()
if(WITH_LINKER_GOLD AND _IS_LINKER_DEFAULT)

View File

@ -487,14 +487,12 @@ if(WITH_IMAGE_OPENEXR)
endif()
endif()
if(WITH_IMAGE_TIFF)
# Try to find tiff first then complain and set static and maybe wrong paths
windows_find_package(TIFF)
if(NOT TIFF_FOUND)
warn_hardcoded_paths(libtiff)
set(TIFF_LIBRARY ${LIBDIR}/tiff/lib/libtiff.lib)
set(TIFF_INCLUDE_DIR ${LIBDIR}/tiff/include)
endif()
# Try to find tiff first then complain and set static and maybe wrong paths
windows_find_package(TIFF)
if(NOT TIFF_FOUND)
warn_hardcoded_paths(libtiff)
set(TIFF_LIBRARY ${LIBDIR}/tiff/lib/libtiff.lib)
set(TIFF_INCLUDE_DIR ${LIBDIR}/tiff/include)
endif()
if(WITH_JACK)

View File

@ -172,6 +172,8 @@ def system_info():
def list_render_passes(scene, srl):
import _cycles
crl = srl.cycles
# Combined pass.
@ -250,6 +252,12 @@ def list_render_passes(scene, srl):
for lightgroup in srl.lightgroups:
yield ("Combined_%s" % lightgroup.name, "RGB", 'COLOR')
# Path guiding debug passes.
if _cycles.with_debug:
yield ("Guiding Color", "RGB", 'COLOR')
yield ("Guiding Probability", "X", 'VALUE')
yield ("Guiding Average Roughness", "X", 'VALUE')
def register_passes(engine, scene, view_layer):
for name, channelids, channeltype in list_render_passes(scene, view_layer):

View File

@ -3,6 +3,7 @@
from __future__ import annotations
import bpy
from bpy.app.translations import contexts as i18n_contexts
from bpy_extras.node_utils import find_node_input
from bl_ui.utils import PresetPanel
@ -318,7 +319,7 @@ class CYCLES_RENDER_PT_sampling_path_guiding(CyclesButtonsPanel, Panel):
col = layout.column(align=True)
col.prop(cscene, "use_surface_guiding", text="Surface")
col.prop(cscene, "use_volume_guiding", text="Volume")
col.prop(cscene, "use_volume_guiding", text="Volume", text_ctxt=i18n_contexts.id_id)
class CYCLES_RENDER_PT_sampling_path_guiding_debug(CyclesDebugButtonsPanel, Panel):
@ -530,7 +531,7 @@ class CYCLES_RENDER_PT_light_paths_max_bounces(CyclesButtonsPanel, Panel):
col.prop(cscene, "diffuse_bounces", text="Diffuse")
col.prop(cscene, "glossy_bounces", text="Glossy")
col.prop(cscene, "transmission_bounces", text="Transmission")
col.prop(cscene, "volume_bounces", text="Volume")
col.prop(cscene, "volume_bounces", text="Volume", text_ctxt=i18n_contexts.id_id)
col = layout.column(align=True)
col.prop(cscene, "transparent_max_bounces", text="Transparent")
@ -980,7 +981,7 @@ class CYCLES_RENDER_PT_passes_light(CyclesButtonsPanel, Panel):
col.prop(view_layer, "use_pass_transmission_indirect", text="Indirect")
col.prop(view_layer, "use_pass_transmission_color", text="Color")
col = layout.column(heading="Volume", align=True)
col = layout.column(heading="Volume", heading_ctxt=i18n_contexts.id_id, align=True)
col.prop(cycles_view_layer, "use_pass_volume_direct", text="Direct")
col.prop(cycles_view_layer, "use_pass_volume_indirect", text="Indirect")
@ -1577,6 +1578,7 @@ class CYCLES_WORLD_PT_surface(CyclesButtonsPanel, Panel):
class CYCLES_WORLD_PT_volume(CyclesButtonsPanel, Panel):
bl_label = "Volume"
bl_translation_context = i18n_contexts.id_id
bl_context = "world"
bl_options = {'DEFAULT_CLOSED'}
@ -1696,6 +1698,7 @@ class CYCLES_WORLD_PT_settings_surface(CyclesButtonsPanel, Panel):
class CYCLES_WORLD_PT_settings_volume(CyclesButtonsPanel, Panel):
bl_label = "Volume"
bl_translation_context = i18n_contexts.id_id
bl_parent_id = "CYCLES_WORLD_PT_settings"
bl_context = "world"
@ -1791,6 +1794,7 @@ class CYCLES_MATERIAL_PT_surface(CyclesButtonsPanel, Panel):
class CYCLES_MATERIAL_PT_volume(CyclesButtonsPanel, Panel):
bl_label = "Volume"
bl_translation_context = i18n_contexts.id_id
bl_context = "material"
bl_options = {'DEFAULT_CLOSED'}
@ -1874,6 +1878,7 @@ class CYCLES_MATERIAL_PT_settings_surface(CyclesButtonsPanel, Panel):
class CYCLES_MATERIAL_PT_settings_volume(CyclesButtonsPanel, Panel):
bl_label = "Volume"
bl_translation_context = i18n_contexts.id_id
bl_parent_id = "CYCLES_MATERIAL_PT_settings"
bl_context = "material"

View File

@ -244,7 +244,7 @@ static void export_pointcloud_motion(PointCloud *pointcloud,
const int num_points = pointcloud->num_points();
/* Point cloud attributes are stored as float4 with the radius in the w element.
* This is explict now as float3 is no longer interchangeable with float4 as it
* This is explicit now as float3 is no longer interchangeable with float4 as it
* is packed now. */
float4 *mP = attr_mP->data_float4() + motion_step * num_points;
bool have_motion = false;

View File

@ -634,6 +634,10 @@ static bool get_known_pass_type(BL::RenderPass &b_pass, PassType &type, PassMode
MAP_PASS("AdaptiveAuxBuffer", PASS_ADAPTIVE_AUX_BUFFER, false);
MAP_PASS("Debug Sample Count", PASS_SAMPLE_COUNT, false);
MAP_PASS("Guiding Color", PASS_GUIDING_COLOR, false);
MAP_PASS("Guiding Probability", PASS_GUIDING_PROBABILITY, false);
MAP_PASS("Guiding Average Roughness", PASS_GUIDING_AVG_ROUGHNESS, false);
if (string_startswith(name, cryptomatte_prefix)) {
type = PASS_CRYPTOMATTE;
mode = PassMode::DENOISED;
@ -684,18 +688,6 @@ void BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLayer &b_v
}
scene->film->set_cryptomatte_passes(cryptomatte_passes);
/* Path guiding debug passes. */
#ifdef WITH_CYCLES_DEBUG
b_engine.add_pass("Guiding Color", 3, "RGB", b_view_layer.name().c_str());
pass_add(scene, PASS_GUIDING_COLOR, "Guiding Color", PassMode::NOISY);
b_engine.add_pass("Guiding Probability", 1, "X", b_view_layer.name().c_str());
pass_add(scene, PASS_GUIDING_PROBABILITY, "Guiding Probability", PassMode::NOISY);
b_engine.add_pass("Guiding Average Roughness", 1, "X", b_view_layer.name().c_str());
pass_add(scene, PASS_GUIDING_AVG_ROUGHNESS, "Guiding Average Roughness", PassMode::NOISY);
#endif
unordered_set<string> expected_passes;
/* Custom AOV passes. */

View File

@ -1167,8 +1167,8 @@ BVHNode *BVHBuild::create_leaf_node(const BVHRange &range, const vector<BVHRefer
void BVHBuild::rotate(BVHNode *node, int max_depth, int iterations)
{
/* in tested scenes, this resulted in slightly slower raytracing, so disabled
* it for now. could be implementation bug, or depend on the scene */
/* In tested scenes, this resulted in slightly slower ray-tracing, so disabled
* it for now. could be implementation bug, or depend on the scene. */
if (node)
for (int i = 0; i < iterations; i++)
rotate(node, max_depth);

View File

@ -181,7 +181,7 @@ string OptiXDevice::compile_kernel_get_common_cflags(const uint kernel_features)
/* Add OptiX SDK include directory to include paths. */
common_cflags += string_printf(" -I\"%s\"", get_optix_include_dir().c_str());
/* Specialization for shader raytracing. */
/* Specialization for shader ray-tracing. */
if (kernel_features & KERNEL_FEATURE_NODE_RAYTRACE) {
common_cflags += " --keep-device-functions";
}
@ -483,7 +483,7 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
group_descs[PG_HITL].hitgroup.entryFunctionNameAH = "__anyhit__kernel_optix_local_hit";
}
/* Shader raytracing replaces some functions with direct callables. */
/* Shader ray-tracing replaces some functions with direct callables. */
if (kernel_features & KERNEL_FEATURE_NODE_RAYTRACE) {
group_descs[PG_RGEN_SHADE_SURFACE_RAYTRACE].kind = OPTIX_PROGRAM_GROUP_KIND_RAYGEN;
group_descs[PG_RGEN_SHADE_SURFACE_RAYTRACE].raygen.module = optix_module;
@ -584,7 +584,7 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
load_osl_kernels();
}
else if (kernel_features & (KERNEL_FEATURE_NODE_RAYTRACE | KERNEL_FEATURE_MNEE)) {
/* Create shader raytracing and MNEE pipeline. */
/* Create shader ray-tracing and MNEE pipeline. */
vector<OptixProgramGroup> pipeline_groups;
pipeline_groups.reserve(NUM_PROGRAM_GROUPS);
if (kernel_features & KERNEL_FEATURE_NODE_RAYTRACE) {

View File

@ -834,7 +834,7 @@ enum ShaderDataFlag {
SD_NEED_VOLUME_ATTRIBUTES = (1 << 28),
/* Shader has emission */
SD_HAS_EMISSION = (1 << 29),
/* Shader has raytracing */
/* Shader has ray-tracing. */
SD_HAS_RAYTRACE = (1 << 30),
/* Use back side for direct light sampling. */
SD_MIS_BACK = (1 << 31),

View File

@ -5890,7 +5890,7 @@ void SeparateHSVNode::compile(OSLCompiler &compiler)
compiler.add(this, "node_separate_hsv");
}
/* Hue Saturation Value */
/* Hue/Saturation/Value */
NODE_DEFINE(HSVNode)
{

View File

@ -204,7 +204,8 @@ GHOST_ContextEGL::GHOST_ContextEGL(const GHOST_System *const system,
m_swap_interval(1),
m_sharedContext(
choose_api(api, s_gl_sharedContext, s_gles_sharedContext, s_vg_sharedContext)),
m_sharedCount(choose_api(api, s_gl_sharedCount, s_gles_sharedCount, s_vg_sharedCount))
m_sharedCount(choose_api(api, s_gl_sharedCount, s_gles_sharedCount, s_vg_sharedCount)),
m_surface_from_native_window(false)
{
}
@ -454,6 +455,7 @@ GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext()
if (m_nativeWindow != 0) {
m_surface = ::eglCreateWindowSurface(m_display, m_config, m_nativeWindow, nullptr);
m_surface_from_native_window = true;
}
else {
static const EGLint pb_attrib_list[] = {
@ -598,8 +600,12 @@ error:
GHOST_TSuccess GHOST_ContextEGL::releaseNativeHandles()
{
m_nativeWindow = 0;
m_nativeDisplay = nullptr;
m_nativeWindow = 0;
if (m_surface_from_native_window) {
m_surface = EGL_NO_SURFACE;
}
return GHOST_kSuccess;
}

View File

@ -122,6 +122,11 @@ class GHOST_ContextEGL : public GHOST_Context {
EGLContext &m_sharedContext;
EGLint &m_sharedCount;
/**
* True when the surface is created from `m_nativeWindow`.
*/
bool m_surface_from_native_window;
static EGLContext s_gl_sharedContext;
static EGLint s_gl_sharedCount;

View File

@ -1400,7 +1400,9 @@ bool GHOST_SystemCocoa::handleOpenDocumentRequest(void *filepathStr)
[[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil];
}
GHOST_Window *window = (GHOST_Window *)m_windowManager->getActiveWindow();
GHOST_Window *window = m_windowManager->getWindows().empty() ?
NULL :
(GHOST_Window *)m_windowManager->getWindows().front();
if (!window) {
return NO;

View File

@ -6339,14 +6339,15 @@ GHOST_TSuccess GHOST_SystemWayland::disposeContext(GHOST_IContext *context)
#ifdef USE_EVENT_BACKGROUND_THREAD
std::lock_guard lock_server_guard{*server_mutex};
#endif
struct wl_surface *wl_surface = (struct wl_surface *)((GHOST_Context *)context)->getUserData();
/* Delete the context before the window so the context is able to release
* native resources (such as the #EGLSurface) before WAYLAND frees them. */
delete context;
wl_egl_window *egl_window = (wl_egl_window *)wl_surface_get_user_data(wl_surface);
wl_egl_window_destroy(egl_window);
wl_surface_destroy(wl_surface);
delete context;
return GHOST_kSuccess;
}

View File

@ -2157,7 +2157,7 @@ char *GHOST_SystemX11::getClipboard(bool selection) const
Atom target = m_atom.UTF8_STRING;
Window owner;
/* from xclip.c doOut() v0.11 */
/* From `xclip.c` `doOut()` v0.11. */
char *sel_buf;
ulong sel_len = 0;
XEvent evt;
@ -2614,13 +2614,13 @@ static bool match_token(const char *haystack, const char *needle)
/* Determining if an X device is a Tablet style device is an imperfect science.
* We rely on common conventions around device names as well as the type reported
* by Wacom tablets. This code will likely need to be expanded for alternate tablet types
* by WACOM tablets. This code will likely need to be expanded for alternate tablet types
*
* Wintab refers to any device that interacts with the tablet as a cursor,
* WINTAB refers to any device that interacts with the tablet as a cursor,
* (stylus, eraser, tablet mouse, airbrush, etc)
* this is not to be confused with wacom x11 configuration "cursor" device.
* Wacoms x11 config "cursor" refers to its device slot (which we mirror with
* our gSysCursors) for puck like devices (tablet mice essentially).
* this is not to be confused with WACOM X11 configuration "cursor" device.
* WACOM tablets X11 configuration "cursor" refers to its device slot (which we mirror with
* our `gSysCursors`) for puck like devices (tablet mice essentially).
*/
static GHOST_TTabletMode tablet_mode_from_name(const char *name, const char *type)
{

View File

@ -138,8 +138,6 @@ enum eGWL_PendingWindowActions {
* The state of the window frame has changed, apply the state from #GWL_Window::frame_pending.
*/
PENDING_WINDOW_FRAME_CONFIGURE = 0,
/** The EGL buffer must be resized to match #GWL_WindowFrame::size. */
PENDING_EGL_WINDOW_RESIZE,
# ifdef GHOST_OPENGL_ALPHA
/** Draw an opaque region behind the window. */
PENDING_OPAQUE_SET,
@ -150,7 +148,17 @@ enum eGWL_PendingWindowActions {
*/
PENDING_OUTPUT_SCALE_UPDATE,
PENDING_WINDOW_SURFACE_SCALE,
/**
* Workaround for a bug/glitch in WLROOTS based compositors (RIVER for e.g.).
* Deferring the scale update one even-loop cycle resolves a bug
* where the output enter/exit events cause the surface buffer being an invalid size.
*
* While these kinds of glitches might be ignored in some cases,
* this caused newly created windows to immediately loose the connection to WAYLAND
* (crashing from a user perspective).
*/
PENDING_OUTPUT_SCALE_UPDATE_DEFERRED,
/**
* The surface needs a commit to run.
* Use this to avoid committing immediately which can cause flickering when other operations
@ -669,20 +677,20 @@ static void gwl_window_pending_actions_handle(GWL_Window *win)
if (actions[PENDING_WINDOW_FRAME_CONFIGURE]) {
gwl_window_frame_update_from_pending(win);
}
if (actions[PENDING_EGL_WINDOW_RESIZE]) {
wl_egl_window_resize(win->egl_window, UNPACK2(win->frame.size), 0, 0);
}
# ifdef GHOST_OPENGL_ALPHA
if (actions[PENDING_OPAQUE_SET]) {
win->ghost_window->setOpaque();
}
# endif
if (actions[PENDING_OUTPUT_SCALE_UPDATE_DEFERRED]) {
gwl_window_pending_actions_tag(win, PENDING_OUTPUT_SCALE_UPDATE);
/* Force postponing scale update to ensure all scale information has been taken into account
* before the actual update is performed. Failing to do so tends to cause flickering. */
actions[PENDING_OUTPUT_SCALE_UPDATE] = false;
}
if (actions[PENDING_OUTPUT_SCALE_UPDATE]) {
win->ghost_window->outputs_changed_update_scale();
}
if (actions[PENDING_WINDOW_SURFACE_SCALE]) {
wl_surface_set_buffer_scale(win->wl_surface, win->frame.buffer_scale);
}
if (actions[PENDING_WINDOW_SURFACE_COMMIT]) {
wl_surface_commit(win->wl_surface);
}
@ -727,19 +735,11 @@ static void gwl_window_frame_update_from_pending_no_lock(GWL_Window *win)
}
if (surface_needs_egl_resize) {
#ifdef USE_EVENT_BACKGROUND_THREAD
gwl_window_pending_actions_tag(win, PENDING_EGL_WINDOW_RESIZE);
#else
wl_egl_window_resize(win->egl_window, UNPACK2(win->frame.size), 0, 0);
#endif
}
if (surface_needs_buffer_scale) {
#ifdef USE_EVENT_BACKGROUND_THREAD
gwl_window_pending_actions_tag(win, PENDING_WINDOW_SURFACE_SCALE);
#else
wl_surface_set_buffer_scale(win->wl_surface, win->frame.buffer_scale);
#endif
}
if (surface_needs_commit) {
@ -1936,7 +1936,10 @@ GHOST_TSuccess GHOST_WindowWayland::notify_decor_redraw()
void GHOST_WindowWayland::outputs_changed_update_scale_tag()
{
#ifdef USE_EVENT_BACKGROUND_THREAD
gwl_window_pending_actions_tag(window_, PENDING_OUTPUT_SCALE_UPDATE);
/* NOTE: if deferring causes problems, it could be isolated to the first scale initialization
* See: #GWL_WindowFrame::is_scale_init. */
gwl_window_pending_actions_tag(window_, PENDING_OUTPUT_SCALE_UPDATE_DEFERRED);
#else
outputs_changed_update_scale();
#endif
@ -1975,16 +1978,6 @@ bool GHOST_WindowWayland::outputs_changed_update_scale()
fractional_scale_next = fractional_scale_from_output;
scale_next = fractional_scale_next / FRACTIONAL_DENOMINATOR;
}
else {
/* NOTE(@ideasman42): This often overrides #wp_fractional_scale_v1_listener::preferred_scale
* in favor of using the greatest overlapping scale.
* This was requested by the studio to prevent a tablet's built-in display of 75%
* from causing the main-display being up-scaled (showing pixelated). */
if (fractional_scale_next < fractional_scale_from_output) {
fractional_scale_next = fractional_scale_from_output;
scale_next = fractional_scale_next / FRACTIONAL_DENOMINATOR;
}
}
bool changed = false;

View File

@ -123,7 +123,7 @@ def expand(line, cursor, namespace, *, private=True):
[white_space + m[len(word_prefix):]
if (word_prefix and m.startswith(word_prefix))
else
white_space + m.split('.')[-1]
white_space + m.rsplit('.', 1)[-1]
for m in matches])
no_calltip = True

View File

@ -28,7 +28,7 @@ def rna_backup_gen(data, include_props=None, exclude_props=None, root=()):
# only writable properties...
for p in data.bl_rna.properties:
pid = p.identifier
if pid == "rna_type" or pid == "original":
if pid in {"rna_type", "original"}:
continue
path = root + (pid,)
if include_props is not None and path not in include_props:

View File

@ -355,7 +355,7 @@ def script_paths(*, subdir=None, user_pref=True, check_all=False, use_user=True)
:arg subdir: Optional subdir.
:type subdir: string
:arg user_pref: Include the user preference script path.
:arg user_pref: Include the user preference script paths.
:type user_pref: bool
:arg check_all: Include local, user and system paths rather just the paths Blender uses.
:type check_all: bool
@ -387,6 +387,9 @@ def script_paths(*, subdir=None, user_pref=True, check_all=False, use_user=True)
if use_user:
base_paths.append(path_user)
if user_pref:
base_paths.extend(script_paths_pref())
scripts = []
for path in base_paths:
if not path:

View File

@ -94,9 +94,7 @@ def keyconfig_test(kc):
if testEntry(kc, child, src, parent):
result = True
else:
for i in range(len(km.keymap_items)):
src = km.keymap_items[i]
for i, src in enumerate(km.keymap_items):
for child in children:
if testEntry(kc, child, src, km):
result = True

View File

@ -417,7 +417,7 @@ def ngon_tessellate(from_data, indices, fix_loops=True, debug_print=True):
if not flip:
for i, fi in enumerate(fill):
fill[i] = tuple([ii for ii in reversed(fi)])
fill[i] = tuple(reversed(fi))
return fill

View File

@ -5,6 +5,44 @@ __all__ = (
)
def connect_sockets(input, output):
"""
Connect sockets in a node tree.
This is useful because the links created through the normal Python API are
invalid when one of the sockets is a virtual socket (grayed out sockets in
Group Input and Group Output nodes).
It replaces node_tree.links.new(input, output)
"""
import bpy
# Swap sockets if they are not passed in the proper order
if input.is_output and not output.is_output:
input, output = output, input
input_node = output.node
output_node = input.node
if input_node.id_data is not output_node.id_data:
print("Sockets do not belong to the same node tree")
return
if type(input) == type(output) == bpy.types.NodeSocketVirtual:
print("Cannot connect two virtual sockets together")
return
if output_node.type == 'GROUP_OUTPUT' and type(input) == bpy.types.NodeSocketVirtual:
output_node.id_data.outputs.new(type(output).__name__, output.name)
input = output_node.inputs[-2]
if input_node.type == 'GROUP_INPUT' and type(output) == bpy.types.NodeSocketVirtual:
output_node.id_data.inputs.new(type(input).__name__, input.name)
output = input_node.outputs[-2]
return input_node.id_data.links.new(input, output)
# XXX Names are not unique. Returns the first match.
def find_node_input(node, name):
for input in node.inputs:

View File

@ -580,7 +580,6 @@ class Mesh(bpy_types.ID):
vertex_indices = tuple(chain.from_iterable(faces))
loop_starts = tuple(islice(chain([0], accumulate(face_lengths)), faces_len))
self.polygons.foreach_set("loop_total", face_lengths)
self.polygons.foreach_set("loop_start", loop_starts)
self.polygons.foreach_set("vertices", vertex_indices)

View File

@ -5600,9 +5600,13 @@ def km_font(params):
("font.move_select", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True, "repeat": True},
{"properties": [("type", 'NEXT_PAGE')]}),
("font.change_spacing", {"type": 'LEFT_ARROW', "value": 'PRESS', "alt": True, "repeat": True},
{"properties": [("delta", -1)]}),
{"properties": [("delta", -1.0)]}),
("font.change_spacing", {"type": 'RIGHT_ARROW', "value": 'PRESS', "alt": True, "repeat": True},
{"properties": [("delta", 1)]}),
{"properties": [("delta", 1.0)]}),
("font.change_spacing", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "alt": True, "repeat": True},
{"properties": [("delta", -0.1)]}),
("font.change_spacing", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "alt": True, "repeat": True},
{"properties": [("delta", 0.1)]}),
("font.change_character", {"type": 'UP_ARROW', "value": 'PRESS', "alt": True, "repeat": True},
{"properties": [("delta", 1)]}),
("font.change_character", {"type": 'DOWN_ARROW', "value": 'PRESS', "alt": True, "repeat": True},

View File

@ -242,7 +242,6 @@ class AddTorus(Operator, object_utils.AddObjectHelper):
mesh.vertices.foreach_set("co", verts_loc)
mesh.polygons.foreach_set("loop_start", range(0, nbr_loops, 4))
mesh.polygons.foreach_set("loop_total", (4,) * nbr_polys)
mesh.loops.foreach_set("vertex_index", faces)
if self.generate_uvs:

View File

@ -239,7 +239,6 @@ def find_next(ele_dst, ele_src):
# expose for operators
def select_next(bm, report):
import bmesh
ele_pair = [None, None]
for i, ele in enumerate(reversed(bm.select_history)):
ele_pair[i] = ele

View File

@ -488,7 +488,7 @@ class CLIP_OT_constraint_to_fcurve(Operator):
efra = max(efra, track.markers[-1].frame)
if sfra is None or efra is None:
return
return {'CANCELLED'}
# Store object matrices.
for x in range(sfra, efra + 1):
@ -516,6 +516,8 @@ class CLIP_OT_constraint_to_fcurve(Operator):
scene.frame_set(frame_current)
return {'FINISHED'}
def execute(self, context):
scene = context.scene
# XXX, should probably use context.selected_editable_objects
@ -662,8 +664,7 @@ class CLIP_OT_setup_tracking_scene(Operator):
if collection.collection.name == collection_name:
setattr(collection, attr_name, True)
break
else:
setup_collection_recursively(collection.children, collection_name, attr_name)
setup_collection_recursively(collection.children, collection_name, attr_name)
collections = context.scene.collection.children
vlayers = context.scene.view_layers
@ -868,7 +869,6 @@ class CLIP_OT_setup_tracking_scene(Operator):
mesh.polygons.add(nbr_polys)
mesh.polygons.foreach_set("loop_start", range(0, nbr_loops, 4))
mesh.polygons.foreach_set("loop_total", (4,) * nbr_polys)
mesh.loops.foreach_set("vertex_index", faces)
mesh.update()

View File

@ -101,9 +101,9 @@ class MeshMirrorUV(Operator):
for i, j in pmap.items():
if not puvsel[i] or not puvsel[j]:
continue
elif DIR == 0 and pcents[i][0] < 0.0:
if DIR == 0 and pcents[i][0] < 0.0:
continue
elif DIR == 1 and pcents[i][0] > 0.0:
if DIR == 1 and pcents[i][0] > 0.0:
continue
# copy UVs

View File

@ -9,8 +9,6 @@ from bpy.types import (
from bpy.props import (
BoolProperty,
CollectionProperty,
EnumProperty,
IntProperty,
StringProperty,
)

View File

@ -618,7 +618,6 @@ class MakeDupliFace(Operator):
mesh.vertices.foreach_set("co", face_verts)
mesh.loops.foreach_set("vertex_index", faces)
mesh.polygons.foreach_set("loop_start", range(0, nbr_faces * 4, 4))
mesh.polygons.foreach_set("loop_total", (4,) * nbr_faces)
mesh.update() # generates edge data
ob_new = bpy.data.objects.new(mesh.name, mesh)

View File

@ -121,8 +121,16 @@ class QuickFur(ObjectModeOperator, Operator):
material = bpy.data.materials.new("Fur Material")
mesh_with_zero_area = False
mesh_missing_uv_map = False
modifier_apply_error = False
for mesh_object in mesh_objects:
mesh = mesh_object.data
if len(mesh.uv_layers) == 0:
mesh_missing_uv_map = True
continue
with context.temp_override(active_object=mesh_object):
bpy.ops.object.curves_empty_hair_add()
curves_object = context.active_object
@ -132,7 +140,11 @@ class QuickFur(ObjectModeOperator, Operator):
area = 0.0
for poly in mesh.polygons:
area += poly.area
density = count / area
if area == 0.0:
mesh_with_zero_area = True
density = 10
else:
density = count / area
generate_modifier = curves_object.modifiers.new(name="Generate", type='NODES')
generate_modifier.node_group = generate_group
@ -166,7 +178,10 @@ class QuickFur(ObjectModeOperator, Operator):
if self.apply_hair_guides:
with context.temp_override(object=curves_object):
bpy.ops.object.modifier_apply(modifier=generate_modifier.name)
try:
bpy.ops.object.modifier_apply(modifier=generate_modifier.name)
except:
modifier_apply_error = True
curves_object.modifiers.move(0, len(curves_object.modifiers) - 1)
@ -174,6 +189,13 @@ class QuickFur(ObjectModeOperator, Operator):
for modifier in curves_object.modifiers:
modifier.node_group = modifier.node_group
if mesh_with_zero_area:
self.report({'WARNING'}, "Mesh has no face area")
if mesh_missing_uv_map:
self.report({'WARNING'}, "Mesh UV map required")
if modifier_apply_error and not mesh_with_zero_area:
self.report({'WARNING'}, "Unable to apply \"Generate\" modifier")
return {'FINISHED'}
@ -454,7 +476,7 @@ class QuickSmoke(ObjectModeOperator, Operator):
# setup smoke domain
bpy.ops.object.modifier_add(type='FLUID')
obj.modifiers[-1].fluid_type = 'DOMAIN'
if self.style == 'FIRE' or self.style == 'BOTH':
if self.style == {'FIRE', 'BOTH'}:
obj.modifiers[-1].domain_settings.use_noise = True
# ensure correct cache file format for smoke

View File

@ -22,8 +22,11 @@ def randomize_selected(context, seed, delta,
obj.delta_location += rand_vec(loc)
else:
obj.location += rand_vec(loc)
else: # otherwise the values change under us
uniform(0.0, 0.0), uniform(0.0, 0.0), uniform(0.0, 0.0)
else:
# Otherwise the values change under us.
uniform(0.0, 0.0)
uniform(0.0, 0.0)
uniform(0.0, 0.0)
if rot:
vec = rand_vec(rot)
@ -68,7 +71,9 @@ def randomize_selected(context, seed, delta,
else:
obj.scale = aX, aY, aZ
else:
uniform(0.0, 0.0), uniform(0.0, 0.0), uniform(0.0, 0.0)
uniform(0.0, 0.0)
uniform(0.0, 0.0)
uniform(0.0, 0.0)
from bpy.props import (

View File

@ -8,6 +8,7 @@ from bpy.app.translations import pgettext_tip as tip_
def guess_player_path(preset):
import os
import sys
if preset == 'INTERNAL':

View File

@ -1170,7 +1170,7 @@ class PREFERENCES_OT_script_directory_new(Operator):
new_dir.directory = self.directory
new_dir.name = os.path.basename(self.directory.rstrip(os.sep))
assert context.preferences.is_dirty == True
assert context.preferences.is_dirty is True
return {'FINISHED'}
@ -1197,10 +1197,11 @@ class PREFERENCES_OT_script_directory_remove(Operator):
script_directories.remove(script_directory)
break
assert context.preferences.is_dirty == True
assert context.preferences.is_dirty is True
return {'FINISHED'}
classes = (
PREFERENCES_OT_addon_disable,
PREFERENCES_OT_addon_enable,

View File

@ -220,8 +220,6 @@ def lightmap_uvpack(
PREF_SEL_ONLY=True,
PREF_NEW_UVLAYER=False,
PREF_PACK_IN_ONE=False,
PREF_APPLY_IMAGE=False,
PREF_IMG_PX_SIZE=512,
PREF_BOX_DIV=8,
PREF_MARGIN_DIV=512,
):
@ -240,8 +238,6 @@ def lightmap_uvpack(
t = time.time()
if PREF_PACK_IN_ONE:
if PREF_APPLY_IMAGE:
image = bpy.data.images.new(name="lightmap", width=PREF_IMG_PX_SIZE, height=PREF_IMG_PX_SIZE, alpha=False)
face_groups = [[]]
else:
face_groups = []
@ -520,20 +516,6 @@ def lightmap_uvpack(
# pf.place(box[1][1], box[1][2], packWidth, packHeight, margin_w, margin_h)
print("done")
if PREF_APPLY_IMAGE:
pass
# removed with texface
'''
if not PREF_PACK_IN_ONE:
image = bpy.data.images.new(name="lightmap",
width=PREF_IMG_PX_SIZE,
height=PREF_IMG_PX_SIZE,
)
for f in face_sel:
f.image = image
'''
for me in meshes:
me.update()
@ -544,11 +526,14 @@ def unwrap(operator, context, **kwargs):
# switch to object mode
is_editmode = context.object and context.object.mode == 'EDIT'
if is_editmode:
objects = context.objects_in_mode_unique_data
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
else:
objects = context.selected_objects
# define list of meshes
meshes = list({
me for obj in context.selected_objects
me for obj in objects
if obj.type == 'MESH'
if (me := obj.data).polygons and me.library is None
})
@ -606,20 +591,6 @@ class LightMapPack(Operator):
description="Create a new UV map for every mesh packed",
default=False,
)
PREF_APPLY_IMAGE: BoolProperty(
name="New Image",
description=(
"Assign new images for every mesh (only one if "
"Share Texture Space is enabled)"
),
default=False,
)
PREF_IMG_PX_SIZE: IntProperty(
name="Image Size",
description="Width and height for the new image",
min=64, max=5000,
default=512,
)
# UV Packing...
PREF_BOX_DIV: IntProperty(
name="Pack Quality",
@ -648,8 +619,6 @@ class LightMapPack(Operator):
layout.prop(self, "PREF_PACK_IN_ONE")
layout.prop(self, "PREF_NEW_UVLAYER")
layout.prop(self, "PREF_APPLY_IMAGE")
layout.prop(self, "PREF_IMG_PX_SIZE")
layout.prop(self, "PREF_BOX_DIV")
layout.prop(self, "PREF_MARGIN_DIV")

View File

@ -120,15 +120,15 @@ def _draw_add_remove_buttons(
list_length,
):
"""Draw the +/- buttons to add and remove list entries."""
add_op = layout.operator(UILIST_OT_entry_add.bl_idname, text="", icon='ADD')
add_op.list_path = list_path
add_op.active_index_path = active_index_path
props = layout.operator(UILIST_OT_entry_add.bl_idname, text="", icon='ADD')
props.list_path = list_path
props.active_index_path = active_index_path
row = layout.row()
row.enabled = list_length > 0
remove_op = row.operator(UILIST_OT_entry_remove.bl_idname, text="", icon='REMOVE')
remove_op.list_path = list_path
remove_op.active_index_path = active_index_path
props = row.operator(UILIST_OT_entry_remove.bl_idname, text="", icon='REMOVE')
props.list_path = list_path
props.active_index_path = active_index_path
def _draw_move_buttons(
@ -141,15 +141,15 @@ def _draw_move_buttons(
"""Draw the up/down arrows to move elements in the list."""
col = layout.column()
col.enabled = list_length > 1
move_up_op = layout.operator(UILIST_OT_entry_move.bl_idname, text="", icon='TRIA_UP')
move_up_op.direction = 'UP'
move_up_op.list_path = list_path
move_up_op.active_index_path = active_index_path
props = layout.operator(UILIST_OT_entry_move.bl_idname, text="", icon='TRIA_UP')
props.direction = 'UP'
props.list_path = list_path
props.active_index_path = active_index_path
move_down_op = layout.operator(UILIST_OT_entry_move.bl_idname, text="", icon='TRIA_DOWN')
move_down_op.direction = 'DOWN'
move_down_op.list_path = list_path
move_down_op.active_index_path = active_index_path
props = layout.operator(UILIST_OT_entry_move.bl_idname, text="", icon='TRIA_DOWN')
props.direction = 'DOWN'
props.list_path = list_path
props.active_index_path = active_index_path
def _get_context_attr(context, data_path):

View File

@ -1,6 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-or-later
import bpy
from bpy.types import Menu
from bpy.app.translations import (
pgettext_iface as iface_,
contexts as i18n_contexts,

View File

@ -423,13 +423,13 @@ class NODE_MT_geometry_node_mesh_topology(Menu):
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeCornersOfFace"),
node_add_menu.add_node_type(layout, "GeometryNodeCornersOfVertex"),
node_add_menu.add_node_type(layout, "GeometryNodeEdgesOfCorner"),
node_add_menu.add_node_type(layout, "GeometryNodeEdgesOfVertex"),
node_add_menu.add_node_type(layout, "GeometryNodeFaceOfCorner"),
node_add_menu.add_node_type(layout, "GeometryNodeOffsetCornerInFace"),
node_add_menu.add_node_type(layout, "GeometryNodeVertexOfCorner"),
node_add_menu.add_node_type(layout, "GeometryNodeCornersOfFace")
node_add_menu.add_node_type(layout, "GeometryNodeCornersOfVertex")
node_add_menu.add_node_type(layout, "GeometryNodeEdgesOfCorner")
node_add_menu.add_node_type(layout, "GeometryNodeEdgesOfVertex")
node_add_menu.add_node_type(layout, "GeometryNodeFaceOfCorner")
node_add_menu.add_node_type(layout, "GeometryNodeOffsetCornerInFace")
node_add_menu.add_node_type(layout, "GeometryNodeVertexOfCorner")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
@ -592,6 +592,7 @@ class NODE_MT_category_GEO_VECTOR(Menu):
class NODE_MT_category_GEO_VOLUME(Menu):
bl_idname = "NODE_MT_category_GEO_VOLUME"
bl_label = "Volume"
bl_translation_context = i18n_contexts.id_id
def draw(self, context):
layout = self.layout

View File

@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
import bpy
from bpy.types import Panel
from bpy.app.translations import contexts as i18n_contexts
from rna_prop_ui import PropertyPanel
from bl_ui.utils import PresetPanel
@ -67,6 +68,7 @@ class DATA_PT_context_camera(CameraButtonsPanel, Panel):
class DATA_PT_lens(CameraButtonsPanel, Panel):
bl_label = "Lens"
bl_translation_context = i18n_contexts.id_camera
COMPAT_ENGINES = {
'BLENDER_RENDER',
'BLENDER_EEVEE',

View File

@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-or-later
from bpy.types import Panel
from bpy.app.translations import contexts as i18n_contexts
class DataButtonsPanel:
@ -15,6 +16,7 @@ class DataButtonsPanel:
class DATA_PT_empty(DataButtonsPanel, Panel):
bl_label = "Empty"
bl_translation_context = i18n_contexts.id_id
def draw(self, context):
layout = self.layout

View File

@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-or-later
import bpy
from bpy.app.translations import contexts as i18n_contexts
from bpy.types import Panel
from rna_prop_ui import PropertyPanel
@ -89,7 +90,7 @@ class DATA_PT_EEVEE_light(DataButtonsPanel, Panel):
col.prop(light, "diffuse_factor", text="Diffuse")
col.prop(light, "specular_factor", text="Specular")
col.prop(light, "volume_factor", text="Volume")
col.prop(light, "volume_factor", text="Volume", text_ctxt=i18n_contexts.id_id)
col.separator()

View File

@ -63,12 +63,12 @@ class MESH_MT_shape_key_context_menu(Menu):
layout.operator("object.join_shapes")
layout.operator("object.shape_key_transfer")
layout.separator()
op = layout.operator("object.shape_key_remove", icon='X', text="Delete All Shape Keys")
op.all = True
op.apply_mix = False
op = layout.operator("object.shape_key_remove", text="Apply All Shape Keys")
op.all = True
op.apply_mix = True
props = layout.operator("object.shape_key_remove", icon='X', text="Delete All Shape Keys")
props.all = True
props.apply_mix = False
props = layout.operator("object.shape_key_remove", text="Apply All Shape Keys")
props.all = True
props.apply_mix = True
layout.separator()
layout.operator("object.shape_key_move", icon='TRIA_UP_BAR', text="Move to Top").type = 'TOP'
layout.operator("object.shape_key_move", icon='TRIA_DOWN_BAR', text="Move to Bottom").type = 'BOTTOM'
@ -674,12 +674,12 @@ class MESH_UL_color_attributes(UIList, ColorAttributesListBase):
row = layout.row()
row.emboss = 'NONE'
prop = row.operator(
props = row.operator(
"geometry.color_attribute_render_set",
text="",
icon='RESTRICT_RENDER_OFF' if active_render else 'RESTRICT_RENDER_ON',
)
prop.name = attribute.name
props.name = attribute.name
class MESH_UL_color_attributes_selector(UIList, ColorAttributesListBase):

View File

@ -739,15 +739,15 @@ class VIEWLAYER_PT_freestyle_linestyle_color(ViewLayerFreestyleLineStyle, Panel)
elif modifier.type == 'DISTANCE_FROM_OBJECT':
box.prop(modifier, "target")
draw_modifier_color_ramp_common(box, modifier, True)
prop = box.operator("scene.freestyle_fill_range_by_selection")
prop.type = 'COLOR'
prop.name = modifier.name
props = box.operator("scene.freestyle_fill_range_by_selection")
props.type = 'COLOR'
props.name = modifier.name
elif modifier.type == 'DISTANCE_FROM_CAMERA':
draw_modifier_color_ramp_common(box, modifier, True)
prop = box.operator("scene.freestyle_fill_range_by_selection")
prop.type = 'COLOR'
prop.name = modifier.name
props = box.operator("scene.freestyle_fill_range_by_selection")
props.type = 'COLOR'
props.name = modifier.name
elif modifier.type == 'MATERIAL':
row = box.row()
@ -842,15 +842,15 @@ class VIEWLAYER_PT_freestyle_linestyle_alpha(ViewLayerFreestyleLineStyle, Panel)
elif modifier.type == 'DISTANCE_FROM_OBJECT':
box.prop(modifier, "target")
draw_modifier_curve_common(box, modifier, True, False)
prop = box.operator("scene.freestyle_fill_range_by_selection")
prop.type = 'ALPHA'
prop.name = modifier.name
props = box.operator("scene.freestyle_fill_range_by_selection")
props.type = 'ALPHA'
props.name = modifier.name
elif modifier.type == 'DISTANCE_FROM_CAMERA':
draw_modifier_curve_common(box, modifier, True, False)
prop = box.operator("scene.freestyle_fill_range_by_selection")
prop.type = 'ALPHA'
prop.name = modifier.name
props = box.operator("scene.freestyle_fill_range_by_selection")
props.type = 'ALPHA'
props.name = modifier.name
elif modifier.type == 'MATERIAL':
box.prop(modifier, "material_attribute", text="Material Attribute")
@ -934,15 +934,15 @@ class VIEWLAYER_PT_freestyle_linestyle_thickness(ViewLayerFreestyleLineStyle, Pa
elif modifier.type == 'DISTANCE_FROM_OBJECT':
box.prop(modifier, "target")
draw_modifier_curve_common(box, modifier, True, True)
prop = box.operator("scene.freestyle_fill_range_by_selection")
prop.type = 'THICKNESS'
prop.name = modifier.name
props = box.operator("scene.freestyle_fill_range_by_selection")
props.type = 'THICKNESS'
props.name = modifier.name
elif modifier.type == 'DISTANCE_FROM_CAMERA':
draw_modifier_curve_common(box, modifier, True, True)
prop = box.operator("scene.freestyle_fill_range_by_selection")
prop.type = 'THICKNESS'
prop.name = modifier.name
props = box.operator("scene.freestyle_fill_range_by_selection")
props.type = 'THICKNESS'
props.name = modifier.name
elif modifier.type == 'MATERIAL':
box.prop(modifier, "material_attribute", text="Material Attribute")

View File

@ -106,10 +106,14 @@ class GreasePencilDisplayPanel:
settings = tool_settings.gpencil_vertex_paint
brush = settings.brush
gp_settings = brush.gpencil_settings
ob = context.active_object
if ob.mode == 'PAINT_GPENCIL':
if self.is_popover and ob.mode not in {'PAINT_GPENCIL', 'VERTEX_GPENCIL'}:
row = layout.row(align=True)
row.use_property_split = False
row.prop(settings, "show_brush", text="Display Cursor")
if ob.mode == 'PAINT_GPENCIL':
if self.is_popover:
row = layout.row(align=True)
row.prop(settings, "show_brush", text="Display Cursor")
@ -135,8 +139,7 @@ class GreasePencilDisplayPanel:
elif ob.mode == 'VERTEX_GPENCIL':
row = layout.row(align=True)
row.prop(settings, "show_brush", text="")
row.label(text="Display Cursor")
row.prop(settings, "show_brush", text="Display Cursor")
class GreasePencilBrushFalloff:
@ -145,16 +148,16 @@ class GreasePencilBrushFalloff:
def draw(self, context):
layout = self.layout
ts = context.tool_settings
tool_settings = context.tool_settings
settings = None
if context.mode == 'PAINT_GPENCIL':
settings = ts.gpencil_paint
settings = tool_settings.gpencil_paint
if context.mode == 'SCULPT_GPENCIL':
settings = ts.gpencil_sculpt_paint
settings = tool_settings.gpencil_sculpt_paint
elif context.mode == 'WEIGHT_GPENCIL':
settings = ts.gpencil_weight_paint
settings = tool_settings.gpencil_weight_paint
elif context.mode == 'VERTEX_GPENCIL':
settings = ts.gpencil_vertex_paint
settings = tool_settings.gpencil_vertex_paint
if settings:
brush = settings.brush
@ -585,9 +588,9 @@ class GreasePencilVertexcolorPanel:
layout.use_property_split = True
layout.use_property_decorate = False
ts = context.scene.tool_settings
tool_settings = context.scene.tool_settings
is_vertex = context.mode == 'VERTEX_GPENCIL'
gpencil_paint = ts.gpencil_vertex_paint if is_vertex else ts.gpencil_paint
gpencil_paint = tool_settings.gpencil_vertex_paint if is_vertex else tool_settings.gpencil_paint
brush = gpencil_paint.brush
gp_settings = brush.gpencil_settings
tool = brush.gpencil_vertex_tool if is_vertex else brush.gpencil_tool
@ -855,30 +858,30 @@ class GreasePencilFlipTintColors(Operator):
@classmethod
def poll(cls, context):
ts = context.tool_settings
tool_settings = context.tool_settings
settings = None
if context.mode == 'PAINT_GPENCIL':
settings = ts.gpencil_paint
settings = tool_settings.gpencil_paint
if context.mode == 'SCULPT_GPENCIL':
settings = ts.gpencil_sculpt_paint
settings = tool_settings.gpencil_sculpt_paint
elif context.mode == 'WEIGHT_GPENCIL':
settings = ts.gpencil_weight_paint
settings = tool_settings.gpencil_weight_paint
elif context.mode == 'VERTEX_GPENCIL':
settings = ts.gpencil_vertex_paint
settings = tool_settings.gpencil_vertex_paint
return settings and settings.brush
def execute(self, context):
ts = context.tool_settings
tool_settings = context.tool_settings
settings = None
if context.mode == 'PAINT_GPENCIL':
settings = ts.gpencil_paint
settings = tool_settings.gpencil_paint
if context.mode == 'SCULPT_GPENCIL':
settings = ts.gpencil_sculpt_paint
settings = tool_settings.gpencil_sculpt_paint
elif context.mode == 'WEIGHT_GPENCIL':
settings = ts.gpencil_weight_paint
settings = tool_settings.gpencil_weight_paint
elif context.mode == 'VERTEX_GPENCIL':
settings = ts.gpencil_vertex_paint
settings = tool_settings.gpencil_vertex_paint
brush = settings.brush
color = brush.color

View File

@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
import bpy
from bpy.types import Menu, Panel, UIList
from bpy.app.translations import contexts as i18n_contexts
from rna_prop_ui import PropertyPanel
from bpy_extras.node_utils import find_node_input
@ -176,6 +177,7 @@ class EEVEE_MATERIAL_PT_surface(MaterialButtonsPanel, Panel):
class EEVEE_MATERIAL_PT_volume(MaterialButtonsPanel, Panel):
bl_label = "Volume"
bl_translation_context = i18n_contexts.id_id
bl_context = "material"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_EEVEE'}

View File

@ -164,8 +164,8 @@ class RENDER_PT_time_stretching(RenderOutputButtonsPanel, Panel):
rd = context.scene.render
col = layout.column(align=True)
col.prop(rd, "frame_map_old", text="Old")
col.prop(rd, "frame_map_new", text="New")
col.prop(rd, "frame_map_old", text="Old", text_ctxt=i18n_contexts.time)
col.prop(rd, "frame_map_new", text="New", text_ctxt=i18n_contexts.time)
class RENDER_PT_post_processing(RenderOutputButtonsPanel, Panel):

View File

@ -378,7 +378,9 @@ class SmoothStrokePanel(BrushPanel):
settings = self.paint_settings(context)
brush = settings.brush
self.layout.prop(brush, "use_smooth_stroke", text="")
self.layout.use_property_split = False
self.layout.prop(brush, "use_smooth_stroke",
text=self.bl_label if self.is_popover else "")
def draw(self, context):
layout = self.layout
@ -472,8 +474,8 @@ class DisplayPanel(BrushPanel):
if self.is_popover:
row = layout.row(align=True)
row.prop(settings, "show_brush", text="")
row.label(text="Display Cursor")
row.use_property_split = False
row.prop(settings, "show_brush", text="Display Cursor")
col = layout.column()
col.active = brush.brush_capabilities.has_overlay and settings.show_brush

View File

@ -328,7 +328,7 @@ class PARTICLE_PT_emission_source(ParticleButtonsPanel, Panel):
col = layout.column()
col.prop(part, "emit_from")
col.prop(part, "use_modifier_stack")
if part.emit_from == 'FACE' or part.emit_from == 'VOLUME':
if part.emit_from in {'FACE', 'VOLUME'}:
col.prop(part, "distribution")
if part.emit_from == 'VERT':
@ -340,7 +340,7 @@ class PARTICLE_PT_emission_source(ParticleButtonsPanel, Panel):
col.prop(part, "use_emit_random", text="Random Order")
col.prop(part, "use_even_distribution")
if part.emit_from == 'FACE' or part.emit_from == 'VOLUME':
if part.emit_from in {'FACE', 'VOLUME'}:
if part.distribution == 'JIT':
col.prop(part, "userjit", text="Particles/Face")

View File

@ -37,6 +37,7 @@ def physics_add(layout, md, name, type, typeicon, toggles):
text_ctxt=i18n_contexts.default,
icon=typeicon,
).type = type
return None
def physics_add_special(layout, data, name, addop, removeop, typeicon):

View File

@ -82,8 +82,7 @@ class PhysicButtonsPanel:
md = context.fluid
flow = md.flow_settings
if (flow.flow_behavior == 'OUTFLOW'):
return True
return (flow.flow_behavior == 'OUTFLOW')
@staticmethod
def poll_fluid_flow_liquid(context):
@ -92,8 +91,7 @@ class PhysicButtonsPanel:
md = context.fluid
flow = md.flow_settings
if (flow.flow_type == 'LIQUID'):
return True
return (flow.flow_type == 'LIQUID')
class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel):

View File

@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-or-later
from bpy.types import Menu, Panel, UIList, ViewLayer
from bpy.app.translations import contexts as i18n_contexts
from rna_prop_ui import PropertyPanel
@ -75,31 +76,6 @@ class VIEWLAYER_PT_eevee_layer_passes_data(ViewLayerButtonsPanel, Panel):
col.prop(view_layer, "use_pass_normal")
class VIEWLAYER_PT_eevee_next_layer_passes_data(ViewLayerButtonsPanel, Panel):
bl_label = "Data"
bl_parent_id = "VIEWLAYER_PT_layer_passes"
COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'}
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
scene = context.scene
view_layer = context.view_layer
col = layout.column()
col.prop(view_layer, "use_pass_combined")
col.prop(view_layer, "use_pass_z")
col.prop(view_layer, "use_pass_mist")
col.prop(view_layer, "use_pass_normal")
col.prop(view_layer, "use_pass_position")
sub = col.column()
sub.active = not scene.eevee.use_motion_blur
sub.prop(view_layer, "use_pass_vector")
class VIEWLAYER_PT_eevee_next_layer_passes_data(ViewLayerButtonsPanel, Panel):
bl_label = "Data"
bl_parent_id = "VIEWLAYER_PT_layer_passes"
@ -140,7 +116,7 @@ class VIEWLAYER_PT_eevee_layer_passes_light(ViewLayerButtonsPanel, Panel):
col.prop(view_layer, "use_pass_glossy_direct", text="Light")
col.prop(view_layer, "use_pass_glossy_color", text="Color")
col = layout.column(heading="Volume", align=True)
col = layout.column(heading="Volume", heading_ctxt=i18n_contexts.id_id, align=True)
col.prop(view_layer_eevee, "use_pass_volume_direct", text="Light")
col = layout.column(heading="Other", align=True)

View File

@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
import bpy
from bpy.types import Panel
from bpy.app.translations import contexts as i18n_contexts
from rna_prop_ui import PropertyPanel
from bpy_extras.node_utils import find_node_input
@ -115,6 +116,7 @@ class EEVEE_WORLD_PT_surface(WorldButtonsPanel, Panel):
class EEVEE_WORLD_PT_volume(WorldButtonsPanel, Panel):
bl_label = "Volume"
bl_translation_context = i18n_contexts.id_id
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_EEVEE'}

View File

@ -890,6 +890,7 @@ class CLIP_PT_tracking_lens(Panel):
bl_region_type = 'UI'
bl_category = "Track"
bl_label = "Lens"
bl_translation_context = i18n_contexts.id_camera
bl_parent_id = 'CLIP_PT_tracking_camera'
bl_options = {'DEFAULT_CLOSED'}
@ -1078,10 +1079,11 @@ class CLIP_PT_2d_cursor(Panel):
@classmethod
def poll(cls, context):
sc = context.space_data
if not CLIP_PT_clip_view_panel.poll(context):
return False
if CLIP_PT_clip_view_panel.poll(context):
return sc.pivot_point == 'CURSOR' or sc.mode == 'MASK'
sc = context.space_data
return sc.pivot_point == 'CURSOR' or sc.mode == 'MASK'
def draw(self, context):
layout = self.layout
@ -1731,13 +1733,13 @@ class CLIP_MT_marker_pie(Menu):
layout = self.layout
pie = layout.menu_pie()
# Use Location Tracking
prop = pie.operator("wm.context_set_enum", text="Location")
prop.data_path = "space_data.clip.tracking.tracks.active.motion_model"
prop.value = "Loc"
props = pie.operator("wm.context_set_enum", text="Location")
props.data_path = "space_data.clip.tracking.tracks.active.motion_model"
props.value = "Loc"
# Use Affine Tracking
prop = pie.operator("wm.context_set_enum", text="Affine")
prop.data_path = "space_data.clip.tracking.tracks.active.motion_model"
prop.value = "Affine"
props = pie.operator("wm.context_set_enum", text="Affine")
props.data_path = "space_data.clip.tracking.tracks.active.motion_model"
props.value = "Affine"
# Copy Settings From Active To Selected
pie.operator("clip.track_settings_to_track", icon='COPYDOWN')
# Make Settings Default
@ -1748,13 +1750,13 @@ class CLIP_MT_marker_pie(Menu):
# Use Brute Force
pie.prop(track_active, "use_brute", text="Use Brute Force")
# Match Keyframe
prop = pie.operator("wm.context_set_enum", text="Match Previous", icon='KEYFRAME_HLT')
prop.data_path = "space_data.clip.tracking.tracks.active.pattern_match"
prop.value = 'PREV_FRAME'
props = pie.operator("wm.context_set_enum", text="Match Previous", icon='KEYFRAME_HLT')
props.data_path = "space_data.clip.tracking.tracks.active.pattern_match"
props.value = 'PREV_FRAME'
# Match Previous Frame
prop = pie.operator("wm.context_set_enum", text="Match Keyframe", icon='KEYFRAME')
prop.data_path = "space_data.clip.tracking.tracks.active.pattern_match"
prop.value = 'KEYFRAME'
props = pie.operator("wm.context_set_enum", text="Match Keyframe", icon='KEYFRAME')
props.data_path = "space_data.clip.tracking.tracks.active.pattern_match"
props.value = 'KEYFRAME'
class CLIP_MT_tracking_pie(Menu):
@ -1772,13 +1774,13 @@ class CLIP_MT_tracking_pie(Menu):
pie = layout.menu_pie()
# Track Backwards
prop = pie.operator("clip.track_markers", icon='TRACKING_BACKWARDS')
prop.backwards = True
prop.sequence = True
props = pie.operator("clip.track_markers", icon='TRACKING_BACKWARDS')
props.backwards = True
props.sequence = True
# Track Forwards
prop = pie.operator("clip.track_markers", icon='TRACKING_FORWARDS')
prop.backwards = False
prop.sequence = True
props = pie.operator("clip.track_markers", icon='TRACKING_FORWARDS')
props.backwards = False
props.sequence = True
# Disable Marker
pie.operator("clip.disable_markers", icon='HIDE_OFF').action = 'TOGGLE'
# Detect Features
@ -1830,11 +1832,11 @@ class CLIP_MT_solving_pie(Menu):
icon='KEYFRAME',
).keyframe = 'KEYFRAME_B'
# Clean Tracks
prop = pie.operator("clip.clean_tracks", icon='X')
props = pie.operator("clip.clean_tracks", icon='X')
props.frames = 15
props.error = 2
# Filter Tracks
pie.operator("clip.filter_tracks", icon='FILTER')
prop.frames = 15
prop.error = 2
class CLIP_MT_reconstruction_pie(Menu):

View File

@ -1,7 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-or-later
from bpy.types import Header, Menu, Panel
from bl_ui_utils.layout import operator_context
from bl_ui.space_dopesheet import (
DopesheetFilterPopoverBase,
dopesheet_filter,
@ -241,6 +240,8 @@ class GRAPH_MT_key(Menu):
bl_label = "Key"
def draw(self, _context):
from bl_ui_utils.layout import operator_context
layout = self.layout
layout.menu("GRAPH_MT_key_transform", text="Transform")

View File

@ -4,7 +4,6 @@ from bpy.types import Header, Menu, Panel
from bpy.app.translations import (
contexts as i18n_contexts,
pgettext_iface as iface_,
)

View File

@ -135,8 +135,6 @@ class SEQUENCER_HT_tool_header(Header):
# TODO: options popover.
def draw_tool_settings(self, context):
pass
layout = self.layout
# Active Tool
@ -621,17 +619,17 @@ class SEQUENCER_MT_change(Menu):
layout.operator_context = 'INVOKE_DEFAULT'
layout.operator_menu_enum("sequencer.change_effect_input", "swap")
layout.operator_menu_enum("sequencer.change_effect_type", "type")
prop = layout.operator("sequencer.change_path", text="Path/Files")
props = layout.operator("sequencer.change_path", text="Path/Files")
if strip:
strip_type = strip.type
if strip_type == 'IMAGE':
prop.filter_image = True
props.filter_image = True
elif strip_type == 'MOVIE':
prop.filter_movie = True
props.filter_movie = True
elif strip_type == 'SOUND':
prop.filter_sound = True
props.filter_sound = True
class SEQUENCER_MT_navigation(Menu):
@ -865,18 +863,18 @@ class SEQUENCER_MT_strip_input(Menu):
layout.operator("sequencer.reload", text="Reload Strips")
layout.operator("sequencer.reload", text="Reload Strips and Adjust Length").adjust_length = True
prop = layout.operator("sequencer.change_path", text="Change Path/Files")
props = layout.operator("sequencer.change_path", text="Change Path/Files")
layout.operator("sequencer.swap_data", text="Swap Data")
if strip:
strip_type = strip.type
if strip_type == 'IMAGE':
prop.filter_image = True
props.filter_image = True
elif strip_type == 'MOVIE':
prop.filter_movie = True
props.filter_movie = True
elif strip_type == 'SOUND':
prop.filter_sound = True
props.filter_sound = True
class SEQUENCER_MT_strip_lock_mute(Menu):
@ -1762,7 +1760,7 @@ class SEQUENCER_PT_scene(SequencerButtonsPanel, Panel):
sub.use_property_decorate = True
split = sub.split(factor=0.4, align=True)
split.alignment = 'RIGHT'
split.label(text="Volume")
split.label(text="Volume", text_ctxt=i18n_contexts.id_sound)
split.prop(scene, "audio_volume", text="")
sub.use_property_decorate = False
@ -1993,7 +1991,7 @@ class SEQUENCER_PT_adjust_sound(SequencerButtonsPanel, Panel):
split = col.split(factor=0.4)
split.alignment = 'RIGHT'
split.label(text="Volume")
split.label(text="Volume", text_ctxt=i18n_contexts.id_sound)
split.prop(strip, "volume", text="")
audio_channels = context.scene.render.ffmpeg.audio_channels
@ -2006,7 +2004,7 @@ class SEQUENCER_PT_adjust_sound(SequencerButtonsPanel, Panel):
split.prop(strip, "pan", text="")
split.enabled = pan_enabled
if audio_channels != 'MONO' and audio_channels != 'STEREO':
if audio_channels not in {'MONO', 'STEREO'}:
split = col.split(factor=0.4)
split.alignment = 'RIGHT'
split.label(text="Pan Angle")

View File

@ -66,12 +66,12 @@ class TEXT_HT_footer(Header):
if text.filepath:
if text.is_dirty:
row.label(
text=iface_("File: *%s (unsaved)" % text.filepath),
text=iface_("File: *%s (unsaved)") % text.filepath,
translate=False,
)
else:
row.label(
text=iface_("File: %s" % text.filepath),
text=iface_("File: %s") % text.filepath,
translate=False,
)
else:

View File

@ -451,6 +451,7 @@ class _defs_view3d_add:
for item in km.keymap_items:
if item.propvalue == propvalue:
return item
return None
if km is not None:
kmi_snap = keymap_item_from_propvalue('SNAP_ON')
@ -2094,13 +2095,13 @@ class _defs_gpencil_paint:
class _defs_gpencil_edit:
def is_segment(context):
ts = context.scene.tool_settings
tool_settings = context.scene.tool_settings
if context.mode == 'EDIT_GPENCIL':
return ts.gpencil_selectmode_edit == 'SEGMENT'
return tool_settings.gpencil_selectmode_edit == 'SEGMENT'
elif context.mode == 'SCULPT_GPENCIL':
return ts.use_gpencil_select_mask_segment
return tool_settings.use_gpencil_select_mask_segment
elif context.mode == 'VERTEX_GPENCIL':
return ts.use_gpencil_vertex_select_mask_segment
return tool_settings.use_gpencil_vertex_select_mask_segment
else:
return False
@ -2283,10 +2284,15 @@ class _defs_gpencil_sculpt:
if context is None:
return True
ob = context.active_object
ts = context.scene.tool_settings
return ob and ob.type == 'GPENCIL' and (ts.use_gpencil_select_mask_point or
ts.use_gpencil_select_mask_stroke or
ts.use_gpencil_select_mask_segment)
tool_settings = context.scene.tool_settings
return (
ob is not None and
ob.type == 'GPENCIL' and (
tool_settings.use_gpencil_select_mask_point or
tool_settings.use_gpencil_select_mask_stroke or
tool_settings.use_gpencil_select_mask_segment
)
)
@staticmethod
def generate_from_brushes(context):
@ -2427,10 +2433,15 @@ class _defs_gpencil_vertex:
if context is None:
return True
ob = context.active_object
ts = context.scene.tool_settings
return ob and ob.type == 'GPENCIL' and (ts.use_gpencil_vertex_select_mask_point or
ts.use_gpencil_vertex_select_mask_stroke or
ts.use_gpencil_vertex_select_mask_segment)
tool_settings = context.scene.tool_settings
return (
ob is not None and
ob.type == 'GPENCIL' and (
tool_settings.use_gpencil_vertex_select_mask_point or
tool_settings.use_gpencil_vertex_select_mask_stroke or
tool_settings.use_gpencil_vertex_select_mask_segment
)
)
@staticmethod
def generate_from_brushes(context):
@ -2652,7 +2663,6 @@ class _defs_sequencer_select:
row = layout.row()
row.use_property_split = False
row.prop(props, "mode", text="", expand=True, icon_only=True)
pass
return dict(
idname="builtin.select_box",
label="Select Box",

View File

@ -1,7 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-or-later
import bpy
from bpy.types import Header, Menu, Panel
from bl_ui_utils.layout import operator_context
from bpy.app.translations import (
pgettext_iface as iface_,
@ -236,34 +235,34 @@ class TOPBAR_MT_file_cleanup(Menu):
layout = self.layout
layout.separator()
op_props = layout.operator("outliner.orphans_purge", text="Unused Data-Blocks")
op_props.do_local_ids = True
op_props.do_linked_ids = True
op_props.do_recursive = False
op_props = layout.operator("outliner.orphans_purge", text="Recursive Unused Data-Blocks")
op_props.do_local_ids = True
op_props.do_linked_ids = True
op_props.do_recursive = True
props = layout.operator("outliner.orphans_purge", text="Unused Data-Blocks")
props.do_local_ids = True
props.do_linked_ids = True
props.do_recursive = False
props = layout.operator("outliner.orphans_purge", text="Recursive Unused Data-Blocks")
props.do_local_ids = True
props.do_linked_ids = True
props.do_recursive = True
layout.separator()
op_props = layout.operator("outliner.orphans_purge", text="Unused Linked Data-Blocks")
op_props.do_local_ids = False
op_props.do_linked_ids = True
op_props.do_recursive = False
op_props = layout.operator("outliner.orphans_purge", text="Recursive Unused Linked Data-Blocks")
op_props.do_local_ids = False
op_props.do_linked_ids = True
op_props.do_recursive = True
props = layout.operator("outliner.orphans_purge", text="Unused Linked Data-Blocks")
props.do_local_ids = False
props.do_linked_ids = True
props.do_recursive = False
props = layout.operator("outliner.orphans_purge", text="Recursive Unused Linked Data-Blocks")
props.do_local_ids = False
props.do_linked_ids = True
props.do_recursive = True
layout.separator()
op_props = layout.operator("outliner.orphans_purge", text="Unused Local Data-Blocks")
op_props.do_local_ids = True
op_props.do_linked_ids = False
op_props.do_recursive = False
op_props = layout.operator("outliner.orphans_purge", text="Recursive Unused Local Data-Blocks")
op_props.do_local_ids = True
op_props.do_linked_ids = False
op_props.do_recursive = True
props = layout.operator("outliner.orphans_purge", text="Unused Local Data-Blocks")
props.do_local_ids = True
props.do_linked_ids = False
props.do_recursive = False
props = layout.operator("outliner.orphans_purge", text="Recursive Unused Local Data-Blocks")
props.do_local_ids = True
props.do_linked_ids = False
props.do_recursive = True
class TOPBAR_MT_file(Menu):
@ -643,11 +642,10 @@ class TOPBAR_MT_window(Menu):
def draw(self, context):
import sys
from bl_ui_utils.layout import operator_context
layout = self.layout
operator_context_default = layout.operator_context
layout.operator("wm.window_new")
layout.operator("wm.window_new_main")

View File

@ -418,7 +418,7 @@ class USERPREF_PT_edit_objects_duplicate_data(EditingPanel, CenterAlignMixIn, Pa
col.prop(edit, "use_duplicate_surface", text="Surface")
col.prop(edit, "use_duplicate_text", text="Text")
# col.prop(edit, "use_duplicate_texture", text="Texture") # Not implemented.
col.prop(edit, "use_duplicate_volume", text="Volume")
col.prop(edit, "use_duplicate_volume", text="Volume", text_ctxt=i18n_contexts.id_id)
class USERPREF_PT_edit_cursor(EditingPanel, CenterAlignMixIn, Panel):
@ -1951,7 +1951,7 @@ class USERPREF_PT_addons(AddOnPanel, Panel):
addon_user_dirs = tuple(
p for p in (
*[os.path.join(pref_p, "addons") for pref_p in bpy.utils.script_path_user()],
*[os.path.join(pref_p, "addons") for pref_p in bpy.utils.script_paths_pref()],
bpy.utils.user_resource('SCRIPTS', path="addons"),
)
if p
@ -2205,12 +2205,12 @@ class StudioLightPanelMixin:
row.template_icon(layout.icon(studio_light), scale=3.0)
col = row.column()
op = col.operator("preferences.studiolight_uninstall", text="", icon='REMOVE')
op.index = studio_light.index
props = col.operator("preferences.studiolight_uninstall", text="", icon='REMOVE')
props.index = studio_light.index
if studio_light.type == 'STUDIO':
op = col.operator("preferences.studiolight_copy_settings", text="", icon='IMPORT')
op.index = studio_light.index
props = col.operator("preferences.studiolight_copy_settings", text="", icon='IMPORT')
props.index = studio_light.index
box.label(text=studio_light.name)
@ -2247,9 +2247,9 @@ class USERPREF_PT_studiolight_lights(StudioLightPanel, StudioLightPanelMixin, Pa
def draw_header_preset(self, _context):
layout = self.layout
op = layout.operator("preferences.studiolight_install", icon='IMPORT', text="Install...")
op.type = 'STUDIO'
op.filter_glob = ".sl"
props = layout.operator("preferences.studiolight_install", icon='IMPORT', text="Install...")
props.type = 'STUDIO'
props.filter_glob = ".sl"
layout.separator()
def get_error_message(self):

View File

@ -1,6 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-or-later
import bpy
from bl_ui_utils.layout import operator_context
from bpy.types import (
Header,
Menu,
@ -570,6 +569,8 @@ class _draw_tool_settings_context_mode:
elif curves_tool == "SLIDE":
layout.popover("VIEW3D_PT_tools_brush_falloff")
return True
class VIEW3D_HT_header(Header):
bl_space_type = 'VIEW_3D'
@ -928,7 +929,7 @@ class VIEW3D_MT_editor_menus(Menu):
edit_object = context.edit_object
gp_edit = obj and obj.mode in {'EDIT_GPENCIL', 'PAINT_GPENCIL', 'SCULPT_GPENCIL',
'WEIGHT_GPENCIL', 'VERTEX_GPENCIL'}
ts = context.scene.tool_settings
tool_settings = context.scene.tool_settings
layout.menu("VIEW3D_MT_view")
@ -937,9 +938,9 @@ class VIEW3D_MT_editor_menus(Menu):
if mode_string not in {'PAINT_GPENCIL', 'WEIGHT_GPENCIL'}:
if (
mode_string == 'SCULPT_GPENCIL' and
(ts.use_gpencil_select_mask_point or
ts.use_gpencil_select_mask_stroke or
ts.use_gpencil_select_mask_segment)
(tool_settings.use_gpencil_select_mask_point or
tool_settings.use_gpencil_select_mask_stroke or
tool_settings.use_gpencil_select_mask_segment)
):
layout.menu("VIEW3D_MT_select_gpencil")
elif mode_string == 'EDIT_GPENCIL':
@ -1443,8 +1444,6 @@ class VIEW3D_MT_select_object_more_less(Menu):
def draw(self, _context):
layout = self.layout
layout = self.layout
layout.operator("object.select_more", text="More")
layout.operator("object.select_less", text="Less")
@ -1509,8 +1508,6 @@ class VIEW3D_MT_select_pose_more_less(Menu):
def draw(self, _context):
layout = self.layout
layout = self.layout
props = layout.operator("pose.select_hierarchy", text="Parent")
props.extend = False
props.direction = 'PARENT'
@ -1619,6 +1616,7 @@ class VIEW3D_MT_edit_mesh_select_by_trait(Menu):
def draw(self, context):
layout = self.layout
tool_settings = context.tool_settings
if tool_settings.mesh_select_mode[2] is False:
layout.operator("mesh.select_non_manifold", text="Non Manifold")
layout.operator("mesh.select_loose", text="Loose Geometry")
@ -1855,8 +1853,6 @@ class VIEW3D_MT_edit_lattice_context_menu(Menu):
def draw(self, _context):
layout = self.layout
layout = self.layout
layout.menu("VIEW3D_MT_mirror")
layout.operator_menu_enum("lattice.flip", "axis")
layout.menu("VIEW3D_MT_snap")
@ -1961,8 +1957,8 @@ class VIEW3D_MT_paint_gpencil(Menu):
layout.separator()
layout.operator("gpencil.vertex_color_invert", text="Invert")
layout.operator("gpencil.vertex_color_levels", text="Levels")
layout.operator("gpencil.vertex_color_hsv", text="Hue Saturation Value")
layout.operator("gpencil.vertex_color_brightness_contrast", text="Bright/Contrast")
layout.operator("gpencil.vertex_color_hsv", text="Hue/Saturation/Value")
layout.operator("gpencil.vertex_color_brightness_contrast", text="Brightness/Contrast")
class VIEW3D_MT_select_gpencil(Menu):
@ -2036,8 +2032,8 @@ class VIEW3D_MT_select_paint_mask_vertex(Menu):
layout.operator("paint.vert_select_all", text="None").action = 'DESELECT'
layout.operator("paint.vert_select_all", text="Invert").action = 'INVERT'
layout.operator("paint.vert_select_more"),
layout.operator("paint.vert_select_less"),
layout.operator("paint.vert_select_more")
layout.operator("paint.vert_select_less")
layout.separator()
@ -2207,9 +2203,10 @@ class TOPBAR_MT_edit_curve_add(Menu):
bl_translation_context = i18n_contexts.operator_default
def draw(self, context):
layout = self.layout
is_surf = context.active_object.type == 'SURFACE'
layout = self.layout
layout.operator_context = 'EXEC_REGION_WIN'
if is_surf:
@ -2310,7 +2307,7 @@ class VIEW3D_MT_add(Menu):
layout.operator("object.text_add", text="Text", icon='OUTLINER_OB_FONT')
if context.preferences.experimental.use_new_point_cloud_type:
layout.operator("object.pointcloud_add", text="Point Cloud", icon='OUTLINER_OB_POINTCLOUD')
layout.menu("VIEW3D_MT_volume_add", text="Volume", icon='OUTLINER_OB_VOLUME')
layout.menu("VIEW3D_MT_volume_add", text="Volume", text_ctxt=i18n_contexts.id_id, icon='OUTLINER_OB_VOLUME')
layout.operator_menu_enum("object.gpencil_add", "type", text="Grease Pencil", icon='OUTLINER_OB_GREASEPENCIL')
layout.separator()
@ -2537,8 +2534,8 @@ class VIEW3D_MT_object_context_menu(Menu):
bl_label = "Object Context Menu"
def draw(self, context):
layout = self.layout
view = context.space_data
obj = context.object
@ -2766,6 +2763,7 @@ class VIEW3D_MT_object_apply(Menu):
def draw(self, _context):
layout = self.layout
# Need invoke for the popup confirming the multi-user data operation
layout.operator_context = 'INVOKE_DEFAULT'
@ -2831,6 +2829,8 @@ class VIEW3D_MT_object_parent(Menu):
bl_label = "Parent"
def draw(self, _context):
from bl_ui_utils.layout import operator_context
layout = self.layout
layout.operator_enum("object.parent_set", "type")
@ -3059,8 +3059,8 @@ class VIEW3D_MT_paint_vertex(Menu):
layout.operator("paint.vertex_color_invert", text="Invert")
layout.operator("paint.vertex_color_levels", text="Levels")
layout.operator("paint.vertex_color_hsv", text="Hue Saturation Value")
layout.operator("paint.vertex_color_brightness_contrast", text="Bright/Contrast")
layout.operator("paint.vertex_color_hsv", text="Hue/Saturation/Value")
layout.operator("paint.vertex_color_brightness_contrast", text="Brightness/Contrast")
class VIEW3D_MT_hook(Menu):
@ -3142,36 +3142,36 @@ class VIEW3D_MT_paint_weight_lock(Menu):
def draw(self, _context):
layout = self.layout
op = layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock All")
op.action, op.mask = 'LOCK', 'ALL'
props = layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock All")
props.action, props.mask = 'LOCK', 'ALL'
op = layout.operator("object.vertex_group_lock", text="Lock Selected")
op.action, op.mask = 'LOCK', 'SELECTED'
props = layout.operator("object.vertex_group_lock", text="Lock Selected")
props.action, props.mask = 'LOCK', 'SELECTED'
op = layout.operator("object.vertex_group_lock", text="Lock Unselected")
op.action, op.mask = 'LOCK', 'UNSELECTED'
props = layout.operator("object.vertex_group_lock", text="Lock Unselected")
props.action, props.mask = 'LOCK', 'UNSELECTED'
op = layout.operator("object.vertex_group_lock", text="Lock Only Selected")
op.action, op.mask = 'LOCK', 'INVERT_UNSELECTED'
props = layout.operator("object.vertex_group_lock", text="Lock Only Selected")
props.action, props.mask = 'LOCK', 'INVERT_UNSELECTED'
op = layout.operator("object.vertex_group_lock", text="Lock Only Unselected")
op.action, op.mask = 'UNLOCK', 'INVERT_UNSELECTED'
props = layout.operator("object.vertex_group_lock", text="Lock Only Unselected")
props.action, props.mask = 'UNLOCK', 'INVERT_UNSELECTED'
layout.separator()
op = layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock All")
op.action, op.mask = 'UNLOCK', 'ALL'
props = layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock All")
props.action, props.mask = 'UNLOCK', 'ALL'
op = layout.operator("object.vertex_group_lock", text="Unlock Selected")
op.action, op.mask = 'UNLOCK', 'SELECTED'
props = layout.operator("object.vertex_group_lock", text="Unlock Selected")
props.action, props.mask = 'UNLOCK', 'SELECTED'
op = layout.operator("object.vertex_group_lock", text="Unlock Unselected")
op.action, op.mask = 'UNLOCK', 'UNSELECTED'
props = layout.operator("object.vertex_group_lock", text="Unlock Unselected")
props.action, props.mask = 'UNLOCK', 'UNSELECTED'
layout.separator()
op = layout.operator("object.vertex_group_lock", icon='ARROW_LEFTRIGHT', text="Invert Locks")
op.action, op.mask = 'INVERT', 'ALL'
props = layout.operator("object.vertex_group_lock", icon='ARROW_LEFTRIGHT', text="Invert Locks")
props.action, props.mask = 'INVERT', 'ALL'
class VIEW3D_MT_paint_weight(Menu):
@ -3416,14 +3416,14 @@ class VIEW3D_MT_face_sets(Menu):
def draw(self, _context):
layout = self.layout
op = layout.operator("sculpt.face_sets_create", text="Face Set from Masked")
op.mode = 'MASKED'
props = layout.operator("sculpt.face_sets_create", text="Face Set from Masked")
props.mode = 'MASKED'
op = layout.operator("sculpt.face_sets_create", text="Face Set from Visible")
op.mode = 'VISIBLE'
props = layout.operator("sculpt.face_sets_create", text="Face Set from Visible")
props.mode = 'VISIBLE'
op = layout.operator("sculpt.face_sets_create", text="Face Set from Edit Mode Selection")
op.mode = 'SELECTION'
props = layout.operator("sculpt.face_sets_create", text="Face Set from Edit Mode Selection")
props.mode = 'SELECTION'
layout.separator()
@ -3431,11 +3431,11 @@ class VIEW3D_MT_face_sets(Menu):
layout.separator()
op = layout.operator("sculpt.face_set_edit", text="Grow Face Set")
op.mode = 'GROW'
props = layout.operator("sculpt.face_set_edit", text="Grow Face Set")
props.mode = 'GROW'
op = layout.operator("sculpt.face_set_edit", text="Shrink Face Set")
op.mode = 'SHRINK'
props = layout.operator("sculpt.face_set_edit", text="Shrink Face Set")
props.mode = 'SHRINK'
layout.separator()
@ -3453,18 +3453,18 @@ class VIEW3D_MT_face_sets(Menu):
layout.separator()
op = layout.operator("mesh.face_set_extract", text="Extract Face Set")
props = layout.operator("mesh.face_set_extract", text="Extract Face Set")
layout.separator()
op = layout.operator("sculpt.face_set_change_visibility", text="Invert Visible Face Sets")
op.mode = 'INVERT'
props = layout.operator("sculpt.face_set_change_visibility", text="Invert Visible Face Sets")
props.mode = 'INVERT'
op = layout.operator("sculpt.reveal_all", text="Show All Face Sets")
props = layout.operator("sculpt.reveal_all", text="Show All Face Sets")
layout.separator()
op = layout.operator("sculpt.face_sets_randomize_colors", text="Randomize Colors")
props = layout.operator("sculpt.face_sets_randomize_colors", text="Randomize Colors")
class VIEW3D_MT_sculpt_set_pivot(Menu):
@ -3495,32 +3495,32 @@ class VIEW3D_MT_face_sets_init(Menu):
def draw(self, _context):
layout = self.layout
op = layout.operator("sculpt.face_sets_init", text="By Loose Parts")
op.mode = 'LOOSE_PARTS'
props = layout.operator("sculpt.face_sets_init", text="By Loose Parts")
props.mode = 'LOOSE_PARTS'
op = layout.operator("sculpt.face_sets_init", text="By Face Set Boundaries")
op.mode = 'FACE_SET_BOUNDARIES'
props = layout.operator("sculpt.face_sets_init", text="By Face Set Boundaries")
props.mode = 'FACE_SET_BOUNDARIES'
op = layout.operator("sculpt.face_sets_init", text="By Materials")
op.mode = 'MATERIALS'
props = layout.operator("sculpt.face_sets_init", text="By Materials")
props.mode = 'MATERIALS'
op = layout.operator("sculpt.face_sets_init", text="By Normals")
op.mode = 'NORMALS'
props = layout.operator("sculpt.face_sets_init", text="By Normals")
props.mode = 'NORMALS'
op = layout.operator("sculpt.face_sets_init", text="By UV Seams")
op.mode = 'UV_SEAMS'
props = layout.operator("sculpt.face_sets_init", text="By UV Seams")
props.mode = 'UV_SEAMS'
op = layout.operator("sculpt.face_sets_init", text="By Edge Creases")
op.mode = 'CREASES'
props = layout.operator("sculpt.face_sets_init", text="By Edge Creases")
props.mode = 'CREASES'
op = layout.operator("sculpt.face_sets_init", text="By Edge Bevel Weight")
op.mode = 'BEVEL_WEIGHT'
props = layout.operator("sculpt.face_sets_init", text="By Edge Bevel Weight")
props.mode = 'BEVEL_WEIGHT'
op = layout.operator("sculpt.face_sets_init", text="By Sharp Edges")
op.mode = 'SHARP_EDGES'
props = layout.operator("sculpt.face_sets_init", text="By Sharp Edges")
props.mode = 'SHARP_EDGES'
op = layout.operator("sculpt.face_sets_init", text="By Face Maps")
op.mode = 'FACE_MAPS'
props = layout.operator("sculpt.face_sets_init", text="By Face Maps")
props.mode = 'FACE_MAPS'
class VIEW3D_MT_random_mask(Menu):
@ -3529,14 +3529,14 @@ class VIEW3D_MT_random_mask(Menu):
def draw(self, _context):
layout = self.layout
op = layout.operator("sculpt.mask_init", text="Per Vertex")
op.mode = 'RANDOM_PER_VERTEX'
props = layout.operator("sculpt.mask_init", text="Per Vertex")
props.mode = 'RANDOM_PER_VERTEX'
op = layout.operator("sculpt.mask_init", text="Per Face Set")
op.mode = 'RANDOM_PER_FACE_SET'
props = layout.operator("sculpt.mask_init", text="Per Face Set")
props.mode = 'RANDOM_PER_FACE_SET'
op = layout.operator("sculpt.mask_init", text="Per Loose Part")
op.mode = 'RANDOM_PER_LOOSE_PART'
props = layout.operator("sculpt.mask_init", text="Per Loose Part")
props.mode = 'RANDOM_PER_LOOSE_PART'
class VIEW3D_MT_particle(Menu):
@ -4430,17 +4430,17 @@ class VIEW3D_MT_edit_mesh_normals_select_strength(Menu):
def draw(self, _context):
layout = self.layout
op = layout.operator("mesh.mod_weighted_strength", text="Weak")
op.set = False
op.face_strength = 'WEAK'
props = layout.operator("mesh.mod_weighted_strength", text="Weak")
props.set = False
props.face_strength = 'WEAK'
op = layout.operator("mesh.mod_weighted_strength", text="Medium")
op.set = False
op.face_strength = 'MEDIUM'
props = layout.operator("mesh.mod_weighted_strength", text="Medium")
props.set = False
props.face_strength = 'MEDIUM'
op = layout.operator("mesh.mod_weighted_strength", text="Strong")
op.set = False
op.face_strength = 'STRONG'
props = layout.operator("mesh.mod_weighted_strength", text="Strong")
props.set = False
props.face_strength = 'STRONG'
class VIEW3D_MT_edit_mesh_normals_set_strength(Menu):
@ -4449,17 +4449,17 @@ class VIEW3D_MT_edit_mesh_normals_set_strength(Menu):
def draw(self, _context):
layout = self.layout
op = layout.operator("mesh.mod_weighted_strength", text="Weak")
op.set = True
op.face_strength = 'WEAK'
props = layout.operator("mesh.mod_weighted_strength", text="Weak")
props.set = True
props.face_strength = 'WEAK'
op = layout.operator("mesh.mod_weighted_strength", text="Medium")
op.set = True
op.face_strength = 'MEDIUM'
props = layout.operator("mesh.mod_weighted_strength", text="Medium")
props.set = True
props.face_strength = 'MEDIUM'
op = layout.operator("mesh.mod_weighted_strength", text="Strong")
op.set = True
op.face_strength = 'STRONG'
props = layout.operator("mesh.mod_weighted_strength", text="Strong")
props.set = True
props.face_strength = 'STRONG'
class VIEW3D_MT_edit_mesh_normals_average(Menu):
@ -4865,8 +4865,8 @@ class VIEW3D_MT_edit_font_kerning(Menu):
text = ob.data
kerning = text.edit_format.kerning
layout.operator("font.change_spacing", text="Decrease Kerning").delta = -1
layout.operator("font.change_spacing", text="Increase Kerning").delta = 1
layout.operator("font.change_spacing", text="Decrease Kerning").delta = -1.0
layout.operator("font.change_spacing", text="Increase Kerning").delta = 1.0
layout.operator("font.change_spacing", text="Reset Kerning").delta = -kerning
@ -5275,9 +5275,9 @@ class VIEW3D_MT_edit_gpencil_stroke(Menu):
layout.separator()
# Convert
op = layout.operator("gpencil.stroke_cyclical_set", text="Close")
op.type = 'CLOSE'
op.geometry = True
props = layout.operator("gpencil.stroke_cyclical_set", text="Close")
props.type = 'CLOSE'
props.geometry = True
layout.operator("gpencil.stroke_cyclical_set", text="Toggle Cyclic").type = 'TOGGLE'
layout.operator_menu_enum("gpencil.stroke_caps_set", text="Toggle Caps", property="type")
layout.operator("gpencil.stroke_flip", text="Switch Direction")
@ -5568,25 +5568,25 @@ class VIEW3D_MT_sculpt_mask_edit_pie(Menu):
layout = self.layout
pie = layout.menu_pie()
op = pie.operator("paint.mask_flood_fill", text="Invert Mask")
op.mode = 'INVERT'
op = pie.operator("paint.mask_flood_fill", text="Clear Mask")
op.mode = 'VALUE'
op.value = 0.0
op = pie.operator("sculpt.mask_filter", text="Smooth Mask")
op.filter_type = 'SMOOTH'
op = pie.operator("sculpt.mask_filter", text="Sharpen Mask")
op.filter_type = 'SHARPEN'
op = pie.operator("sculpt.mask_filter", text="Grow Mask")
op.filter_type = 'GROW'
op = pie.operator("sculpt.mask_filter", text="Shrink Mask")
op.filter_type = 'SHRINK'
op = pie.operator("sculpt.mask_filter", text="Increase Contrast")
op.filter_type = 'CONTRAST_INCREASE'
op.auto_iteration_count = False
op = pie.operator("sculpt.mask_filter", text="Decrease Contrast")
op.filter_type = 'CONTRAST_DECREASE'
op.auto_iteration_count = False
props = pie.operator("paint.mask_flood_fill", text="Invert Mask")
props.mode = 'INVERT'
props = pie.operator("paint.mask_flood_fill", text="Clear Mask")
props.mode = 'VALUE'
props.value = 0.0
props = pie.operator("sculpt.mask_filter", text="Smooth Mask")
props.filter_type = 'SMOOTH'
props = pie.operator("sculpt.mask_filter", text="Sharpen Mask")
props.filter_type = 'SHARPEN'
props = pie.operator("sculpt.mask_filter", text="Grow Mask")
props.filter_type = 'GROW'
props = pie.operator("sculpt.mask_filter", text="Shrink Mask")
props.filter_type = 'SHRINK'
props = pie.operator("sculpt.mask_filter", text="Increase Contrast")
props.filter_type = 'CONTRAST_INCREASE'
props.auto_iteration_count = False
props = pie.operator("sculpt.mask_filter", text="Decrease Contrast")
props.filter_type = 'CONTRAST_DECREASE'
props.auto_iteration_count = False
class VIEW3D_MT_sculpt_automasking_pie(Menu):
@ -5633,16 +5633,16 @@ class VIEW3D_MT_sculpt_face_sets_edit_pie(Menu):
layout = self.layout
pie = layout.menu_pie()
op = pie.operator("sculpt.face_sets_create", text="Face Set from Masked")
op.mode = 'MASKED'
props = pie.operator("sculpt.face_sets_create", text="Face Set from Masked")
props.mode = 'MASKED'
op = pie.operator("sculpt.face_sets_create", text="Face Set from Visible")
op.mode = 'VISIBLE'
props = pie.operator("sculpt.face_sets_create", text="Face Set from Visible")
props.mode = 'VISIBLE'
op = pie.operator("sculpt.face_set_change_visibility", text="Invert Visible")
op.mode = 'INVERT'
props = pie.operator("sculpt.face_set_change_visibility", text="Invert Visible")
props.mode = 'INVERT'
op = pie.operator("sculpt.reveal_all", text="Show All")
props = pie.operator("sculpt.reveal_all", text="Show All")
class VIEW3D_MT_wpaint_vgroup_lock_pie(Menu):
@ -5653,29 +5653,29 @@ class VIEW3D_MT_wpaint_vgroup_lock_pie(Menu):
pie = layout.menu_pie()
# 1: Left
op = pie.operator("object.vertex_group_lock", icon='LOCKED', text="Lock All")
op.action, op.mask = 'LOCK', 'ALL'
props = pie.operator("object.vertex_group_lock", icon='LOCKED', text="Lock All")
props.action, props.mask = 'LOCK', 'ALL'
# 2: Right
op = pie.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock All")
op.action, op.mask = 'UNLOCK', 'ALL'
props = pie.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock All")
props.action, props.mask = 'UNLOCK', 'ALL'
# 3: Down
op = pie.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock Selected")
op.action, op.mask = 'UNLOCK', 'SELECTED'
props = pie.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock Selected")
props.action, props.mask = 'UNLOCK', 'SELECTED'
# 4: Up
op = pie.operator("object.vertex_group_lock", icon='LOCKED', text="Lock Selected")
op.action, op.mask = 'LOCK', 'SELECTED'
props = pie.operator("object.vertex_group_lock", icon='LOCKED', text="Lock Selected")
props.action, props.mask = 'LOCK', 'SELECTED'
# 5: Up/Left
op = pie.operator("object.vertex_group_lock", icon='LOCKED', text="Lock Unselected")
op.action, op.mask = 'LOCK', 'UNSELECTED'
props = pie.operator("object.vertex_group_lock", icon='LOCKED', text="Lock Unselected")
props.action, props.mask = 'LOCK', 'UNSELECTED'
# 6: Up/Right
op = pie.operator("object.vertex_group_lock", text="Lock Only Selected")
op.action, op.mask = 'LOCK', 'INVERT_UNSELECTED'
props = pie.operator("object.vertex_group_lock", text="Lock Only Selected")
props.action, props.mask = 'LOCK', 'INVERT_UNSELECTED'
# 7: Down/Left
op = pie.operator("object.vertex_group_lock", text="Lock Only Unselected")
op.action, op.mask = 'UNLOCK', 'INVERT_UNSELECTED'
props = pie.operator("object.vertex_group_lock", text="Lock Only Unselected")
props.action, props.mask = 'UNLOCK', 'INVERT_UNSELECTED'
# 8: Down/Right
op = pie.operator("object.vertex_group_lock", text="Invert Locks")
op.action, op.mask = 'INVERT', 'ALL'
props = pie.operator("object.vertex_group_lock", text="Invert Locks")
props.action, props.mask = 'INVERT', 'ALL'
# ********** Panel **********
@ -6812,7 +6812,6 @@ class VIEW3D_PT_overlay_sculpt(Panel):
def draw(self, context):
layout = self.layout
tool_settings = context.tool_settings
view = context.space_data
overlay = view.overlay
@ -6843,8 +6842,6 @@ class VIEW3D_PT_overlay_sculpt_curves(Panel):
def draw(self, context):
layout = self.layout
tool_settings = context.tool_settings
sculpt = tool_settings.sculpt
view = context.space_data
overlay = view.overlay
@ -6978,6 +6975,7 @@ class VIEW3D_PT_overlay_weight_paint(Panel):
view = context.space_data
overlay = view.overlay
display_all = overlay.show_overlays
tool_settings = context.tool_settings
col = layout.column()
col.active = display_all
@ -6986,7 +6984,7 @@ class VIEW3D_PT_overlay_weight_paint(Panel):
row = col.split(factor=0.33)
row.label(text="Zero Weights")
sub = row.row()
sub.prop(context.tool_settings, "vertex_group_user", expand=True)
sub.prop(tool_settings, "vertex_group_user", expand=True)
col.prop(overlay, "show_wpaint_contours")
col.prop(overlay, "show_paint_wire")
@ -7157,11 +7155,13 @@ class VIEW3D_PT_gpencil_lock(Panel):
def draw(self, context):
layout = self.layout
tool_settings = context.tool_settings
layout.label(text="Drawing Plane")
row = layout.row()
col = row.column()
col.prop(context.tool_settings.gpencil_sculpt, "lock_axis", expand=True)
col.prop(tool_settings.gpencil_sculpt, "lock_axis", expand=True)
class VIEW3D_PT_gpencil_guide(Panel):
@ -7427,10 +7427,12 @@ class VIEW3D_PT_gpencil_multi_frame(Panel):
bl_label = "Multi Frame"
def draw(self, context):
gpd = context.gpencil_data
settings = context.tool_settings.gpencil_sculpt
layout = self.layout
tool_settings = context.tool_settings
gpd = context.gpencil_data
settings = tool_settings.gpencil_sculpt
col = layout.column(align=True)
col.prop(settings, "use_multiframe_falloff")
@ -7460,12 +7462,12 @@ class VIEW3D_MT_gpencil_edit_context_menu(Menu):
bl_label = ""
def draw(self, context):
is_point_mode = context.tool_settings.gpencil_selectmode_edit == 'POINT'
is_stroke_mode = context.tool_settings.gpencil_selectmode_edit == 'STROKE'
is_segment_mode = context.tool_settings.gpencil_selectmode_edit == 'SEGMENT'
layout = self.layout
tool_settings = context.tool_settings
is_point_mode = tool_settings.gpencil_selectmode_edit == 'POINT'
is_stroke_mode = tool_settings.gpencil_selectmode_edit == 'STROKE'
is_segment_mode = tool_settings.gpencil_selectmode_edit == 'SEGMENT'
layout.operator_context = 'INVOKE_REGION_WIN'
@ -7607,8 +7609,8 @@ class VIEW3D_PT_gpencil_sculpt_automasking(Panel):
def draw(self, context):
layout = self.layout
tool_settings = context.scene.tool_settings
layout.label(text="Auto-masking")
col = layout.column(align=True)
@ -7627,11 +7629,11 @@ class VIEW3D_PT_gpencil_sculpt_context_menu(Panel):
bl_ui_units_x = 12
def draw(self, context):
ts = context.tool_settings
settings = ts.gpencil_sculpt_paint
brush = settings.brush
layout = self.layout
tool_settings = context.tool_settings
settings = tool_settings.gpencil_sculpt_paint
brush = settings.brush
layout.prop(brush, "size", slider=True)
layout.prop(brush, "strength")
@ -7647,8 +7649,8 @@ class VIEW3D_PT_gpencil_weight_context_menu(Panel):
bl_ui_units_x = 12
def draw(self, context):
ts = context.tool_settings
settings = ts.gpencil_weight_paint
tool_settings = context.tool_settings
settings = tool_settings.gpencil_weight_paint
brush = settings.brush
layout = self.layout
@ -7668,12 +7670,12 @@ class VIEW3D_PT_gpencil_draw_context_menu(Panel):
bl_ui_units_x = 12
def draw(self, context):
ts = context.tool_settings
settings = ts.gpencil_paint
layout = self.layout
tool_settings = context.tool_settings
settings = tool_settings.gpencil_paint
brush = settings.brush
gp_settings = brush.gpencil_settings
layout = self.layout
is_pin_vertex = gp_settings.brush_draw_mode == 'VERTEXCOLOR'
is_vertex = settings.color_mode == 'VERTEXCOLOR' or brush.gpencil_tool == 'TINT' or is_pin_vertex
@ -7707,8 +7709,8 @@ class VIEW3D_PT_gpencil_vertex_context_menu(Panel):
def draw(self, context):
layout = self.layout
ts = context.tool_settings
settings = ts.gpencil_vertex_paint
tool_settings = context.tool_settings
settings = tool_settings.gpencil_vertex_paint
brush = settings.brush
gp_settings = brush.gpencil_settings

View File

@ -61,17 +61,17 @@ class VIEW3D_MT_brush_gpencil_context_menu(Menu):
def draw(self, context):
layout = self.layout
ts = context.tool_settings
tool_settings = context.tool_settings
settings = None
if context.mode == 'PAINT_GPENCIL':
settings = ts.gpencil_paint
settings = tool_settings.gpencil_paint
if context.mode == 'SCULPT_GPENCIL':
settings = ts.gpencil_sculpt_paint
settings = tool_settings.gpencil_sculpt_paint
elif context.mode == 'WEIGHT_GPENCIL':
settings = ts.gpencil_weight_paint
settings = tool_settings.gpencil_weight_paint
elif context.mode == 'VERTEX_GPENCIL':
settings = ts.gpencil_vertex_paint
settings = tool_settings.gpencil_vertex_paint
brush = getattr(settings, "brush", None)
# skip if no active brush
@ -203,8 +203,9 @@ class VIEW3D_PT_tools_meshedit_options_automerge(View3DPanel, Panel):
def draw_header(self, context):
tool_settings = context.tool_settings
self.layout.prop(tool_settings, "use_mesh_automerge", text="", toggle=False)
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
@ -612,7 +613,8 @@ class VIEW3D_PT_stencil_projectpaint(View3DPanel, Panel):
def draw_header(self, context):
ipaint = context.tool_settings.image_paint
self.layout.prop(ipaint, "use_stencil_layer", text="")
self.layout.prop(ipaint, "use_stencil_layer",
text=self.bl_label if self.is_popover else "")
def draw(self, context):
layout = self.layout
@ -794,7 +796,8 @@ class VIEW3D_PT_tools_brush_falloff_frontface(View3DPaintPanel, Panel):
settings = self.paint_settings(context)
brush = settings.brush
self.layout.prop(brush, "use_frontface_falloff", text="")
self.layout.prop(brush, "use_frontface_falloff",
text=self.bl_label if self.is_popover else "")
def draw(self, context):
settings = self.paint_settings(context)
@ -823,7 +826,8 @@ class VIEW3D_PT_tools_brush_falloff_normal(View3DPaintPanel, Panel):
tool_settings = context.tool_settings
ipaint = tool_settings.image_paint
self.layout.prop(ipaint, "use_normal_falloff", text="")
self.layout.prop(ipaint, "use_normal_falloff",
text=self.bl_label if self.is_popover else "")
def draw(self, context):
tool_settings = context.tool_settings
@ -1273,7 +1277,8 @@ class VIEW3D_PT_tools_imagepaint_options_cavity(View3DPaintPanel, Panel):
tool_settings = context.tool_settings
ipaint = tool_settings.image_paint
self.layout.prop(ipaint, "use_cavity", text="")
self.layout.prop(ipaint, "use_cavity",
text=self.bl_label if self.is_popover else "")
def draw(self, context):
layout = self.layout
@ -1615,8 +1620,9 @@ class VIEW3D_PT_tools_grease_pencil_brush_stroke(Panel, View3DPanel):
return brush is not None and brush.gpencil_tool == 'DRAW'
def draw(self, _context):
# layout = self.layout
pass
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
class VIEW3D_PT_tools_grease_pencil_brush_stabilizer(Panel, View3DPanel):
@ -1632,12 +1638,11 @@ class VIEW3D_PT_tools_grease_pencil_brush_stabilizer(Panel, View3DPanel):
return brush is not None and brush.gpencil_tool == 'DRAW'
def draw_header(self, context):
if self.is_popover:
return
brush = context.tool_settings.gpencil_paint.brush
gp_settings = brush.gpencil_settings
self.layout.prop(gp_settings, "use_settings_stabilizer", text="")
self.layout.use_property_split = False
self.layout.prop(gp_settings, "use_settings_stabilizer",
text=self.bl_label if self.is_popover else "")
def draw(self, context):
layout = self.layout
@ -1647,11 +1652,6 @@ class VIEW3D_PT_tools_grease_pencil_brush_stabilizer(Panel, View3DPanel):
brush = context.tool_settings.gpencil_paint.brush
gp_settings = brush.gpencil_settings
if self.is_popover:
row = layout.row()
row.prop(gp_settings, "use_settings_stabilizer", text="")
row.label(text=self.bl_label)
col = layout.column()
col.active = gp_settings.use_settings_stabilizer
@ -1672,12 +1672,11 @@ class VIEW3D_PT_tools_grease_pencil_brush_post_processing(View3DPanel, Panel):
return brush is not None and brush.gpencil_tool not in {'ERASE', 'FILL', 'TINT'}
def draw_header(self, context):
if self.is_popover:
return
brush = context.tool_settings.gpencil_paint.brush
gp_settings = brush.gpencil_settings
self.layout.prop(gp_settings, "use_settings_postprocess", text="")
self.layout.use_property_split = False
self.layout.prop(gp_settings, "use_settings_postprocess",
text=self.bl_label if self.is_popover else "")
def draw(self, context):
layout = self.layout
@ -1687,11 +1686,6 @@ class VIEW3D_PT_tools_grease_pencil_brush_post_processing(View3DPanel, Panel):
brush = context.tool_settings.gpencil_paint.brush
gp_settings = brush.gpencil_settings
if self.is_popover:
row = layout.row()
row.prop(gp_settings, "use_settings_postprocess", text="")
row.label(text=self.bl_label)
col = layout.column()
col.active = gp_settings.use_settings_postprocess
@ -1734,12 +1728,11 @@ class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel):
return brush is not None and brush.gpencil_tool not in {'ERASE', 'FILL', 'TINT'}
def draw_header(self, context):
if self.is_popover:
return
brush = context.tool_settings.gpencil_paint.brush
gp_settings = brush.gpencil_settings
self.layout.prop(gp_settings, "use_settings_random", text="")
self.layout.use_property_split = False
self.layout.prop(gp_settings, "use_settings_random",
text=self.bl_label if self.is_popover else "")
def draw(self, context):
layout = self.layout
@ -1751,11 +1744,6 @@ class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel):
mode = tool_settings.gpencil_paint.color_mode
gp_settings = brush.gpencil_settings
if self.is_popover:
row = layout.row()
row.prop(gp_settings, "use_settings_random", text="")
row.label(text=self.bl_label)
col = layout.column()
col.enabled = gp_settings.use_settings_random
@ -1828,8 +1816,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_paint_falloff(GreasePencilBrushFalloff
@classmethod
def poll(cls, context):
ts = context.tool_settings
settings = ts.gpencil_paint
tool_settings = context.tool_settings
settings = tool_settings.gpencil_paint
brush = settings.brush
if brush is None:
return False
@ -1946,8 +1934,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_sculpt_falloff(GreasePencilBrushFallof
@classmethod
def poll(cls, context):
ts = context.tool_settings
settings = ts.gpencil_sculpt_paint
tool_settings = context.tool_settings
settings = tool_settings.gpencil_sculpt_paint
return (settings and settings.brush and settings.brush.curve)
@ -2055,8 +2043,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_weight_falloff(GreasePencilBrushFallof
@classmethod
def poll(cls, context):
ts = context.tool_settings
settings = ts.gpencil_weight_paint
tool_settings = context.tool_settings
settings = tool_settings.gpencil_weight_paint
brush = settings.brush
return (brush and brush.curve)
@ -2131,8 +2119,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_vertex_color(View3DPanel, Panel):
@classmethod
def poll(cls, context):
ob = context.object
ts = context.tool_settings
settings = ts.gpencil_vertex_paint
tool_settings = context.tool_settings
settings = tool_settings.gpencil_vertex_paint
brush = settings.brush
if ob is None or brush is None:
@ -2147,8 +2135,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_vertex_color(View3DPanel, Panel):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
ts = context.tool_settings
settings = ts.gpencil_vertex_paint
tool_settings = context.tool_settings
settings = tool_settings.gpencil_vertex_paint
brush = settings.brush
col = layout.column()
@ -2169,8 +2157,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_vertex_falloff(GreasePencilBrushFallof
@classmethod
def poll(cls, context):
ts = context.tool_settings
settings = ts.gpencil_vertex_paint
tool_settings = context.tool_settings
settings = tool_settings.gpencil_vertex_paint
return (settings and settings.brush and settings.brush.curve)
@ -2183,8 +2171,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_vertex_palette(View3DPanel, Panel):
@classmethod
def poll(cls, context):
ob = context.object
ts = context.tool_settings
settings = ts.gpencil_vertex_paint
tool_settings = context.tool_settings
settings = tool_settings.gpencil_vertex_paint
brush = settings.brush
if ob is None or brush is None:
@ -2199,8 +2187,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_vertex_palette(View3DPanel, Panel):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
ts = context.tool_settings
settings = ts.gpencil_vertex_paint
tool_settings = context.tool_settings
settings = tool_settings.gpencil_vertex_paint
col = layout.column()
@ -2218,8 +2206,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_mixcolor(View3DPanel, Panel):
@classmethod
def poll(cls, context):
ob = context.object
ts = context.tool_settings
settings = ts.gpencil_paint
tool_settings = context.tool_settings
settings = tool_settings.gpencil_paint
brush = settings.brush
if ob is None or brush is None:
@ -2243,8 +2231,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_mixcolor(View3DPanel, Panel):
def draw(self, context):
layout = self.layout
ts = context.tool_settings
settings = ts.gpencil_paint
tool_settings = context.tool_settings
settings = tool_settings.gpencil_paint
brush = settings.brush
gp_settings = brush.gpencil_settings
@ -2282,8 +2270,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_mix_palette(View3DPanel, Panel):
@classmethod
def poll(cls, context):
ob = context.object
ts = context.tool_settings
settings = ts.gpencil_paint
tool_settings = context.tool_settings
settings = tool_settings.gpencil_paint
brush = settings.brush
if ob is None or brush is None:
@ -2306,8 +2294,8 @@ class VIEW3D_PT_tools_grease_pencil_brush_mix_palette(View3DPanel, Panel):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
ts = context.tool_settings
settings = ts.gpencil_paint
tool_settings = context.tool_settings
settings = tool_settings.gpencil_paint
brush = settings.brush
col = layout.column()

View File

@ -29,8 +29,8 @@ set(SRC_DNA_INC
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_fluid_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_freestyle_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_genfile.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_modifier_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_legacy_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpencil_modifier_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_gpu_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_image_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_ipo_types.h
@ -165,10 +165,6 @@ if(WITH_IMAGE_OPENEXR)
add_subdirectory(imbuf/intern/openexr)
endif()
if(WITH_IMAGE_DDS)
add_subdirectory(imbuf/intern/dds)
endif()
if(WITH_IMAGE_CINEON)
add_subdirectory(imbuf/intern/cineon)
endif()

View File

@ -11,6 +11,8 @@
#include "DNA_color_types.h"
#include "DNA_object_enums.h"
#include "BKE_paint.h" /* for ePaintMode */
#ifdef __cplusplus
extern "C" {
#endif
@ -185,6 +187,11 @@ void BKE_brush_scale_size(int *r_brush_size,
float new_unprojected_radius,
float old_unprojected_radius);
/* Returns true if a brush requires a cube
* (often presented to the user as a square) tip inside a specific paint mode.
*/
bool BKE_brush_has_cube_tip(const struct Brush *brush, ePaintMode paint_mode);
/* Accessors */
#define BKE_brush_tool_get(brush, p) \
(CHECK_TYPE_ANY(brush, struct Brush *, const struct Brush *), \

View File

@ -122,7 +122,18 @@ void BKE_mesh_looptri_get_real_edges(const struct MEdge *edges,
* Only use for undo, in most cases `BKE_id_free(nullptr, me)` should be used.
*/
void BKE_mesh_free_data_for_undo(struct Mesh *me);
/**
* Remove all geometry and derived data like caches from the mesh.
*/
void BKE_mesh_clear_geometry(struct Mesh *me);
/**
* Same as #BKE_mesh_clear_geometry, but also clears attribute meta-data like active attribute
* names and vertex group names. Used when the geometry is *entirely* replaced.
*/
void BKE_mesh_clear_geometry_and_metadata(struct Mesh *me);
struct Mesh *BKE_mesh_add(struct Main *bmain, const char *name);
void BKE_mesh_free_editmesh(struct Mesh *mesh);

View File

@ -48,6 +48,7 @@ struct PaintCurve;
struct PaintModeSettings;
struct Palette;
struct PaletteColor;
struct RegionView3D;
struct Scene;
struct StrokeCache;
struct Sculpt;
@ -238,7 +239,8 @@ void BKE_paint_face_set_overlay_color_get(int face_set, int seed, uchar r_color[
bool paint_calculate_rake_rotation(struct UnifiedPaintSettings *ups,
struct Brush *brush,
const float mouse_pos[2]);
const float mouse_pos[2],
ePaintMode paint_mode);
void paint_update_brush_rake_rotation(struct UnifiedPaintSettings *ups,
struct Brush *brush,
float rotation);
@ -524,7 +526,8 @@ typedef struct SculptAttribute {
/* Sculpt usage */
SculptAttributeParams params;
/* Used to keep track of which preallocated SculptAttribute instances
/**
* Used to keep track of which pre-allocated SculptAttribute instances
* inside of SculptSession.temp_attribute are used.
*/
bool used;

View File

@ -119,14 +119,14 @@ typedef struct PTCacheID {
unsigned int default_step;
unsigned int max_step;
/* flags defined in DNA_object_force_types.h */
/** flags defined in `DNA_object_force_types.h`. */
unsigned int data_types, info_types;
/* Copies point data to cache data. */
/** Copies point data to cache data. */
int (*write_point)(int index, void *calldata, void **data, int cfra);
/* Copies cache data to point data. */
/** Copies cache data to point data. */
void (*read_point)(int index, void *calldata, void **data, float cfra, const float *old_data);
/* Interpolated between previously read point data and cache data. */
/** Interpolated between previously read point data and cache data. */
void (*interpolate_point)(int index,
void *calldata,
void **data,
@ -135,32 +135,34 @@ typedef struct PTCacheID {
float cfra2,
const float *old_data);
/* copies point data to cache data */
/** Copies point data to cache data. */
int (*write_stream)(PTCacheFile *pf, void *calldata);
/* copies cache cata to point data */
/** Copies cache data to point data. */
int (*read_stream)(PTCacheFile *pf, void *calldata);
/* copies custom extradata to cache data */
/** Copies custom #PTCacheMem::extradata to cache data. */
void (*write_extra_data)(void *calldata, struct PTCacheMem *pm, int cfra);
/* copies custom extradata to cache data */
/** Copies custom #PTCacheMem::extradata to cache data. */
void (*read_extra_data)(void *calldata, struct PTCacheMem *pm, float cfra);
/* copies custom extradata to cache data */
/** Copies custom #PTCacheMem::extradata to cache data */
void (*interpolate_extra_data)(
void *calldata, struct PTCacheMem *pm, float cfra, float cfra1, float cfra2);
/* Total number of simulated points
* (the cfra parameter is just for using same function pointer with totwrite). */
/**
* Total number of simulated points
* (the `cfra` parameter is just for using same function pointer with `totwrite`).
*/
int (*totpoint)(void *calldata, int cfra);
/* report error if number of points does not match */
/** Report error if number of points does not match */
void (*error)(const struct ID *owner_id, void *calldata, const char *message);
/* number of points written for current cache frame */
/** Number of points written for current cache frame. */
int (*totwrite)(void *calldata, int cfra);
int (*write_header)(PTCacheFile *pf);
int (*read_header)(PTCacheFile *pf);
struct PointCache *cache;
/* used for setting the current cache from ptcaches list */
/** Used for setting the current cache from `ptcaches` list. */
struct PointCache **cache_ptr;
struct ListBase *ptcaches;
} PTCacheID;

View File

@ -144,9 +144,9 @@ set(SRC
intern/geometry_fields.cc
intern/geometry_set.cc
intern/geometry_set_instances.cc
intern/gpencil_legacy.c
intern/gpencil_curve_legacy.c
intern/gpencil_geom_legacy.cc
intern/gpencil_legacy.c
intern/gpencil_modifier_legacy.c
intern/gpencil_update_cache_legacy.c
intern/icons.cc
@ -384,9 +384,9 @@ set(SRC
BKE_geometry_set.hh
BKE_geometry_set_instances.hh
BKE_global.h
BKE_gpencil_legacy.h
BKE_gpencil_curve_legacy.h
BKE_gpencil_geom_legacy.h
BKE_gpencil_legacy.h
BKE_gpencil_modifier_legacy.h
BKE_gpencil_update_cache_legacy.h
BKE_icons.h
@ -594,26 +594,14 @@ if(WITH_IMAGE_OPENEXR)
add_definitions(-DWITH_OPENEXR)
endif()
if(WITH_IMAGE_TIFF)
add_definitions(-DWITH_TIFF)
endif()
if(WITH_IMAGE_OPENJPEG)
add_definitions(-DWITH_OPENJPEG)
endif()
if(WITH_IMAGE_DDS)
add_definitions(-DWITH_DDS)
endif()
if(WITH_IMAGE_CINEON)
add_definitions(-DWITH_CINEON)
endif()
if(WITH_IMAGE_HDR)
add_definitions(-DWITH_HDR)
endif()
if(WITH_IMAGE_WEBP)
add_definitions(-DWITH_WEBP)
endif()

View File

@ -699,7 +699,12 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
* places that wish to use the original mesh but with deformed
* coordinates (like vertex paint). */
if (r_deform) {
mesh_deform = BKE_mesh_copy_for_eval(mesh_input, true);
if (mesh_final) {
mesh_deform = BKE_mesh_copy_for_eval(mesh_final, false);
}
else {
mesh_deform = BKE_mesh_copy_for_eval(mesh_input, false);
}
}
}

View File

@ -2576,3 +2576,26 @@ struct ImBuf *BKE_brush_gen_radial_control_imbuf(Brush *br, bool secondary, bool
return im;
}
bool BKE_brush_has_cube_tip(const Brush *brush, ePaintMode paint_mode)
{
switch (paint_mode) {
case PAINT_MODE_SCULPT: {
if (brush->sculpt_tool == SCULPT_TOOL_MULTIPLANE_SCRAPE) {
return true;
}
if (ELEM(brush->sculpt_tool, SCULPT_TOOL_CLAY_STRIPS, SCULPT_TOOL_PAINT) &&
brush->tip_roundness < 1.0f) {
return true;
}
break;
}
default: {
break;
}
}
return false;
}

View File

@ -80,6 +80,9 @@ static KnotsMode knots_mode_from_legacy(const short flag)
Curves *curve_legacy_to_curves(const Curve &curve_legacy, const ListBase &nurbs_list)
{
const Vector<const Nurb *> src_curves(nurbs_list);
if (src_curves.is_empty()) {
return nullptr;
}
Curves *curves_id = curves_new_nomain(0, src_curves.size());
CurvesGeometry &curves = curves_id->geometry.wrap();
@ -104,10 +107,6 @@ Curves *curve_legacy_to_curves(const Curve &curve_legacy, const ListBase &nurbs_
curves.update_curve_types();
if (curves.curves_num() == 0) {
return curves_id;
}
const OffsetIndices points_by_curve = curves.points_by_curve();
MutableSpan<float3> positions = curves.positions_for_write();
SpanAttributeWriter<float> radius_attribute =

View File

@ -156,11 +156,6 @@ static void curves_blend_read_data(BlendDataReader *reader, ID *id)
BLO_read_data_address(reader, &curves->surface_uv_map);
curves->geometry.runtime = MEM_new<blender::bke::CurvesGeometryRuntime>(__func__);
/* Recalculate curve type count cache that isn't saved in files. */
curves->geometry.wrap().update_curve_types();
/* Materials */
BLO_read_pointer_array(reader, (void **)&curves->mat);
}

View File

@ -100,8 +100,7 @@ static void copy_curves_geometry(CurvesGeometry &dst, const CurvesGeometry &src)
dst.runtime->evaluated_normal_cache = src.runtime->evaluated_normal_cache;
}
CurvesGeometry::CurvesGeometry(const CurvesGeometry &other)
: CurvesGeometry(other.point_num, other.curve_num)
CurvesGeometry::CurvesGeometry(const CurvesGeometry &other) : CurvesGeometry()
{
copy_curves_geometry(*this, other);
}
@ -133,8 +132,7 @@ static void move_curves_geometry(CurvesGeometry &dst, CurvesGeometry &src)
std::swap(dst.runtime, src.runtime);
}
CurvesGeometry::CurvesGeometry(CurvesGeometry &&other)
: CurvesGeometry(other.point_num, other.curve_num)
CurvesGeometry::CurvesGeometry(CurvesGeometry &&other) : CurvesGeometry()
{
move_curves_geometry(*this, other);
}
@ -1582,10 +1580,15 @@ GVArray CurvesGeometry::adapt_domain(const GVArray &varray,
void CurvesGeometry::blend_read(BlendDataReader &reader)
{
this->runtime = MEM_new<blender::bke::CurvesGeometryRuntime>(__func__);
CustomData_blend_read(&reader, &this->point_data, this->point_num);
CustomData_blend_read(&reader, &this->curve_data, this->curve_num);
BLO_read_int32_array(&reader, this->curve_num + 1, &this->curve_offsets);
/* Recalculate curve type count cache that isn't saved in files. */
this->update_curve_types();
}
void CurvesGeometry::blend_write(BlendWriter &writer, ID &id)

View File

@ -80,28 +80,22 @@ int BKE_imtype_to_ftype(const char imtype, ImbFormatOptions *r_options)
if (imtype == R_IMF_IMTYPE_IRIS) {
return IMB_FTYPE_IMAGIC;
}
#ifdef WITH_HDR
if (imtype == R_IMF_IMTYPE_RADHDR) {
return IMB_FTYPE_RADHDR;
}
#endif
if (imtype == R_IMF_IMTYPE_PNG) {
r_options->quality = 15;
return IMB_FTYPE_PNG;
}
#ifdef WITH_DDS
if (imtype == R_IMF_IMTYPE_DDS) {
return IMB_FTYPE_DDS;
}
#endif
if (imtype == R_IMF_IMTYPE_BMP) {
return IMB_FTYPE_BMP;
}
#ifdef WITH_TIFF
if (imtype == R_IMF_IMTYPE_TIFF) {
return IMB_FTYPE_TIF;
}
#endif
if (ELEM(imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER)) {
return IMB_FTYPE_OPENEXR;
}
@ -139,27 +133,21 @@ char BKE_ftype_to_imtype(const int ftype, const ImbFormatOptions *options)
if (ftype == IMB_FTYPE_IMAGIC) {
return R_IMF_IMTYPE_IRIS;
}
#ifdef WITH_HDR
if (ftype == IMB_FTYPE_RADHDR) {
return R_IMF_IMTYPE_RADHDR;
}
#endif
if (ftype == IMB_FTYPE_PNG) {
return R_IMF_IMTYPE_PNG;
}
#ifdef WITH_DDS
if (ftype == IMB_FTYPE_DDS) {
return R_IMF_IMTYPE_DDS;
}
#endif
if (ftype == IMB_FTYPE_BMP) {
return R_IMF_IMTYPE_BMP;
}
#ifdef WITH_TIFF
if (ftype == IMB_FTYPE_TIF) {
return R_IMF_IMTYPE_TIFF;
}
#endif
if (ftype == IMB_FTYPE_OPENEXR) {
return R_IMF_IMTYPE_OPENEXR;
}
@ -327,11 +315,9 @@ char BKE_imtype_from_arg(const char *imtype_arg)
if (STREQ(imtype_arg, "IRIS")) {
return R_IMF_IMTYPE_IRIS;
}
#ifdef WITH_DDS
if (STREQ(imtype_arg, "DDS")) {
return R_IMF_IMTYPE_DDS;
}
#endif
if (STREQ(imtype_arg, "JPEG")) {
return R_IMF_IMTYPE_JPEG90;
}
@ -353,16 +339,12 @@ char BKE_imtype_from_arg(const char *imtype_arg)
if (STREQ(imtype_arg, "BMP")) {
return R_IMF_IMTYPE_BMP;
}
#ifdef WITH_HDR
if (STREQ(imtype_arg, "HDR")) {
return R_IMF_IMTYPE_RADHDR;
}
#endif
#ifdef WITH_TIFF
if (STREQ(imtype_arg, "TIFF")) {
return R_IMF_IMTYPE_TIFF;
}
#endif
#ifdef WITH_OPENEXR
if (STREQ(imtype_arg, "OPEN_EXR")) {
return R_IMF_IMTYPE_OPENEXR;
@ -422,13 +404,11 @@ static bool do_add_image_extension(char *string,
extension = extension_test;
}
}
#ifdef WITH_HDR
else if (imtype == R_IMF_IMTYPE_RADHDR) {
if (!BLI_path_extension_check(string, extension_test = ".hdr")) {
extension = extension_test;
}
}
#endif
else if (ELEM(imtype,
R_IMF_IMTYPE_PNG,
R_IMF_IMTYPE_FFMPEG,
@ -440,13 +420,11 @@ static bool do_add_image_extension(char *string,
extension = extension_test;
}
}
#ifdef WITH_DDS
else if (imtype == R_IMF_IMTYPE_DDS) {
if (!BLI_path_extension_check(string, extension_test = ".dds")) {
extension = extension_test;
}
}
#endif
else if (ELEM(imtype, R_IMF_IMTYPE_TARGA, R_IMF_IMTYPE_RAWTGA)) {
if (!BLI_path_extension_check(string, extension_test = ".tga")) {
extension = extension_test;
@ -457,13 +435,11 @@ static bool do_add_image_extension(char *string,
extension = extension_test;
}
}
#ifdef WITH_TIFF
else if (imtype == R_IMF_IMTYPE_TIFF) {
if (!BLI_path_extension_check_n(string, extension_test = ".tif", ".tiff", nullptr)) {
extension = extension_test;
}
}
#endif
else if (imtype == R_IMF_IMTYPE_PSD) {
if (!BLI_path_extension_check(string, extension_test = ".psd")) {
extension = extension_test;
@ -617,11 +593,9 @@ void BKE_image_format_to_imbuf(ImBuf *ibuf, const ImageFormatData *imf)
if (imtype == R_IMF_IMTYPE_IRIS) {
ibuf->ftype = IMB_FTYPE_IMAGIC;
}
#ifdef WITH_HDR
else if (imtype == R_IMF_IMTYPE_RADHDR) {
ibuf->ftype = IMB_FTYPE_RADHDR;
}
#endif
else if (ELEM(imtype,
R_IMF_IMTYPE_PNG,
R_IMF_IMTYPE_FFMPEG,
@ -639,15 +613,12 @@ void BKE_image_format_to_imbuf(ImBuf *ibuf, const ImageFormatData *imf)
ibuf->foptions.quality = compress;
}
}
#ifdef WITH_DDS
else if (imtype == R_IMF_IMTYPE_DDS) {
ibuf->ftype = IMB_FTYPE_DDS;
}
#endif
else if (imtype == R_IMF_IMTYPE_BMP) {
ibuf->ftype = IMB_FTYPE_BMP;
}
#ifdef WITH_TIFF
else if (imtype == R_IMF_IMTYPE_TIFF) {
ibuf->ftype = IMB_FTYPE_TIF;
@ -667,7 +638,6 @@ void BKE_image_format_to_imbuf(ImBuf *ibuf, const ImageFormatData *imf)
ibuf->foptions.flag |= TIF_COMPRESS_PACKBITS;
}
}
#endif
#ifdef WITH_OPENEXR
else if (ELEM(imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER)) {
ibuf->ftype = IMB_FTYPE_OPENEXR;
@ -787,11 +757,9 @@ void BKE_image_format_from_imbuf(ImageFormatData *im_format, const ImBuf *imbuf)
if (ftype == IMB_FTYPE_IMAGIC) {
im_format->imtype = R_IMF_IMTYPE_IRIS;
}
#ifdef WITH_HDR
else if (ftype == IMB_FTYPE_RADHDR) {
im_format->imtype = R_IMF_IMTYPE_RADHDR;
}
#endif
else if (ftype == IMB_FTYPE_PNG) {
im_format->imtype = R_IMF_IMTYPE_PNG;
@ -801,16 +769,12 @@ void BKE_image_format_from_imbuf(ImageFormatData *im_format, const ImBuf *imbuf)
im_format->compress = quality;
}
#ifdef WITH_DDS
else if (ftype == IMB_FTYPE_DDS) {
im_format->imtype = R_IMF_IMTYPE_DDS;
}
#endif
else if (ftype == IMB_FTYPE_BMP) {
im_format->imtype = R_IMF_IMTYPE_BMP;
}
#ifdef WITH_TIFF
else if (ftype == IMB_FTYPE_TIF) {
im_format->imtype = R_IMF_IMTYPE_TIFF;
if (custom_flags & TIF_16BIT) {
@ -829,7 +793,6 @@ void BKE_image_format_from_imbuf(ImageFormatData *im_format, const ImBuf *imbuf)
im_format->tiff_codec = R_IMF_TIFF_CODEC_PACKBITS;
}
}
#endif
#ifdef WITH_OPENEXR
else if (ftype == IMB_FTYPE_OPENEXR) {

View File

@ -139,7 +139,7 @@ static void mask_blend_read_data(BlendDataReader *reader, ID *id)
BLO_read_list(reader, &mask->masklayers);
LISTBASE_FOREACH (MaskLayer *, masklay, &mask->masklayers) {
/* can't use newdataadr since it's a pointer within an array */
/* Can't use #newdataadr since it's a pointer within an array. */
MaskSplinePoint *act_point_search = NULL;
BLO_read_list(reader, &masklay->splines);

View File

@ -72,7 +72,6 @@ using blender::StringRef;
using blender::VArray;
using blender::Vector;
static void mesh_clear_geometry(Mesh *mesh);
static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata);
static void mesh_init_data(ID *id)
@ -193,11 +192,9 @@ static void mesh_free_data(ID *id)
{
Mesh *mesh = (Mesh *)id;
BLI_freelistN(&mesh->vertex_group_names);
BKE_mesh_free_editmesh(mesh);
mesh_clear_geometry(mesh);
BKE_mesh_clear_geometry_and_metadata(mesh);
MEM_SAFE_FREE(mesh->mat);
delete mesh->runtime;
@ -278,7 +275,6 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
MutableSpan<MPoly> legacy_polys = BKE_mesh_legacy_convert_offsets_to_polys(
mesh, temp_arrays_for_legacy_format, poly_layers);
mesh->poly_offset_indices = nullptr;
BKE_mesh_legacy_convert_hide_layers_to_flags(mesh, legacy_polys);
BKE_mesh_legacy_convert_selection_layers_to_flags(mesh, legacy_polys);
@ -292,6 +288,7 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
mesh->active_color_attribute = nullptr;
mesh->default_color_attribute = nullptr;
BKE_mesh_legacy_convert_loose_edges_to_flag(mesh);
mesh->poly_offset_indices = nullptr;
/* Set deprecated mesh data pointers for forward compatibility. */
mesh->medge = const_cast<MEdge *>(mesh->edges().data());
@ -526,9 +523,9 @@ static bool is_sublayer_name(char const *sublayer_name, char const *name)
return true;
}
static bool is_uv_bool_sublayer(CustomDataLayer const *l)
static bool is_uv_bool_sublayer(const CustomDataLayer &layer)
{
char const *name = l->name;
char const *name = layer.name;
if (name[0] != '.') {
return false;
@ -557,7 +554,7 @@ static int customdata_compare(
for (int i = 0; i < c1->totlayer; i++) {
l1 = &c1->layers[i];
if ((CD_TYPE_AS_MASK(l1->type) & cd_mask_all_attr) && l1->anonymous_id == nullptr &&
!is_uv_bool_sublayer(l1)) {
!is_uv_bool_sublayer(*l1)) {
layer_count1++;
}
}
@ -565,7 +562,7 @@ static int customdata_compare(
for (int i = 0; i < c2->totlayer; i++) {
l2 = &c2->layers[i];
if ((CD_TYPE_AS_MASK(l2->type) & cd_mask_all_attr) && l2->anonymous_id == nullptr &&
!is_uv_bool_sublayer(l2)) {
!is_uv_bool_sublayer(*l2)) {
layer_count2++;
}
}
@ -581,7 +578,7 @@ static int customdata_compare(
for (int i1 = 0; i1 < c1->totlayer; i1++) {
l1 = c1->layers + i1;
if (l1->anonymous_id != nullptr || is_uv_bool_sublayer(l1)) {
if (l1->anonymous_id != nullptr || is_uv_bool_sublayer(*l1)) {
continue;
}
bool found_corresponding_layer = false;
@ -905,37 +902,47 @@ void BKE_mesh_free_data_for_undo(Mesh *me)
* Material slots should be kept in sync with the object.
*
* - Edit-Mesh (#Mesh.edit_mesh)
* Since edit-mesh is tied to the objects mode,
* which crashes when called in edit-mode, see: #90972.
* Since edit-mesh is tied to the object's mode, which crashes when called in edit-mode.
* See: #90972.
*/
static void mesh_clear_geometry(Mesh *mesh)
static void mesh_clear_geometry(Mesh &mesh)
{
CustomData_free(&mesh->vdata, mesh->totvert);
CustomData_free(&mesh->edata, mesh->totedge);
CustomData_free(&mesh->fdata, mesh->totface);
CustomData_free(&mesh->ldata, mesh->totloop);
CustomData_free(&mesh->pdata, mesh->totpoly);
MEM_SAFE_FREE(mesh->poly_offset_indices);
CustomData_free(&mesh.vdata, mesh.totvert);
CustomData_free(&mesh.edata, mesh.totedge);
CustomData_free(&mesh.fdata, mesh.totface);
CustomData_free(&mesh.ldata, mesh.totloop);
CustomData_free(&mesh.pdata, mesh.totpoly);
MEM_SAFE_FREE(mesh.poly_offset_indices);
MEM_SAFE_FREE(mesh->mselect);
MEM_SAFE_FREE(mesh.mselect);
mesh->totvert = 0;
mesh->totedge = 0;
mesh->totface = 0;
mesh->totloop = 0;
mesh->totpoly = 0;
mesh->act_face = -1;
mesh->totselect = 0;
mesh.totvert = 0;
mesh.totedge = 0;
mesh.totface = 0;
mesh.totloop = 0;
mesh.totpoly = 0;
mesh.act_face = -1;
mesh.totselect = 0;
}
BLI_freelistN(&mesh->vertex_group_names);
MEM_SAFE_FREE(mesh->active_color_attribute);
MEM_SAFE_FREE(mesh->default_color_attribute);
static void clear_attribute_names(Mesh &mesh)
{
BLI_freelistN(&mesh.vertex_group_names);
MEM_SAFE_FREE(mesh.active_color_attribute);
MEM_SAFE_FREE(mesh.default_color_attribute);
}
void BKE_mesh_clear_geometry(Mesh *mesh)
{
BKE_mesh_runtime_clear_cache(mesh);
mesh_clear_geometry(mesh);
mesh_clear_geometry(*mesh);
}
void BKE_mesh_clear_geometry_and_metadata(Mesh *mesh)
{
BKE_mesh_runtime_clear_cache(mesh);
mesh_clear_geometry(*mesh);
clear_attribute_names(*mesh);
}
static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata)
@ -963,34 +970,33 @@ void BKE_mesh_poly_offsets_ensure_alloc(Mesh *mesh)
if (mesh->totpoly == 0) {
return;
}
if (!mesh->poly_offset_indices) {
mesh->poly_offset_indices = static_cast<int *>(
MEM_malloc_arrayN(mesh->totpoly + 1, sizeof(int), __func__));
}
mesh->poly_offset_indices = static_cast<int *>(
MEM_malloc_arrayN(mesh->totpoly + 1, sizeof(int), __func__));
#ifdef DEBUG
/* Fill offsets with obviously bad values to simplify finding missing initialization. */
mesh->poly_offsets_for_write().fill(-1);
#endif
mesh->poly_offsets_for_write().last() = mesh->totloop;
mesh->poly_offset_indices[0] = 0;
mesh->poly_offset_indices[mesh->totpoly] = mesh->totloop;
}
/* Custom data layer functions; those assume that totXXX are set correctly. */
static void mesh_ensure_cdlayers_primary(Mesh *mesh)
static void mesh_ensure_cdlayers_primary(Mesh &mesh)
{
if (!CustomData_get_layer_named(&mesh->vdata, CD_PROP_FLOAT3, "position")) {
if (!CustomData_get_layer_named(&mesh.vdata, CD_PROP_FLOAT3, "position")) {
CustomData_add_layer_named(
&mesh->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, mesh->totvert, "position");
&mesh.vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, mesh.totvert, "position");
}
if (!CustomData_get_layer(&mesh->edata, CD_MEDGE)) {
CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_SET_DEFAULT, mesh->totedge);
if (!CustomData_get_layer(&mesh.edata, CD_MEDGE)) {
CustomData_add_layer(&mesh.edata, CD_MEDGE, CD_SET_DEFAULT, mesh.totedge);
}
if (!CustomData_get_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_vert")) {
if (!CustomData_get_layer_named(&mesh.ldata, CD_PROP_INT32, ".corner_vert")) {
CustomData_add_layer_named(
&mesh->ldata, CD_PROP_INT32, CD_SET_DEFAULT, mesh->totloop, ".corner_vert");
&mesh.ldata, CD_PROP_INT32, CD_CONSTRUCT, mesh.totloop, ".corner_vert");
}
if (!CustomData_get_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_edge")) {
if (!CustomData_get_layer_named(&mesh.ldata, CD_PROP_INT32, ".corner_edge")) {
CustomData_add_layer_named(
&mesh->ldata, CD_PROP_INT32, CD_SET_DEFAULT, mesh->totloop, ".corner_edge");
&mesh.ldata, CD_PROP_INT32, CD_CONSTRUCT, mesh.totloop, ".corner_edge");
}
}
@ -1012,7 +1018,7 @@ Mesh *BKE_mesh_new_nomain(int verts_len, int edges_len, int loops_len, int polys
mesh->totloop = loops_len;
mesh->totpoly = polys_len;
mesh_ensure_cdlayers_primary(mesh);
mesh_ensure_cdlayers_primary(*mesh);
BKE_mesh_poly_offsets_ensure_alloc(mesh);
return mesh;
@ -1109,7 +1115,7 @@ Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src,
/* The destination mesh should at least have valid primary CD layers,
* even in cases where the source mesh does not. */
mesh_ensure_cdlayers_primary(me_dst);
mesh_ensure_cdlayers_primary(*me_dst);
BKE_mesh_poly_offsets_ensure_alloc(me_dst);
if (do_tessface && !CustomData_get_layer(&me_dst->fdata, CD_MFACE)) {
CustomData_add_layer(&me_dst->fdata, CD_MFACE, CD_SET_DEFAULT, me_dst->totface);

View File

@ -1114,7 +1114,7 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob)
BLI_assert(mesh_dst == ob->data);
}
BKE_mesh_clear_geometry(mesh_dst);
BKE_mesh_clear_geometry_and_metadata(mesh_dst);
/* Make sure referenced layers have a single user so assigning them to the mesh in main doesn't
* share them. "Referenced" layers are not expected to be shared between original meshes. */
@ -1135,22 +1135,12 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob)
CustomData_copy(&mesh_src->edata, &mesh_dst->edata, mask.emask, CD_ASSIGN, mesh_src->totedge);
CustomData_copy(&mesh_src->pdata, &mesh_dst->pdata, mask.pmask, CD_ASSIGN, mesh_src->totpoly);
CustomData_copy(&mesh_src->ldata, &mesh_dst->ldata, mask.lmask, CD_ASSIGN, mesh_src->totloop);
mesh_dst->poly_offset_indices = static_cast<int *>(mesh_src->poly_offset_indices);
mesh_src->poly_offset_indices = nullptr;
std::swap(mesh_dst->poly_offset_indices, mesh_src->poly_offset_indices);
/* Make sure active/default color attribute (names) are brought over. */
if (mesh_src->active_color_attribute) {
MEM_SAFE_FREE(mesh_dst->active_color_attribute);
mesh_dst->active_color_attribute = BLI_strdup(mesh_src->active_color_attribute);
}
if (mesh_src->default_color_attribute) {
MEM_SAFE_FREE(mesh_dst->default_color_attribute);
mesh_dst->default_color_attribute = BLI_strdup(mesh_src->default_color_attribute);
}
BLI_freelistN(&mesh_dst->vertex_group_names);
mesh_dst->vertex_group_names = mesh_src->vertex_group_names;
BLI_listbase_clear(&mesh_src->vertex_group_names);
/* Make sure attribute names are moved. */
std::swap(mesh_dst->active_color_attribute, mesh_src->active_color_attribute);
std::swap(mesh_dst->default_color_attribute, mesh_src->default_color_attribute);
std::swap(mesh_dst->vertex_group_names, mesh_src->vertex_group_names);
BKE_mesh_copy_parameters(mesh_dst, mesh_src);

View File

@ -1642,7 +1642,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
pcent_dst = blender::bke::mesh::poly_center_calc(
{reinterpret_cast<const blender::float3 *>(vert_positions_dst),
numverts_dst},
corner_verts_src.slice(poly_dst));
blender::Span(corner_verts_dst, numloops_dst).slice(poly_dst));
pcent_dst_valid = true;
}
pcent_src = poly_cents_src[pidx_src];

View File

@ -2131,16 +2131,16 @@ static const char *get_obdata_defname(int type)
case OB_POINTCLOUD:
return DATA_("PointCloud");
case OB_VOLUME:
return DATA_("Volume");
return CTX_DATA_(BLT_I18NCONTEXT_ID_ID, "Volume");
case OB_EMPTY:
return DATA_("Empty");
return CTX_DATA_(BLT_I18NCONTEXT_ID_ID, "Empty");
case OB_GPENCIL_LEGACY:
return DATA_("GPencil");
case OB_LIGHTPROBE:
return DATA_("LightProbe");
default:
CLOG_ERROR(&LOG, "Internal error, bad type: %d", type);
return DATA_("Empty");
return CTX_DATA_(BLT_I18NCONTEXT_ID_ID, "Empty");
}
}

View File

@ -1302,12 +1302,7 @@ float paint_grid_paint_mask(const GridPaintMask *gpm, uint level, uint x, uint y
void paint_update_brush_rake_rotation(UnifiedPaintSettings *ups, Brush *brush, float rotation)
{
if (brush->mtex.brush_angle_mode & MTEX_ANGLE_RAKE) {
ups->brush_rotation = rotation;
}
else {
ups->brush_rotation = 0.0f;
}
ups->brush_rotation = rotation;
if (brush->mask_mtex.brush_angle_mode & MTEX_ANGLE_RAKE) {
ups->brush_rotation_sec = rotation;
@ -1322,17 +1317,19 @@ static bool paint_rake_rotation_active(const MTex &mtex)
return mtex.tex && mtex.brush_angle_mode & MTEX_ANGLE_RAKE;
}
static bool paint_rake_rotation_active(const Brush &brush)
static const bool paint_rake_rotation_active(const Brush &brush, ePaintMode paint_mode)
{
return paint_rake_rotation_active(brush.mtex) || paint_rake_rotation_active(brush.mask_mtex);
return paint_rake_rotation_active(brush.mtex) || paint_rake_rotation_active(brush.mask_mtex) ||
BKE_brush_has_cube_tip(&brush, paint_mode);
}
bool paint_calculate_rake_rotation(UnifiedPaintSettings *ups,
Brush *brush,
const float mouse_pos[2])
const float mouse_pos[2],
ePaintMode paint_mode)
{
bool ok = false;
if (paint_rake_rotation_active(*brush)) {
if (paint_rake_rotation_active(*brush, paint_mode)) {
const float r = RAKE_THRESHHOLD;
float rotation;

View File

@ -37,13 +37,13 @@ struct MultiresDisplacementData {
const MultiresModifierData *mmd;
blender::OffsetIndices<int> polys;
const MDisps *mdisps;
/* Indexed by ptex face index, contains polygon/corner which corresponds
/* Indexed by PTEX face index, contains polygon/corner which corresponds
* to it.
*
* NOTE: For quad polygon this is an index of first corner only, since
* there we only have one ptex. */
* there we only have one PTEX. */
PolyCornerIndex *ptex_poly_corner;
/* Indexed by coarse face index, returns first ptex face index corresponding
/* Indexed by coarse face index, returns first PTEX face index corresponding
* to that coarse face. */
int *face_ptex_offset;
/* Sanity check, is used in debug builds.
@ -52,7 +52,7 @@ struct MultiresDisplacementData {
};
/* Denotes which grid to use to average value of the displacement read from the
* grid which corresponds to the ptex face. */
* grid which corresponds to the PTEX face. */
typedef enum eAverageWith {
AVERAGE_WITH_NONE,
AVERAGE_WITH_ALL,
@ -175,12 +175,12 @@ static void average_read_displacement_object(MultiresDisplacementData *data,
{
const PolyCornerIndex *poly_corner = &data->ptex_poly_corner[ptex_face_index];
const int num_corners = data->polys[poly_corner->poly_index].size();
/* Get (u, v) coordinate within the other ptex face which corresponds to
/* Get (u, v) coordinate within the other PTEX face which corresponds to
* the grid coordinates. */
float u, v;
average_convert_grid_coord_to_ptex(num_corners, corner_index, grid_u, grid_v, &u, &v);
/* Construct tangent matrix which corresponds to partial derivatives
* calculated for the other ptex face. */
* calculated for the other PTEX face. */
float tangent_matrix[3][3];
average_construct_tangent_matrix(
data->subdiv, num_corners, ptex_face_index, corner_index, u, v, tangent_matrix);
@ -208,7 +208,7 @@ static void average_get_other_ptex_and_corner(MultiresDisplacementData *data,
start_ptex_face_index + *r_other_corner_index;
}
/* NOTE: Grid coordinates are relatiev to the other grid already. */
/* NOTE: Grid coordinates are relative to the other grid already. */
static void average_with_other(SubdivDisplacement *displacement,
const int ptex_face_index,
const int corner,
@ -380,7 +380,7 @@ static void displacement_data_init_mapping(SubdivDisplacement *displacement, con
const int num_ptex_faces = count_num_ptex_faces(mesh);
/* Allocate memory. */
data->ptex_poly_corner = static_cast<PolyCornerIndex *>(
MEM_malloc_arrayN(num_ptex_faces, sizeof(*data->ptex_poly_corner), "ptex poly corner"));
MEM_malloc_arrayN(num_ptex_faces, sizeof(*data->ptex_poly_corner), "PTEX poly corner"));
/* Fill in offsets. */
int ptex_face_index = 0;
PolyCornerIndex *ptex_poly_corner = data->ptex_poly_corner;

View File

@ -85,7 +85,8 @@ struct SubdivMeshContext {
static void subdiv_mesh_ctx_cache_uv_layers(SubdivMeshContext *ctx)
{
Mesh *subdiv_mesh = ctx->subdiv_mesh;
ctx->num_uv_layers = CustomData_number_of_layers(&subdiv_mesh->ldata, CD_PROP_FLOAT2);
ctx->num_uv_layers = std::min(CustomData_number_of_layers(&subdiv_mesh->ldata, CD_PROP_FLOAT2),
MAX_MTFACE);
for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) {
ctx->uv_layers[layer_index] = static_cast<float2 *>(CustomData_get_layer_n_for_write(
&subdiv_mesh->ldata, CD_PROP_FLOAT2, layer_index, subdiv_mesh->totloop));

View File

@ -173,11 +173,16 @@ int BLI_wcwidth(char32_t ucs) ATTR_WARN_UNUSED_RESULT;
int BLI_wcswidth(const char32_t *pwcs, size_t n) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
/**
* Upper and lowercase for 32-bit characters for all scripts that distinguish case. One-to-one
* mappings so this doesn't work corectly for uppercase Σ (two lowercase forms) and lowercase ß
* won't become "SS".
* Return the uppercase of a 32-bit character or the character when no case change is needed.
*
* \note A 1:1 mapping doesn't account for multiple characters as part of conversion in some cases.
*/
char32_t BLI_str_utf32_char_to_upper(char32_t wc);
/**
* Return the lowercase of a 32-bit character or the character when no case change is needed.
*
* \note A 1:1 mapping doesn't account for multiple characters as part of conversion in some cases.
*/
char32_t BLI_str_utf32_char_to_lower(char32_t wc);
/**

View File

@ -346,13 +346,15 @@ void extract_normalized_words(StringRef str,
Vector<StringRef, 64> &r_words)
{
const uint32_t unicode_space = uint32_t(' ');
const uint32_t unicode_slash = uint32_t('/');
const uint32_t unicode_right_triangle = UI_MENU_ARROW_SEP_UNICODE;
BLI_assert(unicode_space == BLI_str_utf8_as_unicode(" "));
BLI_assert(unicode_slash == BLI_str_utf8_as_unicode("/"));
BLI_assert(unicode_right_triangle == BLI_str_utf8_as_unicode(UI_MENU_ARROW_SEP));
auto is_separator = [&](uint32_t unicode) {
return ELEM(unicode, unicode_space, unicode_right_triangle);
return ELEM(unicode, unicode_space, unicode_slash, unicode_right_triangle);
};
/* Make a copy of the string so that we can edit it. */

View File

@ -399,7 +399,17 @@ int BLI_str_utf8_char_width_safe(const char *p)
return (columns < 0) ? 1 : columns;
}
char32_t BLI_str_utf32_char_to_upper(char32_t wc)
/* -------------------------------------------------------------------- */
/** \name UTF32 Case Conversion
*
* \warning the lower/uppercase form of some characters use multiple characters.
* These cases are not accounted for by this conversion function.
* A common example is the German `eszett` / `scharfes`.
* Supporting such cases would have to operate on a character array, with support for resizing.
* (for reference - Python's upper/lower functions support this).
* \{ */
char32_t BLI_str_utf32_char_to_upper(const char32_t wc)
{
if (wc < U'\xFF') { /* Latin. */
if ((wc <= U'z' && wc >= U'a') || (wc <= U'\xF6' && wc >= U'\xE0') ||
@ -420,7 +430,7 @@ char32_t BLI_str_utf32_char_to_upper(char32_t wc)
if (wc <= U'\x24E9' && wc >= U'\x24D0') { /* Enclosed Numerals. */
return wc - 26;
}
if (wc <= U'\xFF5A' && wc >= U'\xFF41') { /* Fullwidth Forms. */
if (wc <= U'\xFF5A' && wc >= U'\xFF41') { /* Full-width Forms. */
return wc - 32;
}
@ -506,7 +516,7 @@ char32_t BLI_str_utf32_char_to_upper(char32_t wc)
return wc;
}
char32_t BLI_str_utf32_char_to_lower(char32_t wc)
char32_t BLI_str_utf32_char_to_lower(const char32_t wc)
{
if (wc < U'\xD8') { /* Latin. */
if ((wc <= U'Z' && wc >= U'A') || (wc <= U'\xD6' && wc >= U'\xC0')) {
@ -525,7 +535,7 @@ char32_t BLI_str_utf32_char_to_lower(char32_t wc)
if (wc <= U'\x24CF' && wc >= U'\x24B6') { /* Enclosed Numerals. */
return wc + 26;
}
if (wc <= U'\xFF3A' && wc >= U'\xFF21') { /* Fullwidth Forms. */
if (wc <= U'\xFF3A' && wc >= U'\xFF21') { /* Full-width Forms. */
return wc + 32;
}
@ -611,7 +621,7 @@ char32_t BLI_str_utf32_char_to_lower(char32_t wc)
return wc;
}
/* -------------------------------------------------------------------- */
/** \} */ /* -------------------------------------------------------------------- */
/* copied from glib's gutf8.c, added 'Err' arg */

View File

@ -2237,32 +2237,6 @@ static void *restore_pointer_by_name(IDNameLib_Map *id_map, ID *id, ePointerUser
#endif
}
static void lib_link_seq_clipboard_pt_restore(ID *id, IDNameLib_Map *id_map)
{
if (id) {
/* clipboard must ensure this */
BLI_assert(id->newid != nullptr);
id->newid = static_cast<ID *>(restore_pointer_by_name(id_map, id->newid, USER_REAL));
}
}
static bool lib_link_seq_clipboard_cb(Sequence *seq, void *arg_pt)
{
IDNameLib_Map *id_map = static_cast<IDNameLib_Map *>(arg_pt);
lib_link_seq_clipboard_pt_restore(reinterpret_cast<ID *>(seq->scene), id_map);
lib_link_seq_clipboard_pt_restore(reinterpret_cast<ID *>(seq->scene_camera), id_map);
lib_link_seq_clipboard_pt_restore(reinterpret_cast<ID *>(seq->clip), id_map);
lib_link_seq_clipboard_pt_restore(reinterpret_cast<ID *>(seq->mask), id_map);
lib_link_seq_clipboard_pt_restore(reinterpret_cast<ID *>(seq->sound), id_map);
return true;
}
static void lib_link_clipboard_restore(IDNameLib_Map *id_map)
{
/* update IDs stored in sequencer clipboard */
SEQ_for_each_callback(&seqbase_clipboard, lib_link_seq_clipboard_cb, id_map);
}
static int lib_link_main_data_restore_cb(LibraryIDLinkCallbackData *cb_data)
{
const int cb_flag = cb_data->cb_flag;
@ -2674,9 +2648,6 @@ void blo_lib_link_restore(Main *oldmain,
* that is just some minor harmless double-processing. */
lib_link_main_data_restore(id_map, newmain);
/* update IDs stored in all possible clipboards */
lib_link_clipboard_restore(id_map);
BKE_main_idmap_destroy(id_map);
}

View File

@ -82,55 +82,55 @@ const char *BLT_translate_do_new_dataname(const char *msgctxt, const char *msgid
#define BLT_I18NCONTEXT_ID_ACTION "Action"
#define BLT_I18NCONTEXT_ID_ARMATURE "Armature"
#define BLT_I18NCONTEXT_ID_BRUSH "Brush"
#define BLT_I18NCONTEXT_ID_CAMERA "Camera"
#define BLT_I18NCONTEXT_ID_CACHEFILE "CacheFile"
#define BLT_I18NCONTEXT_ID_CAMERA "Camera"
#define BLT_I18NCONTEXT_ID_COLLECTION "Collection"
#define BLT_I18NCONTEXT_ID_CURVES "Curves"
#define BLT_I18NCONTEXT_ID_CURVE_LEGACY "Curve"
#define BLT_I18NCONTEXT_ID_FREESTYLELINESTYLE "FreestyleLineStyle"
#define BLT_I18NCONTEXT_ID_GPENCIL "GPencil"
#define BLT_I18NCONTEXT_ID_CURVES "Curves"
#define BLT_I18NCONTEXT_ID_ID "ID"
#define BLT_I18NCONTEXT_ID_IMAGE "Image"
// #define BLT_I18NCONTEXT_ID_IPO "Ipo" /* DEPRECATED */
#define BLT_I18NCONTEXT_ID_SHAPEKEY "Key"
#define BLT_I18NCONTEXT_ID_SIMULATION "Simulation"
#define BLT_I18NCONTEXT_ID_LIGHT "Light"
#define BLT_I18NCONTEXT_ID_LIBRARY "Library"
#define BLT_I18NCONTEXT_ID_LATTICE "Lattice"
#define BLT_I18NCONTEXT_ID_LIBRARY "Library"
#define BLT_I18NCONTEXT_ID_LIGHT "Light"
#define BLT_I18NCONTEXT_ID_LIGHTPROBE "LightProbe"
#define BLT_I18NCONTEXT_ID_MASK "Mask"
#define BLT_I18NCONTEXT_ID_MATERIAL "Material"
#define BLT_I18NCONTEXT_ID_METABALL "Metaball"
#define BLT_I18NCONTEXT_ID_MESH "Mesh"
#define BLT_I18NCONTEXT_ID_METABALL "Metaball"
#define BLT_I18NCONTEXT_ID_MOVIECLIP "MovieClip"
#define BLT_I18NCONTEXT_ID_NODETREE "NodeTree"
#define BLT_I18NCONTEXT_ID_OBJECT "Object"
#define BLT_I18NCONTEXT_ID_PAINTCURVE "PaintCurve"
#define BLT_I18NCONTEXT_ID_PALETTE "Palette"
#define BLT_I18NCONTEXT_ID_PARTICLESETTINGS "ParticleSettings"
#define BLT_I18NCONTEXT_ID_POINTCLOUD "PointCloud"
#define BLT_I18NCONTEXT_ID_LIGHTPROBE "LightProbe"
#define BLT_I18NCONTEXT_ID_SCENE "Scene"
#define BLT_I18NCONTEXT_ID_SCREEN "Screen"
#define BLT_I18NCONTEXT_ID_SEQUENCE "Sequence"
#define BLT_I18NCONTEXT_ID_SPEAKER "Speaker"
#define BLT_I18NCONTEXT_ID_SHAPEKEY "Key"
#define BLT_I18NCONTEXT_ID_SIMULATION "Simulation"
#define BLT_I18NCONTEXT_ID_SOUND "Sound"
#define BLT_I18NCONTEXT_ID_TEXTURE "Texture"
#define BLT_I18NCONTEXT_ID_SPEAKER "Speaker"
#define BLT_I18NCONTEXT_ID_TEXT "Text"
#define BLT_I18NCONTEXT_ID_TEXTURE "Texture"
#define BLT_I18NCONTEXT_ID_VFONT "VFont"
#define BLT_I18NCONTEXT_ID_VOLUME "Volume"
#define BLT_I18NCONTEXT_ID_WORLD "World"
#define BLT_I18NCONTEXT_ID_WORKSPACE "WorkSpace"
#define BLT_I18NCONTEXT_ID_WINDOWMANAGER "WindowManager"
#define BLT_I18NCONTEXT_ID_MOVIECLIP "MovieClip"
#define BLT_I18NCONTEXT_ID_MASK "Mask"
#define BLT_I18NCONTEXT_ID_WORKSPACE "WorkSpace"
#define BLT_I18NCONTEXT_ID_WORLD "World"
/* Editors-types contexts. */
#define BLT_I18NCONTEXT_EDITOR_VIEW3D "View3D"
#define BLT_I18NCONTEXT_EDITOR_FILEBROWSER "File browser"
#define BLT_I18NCONTEXT_EDITOR_VIEW3D "View3D"
/* Generic contexts. */
#define BLT_I18NCONTEXT_VIRTUAL_REALITY "Virtual reality"
#define BLT_I18NCONTEXT_CONSTRAINT "Constraint"
#define BLT_I18NCONTEXT_COLOR "Color"
#define BLT_I18NCONTEXT_AMOUNT "Amount"
#define BLT_I18NCONTEXT_COLOR "Color"
#define BLT_I18NCONTEXT_CONSTRAINT "Constraint"
#define BLT_I18NCONTEXT_TIME "Time"
#define BLT_I18NCONTEXT_UNIT "Unit"
/* Helper for bpy.app.i18n object... */
@ -155,25 +155,25 @@ typedef struct {
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_ACTION, "id_action"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_ARMATURE, "id_armature"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_BRUSH, "id_brush"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_CAMERA, "id_camera"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_CACHEFILE, "id_cachefile"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_CAMERA, "id_camera"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_COLLECTION, "id_collection"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_CURVES, "id_curves"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_CURVE_LEGACY, "id_curve"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_FREESTYLELINESTYLE, "id_fs_linestyle"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_GPENCIL, "id_gpencil"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_CURVES, "id_curves"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_ID, "id_id"), \
BLT_I18NCONTEXTS_ITEM( \
BLT_I18NCONTEXT_ID_IMAGE, \
"id_image"), /* BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_IPO, "id_ipo"), */ \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_SHAPEKEY, "id_shapekey"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_LIGHT, "id_light"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_LIBRARY, "id_library"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_LATTICE, "id_lattice"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_LIBRARY, "id_library"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_LIGHT, "id_light"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_LIGHTPROBE, "id_lightprobe"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_MASK, "id_mask"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_MATERIAL, "id_material"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_METABALL, "id_metaball"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_MESH, "id_mesh"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_METABALL, "id_metaball"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_MOVIECLIP, "id_movieclip"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_NODETREE, "id_nodetree"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_OBJECT, "id_object"), \
@ -181,26 +181,26 @@ typedef struct {
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_PALETTE, "id_palette"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_PARTICLESETTINGS, "id_particlesettings"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_POINTCLOUD, "id_pointcloud"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_LIGHTPROBE, "id_lightprobe"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_SCENE, "id_scene"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_SCREEN, "id_screen"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_SEQUENCE, "id_sequence"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_SHAPEKEY, "id_shapekey"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_SIMULATION, "id_simulation"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_SPEAKER, "id_speaker"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_SOUND, "id_sound"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_TEXTURE, "id_texture"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_SPEAKER, "id_speaker"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_TEXT, "id_text"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_TEXTURE, "id_texture"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_VFONT, "id_vfont"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_VOLUME, "id_volume"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_WORLD, "id_world"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_WORKSPACE, "id_workspace"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_WINDOWMANAGER, "id_windowmanager"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_EDITOR_VIEW3D, "editor_view3d"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_WORKSPACE, "id_workspace"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_WORLD, "id_world"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_EDITOR_FILEBROWSER, "editor_filebrowser"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_VIRTUAL_REALITY, "virtual_reality"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_CONSTRAINT, "constraint"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_COLOR, "color"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_EDITOR_VIEW3D, "editor_view3d"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_AMOUNT, "amount"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_COLOR, "color"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_CONSTRAINT, "constraint"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_TIME, "time"), \
BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_UNIT, "unit"), \
{ \
NULL, NULL, NULL \

View File

@ -1382,13 +1382,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
using namespace blender;
const int old_verts_num = me->totvert;
CustomData_free(&me->vdata, me->totvert);
CustomData_free(&me->edata, me->totedge);
CustomData_free(&me->fdata, me->totface);
CustomData_free(&me->ldata, me->totloop);
CustomData_free(&me->pdata, me->totpoly);
MEM_SAFE_FREE(me->poly_offset_indices);
BKE_mesh_runtime_clear_geometry(me);
BKE_mesh_clear_geometry(me);
me->totvert = bm->totvert;
me->totedge = bm->totedge;

View File

@ -172,7 +172,7 @@ class Operation {
void release_inputs();
/* Release the results that were allocated in the execute method but are not actually needed.
* This can be the case if the execute method allocated a dummy texture for an unndeeded result,
* This can be the case if the execute method allocated a dummy texture for an unneeded result,
* see the description of Result::allocate_texture() for more information. This is called after
* the evaluation of the operation. */
void release_unneeded_results();

View File

@ -41,7 +41,7 @@ class ShadingView {
/** Matrix to apply to the viewmat. */
const float4x4 &face_matrix_;
/** Raytracing persistent buffers. Only opaque and refraction can have surface tracing. */
/** Ray-tracing persistent buffers. Only opaque and refraction can have surface tracing. */
// RaytraceBuffer rt_buffer_opaque_;
// RaytraceBuffer rt_buffer_refract_;
DepthOfFieldBuffer dof_buffer_;

View File

@ -26,7 +26,8 @@ void main()
view_clipping_distances(world_pos);
bool show_handle = showCurveHandles;
if ((uint(curveHandleDisplay) == CURVE_HANDLE_SELECTED) && ((data & VERT_SELECTED_BEZT_HANDLE) == 0u)) {
if ((uint(curveHandleDisplay) == CURVE_HANDLE_SELECTED) &&
((data & VERT_SELECTED_BEZT_HANDLE) == 0u)) {
show_handle = false;
}

View File

@ -741,7 +741,7 @@ void ANIM_frame_channel_y_extents(bContext *C, bAnimContext *ac)
ListBase anim_data = {NULL, NULL};
const int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS |
ANIMFILTER_FCURVESONLY);
ANIMFILTER_FCURVESONLY | ANIMFILTER_CURVE_VISIBLE);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
rctf bounds = {.xmin = FLT_MAX, .xmax = -FLT_MAX, .ymin = FLT_MAX, .ymax = -FLT_MAX};

View File

@ -381,7 +381,7 @@ static int insert_into_textbuf(Object *obedit, uintptr_t c)
}
ef->textbuf[ef->pos] = c;
ef->textbufinfo[ef->pos] = cu->curinfo;
ef->textbufinfo[ef->pos].kern = 0;
ef->textbufinfo[ef->pos].kern = 0.0f;
ef->textbufinfo[ef->pos].mat_nr = obedit->actcol;
ef->pos++;
@ -1346,7 +1346,7 @@ static int change_spacing_exec(bContext *C, wmOperator *op)
Object *obedit = CTX_data_edit_object(C);
Curve *cu = obedit->data;
EditFont *ef = cu->editfont;
int kern, delta = RNA_int_get(op->ptr, "delta");
float kern, delta = RNA_float_get(op->ptr, "delta");
int selstart, selend;
bool changed = false;
@ -1361,7 +1361,6 @@ static int change_spacing_exec(bContext *C, wmOperator *op)
for (int i = selstart; i <= selend; i++) {
kern = ef->textbufinfo[i].kern + delta;
CLAMP(kern, -20, 20);
if (ef->textbufinfo[i].kern != kern) {
ef->textbufinfo[i].kern = kern;
@ -1392,15 +1391,15 @@ void FONT_OT_change_spacing(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
RNA_def_int(ot->srna,
"delta",
1,
-20,
20,
"Delta",
"Amount to decrease or increase character spacing with",
-20,
20);
RNA_def_float(ot->srna,
"delta",
1.0,
0.0,
0.0,
"Delta",
"Amount to decrease or increase character spacing with",
0.0,
0.0);
}
/** \} */

View File

@ -57,3 +57,8 @@ void ED_curves_transverts_create(Curves *curves_id, TransVertStore *tvs)
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
ed::curves::transverts_from_curves_positions_create(curves, tvs);
}
int *ED_curves_offsets_for_write(Curves *curves_id)
{
return curves_id->geometry.wrap().offsets_for_write().data();
}

View File

@ -1714,7 +1714,7 @@ static int gpencil_strokes_paste_exec(bContext *C, wmOperator *op)
* doesn't exist already depending on REC button status.
*/
/* Multiframe paste. */
/* Multi-frame paste. */
if (is_multiedit) {
for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
/* Active frame is copied later, so don't need duplicate the stroke here. */

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