forked from blender/blender
WIP: uv-simple-select #1
@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"project_id" : "Blender",
|
|
||||||
"conduit_uri" : "https://developer.blender.org/",
|
|
||||||
"phabricator.uri" : "https://developer.blender.org/",
|
|
||||||
"git.default-relative-commit" : "origin/master",
|
|
||||||
"arc.land.update.default" : "rebase",
|
|
||||||
"arc.land.onto.default" : "master"
|
|
||||||
}
|
|
@ -236,6 +236,8 @@ ForEachMacros:
|
|||||||
- LOOP_UNSELECTED_POINTS
|
- LOOP_UNSELECTED_POINTS
|
||||||
- LOOP_VISIBLE_KEYS
|
- LOOP_VISIBLE_KEYS
|
||||||
- LOOP_VISIBLE_POINTS
|
- LOOP_VISIBLE_POINTS
|
||||||
|
- LIGHT_FOREACH_BEGIN_DIRECTIONAL
|
||||||
|
- LIGHT_FOREACH_BEGIN_LOCAL
|
||||||
- LISTBASE_CIRCULAR_BACKWARD_BEGIN
|
- LISTBASE_CIRCULAR_BACKWARD_BEGIN
|
||||||
- LISTBASE_CIRCULAR_FORWARD_BEGIN
|
- LISTBASE_CIRCULAR_FORWARD_BEGIN
|
||||||
- LISTBASE_FOREACH
|
- LISTBASE_FOREACH
|
||||||
|
@ -524,7 +524,7 @@ endif()
|
|||||||
if(NOT APPLE)
|
if(NOT APPLE)
|
||||||
option(WITH_CYCLES_DEVICE_HIP "Enable Cycles AMD HIP support" ON)
|
option(WITH_CYCLES_DEVICE_HIP "Enable Cycles AMD HIP support" ON)
|
||||||
option(WITH_CYCLES_HIP_BINARIES "Build Cycles AMD HIP binaries" OFF)
|
option(WITH_CYCLES_HIP_BINARIES "Build Cycles AMD HIP binaries" OFF)
|
||||||
set(CYCLES_HIP_BINARIES_ARCH gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 gfx1035 gfx1100 gfx1101 gfx1102 CACHE STRING "AMD HIP architectures to build binaries for")
|
set(CYCLES_HIP_BINARIES_ARCH gfx900 gfx906 gfx90c gfx902 gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 gfx1035 gfx1100 gfx1101 gfx1102 CACHE STRING "AMD HIP architectures to build binaries for")
|
||||||
mark_as_advanced(WITH_CYCLES_DEVICE_HIP)
|
mark_as_advanced(WITH_CYCLES_DEVICE_HIP)
|
||||||
mark_as_advanced(CYCLES_HIP_BINARIES_ARCH)
|
mark_as_advanced(CYCLES_HIP_BINARIES_ARCH)
|
||||||
endif()
|
endif()
|
||||||
@ -625,8 +625,10 @@ mark_as_advanced(
|
|||||||
|
|
||||||
# Vulkan
|
# Vulkan
|
||||||
option(WITH_VULKAN_BACKEND "Enable Vulkan as graphics backend (only for development)" OFF)
|
option(WITH_VULKAN_BACKEND "Enable Vulkan as graphics backend (only for development)" OFF)
|
||||||
|
option(WITH_VULKAN_GUARDEDALLOC "Use guardedalloc for host allocations done inside Vulkan (development option)" OFF)
|
||||||
mark_as_advanced(
|
mark_as_advanced(
|
||||||
WITH_VULKAN_BACKEND
|
WITH_VULKAN_BACKEND
|
||||||
|
WITH_VULKAN_GUARDEDALLOC
|
||||||
)
|
)
|
||||||
|
|
||||||
# Metal
|
# Metal
|
||||||
|
@ -299,7 +299,11 @@ else
|
|||||||
ifneq ("$(wildcard $(DEPS_BUILD_DIR)/build.ninja)","")
|
ifneq ("$(wildcard $(DEPS_BUILD_DIR)/build.ninja)","")
|
||||||
DEPS_BUILD_COMMAND:=ninja
|
DEPS_BUILD_COMMAND:=ninja
|
||||||
else
|
else
|
||||||
|
ifeq ($(OS), Darwin)
|
||||||
DEPS_BUILD_COMMAND:=make -s
|
DEPS_BUILD_COMMAND:=make -s
|
||||||
|
else
|
||||||
|
DEPS_BUILD_COMMAND:="$(BLENDER_DIR)/build_files/build_environment/linux/make_deps_wrapper.sh" -s
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -398,7 +402,7 @@ endif
|
|||||||
|
|
||||||
deps: .FORCE
|
deps: .FORCE
|
||||||
@echo
|
@echo
|
||||||
@echo Configuring dependencies in \"$(DEPS_BUILD_DIR)\"
|
@echo Configuring dependencies in \"$(DEPS_BUILD_DIR)\", install to \"$(DEPS_INSTALL_DIR)\"
|
||||||
|
|
||||||
@cmake -H"$(DEPS_SOURCE_DIR)" \
|
@cmake -H"$(DEPS_SOURCE_DIR)" \
|
||||||
-B"$(DEPS_BUILD_DIR)" \
|
-B"$(DEPS_BUILD_DIR)" \
|
||||||
|
@ -22,7 +22,7 @@ elseif(UNIX AND NOT APPLE)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Boolean crashes with Arm assembly, see T103423.
|
# Boolean crashes with Arm assembly, see #103423.
|
||||||
if(BLENDER_PLATFORM_ARM)
|
if(BLENDER_PLATFORM_ARM)
|
||||||
set(GMP_OPTIONS
|
set(GMP_OPTIONS
|
||||||
${GMP_OPTIONS}
|
${GMP_OPTIONS}
|
||||||
|
74
build_files/build_environment/linux/make_deps_wrapper.sh
Executable file
74
build_files/build_environment/linux/make_deps_wrapper.sh
Executable file
@ -0,0 +1,74 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
# This script ensures:
|
||||||
|
# - One dependency is built at a time.
|
||||||
|
# - That dependency uses all available cores.
|
||||||
|
#
|
||||||
|
# Without this, simply calling `make -j$(nproc)` from the `${CMAKE_BUILD_DIR}/deps/`
|
||||||
|
# directory will build many projects at once.
|
||||||
|
#
|
||||||
|
# This is undesirable for the following reasons:
|
||||||
|
#
|
||||||
|
# - The output from projects is mixed together,
|
||||||
|
# making it difficult to track down the cause of a build failure.
|
||||||
|
#
|
||||||
|
# - Larger dependencies such as LLVM can bottleneck the build process,
|
||||||
|
# making it necessary to cancel the build and manually run build commands in each directory.
|
||||||
|
#
|
||||||
|
# - Building many projects at once means canceling (Control-C) can lead to the build being in an undefined state.
|
||||||
|
# It's possible canceling happens as a patch is being applied or files are being copied.
|
||||||
|
# (steps that aren't part of the compilation process where it's typically safe to cancel).
|
||||||
|
|
||||||
|
if [[ -z "$MY_MAKE_CALL_LEVEL" ]]; then
|
||||||
|
export MY_MAKE_CALL_LEVEL=0
|
||||||
|
export MY_MAKEFLAGS=$MAKEFLAGS
|
||||||
|
|
||||||
|
# Extract the jobs argument (`-jN`, `-j N`, `--jobs=N`).
|
||||||
|
add_next=0
|
||||||
|
for i in "$@"; do
|
||||||
|
case $i in
|
||||||
|
-j*)
|
||||||
|
export MY_JOBS_ARG=$i
|
||||||
|
if [ "$MY_JOBS_ARG" = "-j" ]; then
|
||||||
|
add_next=1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
--jobs=*)
|
||||||
|
shift # past argument=value
|
||||||
|
MY_JOBS_ARG=$i
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if (( add_next == 1 )); then
|
||||||
|
MY_JOBS_ARG="$MY_JOBS_ARG $i"
|
||||||
|
add_next=0
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
unset i add_next
|
||||||
|
|
||||||
|
if [[ -z "$MY_JOBS_ARG" ]]; then
|
||||||
|
MY_JOBS_ARG="-j$(nproc)"
|
||||||
|
fi
|
||||||
|
export MY_JOBS_ARG
|
||||||
|
# Support user defined `MAKEFLAGS`.
|
||||||
|
export MAKEFLAGS="$MY_MAKEFLAGS -j1"
|
||||||
|
else
|
||||||
|
export MY_MAKE_CALL_LEVEL=$(( MY_MAKE_CALL_LEVEL + 1 ))
|
||||||
|
if (( MY_MAKE_CALL_LEVEL == 1 )); then
|
||||||
|
# Important to set jobs to 1, otherwise user defined jobs argument is used.
|
||||||
|
export MAKEFLAGS="$MY_MAKEFLAGS -j1"
|
||||||
|
elif (( MY_MAKE_CALL_LEVEL == 2 )); then
|
||||||
|
# This is the level used by each sub-project.
|
||||||
|
export MAKEFLAGS="$MY_MAKEFLAGS $MY_JOBS_ARG"
|
||||||
|
fi
|
||||||
|
# Else leave `MY_MAKEFLAGS` flags as-is, avoids setting a high number of jobs on recursive
|
||||||
|
# calls (which may easily run out of memory). Let the job-server handle the rest.
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Useful for troubleshooting the wrapper.
|
||||||
|
# echo "Call level: $MY_MAKE_CALL_LEVEL, args=$@".
|
||||||
|
|
||||||
|
# Call actual make but ensure recursive calls run via this script.
|
||||||
|
exec make MAKE="$0" "$@"
|
@ -85,7 +85,7 @@ if(NOT APPLE)
|
|||||||
set(WITH_CYCLES_DEVICE_OPTIX ON CACHE BOOL "" FORCE)
|
set(WITH_CYCLES_DEVICE_OPTIX ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_CYCLES_CUDA_BINARIES ON CACHE BOOL "" FORCE)
|
set(WITH_CYCLES_CUDA_BINARIES ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_CYCLES_CUBIN_COMPILER OFF CACHE BOOL "" FORCE)
|
set(WITH_CYCLES_CUBIN_COMPILER OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_CYCLES_HIP_BINARIES ON CACHE BOOL "" FORCE)
|
set(WITH_CYCLES_HIP_BINARIES OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_CYCLES_DEVICE_ONEAPI ON CACHE BOOL "" FORCE)
|
set(WITH_CYCLES_DEVICE_ONEAPI ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_CYCLES_ONEAPI_BINARIES ON CACHE BOOL "" FORCE)
|
set(WITH_CYCLES_ONEAPI_BINARIES ON CACHE BOOL "" FORCE)
|
||||||
endif()
|
endif()
|
||||||
|
@ -544,7 +544,7 @@ endfunction()
|
|||||||
function(setup_platform_linker_libs
|
function(setup_platform_linker_libs
|
||||||
target
|
target
|
||||||
)
|
)
|
||||||
# jemalloc must be early in the list, to be before pthread (see T57998)
|
# jemalloc must be early in the list, to be before pthread (see #57998).
|
||||||
if(WITH_MEM_JEMALLOC)
|
if(WITH_MEM_JEMALLOC)
|
||||||
target_link_libraries(${target} ${JEMALLOC_LIBRARIES})
|
target_link_libraries(${target} ${JEMALLOC_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
@ -440,7 +440,7 @@ string(APPEND PLATFORM_LINKFLAGS " -stdlib=libc++")
|
|||||||
# Make stack size more similar to Embree, required for Embree.
|
# Make stack size more similar to Embree, required for Embree.
|
||||||
string(APPEND PLATFORM_LINKFLAGS_EXECUTABLE " -Wl,-stack_size,0x100000")
|
string(APPEND PLATFORM_LINKFLAGS_EXECUTABLE " -Wl,-stack_size,0x100000")
|
||||||
|
|
||||||
# Suppress ranlib "has no symbols" warnings (workaround for T48250)
|
# Suppress ranlib "has no symbols" warnings (workaround for #48250).
|
||||||
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||||
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||||
# llvm-ranlib doesn't support this flag. Xcode's libtool does.
|
# llvm-ranlib doesn't support this flag. Xcode's libtool does.
|
||||||
|
@ -121,7 +121,7 @@ if(WITH_WINDOWS_BUNDLE_CRT)
|
|||||||
include(InstallRequiredSystemLibraries)
|
include(InstallRequiredSystemLibraries)
|
||||||
|
|
||||||
# ucrtbase(d).dll cannot be in the manifest, due to the way windows 10 handles
|
# ucrtbase(d).dll cannot be in the manifest, due to the way windows 10 handles
|
||||||
# redirects for this dll, for details see T88813.
|
# redirects for this dll, for details see #88813.
|
||||||
foreach(lib ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS})
|
foreach(lib ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS})
|
||||||
string(FIND ${lib} "ucrtbase" pos)
|
string(FIND ${lib} "ucrtbase" pos)
|
||||||
if(NOT pos EQUAL -1)
|
if(NOT pos EQUAL -1)
|
||||||
@ -295,7 +295,7 @@ unset(MATERIALX_LIB_FOLDER_EXISTS)
|
|||||||
if(NOT MSVC_CLANG AND # Available with MSVC 15.7+ but not for CLANG.
|
if(NOT MSVC_CLANG AND # Available with MSVC 15.7+ but not for CLANG.
|
||||||
NOT WITH_WINDOWS_SCCACHE AND # And not when sccache is enabled
|
NOT WITH_WINDOWS_SCCACHE AND # And not when sccache is enabled
|
||||||
NOT VS_CLANG_TIDY) # Clang-tidy does not like these options
|
NOT VS_CLANG_TIDY) # Clang-tidy does not like these options
|
||||||
add_compile_options(/experimental:external /external:templates- /external:I "${LIBDIR}" /external:W0)
|
add_compile_options(/experimental:external /external:I "${LIBDIR}" /external:W0)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Add each of our libraries to our cmake_prefix_path so find_package() could work
|
# Add each of our libraries to our cmake_prefix_path so find_package() could work
|
||||||
|
@ -38,7 +38,7 @@ PROJECT_NAME = Blender
|
|||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = V3.5
|
PROJECT_NUMBER = V3.6
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer a
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
|
@ -476,7 +476,7 @@ MODULE_GROUPING = {
|
|||||||
|
|
||||||
# -------------------------------BLENDER----------------------------------------
|
# -------------------------------BLENDER----------------------------------------
|
||||||
|
|
||||||
# converting bytes to strings, due to T30154
|
# Converting bytes to strings, due to #30154.
|
||||||
BLENDER_REVISION = str(bpy.app.build_hash, 'utf_8')
|
BLENDER_REVISION = str(bpy.app.build_hash, 'utf_8')
|
||||||
BLENDER_REVISION_TIMESTAMP = bpy.app.build_commit_timestamp
|
BLENDER_REVISION_TIMESTAMP = bpy.app.build_commit_timestamp
|
||||||
|
|
||||||
@ -487,7 +487,7 @@ BLENDER_VERSION_DOTS = "%d.%d" % (bpy.app.version[0], bpy.app.version[1])
|
|||||||
if BLENDER_REVISION != "Unknown":
|
if BLENDER_REVISION != "Unknown":
|
||||||
# SHA1 Git hash
|
# SHA1 Git hash
|
||||||
BLENDER_VERSION_HASH = BLENDER_REVISION
|
BLENDER_VERSION_HASH = BLENDER_REVISION
|
||||||
BLENDER_VERSION_HASH_HTML_LINK = "<a href=https://developer.blender.org/rB%s>%s</a>" % (
|
BLENDER_VERSION_HASH_HTML_LINK = "<a href=https://projects.blender.org/blender/blender/commit/%s>%s</a>" % (
|
||||||
BLENDER_VERSION_HASH, BLENDER_VERSION_HASH,
|
BLENDER_VERSION_HASH, BLENDER_VERSION_HASH,
|
||||||
)
|
)
|
||||||
BLENDER_VERSION_DATE = time.strftime("%d/%m/%Y", time.localtime(BLENDER_REVISION_TIMESTAMP))
|
BLENDER_VERSION_DATE = time.strftime("%d/%m/%Y", time.localtime(BLENDER_REVISION_TIMESTAMP))
|
||||||
@ -647,7 +647,7 @@ def undocumented_message(module_name, type_name, identifier):
|
|||||||
module_name, type_name, identifier,
|
module_name, type_name, identifier,
|
||||||
)
|
)
|
||||||
|
|
||||||
return "Undocumented, consider `contributing <https://developer.blender.org/T51061>`__."
|
return "Undocumented, consider `contributing <https://developer.blender.org/>`__."
|
||||||
|
|
||||||
|
|
||||||
def range_str(val):
|
def range_str(val):
|
||||||
@ -2200,7 +2200,7 @@ def write_rst_enum_items(basepath, key, key_no_prefix, enum_items):
|
|||||||
Write a single page for a static enum in RST.
|
Write a single page for a static enum in RST.
|
||||||
|
|
||||||
This helps avoiding very large lists being in-lined in many places which is an issue
|
This helps avoiding very large lists being in-lined in many places which is an issue
|
||||||
especially with icons in ``bpy.types.UILayout``. See T87008.
|
especially with icons in ``bpy.types.UILayout``. See #87008.
|
||||||
"""
|
"""
|
||||||
filepath = os.path.join(basepath, "%s.rst" % key_no_prefix)
|
filepath = os.path.join(basepath, "%s.rst" % key_no_prefix)
|
||||||
with open(filepath, "w", encoding="utf-8") as fh:
|
with open(filepath, "w", encoding="utf-8") as fh:
|
||||||
|
@ -1676,15 +1676,18 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
|||||||
col.label(text="and NVIDIA driver version %s or newer" % driver_version,
|
col.label(text="and NVIDIA driver version %s or newer" % driver_version,
|
||||||
icon='BLANK1', translate=False)
|
icon='BLANK1', translate=False)
|
||||||
elif device_type == 'HIP':
|
elif device_type == 'HIP':
|
||||||
|
if True:
|
||||||
|
col.label(text="HIP temporarily disabled due to compiler bugs", icon='BLANK1')
|
||||||
|
else:
|
||||||
import sys
|
import sys
|
||||||
if sys.platform[:3] == "win":
|
if sys.platform[:3] == "win":
|
||||||
driver_version = "21.Q4"
|
driver_version = "21.Q4"
|
||||||
col.label(text="Requires AMD GPU with RDNA architecture", icon='BLANK1')
|
col.label(text="Requires AMD GPU with Vega or RDNA architecture", icon='BLANK1')
|
||||||
col.label(text=iface_("and AMD Radeon Pro %s driver or newer") % driver_version,
|
col.label(text=iface_("and AMD Radeon Pro %s driver or newer") % driver_version,
|
||||||
icon='BLANK1', translate=False)
|
icon='BLANK1', translate=False)
|
||||||
elif sys.platform.startswith("linux"):
|
elif sys.platform.startswith("linux"):
|
||||||
driver_version = "22.10"
|
driver_version = "22.10"
|
||||||
col.label(text="Requires AMD GPU with RDNA architecture", icon='BLANK1')
|
col.label(text="Requires AMD GPU with Vega or RDNA architecture", icon='BLANK1')
|
||||||
col.label(text=iface_("and AMD driver version %s or newer") % driver_version, icon='BLANK1',
|
col.label(text=iface_("and AMD driver version %s or newer") % driver_version, icon='BLANK1',
|
||||||
translate=False)
|
translate=False)
|
||||||
elif device_type == 'ONEAPI':
|
elif device_type == 'ONEAPI':
|
||||||
|
@ -20,7 +20,7 @@ class CyclesPresetPanel(PresetPanel, Panel):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def post_cb(context):
|
def post_cb(context):
|
||||||
# Modify an arbitrary built-in scene property to force a depsgraph
|
# Modify an arbitrary built-in scene property to force a depsgraph
|
||||||
# update, because add-on properties don't. (see T62325)
|
# update, because add-on properties don't. (see #62325)
|
||||||
render = context.scene.render
|
render = context.scene.render
|
||||||
render.filter_size = render.filter_size
|
render.filter_size = render.filter_size
|
||||||
|
|
||||||
|
@ -105,11 +105,12 @@ GPUShader *BlenderFallbackDisplayShader::bind(int width, int height)
|
|||||||
|
|
||||||
/* Bind shader now to enable uniform assignment. */
|
/* Bind shader now to enable uniform assignment. */
|
||||||
GPU_shader_bind(shader_program_);
|
GPU_shader_bind(shader_program_);
|
||||||
GPU_shader_uniform_int(shader_program_, image_texture_location_, 0);
|
int slot = 0;
|
||||||
|
GPU_shader_uniform_int_ex(shader_program_, image_texture_location_, 1, 1, &slot);
|
||||||
float size[2];
|
float size[2];
|
||||||
size[0] = width;
|
size[0] = width;
|
||||||
size[1] = height;
|
size[1] = height;
|
||||||
GPU_shader_uniform_vector(shader_program_, fullscreen_location_, 2, 1, size);
|
GPU_shader_uniform_float_ex(shader_program_, fullscreen_location_, 2, 1, size);
|
||||||
return shader_program_;
|
return shader_program_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ BlenderImageLoader::BlenderImageLoader(BL::Image b_image,
|
|||||||
: b_image(b_image),
|
: b_image(b_image),
|
||||||
frame(frame),
|
frame(frame),
|
||||||
tile_number(tile_number),
|
tile_number(tile_number),
|
||||||
/* Don't free cache for preview render to avoid race condition from T93560, to be fixed
|
/* Don't free cache for preview render to avoid race condition from #93560, to be fixed
|
||||||
* properly later as we are close to release. */
|
* properly later as we are close to release. */
|
||||||
free_cache(!is_preview_render && !b_image.has_data())
|
free_cache(!is_preview_render && !b_image.has_data())
|
||||||
{
|
{
|
||||||
@ -72,7 +72,7 @@ bool BlenderImageLoader::load_metadata(const ImageDeviceFeatures &, ImageMetaDat
|
|||||||
metadata.colorspace = u_colorspace_raw;
|
metadata.colorspace = u_colorspace_raw;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* In some cases (e.g. T94135), the colorspace setting in Blender gets updated as part of the
|
/* In some cases (e.g. #94135), the colorspace setting in Blender gets updated as part of the
|
||||||
* metadata queries in this function, so update the colorspace setting here. */
|
* metadata queries in this function, so update the colorspace setting here. */
|
||||||
PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr;
|
PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr;
|
||||||
metadata.colorspace = get_enum_identifier(colorspace_ptr, "name");
|
metadata.colorspace = get_enum_identifier(colorspace_ptr, "name");
|
||||||
|
@ -24,7 +24,7 @@ void BlenderSync::sync_light(BL::Object &b_parent,
|
|||||||
Light *light = light_map.find(key);
|
Light *light = light_map.find(key);
|
||||||
|
|
||||||
/* Check if the transform was modified, in case a linked collection is moved we do not get a
|
/* Check if the transform was modified, in case a linked collection is moved we do not get a
|
||||||
* specific depsgraph update (T88515). This also mimics the behavior for Objects. */
|
* specific depsgraph update (#88515). This also mimics the behavior for Objects. */
|
||||||
const bool tfm_updated = (light && light->get_tfm() != tfm);
|
const bool tfm_updated = (light && light->get_tfm() != tfm);
|
||||||
|
|
||||||
/* Update if either object or light data changed. */
|
/* Update if either object or light data changed. */
|
||||||
|
@ -94,7 +94,7 @@ void python_thread_state_restore(void **python_thread_state)
|
|||||||
*python_thread_state = NULL;
|
*python_thread_state = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
|
static const char *PyC_UnicodeAsBytes(PyObject *py_str, PyObject **coerce)
|
||||||
{
|
{
|
||||||
const char *result = PyUnicode_AsUTF8(py_str);
|
const char *result = PyUnicode_AsUTF8(py_str);
|
||||||
if (result) {
|
if (result) {
|
||||||
@ -131,8 +131,8 @@ static PyObject *init_func(PyObject * /*self*/, PyObject *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PyObject *path_coerce = nullptr, *user_path_coerce = nullptr;
|
PyObject *path_coerce = nullptr, *user_path_coerce = nullptr;
|
||||||
path_init(PyC_UnicodeAsByte(path, &path_coerce),
|
path_init(PyC_UnicodeAsBytes(path, &path_coerce),
|
||||||
PyC_UnicodeAsByte(user_path, &user_path_coerce));
|
PyC_UnicodeAsBytes(user_path, &user_path_coerce));
|
||||||
Py_XDECREF(path_coerce);
|
Py_XDECREF(path_coerce);
|
||||||
Py_XDECREF(user_path_coerce);
|
Py_XDECREF(user_path_coerce);
|
||||||
|
|
||||||
|
@ -404,7 +404,7 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
|
|||||||
* point we know that we've got everything to render current view layer.
|
* point we know that we've got everything to render current view layer.
|
||||||
*/
|
*/
|
||||||
/* At the moment we only free if we are not doing multi-view
|
/* At the moment we only free if we are not doing multi-view
|
||||||
* (or if we are rendering the last view). See T58142/D4239 for discussion.
|
* (or if we are rendering the last view). See #58142/D4239 for discussion.
|
||||||
*/
|
*/
|
||||||
if (view_index == num_views - 1) {
|
if (view_index == num_views - 1) {
|
||||||
free_blender_memory_if_possible();
|
free_blender_memory_if_possible();
|
||||||
|
@ -766,7 +766,7 @@ void BlenderSync::free_data_after_sync(BL::Depsgraph &b_depsgraph)
|
|||||||
(BlenderSession::headless || is_interface_locked) &&
|
(BlenderSession::headless || is_interface_locked) &&
|
||||||
/* Baking re-uses the depsgraph multiple times, clearing crashes
|
/* Baking re-uses the depsgraph multiple times, clearing crashes
|
||||||
* reading un-evaluated mesh data which isn't aligned with the
|
* reading un-evaluated mesh data which isn't aligned with the
|
||||||
* geometry we're baking, see T71012. */
|
* geometry we're baking, see #71012. */
|
||||||
!scene->bake_manager->get_baking() &&
|
!scene->bake_manager->get_baking() &&
|
||||||
/* Persistent data must main caches for performance and correctness. */
|
/* Persistent data must main caches for performance and correctness. */
|
||||||
!is_persistent_data;
|
!is_persistent_data;
|
||||||
|
@ -42,12 +42,15 @@ endif()
|
|||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
if(WITH_CYCLES_HIP_BINARIES AND WITH_CYCLES_DEVICE_HIP)
|
if(WITH_CYCLES_HIP_BINARIES AND WITH_CYCLES_DEVICE_HIP)
|
||||||
find_package(HIP)
|
set(WITH_CYCLES_HIP_BINARIES OFF)
|
||||||
set_and_warn_library_found("HIP compiler" HIP_FOUND WITH_CYCLES_HIP_BINARIES)
|
message(STATUS "HIP temporarily disabled due to compiler bugs")
|
||||||
|
|
||||||
if(HIP_FOUND)
|
# find_package(HIP)
|
||||||
message(STATUS "Found HIP ${HIP_HIPCC_EXECUTABLE} (${HIP_VERSION})")
|
# set_and_warn_library_found("HIP compiler" HIP_FOUND WITH_CYCLES_HIP_BINARIES)
|
||||||
endif()
|
|
||||||
|
# if(HIP_FOUND)
|
||||||
|
# message(STATUS "Found HIP ${HIP_HIPCC_EXECUTABLE} (${HIP_VERSION})")
|
||||||
|
# endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT WITH_HIP_DYNLOAD)
|
if(NOT WITH_HIP_DYNLOAD)
|
||||||
|
@ -906,7 +906,7 @@ bool HIPDevice::should_use_graphics_interop()
|
|||||||
* possible, but from the empiric measurements it can be considerably slower than using naive
|
* possible, but from the empiric measurements it can be considerably slower than using naive
|
||||||
* pixels copy. */
|
* pixels copy. */
|
||||||
|
|
||||||
/* Disable graphics interop for now, because of driver bug in 21.40. See T92972 */
|
/* Disable graphics interop for now, because of driver bug in 21.40. See #92972 */
|
||||||
# if 0
|
# if 0
|
||||||
HIPContextScope scope(this);
|
HIPContextScope scope(this);
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ static inline bool hipSupportsDevice(const int hipDevId)
|
|||||||
hipDeviceGetAttribute(&major, hipDeviceAttributeComputeCapabilityMajor, hipDevId);
|
hipDeviceGetAttribute(&major, hipDeviceAttributeComputeCapabilityMajor, hipDevId);
|
||||||
hipDeviceGetAttribute(&minor, hipDeviceAttributeComputeCapabilityMinor, hipDevId);
|
hipDeviceGetAttribute(&minor, hipDeviceAttributeComputeCapabilityMinor, hipDevId);
|
||||||
|
|
||||||
return (major >= 10);
|
return (major >= 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
CCL_NAMESPACE_END
|
||||||
|
@ -586,7 +586,7 @@ void MetalDevice::erase_allocation(device_memory &mem)
|
|||||||
if (it != metal_mem_map.end()) {
|
if (it != metal_mem_map.end()) {
|
||||||
MetalMem *mmem = it->second.get();
|
MetalMem *mmem = it->second.get();
|
||||||
|
|
||||||
/* blank out reference to MetalMem* in the launch params (fixes crash T94736) */
|
/* blank out reference to MetalMem* in the launch params (fixes crash #94736) */
|
||||||
if (mmem->pointer_index >= 0) {
|
if (mmem->pointer_index >= 0) {
|
||||||
device_ptr *pointers = (device_ptr *)&launch_params;
|
device_ptr *pointers = (device_ptr *)&launch_params;
|
||||||
pointers[mmem->pointer_index] = 0;
|
pointers[mmem->pointer_index] = 0;
|
||||||
|
@ -886,7 +886,7 @@ int RenderScheduler::get_num_samples_during_navigation(int resolution_divider) c
|
|||||||
{
|
{
|
||||||
/* Special trick for fast navigation: schedule multiple samples during fast navigation
|
/* Special trick for fast navigation: schedule multiple samples during fast navigation
|
||||||
* (which will prefer to use lower resolution to keep up with refresh rate). This gives more
|
* (which will prefer to use lower resolution to keep up with refresh rate). This gives more
|
||||||
* usable visual feedback for artists. There are a couple of tricks though. */
|
* usable visual feedback for artists. */
|
||||||
|
|
||||||
if (is_denoise_active_during_update()) {
|
if (is_denoise_active_during_update()) {
|
||||||
/* When denoising is used during navigation prefer using a higher resolution with less samples
|
/* When denoising is used during navigation prefer using a higher resolution with less samples
|
||||||
@ -896,25 +896,12 @@ int RenderScheduler::get_num_samples_during_navigation(int resolution_divider) c
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resolution_divider <= pixel_size_) {
|
/* Schedule samples equal to the resolution divider up to a maximum of 4.
|
||||||
/* When resolution divider is at or below pixel size, schedule one sample. This doesn't effect
|
* The idea is to have enough information on the screen by increasing the sample count as the
|
||||||
* the sample count at this resolution division, but instead assists in the calculation of
|
* resolution is decreased. */
|
||||||
* the resolution divider. */
|
/* NOTE: Changing this formula will change the formula in
|
||||||
return 1;
|
* `RenderScheduler::calculate_resolution_divider_for_time()`. */
|
||||||
}
|
return min(max(1, resolution_divider / pixel_size_), 4);
|
||||||
|
|
||||||
if (resolution_divider == pixel_size_ * 2) {
|
|
||||||
/* When resolution divider is the previous step to the final resolution, schedule two samples.
|
|
||||||
* This is so that rendering on lower resolution does not exceed time that it takes to render
|
|
||||||
* first sample at the full resolution. */
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Always render 4 samples, even if scene is configured for less.
|
|
||||||
* The idea here is to have enough information on the screen. Resolution divider of 2 allows us
|
|
||||||
* to have 4 time extra samples, so overall worst case timing is the same as the final resolution
|
|
||||||
* at one sample. */
|
|
||||||
return 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderScheduler::work_need_adaptive_filter() const
|
bool RenderScheduler::work_need_adaptive_filter() const
|
||||||
@ -1100,9 +1087,10 @@ void RenderScheduler::update_start_resolution_divider()
|
|||||||
/* TODO(sergey): Need to add hysteresis to avoid resolution divider bouncing around when actual
|
/* TODO(sergey): Need to add hysteresis to avoid resolution divider bouncing around when actual
|
||||||
* render time is somewhere on a boundary between two resolutions. */
|
* render time is somewhere on a boundary between two resolutions. */
|
||||||
|
|
||||||
/* Never increase resolution to higher than the pixel size (which is possible if the scene is
|
/* Don't let resolution drop below the desired one. It's better to be slow than provide an
|
||||||
* simple and compute device is fast). */
|
* unreadable viewport render. */
|
||||||
start_resolution_divider_ = max(resolution_divider_for_update, pixel_size_);
|
start_resolution_divider_ = min(resolution_divider_for_update,
|
||||||
|
default_start_resolution_divider_);
|
||||||
|
|
||||||
VLOG_WORK << "Calculated resolution divider is " << start_resolution_divider_;
|
VLOG_WORK << "Calculated resolution divider is " << start_resolution_divider_;
|
||||||
}
|
}
|
||||||
@ -1187,24 +1175,24 @@ void RenderScheduler::check_time_limit_reached()
|
|||||||
|
|
||||||
int RenderScheduler::calculate_resolution_divider_for_time(double desired_time, double actual_time)
|
int RenderScheduler::calculate_resolution_divider_for_time(double desired_time, double actual_time)
|
||||||
{
|
{
|
||||||
/* TODO(sergey): There should a non-iterative analytical formula here. */
|
const double ratio_between_times = actual_time / desired_time;
|
||||||
|
|
||||||
int resolution_divider = 1;
|
/* We can pass `ratio_between_times` to `get_num_samples_during_navigation()` to get our
|
||||||
|
* navigation samples because the equation for calculating the resolution divider is as follows:
|
||||||
|
* `actual_time / desired_time = sqr(resolution_divider) / sample_count`.
|
||||||
|
* While `resolution_divider` is less than or equal to 4, `resolution_divider = sample_count`
|
||||||
|
* (This relationship is determined in `get_num_samples_during_navigation()`). With some
|
||||||
|
* substitution we end up with `actual_time / desired_time = resolution_divider` while the
|
||||||
|
* resolution divider is less than or equal to 4. Once the resolution divider increases above 4,
|
||||||
|
* the relationship of `actual_time / desired_time = resolution_divider` is no longer true,
|
||||||
|
* however the sample count retrieved from `get_num_samples_during_navigation()` is still
|
||||||
|
* accurate if we continue using this assumption. It should be noted that the interaction between
|
||||||
|
* `pixel_size`, sample count, and resolution divider are automatically accounted for and that's
|
||||||
|
* why `pixel_size` isn't included in any of the equations. */
|
||||||
|
const int navigation_samples = get_num_samples_during_navigation(
|
||||||
|
ceil_to_int(ratio_between_times));
|
||||||
|
|
||||||
/* This algorithm iterates through resolution dividers until a divider is found that achieves
|
return ceil_to_int(sqrt(navigation_samples * ratio_between_times));
|
||||||
* the desired render time. A limit of default_start_resolution_divider_ is put in place as the
|
|
||||||
* maximum resolution divider to avoid an unreadable viewport due to a low resolution.
|
|
||||||
* pre_resolution_division_samples and post_resolution_division_samples are used in this
|
|
||||||
* calculation to better predict the performance impact of changing resolution divisions as
|
|
||||||
* the sample count can also change between resolution divisions. */
|
|
||||||
while (actual_time > desired_time && resolution_divider < default_start_resolution_divider_) {
|
|
||||||
int pre_resolution_division_samples = get_num_samples_during_navigation(resolution_divider);
|
|
||||||
resolution_divider = resolution_divider * 2;
|
|
||||||
int post_resolution_division_samples = get_num_samples_during_navigation(resolution_divider);
|
|
||||||
actual_time /= 4.0 * pre_resolution_division_samples / post_resolution_division_samples;
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolution_divider;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int calculate_resolution_divider_for_resolution(int width, int height, int resolution)
|
int calculate_resolution_divider_for_resolution(int width, int height, int resolution)
|
||||||
|
@ -412,11 +412,12 @@ if(WITH_CYCLES_CUDA_BINARIES)
|
|||||||
# warn for other versions
|
# warn for other versions
|
||||||
if((CUDA_VERSION STREQUAL "101") OR
|
if((CUDA_VERSION STREQUAL "101") OR
|
||||||
(CUDA_VERSION STREQUAL "102") OR
|
(CUDA_VERSION STREQUAL "102") OR
|
||||||
(CUDA_VERSION_MAJOR STREQUAL "11"))
|
(CUDA_VERSION_MAJOR STREQUAL "11") OR
|
||||||
|
(CUDA_VERSION_MAJOR STREQUAL "12"))
|
||||||
else()
|
else()
|
||||||
message(WARNING
|
message(WARNING
|
||||||
"CUDA version ${CUDA_VERSION_MAJOR}.${CUDA_VERSION_MINOR} detected, "
|
"CUDA version ${CUDA_VERSION_MAJOR}.${CUDA_VERSION_MINOR} detected, "
|
||||||
"build may succeed but only CUDA 11, 10.2 and 10.1 have been tested")
|
"build may succeed but only CUDA 12, 11, 10.2 and 10.1 have been tested")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# build for each arch
|
# build for each arch
|
||||||
@ -514,6 +515,16 @@ if(WITH_CYCLES_CUDA_BINARIES)
|
|||||||
else()
|
else()
|
||||||
message(STATUS "CUDA binaries for ${arch} require CUDA 10 or earlier, skipped.")
|
message(STATUS "CUDA binaries for ${arch} require CUDA 10 or earlier, skipped.")
|
||||||
endif()
|
endif()
|
||||||
|
elseif(${arch} MATCHES ".*_3.")
|
||||||
|
if(DEFINED CUDA11_NVCC_EXECUTABLE)
|
||||||
|
set(cuda_nvcc_executable ${CUDA11_NVCC_EXECUTABLE})
|
||||||
|
set(cuda_toolkit_root_dir ${CUDA11_TOOLKIT_ROOT_DIR})
|
||||||
|
elseif("${CUDA_VERSION}" LESS 120) # Support for sm_35, sm_37 was removed in CUDA 12
|
||||||
|
set(cuda_nvcc_executable ${CUDA_NVCC_EXECUTABLE})
|
||||||
|
set(cuda_toolkit_root_dir ${CUDA_TOOLKIT_ROOT_DIR})
|
||||||
|
else()
|
||||||
|
message(STATUS "CUDA binaries for ${arch} require CUDA 11 or earlier, skipped.")
|
||||||
|
endif()
|
||||||
elseif(${arch} MATCHES ".*_7." AND "${CUDA_VERSION}" LESS 100)
|
elseif(${arch} MATCHES ".*_7." AND "${CUDA_VERSION}" LESS 100)
|
||||||
message(STATUS "CUDA binaries for ${arch} require CUDA 10.0+, skipped.")
|
message(STATUS "CUDA binaries for ${arch} require CUDA 10.0+, skipped.")
|
||||||
elseif(${arch} MATCHES ".*_8.")
|
elseif(${arch} MATCHES ".*_8.")
|
||||||
|
@ -686,7 +686,7 @@ ccl_device_inline Spectrum bsdf_albedo(ccl_private const ShaderData *sd,
|
|||||||
albedo *= ((ccl_private const PrincipledSheenBsdf *)sc)->avg_value;
|
albedo *= ((ccl_private const PrincipledSheenBsdf *)sc)->avg_value;
|
||||||
break;
|
break;
|
||||||
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
|
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
|
||||||
albedo *= bsdf_principled_hair_albedo(sc);
|
albedo *= bsdf_principled_hair_albedo(sd, sc);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -478,10 +478,18 @@ ccl_device_inline float bsdf_principled_hair_albedo_roughness_scale(
|
|||||||
return (((((0.245f * x) + 5.574f) * x - 10.73f) * x + 2.532f) * x - 0.215f) * x + 5.969f;
|
return (((((0.245f * x) + 5.574f) * x - 10.73f) * x + 2.532f) * x - 0.215f) * x + 5.969f;
|
||||||
}
|
}
|
||||||
|
|
||||||
ccl_device Spectrum bsdf_principled_hair_albedo(ccl_private const ShaderClosure *sc)
|
ccl_device Spectrum bsdf_principled_hair_albedo(ccl_private const ShaderData *sd,
|
||||||
|
ccl_private const ShaderClosure *sc)
|
||||||
{
|
{
|
||||||
ccl_private PrincipledHairBSDF *bsdf = (ccl_private PrincipledHairBSDF *)sc;
|
ccl_private PrincipledHairBSDF *bsdf = (ccl_private PrincipledHairBSDF *)sc;
|
||||||
return exp(-sqrt(bsdf->sigma) * bsdf_principled_hair_albedo_roughness_scale(bsdf->v));
|
|
||||||
|
const float cos_theta_o = cos_from_sin(dot(sd->wi, safe_normalize(sd->dPdu)));
|
||||||
|
const float cos_gamma_o = cos_from_sin(bsdf->extra->geom.w);
|
||||||
|
const float f = fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta);
|
||||||
|
|
||||||
|
const float roughness_scale = bsdf_principled_hair_albedo_roughness_scale(bsdf->v);
|
||||||
|
/* TODO(lukas): Adding the Fresnel term here as a workaround until the proper refactor. */
|
||||||
|
return exp(-sqrt(bsdf->sigma) * roughness_scale) + make_spectrum(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
ccl_device_inline Spectrum
|
ccl_device_inline Spectrum
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#ifndef WITH_CYCLES_OPTIMIZED_KERNEL_AVX2
|
#ifndef WITH_CYCLES_OPTIMIZED_KERNEL_AVX2
|
||||||
# define KERNEL_STUB
|
# define KERNEL_STUB
|
||||||
#else
|
#else
|
||||||
/* SSE optimization disabled for now on 32 bit, see bug T36316. */
|
/* SSE optimization disabled for now on 32 bit, see bug #36316. */
|
||||||
# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
|
# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
|
||||||
# define __KERNEL_SSE__
|
# define __KERNEL_SSE__
|
||||||
# define __KERNEL_SSE2__
|
# define __KERNEL_SSE2__
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#ifndef WITH_CYCLES_OPTIMIZED_KERNEL_SSE2
|
#ifndef WITH_CYCLES_OPTIMIZED_KERNEL_SSE2
|
||||||
# define KERNEL_STUB
|
# define KERNEL_STUB
|
||||||
#else
|
#else
|
||||||
/* SSE optimization disabled for now on 32 bit, see bug T36316. */
|
/* SSE optimization disabled for now on 32 bit, see bug #36316. */
|
||||||
# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
|
# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
|
||||||
# define __KERNEL_SSE2__
|
# define __KERNEL_SSE2__
|
||||||
# endif
|
# endif
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#ifndef WITH_CYCLES_OPTIMIZED_KERNEL_SSE41
|
#ifndef WITH_CYCLES_OPTIMIZED_KERNEL_SSE41
|
||||||
# define KERNEL_STUB
|
# define KERNEL_STUB
|
||||||
#else
|
#else
|
||||||
/* SSE optimization disabled for now on 32 bit, see bug T36316. */
|
/* SSE optimization disabled for now on 32 bit, see bug #36316. */
|
||||||
# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
|
# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
|
||||||
# define __KERNEL_SSE2__
|
# define __KERNEL_SSE2__
|
||||||
# define __KERNEL_SSE3__
|
# define __KERNEL_SSE3__
|
||||||
|
@ -645,7 +645,7 @@ ccl_device_inline void kernel_gpu_film_convert_half_write(ccl_global uchar4 *rgb
|
|||||||
const int y,
|
const int y,
|
||||||
const half4 half_pixel)
|
const half4 half_pixel)
|
||||||
{
|
{
|
||||||
/* Work around HIP issue with half float display, see T92972. */
|
/* Work around HIP issue with half float display, see #92972. */
|
||||||
#ifdef __KERNEL_HIP__
|
#ifdef __KERNEL_HIP__
|
||||||
ccl_global half *out = ((ccl_global half *)rgba) + (rgba_offset + y * rgba_stride + x) * 4;
|
ccl_global half *out = ((ccl_global half *)rgba) + (rgba_offset + y * rgba_stride + x) * 4;
|
||||||
out[0] = half_pixel.x;
|
out[0] = half_pixel.x;
|
||||||
|
@ -394,7 +394,7 @@ bool OSLShaderManager::osl_compile(const string &inputfile, const string &output
|
|||||||
|
|
||||||
/* Compile.
|
/* Compile.
|
||||||
*
|
*
|
||||||
* Mutex protected because the OSL compiler does not appear to be thread safe, see T92503. */
|
* Mutex protected because the OSL compiler does not appear to be thread safe, see #92503. */
|
||||||
static thread_mutex osl_compiler_mutex;
|
static thread_mutex osl_compiler_mutex;
|
||||||
thread_scoped_lock lock(osl_compiler_mutex);
|
thread_scoped_lock lock(osl_compiler_mutex);
|
||||||
|
|
||||||
|
@ -573,7 +573,7 @@ void ShaderManager::device_update_common(Device * /*device*/,
|
|||||||
kfilm->is_rec709 = is_rec709;
|
kfilm->is_rec709 = is_rec709;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderManager::device_free_common(Device *, DeviceScene *dscene, Scene *scene)
|
void ShaderManager::device_free_common(Device * /*device*/, DeviceScene *dscene, Scene * /*scene*/)
|
||||||
{
|
{
|
||||||
dscene->shaders.free();
|
dscene->shaders.free();
|
||||||
}
|
}
|
||||||
|
@ -520,7 +520,7 @@ bool TileManager::write_tile(const RenderBuffers &tile_buffers)
|
|||||||
/* If there is an overscan used for the tile copy pixels into single continuous block of memory
|
/* If there is an overscan used for the tile copy pixels into single continuous block of memory
|
||||||
* without any "gaps".
|
* without any "gaps".
|
||||||
* This is a workaround for bug in OIIO (https://github.com/OpenImageIO/oiio/pull/3176).
|
* This is a workaround for bug in OIIO (https://github.com/OpenImageIO/oiio/pull/3176).
|
||||||
* Our task reference: T93008. */
|
* Our task reference: #93008. */
|
||||||
if (tile_params.window_x || tile_params.window_y ||
|
if (tile_params.window_x || tile_params.window_y ||
|
||||||
tile_params.window_width != tile_params.width ||
|
tile_params.window_width != tile_params.width ||
|
||||||
tile_params.window_height != tile_params.height) {
|
tile_params.window_height != tile_params.height) {
|
||||||
|
@ -421,7 +421,7 @@ ccl_device_inline float fast_expf(float x)
|
|||||||
|
|
||||||
#if !defined(__KERNEL_GPU__) && !defined(_MSC_VER)
|
#if !defined(__KERNEL_GPU__) && !defined(_MSC_VER)
|
||||||
/* MSVC seems to have a code-gen bug here in at least SSE41/AVX, see
|
/* MSVC seems to have a code-gen bug here in at least SSE41/AVX, see
|
||||||
* T78047 and T78869 for details. Just disable for now, it only makes
|
* #78047 and #78869 for details. Just disable for now, it only makes
|
||||||
* a small difference in denoising performance. */
|
* a small difference in denoising performance. */
|
||||||
ccl_device float4 fast_exp2f4(float4 x)
|
ccl_device float4 fast_exp2f4(float4 x)
|
||||||
{
|
{
|
||||||
|
@ -516,7 +516,7 @@ GHOST_TSuccess GHOST_ContextCGL::releaseNativeHandles()
|
|||||||
|
|
||||||
/* OpenGL on Metal
|
/* OpenGL on Metal
|
||||||
*
|
*
|
||||||
* Use Metal layer to avoid Viewport lagging on macOS, see T60043. */
|
* Use Metal layer to avoid Viewport lagging on macOS, see #60043. */
|
||||||
|
|
||||||
static const MTLPixelFormat METAL_FRAMEBUFFERPIXEL_FORMAT = MTLPixelFormatBGRA8Unorm;
|
static const MTLPixelFormat METAL_FRAMEBUFFERPIXEL_FORMAT = MTLPixelFormatBGRA8Unorm;
|
||||||
static const OSType METAL_CORE_VIDEO_PIXEL_FORMAT = kCVPixelFormatType_32BGRA;
|
static const OSType METAL_CORE_VIDEO_PIXEL_FORMAT = kCVPixelFormatType_32BGRA;
|
||||||
|
@ -141,7 +141,7 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
|
|||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
#else
|
#else
|
||||||
/* Important to initialize only GLXEW (_not_ GLEW),
|
/* Important to initialize only GLXEW (_not_ GLEW),
|
||||||
* since this breaks w/ Mesa's `swrast`, see: T46431. */
|
* since this breaks w/ Mesa's `swrast`, see: #46431. */
|
||||||
glxewInit();
|
glxewInit();
|
||||||
#endif /* USE_GLXEW_INIT_WORKAROUND */
|
#endif /* USE_GLXEW_INIT_WORKAROUND */
|
||||||
|
|
||||||
|
@ -302,7 +302,7 @@ bool GHOST_NDOFManager::setDevice(ushort vendor_id, ushort product_id)
|
|||||||
switch (product_id) {
|
switch (product_id) {
|
||||||
case 0xC62E: /* Plugged in. */
|
case 0xC62E: /* Plugged in. */
|
||||||
case 0xC62F: /* Wireless. */
|
case 0xC62F: /* Wireless. */
|
||||||
case 0xC658: /* Wireless (3DConnexion Universal Wireless Receiver in WIN32), see T82412. */
|
case 0xC658: /* Wireless (3DConnexion Universal Wireless Receiver in WIN32), see #82412. */
|
||||||
{
|
{
|
||||||
device_type_ = NDOF_SpaceMouseWireless;
|
device_type_ = NDOF_SpaceMouseWireless;
|
||||||
hid_map_button_num_ = 2;
|
hid_map_button_num_ = 2;
|
||||||
|
@ -141,7 +141,7 @@ constexpr size_t events_pending_default_size = 4096 / sizeof(void *);
|
|||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GNOME (mutter 42.2 had a bug with confine not respecting scale - Hi-DPI), See: T98793.
|
* GNOME (mutter 42.2 had a bug with confine not respecting scale - Hi-DPI), See: #98793.
|
||||||
* Even though this has been fixed, at time of writing it's not yet in a release.
|
* Even though this has been fixed, at time of writing it's not yet in a release.
|
||||||
* Workaround the problem by implementing confine with a software cursor.
|
* Workaround the problem by implementing confine with a software cursor.
|
||||||
* While this isn't ideal, it's not adding a lot of overhead as software
|
* While this isn't ideal, it's not adding a lot of overhead as software
|
||||||
@ -176,7 +176,7 @@ static bool use_gnome_confine_hack = false;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* KDE (plasma 5.26.1) has a bug where the cursor surface needs to be committed
|
* KDE (plasma 5.26.1) has a bug where the cursor surface needs to be committed
|
||||||
* (via `wl_surface_commit`) when it was hidden and is being set to visible again, see: T102048.
|
* (via `wl_surface_commit`) when it was hidden and is being set to visible again, see: #102048.
|
||||||
* See: https://bugs.kde.org/show_bug.cgi?id=461001
|
* See: https://bugs.kde.org/show_bug.cgi?id=461001
|
||||||
*/
|
*/
|
||||||
#define USE_KDE_TABLET_HIDDEN_CURSOR_HACK
|
#define USE_KDE_TABLET_HIDDEN_CURSOR_HACK
|
||||||
@ -197,8 +197,8 @@ static bool use_gnome_confine_hack = false;
|
|||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fix short-cut part of keyboard reading code not properly handling some keys, see: T102194.
|
* Fix short-cut part of keyboard reading code not properly handling some keys, see: #102194.
|
||||||
* \note This is similar to X11 workaround by the same name, see: T47228.
|
* \note This is similar to X11 workaround by the same name, see: #47228.
|
||||||
*/
|
*/
|
||||||
#define USE_NON_LATIN_KB_WORKAROUND
|
#define USE_NON_LATIN_KB_WORKAROUND
|
||||||
|
|
||||||
@ -1328,7 +1328,7 @@ static void ghost_wl_display_report_error(struct wl_display *display)
|
|||||||
* So in practice re-connecting to the display server isn't an option.
|
* So in practice re-connecting to the display server isn't an option.
|
||||||
*
|
*
|
||||||
* Exit since leaving the process open will simply flood the output and do nothing.
|
* Exit since leaving the process open will simply flood the output and do nothing.
|
||||||
* Although as the process is in a valid state, auto-save for e.g. is possible, see: T100855. */
|
* Although as the process is in a valid state, auto-save for e.g. is possible, see: #100855. */
|
||||||
::exit(-1);
|
::exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1442,7 +1442,7 @@ static GHOST_TKey xkb_map_gkey(const xkb_keysym_t sym)
|
|||||||
|
|
||||||
/* Additional keys for non US layouts. */
|
/* Additional keys for non US layouts. */
|
||||||
|
|
||||||
/* Uses the same physical key as #XKB_KEY_KP_Decimal for QWERTZ layout, see: T102287. */
|
/* Uses the same physical key as #XKB_KEY_KP_Decimal for QWERTZ layout, see: #102287. */
|
||||||
GXMAP(gkey, XKB_KEY_KP_Separator, GHOST_kKeyNumpadPeriod);
|
GXMAP(gkey, XKB_KEY_KP_Separator, GHOST_kKeyNumpadPeriod);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -3810,7 +3810,7 @@ static xkb_keysym_t xkb_state_key_get_one_sym_without_modifiers(
|
|||||||
|
|
||||||
/* NOTE(@ideasman42): Only perform the number-locked lookup as a fallback
|
/* NOTE(@ideasman42): Only perform the number-locked lookup as a fallback
|
||||||
* when a number-pad key has been pressed. This is important as some key-maps use number lock
|
* when a number-pad key has been pressed. This is important as some key-maps use number lock
|
||||||
* for switching other layers (in particular `de(neo_qwertz)` turns on layer-4), see: T96170.
|
* for switching other layers (in particular `de(neo_qwertz)` turns on layer-4), see: #96170.
|
||||||
* Alternative solutions could be to inspect the layout however this could get involved
|
* Alternative solutions could be to inspect the layout however this could get involved
|
||||||
* and turning on the number-lock is only needed for a limited set of keys. */
|
* and turning on the number-lock is only needed for a limited set of keys. */
|
||||||
|
|
||||||
@ -4467,7 +4467,7 @@ static void xdg_output_handle_logical_size(void *data,
|
|||||||
|
|
||||||
#ifdef USE_GNOME_CONFINE_HACK
|
#ifdef USE_GNOME_CONFINE_HACK
|
||||||
/* Use a bug in GNOME to check GNOME is in use. If the bug is fixed this won't cause an issue
|
/* Use a bug in GNOME to check GNOME is in use. If the bug is fixed this won't cause an issue
|
||||||
* as T98793 has been fixed up-stream too, but not in a release at time of writing. */
|
* as #98793 has been fixed up-stream too, but not in a release at time of writing. */
|
||||||
use_gnome_confine_hack = true;
|
use_gnome_confine_hack = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -208,7 +208,7 @@ class GHOST_SystemWayland : public GHOST_System {
|
|||||||
* Clear all references to this output.
|
* Clear all references to this output.
|
||||||
*
|
*
|
||||||
* \note The compositor should have already called the `wl_surface_listener.leave` callback,
|
* \note The compositor should have already called the `wl_surface_listener.leave` callback,
|
||||||
* however some compositors may not (see T103586).
|
* however some compositors may not (see #103586).
|
||||||
* So remove references to the output before it's destroyed to avoid crashing.
|
* So remove references to the output before it's destroyed to avoid crashing.
|
||||||
*
|
*
|
||||||
* \return true when any references were removed.
|
* \return true when any references were removed.
|
||||||
|
@ -565,8 +565,8 @@ GHOST_TKey GHOST_SystemWin32::hardKey(RAWINPUT const &raw, bool *r_key_down)
|
|||||||
/**
|
/**
|
||||||
* \note this function can be extended to include other exotic cases as they arise.
|
* \note this function can be extended to include other exotic cases as they arise.
|
||||||
*
|
*
|
||||||
* This function was added in response to bug T25715.
|
* This function was added in response to bug #25715.
|
||||||
* This is going to be a long list T42426.
|
* This is going to be a long list #42426.
|
||||||
*/
|
*/
|
||||||
GHOST_TKey GHOST_SystemWin32::processSpecialKey(short vKey, short scanCode) const
|
GHOST_TKey GHOST_SystemWin32::processSpecialKey(short vKey, short scanCode) const
|
||||||
{
|
{
|
||||||
@ -1083,7 +1083,7 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind
|
|||||||
* so the box needs to small enough not to let the cursor escape the window but large
|
* so the box needs to small enough not to let the cursor escape the window but large
|
||||||
* enough that the cursor isn't being warped every time.
|
* enough that the cursor isn't being warped every time.
|
||||||
* If this was not the case it would be less trouble to simply warp the cursor to the
|
* If this was not the case it would be less trouble to simply warp the cursor to the
|
||||||
* center of the screen on every motion, see: D16558 (alternative fix for T102346). */
|
* center of the screen on every motion, see: D16558 (alternative fix for #102346). */
|
||||||
const int32_t subregion_div = 4; /* One quarter of the region. */
|
const int32_t subregion_div = 4; /* One quarter of the region. */
|
||||||
const int32_t size[2] = {bounds.getWidth(), bounds.getHeight()};
|
const int32_t size[2] = {bounds.getWidth(), bounds.getHeight()};
|
||||||
const int32_t center[2] = {(bounds.m_l + bounds.m_r) / 2, (bounds.m_t + bounds.m_b) / 2};
|
const int32_t center[2] = {(bounds.m_l + bounds.m_r) / 2, (bounds.m_t + bounds.m_b) / 2};
|
||||||
@ -1209,7 +1209,7 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA
|
|||||||
const bool ctrl_pressed = has_state && state[VK_CONTROL] & 0x80;
|
const bool ctrl_pressed = has_state && state[VK_CONTROL] & 0x80;
|
||||||
const bool alt_pressed = has_state && state[VK_MENU] & 0x80;
|
const bool alt_pressed = has_state && state[VK_MENU] & 0x80;
|
||||||
|
|
||||||
/* We can be here with !key_down if processing dead keys (diacritics). See T103119. */
|
/* We can be here with !key_down if processing dead keys (diacritics). See #103119. */
|
||||||
|
|
||||||
/* No text with control key pressed (Alt can be used to insert special characters though!). */
|
/* No text with control key pressed (Alt can be used to insert special characters though!). */
|
||||||
if (ctrl_pressed && !alt_pressed) {
|
if (ctrl_pressed && !alt_pressed) {
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
#ifdef WITH_X11_XFIXES
|
#ifdef WITH_X11_XFIXES
|
||||||
# include <X11/extensions/Xfixes.h>
|
# include <X11/extensions/Xfixes.h>
|
||||||
/* Workaround for XWayland grab glitch: T53004. */
|
/* Workaround for XWayland grab glitch: #53004. */
|
||||||
# define WITH_XWAYLAND_HACK
|
# define WITH_XWAYLAND_HACK
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -71,11 +71,11 @@
|
|||||||
# define USE_XINPUT_HOTPLUG
|
# define USE_XINPUT_HOTPLUG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* see T34039 Fix Alt key glitch on Unity desktop */
|
/* see #34039 Fix Alt key glitch on Unity desktop */
|
||||||
#define USE_UNITY_WORKAROUND
|
#define USE_UNITY_WORKAROUND
|
||||||
|
|
||||||
/* Fix 'shortcut' part of keyboard reading code only ever using first defined key-map
|
/* Fix 'shortcut' part of keyboard reading code only ever using first defined key-map
|
||||||
* instead of active one. See T47228 and D1746 */
|
* instead of active one. See #47228 and D1746 */
|
||||||
#define USE_NON_LATIN_KB_WORKAROUND
|
#define USE_NON_LATIN_KB_WORKAROUND
|
||||||
|
|
||||||
static uchar bit_is_on(const uchar *ptr, int bit)
|
static uchar bit_is_on(const uchar *ptr, int bit)
|
||||||
@ -928,7 +928,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
|||||||
window->getClientBounds(bounds);
|
window->getClientBounds(bounds);
|
||||||
|
|
||||||
/* TODO(@ideasman42): warp the cursor to `window->getCursorGrabInitPos`,
|
/* TODO(@ideasman42): warp the cursor to `window->getCursorGrabInitPos`,
|
||||||
* on every motion event, see: D16557 (alternative fix for T102346). */
|
* on every motion event, see: D16557 (alternative fix for #102346). */
|
||||||
const int32_t subregion_div = 4; /* One quarter of the region. */
|
const int32_t subregion_div = 4; /* One quarter of the region. */
|
||||||
const int32_t size[2] = {bounds.getWidth(), bounds.getHeight()};
|
const int32_t size[2] = {bounds.getWidth(), bounds.getHeight()};
|
||||||
const int32_t center[2] = {
|
const int32_t center[2] = {
|
||||||
@ -964,7 +964,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
|||||||
if (x_new != xme.x_root || y_new != xme.y_root) {
|
if (x_new != xme.x_root || y_new != xme.y_root) {
|
||||||
/* Use time of last event to avoid wrapping several times on the 'same' actual wrap.
|
/* Use time of last event to avoid wrapping several times on the 'same' actual wrap.
|
||||||
* Note that we need to deal with X and Y separately as those might wrap at the same time
|
* Note that we need to deal with X and Y separately as those might wrap at the same time
|
||||||
* but still in two different events (corner case, see T74918).
|
* but still in two different events (corner case, see #74918).
|
||||||
* We also have to add a few extra milliseconds of 'padding', as sometimes we get two
|
* We also have to add a few extra milliseconds of 'padding', as sometimes we get two
|
||||||
* close events that will generate extra wrap on the same axis within those few
|
* close events that will generate extra wrap on the same axis within those few
|
||||||
* milliseconds. */
|
* milliseconds. */
|
||||||
@ -1028,7 +1028,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
|||||||
/* XXX: Code below is kinda awfully convoluted... Issues are:
|
/* XXX: Code below is kinda awfully convoluted... Issues are:
|
||||||
* - In keyboards like Latin ones, numbers need a 'Shift' to be accessed but key_sym
|
* - In keyboards like Latin ones, numbers need a 'Shift' to be accessed but key_sym
|
||||||
* is unmodified (or anyone swapping the keys with `xmodmap`).
|
* is unmodified (or anyone swapping the keys with `xmodmap`).
|
||||||
* - #XLookupKeysym seems to always use first defined key-map (see T47228), which generates
|
* - #XLookupKeysym seems to always use first defined key-map (see #47228), which generates
|
||||||
* key-codes unusable by ghost_key_from_keysym for non-Latin-compatible key-maps.
|
* key-codes unusable by ghost_key_from_keysym for non-Latin-compatible key-maps.
|
||||||
*
|
*
|
||||||
* To address this, we:
|
* To address this, we:
|
||||||
@ -1715,7 +1715,7 @@ GHOST_TSuccess GHOST_SystemX11::setCursorPosition(int32_t x, int32_t y)
|
|||||||
|
|
||||||
#if defined(WITH_X11_XINPUT) && defined(USE_X11_XINPUT_WARP)
|
#if defined(WITH_X11_XINPUT) && defined(USE_X11_XINPUT_WARP)
|
||||||
if ((m_xinput_version.present) && (m_xinput_version.major_version >= 2)) {
|
if ((m_xinput_version.present) && (m_xinput_version.major_version >= 2)) {
|
||||||
/* Needed to account for XInput "Coordinate Transformation Matrix", see T48901 */
|
/* Needed to account for XInput "Coordinate Transformation Matrix", see #48901 */
|
||||||
int device_id;
|
int device_id;
|
||||||
if (XIGetClientPointer(m_display, None, &device_id) != False) {
|
if (XIGetClientPointer(m_display, None, &device_id) != False) {
|
||||||
XIWarpPointer(m_display, device_id, None, None, 0, 0, 0, 0, relx, rely);
|
XIWarpPointer(m_display, device_id, None, None, 0, 0, 0, 0, relx, rely);
|
||||||
|
@ -20,8 +20,8 @@
|
|||||||
|
|
||||||
/* Disable XINPUT warp, currently not implemented by Xorg for multi-head display.
|
/* Disable XINPUT warp, currently not implemented by Xorg for multi-head display.
|
||||||
* (see comment in XSERVER `Xi/xiwarppointer.c` -> `FIXME: panoramix stuff is missing` ~ v1.13.4)
|
* (see comment in XSERVER `Xi/xiwarppointer.c` -> `FIXME: panoramix stuff is missing` ~ v1.13.4)
|
||||||
* If this is supported we can add back XINPUT for warping (fixing T48901).
|
* If this is supported we can add back XINPUT for warping (fixing #48901).
|
||||||
* For now disable (see T50383). */
|
* For now disable (see #50383). */
|
||||||
// # define USE_X11_XINPUT_WARP
|
// # define USE_X11_XINPUT_WARP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -306,14 +306,23 @@ static void gwl_window_frame_update_from_pending(GWL_Window *win);
|
|||||||
#ifdef USE_EVENT_BACKGROUND_THREAD
|
#ifdef USE_EVENT_BACKGROUND_THREAD
|
||||||
|
|
||||||
enum eGWL_PendingWindowActions {
|
enum eGWL_PendingWindowActions {
|
||||||
PENDING_FRAME_CONFIGURE = 0,
|
/**
|
||||||
PENDING_EGL_RESIZE,
|
* 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
|
# ifdef GHOST_OPENGL_ALPHA
|
||||||
|
/** Draw an opaque region behind the window. */
|
||||||
PENDING_OPAQUE_SET,
|
PENDING_OPAQUE_SET,
|
||||||
# endif
|
# endif
|
||||||
PENDING_SCALE_UPDATE,
|
/**
|
||||||
|
* The DPI for a monitor has changed or the monitors (outputs)
|
||||||
|
* this window is visible on may have changed. Recalculate the windows scale.
|
||||||
|
*/
|
||||||
|
PENDING_OUTPUT_SCALE_UPDATE,
|
||||||
};
|
};
|
||||||
# define PENDING_NUM (PENDING_SCALE_UPDATE + 1)
|
# define PENDING_NUM (PENDING_OUTPUT_SCALE_UPDATE + 1)
|
||||||
|
|
||||||
static void gwl_window_pending_actions_tag(GWL_Window *win, enum eGWL_PendingWindowActions type)
|
static void gwl_window_pending_actions_tag(GWL_Window *win, enum eGWL_PendingWindowActions type)
|
||||||
{
|
{
|
||||||
@ -323,10 +332,10 @@ static void gwl_window_pending_actions_tag(GWL_Window *win, enum eGWL_PendingWin
|
|||||||
|
|
||||||
static void gwl_window_pending_actions_handle(GWL_Window *win)
|
static void gwl_window_pending_actions_handle(GWL_Window *win)
|
||||||
{
|
{
|
||||||
if (win->pending_actions[PENDING_FRAME_CONFIGURE].exchange(false)) {
|
if (win->pending_actions[PENDING_WINDOW_FRAME_CONFIGURE].exchange(false)) {
|
||||||
gwl_window_frame_update_from_pending(win);
|
gwl_window_frame_update_from_pending(win);
|
||||||
}
|
}
|
||||||
if (win->pending_actions[PENDING_EGL_RESIZE].exchange(false)) {
|
if (win->pending_actions[PENDING_EGL_WINDOW_RESIZE].exchange(false)) {
|
||||||
wl_egl_window_resize(win->egl_window, UNPACK2(win->frame.size), 0, 0);
|
wl_egl_window_resize(win->egl_window, UNPACK2(win->frame.size), 0, 0);
|
||||||
}
|
}
|
||||||
# ifdef GHOST_OPENGL_ALPHA
|
# ifdef GHOST_OPENGL_ALPHA
|
||||||
@ -334,7 +343,7 @@ static void gwl_window_pending_actions_handle(GWL_Window *win)
|
|||||||
win->ghost_window->setOpaque();
|
win->ghost_window->setOpaque();
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
if (win->pending_actions[PENDING_SCALE_UPDATE].exchange(false)) {
|
if (win->pending_actions[PENDING_OUTPUT_SCALE_UPDATE].exchange(false)) {
|
||||||
win->ghost_window->outputs_changed_update_scale();
|
win->ghost_window->outputs_changed_update_scale();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -342,9 +351,10 @@ static void gwl_window_pending_actions_handle(GWL_Window *win)
|
|||||||
#endif /* USE_EVENT_BACKGROUND_THREAD */
|
#endif /* USE_EVENT_BACKGROUND_THREAD */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the window's #GWL_WindowFrame
|
* Update the window's #GWL_WindowFrame.
|
||||||
|
* The caller must handle locking & run from the main thread.
|
||||||
*/
|
*/
|
||||||
static void gwl_window_frame_update_from_pending_lockfree(GWL_Window *win)
|
static void gwl_window_frame_update_from_pending_no_lock(GWL_Window *win)
|
||||||
{
|
{
|
||||||
#ifdef USE_EVENT_BACKGROUND_THREAD
|
#ifdef USE_EVENT_BACKGROUND_THREAD
|
||||||
GHOST_ASSERT(win->ghost_system->main_thread_id == std::this_thread::get_id(),
|
GHOST_ASSERT(win->ghost_system->main_thread_id == std::this_thread::get_id(),
|
||||||
@ -381,7 +391,7 @@ static void gwl_window_frame_update_from_pending(GWL_Window *win)
|
|||||||
#ifdef USE_EVENT_BACKGROUND_THREAD
|
#ifdef USE_EVENT_BACKGROUND_THREAD
|
||||||
std::lock_guard lock_frame_guard{win->frame_pending_mutex};
|
std::lock_guard lock_frame_guard{win->frame_pending_mutex};
|
||||||
#endif
|
#endif
|
||||||
gwl_window_frame_update_from_pending_lockfree(win);
|
gwl_window_frame_update_from_pending_no_lock(win);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
@ -576,12 +586,12 @@ static void frame_handle_configure(struct libdecor_frame *frame,
|
|||||||
GHOST_SystemWayland *system = win->ghost_system;
|
GHOST_SystemWayland *system = win->ghost_system;
|
||||||
const bool is_main_thread = system->main_thread_id == std::this_thread::get_id();
|
const bool is_main_thread = system->main_thread_id == std::this_thread::get_id();
|
||||||
if (!is_main_thread) {
|
if (!is_main_thread) {
|
||||||
gwl_window_pending_actions_tag(win, PENDING_FRAME_CONFIGURE);
|
gwl_window_pending_actions_tag(win, PENDING_WINDOW_FRAME_CONFIGURE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
# endif
|
# endif
|
||||||
{
|
{
|
||||||
gwl_window_frame_update_from_pending_lockfree(win);
|
gwl_window_frame_update_from_pending_no_lock(win);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -671,7 +681,7 @@ static void xdg_surface_handle_configure(void *data,
|
|||||||
if (!is_main_thread) {
|
if (!is_main_thread) {
|
||||||
/* NOTE(@ideasman42): this only gets one redraw,
|
/* NOTE(@ideasman42): this only gets one redraw,
|
||||||
* I could not find a case where this causes problems. */
|
* I could not find a case where this causes problems. */
|
||||||
gwl_window_pending_actions_tag(win, PENDING_FRAME_CONFIGURE);
|
gwl_window_pending_actions_tag(win, PENDING_WINDOW_FRAME_CONFIGURE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@ -812,12 +822,12 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
|
|||||||
* when the `window_->scale` changed. */
|
* when the `window_->scale` changed. */
|
||||||
const int32_t size_min[2] = {320, 240};
|
const int32_t size_min[2] = {320, 240};
|
||||||
|
|
||||||
/* This value is expected to match the base name of the `.desktop` file. see T101805.
|
/* This value is expected to match the base name of the `.desktop` file. see #101805.
|
||||||
*
|
*
|
||||||
* NOTE: the XDG desktop-entry-spec defines that this should follow the "reverse DNS" convention.
|
* NOTE: the XDG desktop-entry-spec defines that this should follow the "reverse DNS" convention.
|
||||||
* For e.g. `org.blender.Blender` - however the `.desktop` file distributed with Blender is
|
* For e.g. `org.blender.Blender` - however the `.desktop` file distributed with Blender is
|
||||||
* simply called `blender.desktop`, so the it's important to follow that name.
|
* simply called `blender.desktop`, so the it's important to follow that name.
|
||||||
* Other distributions such as SNAP & FLATPAK may need to change this value T101779.
|
* Other distributions such as SNAP & FLATPAK may need to change this value #101779.
|
||||||
* Currently there isn't a way to configure this, we may want to support that. */
|
* Currently there isn't a way to configure this, we may want to support that. */
|
||||||
const char *xdg_app_id = (
|
const char *xdg_app_id = (
|
||||||
#ifdef WITH_GHOST_WAYLAND_APP_ID
|
#ifdef WITH_GHOST_WAYLAND_APP_ID
|
||||||
@ -1080,7 +1090,7 @@ GHOST_WindowWayland::~GHOST_WindowWayland()
|
|||||||
|
|
||||||
/* NOTE(@ideasman42): Flushing will often run the appropriate handlers event
|
/* NOTE(@ideasman42): Flushing will often run the appropriate handlers event
|
||||||
* (#wl_surface_listener.leave in particular) to avoid attempted access to the freed surfaces.
|
* (#wl_surface_listener.leave in particular) to avoid attempted access to the freed surfaces.
|
||||||
* This is not fool-proof though, hence the call to #window_surface_unref, see: T99078. */
|
* This is not fool-proof though, hence the call to #window_surface_unref, see: #99078. */
|
||||||
wl_display_flush(system_->wl_display());
|
wl_display_flush(system_->wl_display());
|
||||||
|
|
||||||
delete window_;
|
delete window_;
|
||||||
@ -1373,7 +1383,7 @@ bool GHOST_WindowWayland::outputs_changed_update_scale()
|
|||||||
{
|
{
|
||||||
#ifdef USE_EVENT_BACKGROUND_THREAD
|
#ifdef USE_EVENT_BACKGROUND_THREAD
|
||||||
if (system_->main_thread_id != std::this_thread::get_id()) {
|
if (system_->main_thread_id != std::this_thread::get_id()) {
|
||||||
gwl_window_pending_actions_tag(window_, PENDING_SCALE_UPDATE);
|
gwl_window_pending_actions_tag(window_, PENDING_OUTPUT_SCALE_UPDATE);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#include <wayland-util.h> /* For #wl_fixed_t */
|
#include <wayland-util.h> /* For #wl_fixed_t */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define to workaround for a bug/limitation in WAYLAND, see: T100855 & upstream report:
|
* Define to workaround for a bug/limitation in WAYLAND, see: #100855 & upstream report:
|
||||||
* https://gitlab.freedesktop.org/wayland/wayland/-/issues/159
|
* https://gitlab.freedesktop.org/wayland/wayland/-/issues/159
|
||||||
*
|
*
|
||||||
* Consume events from WAYLAND in a thread, this is needed because overflowing the event queue
|
* Consume events from WAYLAND in a thread, this is needed because overflowing the event queue
|
||||||
|
@ -93,7 +93,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
|
|||||||
}
|
}
|
||||||
|
|
||||||
RECT win_rect = {left, top, long(left + width), long(top + height)};
|
RECT win_rect = {left, top, long(left + width), long(top + height)};
|
||||||
adjustWindowRectForClosestMonitor(&win_rect, style, extended_style);
|
adjustWindowRectForDesktop(&win_rect, style, extended_style);
|
||||||
|
|
||||||
wchar_t *title_16 = alloc_utf16_from_8((char *)title, 0);
|
wchar_t *title_16 = alloc_utf16_from_8((char *)title, 0);
|
||||||
m_hWnd = ::CreateWindowExW(extended_style, /* window extended style */
|
m_hWnd = ::CreateWindowExW(extended_style, /* window extended style */
|
||||||
@ -154,7 +154,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (parentwindow) {
|
if (parentwindow) {
|
||||||
/* Release any parent capture to allow immediate interaction (T90110). */
|
/* Release any parent capture to allow immediate interaction (#90110). */
|
||||||
::ReleaseCapture();
|
::ReleaseCapture();
|
||||||
parentwindow->lostMouseCapture();
|
parentwindow->lostMouseCapture();
|
||||||
}
|
}
|
||||||
@ -298,24 +298,52 @@ GHOST_WindowWin32::~GHOST_WindowWin32()
|
|||||||
m_directManipulationHelper = NULL;
|
m_directManipulationHelper = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GHOST_WindowWin32::adjustWindowRectForClosestMonitor(LPRECT win_rect,
|
void GHOST_WindowWin32::adjustWindowRectForDesktop(LPRECT win_rect, DWORD dwStyle, DWORD dwExStyle)
|
||||||
DWORD dwStyle,
|
|
||||||
DWORD dwExStyle)
|
|
||||||
{
|
{
|
||||||
/* Get Details of the closest monitor. */
|
/* Windows can span multiple monitors, but must be usable. The desktop can have a larger
|
||||||
HMONITOR hmonitor = MonitorFromRect(win_rect, MONITOR_DEFAULTTONEAREST);
|
* surface than all monitors combined, for example when two monitors are aligned diagonally.
|
||||||
|
* Therefore we ensure that all the window's corners are within some monitor's Work area. */
|
||||||
|
|
||||||
|
POINT pt;
|
||||||
|
HMONITOR hmonitor;
|
||||||
MONITORINFOEX monitor;
|
MONITORINFOEX monitor;
|
||||||
monitor.cbSize = sizeof(MONITORINFOEX);
|
monitor.cbSize = sizeof(MONITORINFOEX);
|
||||||
monitor.dwFlags = 0;
|
monitor.dwFlags = 0;
|
||||||
GetMonitorInfo(hmonitor, &monitor);
|
|
||||||
|
|
||||||
/* Constrain requested size and position to fit within this monitor. */
|
/* Note that with MonitorFromPoint using MONITOR_DEFAULTTONEAREST, it will return
|
||||||
LONG width = min(monitor.rcWork.right - monitor.rcWork.left, win_rect->right - win_rect->left);
|
* the exact monitor if there is one at the location or the nearest monitor if not. */
|
||||||
LONG height = min(monitor.rcWork.bottom - monitor.rcWork.top, win_rect->bottom - win_rect->top);
|
|
||||||
win_rect->left = min(max(monitor.rcWork.left, win_rect->left), monitor.rcWork.right - width);
|
/* Top-left. */
|
||||||
win_rect->right = win_rect->left + width;
|
pt.x = win_rect->left;
|
||||||
win_rect->top = min(max(monitor.rcWork.top, win_rect->top), monitor.rcWork.bottom - height);
|
pt.y = win_rect->top;
|
||||||
win_rect->bottom = win_rect->top + height;
|
hmonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST);
|
||||||
|
GetMonitorInfo(hmonitor, &monitor);
|
||||||
|
win_rect->top = max(win_rect->top, monitor.rcWork.top);
|
||||||
|
win_rect->left = max(win_rect->left, monitor.rcWork.left);
|
||||||
|
|
||||||
|
/* Top-right. */
|
||||||
|
pt.x = win_rect->right;
|
||||||
|
pt.y = win_rect->top;
|
||||||
|
hmonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST);
|
||||||
|
GetMonitorInfo(hmonitor, &monitor);
|
||||||
|
win_rect->top = max(win_rect->top, monitor.rcWork.top);
|
||||||
|
win_rect->right = min(win_rect->right, monitor.rcWork.right);
|
||||||
|
|
||||||
|
/* Bottom-left. */
|
||||||
|
pt.x = win_rect->left;
|
||||||
|
pt.y = win_rect->bottom;
|
||||||
|
hmonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST);
|
||||||
|
GetMonitorInfo(hmonitor, &monitor);
|
||||||
|
win_rect->bottom = min(win_rect->bottom, monitor.rcWork.bottom);
|
||||||
|
win_rect->left = max(win_rect->left, monitor.rcWork.left);
|
||||||
|
|
||||||
|
/* Bottom-right. */
|
||||||
|
pt.x = win_rect->right;
|
||||||
|
pt.y = win_rect->bottom;
|
||||||
|
hmonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST);
|
||||||
|
GetMonitorInfo(hmonitor, &monitor);
|
||||||
|
win_rect->bottom = min(win_rect->bottom, monitor.rcWork.bottom);
|
||||||
|
win_rect->right = min(win_rect->right, monitor.rcWork.right);
|
||||||
|
|
||||||
/* With Windows 10 and newer we can adjust for chrome that differs with DPI and scale. */
|
/* With Windows 10 and newer we can adjust for chrome that differs with DPI and scale. */
|
||||||
GHOST_WIN32_AdjustWindowRectExForDpi fpAdjustWindowRectExForDpi = nullptr;
|
GHOST_WIN32_AdjustWindowRectExForDpi fpAdjustWindowRectExForDpi = nullptr;
|
||||||
@ -334,9 +362,6 @@ void GHOST_WindowWin32::adjustWindowRectForClosestMonitor(LPRECT win_rect,
|
|||||||
else {
|
else {
|
||||||
AdjustWindowRectEx(win_rect, dwStyle & ~WS_OVERLAPPED, FALSE, dwExStyle);
|
AdjustWindowRectEx(win_rect, dwStyle & ~WS_OVERLAPPED, FALSE, dwExStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* But never allow a top position that can hide part of the title bar. */
|
|
||||||
win_rect->top = max(monitor.rcWork.top, win_rect->top);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GHOST_WindowWin32::getValid() const
|
bool GHOST_WindowWin32::getValid() const
|
||||||
|
@ -87,12 +87,12 @@ class GHOST_WindowWin32 : public GHOST_Window {
|
|||||||
~GHOST_WindowWin32();
|
~GHOST_WindowWin32();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adjusts a requested window rect to fit and position correctly in monitor.
|
* Adjusts a requested window rect to fit and position within the desktop.
|
||||||
* \param win_rect: pointer to rectangle that will be modified.
|
* \param win_rect: pointer to rectangle that will be modified.
|
||||||
* \param dwStyle: The Window Style of the window whose required size is to be calculated.
|
* \param dwStyle: The Window Style of the window whose required size is to be calculated.
|
||||||
* \param dwExStyle: The Extended Window Style of the window.
|
* \param dwExStyle: The Extended Window Style of the window.
|
||||||
*/
|
*/
|
||||||
void adjustWindowRectForClosestMonitor(LPRECT win_rect, DWORD dwStyle, DWORD dwExStyle);
|
void adjustWindowRectForDesktop(LPRECT win_rect, DWORD dwStyle, DWORD dwExStyle);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns indication as to whether the window is valid.
|
* Returns indication as to whether the window is valid.
|
||||||
|
@ -418,7 +418,7 @@ void GHOST_WindowX11::refreshXInputDevices()
|
|||||||
for (GHOST_SystemX11::GHOST_TabletX11 &xtablet : m_system->GetXTablets()) {
|
for (GHOST_SystemX11::GHOST_TabletX11 &xtablet : m_system->GetXTablets()) {
|
||||||
/* With modern XInput (XLIB 1.6.2 at least and/or EVDEV 2.9.0) and some 'no-name' tablets
|
/* With modern XInput (XLIB 1.6.2 at least and/or EVDEV 2.9.0) and some 'no-name' tablets
|
||||||
* like 'UC-LOGIC Tablet WP5540U', we also need to 'select' ButtonPress for motion event,
|
* like 'UC-LOGIC Tablet WP5540U', we also need to 'select' ButtonPress for motion event,
|
||||||
* otherwise we do not get any tablet motion event once pen is pressed... See T43367.
|
* otherwise we do not get any tablet motion event once pen is pressed... See #43367.
|
||||||
*/
|
*/
|
||||||
XEventClass ev;
|
XEventClass ev;
|
||||||
|
|
||||||
@ -1467,7 +1467,7 @@ GHOST_TSuccess GHOST_WindowX11::setWindowCursorGrab(GHOST_TGrabCursorMode mode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform this last so to workaround XWayland bug, see: T53004. */
|
/* Perform this last so to workaround XWayland bug, see: #53004. */
|
||||||
if (m_cursorGrab == GHOST_kGrabHide) {
|
if (m_cursorGrab == GHOST_kGrabHide) {
|
||||||
setWindowCursorVisibility(true);
|
setWindowCursorVisibility(true);
|
||||||
}
|
}
|
||||||
|
@ -281,6 +281,8 @@ inline T *MEM_new(const char *allocation_name, Args &&...args)
|
|||||||
*/
|
*/
|
||||||
template<typename T> inline void MEM_delete(const T *ptr)
|
template<typename T> inline void MEM_delete(const T *ptr)
|
||||||
{
|
{
|
||||||
|
static_assert(!std::is_void_v<T>,
|
||||||
|
"MEM_delete on a void pointer not possible. Cast it to a non-void type?");
|
||||||
if (ptr == nullptr) {
|
if (ptr == nullptr) {
|
||||||
/* Support #ptr being null, because C++ `delete` supports that as well. */
|
/* Support #ptr being null, because C++ `delete` supports that as well. */
|
||||||
return;
|
return;
|
||||||
|
@ -108,7 +108,7 @@ void bl_locale_set(const char *locale)
|
|||||||
}
|
}
|
||||||
/* Extra catch on `std::runtime_error` is needed for macOS/Clang as it seems that exceptions
|
/* Extra catch on `std::runtime_error` is needed for macOS/Clang as it seems that exceptions
|
||||||
* like `boost::locale::conv::conversion_error` (which inherit from `std::runtime_error`) are
|
* like `boost::locale::conv::conversion_error` (which inherit from `std::runtime_error`) are
|
||||||
* not caught by their ancestor `std::exception`. See T88877#1177108 */
|
* not caught by their ancestor `std::exception`. See #88877#1177108 */
|
||||||
catch (std::runtime_error const &e) {
|
catch (std::runtime_error const &e) {
|
||||||
std::cout << "bl_locale_set(" << locale << "): " << e.what() << " \n";
|
std::cout << "bl_locale_set(" << locale << "): " << e.what() << " \n";
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ const char *osx_user_locale()
|
|||||||
[myNSLocale autorelease];
|
[myNSLocale autorelease];
|
||||||
|
|
||||||
// This produces gettext-invalid locale in recent macOS versions (11.4),
|
// This produces gettext-invalid locale in recent macOS versions (11.4),
|
||||||
// like `ko-Kore_KR` instead of `ko_KR`. See T88877.
|
// like `ko-Kore_KR` instead of `ko_KR`. See #88877.
|
||||||
// NSString *nsIdentifier = [myNSLocale localeIdentifier];
|
// NSString *nsIdentifier = [myNSLocale localeIdentifier];
|
||||||
|
|
||||||
const NSString *nsIdentifier = [myNSLocale languageCode];
|
const NSString *nsIdentifier = [myNSLocale languageCode];
|
||||||
|
@ -193,7 +193,7 @@ static bool createGPUShader(OCIO_GPUShader &shader,
|
|||||||
info.fragment_source("gpu_shader_display_transform_frag.glsl");
|
info.fragment_source("gpu_shader_display_transform_frag.glsl");
|
||||||
info.fragment_source_generated = source;
|
info.fragment_source_generated = source;
|
||||||
|
|
||||||
/* T96502: Work around for incorrect OCIO GLSL code generation when using
|
/* #96502: Work around for incorrect OCIO GLSL code generation when using
|
||||||
* GradingPrimaryTransform. Should be reevaluated when changing to a next version of OCIO.
|
* GradingPrimaryTransform. Should be reevaluated when changing to a next version of OCIO.
|
||||||
* (currently v2.1.1). */
|
* (currently v2.1.1). */
|
||||||
info.define("inf 1e32");
|
info.define("inf 1e32");
|
||||||
|
@ -145,7 +145,7 @@ const UserDef U_default = {
|
|||||||
.ndof_flag = (NDOF_MODE_ORBIT | NDOF_LOCK_HORIZON | NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM |
|
.ndof_flag = (NDOF_MODE_ORBIT | NDOF_LOCK_HORIZON | NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM |
|
||||||
NDOF_SHOULD_ROTATE |
|
NDOF_SHOULD_ROTATE |
|
||||||
/* Software from the driver authors follows this convention
|
/* Software from the driver authors follows this convention
|
||||||
* so invert this by default, see: T67579. */
|
* so invert this by default, see: #67579. */
|
||||||
NDOF_ROTX_INVERT_AXIS | NDOF_ROTY_INVERT_AXIS | NDOF_ROTZ_INVERT_AXIS |
|
NDOF_ROTX_INVERT_AXIS | NDOF_ROTY_INVERT_AXIS | NDOF_ROTZ_INVERT_AXIS |
|
||||||
NDOF_PANX_INVERT_AXIS | NDOF_PANY_INVERT_AXIS | NDOF_PANZ_INVERT_AXIS |
|
NDOF_PANX_INVERT_AXIS | NDOF_PANY_INVERT_AXIS | NDOF_PANZ_INVERT_AXIS |
|
||||||
NDOF_ZOOM_INVERT | NDOF_CAMERA_PAN_ZOOM),
|
NDOF_ZOOM_INVERT | NDOF_CAMERA_PAN_ZOOM),
|
||||||
|
@ -370,6 +370,7 @@ const bTheme U_theme_default = {
|
|||||||
.clipping_border_3d = RGBA(0x3f3f3fff),
|
.clipping_border_3d = RGBA(0x3f3f3fff),
|
||||||
.bundle_solid = RGBA(0xc8c8c8ff),
|
.bundle_solid = RGBA(0xc8c8c8ff),
|
||||||
.camera_path = RGBA(0x000000ff),
|
.camera_path = RGBA(0x000000ff),
|
||||||
|
.camera_passepartout = RGBA(0x000000),
|
||||||
.gp_vertex_size = 3,
|
.gp_vertex_size = 3,
|
||||||
.gp_vertex = RGBA(0x000000ff),
|
.gp_vertex = RGBA(0x000000ff),
|
||||||
.gp_vertex_select = RGBA(0xff8500ff),
|
.gp_vertex_select = RGBA(0xff8500ff),
|
||||||
|
@ -286,7 +286,7 @@ class pySketchyChainingIterator(ChainingIterator):
|
|||||||
|
|
||||||
if not found:
|
if not found:
|
||||||
# This is a fatal error condition: self.current_edge must be found
|
# This is a fatal error condition: self.current_edge must be found
|
||||||
# among the edges seen by the AdjacencyIterator [bug T35695].
|
# among the edges seen by the AdjacencyIterator [bug #35695].
|
||||||
if bpy.app.debug_freestyle:
|
if bpy.app.debug_freestyle:
|
||||||
print('pySketchyChainingIterator: current edge not found')
|
print('pySketchyChainingIterator: current edge not found')
|
||||||
return None
|
return None
|
||||||
|
@ -113,7 +113,7 @@ def expand(line, cursor, namespace, *, private=True):
|
|||||||
if len(matches) == 1:
|
if len(matches) == 1:
|
||||||
scrollback = ''
|
scrollback = ''
|
||||||
else:
|
else:
|
||||||
# causes blender bug T27495 since string keys may contain '.'
|
# causes blender bug #27495 since string keys may contain '.'
|
||||||
# scrollback = ' '.join([m.split('.')[-1] for m in matches])
|
# scrollback = ' '.join([m.split('.')[-1] for m in matches])
|
||||||
|
|
||||||
# add white space to align with the cursor
|
# add white space to align with the cursor
|
||||||
|
@ -30,7 +30,7 @@ def url_prefill_from_blender(*, addon_info=None):
|
|||||||
"**Blender Version**\n"
|
"**Blender Version**\n"
|
||||||
)
|
)
|
||||||
fh.write(
|
fh.write(
|
||||||
"Broken: version: %s, branch: %s, commit date: %s %s, hash: `rB%s`\n" % (
|
"Broken: version: %s, branch: %s, commit date: %s %s, hash: `%s`\n" % (
|
||||||
bpy.app.version_string,
|
bpy.app.version_string,
|
||||||
bpy.app.build_branch.decode('utf-8', 'replace'),
|
bpy.app.build_branch.decode('utf-8', 'replace'),
|
||||||
bpy.app.build_commit_date.decode('utf-8', 'replace'),
|
bpy.app.build_commit_date.decode('utf-8', 'replace'),
|
||||||
|
@ -32,7 +32,7 @@ class _BPyOpsSubModOp:
|
|||||||
# XXX You never quite know what you get from bpy.types,
|
# XXX You never quite know what you get from bpy.types,
|
||||||
# with operators... Operator and OperatorProperties
|
# with operators... Operator and OperatorProperties
|
||||||
# are shadowing each other, and not in the same way for
|
# are shadowing each other, and not in the same way for
|
||||||
# native ops and py ones! See T39158.
|
# native ops and py ones! See #39158.
|
||||||
# op_class = getattr(bpy.types, idname)
|
# op_class = getattr(bpy.types, idname)
|
||||||
op_class = _op_get_rna_type(idname)
|
op_class = _op_get_rna_type(idname)
|
||||||
descr = op_class.description
|
descr = op_class.description
|
||||||
|
@ -259,15 +259,15 @@ def bake_action_iter(
|
|||||||
if is_new_action:
|
if is_new_action:
|
||||||
action = bpy.data.actions.new("Action")
|
action = bpy.data.actions.new("Action")
|
||||||
|
|
||||||
# Only leave tweak mode if we actually need to modify the action (T57159)
|
# Only leave tweak mode if we actually need to modify the action (#57159)
|
||||||
if action != atd.action:
|
if action != atd.action:
|
||||||
# Leave tweak mode before trying to modify the action (T48397)
|
# Leave tweak mode before trying to modify the action (#48397)
|
||||||
if atd.use_tweak_mode:
|
if atd.use_tweak_mode:
|
||||||
atd.use_tweak_mode = False
|
atd.use_tweak_mode = False
|
||||||
|
|
||||||
atd.action = action
|
atd.action = action
|
||||||
|
|
||||||
# Baking the action only makes sense in Replace mode, so force it (T69105)
|
# Baking the action only makes sense in Replace mode, so force it (#69105)
|
||||||
if not atd.use_tweak_mode:
|
if not atd.use_tweak_mode:
|
||||||
atd.action_blend_type = 'REPLACE'
|
atd.action_blend_type = 'REPLACE'
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ def orientation_helper(axis_forward='Y', axis_up='Z'):
|
|||||||
"""
|
"""
|
||||||
def wrapper(cls):
|
def wrapper(cls):
|
||||||
# Without that, we may end up adding those fields to some **parent** class' __annotations__ property
|
# Without that, we may end up adding those fields to some **parent** class' __annotations__ property
|
||||||
# (like the ImportHelper or ExportHelper ones)! See T58772.
|
# (like the ImportHelper or ExportHelper ones)! See #58772.
|
||||||
if "__annotations__" not in cls.__dict__:
|
if "__annotations__" not in cls.__dict__:
|
||||||
setattr(cls, "__annotations__", {})
|
setattr(cls, "__annotations__", {})
|
||||||
|
|
||||||
|
@ -564,7 +564,7 @@ class Mesh(bpy_types.ID):
|
|||||||
|
|
||||||
face_lengths = tuple(map(len, faces))
|
face_lengths = tuple(map(len, faces))
|
||||||
|
|
||||||
# NOTE: check non-empty lists by length because of how `numpy` handles truth tests, see: T90268.
|
# NOTE: check non-empty lists by length because of how `numpy` handles truth tests, see: #90268.
|
||||||
vertices_len = len(vertices)
|
vertices_len = len(vertices)
|
||||||
edges_len = len(edges)
|
edges_len = len(edges)
|
||||||
faces_len = len(faces)
|
faces_len = len(faces)
|
||||||
|
@ -991,6 +991,7 @@ url_manual_mapping = (
|
|||||||
("bpy.types.geometrynodeinputmeshfacearea*", "modeling/geometry_nodes/mesh/read/face_area.html#bpy-types-geometrynodeinputmeshfacearea"),
|
("bpy.types.geometrynodeinputmeshfacearea*", "modeling/geometry_nodes/mesh/read/face_area.html#bpy-types-geometrynodeinputmeshfacearea"),
|
||||||
("bpy.types.geometrynodeinputsplinecyclic*", "modeling/geometry_nodes/curve/read/is_spline_cyclic.html#bpy-types-geometrynodeinputsplinecyclic"),
|
("bpy.types.geometrynodeinputsplinecyclic*", "modeling/geometry_nodes/curve/read/is_spline_cyclic.html#bpy-types-geometrynodeinputsplinecyclic"),
|
||||||
("bpy.types.geometrynodeinstancestopoints*", "modeling/geometry_nodes/instances/instances_to_points.html#bpy-types-geometrynodeinstancestopoints"),
|
("bpy.types.geometrynodeinstancestopoints*", "modeling/geometry_nodes/instances/instances_to_points.html#bpy-types-geometrynodeinstancestopoints"),
|
||||||
|
("bpy.types.geometrynodematerialselection*", "modeling/geometry_nodes/material/material_selection.html#bpy-types-geometrynodematerialselection"),
|
||||||
("bpy.types.gpencillayer.viewlayer_render*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-viewlayer-render"),
|
("bpy.types.gpencillayer.viewlayer_render*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-viewlayer-render"),
|
||||||
("bpy.types.imagepaint.use_normal_falloff*", "sculpt_paint/brush/falloff.html#bpy-types-imagepaint-use-normal-falloff"),
|
("bpy.types.imagepaint.use_normal_falloff*", "sculpt_paint/brush/falloff.html#bpy-types-imagepaint-use-normal-falloff"),
|
||||||
("bpy.types.layercollection.hide_viewport*", "editors/outliner/interface.html#bpy-types-layercollection-hide-viewport"),
|
("bpy.types.layercollection.hide_viewport*", "editors/outliner/interface.html#bpy-types-layercollection-hide-viewport"),
|
||||||
@ -2027,6 +2028,7 @@ url_manual_mapping = (
|
|||||||
("bpy.ops.graph.equalize_handles*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-equalize-handles"),
|
("bpy.ops.graph.equalize_handles*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-equalize-handles"),
|
||||||
("bpy.ops.mball.delete_metaelems*", "modeling/metas/editing.html#bpy-ops-mball-delete-metaelems"),
|
("bpy.ops.mball.delete_metaelems*", "modeling/metas/editing.html#bpy-ops-mball-delete-metaelems"),
|
||||||
("bpy.ops.mball.reveal_metaelems*", "modeling/metas/properties.html#bpy-ops-mball-reveal-metaelems"),
|
("bpy.ops.mball.reveal_metaelems*", "modeling/metas/properties.html#bpy-ops-mball-reveal-metaelems"),
|
||||||
|
("bpy.ops.mesh.bridge_edge_loops*", "modeling/meshes/editing/edge/bridge_edge_loops.html#bpy-ops-mesh-bridge-edge-loops"),
|
||||||
("bpy.ops.mesh.intersect_boolean*", "modeling/meshes/editing/face/intersect_boolean.html#bpy-ops-mesh-intersect-boolean"),
|
("bpy.ops.mesh.intersect_boolean*", "modeling/meshes/editing/face/intersect_boolean.html#bpy-ops-mesh-intersect-boolean"),
|
||||||
("bpy.ops.mesh.loop_multi_select*", "modeling/meshes/selecting/loops.html#bpy-ops-mesh-loop-multi-select"),
|
("bpy.ops.mesh.loop_multi_select*", "modeling/meshes/selecting/loops.html#bpy-ops-mesh-loop-multi-select"),
|
||||||
("bpy.ops.mesh.vert_connect_path*", "modeling/meshes/editing/vertex/connect_vertex_path.html#bpy-ops-mesh-vert-connect-path"),
|
("bpy.ops.mesh.vert_connect_path*", "modeling/meshes/editing/vertex/connect_vertex_path.html#bpy-ops-mesh-vert-connect-path"),
|
||||||
@ -3021,6 +3023,7 @@ url_manual_mapping = (
|
|||||||
("bpy.types.bakesettings*", "render/cycles/baking.html#bpy-types-bakesettings"),
|
("bpy.types.bakesettings*", "render/cycles/baking.html#bpy-types-bakesettings"),
|
||||||
("bpy.types.blendtexture*", "render/materials/legacy_textures/types/blend.html#bpy-types-blendtexture"),
|
("bpy.types.blendtexture*", "render/materials/legacy_textures/types/blend.html#bpy-types-blendtexture"),
|
||||||
("bpy.types.brush.height*", "sculpt_paint/sculpting/tools/layer.html#bpy-types-brush-height"),
|
("bpy.types.brush.height*", "sculpt_paint/sculpting/tools/layer.html#bpy-types-brush-height"),
|
||||||
|
("bpy.types.brush.jitter*", "sculpt_paint/brush/stroke.html#bpy-types-brush-jitter"),
|
||||||
("bpy.types.castmodifier*", "modeling/modifiers/deform/cast.html#bpy-types-castmodifier"),
|
("bpy.types.castmodifier*", "modeling/modifiers/deform/cast.html#bpy-types-castmodifier"),
|
||||||
("bpy.types.curve.offset*", "modeling/curves/properties/geometry.html#bpy-types-curve-offset"),
|
("bpy.types.curve.offset*", "modeling/curves/properties/geometry.html#bpy-types-curve-offset"),
|
||||||
("bpy.types.geometrynode*", "modeling/geometry_nodes/index.html#bpy-types-geometrynode"),
|
("bpy.types.geometrynode*", "modeling/geometry_nodes/index.html#bpy-types-geometrynode"),
|
||||||
|
@ -29,11 +29,11 @@
|
|||||||
icon_modifier="#84b8ffff"
|
icon_modifier="#84b8ffff"
|
||||||
icon_shading="#ea7581ff"
|
icon_shading="#ea7581ff"
|
||||||
icon_folder="#e3c16eff"
|
icon_folder="#e3c16eff"
|
||||||
icon_border_intensity="0.85"
|
icon_border_intensity="1"
|
||||||
>
|
>
|
||||||
<wcol_regular>
|
<wcol_regular>
|
||||||
<ThemeWidgetColors
|
<ThemeWidgetColors
|
||||||
outline="#b8b8b8"
|
outline="#4d4d4d"
|
||||||
inner="#dbdbdbff"
|
inner="#dbdbdbff"
|
||||||
inner_sel="#668cccff"
|
inner_sel="#668cccff"
|
||||||
item="#191919ff"
|
item="#191919ff"
|
||||||
@ -48,7 +48,7 @@
|
|||||||
</wcol_regular>
|
</wcol_regular>
|
||||||
<wcol_tool>
|
<wcol_tool>
|
||||||
<ThemeWidgetColors
|
<ThemeWidgetColors
|
||||||
outline="#b8b8b8"
|
outline="#4d4d4d"
|
||||||
inner="#dbdbdbff"
|
inner="#dbdbdbff"
|
||||||
inner_sel="#5680c2ff"
|
inner_sel="#5680c2ff"
|
||||||
item="#191919ff"
|
item="#191919ff"
|
||||||
@ -63,7 +63,7 @@
|
|||||||
</wcol_tool>
|
</wcol_tool>
|
||||||
<wcol_toolbar_item>
|
<wcol_toolbar_item>
|
||||||
<ThemeWidgetColors
|
<ThemeWidgetColors
|
||||||
outline="#363636"
|
outline="#4d4d4d"
|
||||||
inner="#434343ff"
|
inner="#434343ff"
|
||||||
inner_sel="#5680c2ff"
|
inner_sel="#5680c2ff"
|
||||||
item="#e6e6e6cc"
|
item="#e6e6e6cc"
|
||||||
@ -78,7 +78,7 @@
|
|||||||
</wcol_toolbar_item>
|
</wcol_toolbar_item>
|
||||||
<wcol_radio>
|
<wcol_radio>
|
||||||
<ThemeWidgetColors
|
<ThemeWidgetColors
|
||||||
outline="#434343"
|
outline="#4d4d4d"
|
||||||
inner="#3b3b3bff"
|
inner="#3b3b3bff"
|
||||||
inner_sel="#5680c2e6"
|
inner_sel="#5680c2e6"
|
||||||
item="#ffffffff"
|
item="#ffffffff"
|
||||||
@ -93,7 +93,7 @@
|
|||||||
</wcol_radio>
|
</wcol_radio>
|
||||||
<wcol_text>
|
<wcol_text>
|
||||||
<ThemeWidgetColors
|
<ThemeWidgetColors
|
||||||
outline="#666666"
|
outline="#4d4d4d"
|
||||||
inner="#282828ff"
|
inner="#282828ff"
|
||||||
inner_sel="#333333ff"
|
inner_sel="#333333ff"
|
||||||
item="#5680c2ff"
|
item="#5680c2ff"
|
||||||
@ -108,7 +108,7 @@
|
|||||||
</wcol_text>
|
</wcol_text>
|
||||||
<wcol_option>
|
<wcol_option>
|
||||||
<ThemeWidgetColors
|
<ThemeWidgetColors
|
||||||
outline="#373737"
|
outline="#4d4d4d"
|
||||||
inner="#3c3c3cff"
|
inner="#3c3c3cff"
|
||||||
inner_sel="#5680c2ff"
|
inner_sel="#5680c2ff"
|
||||||
item="#ffffffff"
|
item="#ffffffff"
|
||||||
@ -123,8 +123,8 @@
|
|||||||
</wcol_option>
|
</wcol_option>
|
||||||
<wcol_toggle>
|
<wcol_toggle>
|
||||||
<ThemeWidgetColors
|
<ThemeWidgetColors
|
||||||
outline="#999999"
|
outline="#4d4d4d"
|
||||||
inner="#c0c0c0ff"
|
inner="#dbdbdbff"
|
||||||
inner_sel="#5680c2ff"
|
inner_sel="#5680c2ff"
|
||||||
item="#191919ff"
|
item="#191919ff"
|
||||||
text="#000000"
|
text="#000000"
|
||||||
@ -138,7 +138,7 @@
|
|||||||
</wcol_toggle>
|
</wcol_toggle>
|
||||||
<wcol_num>
|
<wcol_num>
|
||||||
<ThemeWidgetColors
|
<ThemeWidgetColors
|
||||||
outline="#b8b8b8"
|
outline="#4d4d4d"
|
||||||
inner="#d3d3d3ff"
|
inner="#d3d3d3ff"
|
||||||
inner_sel="#5680c2ff"
|
inner_sel="#5680c2ff"
|
||||||
item="#80b1ffff"
|
item="#80b1ffff"
|
||||||
@ -153,7 +153,7 @@
|
|||||||
</wcol_num>
|
</wcol_num>
|
||||||
<wcol_numslider>
|
<wcol_numslider>
|
||||||
<ThemeWidgetColors
|
<ThemeWidgetColors
|
||||||
outline="#b8b8b8"
|
outline="#4d4d4d"
|
||||||
inner="#999999ff"
|
inner="#999999ff"
|
||||||
inner_sel="#999999ff"
|
inner_sel="#999999ff"
|
||||||
item="#e6e6e6ff"
|
item="#e6e6e6ff"
|
||||||
@ -168,8 +168,8 @@
|
|||||||
</wcol_numslider>
|
</wcol_numslider>
|
||||||
<wcol_box>
|
<wcol_box>
|
||||||
<ThemeWidgetColors
|
<ThemeWidgetColors
|
||||||
outline="#959595"
|
outline="#4d4d4d"
|
||||||
inner="#cccccc80"
|
inner="#80808080"
|
||||||
inner_sel="#5680c2ff"
|
inner_sel="#5680c2ff"
|
||||||
item="#191919ff"
|
item="#191919ff"
|
||||||
text="#333333"
|
text="#333333"
|
||||||
@ -183,7 +183,7 @@
|
|||||||
</wcol_box>
|
</wcol_box>
|
||||||
<wcol_menu>
|
<wcol_menu>
|
||||||
<ThemeWidgetColors
|
<ThemeWidgetColors
|
||||||
outline="#3b3b3b"
|
outline="#3d3d3d"
|
||||||
inner="#3b3b3bff"
|
inner="#3b3b3bff"
|
||||||
inner_sel="#767676ff"
|
inner_sel="#767676ff"
|
||||||
item="#808080ff"
|
item="#808080ff"
|
||||||
@ -217,7 +217,7 @@
|
|||||||
inner="#c0c0c0ff"
|
inner="#c0c0c0ff"
|
||||||
inner_sel="#cdcdcdff"
|
inner_sel="#cdcdcdff"
|
||||||
item="#727272ff"
|
item="#727272ff"
|
||||||
text="#1a1a1a"
|
text="#4d4d4d"
|
||||||
text_sel="#1a1a1a"
|
text_sel="#1a1a1a"
|
||||||
show_shaded="FALSE"
|
show_shaded="FALSE"
|
||||||
shadetop="25"
|
shadetop="25"
|
||||||
@ -304,11 +304,11 @@
|
|||||||
<wcol_list_item>
|
<wcol_list_item>
|
||||||
<ThemeWidgetColors
|
<ThemeWidgetColors
|
||||||
outline="#e6e6e6"
|
outline="#e6e6e6"
|
||||||
inner="#00000000"
|
inner="#1a1a1a00"
|
||||||
inner_sel="#808080ff"
|
inner_sel="#c0c0c0ff"
|
||||||
item="#1a1a1aff"
|
item="#1a1a1aff"
|
||||||
text="#1a1a1a"
|
text="#1a1a1a"
|
||||||
text_sel="#ffffff"
|
text_sel="#000000"
|
||||||
show_shaded="FALSE"
|
show_shaded="FALSE"
|
||||||
shadetop="0"
|
shadetop="0"
|
||||||
shadedown="0"
|
shadedown="0"
|
||||||
@ -316,6 +316,21 @@
|
|||||||
>
|
>
|
||||||
</ThemeWidgetColors>
|
</ThemeWidgetColors>
|
||||||
</wcol_list_item>
|
</wcol_list_item>
|
||||||
|
<wcol_view_item>
|
||||||
|
<ThemeWidgetColors
|
||||||
|
outline="#e6e6e6"
|
||||||
|
inner="#c0c0c044"
|
||||||
|
inner_sel="#c0c0c0ff"
|
||||||
|
item="#1a1a1aff"
|
||||||
|
text="#1a1a1a"
|
||||||
|
text_sel="#000000"
|
||||||
|
show_shaded="FALSE"
|
||||||
|
shadetop="0"
|
||||||
|
shadedown="0"
|
||||||
|
roundness="0.4"
|
||||||
|
>
|
||||||
|
</ThemeWidgetColors>
|
||||||
|
</wcol_view_item>
|
||||||
<wcol_state>
|
<wcol_state>
|
||||||
<ThemeWidgetStateColors
|
<ThemeWidgetStateColors
|
||||||
inner_anim="#73be4c"
|
inner_anim="#73be4c"
|
||||||
@ -334,8 +349,8 @@
|
|||||||
</wcol_state>
|
</wcol_state>
|
||||||
<wcol_tab>
|
<wcol_tab>
|
||||||
<ThemeWidgetColors
|
<ThemeWidgetColors
|
||||||
outline="#656565"
|
outline="#333333"
|
||||||
inner="#818181ff"
|
inner="#808080cc"
|
||||||
inner_sel="#b3b3b3ff"
|
inner_sel="#b3b3b3ff"
|
||||||
item="#28292dff"
|
item="#28292dff"
|
||||||
text="#1a1a1a"
|
text="#1a1a1a"
|
||||||
@ -414,6 +429,7 @@
|
|||||||
bone_locked_weight="#ff000080"
|
bone_locked_weight="#ff000080"
|
||||||
bundle_solid="#c8c8c8"
|
bundle_solid="#c8c8c8"
|
||||||
camera_path="#000000"
|
camera_path="#000000"
|
||||||
|
camera_passepartout="#000000"
|
||||||
skin_root="#b44d4d"
|
skin_root="#b44d4d"
|
||||||
view_overlay="#000000"
|
view_overlay="#000000"
|
||||||
transform="#ffffff"
|
transform="#ffffff"
|
||||||
@ -452,9 +468,9 @@
|
|||||||
</gradients>
|
</gradients>
|
||||||
<panelcolors>
|
<panelcolors>
|
||||||
<ThemePanelColors
|
<ThemePanelColors
|
||||||
header="#b3b3b3ff"
|
header="#ccccccff"
|
||||||
back="#b3b3b3cc"
|
back="#ccccccff"
|
||||||
sub_back="#00000024"
|
sub_back="#0000000f"
|
||||||
>
|
>
|
||||||
</ThemePanelColors>
|
</ThemePanelColors>
|
||||||
</panelcolors>
|
</panelcolors>
|
||||||
@ -519,9 +535,9 @@
|
|||||||
>
|
>
|
||||||
<panelcolors>
|
<panelcolors>
|
||||||
<ThemePanelColors
|
<ThemePanelColors
|
||||||
header="#42424200"
|
header="#ccccccff"
|
||||||
back="#00000028"
|
back="#ccccccff"
|
||||||
sub_back="#00000024"
|
sub_back="#0000000f"
|
||||||
>
|
>
|
||||||
</ThemePanelColors>
|
</ThemePanelColors>
|
||||||
</panelcolors>
|
</panelcolors>
|
||||||
@ -552,7 +568,7 @@
|
|||||||
header="#adadadff"
|
header="#adadadff"
|
||||||
header_text="#000000"
|
header_text="#000000"
|
||||||
header_text_hi="#ffffff"
|
header_text_hi="#ffffff"
|
||||||
button="#999999e6"
|
button="#b3b3b3ff"
|
||||||
button_title="#1a1a1a"
|
button_title="#1a1a1a"
|
||||||
button_text="#000000"
|
button_text="#000000"
|
||||||
button_text_hi="#000000"
|
button_text_hi="#000000"
|
||||||
@ -565,9 +581,9 @@
|
|||||||
>
|
>
|
||||||
<panelcolors>
|
<panelcolors>
|
||||||
<ThemePanelColors
|
<ThemePanelColors
|
||||||
header="#42424200"
|
header="#ccccccff"
|
||||||
back="#00000028"
|
back="#ccccccff"
|
||||||
sub_back="#00000024"
|
sub_back="#0000000f"
|
||||||
>
|
>
|
||||||
</ThemePanelColors>
|
</ThemePanelColors>
|
||||||
</panelcolors>
|
</panelcolors>
|
||||||
@ -623,9 +639,9 @@
|
|||||||
>
|
>
|
||||||
<panelcolors>
|
<panelcolors>
|
||||||
<ThemePanelColors
|
<ThemePanelColors
|
||||||
header="#42424200"
|
header="#ccccccff"
|
||||||
back="#00000028"
|
back="#ccccccff"
|
||||||
sub_back="#00000024"
|
sub_back="#0000000f"
|
||||||
>
|
>
|
||||||
</ThemePanelColors>
|
</ThemePanelColors>
|
||||||
</panelcolors>
|
</panelcolors>
|
||||||
@ -698,9 +714,9 @@
|
|||||||
>
|
>
|
||||||
<panelcolors>
|
<panelcolors>
|
||||||
<ThemePanelColors
|
<ThemePanelColors
|
||||||
header="#42424200"
|
header="#ccccccff"
|
||||||
back="#00000028"
|
back="#ccccccff"
|
||||||
sub_back="#00000024"
|
sub_back="#0000000f"
|
||||||
>
|
>
|
||||||
</ThemePanelColors>
|
</ThemePanelColors>
|
||||||
</panelcolors>
|
</panelcolors>
|
||||||
@ -783,9 +799,9 @@
|
|||||||
>
|
>
|
||||||
<panelcolors>
|
<panelcolors>
|
||||||
<ThemePanelColors
|
<ThemePanelColors
|
||||||
header="#b3b3b3ff"
|
header="#ccccccff"
|
||||||
back="#b3b3b3cc"
|
back="#ccccccff"
|
||||||
sub_back="#00000024"
|
sub_back="#0000000f"
|
||||||
>
|
>
|
||||||
</ThemePanelColors>
|
</ThemePanelColors>
|
||||||
</panelcolors>
|
</panelcolors>
|
||||||
@ -843,14 +859,23 @@
|
|||||||
>
|
>
|
||||||
<panelcolors>
|
<panelcolors>
|
||||||
<ThemePanelColors
|
<ThemePanelColors
|
||||||
header="#b3b3b3ff"
|
header="#ccccccff"
|
||||||
back="#b3b3b3cc"
|
back="#ccccccff"
|
||||||
sub_back="#00000024"
|
sub_back="#0000000f"
|
||||||
>
|
>
|
||||||
</ThemePanelColors>
|
</ThemePanelColors>
|
||||||
</panelcolors>
|
</panelcolors>
|
||||||
</ThemeSpaceGeneric>
|
</ThemeSpaceGeneric>
|
||||||
</space>
|
</space>
|
||||||
|
<space_list>
|
||||||
|
<ThemeSpaceListGeneric
|
||||||
|
list="#181818"
|
||||||
|
list_title="#ffffff"
|
||||||
|
list_text="#ffffff"
|
||||||
|
list_text_hi="#ffffff"
|
||||||
|
>
|
||||||
|
</ThemeSpaceListGeneric>
|
||||||
|
</space_list>
|
||||||
</ThemeSequenceEditor>
|
</ThemeSequenceEditor>
|
||||||
</sequence_editor>
|
</sequence_editor>
|
||||||
<properties>
|
<properties>
|
||||||
@ -871,7 +896,7 @@
|
|||||||
button_title="#000000"
|
button_title="#000000"
|
||||||
button_text="#000000"
|
button_text="#000000"
|
||||||
button_text_hi="#000000"
|
button_text_hi="#000000"
|
||||||
navigation_bar="#656565ff"
|
navigation_bar="#1d1d1dff"
|
||||||
execution_buts="#00000000"
|
execution_buts="#00000000"
|
||||||
tab_active="#6697e6"
|
tab_active="#6697e6"
|
||||||
tab_inactive="#535353"
|
tab_inactive="#535353"
|
||||||
@ -880,9 +905,9 @@
|
|||||||
>
|
>
|
||||||
<panelcolors>
|
<panelcolors>
|
||||||
<ThemePanelColors
|
<ThemePanelColors
|
||||||
header="#b3b3b300"
|
header="#ccccccff"
|
||||||
back="#a3a3a3cc"
|
back="#ccccccff"
|
||||||
sub_back="#00000024"
|
sub_back="#0000000f"
|
||||||
>
|
>
|
||||||
</ThemePanelColors>
|
</ThemePanelColors>
|
||||||
</panelcolors>
|
</panelcolors>
|
||||||
@ -927,9 +952,9 @@
|
|||||||
>
|
>
|
||||||
<panelcolors>
|
<panelcolors>
|
||||||
<ThemePanelColors
|
<ThemePanelColors
|
||||||
header="#42424200"
|
header="#ccccccff"
|
||||||
back="#00000028"
|
back="#ccccccff"
|
||||||
sub_back="#00000024"
|
sub_back="#0000000f"
|
||||||
>
|
>
|
||||||
</ThemePanelColors>
|
</ThemePanelColors>
|
||||||
</panelcolors>
|
</panelcolors>
|
||||||
@ -939,44 +964,44 @@
|
|||||||
</text_editor>
|
</text_editor>
|
||||||
<node_editor>
|
<node_editor>
|
||||||
<ThemeNodeEditor
|
<ThemeNodeEditor
|
||||||
grid="#1B1B1B"
|
grid="#282828"
|
||||||
node_selected="#f15800"
|
node_selected="#ed5700"
|
||||||
node_active="#f15800"
|
node_active="#ffffff"
|
||||||
wire="#191919"
|
wire="#1a1a1aff"
|
||||||
wire_inner="#999999"
|
wire_inner="#8d8d8d"
|
||||||
wire_select="#ffa733"
|
wire_select="#ffffffb3"
|
||||||
selected_text="#7f7070"
|
selected_text="#7f7f7f"
|
||||||
node_backdrop="#e6e6e6ff"
|
node_backdrop="#666666ff"
|
||||||
converter_node="#66c4ff"
|
converter_node="#12adff"
|
||||||
color_node="#ffcb4d"
|
color_node="#cccc00"
|
||||||
group_node="#59b36ab9"
|
group_node="#3b660a"
|
||||||
group_socket_node="#dfc300"
|
group_socket_node="#000000"
|
||||||
frame_node="#9b9b9b60"
|
frame_node="#0f0f0fcc"
|
||||||
matte_node="#977474"
|
matte_node="#973c3c"
|
||||||
distor_node="#749797"
|
distor_node="#4c9797"
|
||||||
noodle_curving="4"
|
noodle_curving="4"
|
||||||
grid_levels="3"
|
grid_levels="3"
|
||||||
dash_alpha="0.5"
|
dash_alpha="0.5"
|
||||||
input_node="#cb3d4a"
|
input_node="#ff3371"
|
||||||
output_node="#cb3d4a"
|
output_node="#4d0017"
|
||||||
filter_node="#6c696f"
|
filter_node="#551a80"
|
||||||
vector_node="#9999ff"
|
vector_node="#4d4dff"
|
||||||
texture_node="#ffc399"
|
texture_node="#e66800"
|
||||||
shader_node="#ea7581"
|
shader_node="#24b524"
|
||||||
script_node="#6c696f"
|
script_node="#084d4d"
|
||||||
pattern_node="#6c696f"
|
pattern_node="#6c696f"
|
||||||
layout_node="#6c696f"
|
layout_node="#6c696f"
|
||||||
geometry_node="#00d7a4"
|
geometry_node="#00d6a3"
|
||||||
attribute_node="#3f5980"
|
attribute_node="#001566"
|
||||||
>
|
>
|
||||||
<space>
|
<space>
|
||||||
<ThemeSpaceGeneric
|
<ThemeSpaceGeneric
|
||||||
back="#353535"
|
back="#1d1d1d"
|
||||||
title="#000000"
|
title="#eeeeee"
|
||||||
text="#000000"
|
text="#e6e6e6"
|
||||||
text_hi="#ffffff"
|
text_hi="#ffffff"
|
||||||
header="#b3b3b3ff"
|
header="#b3b3b3ff"
|
||||||
header_text="#000000"
|
header_text="#eeeeee"
|
||||||
header_text_hi="#ffffff"
|
header_text_hi="#ffffff"
|
||||||
button="#99999900"
|
button="#99999900"
|
||||||
button_title="#1a1a1a"
|
button_title="#1a1a1a"
|
||||||
@ -991,9 +1016,9 @@
|
|||||||
>
|
>
|
||||||
<panelcolors>
|
<panelcolors>
|
||||||
<ThemePanelColors
|
<ThemePanelColors
|
||||||
header="#b3b3b3ff"
|
header="#ccccccff"
|
||||||
back="#b3b3b3cc"
|
back="#ccccccff"
|
||||||
sub_back="#00000024"
|
sub_back="#0000000f"
|
||||||
>
|
>
|
||||||
</ThemePanelColors>
|
</ThemePanelColors>
|
||||||
</panelcolors>
|
</panelcolors>
|
||||||
@ -1013,8 +1038,8 @@
|
|||||||
<outliner>
|
<outliner>
|
||||||
<ThemeOutliner
|
<ThemeOutliner
|
||||||
match="#337f33"
|
match="#337f33"
|
||||||
selected_highlight="#7a8e99"
|
selected_highlight="#7a8499"
|
||||||
active="#92aab7"
|
active="#929eb7"
|
||||||
selected_object="#ffddb3"
|
selected_object="#ffddb3"
|
||||||
active_object="#ffffff"
|
active_object="#ffffff"
|
||||||
edited_object="#0080624d"
|
edited_object="#0080624d"
|
||||||
@ -1042,9 +1067,9 @@
|
|||||||
>
|
>
|
||||||
<panelcolors>
|
<panelcolors>
|
||||||
<ThemePanelColors
|
<ThemePanelColors
|
||||||
header="#42424200"
|
header="#ccccccff"
|
||||||
back="#00000028"
|
back="#ccccccff"
|
||||||
sub_back="#00000024"
|
sub_back="#0000000f"
|
||||||
>
|
>
|
||||||
</ThemePanelColors>
|
</ThemePanelColors>
|
||||||
</panelcolors>
|
</panelcolors>
|
||||||
@ -1091,9 +1116,9 @@
|
|||||||
>
|
>
|
||||||
<panelcolors>
|
<panelcolors>
|
||||||
<ThemePanelColors
|
<ThemePanelColors
|
||||||
header="#42424200"
|
header="#ccccccff"
|
||||||
back="#00000028"
|
back="#ccccccff"
|
||||||
sub_back="#00000024"
|
sub_back="#0000000f"
|
||||||
>
|
>
|
||||||
</ThemePanelColors>
|
</ThemePanelColors>
|
||||||
</panelcolors>
|
</panelcolors>
|
||||||
@ -1125,9 +1150,9 @@
|
|||||||
>
|
>
|
||||||
<panelcolors>
|
<panelcolors>
|
||||||
<ThemePanelColors
|
<ThemePanelColors
|
||||||
header="#b3b3b300"
|
header="#ccccccff"
|
||||||
back="#a3a3a3cc"
|
back="#ccccccff"
|
||||||
sub_back="#00000024"
|
sub_back="#0000000f"
|
||||||
>
|
>
|
||||||
</ThemePanelColors>
|
</ThemePanelColors>
|
||||||
</panelcolors>
|
</panelcolors>
|
||||||
@ -1137,26 +1162,26 @@
|
|||||||
</preferences>
|
</preferences>
|
||||||
<console>
|
<console>
|
||||||
<ThemeConsole
|
<ThemeConsole
|
||||||
line_output="#6080ff"
|
line_output="#71a8ff"
|
||||||
line_input="#ffffff"
|
line_input="#f2f2f2"
|
||||||
line_info="#00aa00"
|
line_info="#95d600"
|
||||||
line_error="#dc6060"
|
line_error="#ff4d84"
|
||||||
cursor="#dc6060"
|
cursor="#ff0000"
|
||||||
select="#ffffff30"
|
select="#ffffff30"
|
||||||
>
|
>
|
||||||
<space>
|
<space>
|
||||||
<ThemeSpaceGeneric
|
<ThemeSpaceGeneric
|
||||||
back="#000000"
|
back="#1d1d1d"
|
||||||
title="#000000"
|
title="#eeeeee"
|
||||||
text="#000000"
|
text="#e6e6e6"
|
||||||
text_hi="#ffffff"
|
text_hi="#ffffff"
|
||||||
header="#b3b3b3ff"
|
header="#b3b3b3ff"
|
||||||
header_text="#000000"
|
header_text="#000000"
|
||||||
header_text_hi="#ffffff"
|
header_text_hi="#ffffff"
|
||||||
button="#7272727f"
|
button="#30303000"
|
||||||
button_title="#000000"
|
button_title="#ffffff"
|
||||||
button_text="#000000"
|
button_text="#cccccc"
|
||||||
button_text_hi="#000000"
|
button_text_hi="#ffffff"
|
||||||
navigation_bar="#00000000"
|
navigation_bar="#00000000"
|
||||||
execution_buts="#00000000"
|
execution_buts="#00000000"
|
||||||
tab_active="#6697e6"
|
tab_active="#6697e6"
|
||||||
@ -1166,9 +1191,9 @@
|
|||||||
>
|
>
|
||||||
<panelcolors>
|
<panelcolors>
|
||||||
<ThemePanelColors
|
<ThemePanelColors
|
||||||
header="#42424200"
|
header="#ccccccff"
|
||||||
back="#00000028"
|
back="#ccccccff"
|
||||||
sub_back="#00000024"
|
sub_back="#0000000f"
|
||||||
>
|
>
|
||||||
</ThemePanelColors>
|
</ThemePanelColors>
|
||||||
</panelcolors>
|
</panelcolors>
|
||||||
@ -1231,9 +1256,9 @@
|
|||||||
>
|
>
|
||||||
<panelcolors>
|
<panelcolors>
|
||||||
<ThemePanelColors
|
<ThemePanelColors
|
||||||
header="#42424200"
|
header="#ccccccff"
|
||||||
back="#00000028"
|
back="#ccccccff"
|
||||||
sub_back="#00000024"
|
sub_back="#0000000f"
|
||||||
>
|
>
|
||||||
</ThemePanelColors>
|
</ThemePanelColors>
|
||||||
</panelcolors>
|
</panelcolors>
|
||||||
@ -1274,9 +1299,9 @@
|
|||||||
>
|
>
|
||||||
<panelcolors>
|
<panelcolors>
|
||||||
<ThemePanelColors
|
<ThemePanelColors
|
||||||
header="#42424200"
|
header="#ccccccff"
|
||||||
back="#00000028"
|
back="#ccccccff"
|
||||||
sub_back="#00000024"
|
sub_back="#0000000f"
|
||||||
>
|
>
|
||||||
</ThemePanelColors>
|
</ThemePanelColors>
|
||||||
</panelcolors>
|
</panelcolors>
|
||||||
@ -1292,7 +1317,7 @@
|
|||||||
title="#ffffff"
|
title="#ffffff"
|
||||||
text="#ffffff"
|
text="#ffffff"
|
||||||
text_hi="#ffffff"
|
text_hi="#ffffff"
|
||||||
header="#adadadff"
|
header="#999999ff"
|
||||||
header_text="#1a1a1a"
|
header_text="#1a1a1a"
|
||||||
header_text_hi="#ffffff"
|
header_text_hi="#ffffff"
|
||||||
button="#2f303500"
|
button="#2f303500"
|
||||||
@ -1308,9 +1333,9 @@
|
|||||||
>
|
>
|
||||||
<panelcolors>
|
<panelcolors>
|
||||||
<ThemePanelColors
|
<ThemePanelColors
|
||||||
header="#42424200"
|
header="#ccccccff"
|
||||||
back="#00000028"
|
back="#ccccccff"
|
||||||
sub_back="#00000024"
|
sub_back="#0000000f"
|
||||||
>
|
>
|
||||||
</ThemePanelColors>
|
</ThemePanelColors>
|
||||||
</panelcolors>
|
</panelcolors>
|
||||||
@ -1331,7 +1356,7 @@
|
|||||||
header="#adadadff"
|
header="#adadadff"
|
||||||
header_text="#000000"
|
header_text="#000000"
|
||||||
header_text_hi="#ffffff"
|
header_text_hi="#ffffff"
|
||||||
button="#999999e6"
|
button="#b3b3b3ff"
|
||||||
button_title="#1a1a1a"
|
button_title="#1a1a1a"
|
||||||
button_text="#000000"
|
button_text="#000000"
|
||||||
button_text_hi="#000000"
|
button_text_hi="#000000"
|
||||||
@ -1344,9 +1369,9 @@
|
|||||||
>
|
>
|
||||||
<panelcolors>
|
<panelcolors>
|
||||||
<ThemePanelColors
|
<ThemePanelColors
|
||||||
header="#42424200"
|
header="#ccccccff"
|
||||||
back="#00000028"
|
back="#ccccccff"
|
||||||
sub_back="#00000024"
|
sub_back="#0000000f"
|
||||||
>
|
>
|
||||||
</ThemePanelColors>
|
</ThemePanelColors>
|
||||||
</panelcolors>
|
</panelcolors>
|
||||||
@ -1585,8 +1610,8 @@
|
|||||||
shadow="3"
|
shadow="3"
|
||||||
shadow_offset_x="0"
|
shadow_offset_x="0"
|
||||||
shadow_offset_y="-1"
|
shadow_offset_y="-1"
|
||||||
shadow_alpha="0.3"
|
shadow_alpha="1"
|
||||||
shadow_value="0.7"
|
shadow_value="0.8"
|
||||||
>
|
>
|
||||||
</ThemeFontStyle>
|
</ThemeFontStyle>
|
||||||
</panel_title>
|
</panel_title>
|
||||||
@ -1596,8 +1621,8 @@
|
|||||||
shadow="3"
|
shadow="3"
|
||||||
shadow_offset_x="0"
|
shadow_offset_x="0"
|
||||||
shadow_offset_y="-1"
|
shadow_offset_y="-1"
|
||||||
shadow_alpha="0.3"
|
shadow_alpha="0"
|
||||||
shadow_value="0.7"
|
shadow_value="0.8"
|
||||||
>
|
>
|
||||||
</ThemeFontStyle>
|
</ThemeFontStyle>
|
||||||
</widget_label>
|
</widget_label>
|
||||||
@ -1607,8 +1632,8 @@
|
|||||||
shadow="1"
|
shadow="1"
|
||||||
shadow_offset_x="0"
|
shadow_offset_x="0"
|
||||||
shadow_offset_y="-1"
|
shadow_offset_y="-1"
|
||||||
shadow_alpha="0.3"
|
shadow_alpha="0"
|
||||||
shadow_value="0.7"
|
shadow_value="0.8"
|
||||||
>
|
>
|
||||||
</ThemeFontStyle>
|
</ThemeFontStyle>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -86,7 +86,7 @@ class Prefs(bpy.types.KeyConfigPreferences):
|
|||||||
update=update_fn,
|
update=update_fn,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Experimental: only show with developer extras, see: T96544.
|
# Experimental: only show with developer extras, see: #96544.
|
||||||
use_tweak_select_passthrough: BoolProperty(
|
use_tweak_select_passthrough: BoolProperty(
|
||||||
name="Tweak Select: Mouse Select & Move",
|
name="Tweak Select: Mouse Select & Move",
|
||||||
description=(
|
description=(
|
||||||
@ -96,7 +96,7 @@ class Prefs(bpy.types.KeyConfigPreferences):
|
|||||||
default=False,
|
default=False,
|
||||||
update=update_fn,
|
update=update_fn,
|
||||||
)
|
)
|
||||||
# Experimental: only show with developer extras, see: T96544.
|
# Experimental: only show with developer extras, see: #96544.
|
||||||
use_tweak_tool_lmb_interaction: BoolProperty(
|
use_tweak_tool_lmb_interaction: BoolProperty(
|
||||||
name="Tweak Tool: Left Mouse Select & Move",
|
name="Tweak Tool: Left Mouse Select & Move",
|
||||||
description=(
|
description=(
|
||||||
|
@ -37,7 +37,7 @@ class Params:
|
|||||||
# instead be bound to a binding that doesn't de-select all, this way:
|
# instead be bound to a binding that doesn't de-select all, this way:
|
||||||
# - Click-drag moves the current selection.
|
# - Click-drag moves the current selection.
|
||||||
# - Click selects only the item at the cursor position.
|
# - Click selects only the item at the cursor position.
|
||||||
# See: T97032.
|
# See: #97032.
|
||||||
"use_tweak_select_passthrough",
|
"use_tweak_select_passthrough",
|
||||||
"use_tweak_tool_lmb_interaction",
|
"use_tweak_tool_lmb_interaction",
|
||||||
"use_mouse_emulate_3_button",
|
"use_mouse_emulate_3_button",
|
||||||
@ -465,7 +465,7 @@ def _template_items_tool_select(
|
|||||||
fallback=False,
|
fallback=False,
|
||||||
):
|
):
|
||||||
if not params.legacy and not fallback:
|
if not params.legacy and not fallback:
|
||||||
# Experimental support for LMB interaction for the tweak tool. see: T96544.
|
# Experimental support for LMB interaction for the tweak tool. see: #96544.
|
||||||
# NOTE: For RMB-select this is a much bigger change as it disables 3D cursor placement on LMB.
|
# NOTE: For RMB-select this is a much bigger change as it disables 3D cursor placement on LMB.
|
||||||
# For LMB-select this means an LMB -drag will not first de-select all (similar to node/graph editor).
|
# For LMB-select this means an LMB -drag will not first de-select all (similar to node/graph editor).
|
||||||
select_passthrough = False
|
select_passthrough = False
|
||||||
@ -498,7 +498,7 @@ def _template_items_tool_select(
|
|||||||
{"properties": [("toggle", True), *operator_props]}),
|
{"properties": [("toggle", True), *operator_props]}),
|
||||||
|
|
||||||
# Fallback key-map must transform as the primary tool is expected
|
# Fallback key-map must transform as the primary tool is expected
|
||||||
# to be accessed via gizmos in this case. See: T96885.
|
# to be accessed via gizmos in this case. See: #96885.
|
||||||
*(() if not fallback else (
|
*(() if not fallback else (
|
||||||
("transform.translate", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG'},
|
("transform.translate", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG'},
|
||||||
{"properties": [("release_confirm", True)]}),
|
{"properties": [("release_confirm", True)]}),
|
||||||
@ -4730,7 +4730,7 @@ def _template_paint_radial_control(paint, rotation=False, secondary_rotation=Fal
|
|||||||
|
|
||||||
def _template_view3d_select(*, type, value, legacy, select_passthrough, exclude_mod=None):
|
def _template_view3d_select(*, type, value, legacy, select_passthrough, exclude_mod=None):
|
||||||
# NOTE: `exclude_mod` is needed since we don't want this tool to exclude Control-RMB actions when this is used
|
# NOTE: `exclude_mod` is needed since we don't want this tool to exclude Control-RMB actions when this is used
|
||||||
# as a tool key-map with RMB-select and `use_fallback_tool` is enabled with RMB select. See T92467.
|
# as a tool key-map with RMB-select and `use_fallback_tool` is enabled with RMB select. See #92467.
|
||||||
|
|
||||||
props_vert_without_handles = ()
|
props_vert_without_handles = ()
|
||||||
if select_passthrough:
|
if select_passthrough:
|
||||||
@ -5629,6 +5629,10 @@ def km_curves(params):
|
|||||||
("curves.disable_selection", {"type": 'TWO', "value": 'PRESS', "alt": True}, None),
|
("curves.disable_selection", {"type": 'TWO', "value": 'PRESS', "alt": True}, None),
|
||||||
*_template_items_select_actions(params, "curves.select_all"),
|
*_template_items_select_actions(params, "curves.select_all"),
|
||||||
("curves.select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None),
|
("curves.select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None),
|
||||||
|
("curves.delete", {"type": 'X', "value": 'PRESS'}, None),
|
||||||
|
("curves.delete", {"type": 'DEL', "value": 'PRESS'}, None),
|
||||||
|
("curves.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None),
|
||||||
|
("curves.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None),
|
||||||
])
|
])
|
||||||
|
|
||||||
return keymap
|
return keymap
|
||||||
@ -5683,7 +5687,7 @@ def km_object_non_modal(params):
|
|||||||
])
|
])
|
||||||
else:
|
else:
|
||||||
items.extend([
|
items.extend([
|
||||||
# NOTE: this shortcut (while not temporary) is not ideal, see: T89757.
|
# NOTE: this shortcut (while not temporary) is not ideal, see: #89757.
|
||||||
("object.transfer_mode", {"type": 'Q', "value": 'PRESS', "alt": True}, None),
|
("object.transfer_mode", {"type": 'Q', "value": 'PRESS', "alt": True}, None),
|
||||||
])
|
])
|
||||||
|
|
||||||
@ -6345,9 +6349,8 @@ def km_node_link_modal_map(_params):
|
|||||||
|
|
||||||
return keymap
|
return keymap
|
||||||
|
|
||||||
|
|
||||||
# Fallback for gizmos that don't have custom a custom key-map.
|
# Fallback for gizmos that don't have custom a custom key-map.
|
||||||
|
|
||||||
|
|
||||||
def km_generic_gizmo(_params):
|
def km_generic_gizmo(_params):
|
||||||
keymap = (
|
keymap = (
|
||||||
"Generic Gizmo",
|
"Generic Gizmo",
|
||||||
|
@ -6,8 +6,8 @@ from bpy.types import Operator
|
|||||||
from bpy.app.translations import pgettext_data as data_
|
from bpy.app.translations import pgettext_data as data_
|
||||||
|
|
||||||
|
|
||||||
def geometry_node_group_empty_new():
|
def build_default_empty_geometry_node_group(name):
|
||||||
group = bpy.data.node_groups.new(data_("Geometry Nodes"), 'GeometryNodeTree')
|
group = bpy.data.node_groups.new(name, 'GeometryNodeTree')
|
||||||
group.inputs.new('NodeSocketGeometry', data_("Geometry"))
|
group.inputs.new('NodeSocketGeometry', data_("Geometry"))
|
||||||
group.outputs.new('NodeSocketGeometry', data_("Geometry"))
|
group.outputs.new('NodeSocketGeometry', data_("Geometry"))
|
||||||
input_node = group.nodes.new('NodeGroupInput')
|
input_node = group.nodes.new('NodeGroupInput')
|
||||||
@ -20,8 +20,12 @@ def geometry_node_group_empty_new():
|
|||||||
input_node.location.x = -200 - input_node.width
|
input_node.location.x = -200 - input_node.width
|
||||||
output_node.location.x = 200
|
output_node.location.x = 200
|
||||||
|
|
||||||
group.links.new(output_node.inputs[0], input_node.outputs[0])
|
return group
|
||||||
|
|
||||||
|
|
||||||
|
def geometry_node_group_empty_new():
|
||||||
|
group = build_default_empty_geometry_node_group(data_("Geometry Nodes"))
|
||||||
|
group.links.new(group.nodes["Group Input"].outputs[0], group.nodes["Group Output"].inputs[0])
|
||||||
return group
|
return group
|
||||||
|
|
||||||
|
|
||||||
@ -35,6 +39,158 @@ def geometry_modifier_poll(context):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def get_context_modifier(context):
|
||||||
|
if context.area.type == 'PROPERTIES':
|
||||||
|
modifier = context.modifier
|
||||||
|
else:
|
||||||
|
modifier = context.object.modifiers.active
|
||||||
|
if modifier is None or modifier.type != 'NODES':
|
||||||
|
return None
|
||||||
|
return modifier
|
||||||
|
|
||||||
|
|
||||||
|
def edit_geometry_nodes_modifier_poll(context):
|
||||||
|
return get_context_modifier(context) is not None
|
||||||
|
|
||||||
|
|
||||||
|
def socket_idname_to_attribute_type(idname):
|
||||||
|
if idname.startswith("NodeSocketInt"):
|
||||||
|
return "INT"
|
||||||
|
elif idname.startswith("NodeSocketColor"):
|
||||||
|
return "FLOAT_COLOR"
|
||||||
|
elif idname.startswith("NodeSocketVector"):
|
||||||
|
return "FLOAT_VECTOR"
|
||||||
|
elif idname.startswith("NodeSocketBool"):
|
||||||
|
return "BOOLEAN"
|
||||||
|
elif idname.startswith("NodeSocketFloat"):
|
||||||
|
return "FLOAT"
|
||||||
|
raise ValueError("Unsupported socket type")
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
def modifier_attribute_name_get(modifier, identifier):
|
||||||
|
try:
|
||||||
|
return modifier[identifier + "_attribute_name"]
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def modifier_input_use_attribute(modifier, identifier):
|
||||||
|
try:
|
||||||
|
return modifier[identifier + "_use_attribute"] != 0
|
||||||
|
except KeyError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def get_socket_with_identifier(sockets, identifier):
|
||||||
|
for socket in sockets:
|
||||||
|
if socket.identifier == identifier:
|
||||||
|
return socket
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_enabled_socket_with_name(sockets, name):
|
||||||
|
for socket in sockets:
|
||||||
|
if socket.name == name and socket.enabled:
|
||||||
|
return socket
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class MoveModifierToNodes(Operator):
|
||||||
|
"""Move inputs and outputs from in the modifier to a new node group"""
|
||||||
|
|
||||||
|
bl_idname = "object.geometry_nodes_move_to_nodes"
|
||||||
|
bl_label = "Move to Nodes"
|
||||||
|
bl_options = {'REGISTER', 'UNDO'}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
return edit_geometry_nodes_modifier_poll(context)
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
modifier = get_context_modifier(context)
|
||||||
|
if not modifier:
|
||||||
|
return {'CANCELLED'}
|
||||||
|
old_group = modifier.node_group
|
||||||
|
if not old_group:
|
||||||
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
wrapper_name = old_group.name + ".wrapper"
|
||||||
|
group = build_default_empty_geometry_node_group(wrapper_name)
|
||||||
|
group_node = group.nodes.new("GeometryNodeGroup")
|
||||||
|
group_node.node_tree = old_group
|
||||||
|
group_node.update()
|
||||||
|
|
||||||
|
group_input_node = group.nodes["Group Input"]
|
||||||
|
group_output_node = group.nodes["Group Output"]
|
||||||
|
|
||||||
|
# Copy default values for inputs and create named attribute input nodes.
|
||||||
|
input_nodes = []
|
||||||
|
first_geometry_input = None
|
||||||
|
for input_socket in old_group.inputs:
|
||||||
|
identifier = input_socket.identifier
|
||||||
|
group_node_input = get_socket_with_identifier(group_node.inputs, identifier)
|
||||||
|
if modifier_input_use_attribute(modifier, identifier):
|
||||||
|
input_node = group.nodes.new("GeometryNodeInputNamedAttribute")
|
||||||
|
input_nodes.append(input_node)
|
||||||
|
input_node.data_type = socket_idname_to_attribute_type(input_socket.bl_socket_idname)
|
||||||
|
attribute_name = modifier_attribute_name_get(modifier, identifier)
|
||||||
|
input_node.inputs["Name"].default_value = attribute_name
|
||||||
|
output_socket = get_enabled_socket_with_name(input_node.outputs, "Attribute")
|
||||||
|
group.links.new(output_socket, group_node_input)
|
||||||
|
elif hasattr(input_socket, "default_value"):
|
||||||
|
group_node_input.default_value = modifier[identifier]
|
||||||
|
elif input_socket.bl_socket_idname == 'NodeSocketGeometry':
|
||||||
|
if not first_geometry_input:
|
||||||
|
first_geometry_input = group_node_input
|
||||||
|
|
||||||
|
group.links.new(group_input_node.outputs[0], first_geometry_input)
|
||||||
|
|
||||||
|
# Adjust locations of named attribute input nodes and group input node to make some space.
|
||||||
|
if input_nodes:
|
||||||
|
for i, node in enumerate(input_nodes):
|
||||||
|
node.location.x = -175
|
||||||
|
node.location.y = i * -50
|
||||||
|
group_input_node.location.x = -350
|
||||||
|
|
||||||
|
# Connect outputs to store named attribute nodes to replace modifier attribute outputs.
|
||||||
|
store_nodes = []
|
||||||
|
first_geometry_output = None
|
||||||
|
for output_socket in old_group.outputs:
|
||||||
|
identifier = output_socket.identifier
|
||||||
|
group_node_output = get_socket_with_identifier(group_node.outputs, identifier)
|
||||||
|
attribute_name = modifier_attribute_name_get(modifier, identifier)
|
||||||
|
if attribute_name:
|
||||||
|
store_node = group.nodes.new("GeometryNodeStoreNamedAttribute")
|
||||||
|
store_nodes.append(store_node)
|
||||||
|
store_node.data_type = socket_idname_to_attribute_type(output_socket.bl_socket_idname)
|
||||||
|
store_node.domain = output_socket.attribute_domain
|
||||||
|
store_node.inputs["Name"].default_value = attribute_name
|
||||||
|
input_socket = get_enabled_socket_with_name(store_node.inputs, "Value")
|
||||||
|
group.links.new(group_node_output, input_socket)
|
||||||
|
elif output_socket.bl_socket_idname == 'NodeSocketGeometry':
|
||||||
|
if not first_geometry_output:
|
||||||
|
first_geometry_output = group_node_output
|
||||||
|
|
||||||
|
# Adjust locations of store named attribute nodes and move group output.
|
||||||
|
if store_nodes:
|
||||||
|
for i, node in enumerate(store_nodes):
|
||||||
|
node.location.x = (i + 1) * 175
|
||||||
|
node.location.y = 0
|
||||||
|
group_output_node.location.x = (len(store_nodes) + 1) * 175
|
||||||
|
|
||||||
|
group.links.new(first_geometry_output, store_nodes[0].inputs["Geometry"])
|
||||||
|
for i in range(len(store_nodes) - 1):
|
||||||
|
group.links.new(store_nodes[i].outputs["Geometry"], store_nodes[i + 1].inputs["Geometry"])
|
||||||
|
group.links.new(store_nodes[-1].outputs["Geometry"], group_output_node.inputs["Geometry"])
|
||||||
|
else:
|
||||||
|
group.links.new(first_geometry_output, group_output_node.inputs["Geometry"])
|
||||||
|
|
||||||
|
modifier.node_group = group
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class NewGeometryNodesModifier(Operator):
|
class NewGeometryNodesModifier(Operator):
|
||||||
"""Create a new modifier with a new geometry node group"""
|
"""Create a new modifier with a new geometry node group"""
|
||||||
|
|
||||||
@ -48,7 +204,6 @@ class NewGeometryNodesModifier(Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
modifier = context.object.modifiers.new(data_("GeometryNodes"), "NODES")
|
modifier = context.object.modifiers.new(data_("GeometryNodes"), "NODES")
|
||||||
|
|
||||||
if not modifier:
|
if not modifier:
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
@ -70,11 +225,7 @@ class NewGeometryNodeTreeAssign(Operator):
|
|||||||
return geometry_modifier_poll(context)
|
return geometry_modifier_poll(context)
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
if context.area.type == 'PROPERTIES':
|
modifier = get_context_modifier(context)
|
||||||
modifier = context.modifier
|
|
||||||
else:
|
|
||||||
modifier = context.object.modifiers.active
|
|
||||||
|
|
||||||
if not modifier:
|
if not modifier:
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
@ -87,4 +238,5 @@ class NewGeometryNodeTreeAssign(Operator):
|
|||||||
classes = (
|
classes = (
|
||||||
NewGeometryNodesModifier,
|
NewGeometryNodesModifier,
|
||||||
NewGeometryNodeTreeAssign,
|
NewGeometryNodeTreeAssign,
|
||||||
|
MoveModifierToNodes,
|
||||||
)
|
)
|
||||||
|
@ -790,7 +790,7 @@ class TransformsToDeltasAnim(Operator):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# first pass over F-Curves: ensure that we don't have conflicting
|
# first pass over F-Curves: ensure that we don't have conflicting
|
||||||
# transforms already (e.g. if this was applied already) T29110.
|
# transforms already (e.g. if this was applied already) #29110.
|
||||||
existingFCurves = {}
|
existingFCurves = {}
|
||||||
for fcu in adt.action.fcurves:
|
for fcu in adt.action.fcurves:
|
||||||
# get "delta" path - i.e. the final paths which may clash
|
# get "delta" path - i.e. the final paths which may clash
|
||||||
|
@ -36,67 +36,136 @@ class ObjectModeOperator:
|
|||||||
|
|
||||||
|
|
||||||
class QuickFur(ObjectModeOperator, Operator):
|
class QuickFur(ObjectModeOperator, Operator):
|
||||||
"""Add fur setup to the selected objects"""
|
"""Add a fur setup to the selected objects"""
|
||||||
bl_idname = "object.quick_fur"
|
bl_idname = "object.quick_fur"
|
||||||
bl_label = "Quick Fur"
|
bl_label = "Quick Fur"
|
||||||
bl_options = {'REGISTER', 'UNDO'}
|
bl_options = {'REGISTER', 'UNDO'}
|
||||||
|
|
||||||
density: EnumProperty(
|
density: EnumProperty(
|
||||||
name="Fur Density",
|
name="Density",
|
||||||
items=(
|
items=(
|
||||||
('LIGHT', "Light", ""),
|
('LOW', "Low", ""),
|
||||||
('MEDIUM', "Medium", ""),
|
('MEDIUM', "Medium", ""),
|
||||||
('HEAVY', "Heavy", ""),
|
('HIGH', "High", ""),
|
||||||
),
|
),
|
||||||
default='MEDIUM',
|
default='MEDIUM',
|
||||||
)
|
)
|
||||||
view_percentage: IntProperty(
|
|
||||||
name="View %",
|
|
||||||
min=1, max=100,
|
|
||||||
soft_min=1, soft_max=100,
|
|
||||||
default=10,
|
|
||||||
)
|
|
||||||
length: FloatProperty(
|
length: FloatProperty(
|
||||||
name="Length",
|
name="Length",
|
||||||
min=0.001, max=100,
|
min=0.001, max=100,
|
||||||
soft_min=0.01, soft_max=10,
|
soft_min=0.01, soft_max=10,
|
||||||
default=0.1,
|
default=0.1,
|
||||||
|
subtype='DISTANCE'
|
||||||
|
)
|
||||||
|
radius: FloatProperty(
|
||||||
|
name="Hair Radius",
|
||||||
|
min=0.0, max=10,
|
||||||
|
soft_min=0.0001, soft_max=0.1,
|
||||||
|
default=0.001,
|
||||||
|
subtype='DISTANCE'
|
||||||
|
)
|
||||||
|
view_percentage: FloatProperty(
|
||||||
|
name="View Percentage",
|
||||||
|
min=0.0, max=1.0,
|
||||||
|
default=1.0,
|
||||||
|
subtype='FACTOR'
|
||||||
|
)
|
||||||
|
apply_hair_guides: BoolProperty(
|
||||||
|
name="Apply Hair Guides",
|
||||||
|
default=True,
|
||||||
|
)
|
||||||
|
use_noise: BoolProperty(
|
||||||
|
name="Noise",
|
||||||
|
default=True,
|
||||||
|
)
|
||||||
|
use_frizz: BoolProperty(
|
||||||
|
name="Frizz",
|
||||||
|
default=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
fake_context = context.copy()
|
import os
|
||||||
mesh_objects = [obj for obj in context.selected_objects
|
mesh_objects = [obj for obj in context.selected_objects if obj.type == 'MESH']
|
||||||
if obj.type == 'MESH']
|
|
||||||
|
|
||||||
if not mesh_objects:
|
if not mesh_objects:
|
||||||
self.report({'ERROR'}, "Select at least one mesh object")
|
self.report({'ERROR'}, "Select at least one mesh object")
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
mat = bpy.data.materials.new("Fur Material")
|
if self.density == 'LOW':
|
||||||
|
count = 1000
|
||||||
for obj in mesh_objects:
|
|
||||||
fake_context["object"] = obj
|
|
||||||
bpy.ops.object.particle_system_add(fake_context)
|
|
||||||
|
|
||||||
psys = obj.particle_systems[-1]
|
|
||||||
psys.settings.type = 'HAIR'
|
|
||||||
|
|
||||||
if self.density == 'LIGHT':
|
|
||||||
psys.settings.count = 100
|
|
||||||
elif self.density == 'MEDIUM':
|
elif self.density == 'MEDIUM':
|
||||||
psys.settings.count = 1000
|
count = 10000
|
||||||
elif self.density == 'HEAVY':
|
elif self.density == 'HIGH':
|
||||||
psys.settings.count = 10000
|
count = 100000
|
||||||
|
|
||||||
psys.settings.child_nbr = self.view_percentage
|
node_groups_to_append = {"Generate Hair Curves", "Set Hair Curve Profile", "Interpolate Hair Curves"}
|
||||||
psys.settings.hair_length = self.length
|
if self.use_noise:
|
||||||
psys.settings.use_strand_primitive = True
|
node_groups_to_append.add("Hair Curves Noise")
|
||||||
psys.settings.use_hair_bspline = True
|
if self.use_frizz:
|
||||||
psys.settings.child_type = 'INTERPOLATED'
|
node_groups_to_append.add("Frizz Hair Curves")
|
||||||
psys.settings.tip_radius = 0.25
|
assets_directory = os.path.join(bpy.utils.system_resource('DATAFILES'),
|
||||||
|
"assets",
|
||||||
|
"geometry_nodes",
|
||||||
|
"procedural_hair_node_assets.blend",
|
||||||
|
"NodeTree")
|
||||||
|
for name in node_groups_to_append:
|
||||||
|
bpy.ops.wm.append(directory=assets_directory,
|
||||||
|
filename=name,
|
||||||
|
use_recursive=True,
|
||||||
|
clear_asset_data=True,
|
||||||
|
do_reuse_local_id=True)
|
||||||
|
generate_group = bpy.data.node_groups["Generate Hair Curves"]
|
||||||
|
interpolate_group = bpy.data.node_groups["Interpolate Hair Curves"]
|
||||||
|
radius_group = bpy.data.node_groups["Set Hair Curve Profile"]
|
||||||
|
noise_group = bpy.data.node_groups["Hair Curves Noise"] if self.use_noise else None
|
||||||
|
frizz_group = bpy.data.node_groups["Frizz Hair Curves"] if self.use_frizz else None
|
||||||
|
|
||||||
obj.data.materials.append(mat)
|
material = bpy.data.materials.new("Fur Material")
|
||||||
psys.settings.material = len(obj.data.materials)
|
|
||||||
|
for mesh_object in mesh_objects:
|
||||||
|
mesh = mesh_object.data
|
||||||
|
with context.temp_override(active_object=mesh_object):
|
||||||
|
bpy.ops.object.curves_empty_hair_add()
|
||||||
|
curves_object = context.active_object
|
||||||
|
curves = curves_object.data
|
||||||
|
curves.materials.append(material)
|
||||||
|
|
||||||
|
area = 0.0
|
||||||
|
for poly in mesh.polygons:
|
||||||
|
area += poly.area
|
||||||
|
density = count / area
|
||||||
|
|
||||||
|
generate_modifier = curves_object.modifiers.new(name="Generate", type='NODES')
|
||||||
|
generate_modifier.node_group = generate_group
|
||||||
|
generate_modifier["Input_2"] = mesh_object
|
||||||
|
generate_modifier["Input_18_attribute_name"] = curves.surface_uv_map
|
||||||
|
generate_modifier["Input_20"] = self.length
|
||||||
|
generate_modifier["Input_22"] = material
|
||||||
|
generate_modifier["Input_15"] = density * 0.01
|
||||||
|
curves_object.modifiers.move(1, 0)
|
||||||
|
|
||||||
|
radius_modifier = curves_object.modifiers.new(name="Set Hair Curve Profile", type='NODES')
|
||||||
|
radius_modifier.node_group = radius_group
|
||||||
|
radius_modifier["Input_3"] = self.radius
|
||||||
|
|
||||||
|
interpolate_modifier = curves_object.modifiers.new(name="Interpolate Hair Curves", type='NODES')
|
||||||
|
interpolate_modifier.node_group = interpolate_group
|
||||||
|
interpolate_modifier["Input_2"] = mesh_object
|
||||||
|
interpolate_modifier["Input_18_attribute_name"] = curves.surface_uv_map
|
||||||
|
interpolate_modifier["Input_15"] = density
|
||||||
|
interpolate_modifier["Input_17"] = self.view_percentage
|
||||||
|
interpolate_modifier["Input_24"] = True
|
||||||
|
|
||||||
|
if noise_group:
|
||||||
|
noise_modifier = curves_object.modifiers.new(name="Hair Curves Noise", type='NODES')
|
||||||
|
noise_modifier.node_group = noise_group
|
||||||
|
|
||||||
|
if frizz_group:
|
||||||
|
frizz_modifier = curves_object.modifiers.new(name="Frizz Hair Curves", type='NODES')
|
||||||
|
frizz_modifier.node_group = frizz_group
|
||||||
|
|
||||||
|
if self.apply_hair_guides:
|
||||||
|
with context.temp_override(object=curves_object):
|
||||||
|
bpy.ops.object.modifier_apply(modifier=generate_modifier.name)
|
||||||
|
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
@ -700,7 +700,7 @@ class PREFERENCES_OT_addon_install(Operator):
|
|||||||
addons_new.discard("modules")
|
addons_new.discard("modules")
|
||||||
|
|
||||||
# disable any addons we may have enabled previously and removed.
|
# disable any addons we may have enabled previously and removed.
|
||||||
# this is unlikely but do just in case. bug T23978.
|
# this is unlikely but do just in case. bug #23978.
|
||||||
for new_addon in addons_new:
|
for new_addon in addons_new:
|
||||||
addon_utils.disable(new_addon, default_set=True)
|
addon_utils.disable(new_addon, default_set=True)
|
||||||
|
|
||||||
|
@ -581,7 +581,7 @@ class LightMapPack(Operator):
|
|||||||
# Proper solution would be to make undo stack aware of such things,
|
# Proper solution would be to make undo stack aware of such things,
|
||||||
# but for now just disable redo. Keep undo here so unwanted changes to uv
|
# but for now just disable redo. Keep undo here so unwanted changes to uv
|
||||||
# coords might be undone.
|
# coords might be undone.
|
||||||
# This fixes infinite image creation reported there T30968 (sergey)
|
# This fixes infinite image creation reported there #30968 (sergey)
|
||||||
bl_options = {'UNDO'}
|
bl_options = {'UNDO'}
|
||||||
|
|
||||||
PREF_CONTEXT: bpy.props.EnumProperty(
|
PREF_CONTEXT: bpy.props.EnumProperty(
|
||||||
|
@ -90,7 +90,7 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean,
|
|||||||
tone_range = max_tone - min_tone
|
tone_range = max_tone - min_tone
|
||||||
|
|
||||||
if tone_range < 0.0001:
|
if tone_range < 0.0001:
|
||||||
# weak, don't cancel, see T43345
|
# weak, don't cancel, see #43345
|
||||||
tone_range = 0.0
|
tone_range = 0.0
|
||||||
else:
|
else:
|
||||||
tone_range = 1.0 / tone_range
|
tone_range = 1.0 / tone_range
|
||||||
|
@ -42,7 +42,7 @@ class VIEW3D_OT_edit_mesh_extrude_individual_move(Operator):
|
|||||||
bpy.ops.mesh.extrude_vertices_move('INVOKE_REGION_WIN')
|
bpy.ops.mesh.extrude_vertices_move('INVOKE_REGION_WIN')
|
||||||
|
|
||||||
# ignore return from operators above because they are 'RUNNING_MODAL',
|
# ignore return from operators above because they are 'RUNNING_MODAL',
|
||||||
# and cause this one not to be freed. T24671.
|
# and cause this one not to be freed. #24671.
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, _event):
|
def invoke(self, context, _event):
|
||||||
@ -104,7 +104,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
|
|||||||
'INVOKE_REGION_WIN',
|
'INVOKE_REGION_WIN',
|
||||||
TRANSFORM_OT_translate={
|
TRANSFORM_OT_translate={
|
||||||
# Don't set the constraint axis since users will expect MMB
|
# Don't set the constraint axis since users will expect MMB
|
||||||
# to use the user setting, see: T61637
|
# to use the user setting, see: #61637
|
||||||
# "orient_type": 'NORMAL',
|
# "orient_type": 'NORMAL',
|
||||||
# Not a popular choice, too restrictive for retopo.
|
# Not a popular choice, too restrictive for retopo.
|
||||||
# "constraint_axis": (True, True, False)})
|
# "constraint_axis": (True, True, False)})
|
||||||
@ -114,7 +114,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
|
|||||||
bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN')
|
bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN')
|
||||||
|
|
||||||
# ignore return from operators above because they are 'RUNNING_MODAL',
|
# ignore return from operators above because they are 'RUNNING_MODAL',
|
||||||
# and cause this one not to be freed. T24671.
|
# and cause this one not to be freed. #24671.
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
|
@ -1249,7 +1249,31 @@ class WM_OT_doc_view_manual(Operator):
|
|||||||
# XXX, for some reason all RNA ID's are stored lowercase
|
# XXX, for some reason all RNA ID's are stored lowercase
|
||||||
# Adding case into all ID's isn't worth the hassle so force lowercase.
|
# Adding case into all ID's isn't worth the hassle so force lowercase.
|
||||||
rna_id = rna_id.lower()
|
rna_id = rna_id.lower()
|
||||||
|
|
||||||
|
# NOTE: `fnmatch` in Python is slow as it translate the string to a regular-expression
|
||||||
|
# which needs to be compiled (as of Python 3.11), this is slow enough to cause a noticeable
|
||||||
|
# delay when opening manual links (approaching half a second).
|
||||||
|
#
|
||||||
|
# Resolve by matching characters that have a special meaning to `fnmatch`.
|
||||||
|
# The characters that can occur as the first special character are `*?[`.
|
||||||
|
# If any of these are used we must let `fnmatch` run its own matching logic.
|
||||||
|
# However, in most cases a literal prefix is used making it considerably faster
|
||||||
|
# to do a simple `startswith` check before performing a full match.
|
||||||
|
# An alternative solution could be to use `fnmatch` from C which is significantly
|
||||||
|
# faster than Python's, see !104581 for details.
|
||||||
|
import re
|
||||||
|
re_match_non_special = re.compile(r"^[^?\*\[]+").match
|
||||||
|
|
||||||
for pattern, url_suffix in url_mapping:
|
for pattern, url_suffix in url_mapping:
|
||||||
|
|
||||||
|
# Simple optimization, makes a big difference (over 50x speedup).
|
||||||
|
# Even when `non_special.end()` is zero (resulting in an empty-string),
|
||||||
|
# the `startswith` check succeeds so there is no need to check for an empty match.
|
||||||
|
non_special = re_match_non_special(pattern)
|
||||||
|
if non_special is None or not rna_id.startswith(pattern[:non_special.end()]):
|
||||||
|
continue
|
||||||
|
# End simple optimization.
|
||||||
|
|
||||||
if fnmatchcase(rna_id, pattern):
|
if fnmatchcase(rna_id, pattern):
|
||||||
if verbose:
|
if verbose:
|
||||||
print(" match found: '%s' --> '%s'" % (pattern, url_suffix))
|
print(" match found: '%s' --> '%s'" % (pattern, url_suffix))
|
||||||
@ -1725,7 +1749,7 @@ class WM_OT_properties_edit(Operator):
|
|||||||
for nt in adt.nla_tracks:
|
for nt in adt.nla_tracks:
|
||||||
_update_strips(nt.strips)
|
_update_strips(nt.strips)
|
||||||
|
|
||||||
# Otherwise existing buttons which reference freed memory may crash Blender (T26510).
|
# Otherwise existing buttons which reference freed memory may crash Blender (#26510).
|
||||||
for win in context.window_manager.windows:
|
for win in context.window_manager.windows:
|
||||||
for area in win.screen.areas:
|
for area in win.screen.areas:
|
||||||
area.tag_redraw()
|
area.tag_redraw()
|
||||||
|
@ -604,7 +604,7 @@ class DATA_PT_mesh_attributes(MeshButtonsPanel, Panel):
|
|||||||
colliding_names = []
|
colliding_names = []
|
||||||
for collection in (
|
for collection in (
|
||||||
# Built-in names.
|
# Built-in names.
|
||||||
{"shade_smooth": None, "normal": None, "crease": None},
|
{"shade_smooth": None, "crease": None},
|
||||||
mesh.attributes,
|
mesh.attributes,
|
||||||
None if ob is None else ob.vertex_groups,
|
None if ob is None else ob.vertex_groups,
|
||||||
):
|
):
|
||||||
|
@ -1141,6 +1141,11 @@ def brush_texture_settings(layout, brush, sculpt):
|
|||||||
# texture_sample_bias
|
# texture_sample_bias
|
||||||
layout.prop(brush, "texture_sample_bias", slider=True, text="Sample Bias")
|
layout.prop(brush, "texture_sample_bias", slider=True, text="Sample Bias")
|
||||||
|
|
||||||
|
if brush.sculpt_tool == 'DRAW':
|
||||||
|
col = layout.column()
|
||||||
|
col.active = tex_slot.map_mode == 'AREA_PLANE'
|
||||||
|
col.prop(brush, "use_color_as_displacement", text="Vector Displacement")
|
||||||
|
|
||||||
|
|
||||||
def brush_mask_texture_settings(layout, brush):
|
def brush_mask_texture_settings(layout, brush):
|
||||||
mask_tex_slot = brush.mask_texture_slot
|
mask_tex_slot = brush.mask_texture_slot
|
||||||
|
@ -91,7 +91,7 @@ class TEXTURE_PT_preview(TextureButtonsPanel, Panel):
|
|||||||
else:
|
else:
|
||||||
layout.template_preview(tex, slot=slot)
|
layout.template_preview(tex, slot=slot)
|
||||||
|
|
||||||
# Show Alpha Button for Brush Textures, see T29502.
|
# Show Alpha Button for Brush Textures, see #29502.
|
||||||
idblock = context_tex_datablock(context)
|
idblock = context_tex_datablock(context)
|
||||||
if isinstance(idblock, Brush):
|
if isinstance(idblock, Brush):
|
||||||
layout.prop(tex, "use_preview_alpha")
|
layout.prop(tex, "use_preview_alpha")
|
||||||
|
@ -22,7 +22,7 @@ class FILEBROWSER_HT_header(Header):
|
|||||||
|
|
||||||
layout.separator_spacer()
|
layout.separator_spacer()
|
||||||
|
|
||||||
if params.asset_library_ref != 'LOCAL':
|
if params.asset_library_ref not in {'LOCAL', 'ESSENTIALS'}:
|
||||||
layout.prop(params, "import_type", text="")
|
layout.prop(params, "import_type", text="")
|
||||||
|
|
||||||
layout.separator_spacer()
|
layout.separator_spacer()
|
||||||
|
@ -62,7 +62,7 @@ class NODE_HT_header(Header):
|
|||||||
|
|
||||||
types_that_support_material = {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META',
|
types_that_support_material = {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META',
|
||||||
'GPENCIL', 'VOLUME', 'CURVES', 'POINTCLOUD'}
|
'GPENCIL', 'VOLUME', 'CURVES', 'POINTCLOUD'}
|
||||||
# disable material slot buttons when pinned, cannot find correct slot within id_from (T36589)
|
# disable material slot buttons when pinned, cannot find correct slot within id_from (#36589)
|
||||||
# disable also when the selected object does not support materials
|
# disable also when the selected object does not support materials
|
||||||
has_material_slots = not snode.pin and ob_type in types_that_support_material
|
has_material_slots = not snode.pin and ob_type in types_that_support_material
|
||||||
|
|
||||||
|
@ -407,7 +407,7 @@ class SEQUENCER_MT_view(Menu):
|
|||||||
if st.view_type == 'PREVIEW':
|
if st.view_type == 'PREVIEW':
|
||||||
# Specifying the REGION_PREVIEW context is needed in preview-only
|
# Specifying the REGION_PREVIEW context is needed in preview-only
|
||||||
# mode, else the lookup for the shortcut will fail in
|
# mode, else the lookup for the shortcut will fail in
|
||||||
# wm_keymap_item_find_props() (see T32595).
|
# wm_keymap_item_find_props() (see #32595).
|
||||||
layout.operator_context = 'INVOKE_REGION_PREVIEW'
|
layout.operator_context = 'INVOKE_REGION_PREVIEW'
|
||||||
layout.prop(st, "show_region_ui")
|
layout.prop(st, "show_region_ui")
|
||||||
layout.prop(st, "show_region_tool_header")
|
layout.prop(st, "show_region_tool_header")
|
||||||
@ -429,7 +429,7 @@ class SEQUENCER_MT_view(Menu):
|
|||||||
|
|
||||||
layout.operator_context = 'INVOKE_REGION_WIN'
|
layout.operator_context = 'INVOKE_REGION_WIN'
|
||||||
if st.view_type == 'PREVIEW':
|
if st.view_type == 'PREVIEW':
|
||||||
# See above (T32595)
|
# See above (#32595)
|
||||||
layout.operator_context = 'INVOKE_REGION_PREVIEW'
|
layout.operator_context = 'INVOKE_REGION_PREVIEW'
|
||||||
layout.operator("sequencer.view_selected", text="Frame Selected")
|
layout.operator("sequencer.view_selected", text="Frame Selected")
|
||||||
|
|
||||||
@ -931,8 +931,14 @@ class SEQUENCER_MT_strip(Menu):
|
|||||||
|
|
||||||
if has_sequencer:
|
if has_sequencer:
|
||||||
|
|
||||||
layout.operator("sequencer.split", text="Split").type = 'SOFT'
|
props = layout.operator("sequencer.split", text="Split")
|
||||||
layout.operator("sequencer.split", text="Hold Split").type = 'HARD'
|
props.type = 'SOFT'
|
||||||
|
props.side = 'RIGHT'
|
||||||
|
|
||||||
|
props = layout.operator("sequencer.split", text="Hold Split")
|
||||||
|
props.type = 'HARD'
|
||||||
|
props.side = 'RIGHT'
|
||||||
|
|
||||||
layout.separator()
|
layout.separator()
|
||||||
|
|
||||||
if has_sequencer:
|
if has_sequencer:
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -326,7 +326,7 @@ class TOPBAR_MT_file_new(Menu):
|
|||||||
# Expand template paths.
|
# Expand template paths.
|
||||||
|
|
||||||
# Use a set to avoid duplicate user/system templates.
|
# Use a set to avoid duplicate user/system templates.
|
||||||
# This is a corner case, but users managed to do it! T76849.
|
# This is a corner case, but users managed to do it! #76849.
|
||||||
app_templates = set()
|
app_templates = set()
|
||||||
for path in template_paths:
|
for path in template_paths:
|
||||||
for d in os.listdir(path):
|
for d in os.listdir(path):
|
||||||
|
@ -1424,34 +1424,40 @@ class USERPREF_PT_file_paths_asset_libraries(FilePathsPanel, Panel):
|
|||||||
layout.use_property_decorate = False
|
layout.use_property_decorate = False
|
||||||
|
|
||||||
paths = context.preferences.filepaths
|
paths = context.preferences.filepaths
|
||||||
|
active_library_index = paths.active_asset_library
|
||||||
|
|
||||||
box = layout.box()
|
row = layout.row()
|
||||||
split = box.split(factor=0.35)
|
|
||||||
name_col = split.column()
|
|
||||||
path_col = split.column()
|
|
||||||
|
|
||||||
row = name_col.row(align=True) # Padding
|
row.template_list(
|
||||||
row.separator()
|
"USERPREF_UL_asset_libraries", "user_asset_libraries",
|
||||||
row.label(text="Name")
|
paths, "asset_libraries",
|
||||||
|
paths, "active_asset_library"
|
||||||
|
)
|
||||||
|
|
||||||
row = path_col.row(align=True) # Padding
|
col = row.column(align=True)
|
||||||
row.separator()
|
col.operator("preferences.asset_library_add", text="", icon='ADD')
|
||||||
row.label(text="Path")
|
props = col.operator("preferences.asset_library_remove", text="", icon='REMOVE')
|
||||||
|
props.index = active_library_index
|
||||||
|
|
||||||
for i, library in enumerate(paths.asset_libraries):
|
if active_library_index < 0:
|
||||||
row = name_col.row()
|
return
|
||||||
row.alert = not library.name
|
|
||||||
row.prop(library, "name", text="")
|
|
||||||
|
|
||||||
row = path_col.row()
|
layout.separator()
|
||||||
subrow = row.row()
|
|
||||||
subrow.alert = not library.path
|
|
||||||
subrow.prop(library, "path", text="")
|
|
||||||
row.operator("preferences.asset_library_remove", text="", icon='X', emboss=False).index = i
|
|
||||||
|
|
||||||
row = box.row()
|
active_library = paths.asset_libraries[active_library_index]
|
||||||
row.alignment = 'RIGHT'
|
layout.prop(active_library, "path")
|
||||||
row.operator("preferences.asset_library_add", text="", icon='ADD', emboss=False)
|
layout.prop(active_library, "import_method", text="Import Method")
|
||||||
|
|
||||||
|
|
||||||
|
class USERPREF_UL_asset_libraries(bpy.types.UIList):
|
||||||
|
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
|
||||||
|
asset_library = item
|
||||||
|
|
||||||
|
if self.layout_type in {'DEFAULT', 'COMPACT'}:
|
||||||
|
layout.prop(asset_library, "name", text="", emboss=False)
|
||||||
|
elif self.layout_type == 'GRID':
|
||||||
|
layout.alignment = 'CENTER'
|
||||||
|
layout.prop(asset_library, "name", text="", emboss=False)
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
@ -2319,19 +2325,13 @@ class USERPREF_PT_experimental_new_features(ExperimentalPanel, Panel):
|
|||||||
bl_label = "New Features"
|
bl_label = "New Features"
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
self._draw_items(context,
|
self._draw_items(
|
||||||
(({"property": "use_sculpt_tools_tilt"},
|
context, (
|
||||||
("blender/blender/issues/82877",
|
({"property": "use_sculpt_tools_tilt"}, ("blender/blender/issues/82877", "#82877")),
|
||||||
"#82877")),
|
|
||||||
({"property": "use_extended_asset_browser"},
|
({"property": "use_extended_asset_browser"},
|
||||||
("blender/blender/projects/10",
|
("blender/blender/projects/10", "Pipeline, Assets & IO Project Page")),
|
||||||
"Pipeline, Assets & IO Project Page")),
|
({"property": "use_override_templates"}, ("blender/blender/issues/73318", "Milestone 4")),
|
||||||
({"property": "use_override_templates"},
|
({"property": "use_new_volume_nodes"}, ("blender/blender/issues/103248", "#103248")),
|
||||||
("blender/blender/issues/73318",
|
|
||||||
"Milestone 4")),
|
|
||||||
({"property": "use_new_volume_nodes"},
|
|
||||||
("blender/blender/issues/103248",
|
|
||||||
"#103248")),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -2493,6 +2493,9 @@ classes = (
|
|||||||
# USERPREF_PT_experimental_tweaks,
|
# USERPREF_PT_experimental_tweaks,
|
||||||
USERPREF_PT_experimental_debugging,
|
USERPREF_PT_experimental_debugging,
|
||||||
|
|
||||||
|
# UI lists
|
||||||
|
USERPREF_UL_asset_libraries,
|
||||||
|
|
||||||
# Add dynamically generated editor theme panels last,
|
# Add dynamically generated editor theme panels last,
|
||||||
# so they show up last in the theme section.
|
# so they show up last in the theme section.
|
||||||
*ThemeGenericClassGenerator.generate_panel_classes_from_theme_areas(),
|
*ThemeGenericClassGenerator.generate_panel_classes_from_theme_areas(),
|
||||||
|
@ -161,6 +161,8 @@ class VIEW3D_HT_tool_header(Header):
|
|||||||
sub.prop(context.object.data, "use_mirror_y", text="Y", toggle=True)
|
sub.prop(context.object.data, "use_mirror_y", text="Y", toggle=True)
|
||||||
sub.prop(context.object.data, "use_mirror_z", text="Z", toggle=True)
|
sub.prop(context.object.data, "use_mirror_z", text="Z", toggle=True)
|
||||||
|
|
||||||
|
layout.prop(context.object.data, "use_sculpt_collision", icon='MOD_PHYSICS', icon_only=True, toggle=True)
|
||||||
|
|
||||||
# Expand panels from the side-bar as popovers.
|
# Expand panels from the side-bar as popovers.
|
||||||
popover_kw = {"space_type": 'VIEW_3D', "region_type": 'UI', "category": "Tool"}
|
popover_kw = {"space_type": 'VIEW_3D', "region_type": 'UI', "category": "Tool"}
|
||||||
|
|
||||||
@ -520,7 +522,8 @@ class _draw_tool_settings_context_mode:
|
|||||||
|
|
||||||
if curves_tool == 'COMB':
|
if curves_tool == 'COMB':
|
||||||
layout.prop(brush, "falloff_shape", expand=True)
|
layout.prop(brush, "falloff_shape", expand=True)
|
||||||
layout.popover("VIEW3D_PT_tools_brush_falloff")
|
layout.popover("VIEW3D_PT_tools_brush_falloff", text="Brush Falloff")
|
||||||
|
layout.popover("VIEW3D_PT_curves_sculpt_parameter_falloff", text="Curve Falloff")
|
||||||
elif curves_tool == 'ADD':
|
elif curves_tool == 'ADD':
|
||||||
layout.prop(brush, "falloff_shape", expand=True)
|
layout.prop(brush, "falloff_shape", expand=True)
|
||||||
layout.prop(brush.curves_sculpt_settings, "add_amount")
|
layout.prop(brush.curves_sculpt_settings, "add_amount")
|
||||||
@ -890,7 +893,7 @@ class VIEW3D_HT_header(Header):
|
|||||||
row.active = (object_mode == 'EDIT') or (shading.type in {'WIREFRAME', 'SOLID'})
|
row.active = (object_mode == 'EDIT') or (shading.type in {'WIREFRAME', 'SOLID'})
|
||||||
|
|
||||||
# While exposing `shading.show_xray(_wireframe)` is correct.
|
# While exposing `shading.show_xray(_wireframe)` is correct.
|
||||||
# this hides the key shortcut from users: T70433.
|
# this hides the key shortcut from users: #70433.
|
||||||
if has_pose_mode:
|
if has_pose_mode:
|
||||||
draw_depressed = overlay.show_xray_bone
|
draw_depressed = overlay.show_xray_bone
|
||||||
elif shading.type == 'WIREFRAME':
|
elif shading.type == 'WIREFRAME':
|
||||||
@ -2041,6 +2044,16 @@ class VIEW3D_MT_select_paint_mask_vertex(Menu):
|
|||||||
layout.operator("paint.vert_select_linked", text="Select Linked")
|
layout.operator("paint.vert_select_linked", text="Select Linked")
|
||||||
|
|
||||||
|
|
||||||
|
class VIEW3D_MT_edit_curves_select_more_less(Menu):
|
||||||
|
bl_label = "Select More/Less"
|
||||||
|
|
||||||
|
def draw(self, _context):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
layout.operator("curves.select_more", text="More")
|
||||||
|
layout.operator("curves.select_less", text="Less")
|
||||||
|
|
||||||
|
|
||||||
class VIEW3D_MT_select_edit_curves(Menu):
|
class VIEW3D_MT_select_edit_curves(Menu):
|
||||||
bl_label = "Select"
|
bl_label = "Select"
|
||||||
|
|
||||||
@ -2050,10 +2063,17 @@ class VIEW3D_MT_select_edit_curves(Menu):
|
|||||||
layout.operator("curves.select_all", text="All").action = 'SELECT'
|
layout.operator("curves.select_all", text="All").action = 'SELECT'
|
||||||
layout.operator("curves.select_all", text="None").action = 'DESELECT'
|
layout.operator("curves.select_all", text="None").action = 'DESELECT'
|
||||||
layout.operator("curves.select_all", text="Invert").action = 'INVERT'
|
layout.operator("curves.select_all", text="Invert").action = 'INVERT'
|
||||||
|
|
||||||
|
layout.separator()
|
||||||
|
|
||||||
layout.operator("curves.select_random", text="Random")
|
layout.operator("curves.select_random", text="Random")
|
||||||
layout.operator("curves.select_end", text="Endpoints")
|
layout.operator("curves.select_end", text="Endpoints")
|
||||||
layout.operator("curves.select_linked", text="Linked")
|
layout.operator("curves.select_linked", text="Linked")
|
||||||
|
|
||||||
|
layout.separator()
|
||||||
|
|
||||||
|
layout.menu("VIEW3D_MT_edit_curves_select_more_less")
|
||||||
|
|
||||||
|
|
||||||
class VIEW3D_MT_select_sculpt_curves(Menu):
|
class VIEW3D_MT_select_sculpt_curves(Menu):
|
||||||
bl_label = "Select"
|
bl_label = "Select"
|
||||||
@ -2114,6 +2134,7 @@ class VIEW3D_MT_curve_add(Menu):
|
|||||||
layout.separator()
|
layout.separator()
|
||||||
|
|
||||||
layout.operator("object.curves_empty_hair_add", text="Empty Hair", icon='CURVES_DATA')
|
layout.operator("object.curves_empty_hair_add", text="Empty Hair", icon='CURVES_DATA')
|
||||||
|
layout.operator("object.quick_fur", text="Fur", icon='CURVES_DATA')
|
||||||
|
|
||||||
experimental = context.preferences.experimental
|
experimental = context.preferences.experimental
|
||||||
if experimental.use_new_curves_tools:
|
if experimental.use_new_curves_tools:
|
||||||
@ -2268,7 +2289,7 @@ class VIEW3D_MT_add(Menu):
|
|||||||
# NOTE: don't use 'EXEC_SCREEN' or operators won't get the `v3d` context.
|
# NOTE: don't use 'EXEC_SCREEN' or operators won't get the `v3d` context.
|
||||||
|
|
||||||
# NOTE: was `EXEC_AREA`, but this context does not have the `rv3d`, which prevents
|
# NOTE: was `EXEC_AREA`, but this context does not have the `rv3d`, which prevents
|
||||||
# "align_view" to work on first call (see T32719).
|
# "align_view" to work on first call (see #32719).
|
||||||
layout.operator_context = 'EXEC_REGION_WIN'
|
layout.operator_context = 'EXEC_REGION_WIN'
|
||||||
|
|
||||||
# layout.operator_menu_enum("object.mesh_add", "type", text="Mesh", icon='OUTLINER_OB_MESH')
|
# layout.operator_menu_enum("object.mesh_add", "type", text="Mesh", icon='OUTLINER_OB_MESH')
|
||||||
@ -3867,6 +3888,7 @@ class VIEW3D_MT_edit_mesh(Menu):
|
|||||||
layout.menu("VIEW3D_MT_edit_mesh_normals")
|
layout.menu("VIEW3D_MT_edit_mesh_normals")
|
||||||
layout.menu("VIEW3D_MT_edit_mesh_shading")
|
layout.menu("VIEW3D_MT_edit_mesh_shading")
|
||||||
layout.menu("VIEW3D_MT_edit_mesh_weights")
|
layout.menu("VIEW3D_MT_edit_mesh_weights")
|
||||||
|
layout.operator("mesh.attribute_set")
|
||||||
layout.operator_menu_enum("mesh.sort_elements", "type", text="Sort Elements...")
|
layout.operator_menu_enum("mesh.sort_elements", "type", text="Sort Elements...")
|
||||||
|
|
||||||
layout.separator()
|
layout.separator()
|
||||||
@ -5308,6 +5330,7 @@ class VIEW3D_MT_edit_curves(Menu):
|
|||||||
|
|
||||||
layout.menu("VIEW3D_MT_transform")
|
layout.menu("VIEW3D_MT_transform")
|
||||||
layout.separator()
|
layout.separator()
|
||||||
|
layout.operator("curves.delete")
|
||||||
|
|
||||||
|
|
||||||
class VIEW3D_MT_object_mode_pie(Menu):
|
class VIEW3D_MT_object_mode_pie(Menu):
|
||||||
@ -5376,7 +5399,7 @@ class VIEW3D_MT_shading_ex_pie(Menu):
|
|||||||
pie.prop_enum(view.shading, "type", value='WIREFRAME')
|
pie.prop_enum(view.shading, "type", value='WIREFRAME')
|
||||||
pie.prop_enum(view.shading, "type", value='SOLID')
|
pie.prop_enum(view.shading, "type", value='SOLID')
|
||||||
|
|
||||||
# Note this duplicates "view3d.toggle_xray" logic, so we can see the active item: T58661.
|
# Note this duplicates "view3d.toggle_xray" logic, so we can see the active item: #58661.
|
||||||
if context.pose_object:
|
if context.pose_object:
|
||||||
pie.prop(view.overlay, "show_xray_bone", icon='XRAY')
|
pie.prop(view.overlay, "show_xray_bone", icon='XRAY')
|
||||||
else:
|
else:
|
||||||
@ -6718,15 +6741,15 @@ class VIEW3D_PT_overlay_sculpt(Panel):
|
|||||||
overlay = view.overlay
|
overlay = view.overlay
|
||||||
|
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.prop(overlay, "sculpt_show_mask", text="")
|
row.prop(overlay, "show_sculpt_mask", text="")
|
||||||
sub = row.row()
|
sub = row.row()
|
||||||
sub.active = overlay.sculpt_show_mask
|
sub.active = overlay.show_sculpt_mask
|
||||||
sub.prop(overlay, "sculpt_mode_mask_opacity", text="Mask")
|
sub.prop(overlay, "sculpt_mode_mask_opacity", text="Mask")
|
||||||
|
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.prop(overlay, "sculpt_show_face_sets", text="")
|
row.prop(overlay, "show_sculpt_face_sets", text="")
|
||||||
sub = row.row()
|
sub = row.row()
|
||||||
sub.active = overlay.sculpt_show_face_sets
|
sub.active = overlay.show_sculpt_face_sets
|
||||||
row.prop(overlay, "sculpt_mode_face_sets_opacity", text="Face Sets")
|
row.prop(overlay, "sculpt_mode_face_sets_opacity", text="Face Sets")
|
||||||
|
|
||||||
|
|
||||||
@ -6753,6 +6776,13 @@ class VIEW3D_PT_overlay_sculpt_curves(Panel):
|
|||||||
row.active = overlay.show_overlays
|
row.active = overlay.show_overlays
|
||||||
row.prop(overlay, "sculpt_mode_mask_opacity", text="Selection Opacity")
|
row.prop(overlay, "sculpt_mode_mask_opacity", text="Selection Opacity")
|
||||||
|
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.active = overlay.show_overlays
|
||||||
|
row.prop(overlay, "show_sculpt_curves_cage", text="")
|
||||||
|
subrow = row.row(align=True)
|
||||||
|
subrow.active = overlay.show_sculpt_curves_cage
|
||||||
|
subrow.prop(overlay, "sculpt_curves_cage_opacity", text="Cage Opacity")
|
||||||
|
|
||||||
|
|
||||||
class VIEW3D_PT_overlay_bones(Panel):
|
class VIEW3D_PT_overlay_bones(Panel):
|
||||||
bl_space_type = 'VIEW_3D'
|
bl_space_type = 'VIEW_3D'
|
||||||
@ -7934,6 +7964,28 @@ class VIEW3D_PT_curves_sculpt_add_shape(Panel):
|
|||||||
col.prop(brush.curves_sculpt_settings, "points_per_curve", text="Points")
|
col.prop(brush.curves_sculpt_settings, "points_per_curve", text="Points")
|
||||||
|
|
||||||
|
|
||||||
|
class VIEW3D_PT_curves_sculpt_parameter_falloff(Panel):
|
||||||
|
# Only for popover, these are dummy values.
|
||||||
|
bl_space_type = 'VIEW_3D'
|
||||||
|
bl_region_type = 'WINDOW'
|
||||||
|
bl_label = "Curves Sculpt Parameter Falloff"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
settings = UnifiedPaintPanel.paint_settings(context)
|
||||||
|
brush = settings.brush
|
||||||
|
|
||||||
|
layout.template_curve_mapping(brush.curves_sculpt_settings, "curve_parameter_falloff")
|
||||||
|
row = layout.row(align=True)
|
||||||
|
row.operator("brush.sculpt_curves_falloff_preset", icon='SMOOTHCURVE', text="").shape = 'SMOOTH'
|
||||||
|
row.operator("brush.sculpt_curves_falloff_preset", icon='SPHERECURVE', text="").shape = 'ROUND'
|
||||||
|
row.operator("brush.sculpt_curves_falloff_preset", icon='ROOTCURVE', text="").shape = 'ROOT'
|
||||||
|
row.operator("brush.sculpt_curves_falloff_preset", icon='SHARPCURVE', text="").shape = 'SHARP'
|
||||||
|
row.operator("brush.sculpt_curves_falloff_preset", icon='LINCURVE', text="").shape = 'LINE'
|
||||||
|
row.operator("brush.sculpt_curves_falloff_preset", icon='NOCURVE', text="").shape = 'MAX'
|
||||||
|
|
||||||
|
|
||||||
class VIEW3D_PT_curves_sculpt_grow_shrink_scaling(Panel):
|
class VIEW3D_PT_curves_sculpt_grow_shrink_scaling(Panel):
|
||||||
# Only for popover, these are dummy values.
|
# Only for popover, these are dummy values.
|
||||||
bl_space_type = 'VIEW_3D'
|
bl_space_type = 'VIEW_3D'
|
||||||
@ -8011,6 +8063,7 @@ classes = (
|
|||||||
VIEW3D_MT_select_gpencil,
|
VIEW3D_MT_select_gpencil,
|
||||||
VIEW3D_MT_select_paint_mask,
|
VIEW3D_MT_select_paint_mask,
|
||||||
VIEW3D_MT_select_paint_mask_vertex,
|
VIEW3D_MT_select_paint_mask_vertex,
|
||||||
|
VIEW3D_MT_edit_curves_select_more_less,
|
||||||
VIEW3D_MT_select_edit_curves,
|
VIEW3D_MT_select_edit_curves,
|
||||||
VIEW3D_MT_select_sculpt_curves,
|
VIEW3D_MT_select_sculpt_curves,
|
||||||
VIEW3D_MT_mesh_add,
|
VIEW3D_MT_mesh_add,
|
||||||
@ -8211,6 +8264,7 @@ classes = (
|
|||||||
TOPBAR_PT_gpencil_vertexcolor,
|
TOPBAR_PT_gpencil_vertexcolor,
|
||||||
TOPBAR_PT_annotation_layers,
|
TOPBAR_PT_annotation_layers,
|
||||||
VIEW3D_PT_curves_sculpt_add_shape,
|
VIEW3D_PT_curves_sculpt_add_shape,
|
||||||
|
VIEW3D_PT_curves_sculpt_parameter_falloff,
|
||||||
VIEW3D_PT_curves_sculpt_grow_shrink_scaling,
|
VIEW3D_PT_curves_sculpt_grow_shrink_scaling,
|
||||||
VIEW3D_PT_viewport_debug,
|
VIEW3D_PT_viewport_debug,
|
||||||
)
|
)
|
||||||
|
@ -639,7 +639,7 @@ class BUILTIN_KSI_DeltaScale(KeyingSetInfo):
|
|||||||
|
|
||||||
# Note that this controls order of options in `insert keyframe` menu.
|
# Note that this controls order of options in `insert keyframe` menu.
|
||||||
# Better try to keep some logical order here beyond mere alphabetical one, also because of menu entries shortcut.
|
# Better try to keep some logical order here beyond mere alphabetical one, also because of menu entries shortcut.
|
||||||
# See also T51867.
|
# See also #51867.
|
||||||
classes = (
|
classes = (
|
||||||
BUILTIN_KSI_Available,
|
BUILTIN_KSI_Available,
|
||||||
BUILTIN_KSI_Location,
|
BUILTIN_KSI_Location,
|
||||||
|
@ -58,6 +58,11 @@ class AssetLibrary {
|
|||||||
|
|
||||||
std::function<void(AssetLibrary &self)> on_refresh_;
|
std::function<void(AssetLibrary &self)> on_refresh_;
|
||||||
|
|
||||||
|
std::optional<eAssetImportMethod> import_method_;
|
||||||
|
/** Assets owned by this library may be imported with a different method than set in
|
||||||
|
* #import_method_ above, it's just a default. */
|
||||||
|
bool may_override_import_method_ = false;
|
||||||
|
|
||||||
bCallbackFuncStore on_save_callback_store_{};
|
bCallbackFuncStore on_save_callback_store_{};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -68,6 +73,7 @@ class AssetLibrary {
|
|||||||
std::unique_ptr<AssetCatalogService> catalog_service;
|
std::unique_ptr<AssetCatalogService> catalog_service;
|
||||||
|
|
||||||
friend class AssetLibraryService;
|
friend class AssetLibraryService;
|
||||||
|
friend class AssetRepresentation;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -22,6 +22,8 @@ const char *AS_asset_representation_name_get(const AssetRepresentation *asset)
|
|||||||
AssetMetaData *AS_asset_representation_metadata_get(const AssetRepresentation *asset)
|
AssetMetaData *AS_asset_representation_metadata_get(const AssetRepresentation *asset)
|
||||||
ATTR_WARN_UNUSED_RESULT;
|
ATTR_WARN_UNUSED_RESULT;
|
||||||
bool AS_asset_representation_is_local_id(const AssetRepresentation *asset) ATTR_WARN_UNUSED_RESULT;
|
bool AS_asset_representation_is_local_id(const AssetRepresentation *asset) ATTR_WARN_UNUSED_RESULT;
|
||||||
|
bool AS_asset_representation_is_never_link(const AssetRepresentation *asset)
|
||||||
|
ATTR_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "BLI_string_ref.hh"
|
#include "BLI_string_ref.hh"
|
||||||
|
|
||||||
|
#include "DNA_asset_types.h"
|
||||||
|
|
||||||
#include "AS_asset_identifier.hh"
|
#include "AS_asset_identifier.hh"
|
||||||
|
|
||||||
struct AssetMetaData;
|
struct AssetMetaData;
|
||||||
@ -23,11 +26,15 @@ struct ID;
|
|||||||
|
|
||||||
namespace blender::asset_system {
|
namespace blender::asset_system {
|
||||||
|
|
||||||
|
class AssetLibrary;
|
||||||
|
|
||||||
class AssetRepresentation {
|
class AssetRepresentation {
|
||||||
AssetIdentifier identifier_;
|
AssetIdentifier identifier_;
|
||||||
/** Indicate if this is a local or external asset, and as such, which of the union members below
|
/** Indicate if this is a local or external asset, and as such, which of the union members below
|
||||||
* should be used. */
|
* should be used. */
|
||||||
const bool is_local_id_ = false;
|
const bool is_local_id_ = false;
|
||||||
|
/** Asset library that owns this asset representation. */
|
||||||
|
const AssetLibrary *owner_asset_library_;
|
||||||
|
|
||||||
struct ExternalAsset {
|
struct ExternalAsset {
|
||||||
std::string name;
|
std::string name;
|
||||||
@ -44,10 +51,13 @@ class AssetRepresentation {
|
|||||||
/** Constructs an asset representation for an external ID. The asset will not be editable. */
|
/** Constructs an asset representation for an external ID. The asset will not be editable. */
|
||||||
AssetRepresentation(AssetIdentifier &&identifier,
|
AssetRepresentation(AssetIdentifier &&identifier,
|
||||||
StringRef name,
|
StringRef name,
|
||||||
std::unique_ptr<AssetMetaData> metadata);
|
std::unique_ptr<AssetMetaData> metadata,
|
||||||
|
const AssetLibrary &owner_asset_library);
|
||||||
/** Constructs an asset representation for an ID stored in the current file. This makes the asset
|
/** Constructs an asset representation for an ID stored in the current file. This makes the asset
|
||||||
* local and fully editable. */
|
* local and fully editable. */
|
||||||
AssetRepresentation(AssetIdentifier &&identifier, ID &id);
|
AssetRepresentation(AssetIdentifier &&identifier,
|
||||||
|
ID &id,
|
||||||
|
const AssetLibrary &owner_asset_library);
|
||||||
AssetRepresentation(AssetRepresentation &&other);
|
AssetRepresentation(AssetRepresentation &&other);
|
||||||
/* Non-copyable type. */
|
/* Non-copyable type. */
|
||||||
AssetRepresentation(const AssetRepresentation &other) = delete;
|
AssetRepresentation(const AssetRepresentation &other) = delete;
|
||||||
@ -63,8 +73,18 @@ class AssetRepresentation {
|
|||||||
|
|
||||||
StringRefNull get_name() const;
|
StringRefNull get_name() const;
|
||||||
AssetMetaData &get_metadata() const;
|
AssetMetaData &get_metadata() const;
|
||||||
|
/** Get the import method to use for this asset. A different one may be used if
|
||||||
|
* #may_override_import_method() returns true, otherwise, the returned value must be used. If
|
||||||
|
* there is no import method predefined for this asset no value is returned.
|
||||||
|
*/
|
||||||
|
std::optional<eAssetImportMethod> get_import_method() const;
|
||||||
|
/** Returns if this asset may be imported with an import method other than the one returned by
|
||||||
|
* #get_import_method(). Also returns true if there is no predefined import method
|
||||||
|
* (when #get_import_method() returns no value). */
|
||||||
|
bool may_override_import_method() const;
|
||||||
/** Returns if this asset is stored inside this current file, and as such fully editable. */
|
/** Returns if this asset is stored inside this current file, and as such fully editable. */
|
||||||
bool is_local_id() const;
|
bool is_local_id() const;
|
||||||
|
const AssetLibrary &owner_asset_library() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace blender::asset_system
|
} // namespace blender::asset_system
|
||||||
@ -73,3 +93,6 @@ class AssetRepresentation {
|
|||||||
struct AssetRepresentation;
|
struct AssetRepresentation;
|
||||||
|
|
||||||
const std::string AS_asset_representation_full_path_get(const ::AssetRepresentation *asset);
|
const std::string AS_asset_representation_full_path_get(const ::AssetRepresentation *asset);
|
||||||
|
std::optional<eAssetImportMethod> AS_asset_representation_import_method_get(
|
||||||
|
const ::AssetRepresentation *asset_handle);
|
||||||
|
bool AS_asset_representation_may_override_import_method(const ::AssetRepresentation *asset_handle);
|
||||||
|
15
source/blender/asset_system/AS_essentials_library.hh
Normal file
15
source/blender/asset_system/AS_essentials_library.hh
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
/** \file
|
||||||
|
* \ingroup asset_system
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "BLI_string_ref.hh"
|
||||||
|
|
||||||
|
namespace blender::asset_system {
|
||||||
|
|
||||||
|
StringRefNull essentials_directory_path();
|
||||||
|
|
||||||
|
}
|
@ -17,6 +17,7 @@ set(SRC
|
|||||||
intern/asset_catalog.cc
|
intern/asset_catalog.cc
|
||||||
intern/asset_catalog_path.cc
|
intern/asset_catalog_path.cc
|
||||||
intern/asset_catalog_tree.cc
|
intern/asset_catalog_tree.cc
|
||||||
|
intern/asset_essentials_library.cc
|
||||||
intern/asset_identifier.cc
|
intern/asset_identifier.cc
|
||||||
intern/asset_library.cc
|
intern/asset_library.cc
|
||||||
intern/asset_library_service.cc
|
intern/asset_library_service.cc
|
||||||
@ -30,6 +31,7 @@ set(SRC
|
|||||||
AS_asset_identifier.hh
|
AS_asset_identifier.hh
|
||||||
AS_asset_library.hh
|
AS_asset_library.hh
|
||||||
AS_asset_representation.hh
|
AS_asset_representation.hh
|
||||||
|
AS_essentials_library.hh
|
||||||
intern/asset_library_service.hh
|
intern/asset_library_service.hh
|
||||||
intern/asset_storage.hh
|
intern/asset_storage.hh
|
||||||
intern/utils.hh
|
intern/utils.hh
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
/** \file
|
||||||
|
* \ingroup asset_system
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "BLI_path_util.h"
|
||||||
|
|
||||||
|
#include "BKE_appdir.h"
|
||||||
|
|
||||||
|
#include "AS_essentials_library.hh"
|
||||||
|
|
||||||
|
namespace blender::asset_system {
|
||||||
|
|
||||||
|
StringRefNull essentials_directory_path()
|
||||||
|
{
|
||||||
|
static std::string path = []() {
|
||||||
|
const char *datafiles_path = BKE_appdir_folder_id(BLENDER_DATAFILES, "assets");
|
||||||
|
return datafiles_path;
|
||||||
|
}();
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace blender::asset_system
|
@ -169,13 +169,14 @@ AssetRepresentation &AssetLibrary::add_external_asset(StringRef relative_asset_p
|
|||||||
std::unique_ptr<AssetMetaData> metadata)
|
std::unique_ptr<AssetMetaData> metadata)
|
||||||
{
|
{
|
||||||
AssetIdentifier identifier = asset_identifier_from_library(relative_asset_path);
|
AssetIdentifier identifier = asset_identifier_from_library(relative_asset_path);
|
||||||
return asset_storage_->add_external_asset(std::move(identifier), name, std::move(metadata));
|
return asset_storage_->add_external_asset(
|
||||||
|
std::move(identifier), name, std::move(metadata), *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetRepresentation &AssetLibrary::add_local_id_asset(StringRef relative_asset_path, ID &id)
|
AssetRepresentation &AssetLibrary::add_local_id_asset(StringRef relative_asset_path, ID &id)
|
||||||
{
|
{
|
||||||
AssetIdentifier identifier = asset_identifier_from_library(relative_asset_path);
|
AssetIdentifier identifier = asset_identifier_from_library(relative_asset_path);
|
||||||
return asset_storage_->add_local_id_asset(std::move(identifier), id);
|
return asset_storage_->add_local_id_asset(std::move(identifier), id, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AssetLibrary::remove_asset(AssetRepresentation &asset)
|
bool AssetLibrary::remove_asset(AssetRepresentation &asset)
|
||||||
@ -259,6 +260,12 @@ StringRefNull AssetLibrary::root_path() const
|
|||||||
Vector<AssetLibraryReference> all_valid_asset_library_refs()
|
Vector<AssetLibraryReference> all_valid_asset_library_refs()
|
||||||
{
|
{
|
||||||
Vector<AssetLibraryReference> result;
|
Vector<AssetLibraryReference> result;
|
||||||
|
{
|
||||||
|
AssetLibraryReference library_ref{};
|
||||||
|
library_ref.custom_library_index = -1;
|
||||||
|
library_ref.type = ASSET_LIBRARY_ESSENTIALS;
|
||||||
|
result.append(library_ref);
|
||||||
|
}
|
||||||
int i;
|
int i;
|
||||||
LISTBASE_FOREACH_INDEX (const bUserAssetLibrary *, asset_library, &U.asset_libraries, i) {
|
LISTBASE_FOREACH_INDEX (const bUserAssetLibrary *, asset_library, &U.asset_libraries, i) {
|
||||||
if (!BLI_is_dir(asset_library->path)) {
|
if (!BLI_is_dir(asset_library->path)) {
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "AS_asset_catalog_tree.hh"
|
#include "AS_asset_catalog_tree.hh"
|
||||||
#include "AS_asset_library.hh"
|
#include "AS_asset_library.hh"
|
||||||
|
#include "AS_essentials_library.hh"
|
||||||
#include "asset_library_service.hh"
|
#include "asset_library_service.hh"
|
||||||
#include "utils.hh"
|
#include "utils.hh"
|
||||||
|
|
||||||
@ -60,6 +61,14 @@ AssetLibrary *AssetLibraryService::get_asset_library(
|
|||||||
const eAssetLibraryType type = eAssetLibraryType(library_reference.type);
|
const eAssetLibraryType type = eAssetLibraryType(library_reference.type);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case ASSET_LIBRARY_ESSENTIALS: {
|
||||||
|
const StringRefNull root_path = essentials_directory_path();
|
||||||
|
|
||||||
|
AssetLibrary *library = get_asset_library_on_disk(root_path);
|
||||||
|
library->import_method_ = ASSET_IMPORT_APPEND_REUSE;
|
||||||
|
|
||||||
|
return library;
|
||||||
|
}
|
||||||
case ASSET_LIBRARY_LOCAL: {
|
case ASSET_LIBRARY_LOCAL: {
|
||||||
/* For the "Current File" library we get the asset library root path based on main. */
|
/* For the "Current File" library we get the asset library root path based on main. */
|
||||||
std::string root_path = bmain ? AS_asset_library_find_suitable_root_path_from_main(bmain) :
|
std::string root_path = bmain ? AS_asset_library_find_suitable_root_path_from_main(bmain) :
|
||||||
@ -74,12 +83,22 @@ AssetLibrary *AssetLibraryService::get_asset_library(
|
|||||||
case ASSET_LIBRARY_ALL:
|
case ASSET_LIBRARY_ALL:
|
||||||
return get_asset_library_all(bmain);
|
return get_asset_library_all(bmain);
|
||||||
case ASSET_LIBRARY_CUSTOM: {
|
case ASSET_LIBRARY_CUSTOM: {
|
||||||
std::string root_path = root_path_from_library_ref(library_reference);
|
bUserAssetLibrary *custom_library = find_custom_asset_library_from_library_ref(
|
||||||
|
library_reference);
|
||||||
if (!root_path.empty()) {
|
if (!custom_library) {
|
||||||
return get_asset_library_on_disk(root_path);
|
return nullptr;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
std::string root_path = custom_library->path;
|
||||||
|
if (root_path.empty()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetLibrary *library = get_asset_library_on_disk(root_path);
|
||||||
|
library->import_method_ = eAssetImportMethod(custom_library->import_method);
|
||||||
|
library->may_override_import_method_ = true;
|
||||||
|
|
||||||
|
return library;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,6 +199,15 @@ AssetLibrary *AssetLibraryService::get_asset_library_all(const Main *bmain)
|
|||||||
return all_library_.get();
|
return all_library_.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bUserAssetLibrary *AssetLibraryService::find_custom_asset_library_from_library_ref(
|
||||||
|
const AssetLibraryReference &library_reference)
|
||||||
|
{
|
||||||
|
BLI_assert(library_reference.type == ASSET_LIBRARY_CUSTOM);
|
||||||
|
BLI_assert(library_reference.custom_library_index >= 0);
|
||||||
|
|
||||||
|
return BKE_preferences_asset_library_find_from_index(&U, library_reference.custom_library_index);
|
||||||
|
}
|
||||||
|
|
||||||
std::string AssetLibraryService::root_path_from_library_ref(
|
std::string AssetLibraryService::root_path_from_library_ref(
|
||||||
const AssetLibraryReference &library_reference)
|
const AssetLibraryReference &library_reference)
|
||||||
{
|
{
|
||||||
@ -187,16 +215,13 @@ std::string AssetLibraryService::root_path_from_library_ref(
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
BLI_assert(library_reference.type == ASSET_LIBRARY_CUSTOM);
|
bUserAssetLibrary *custom_library = find_custom_asset_library_from_library_ref(
|
||||||
BLI_assert(library_reference.custom_library_index >= 0);
|
library_reference);
|
||||||
|
if (!custom_library || !custom_library->path[0]) {
|
||||||
bUserAssetLibrary *user_library = BKE_preferences_asset_library_find_from_index(
|
|
||||||
&U, library_reference.custom_library_index);
|
|
||||||
if (!user_library || !user_library->path[0]) {
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
return user_library->path;
|
return custom_library->path;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetLibraryService::allocate_service_instance()
|
void AssetLibraryService::allocate_service_instance()
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
struct AssetLibraryReference;
|
struct AssetLibraryReference;
|
||||||
|
struct bUserAssetLibrary;
|
||||||
|
|
||||||
namespace blender::asset_system {
|
namespace blender::asset_system {
|
||||||
|
|
||||||
@ -58,6 +59,8 @@ class AssetLibraryService {
|
|||||||
static void destroy();
|
static void destroy();
|
||||||
|
|
||||||
static std::string root_path_from_library_ref(const AssetLibraryReference &library_reference);
|
static std::string root_path_from_library_ref(const AssetLibraryReference &library_reference);
|
||||||
|
static bUserAssetLibrary *find_custom_asset_library_from_library_ref(
|
||||||
|
const AssetLibraryReference &library_reference);
|
||||||
|
|
||||||
AssetLibrary *get_asset_library(const Main *bmain,
|
AssetLibrary *get_asset_library(const Main *bmain,
|
||||||
const AssetLibraryReference &library_reference);
|
const AssetLibraryReference &library_reference);
|
||||||
|
@ -8,8 +8,10 @@
|
|||||||
|
|
||||||
#include "DNA_ID.h"
|
#include "DNA_ID.h"
|
||||||
#include "DNA_asset_types.h"
|
#include "DNA_asset_types.h"
|
||||||
|
#include "DNA_userdef_types.h"
|
||||||
|
|
||||||
#include "AS_asset_identifier.hh"
|
#include "AS_asset_identifier.hh"
|
||||||
|
#include "AS_asset_library.hh"
|
||||||
#include "AS_asset_representation.h"
|
#include "AS_asset_representation.h"
|
||||||
#include "AS_asset_representation.hh"
|
#include "AS_asset_representation.hh"
|
||||||
|
|
||||||
@ -17,15 +19,24 @@ namespace blender::asset_system {
|
|||||||
|
|
||||||
AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier,
|
AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier,
|
||||||
StringRef name,
|
StringRef name,
|
||||||
std::unique_ptr<AssetMetaData> metadata)
|
std::unique_ptr<AssetMetaData> metadata,
|
||||||
: identifier_(identifier), is_local_id_(false), external_asset_()
|
const AssetLibrary &owner_asset_library)
|
||||||
|
: identifier_(identifier),
|
||||||
|
is_local_id_(false),
|
||||||
|
owner_asset_library_(&owner_asset_library),
|
||||||
|
external_asset_()
|
||||||
{
|
{
|
||||||
external_asset_.name = name;
|
external_asset_.name = name;
|
||||||
external_asset_.metadata_ = std::move(metadata);
|
external_asset_.metadata_ = std::move(metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier, ID &id)
|
AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier,
|
||||||
: identifier_(identifier), is_local_id_(true), local_asset_id_(&id)
|
ID &id,
|
||||||
|
const AssetLibrary &owner_asset_library)
|
||||||
|
: identifier_(identifier),
|
||||||
|
is_local_id_(true),
|
||||||
|
owner_asset_library_(&owner_asset_library),
|
||||||
|
local_asset_id_(&id)
|
||||||
{
|
{
|
||||||
if (!id.asset_data) {
|
if (!id.asset_data) {
|
||||||
throw std::invalid_argument("Passed ID is not an asset");
|
throw std::invalid_argument("Passed ID is not an asset");
|
||||||
@ -70,11 +81,32 @@ AssetMetaData &AssetRepresentation::get_metadata() const
|
|||||||
return is_local_id_ ? *local_asset_id_->asset_data : *external_asset_.metadata_;
|
return is_local_id_ ? *local_asset_id_->asset_data : *external_asset_.metadata_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<eAssetImportMethod> AssetRepresentation::get_import_method() const
|
||||||
|
{
|
||||||
|
if (!owner_asset_library_) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return owner_asset_library_->import_method_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssetRepresentation::may_override_import_method() const
|
||||||
|
{
|
||||||
|
if (!owner_asset_library_ || !owner_asset_library_->import_method_) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return owner_asset_library_->may_override_import_method_;
|
||||||
|
}
|
||||||
|
|
||||||
bool AssetRepresentation::is_local_id() const
|
bool AssetRepresentation::is_local_id() const
|
||||||
{
|
{
|
||||||
return is_local_id_;
|
return is_local_id_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const AssetLibrary &AssetRepresentation::owner_asset_library() const
|
||||||
|
{
|
||||||
|
return *owner_asset_library_;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace blender::asset_system
|
} // namespace blender::asset_system
|
||||||
|
|
||||||
using namespace blender;
|
using namespace blender;
|
||||||
@ -87,6 +119,21 @@ const std::string AS_asset_representation_full_path_get(const AssetRepresentatio
|
|||||||
return identifier.full_path();
|
return identifier.full_path();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<eAssetImportMethod> AS_asset_representation_import_method_get(
|
||||||
|
const AssetRepresentation *asset_handle)
|
||||||
|
{
|
||||||
|
const asset_system::AssetRepresentation *asset =
|
||||||
|
reinterpret_cast<const asset_system::AssetRepresentation *>(asset_handle);
|
||||||
|
return asset->get_import_method();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AS_asset_representation_may_override_import_method(const AssetRepresentation *asset_handle)
|
||||||
|
{
|
||||||
|
const asset_system::AssetRepresentation *asset =
|
||||||
|
reinterpret_cast<const asset_system::AssetRepresentation *>(asset_handle);
|
||||||
|
return asset->may_override_import_method();
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
/** \name C-API
|
/** \name C-API
|
||||||
* \{ */
|
* \{ */
|
||||||
|
@ -15,18 +15,21 @@
|
|||||||
|
|
||||||
namespace blender::asset_system {
|
namespace blender::asset_system {
|
||||||
|
|
||||||
AssetRepresentation &AssetStorage::add_local_id_asset(AssetIdentifier &&identifier, ID &id)
|
AssetRepresentation &AssetStorage::add_local_id_asset(AssetIdentifier &&identifier,
|
||||||
|
ID &id,
|
||||||
|
const AssetLibrary &owner_asset_library)
|
||||||
{
|
{
|
||||||
return *local_id_assets_.lookup_key_or_add(
|
return *local_id_assets_.lookup_key_or_add(
|
||||||
std::make_unique<AssetRepresentation>(std::move(identifier), id));
|
std::make_unique<AssetRepresentation>(std::move(identifier), id, owner_asset_library));
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetRepresentation &AssetStorage::add_external_asset(AssetIdentifier &&identifier,
|
AssetRepresentation &AssetStorage::add_external_asset(AssetIdentifier &&identifier,
|
||||||
StringRef name,
|
StringRef name,
|
||||||
std::unique_ptr<AssetMetaData> metadata)
|
std::unique_ptr<AssetMetaData> metadata,
|
||||||
|
const AssetLibrary &owner_asset_library)
|
||||||
{
|
{
|
||||||
return *external_assets_.lookup_key_or_add(
|
return *external_assets_.lookup_key_or_add(std::make_unique<AssetRepresentation>(
|
||||||
std::make_unique<AssetRepresentation>(std::move(identifier), name, std::move(metadata)));
|
std::move(identifier), name, std::move(metadata), owner_asset_library));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AssetStorage::remove_asset(AssetRepresentation &asset)
|
bool AssetStorage::remove_asset(AssetRepresentation &asset)
|
||||||
|
@ -35,9 +35,12 @@ class AssetStorage {
|
|||||||
/** See #AssetLibrary::add_external_asset(). */
|
/** See #AssetLibrary::add_external_asset(). */
|
||||||
AssetRepresentation &add_external_asset(AssetIdentifier &&identifier,
|
AssetRepresentation &add_external_asset(AssetIdentifier &&identifier,
|
||||||
StringRef name,
|
StringRef name,
|
||||||
std::unique_ptr<AssetMetaData> metadata);
|
std::unique_ptr<AssetMetaData> metadata,
|
||||||
|
const AssetLibrary &owner_asset_library);
|
||||||
/** See #AssetLibrary::add_external_asset(). */
|
/** See #AssetLibrary::add_external_asset(). */
|
||||||
AssetRepresentation &add_local_id_asset(AssetIdentifier &&identifier, ID &id);
|
AssetRepresentation &add_local_id_asset(AssetIdentifier &&identifier,
|
||||||
|
ID &id,
|
||||||
|
const AssetLibrary &owner_asset_library);
|
||||||
|
|
||||||
/** See #AssetLibrary::remove_asset(). */
|
/** See #AssetLibrary::remove_asset(). */
|
||||||
bool remove_asset(AssetRepresentation &asset);
|
bool remove_asset(AssetRepresentation &asset);
|
||||||
|
@ -165,7 +165,7 @@ int BLF_load_unique(const char *name)
|
|||||||
|
|
||||||
/* XXX: Temporarily disable kerning in our main font. Kerning had been accidentally removed from
|
/* XXX: Temporarily disable kerning in our main font. Kerning had been accidentally removed from
|
||||||
* our font in 3.1. In 3.4 we disable kerning here in the new version to keep spacing the same
|
* our font in 3.1. In 3.4 we disable kerning here in the new version to keep spacing the same
|
||||||
* (T101506). Enable again later with change of font, placement, or rendering - Harley. */
|
* (#101506). Enable again later with change of font, placement, or rendering - Harley. */
|
||||||
if (font && BLI_str_endswith(filepath, BLF_DEFAULT_PROPORTIONAL_FONT)) {
|
if (font && BLI_str_endswith(filepath, BLF_DEFAULT_PROPORTIONAL_FONT)) {
|
||||||
font->face_flags &= ~FT_FACE_FLAG_KERNING;
|
font->face_flags &= ~FT_FACE_FLAG_KERNING;
|
||||||
}
|
}
|
||||||
|
@ -271,7 +271,7 @@ struct bPoseChannel *BKE_pose_channel_active_if_layer_visible(struct Object *ob)
|
|||||||
* In this case the active-selected is an obvious choice when finding the target for a
|
* In this case the active-selected is an obvious choice when finding the target for a
|
||||||
* constraint for eg. however from the users perspective the active pose bone of the
|
* constraint for eg. however from the users perspective the active pose bone of the
|
||||||
* active object is the _real_ active bone, so any other non-active selected bone
|
* active object is the _real_ active bone, so any other non-active selected bone
|
||||||
* is a candidate for being the other selected bone, see: T58447.
|
* is a candidate for being the other selected bone, see: #58447.
|
||||||
*/
|
*/
|
||||||
struct bPoseChannel *BKE_pose_channel_active_or_first_selected(struct Object *ob);
|
struct bPoseChannel *BKE_pose_channel_active_or_first_selected(struct Object *ob);
|
||||||
/**
|
/**
|
||||||
|
@ -37,7 +37,7 @@ struct bActionGroup;
|
|||||||
/* Container for data required to do FCurve and Driver evaluation. */
|
/* Container for data required to do FCurve and Driver evaluation. */
|
||||||
typedef struct AnimationEvalContext {
|
typedef struct AnimationEvalContext {
|
||||||
/* For drivers, so that they have access to the dependency graph and the current view layer. See
|
/* For drivers, so that they have access to the dependency graph and the current view layer. See
|
||||||
* T77086. */
|
* #77086. */
|
||||||
struct Depsgraph *depsgraph;
|
struct Depsgraph *depsgraph;
|
||||||
|
|
||||||
/* FCurves and Drivers can be evaluated at a different time than the current scene time, for
|
/* FCurves and Drivers can be evaluated at a different time than the current scene time, for
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user