Merge branch 'master' into refactor-mesh-corners-generic

This commit is contained in:
Hans Goudey 2023-01-19 16:15:09 -06:00
commit 932a211f6c
181 changed files with 3446 additions and 3250 deletions

View File

@ -399,6 +399,26 @@ mark_as_advanced(WITH_SYSTEM_GLOG)
# Freestyle
option(WITH_FREESTYLE "Enable Freestyle (advanced edges rendering)" ON)
# Libraries.
if(UNIX AND NOT APPLE)
# Optionally build without pre-compiled libraries.
# NOTE: this could be supported on all platforms however in practice UNIX is the only platform
# that has good support for detecting installed libraries.
option(WITH_LIBS_PRECOMPILED "\
Detect and link against pre-compiled libraries (typically found under \"../lib/\"). \
Disabling this option will use the system libraries although cached paths \
that point to pre-compiled libraries will be left as-is."
ON
)
mark_as_advanced(WITH_LIBS_PRECOMPILED)
option(WITH_STATIC_LIBS "Try to link with static libraries, as much as possible, to make blender more portable across distributions" OFF)
if(WITH_STATIC_LIBS)
option(WITH_BOOST_ICU "Boost uses ICU library (required for linking with static Boost built with libicu)." OFF)
mark_as_advanced(WITH_BOOST_ICU)
endif()
endif()
# Misc
if(WIN32 OR APPLE)
option(WITH_INPUT_IME "Enable Input Method Editor (IME) for complex Asian character input" ON)
@ -406,11 +426,6 @@ endif()
option(WITH_INPUT_NDOF "Enable NDOF input devices (SpaceNavigator and friends)" ON)
if(UNIX AND NOT APPLE)
option(WITH_INSTALL_PORTABLE "Install redistributable runtime, otherwise install into CMAKE_INSTALL_PREFIX" ON)
option(WITH_STATIC_LIBS "Try to link with static libraries, as much as possible, to make blender more portable across distributions" OFF)
if(WITH_STATIC_LIBS)
option(WITH_BOOST_ICU "Boost uses ICU library (required for linking with static Boost built with libicu)." OFF)
mark_as_advanced(WITH_BOOST_ICU)
endif()
endif()
option(WITH_PYTHON_INSTALL "Copy system python into the blender install folder" ON)
@ -993,6 +1008,8 @@ set(PLATFORM_LINKLIBS "")
# - CMAKE_EXE_LINKER_FLAGS_DEBUG
set(PLATFORM_LINKFLAGS "")
set(PLATFORM_LINKFLAGS_DEBUG "")
set(PLATFORM_LINKFLAGS_RELEASE "")
set(PLATFORM_LINKFLAGS_EXECUTABLE "")
if(NOT CMAKE_BUILD_TYPE MATCHES "Release")
if(WITH_COMPILER_ASAN)
@ -1262,12 +1279,14 @@ endif()
# -----------------------------------------------------------------------------
# Configure Bullet
if(WITH_BULLET AND WITH_SYSTEM_BULLET)
find_package(Bullet)
set_and_warn_library_found("Bullet" BULLET_FOUND WITH_BULLET)
else()
set(BULLET_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/extern/bullet2/src")
# set(BULLET_LIBRARIES "")
if(WITH_BULLET)
if(WITH_SYSTEM_BULLET)
find_package(Bullet)
set_and_warn_library_found("Bullet" BULLET_FOUND WITH_BULLET)
else()
set(BULLET_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/extern/bullet2/src")
set(BULLET_LIBRARIES "extern_bullet")
endif()
endif()

View File

@ -29,7 +29,7 @@ elseif(UNIX)
set(USD_PLATFORM_FLAGS
-DPYTHON_INCLUDE_DIR=${LIBDIR}/python/include/python${PYTHON_SHORT_VERSION}/
-DPYTHON_LIBRARY=${LIBDIR}/tbb/lib/${LIBPREFIX}${TBB_LIBRARY}${SHAREDLIBEXT}
)
)
if(APPLE)
set(USD_SHARED_LINKER_FLAGS "-Xlinker -undefined -Xlinker dynamic_lookup")

View File

@ -19,9 +19,13 @@ ENDIF()
SET(_moltenvk_SEARCH_DIRS
${MOLTENVK_ROOT_DIR}
${LIBDIR}/vulkan/MoltenVK
)
# FIXME: These finder modules typically don't use LIBDIR,
# this should be set by `./build_files/cmake/platform/` instead.
IF(DEFINED LIBDIR)
SET(_moltenvk_SEARCH_DIRS ${_moltenvk_SEARCH_DIRS} ${LIBDIR}/vulkan/MoltenVK)
ENDIF()
FIND_PATH(MOLTENVK_INCLUDE_DIR
NAMES

View File

@ -17,9 +17,13 @@ ENDIF()
SET(_optix_SEARCH_DIRS
${OPTIX_ROOT_DIR}
"$ENV{PROGRAMDATA}/NVIDIA Corporation/OptiX SDK 7.3.0"
)
# TODO: Which environment uses this?
if(DEFINED ENV{PROGRAMDATA})
list(APPEND _optix_SEARCH_DIRS "$ENV{PROGRAMDATA}/NVIDIA Corporation/OptiX SDK 7.3.0")
endif()
FIND_PATH(OPTIX_INCLUDE_DIR
NAMES
optix.h

View File

@ -67,6 +67,8 @@ ENDIF()
STRING(REPLACE "." "" PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION})
SET(_PYTHON_ABI_FLAGS "")
SET(_python_SEARCH_DIRS
${PYTHON_ROOT_DIR}
"$ENV{HOME}/py${PYTHON_VERSION_NO_DOTS}"

View File

@ -6,18 +6,80 @@
import re
import sys
from typing import Optional
cmakelists_file = sys.argv[-1]
def main():
def count_backslashes_before_pos(file_data: str, pos: int) -> int:
slash_count = 0
pos -= 1
while pos >= 0:
if file_data[pos] != '\\':
break
pos -= 1
slash_count += 1
return slash_count
def extract_cmake_string_at_pos(file_data: str, pos_beg: int) -> Optional[str]:
assert file_data[pos_beg - 1] == '"'
pos = pos_beg
# Dummy assignment.
pos_end = pos_beg
while True:
pos_next = file_data.find('"', pos)
if pos_next == -1:
raise Exception("Un-terminated string (parse error?)")
count_slashes = count_backslashes_before_pos(file_data, pos_next)
if (count_slashes % 2) == 0:
pos_end = pos_next
# Found the closing quote.
break
# The quote was back-slash escaped, step over it.
pos = pos_next + 1
file_data[pos_next]
assert file_data[pos_end] == '"'
if pos_beg == pos_end:
return None
# See: https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#escape-sequences
text = file_data[pos_beg: pos_end].replace(
# Handle back-slash literals.
"\\\\", "\\",
).replace(
# Handle tabs.
"\\t", "\t",
).replace(
# Handle escaped quotes.
"\\\"", "\"",
).replace(
# Handle tabs.
"\\;", ";",
).replace(
# Handle trailing newlines.
"\\\n", "",
)
return text
def main() -> None:
options = []
for l in open(cmakelists_file, 'r').readlines():
if not l.lstrip().startswith('#'):
l_option = re.sub(r'.*\boption\s*\(\s*(WITH_[a-zA-Z0-9_]+)\s+\"(.*)\"\s*.*', r'\g<1> - \g<2>', l)
if l_option != l:
l_option = l_option.strip()
if l_option.startswith('WITH_'):
options.append(l_option)
with open(cmakelists_file, 'r', encoding="utf-8") as fh:
file_data = fh.read()
for m in re.finditer(r"^\s*option\s*\(\s*(WITH_[a-zA-Z0-9_]+)\s+(\")", file_data, re.MULTILINE):
option_name = m.group(1)
option_descr = extract_cmake_string_at_pos(file_data, m.span(2)[1])
if option_descr is None:
# Possibly a parsing error, at least show something.
option_descr = "(UNDOCUMENTED)"
options.append("{:s}: {:s}".format(option_name, option_descr))
print('\n'.join(options))

View File

@ -550,7 +550,9 @@ function(setup_platform_linker_libs
endif()
if(WIN32 AND NOT UNIX)
target_link_libraries(${target} ${PTHREADS_LIBRARIES})
if(DEFINED PTHREADS_LIBRARIES)
target_link_libraries(${target} ${PTHREADS_LIBRARIES})
endif()
endif()
# target_link_libraries(${target} ${PLATFORM_LINKLIBS} ${CMAKE_DL_LIBS})
@ -1115,7 +1117,7 @@ function(find_python_package
# endif()
# Not set, so initialize.
else()
string(REPLACE "." ";" _PY_VER_SPLIT "${PYTHON_VERSION}")
string(REPLACE "." ";" _PY_VER_SPLIT "${PYTHON_VERSION}")
list(GET _PY_VER_SPLIT 0 _PY_VER_MAJOR)
# re-cache
@ -1262,7 +1264,7 @@ endmacro()
# Utility to gather and install precompiled shared libraries.
macro(add_bundled_libraries library_dir)
if(EXISTS ${LIBDIR})
if(DEFINED LIBDIR)
set(_library_dir ${LIBDIR}/${library_dir})
if(WIN32)
file(GLOB _all_library_versions ${_library_dir}/*\.dll)
@ -1275,7 +1277,7 @@ macro(add_bundled_libraries library_dir)
list(APPEND PLATFORM_BUNDLED_LIBRARY_DIRS ${_library_dir})
unset(_all_library_versions)
unset(_library_dir)
endif()
endif()
endmacro()
macro(windows_install_shared_manifest)

View File

@ -1,7 +1,12 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright 2022 Blender Foundation. All rights reserved.
# Auto update existing CMake caches for new libraries
# Auto update existing CMake caches for new libraries.
# Assert that `LIBDIR` is defined.
if(NOT (DEFINED LIBDIR))
message(FATAL_ERROR "Logical error, expected 'LIBDIR' to be defined!")
endif()
# Clear cached variables whose name matches `pattern`.
function(unset_cache_variables pattern)

View File

@ -4,38 +4,52 @@
# Libraries configuration for any *nix system including Linux and Unix (excluding APPLE).
# Detect precompiled library directory
if(NOT DEFINED LIBDIR)
# Path to a locally compiled libraries.
set(LIBDIR_NAME ${CMAKE_SYSTEM_NAME}_${CMAKE_SYSTEM_PROCESSOR})
string(TOLOWER ${LIBDIR_NAME} LIBDIR_NAME)
set(LIBDIR_NATIVE_ABI ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_NAME})
# Path to precompiled libraries with known glibc 2.28 ABI.
set(LIBDIR_GLIBC228_ABI ${CMAKE_SOURCE_DIR}/../lib/linux_x86_64_glibc_228)
if(NOT WITH_LIBS_PRECOMPILED)
unset(LIBDIR)
else()
if(NOT DEFINED LIBDIR)
# Path to a locally compiled libraries.
set(LIBDIR_NAME ${CMAKE_SYSTEM_NAME}_${CMAKE_SYSTEM_PROCESSOR})
string(TOLOWER ${LIBDIR_NAME} LIBDIR_NAME)
set(LIBDIR_NATIVE_ABI ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_NAME})
# Choose the best suitable libraries.
if(EXISTS ${LIBDIR_NATIVE_ABI})
set(LIBDIR ${LIBDIR_NATIVE_ABI})
set(WITH_LIBC_MALLOC_HOOK_WORKAROUND True)
elseif(EXISTS ${LIBDIR_GLIBC228_ABI})
set(LIBDIR ${LIBDIR_GLIBC228_ABI})
if(WITH_MEM_JEMALLOC)
# jemalloc provides malloc hooks.
set(WITH_LIBC_MALLOC_HOOK_WORKAROUND False)
else()
# Path to precompiled libraries with known glibc 2.28 ABI.
set(LIBDIR_GLIBC228_ABI ${CMAKE_SOURCE_DIR}/../lib/linux_x86_64_glibc_228)
# Choose the best suitable libraries.
if(EXISTS ${LIBDIR_NATIVE_ABI})
set(LIBDIR ${LIBDIR_NATIVE_ABI})
set(WITH_LIBC_MALLOC_HOOK_WORKAROUND True)
elseif(EXISTS ${LIBDIR_GLIBC228_ABI})
set(LIBDIR ${LIBDIR_GLIBC228_ABI})
if(WITH_MEM_JEMALLOC)
# jemalloc provides malloc hooks.
set(WITH_LIBC_MALLOC_HOOK_WORKAROUND False)
else()
set(WITH_LIBC_MALLOC_HOOK_WORKAROUND True)
endif()
endif()
# Avoid namespace pollustion.
unset(LIBDIR_NATIVE_ABI)
unset(LIBDIR_GLIBC228_ABI)
endif()
# Avoid namespace pollustion.
unset(LIBDIR_NATIVE_ABI)
unset(LIBDIR_GLIBC228_ABI)
if(NOT (EXISTS ${LIBDIR}))
message(STATUS
"Unable to find LIBDIR: ${LIBDIR}, system libraries may be used "
"(disable WITH_LIBS_PRECOMPILED to suppress this message)."
)
unset(LIBDIR)
endif()
endif()
# Support restoring this value once pre-compiled libraries have been handled.
set(WITH_STATIC_LIBS_INIT ${WITH_STATIC_LIBS})
if(EXISTS ${LIBDIR})
if(DEFINED LIBDIR)
message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}")
file(GLOB LIB_SUBDIRS ${LIBDIR}/*)
@ -85,7 +99,7 @@ endmacro()
# These are libraries that may be precompiled. For this we disable searching in
# the system directories so that we don't accidentally use them instead.
if(EXISTS ${LIBDIR})
if(DEFINED LIBDIR)
without_system_libs_begin()
endif()
@ -114,7 +128,7 @@ endfunction()
if(NOT WITH_SYSTEM_FREETYPE)
# FreeType compiled with Brotli compression for woff2.
find_package_wrapper(Freetype REQUIRED)
if(EXISTS ${LIBDIR})
if(DEFINED LIBDIR)
find_package_wrapper(Brotli REQUIRED)
# NOTE: This is done on WIN32 & APPLE but fails on some Linux systems.
@ -141,7 +155,7 @@ if(WITH_PYTHON)
if(WITH_PYTHON_MODULE AND NOT WITH_INSTALL_PORTABLE)
# Installing into `site-packages`, warn when installing into `./../lib/`
# which script authors almost certainly don't want.
if(EXISTS ${LIBDIR})
if(DEFINED LIBDIR)
path_is_prefix(LIBDIR PYTHON_SITE_PACKAGES _is_prefix)
if(_is_prefix)
message(WARNING "
@ -217,7 +231,7 @@ if(WITH_CODEC_SNDFILE)
endif()
if(WITH_CODEC_FFMPEG)
if(EXISTS ${LIBDIR})
if(DEFINED LIBDIR)
set(FFMPEG_ROOT_DIR ${LIBDIR}/ffmpeg)
# Override FFMPEG components to also include static library dependencies
# included with precompiled libraries, and to ensure correct link order.
@ -232,7 +246,7 @@ if(WITH_CODEC_FFMPEG)
vpx
x264
xvidcore)
if(EXISTS ${LIBDIR}/ffmpeg/lib/libaom.a)
if((DEFINED LIBDIR) AND (EXISTS ${LIBDIR}/ffmpeg/lib/libaom.a))
list(APPEND FFMPEG_FIND_COMPONENTS aom)
endif()
elseif(FFMPEG)
@ -430,10 +444,13 @@ if(WITH_OPENIMAGEIO)
${PNG_LIBRARIES}
${JPEG_LIBRARIES}
${ZLIB_LIBRARIES}
${BOOST_LIBRARIES}
)
set(OPENIMAGEIO_DEFINITIONS "")
if(WITH_BOOST)
list(APPEND OPENIMAGEIO_LIBRARIES "${BOOST_LIBRARIES}")
endif()
if(WITH_IMAGE_TIFF)
list(APPEND OPENIMAGEIO_LIBRARIES "${TIFF_LIBRARY}")
endif()
@ -451,7 +468,7 @@ add_bundled_libraries(openimageio/lib)
if(WITH_OPENCOLORIO)
find_package_wrapper(OpenColorIO 2.0.0)
set(OPENCOLORIO_DEFINITIONS)
set(OPENCOLORIO_DEFINITIONS "")
set_and_warn_library_found("OpenColorIO" OPENCOLORIO_FOUND WITH_OPENCOLORIO)
endif()
add_bundled_libraries(opencolorio/lib)
@ -466,7 +483,7 @@ if(WITH_OPENIMAGEDENOISE)
endif()
if(WITH_LLVM)
if(EXISTS ${LIBDIR})
if(DEFINED LIBDIR)
set(LLVM_STATIC ON)
endif()
@ -480,7 +497,7 @@ if(WITH_LLVM)
endif()
# Symbol conflicts with same UTF library used by OpenCollada
if(EXISTS ${LIBDIR})
if(DEFINED LIBDIR)
if(WITH_OPENCOLLADA AND (${LLVM_VERSION} VERSION_LESS "4.0.0"))
list(REMOVE_ITEM OPENCOLLADA_LIBRARIES ${OPENCOLLADA_UTF_LIBRARY})
endif()
@ -536,7 +553,7 @@ if(WITH_CYCLES AND WITH_CYCLES_PATH_GUIDING)
endif()
endif()
if(EXISTS ${LIBDIR})
if(DEFINED LIBDIR)
without_system_libs_end()
endif()
@ -551,9 +568,14 @@ else()
endif()
find_package(Threads REQUIRED)
list(APPEND PLATFORM_LINKLIBS ${CMAKE_THREAD_LIBS_INIT})
# used by other platforms
set(PTHREADS_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
# `FindThreads` documentation notes that this may be empty
# with the system libraries provide threading functionality.
if(CMAKE_THREAD_LIBS_INIT)
list(APPEND PLATFORM_LINKLIBS ${CMAKE_THREAD_LIBS_INIT})
# used by other platforms
set(PTHREADS_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
endif()
if(CMAKE_DL_LIBS)
list(APPEND PLATFORM_LINKLIBS ${CMAKE_DL_LIBS})
@ -575,7 +597,7 @@ add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
#
# Keep last, so indirectly linked libraries don't override our own pre-compiled libs.
if(EXISTS ${LIBDIR})
if(DEFINED LIBDIR)
# Clear the prefix path as it causes the `LIBDIR` to override system locations.
unset(CMAKE_PREFIX_PATH)
@ -631,7 +653,7 @@ if(WITH_GHOST_WAYLAND)
# When dynamically linked WAYLAND is used and `${LIBDIR}/wayland` is present,
# there is no need to search for the libraries as they are not needed for building.
# Only the headers are needed which can reference the known paths.
if(EXISTS "${LIBDIR}/wayland" AND WITH_GHOST_WAYLAND_DYNLOAD)
if((DEFINED LIBDIR) AND (EXISTS "${LIBDIR}/wayland" AND WITH_GHOST_WAYLAND_DYNLOAD))
set(_use_system_wayland OFF)
else()
set(_use_system_wayland ON)
@ -695,7 +717,7 @@ if(WITH_GHOST_WAYLAND)
add_definitions(-DWITH_GHOST_WAYLAND_LIBDECOR)
endif()
if(EXISTS "${LIBDIR}/wayland/bin/wayland-scanner")
if((DEFINED LIBDIR) AND (EXISTS "${LIBDIR}/wayland/bin/wayland-scanner"))
set(WAYLAND_SCANNER "${LIBDIR}/wayland/bin/wayland-scanner")
else()
pkg_get_variable(WAYLAND_SCANNER wayland-scanner wayland_scanner)

View File

@ -13,10 +13,12 @@ endif()
# Exporting functions from the blender binary gives linker warnings on Apple arm64 systems.
# Silence them here.
if(APPLE AND ("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64"))
if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
string(APPEND CMAKE_C_FLAGS " -fvisibility=hidden")
string(APPEND CMAKE_CXX_FLAGS " -fvisibility=hidden")
if(APPLE)
if("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64")
if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
string(APPEND CMAKE_C_FLAGS " -fvisibility=hidden")
string(APPEND CMAKE_CXX_FLAGS " -fvisibility=hidden")
endif()
endif()
endif()
@ -261,9 +263,11 @@ set(LIB
blender_add_lib(extern_mantaflow "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
# The VDB libs above are only added to as INTERFACE libs by blender_add_lib,
# meaning extern_mantaflow itself actually does not have a dependency on the
# openvdb libraries, and CMAKE is free to link the vdb libs before
# extern_mantaflow causing linker errors on linux. By explicitly declaring
# a dependency here, cmake will do the right thing.
target_link_libraries(extern_mantaflow PRIVATE ${OPENVDB_LIBRARIES})
if(WITH_OPENVDB)
# The VDB libs above are only added to as INTERFACE libs by blender_add_lib,
# meaning extern_mantaflow itself actually does not have a dependency on the
# openvdb libraries, and CMAKE is free to link the vdb libs before
# extern_mantaflow causing linker errors on linux. By explicitly declaring
# a dependency here, cmake will do the right thing.
target_link_libraries(extern_mantaflow PRIVATE ${OPENVDB_LIBRARIES})
endif()

View File

@ -111,8 +111,10 @@ macro(cycles_external_libraries_append libraries)
endif()
if(WITH_OPENIMAGEDENOISE)
list(APPEND ${libraries} ${OPENIMAGEDENOISE_LIBRARIES})
if(APPLE AND "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64")
list(APPEND ${libraries} "-framework Accelerate")
if(APPLE)
if("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64")
list(APPEND ${libraries} "-framework Accelerate")
endif()
endif()
endif()
if(WITH_ALEMBIC)
@ -136,7 +138,15 @@ macro(cycles_external_libraries_append libraries)
${PYTHON_LIBRARIES}
${ZLIB_LIBRARIES}
${CMAKE_DL_LIBS}
${PTHREADS_LIBRARIES}
)
if(DEFINED PTHREADS_LIBRARIES)
list(APPEND ${libraries}
${PTHREADS_LIBRARIES}
)
endif()
list(APPEND ${libraries}
${PLATFORM_LINKLIBS}
)

View File

@ -327,10 +327,21 @@ void MetalDevice::make_source(MetalPipelineType pso_type, const uint kernel_feat
# define KERNEL_STRUCT_BEGIN(name, parent) \
string_replace_same_length(source, "kernel_data." #parent ".", "kernel_data_" #parent "_");
bool next_member_is_specialized = true;
# define KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE next_member_is_specialized = false;
/* Add constants to md5 so that 'get_best_pipeline' is able to return a suitable match. */
# define KERNEL_STRUCT_MEMBER(parent, _type, name) \
baked_constants += string(#parent "." #name "=") + \
to_string(_type(launch_params.data.parent.name)) + "\n";
if (next_member_is_specialized) { \
baked_constants += string(#parent "." #name "=") + \
to_string(_type(launch_params.data.parent.name)) + "\n"; \
} \
else { \
string_replace( \
source, "kernel_data_" #parent "_" #name, "kernel_data." #parent ".__unused_" #name); \
next_member_is_specialized = true; \
}
# include "kernel/data_template.h"

View File

@ -49,6 +49,18 @@ struct ShaderCache {
if (MetalInfo::get_device_vendor(mtlDevice) == METAL_GPU_APPLE) {
switch (MetalInfo::get_apple_gpu_architecture(mtlDevice)) {
default:
case APPLE_M2_BIG:
occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_COMPACT_SHADOW_STATES] = {384, 128};
occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_INIT_FROM_CAMERA] = {640, 128};
occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST] = {1024, 64};
occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW] = {704, 704};
occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_INTERSECT_SUBSURFACE] = {640, 32};
occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_QUEUED_PATHS_ARRAY] = {896, 768};
occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND] = {512, 128};
occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_SHADE_SHADOW] = {32, 32};
occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE] = {768, 576};
occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_SORTED_PATHS_ARRAY] = {896, 768};
break;
case APPLE_M2:
occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_COMPACT_SHADOW_STATES] = {32, 32};
occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_INIT_FROM_CAMERA] = {832, 32};
@ -448,13 +460,18 @@ static MTLFunctionConstantValues *GetConstantValues(KernelData const *data = nul
if (!data) {
data = &zero_data;
}
int zero_int = 0;
[constant_values setConstantValue:&zero_int type:MTLDataType_int atIndex:Kernel_DummyConstant];
[constant_values setConstantValue:&zero_data type:MTLDataType_int atIndex:Kernel_DummyConstant];
bool next_member_is_specialized = true;
# define KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE next_member_is_specialized = false;
# define KERNEL_STRUCT_MEMBER(parent, _type, name) \
[constant_values setConstantValue:&data->parent.name \
[constant_values setConstantValue:next_member_is_specialized ? (void *)&data->parent.name : \
(void *)&zero_data \
type:MTLDataType_##_type \
atIndex:KernelData_##parent##_##name];
atIndex:KernelData_##parent##_##name]; \
next_member_is_specialized = true;
# include "kernel/data_template.h"

View File

@ -278,7 +278,8 @@ int MetalDeviceQueue::num_concurrent_states(const size_t state_size) const
if (metal_device_->device_vendor == METAL_GPU_APPLE) {
result *= 4;
if (MetalInfo::get_apple_gpu_architecture(metal_device_->mtlDevice) == APPLE_M2) {
/* Increasing the state count doesn't notably benefit M1-family systems. */
if (MetalInfo::get_apple_gpu_architecture(metal_device_->mtlDevice) != APPLE_M1) {
size_t system_ram = system_physical_ram();
size_t allocated_so_far = [metal_device_->mtlDevice currentAllocatedSize];
size_t max_recommended_working_set = [metal_device_->mtlDevice recommendedMaxWorkingSetSize];

View File

@ -29,6 +29,7 @@ enum AppleGPUArchitecture {
APPLE_UNKNOWN,
APPLE_M1,
APPLE_M2,
APPLE_M2_BIG,
};
/* Contains static Metal helper functions. */

View File

@ -52,7 +52,7 @@ AppleGPUArchitecture MetalInfo::get_apple_gpu_architecture(id<MTLDevice> device)
return APPLE_M1;
}
else if (strstr(device_name, "M2")) {
return APPLE_M2;
return get_apple_gpu_core_count(device) <= 10 ? APPLE_M2 : APPLE_M2_BIG;
}
return APPLE_UNKNOWN;
}

View File

@ -5,6 +5,9 @@ set(INC
..
)
set(INC_SYS
)
set(SRC
node.cpp
node_type.cpp

View File

@ -5,6 +5,9 @@ set(INC
..
)
set(INC_SYS
)
set(SRC
adaptive_sampling.cpp
denoiser.cpp

View File

@ -732,25 +732,25 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
endif()
# SYCL_CPP_FLAGS is a variable that the user can set to pass extra compiler options
set(sycl_compiler_flags
${CMAKE_CURRENT_SOURCE_DIR}/${SRC_KERNEL_DEVICE_ONEAPI}
-fsycl
-fsycl-unnamed-lambda
-fdelayed-template-parsing
-mllvm -inlinedefault-threshold=250
-mllvm -inlinehint-threshold=350
-fsycl-device-code-split=per_kernel
-fsycl-max-parallel-link-jobs=${SYCL_OFFLINE_COMPILER_PARALLEL_JOBS}
-shared
-DWITH_ONEAPI
-ffast-math
-DNDEBUG
-O2
-o ${cycles_kernel_oneapi_lib}
-I${CMAKE_CURRENT_SOURCE_DIR}/..
${SYCL_CPP_FLAGS}
)
${CMAKE_CURRENT_SOURCE_DIR}/${SRC_KERNEL_DEVICE_ONEAPI}
-fsycl
-fsycl-unnamed-lambda
-fdelayed-template-parsing
-mllvm -inlinedefault-threshold=250
-mllvm -inlinehint-threshold=350
-fsycl-device-code-split=per_kernel
-fsycl-max-parallel-link-jobs=${SYCL_OFFLINE_COMPILER_PARALLEL_JOBS}
-shared
-DWITH_ONEAPI
-ffast-math
-DNDEBUG
-O2
-o ${cycles_kernel_oneapi_lib}
-I${CMAKE_CURRENT_SOURCE_DIR}/..
${SYCL_CPP_FLAGS}
)
if (WITH_CYCLES_ONEAPI_HOST_TASK_EXECUTION)
if(WITH_CYCLES_ONEAPI_HOST_TASK_EXECUTION)
list(APPEND sycl_compiler_flags -DWITH_ONEAPI_SYCL_HOST_TASK)
endif()

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,9 @@
#ifndef KERNEL_STRUCT_MEMBER
# define KERNEL_STRUCT_MEMBER(parent, type, name)
#endif
#ifndef KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE
# define KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE
#endif
/* Background. */
@ -179,9 +182,12 @@ KERNEL_STRUCT_MEMBER(integrator, float, sample_clamp_indirect)
KERNEL_STRUCT_MEMBER(integrator, int, use_caustics)
/* Sampling pattern. */
KERNEL_STRUCT_MEMBER(integrator, int, sampling_pattern)
KERNEL_STRUCT_MEMBER(integrator, int, tabulated_sobol_sequence_size)
KERNEL_STRUCT_MEMBER(integrator, int, sobol_index_mask)
KERNEL_STRUCT_MEMBER(integrator, float, scrambling_distance)
/* Sobol pattern. */
KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE
KERNEL_STRUCT_MEMBER(integrator, int, tabulated_sobol_sequence_size)
KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE
KERNEL_STRUCT_MEMBER(integrator, int, sobol_index_mask)
/* Volume render. */
KERNEL_STRUCT_MEMBER(integrator, int, use_volumes)
KERNEL_STRUCT_MEMBER(integrator, int, volume_max_steps)
@ -216,4 +222,5 @@ KERNEL_STRUCT_END(KernelSVMUsage)
#undef KERNEL_STRUCT_BEGIN
#undef KERNEL_STRUCT_MEMBER
#undef KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE
#undef KERNEL_STRUCT_END

View File

@ -616,15 +616,13 @@ ccl_device_forceinline Spectrum mnee_eval_bsdf_contribution(ccl_private ShaderCl
float alpha2 = bsdf->alpha_x * bsdf->alpha_y;
float cosThetaM = dot(bsdf->N, Ht);
/* Now calculate G1(i, m) and G1(o, m). */
float G;
if (bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID) {
/* Eq. 26, 27: now calculate G1(i,m) and G1(o,m). */
G = bsdf_beckmann_G1(bsdf->alpha_x, cosNI) * bsdf_beckmann_G1(bsdf->alpha_x, cosNO);
G = bsdf_G<MicrofacetType::BECKMANN>(alpha2, cosNI, cosNO);
}
else { /* bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID assumed */
/* Eq. 34: now calculate G1(i,m) and G1(o,m). */
G = (2.f / (1.f + safe_sqrtf(1.f + alpha2 * (1.f - cosNI * cosNI) / (cosNI * cosNI)))) *
(2.f / (1.f + safe_sqrtf(1.f + alpha2 * (1.f - cosNO * cosNO) / (cosNO * cosNO))));
G = bsdf_G<MicrofacetType::GGX>(alpha2, cosNI, cosNO);
}
/*

View File

@ -20,6 +20,7 @@
#include "kernel/osl/globals.h"
#include "kernel/osl/services.h"
#include "kernel/osl/types.h"
#include "util/foreach.h"
#include "util/log.h"
@ -119,6 +120,8 @@ ustring OSLRenderServices::u_u("u");
ustring OSLRenderServices::u_v("v");
ustring OSLRenderServices::u_empty;
ImageManager *OSLRenderServices::image_manager = nullptr;
OSLRenderServices::OSLRenderServices(OSL::TextureSystem *texture_system, int device_type)
: OSL::RendererServices(texture_system), device_type_(device_type)
{
@ -1154,7 +1157,7 @@ TextureSystem::TextureHandle *OSLRenderServices::get_texture_handle(ustring file
/* For non-OIIO textures, just return a pointer to our own OSLTextureHandle. */
if (it != textures.end()) {
if (it->second->type != OSLTextureHandle::OIIO) {
return (TextureSystem::TextureHandle *)it->second.get();
return reinterpret_cast<TextureSystem::TextureHandle *>(it->second.get());
}
}
@ -1173,16 +1176,53 @@ TextureSystem::TextureHandle *OSLRenderServices::get_texture_handle(ustring file
/* Assign OIIO texture handle and return. */
it->second->oiio_handle = handle;
return (TextureSystem::TextureHandle *)it->second.get();
return reinterpret_cast<TextureSystem::TextureHandle *>(it->second.get());
}
else {
if (it != textures.end() && it->second->type == OSLTextureHandle::SVM &&
it->second->svm_slots[0].w == -1) {
return reinterpret_cast<TextureSystem::TextureHandle *>(
static_cast<uintptr_t>(it->second->svm_slots[0].y + 1));
/* Construct GPU texture handle for existing textures. */
if (it != textures.end()) {
switch (it->second->type) {
case OSLTextureHandle::OIIO:
return NULL;
case OSLTextureHandle::SVM:
if (!it->second->handle.empty() && it->second->handle.get_manager() != image_manager) {
it.clear();
break;
}
return reinterpret_cast<TextureSystem::TextureHandle *>(OSL_TEXTURE_HANDLE_TYPE_SVM |
it->second->svm_slots[0].y);
case OSLTextureHandle::IES:
if (!it->second->handle.empty() && it->second->handle.get_manager() != image_manager) {
it.clear();
break;
}
return reinterpret_cast<TextureSystem::TextureHandle *>(OSL_TEXTURE_HANDLE_TYPE_IES |
it->second->svm_slots[0].y);
case OSLTextureHandle::AO:
return reinterpret_cast<TextureSystem::TextureHandle *>(
OSL_TEXTURE_HANDLE_TYPE_AO_OR_BEVEL | 1);
case OSLTextureHandle::BEVEL:
return reinterpret_cast<TextureSystem::TextureHandle *>(
OSL_TEXTURE_HANDLE_TYPE_AO_OR_BEVEL | 2);
}
}
return NULL;
if (!image_manager) {
return NULL;
}
/* Load new textures using SVM image manager. */
ImageHandle handle = image_manager->add_image(filename.string(), ImageParams());
if (handle.empty()) {
return NULL;
}
if (!textures.insert(filename, new OSLTextureHandle(handle))) {
return NULL;
}
return reinterpret_cast<TextureSystem::TextureHandle *>(OSL_TEXTURE_HANDLE_TYPE_SVM |
handle.svm_slot());
}
}

View File

@ -16,6 +16,8 @@
#include <OSL/oslexec.h>
#include <OSL/rendererservices.h>
#include "scene/image.h"
#ifdef WITH_PTEX
class PtexCache;
#endif
@ -54,10 +56,20 @@ struct OSLTextureHandle : public OIIO::RefCnt {
{
}
OSLTextureHandle(const ImageHandle &handle)
: type(SVM),
svm_slots(handle.get_svm_slots()),
oiio_handle(nullptr),
processor(nullptr),
handle(handle)
{
}
Type type;
vector<int4> svm_slots;
OSL::TextureSystem::TextureHandle *oiio_handle;
ColorSpaceProcessor *processor;
ImageHandle handle;
};
typedef OIIO::intrusive_ptr<OSLTextureHandle> OSLTextureHandleRef;
@ -324,6 +336,8 @@ class OSLRenderServices : public OSL::RendererServices {
* shading system. */
OSLTextureHandleMap textures;
static ImageManager *image_manager;
private:
int device_type_;
};

View File

@ -1443,6 +1443,8 @@ OSL_NOISE_IMPL(osl_snoise, snoise)
/* Texturing */
#include "kernel/svm/ies.h"
ccl_device_extern ccl_private OSLTextureOptions *osl_get_texture_options(
ccl_private ShaderGlobals *sg)
{
@ -1548,25 +1550,31 @@ ccl_device_extern bool osl_texture(ccl_private ShaderGlobals *sg,
ccl_private float *dalphady,
ccl_private void *errormessage)
{
if (!texture_handle) {
return false;
const unsigned int type = OSL_TEXTURE_HANDLE_TYPE(texture_handle);
const unsigned int slot = OSL_TEXTURE_HANDLE_SLOT(texture_handle);
switch (type) {
case OSL_TEXTURE_HANDLE_TYPE_SVM: {
const float4 rgba = kernel_tex_image_interp(nullptr, slot, s, 1.0f - t);
if (nchannels > 0)
result[0] = rgba.x;
if (nchannels > 1)
result[1] = rgba.y;
if (nchannels > 2)
result[2] = rgba.z;
if (alpha)
*alpha = rgba.w;
return true;
}
case OSL_TEXTURE_HANDLE_TYPE_IES: {
if (nchannels > 0)
result[0] = kernel_ies_interp(nullptr, slot, s, t);
return true;
}
default: {
return false;
}
}
/* Only SVM textures are supported. */
int id = static_cast<int>(reinterpret_cast<size_t>(texture_handle) - 1);
const float4 rgba = kernel_tex_image_interp(nullptr, id, s, 1.0f - t);
if (nchannels > 0)
result[0] = rgba.x;
if (nchannels > 1)
result[1] = rgba.y;
if (nchannels > 2)
result[2] = rgba.z;
if (alpha)
*alpha = rgba.w;
return true;
}
ccl_device_extern bool osl_texture3d(ccl_private ShaderGlobals *sg,
@ -1586,25 +1594,26 @@ ccl_device_extern bool osl_texture3d(ccl_private ShaderGlobals *sg,
ccl_private float *dalphady,
ccl_private void *errormessage)
{
if (!texture_handle) {
return false;
const unsigned int type = OSL_TEXTURE_HANDLE_TYPE(texture_handle);
const unsigned int slot = OSL_TEXTURE_HANDLE_SLOT(texture_handle);
switch (type) {
case OSL_TEXTURE_HANDLE_TYPE_SVM: {
const float4 rgba = kernel_tex_image_interp_3d(nullptr, slot, *P, INTERPOLATION_NONE);
if (nchannels > 0)
result[0] = rgba.x;
if (nchannels > 1)
result[1] = rgba.y;
if (nchannels > 2)
result[2] = rgba.z;
if (alpha)
*alpha = rgba.w;
return true;
}
default: {
return false;
}
}
/* Only SVM textures are supported. */
int id = static_cast<int>(reinterpret_cast<size_t>(texture_handle) - 1);
const float4 rgba = kernel_tex_image_interp_3d(nullptr, id, *P, INTERPOLATION_NONE);
if (nchannels > 0)
result[0] = rgba.x;
if (nchannels > 1)
result[1] = rgba.y;
if (nchannels > 2)
result[2] = rgba.z;
if (alpha)
*alpha = rgba.w;
return true;
}
ccl_device_extern bool osl_environment(ccl_private ShaderGlobals *sg,

View File

@ -96,4 +96,13 @@ struct OSLNoiseOptions {
struct OSLTextureOptions {
};
#define OSL_TEXTURE_HANDLE_TYPE_IES ((uintptr_t)0x2 << 30)
#define OSL_TEXTURE_HANDLE_TYPE_SVM ((uintptr_t)0x1 << 30)
#define OSL_TEXTURE_HANDLE_TYPE_AO_OR_BEVEL ((uintptr_t)0x3 << 30)
#define OSL_TEXTURE_HANDLE_TYPE(handle) \
((unsigned int)((uintptr_t)(handle) & ((uintptr_t)0x3 << 30)))
#define OSL_TEXTURE_HANDLE_SLOT(handle) \
((unsigned int)((uintptr_t)(handle) & ((uintptr_t)0x3FFFFFFF)))
CCL_NAMESPACE_END

View File

@ -84,6 +84,7 @@ ccl_device_inline float kernel_ies_interp(KernelGlobals kg, int slot, float h_an
return max(cubic_interp(a, b, c, d, h_frac), 0.0f);
}
#ifdef __SVM__
ccl_device_noinline void svm_node_ies(KernelGlobals kg,
ccl_private ShaderData *sd,
ccl_private float *stack,
@ -105,5 +106,6 @@ ccl_device_noinline void svm_node_ies(KernelGlobals kg,
stack_store_float(stack, fac_offset, fac);
}
}
#endif
CCL_NAMESPACE_END

View File

@ -34,8 +34,6 @@ CCL_NAMESPACE_BEGIN
#define VOLUME_BOUNDS_MAX 1024
#define BECKMANN_TABLE_SIZE 256
#define SHADER_NONE (~0)
#define OBJECT_NONE (~0)
#define PRIM_NONE (~0)
@ -1187,9 +1185,8 @@ typedef enum KernelBVHLayout {
#include "kernel/data_template.h"
typedef struct KernelTables {
int beckmann_offset;
int filter_table_offset;
int pad1, pad2;
int pad1, pad2, pad3;
} KernelTables;
static_assert_align(KernelTables, 16);

View File

@ -222,6 +222,11 @@ VDBImageLoader *ImageHandle::vdb_loader(const int tile_index) const
return NULL;
}
ImageManager *ImageHandle::get_manager() const
{
return manager;
}
bool ImageHandle::operator==(const ImageHandle &other) const
{
return manager == other.manager && tile_slots == other.tile_slots;

View File

@ -153,6 +153,8 @@ class ImageHandle {
VDBImageLoader *vdb_loader(const int tile_index = 0) const;
ImageManager *get_manager() const;
protected:
vector<int> tile_slots;
ImageManager *manager;

View File

@ -184,9 +184,19 @@ void OSLShaderManager::device_update_specific(Device *device,
* is being freed after the Session is freed.
*/
thread_scoped_lock lock(ss_shared_mutex);
/* Set current image manager during the lock, so that there is no conflict with other shader
* manager instances.
*
* It is used in "OSLRenderServices::get_texture_handle" called during optimization below to
* load images for the GPU. */
OSLRenderServices::image_manager = scene->image_manager;
for (const auto &[device_type, ss] : ss_shared) {
ss->optimize_all_groups();
}
OSLRenderServices::image_manager = nullptr;
}
/* load kernels */
@ -213,6 +223,22 @@ void OSLShaderManager::device_free(Device *device, DeviceScene *dscene, Scene *s
og->bump_state.clear();
og->background_state.reset();
});
/* Remove any textures specific to an image manager from shared render services textures, since
* the image manager may get destroyed next. */
for (const auto &[device_type, ss] : ss_shared) {
OSLRenderServices *services = static_cast<OSLRenderServices *>(ss->renderer());
for (auto it = services->textures.begin(); it != services->textures.end(); ++it) {
if (it->second->handle.get_manager() == scene->image_manager) {
/* Don't lock again, since the iterator already did so. */
services->textures.erase(it->first, false);
it.clear();
/* Iterator was invalidated, start from the beginning again. */
it = services->textures.begin();
}
}
}
}
void OSLShaderManager::texture_system_init()

View File

@ -32,114 +32,6 @@ namespace OCIO = OCIO_NAMESPACE;
CCL_NAMESPACE_BEGIN
thread_mutex ShaderManager::lookup_table_mutex;
vector<float> ShaderManager::beckmann_table;
bool ShaderManager::beckmann_table_ready = false;
/* Beckmann sampling precomputed table, see bsdf_microfacet.h */
/* 2D slope distribution (alpha = 1.0) */
static float beckmann_table_P22(const float slope_x, const float slope_y)
{
return expf(-(slope_x * slope_x + slope_y * slope_y));
}
/* maximal slope amplitude (range that contains 99.99% of the distribution) */
static float beckmann_table_slope_max()
{
return 6.0;
}
/* MSVC 2015 needs this ugly hack to prevent a codegen bug on x86
* see T50176 for details
*/
#if defined(_MSC_VER) && (_MSC_VER == 1900)
# define MSVC_VOLATILE volatile
#else
# define MSVC_VOLATILE
#endif
/* Paper used: Importance Sampling Microfacet-Based BSDFs with the
* Distribution of Visible Normals. Supplemental Material 2/2.
*
* http://hal.inria.fr/docs/01/00/66/20/ANNEX/supplemental2.pdf
*/
static void beckmann_table_rows(float *table, int row_from, int row_to)
{
/* allocate temporary data */
const int DATA_TMP_SIZE = 512;
vector<double> slope_x(DATA_TMP_SIZE);
vector<double> CDF_P22_omega_i(DATA_TMP_SIZE);
/* loop over incident directions */
for (int index_theta = row_from; index_theta < row_to; index_theta++) {
/* incident vector */
const float cos_theta = index_theta / (BECKMANN_TABLE_SIZE - 1.0f);
const float sin_theta = safe_sqrtf(1.0f - cos_theta * cos_theta);
/* for a given incident vector
* integrate P22_{omega_i}(x_slope, 1, 1), Eq. (10) */
slope_x[0] = (double)-beckmann_table_slope_max();
CDF_P22_omega_i[0] = 0;
for (MSVC_VOLATILE int index_slope_x = 1; index_slope_x < DATA_TMP_SIZE; ++index_slope_x) {
/* slope_x */
slope_x[index_slope_x] = (double)(-beckmann_table_slope_max() +
2.0f * beckmann_table_slope_max() * index_slope_x /
(DATA_TMP_SIZE - 1.0f));
/* dot product with incident vector */
float dot_product = fmaxf(0.0f, -(float)slope_x[index_slope_x] * sin_theta + cos_theta);
/* marginalize P22_{omega_i}(x_slope, 1, 1), Eq. (10) */
float P22_omega_i = 0.0f;
for (int j = 0; j < 100; ++j) {
float slope_y = -beckmann_table_slope_max() +
2.0f * beckmann_table_slope_max() * j * (1.0f / 99.0f);
P22_omega_i += dot_product * beckmann_table_P22((float)slope_x[index_slope_x], slope_y);
}
/* CDF of P22_{omega_i}(x_slope, 1, 1), Eq. (10) */
CDF_P22_omega_i[index_slope_x] = CDF_P22_omega_i[index_slope_x - 1] + (double)P22_omega_i;
}
/* renormalize CDF_P22_omega_i */
for (int index_slope_x = 1; index_slope_x < DATA_TMP_SIZE; ++index_slope_x)
CDF_P22_omega_i[index_slope_x] /= CDF_P22_omega_i[DATA_TMP_SIZE - 1];
/* loop over random number U1 */
int index_slope_x = 0;
for (int index_U = 0; index_U < BECKMANN_TABLE_SIZE; ++index_U) {
const double U = 0.0000001 + 0.9999998 * index_U / (double)(BECKMANN_TABLE_SIZE - 1);
/* inverse CDF_P22_omega_i, solve Eq.(11) */
while (CDF_P22_omega_i[index_slope_x] <= U)
++index_slope_x;
const double interp = (CDF_P22_omega_i[index_slope_x] - U) /
(CDF_P22_omega_i[index_slope_x] - CDF_P22_omega_i[index_slope_x - 1]);
/* store value */
table[index_U + index_theta * BECKMANN_TABLE_SIZE] =
(float)(interp * slope_x[index_slope_x - 1] + (1.0 - interp) * slope_x[index_slope_x]);
}
}
}
#undef MSVC_VOLATILE
static void beckmann_table_build(vector<float> &table)
{
table.resize(BECKMANN_TABLE_SIZE * BECKMANN_TABLE_SIZE);
/* multithreaded build */
TaskPool pool;
for (int i = 0; i < BECKMANN_TABLE_SIZE; i += 8)
pool.push(function_bind(&beckmann_table_rows, &table[0], i, i + 8));
pool.wait_work();
}
/* Shader */
@ -491,7 +383,6 @@ bool Shader::need_update_geometry() const
ShaderManager::ShaderManager()
{
update_flags = UPDATE_ALL;
beckmann_table_offset = TABLE_OFFSET_INVALID;
init_xyz_transforms();
}
@ -663,22 +554,6 @@ void ShaderManager::device_update_common(Device * /*device*/,
dscene->shaders.copy_to_device();
/* lookup tables */
KernelTables *ktables = &dscene->data.tables;
/* beckmann lookup table */
if (beckmann_table_offset == TABLE_OFFSET_INVALID) {
if (!beckmann_table_ready) {
thread_scoped_lock lock(lookup_table_mutex);
if (!beckmann_table_ready) {
beckmann_table_build(beckmann_table);
beckmann_table_ready = true;
}
}
beckmann_table_offset = scene->lookup_tables->add_table(dscene, beckmann_table);
}
ktables->beckmann_offset = (int)beckmann_table_offset;
/* integrator */
KernelIntegrator *kintegrator = &dscene->data.integrator;
kintegrator->use_volumes = has_volumes;
@ -700,8 +575,6 @@ void ShaderManager::device_update_common(Device * /*device*/,
void ShaderManager::device_free_common(Device *, DeviceScene *dscene, Scene *scene)
{
scene->lookup_tables->remove_table(&beckmann_table_offset);
dscene->shaders.free();
}
@ -844,7 +717,6 @@ uint ShaderManager::get_kernel_features(Scene *scene)
void ShaderManager::free_memory()
{
beckmann_table.free_memory();
#ifdef WITH_OSL
OSLShaderManager::free_memory();

View File

@ -232,10 +232,6 @@ class ShaderManager {
AttributeIDMap unique_attribute_id;
static thread_mutex lookup_table_mutex;
static vector<float> beckmann_table;
static bool beckmann_table_ready;
size_t beckmann_table_offset;
uint get_graph_kernel_features(ShaderGraph *graph);

View File

@ -5,6 +5,9 @@ set(INC
..
)
set(INC_SYS
)
set(SRC
buffers.cpp
denoising.cpp

View File

@ -360,6 +360,15 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND)
COMMAND ${WAYLAND_SCANNER} private-code ${PROT_DEF} ${INC_DST}/${_name}-client-protocol.c
DEPENDS ${INC_DST}/${_name}-client-protocol.h
)
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
# Prevent warnings/failure to compile with generated `WL_PRIVATE` declarations.
set_source_files_properties(
"${INC_DST}/${_name}-client-protocol.c"
PROPERTIES COMPILE_FLAGS "-Wno-missing-variable-declarations"
)
endif()
list(APPEND SRC
${INC_DST}/${_name}-client-protocol.c
${INC_DST}/${_name}-client-protocol.h

View File

@ -41,10 +41,11 @@ if(WIN32 AND NOT UNIX)
list(APPEND INC_SYS
${PTHREADS_INC}
)
list(APPEND LIB
${PTHREADS_LIBRARIES}
)
if(DEFINED PTHREADS_LIBRARIES)
list(APPEND LIB
${PTHREADS_LIBRARIES}
)
endif()
endif()
# Jemalloc 5.0.0+ needs extra configuration.

View File

@ -20,7 +20,6 @@ set(SRC
)
set(LIB
extern_bullet
${BULLET_LIBRARIES}
)

@ -1 +1 @@
Subproject commit bf49eeaa14c445d3c53068203fdf91bff568fe64
Subproject commit 6fcd157f2497d9ba4ba82191cb2abf3de11a0394

@ -1 +1 @@
Subproject commit 0f72f6c85c3743a9072273acb6a8a34b1cf1064b
Subproject commit 9d538629bb8a425991c7d10a49bab1ba0788c18f

View File

@ -1587,8 +1587,9 @@ class WM_OT_properties_edit(Operator):
elif self.property_type == 'STRING':
self.default_string = rna_data["default"]
elif self.property_type in {'BOOL', 'BOOL_ARRAY'}:
self.default_int = self._convert_new_value_array(rna_data["default"], bool, 32)
elif self.property_type in {'FLOAT_ARRAY', 'INT_ARRAY', 'BOOL_ARRAY'}:
self.default_bool = self._convert_new_value_array(rna_data["default"], bool, 32)
if self.property_type in {'FLOAT_ARRAY', 'INT_ARRAY', 'BOOL_ARRAY'}:
self.array_length = len(item[name])
# The dictionary does not contain the description if it was empty.

View File

@ -50,5 +50,7 @@ else()
add_executable(blender-thumbnailer ${SRC} ${SRC_CMD})
setup_platform_linker_flags(blender-thumbnailer)
target_link_libraries(blender-thumbnailer bf_blenlib)
target_link_libraries(blender-thumbnailer ${PTHREADS_LIBRARIES})
if(DEFINED PTHREADS_LIBRARIES)
target_link_libraries(blender-thumbnailer ${PTHREADS_LIBRARIES})
endif()
endif()

View File

@ -753,20 +753,6 @@ Vector<AttributeTransferData> retrieve_attributes_for_transfer(
const AnonymousAttributePropagationInfo &propagation_info,
const Set<std::string> &skip = {});
/**
* Copy attributes for the domain based on the elementwise mask.
*
* \param mask_indices: Indexed elements to copy from the source data-block.
* \param domain: Attribute domain to transfer.
* \param skip: Named attributes to ignore/skip.
*/
void copy_attribute_domain(AttributeAccessor src_attributes,
MutableAttributeAccessor dst_attributes,
IndexMask selection,
eAttrDomain domain,
const AnonymousAttributePropagationInfo &propagation_info,
const Set<std::string> &skip = {});
bool allow_procedural_attribute_access(StringRef attribute_name);
extern const char *no_procedural_access_message;

View File

@ -30,17 +30,6 @@
namespace blender::bke {
template<typename T, BLI_ENABLE_IF(std::is_integral_v<T>)>
constexpr IndexRange offsets_to_range(Span<T> offsets, int64_t index)
{
BLI_assert(index >= 0);
BLI_assert(index < offsets.size());
const int offset = offsets[index];
const int offset_next = offsets[index + 1];
return {offset, offset_next - offset};
}
namespace curves::nurbs {
struct BasisCache {
@ -81,7 +70,7 @@ class CurvesGeometryRuntime {
* evaluated points, Bezier curve vector segments, different resolutions per curve, etc.
*/
mutable Vector<int> evaluated_offsets_cache;
mutable Vector<int> bezier_evaluated_offsets;
mutable Vector<int> all_bezier_evaluated_offsets;
mutable CacheMutex offsets_cache_mutex;
mutable Vector<curves::nurbs::BasisCache> nurbs_basis_cache;
@ -303,25 +292,14 @@ class CurvesGeometry : public ::CurvesGeometry {
int evaluated_points_num() const;
/**
* Access a range of indices of point data for a specific curve.
* Call #evaluated_offsets() first to ensure that the evaluated offsets cache is current.
* The offsets of every curve's evaluated points.
*/
IndexRange evaluated_points_for_curve(int index) const;
IndexRange evaluated_points_for_curves(IndexRange curves) const;
OffsetIndices<int> evaluated_points_by_curve() const;
/**
* The index of the first evaluated point for every curve. The size of this span is one larger
* than the number of curves. Consider using #evaluated_points_for_curve rather than using the
* offsets directly.
*/
Span<int> evaluated_offsets() const;
/** Makes sure the data described by #evaluated_offsets if necessary. */
void ensure_evaluated_offsets() const;
/**
* Retrieve offsets into a Bezier curve's evaluated points for each control point.
* Call #ensure_evaluated_offsets() first to ensure that the evaluated offsets cache is current.
* Retrieve offsets into a Bezier curve's evaluated points for each control point. Stored in the
* same format as #OffsetIndices. Call #evaluated_points_by_curve() first to ensure that the
* evaluated offsets cache is current.
*/
Span<int> bezier_evaluated_offsets_for_curve(int curve_index) const;
@ -489,6 +467,17 @@ inline float3 decode_surface_bary_coord(const float2 &v)
return {v.x, v.y, 1.0f - v.x - v.y};
}
/**
* Return a range used to retrieve values from an array of values stored per point, but with an
* extra element at the end of each curve. This is useful for offsets within curves, where it is
* convenient to store the first 0 and have the last offset be the total result curve size, using
* the same rules as #OffsetIndices.
*/
inline IndexRange per_curve_point_offsets_range(const IndexRange points, const int curve_index)
{
return {curve_index + points.start(), points.size() + 1};
}
/** \} */
/* -------------------------------------------------------------------- */
@ -567,8 +556,9 @@ bool point_is_sharp(Span<int8_t> handle_types_left, Span<int8_t> handle_types_ri
* point edges generate the number of edges specified by the resolution, vector segments only
* generate one edge.
*
* The size of the offsets array must be the same as the number of points. The value at each index
* is the evaluated point offset including the following segment.
* The expectations for the result \a evaluated_offsets are the same as for #OffsetIndices, so the
* size must be one greater than the number of points. The value at each index is the evaluated
* point at the start of that segment.
*/
void calculate_evaluated_offsets(Span<int8_t> handle_types_left,
Span<int8_t> handle_types_right,
@ -668,7 +658,7 @@ void evaluate_segment(const float3 &point_0,
void calculate_evaluated_positions(Span<float3> positions,
Span<float3> handles_left,
Span<float3> handles_right,
Span<int> evaluated_offsets,
OffsetIndices<int> evaluated_offsets,
MutableSpan<float3> evaluated_positions);
/**
@ -676,7 +666,7 @@ void calculate_evaluated_positions(Span<float3> positions,
* #evaluated_offsets. Unlike other curve types, for Bezier curves generic data and positions
* are treated separately, since attribute values aren't stored for the handle control points.
*/
void interpolate_to_evaluated(GSpan src, Span<int> evaluated_offsets, GMutableSpan dst);
void interpolate_to_evaluated(GSpan src, OffsetIndices<int> evaluated_offsets, GMutableSpan dst);
} // namespace bezier
@ -702,12 +692,12 @@ int calculate_evaluated_num(int points_num, bool cyclic, int resolution);
void interpolate_to_evaluated(GSpan src, bool cyclic, int resolution, GMutableSpan dst);
/**
* Evaluate the Catmull Rom curve. The size of each segment and its offset in the #dst span
* is encoded in #evaluated_offsets, with the same method as #CurvesGeometry::offsets().
* Evaluate the Catmull Rom curve. The placement of each segment in the #dst span is desribed by
* #evaluated_offsets.
*/
void interpolate_to_evaluated(const GSpan src,
const bool cyclic,
const Span<int> evaluated_offsets,
const OffsetIndices<int> evaluated_offsets,
GMutableSpan dst);
void calculate_basis(const float parameter, float4 &r_weights);
@ -877,36 +867,22 @@ inline OffsetIndices<int> CurvesGeometry::points_by_curve() const
inline int CurvesGeometry::evaluated_points_num() const
{
/* This could avoid calculating offsets in the future in simple circumstances. */
return this->evaluated_offsets().last();
}
inline IndexRange CurvesGeometry::evaluated_points_for_curve(int index) const
{
BLI_assert(this->runtime->offsets_cache_mutex.is_cached());
return offsets_to_range(this->runtime->evaluated_offsets_cache.as_span(), index);
}
inline IndexRange CurvesGeometry::evaluated_points_for_curves(const IndexRange curves) const
{
BLI_assert(this->runtime->offsets_cache_mutex.is_cached());
BLI_assert(this->curve_num > 0);
const int offset = this->runtime->evaluated_offsets_cache[curves.start()];
const int offset_next = this->runtime->evaluated_offsets_cache[curves.one_after_last()];
return {offset, offset_next - offset};
return this->evaluated_points_by_curve().total_size();
}
inline Span<int> CurvesGeometry::bezier_evaluated_offsets_for_curve(const int curve_index) const
{
const OffsetIndices points_by_curve = this->points_by_curve();
const IndexRange points = points_by_curve[curve_index];
return this->runtime->bezier_evaluated_offsets.as_span().slice(points);
const IndexRange range = curves::per_curve_point_offsets_range(points, curve_index);
return this->runtime->all_bezier_evaluated_offsets.as_span().slice(range);
}
inline IndexRange CurvesGeometry::lengths_range_for_curve(const int curve_index,
const bool cyclic) const
{
BLI_assert(cyclic == this->cyclic()[curve_index]);
const IndexRange points = this->evaluated_points_for_curve(curve_index);
const IndexRange points = this->evaluated_points_by_curve()[curve_index];
const int start = points.start() + curve_index;
return {start, curves::segments_num(points.size(), cyclic)};
}

View File

@ -76,14 +76,17 @@ struct CurvePoint : public CurveSegment {
* [0, range_size) can be iterated over an arbitrary amount of times in between.
*/
class IndexRangeCyclic {
/* Index to the start and end of the iterated range.
/**
* Index to the start and end of the iterated range.
*/
int start_ = 0;
int end_ = 0;
/* Size of the underlying iterable range.
/**
* Size of the underlying iterable range.
*/
int range_size_ = 0;
/* Number of times the range end is passed when the range is iterated.
/**
* Number of times the range end is passed when the range is iterated.
*/
int cycles_ = 0;
@ -519,18 +522,22 @@ void fill_points(const CurvesGeometry &curves,
}
/**
* Copy only the attributes on the curve domain, but not the offsets or any point attributes,
* meant for operations that change the number of points but not the number of curves.
* Create new curves with the same number of curves as the input, but no points. Copy all curve
* domain attributes to the new curves, except the offsets encoding the size of each curve.
*
* Used for operations that change the number of points but not the number of curves, allowing
* creation of the new offsets directly inside the new array.
*
* \warning The returned curves have invalid offsets!
*/
bke::CurvesGeometry copy_only_curve_domain(const bke::CurvesGeometry &src_curves);
/**
* Copy the size of every curve in #curve_ranges to the corresponding index in #counts.
* Copy the number of points in every curve in #curve_ranges to the corresponding index in #sizes.
*/
void fill_curve_counts(const bke::CurvesGeometry &curves,
Span<IndexRange> curve_ranges,
MutableSpan<int> counts);
void copy_curve_sizes(const bke::CurvesGeometry &curves,
Span<IndexRange> curve_ranges,
MutableSpan<int> sizes);
IndexMask indices_for_type(const VArray<int8_t> &types,
const std::array<int, CURVE_TYPES_NUM> &type_counts,

View File

@ -92,8 +92,10 @@ int BKE_object_data_transfer_dttype_to_srcdst_index(int dtdata_type);
DT_TYPE_SHAPEKEY, \
DT_TYPE_MPROPCOL_VERT, \
DT_TYPE_MLOOPCOL_VERT, \
DT_TYPE_MPROPCOL_VERT | DT_TYPE_MLOOPCOL_VERT, \
DT_TYPE_MPROPCOL_LOOP, \
DT_TYPE_MLOOPCOL_LOOP, \
DT_TYPE_MPROPCOL_LOOP | DT_TYPE_MLOOPCOL_LOOP, \
DT_TYPE_UV)
enum {

View File

@ -139,6 +139,13 @@ typedef struct Global {
* Typically Python drivers.
*/
char autoexec_fail[200];
/**
* Has there been an opengl deprecation call detected when running on a none OpenGL backend.
*/
bool opengl_deprecation_usage_detected;
const char *opengl_deprecation_usage_filename;
int opengl_deprecation_usage_lineno;
} Global;
/* **************** GLOBAL ********************* */

View File

@ -10,6 +10,8 @@
/** Temp constant defined for these functions only. */
#define NLASTRIP_MIN_LEN_THRESH 0.1f
#include "DNA_listBase.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -295,6 +297,11 @@ void BKE_nlastrip_recalculate_bounds(struct NlaStrip *strip);
*/
void BKE_nlastrip_recalculate_bounds_sync_action(struct NlaStrip *strip);
/**
* Recalculate the Blendin and Blendout values after a strip transform update.
*/
void BKE_nlastrip_recalculate_blend(struct NlaStrip *strip);
/**
* Find (and set) a unique name for a strip from the whole AnimData block
* Uses a similar method to the BLI method, but is implemented differently

View File

@ -559,15 +559,16 @@ if(WIN32)
endif()
if(WITH_AUDASPACE)
add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
)
list(APPEND LIB
${AUDASPACE_C_LIBRARIES}
${AUDASPACE_PY_LIBRARIES}
)
if(WITH_SYSTEM_AUDASPACE)
list(APPEND LIB
${AUDASPACE_C_LIBRARIES}
${AUDASPACE_PY_LIBRARIES}
)
endif()
add_definitions(-DWITH_AUDASPACE)
endif()
if(WITH_BULLET)
@ -577,13 +578,6 @@ if(WITH_BULLET)
list(APPEND INC
../../../intern/rigidbody
)
if(NOT WITH_SYSTEM_BULLET)
list(APPEND LIB
extern_bullet
)
endif()
list(APPEND LIB
bf_intern_rigidbody
@ -843,6 +837,7 @@ if(WITH_GTESTS)
intern/lib_id_remapper_test.cc
intern/lib_id_test.cc
intern/lib_remap_test.cc
intern/nla_test.cc
intern/tracking_test.cc
)
set(TEST_INC
@ -853,4 +848,4 @@ if(WITH_GTESTS)
# RNA_prototypes.h
add_dependencies(bf_blenkernel_tests bf_rna)
endif()
endif()

View File

@ -913,38 +913,6 @@ Vector<AttributeTransferData> retrieve_attributes_for_transfer(
return attributes;
}
void copy_attribute_domain(const AttributeAccessor src_attributes,
MutableAttributeAccessor dst_attributes,
const IndexMask selection,
const eAttrDomain domain,
const AnonymousAttributePropagationInfo &propagation_info,
const Set<std::string> &skip)
{
src_attributes.for_all(
[&](const bke::AttributeIDRef &id, const bke::AttributeMetaData &meta_data) {
if (meta_data.domain != domain) {
return true;
}
if (id.is_anonymous() && !propagation_info.propagate(id.anonymous_id())) {
return true;
}
if (skip.contains(id.name())) {
return true;
}
const GVArray src = src_attributes.lookup(id, meta_data.domain);
BLI_assert(src);
/* Copy attribute. */
GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span(
id, domain, meta_data.data_type);
array_utils::copy(src, selection, dst.span);
dst.finish();
return true;
});
}
} // namespace blender::bke
/** \} */

View File

@ -33,20 +33,21 @@ void calculate_evaluated_offsets(const Span<int8_t> handle_types_left,
MutableSpan<int> evaluated_offsets)
{
const int size = handle_types_left.size();
BLI_assert(evaluated_offsets.size() == size);
BLI_assert(evaluated_offsets.size() == size + 1);
evaluated_offsets.first() = 0;
if (size == 1) {
evaluated_offsets.first() = 1;
evaluated_offsets.last() = 1;
return;
}
int offset = 0;
for (const int i : IndexRange(size - 1)) {
offset += segment_is_vector(handle_types_left, handle_types_right, i) ? 1 : resolution;
evaluated_offsets[i] = offset;
offset += segment_is_vector(handle_types_left, handle_types_right, i) ? 1 : resolution;
}
evaluated_offsets.last(1) = offset;
if (cyclic) {
offset += last_cyclic_segment_is_vector(handle_types_left, handle_types_right) ? 1 :
resolution;
@ -233,12 +234,11 @@ void evaluate_segment(const float3 &point_0,
void calculate_evaluated_positions(const Span<float3> positions,
const Span<float3> handles_left,
const Span<float3> handles_right,
const Span<int> evaluated_offsets,
const OffsetIndices<int> evaluated_offsets,
MutableSpan<float3> evaluated_positions)
{
BLI_assert(evaluated_offsets.last() == evaluated_positions.size());
BLI_assert(evaluated_offsets.size() == positions.size());
if (evaluated_offsets.last() == 1) {
BLI_assert(evaluated_offsets.total_size() == evaluated_positions.size());
if (evaluated_offsets.total_size() == 1) {
evaluated_positions.first() = positions.first();
return;
}
@ -248,29 +248,29 @@ void calculate_evaluated_positions(const Span<float3> positions,
handles_right.first(),
handles_left[1],
positions[1],
evaluated_positions.take_front(evaluated_offsets.first()));
evaluated_positions.slice(evaluated_offsets[0]));
/* Give each task fewer segments as the resolution gets larger. */
const int grain_size = std::max<int>(evaluated_positions.size() / positions.size() * 32, 1);
threading::parallel_for(
positions.index_range().drop_back(1).drop_front(1), grain_size, [&](IndexRange range) {
for (const int i : range) {
const IndexRange evaluated_range = offsets_to_range(evaluated_offsets, i - 1);
if (evaluated_range.size() == 1) {
evaluated_positions[evaluated_range.first()] = positions[i];
}
else {
evaluate_segment(positions[i],
handles_right[i],
handles_left[i + 1],
positions[i + 1],
evaluated_positions.slice(evaluated_range));
}
}
});
const IndexRange inner_segments = positions.index_range().drop_back(1).drop_front(1);
threading::parallel_for(inner_segments, grain_size, [&](IndexRange range) {
for (const int i : range) {
const IndexRange evaluated_range = evaluated_offsets[i];
if (evaluated_range.size() == 1) {
evaluated_positions[evaluated_range.first()] = positions[i];
}
else {
evaluate_segment(positions[i],
handles_right[i],
handles_left[i + 1],
positions[i + 1],
evaluated_positions.slice(evaluated_range));
}
}
});
/* Evaluate the final cyclic segment if necessary. */
const IndexRange last_segment_points = offsets_to_range(evaluated_offsets, positions.size() - 2);
const IndexRange last_segment_points = evaluated_offsets[positions.index_range().last()];
if (last_segment_points.size() == 1) {
evaluated_positions.last() = positions.last();
}
@ -295,34 +295,34 @@ static inline void linear_interpolation(const T &a, const T &b, MutableSpan<T> d
template<typename T>
static void interpolate_to_evaluated(const Span<T> src,
const Span<int> evaluated_offsets,
const OffsetIndices<int> evaluated_offsets,
MutableSpan<T> dst)
{
BLI_assert(!src.is_empty());
BLI_assert(evaluated_offsets.size() == src.size());
BLI_assert(evaluated_offsets.last() == dst.size());
BLI_assert(evaluated_offsets.total_size() == dst.size());
if (src.size() == 1) {
BLI_assert(dst.size() == 1);
dst.first() = src.first();
return;
}
linear_interpolation(src.first(), src[1], dst.take_front(evaluated_offsets.first()));
linear_interpolation(src.first(), src[1], dst.slice(evaluated_offsets[0]));
threading::parallel_for(
src.index_range().drop_back(1).drop_front(1), 512, [&](IndexRange range) {
for (const int i : range) {
const IndexRange segment_points = offsets_to_range(evaluated_offsets, i - 1);
linear_interpolation(src[i], src[i + 1], dst.slice(segment_points));
const IndexRange segment = evaluated_offsets[i];
linear_interpolation(src[i], src[i + 1], dst.slice(segment));
}
});
const IndexRange last_segment_points(evaluated_offsets.last(1),
evaluated_offsets.last() - evaluated_offsets.last(1));
linear_interpolation(src.last(), src.first(), dst.slice(last_segment_points));
const IndexRange last_segment = evaluated_offsets[src.index_range().last()];
linear_interpolation(src.last(), src.first(), dst.slice(last_segment));
}
void interpolate_to_evaluated(const GSpan src, const Span<int> evaluated_offsets, GMutableSpan dst)
void interpolate_to_evaluated(const GSpan src,
const OffsetIndices<int> evaluated_offsets,
GMutableSpan dst)
{
attribute_math::convert_to_static_type(src.type(), [&](auto dummy) {
using T = decltype(dummy);

View File

@ -123,7 +123,7 @@ static void interpolate_to_evaluated(const Span<T> src,
template<typename T>
static void interpolate_to_evaluated(const Span<T> src,
const bool cyclic,
const Span<int> evaluated_offsets,
const OffsetIndices<int> evaluated_offsets,
MutableSpan<T> dst)
{
@ -131,7 +131,7 @@ static void interpolate_to_evaluated(const Span<T> src,
src,
cyclic,
[evaluated_offsets](const int segment_i) -> IndexRange {
return bke::offsets_to_range(evaluated_offsets, segment_i);
return evaluated_offsets[segment_i];
},
dst);
}
@ -149,7 +149,7 @@ void interpolate_to_evaluated(const GSpan src,
void interpolate_to_evaluated(const GSpan src,
const bool cyclic,
const Span<int> evaluated_offsets,
const OffsetIndices<int> evaluated_offsets,
GMutableSpan dst)
{
attribute_math::convert_to_static_type(src.type(), [&](auto dummy) {

View File

@ -165,7 +165,7 @@ static void mark_bezier_vector_edges_sharp(const int profile_point_num,
for (const int i : IndexRange(profile_point_num).drop_front(1)) {
if (curves::bezier::point_is_sharp(handle_types_left, handle_types_right, i)) {
const int offset = main_edges_start + main_segment_num * control_point_offsets[i - 1];
const int offset = main_edges_start + main_segment_num * control_point_offsets[i];
sharp_edges.slice(offset, main_segment_num).fill(true);
}
}
@ -245,8 +245,8 @@ static ResultOffsets calculate_result_offsets(const CurvesInfo &info, const bool
result.main_indices.reinitialize(result.total);
result.profile_indices.reinitialize(result.total);
info.main.ensure_evaluated_offsets();
info.profile.ensure_evaluated_offsets();
const OffsetIndices<int> main_offsets = info.main.evaluated_points_by_curve();
const OffsetIndices<int> profile_offsets = info.profile.evaluated_points_by_curve();
int mesh_index = 0;
int vert_offset = 0;
@ -255,7 +255,7 @@ static ResultOffsets calculate_result_offsets(const CurvesInfo &info, const bool
int poly_offset = 0;
for (const int i_main : info.main.curves_range()) {
const bool main_cyclic = info.main_cyclic[i_main];
const int main_point_num = info.main.evaluated_points_for_curve(i_main).size();
const int main_point_num = main_offsets.size(i_main);
const int main_segment_num = curves::segments_num(main_point_num, main_cyclic);
for (const int i_profile : info.profile.curves_range()) {
result.vert[mesh_index] = vert_offset;
@ -267,7 +267,7 @@ static ResultOffsets calculate_result_offsets(const CurvesInfo &info, const bool
result.profile_indices[mesh_index] = i_profile;
const bool profile_cyclic = info.profile_cyclic[i_profile];
const int profile_point_num = info.profile.evaluated_points_for_curve(i_profile).size();
const int profile_point_num = profile_offsets.size(i_profile);
const int profile_segment_num = curves::segments_num(profile_point_num, profile_cyclic);
const bool has_caps = fill_caps && !main_cyclic && profile_cyclic;
@ -376,13 +376,19 @@ static void foreach_curve_combination(const CurvesInfo &info,
const ResultOffsets &offsets,
const Fn &fn)
{
const OffsetIndices<int> main_offsets = info.main.evaluated_points_by_curve();
const OffsetIndices<int> profile_offsets = info.profile.evaluated_points_by_curve();
const OffsetIndices<int> vert_offsets(offsets.vert);
const OffsetIndices<int> edge_offsets(offsets.edge);
const OffsetIndices<int> poly_offsets(offsets.poly);
const OffsetIndices<int> loop_offsets(offsets.loop);
threading::parallel_for(IndexRange(offsets.total), 512, [&](IndexRange range) {
for (const int i : range) {
const int i_main = offsets.main_indices[i];
const int i_profile = offsets.profile_indices[i];
const IndexRange main_points = info.main.evaluated_points_for_curve(i_main);
const IndexRange profile_points = info.profile.evaluated_points_for_curve(i_profile);
const IndexRange main_points = main_offsets[i_main];
const IndexRange profile_points = profile_offsets[i_profile];
const bool main_cyclic = info.main_cyclic[i_main];
const bool profile_cyclic = info.profile_cyclic[i_profile];
@ -398,10 +404,10 @@ static void foreach_curve_combination(const CurvesInfo &info,
profile_cyclic,
curves::segments_num(main_points.size(), main_cyclic),
curves::segments_num(profile_points.size(), profile_cyclic),
offsets_to_range(offsets.vert.as_span(), i),
offsets_to_range(offsets.edge.as_span(), i),
offsets_to_range(offsets.poly.as_span(), i),
offsets_to_range(offsets.loop.as_span(), i)});
vert_offsets[i],
edge_offsets[i],
poly_offsets[i],
loop_offsets[i]});
}
});
}
@ -569,7 +575,7 @@ static void copy_profile_point_domain_attribute_to_mesh(const CurvesInfo &curves
template<typename T>
static void copy_indices_to_offset_ranges(const VArray<T> &src,
const Span<int> curve_indices,
const Span<int> mesh_offsets,
const OffsetIndices<int> mesh_offsets,
MutableSpan<T> dst)
{
/* This unnecessarily instantiates the "is single" case (which should be handled elsewhere if
@ -578,7 +584,7 @@ static void copy_indices_to_offset_ranges(const VArray<T> &src,
devirtualize_varray(src, [&](const auto &src) {
threading::parallel_for(curve_indices.index_range(), 512, [&](IndexRange range) {
for (const int i : range) {
dst.slice(offsets_to_range(mesh_offsets, i)).fill(src[curve_indices[i]]);
dst.slice(mesh_offsets[i]).fill(src[curve_indices[i]]);
}
});
});

View File

@ -760,6 +760,7 @@ static void create_samples(CurveProfile *profile,
}
BLI_assert(n_added == n_segments); /* n_added is just used for this assert, could remove it. */
UNUSED_VARS_NDEBUG(n_added);
/* Sample the points and add them to the locations table. */
for (int i_sample = 0, i = 0; i < totedges; i++) {

View File

@ -455,18 +455,18 @@ template<typename CountFn> void build_offsets(MutableSpan<int> offsets, const Co
static void calculate_evaluated_offsets(const CurvesGeometry &curves,
MutableSpan<int> offsets,
MutableSpan<int> bezier_evaluated_offsets)
MutableSpan<int> all_bezier_offsets)
{
const OffsetIndices points_by_curve = curves.points_by_curve();
VArray<int8_t> types = curves.curve_types();
VArray<int> resolution = curves.resolution();
VArray<bool> cyclic = curves.cyclic();
const VArray<int8_t> types = curves.curve_types();
const VArray<int> resolution = curves.resolution();
const VArray<bool> cyclic = curves.cyclic();
VArraySpan<int8_t> handle_types_left{curves.handle_types_left()};
VArraySpan<int8_t> handle_types_right{curves.handle_types_right()};
const VArraySpan<int8_t> handle_types_left{curves.handle_types_left()};
const VArraySpan<int8_t> handle_types_right{curves.handle_types_right()};
VArray<int8_t> nurbs_orders = curves.nurbs_orders();
VArray<int8_t> nurbs_knots_modes = curves.nurbs_knots_modes();
const VArray<int8_t> nurbs_orders = curves.nurbs_orders();
const VArray<int8_t> nurbs_knots_modes = curves.nurbs_knots_modes();
build_offsets(offsets, [&](const int curve_index) -> int {
const IndexRange points = points_by_curve[curve_index];
@ -476,13 +476,15 @@ static void calculate_evaluated_offsets(const CurvesGeometry &curves,
points.size(), cyclic[curve_index], resolution[curve_index]);
case CURVE_TYPE_POLY:
return points.size();
case CURVE_TYPE_BEZIER:
case CURVE_TYPE_BEZIER: {
const IndexRange offsets = curves::per_curve_point_offsets_range(points, curve_index);
curves::bezier::calculate_evaluated_offsets(handle_types_left.slice(points),
handle_types_right.slice(points),
cyclic[curve_index],
resolution[curve_index],
bezier_evaluated_offsets.slice(points));
return bezier_evaluated_offsets[points.last()];
all_bezier_offsets.slice(offsets));
return all_bezier_offsets[offsets.last()];
}
case CURVE_TYPE_NURBS:
return curves::nurbs::calculate_evaluated_num(points.size(),
nurbs_orders[curve_index],
@ -495,27 +497,32 @@ static void calculate_evaluated_offsets(const CurvesGeometry &curves,
});
}
void CurvesGeometry::ensure_evaluated_offsets() const
OffsetIndices<int> CurvesGeometry::evaluated_points_by_curve() const
{
if (this->is_single_type(CURVE_TYPE_POLY)) {
/* When all the curves are poly curves, the evaluated offsets are the same as the control
* point offsets, so it's possible to completely avoid building a new offsets array. */
this->runtime->offsets_cache_mutex.ensure(
[&]() { this->runtime->evaluated_offsets_cache.clear_and_shrink(); });
return this->points_by_curve();
}
this->runtime->offsets_cache_mutex.ensure([&]() {
this->runtime->evaluated_offsets_cache.resize(this->curves_num() + 1);
if (this->has_curve_with_type(CURVE_TYPE_BEZIER)) {
this->runtime->bezier_evaluated_offsets.resize(this->points_num());
this->runtime->all_bezier_evaluated_offsets.resize(this->points_num() + this->curves_num());
}
else {
this->runtime->bezier_evaluated_offsets.clear_and_shrink();
this->runtime->all_bezier_evaluated_offsets.clear_and_shrink();
}
calculate_evaluated_offsets(
*this, this->runtime->evaluated_offsets_cache, this->runtime->bezier_evaluated_offsets);
calculate_evaluated_offsets(*this,
this->runtime->evaluated_offsets_cache,
this->runtime->all_bezier_evaluated_offsets);
});
}
Span<int> CurvesGeometry::evaluated_offsets() const
{
this->ensure_evaluated_offsets();
return this->runtime->evaluated_offsets_cache;
return OffsetIndices<int>(this->runtime->evaluated_offsets_cache);
}
IndexMask CurvesGeometry::indices_for_curve_type(const CurveType type,
@ -557,14 +564,16 @@ void CurvesGeometry::ensure_nurbs_basis_cache() const
MutableSpan<curves::nurbs::BasisCache> basis_caches(this->runtime->nurbs_basis_cache);
const OffsetIndices<int> points_by_curve = this->points_by_curve();
VArray<bool> cyclic = this->cyclic();
VArray<int8_t> orders = this->nurbs_orders();
VArray<int8_t> knots_modes = this->nurbs_knots_modes();
const OffsetIndices<int> evaluated_points_by_curve = this->evaluated_points_by_curve();
const VArray<bool> cyclic = this->cyclic();
const VArray<int8_t> orders = this->nurbs_orders();
const VArray<int8_t> knots_modes = this->nurbs_knots_modes();
threading::parallel_for(nurbs_mask.index_range(), 64, [&](const IndexRange range) {
Vector<float, 32> knots;
for (const int curve_index : nurbs_mask.slice(range)) {
const IndexRange points = points_by_curve[curve_index];
const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index);
const IndexRange evaluated_points = evaluated_points_by_curve[curve_index];
const int8_t order = orders[curve_index];
const bool is_cyclic = cyclic[curve_index];
@ -575,8 +584,7 @@ void CurvesGeometry::ensure_nurbs_basis_cache() const
continue;
}
const int knots_num = curves::nurbs::knots_num(points.size(), order, is_cyclic);
Array<float> knots(knots_num);
knots.reinitialize(curves::nurbs::knots_num(points.size(), order, is_cyclic));
curves::nurbs::calculate_knots(points.size(), mode, order, is_cyclic, knots);
curves::nurbs::calculate_basis_cache(points.size(),
evaluated_points.size(),
@ -603,24 +611,25 @@ Span<float3> CurvesGeometry::evaluated_positions() const
this->runtime->evaluated_positions_span = evaluated_positions;
const OffsetIndices<int> points_by_curve = this->points_by_curve();
VArray<int8_t> types = this->curve_types();
VArray<bool> cyclic = this->cyclic();
VArray<int> resolution = this->resolution();
Span<float3> positions = this->positions();
const OffsetIndices<int> evaluated_points_by_curve = this->evaluated_points_by_curve();
const VArray<int8_t> types = this->curve_types();
const VArray<bool> cyclic = this->cyclic();
const VArray<int> resolution = this->resolution();
const Span<float3> positions = this->positions();
Span<float3> handle_positions_left = this->handle_positions_left();
Span<float3> handle_positions_right = this->handle_positions_right();
Span<int> bezier_evaluated_offsets = this->runtime->bezier_evaluated_offsets;
const Span<float3> handle_positions_left = this->handle_positions_left();
const Span<float3> handle_positions_right = this->handle_positions_right();
const Span<int> all_bezier_evaluated_offsets = this->runtime->all_bezier_evaluated_offsets;
VArray<int8_t> nurbs_orders = this->nurbs_orders();
Span<float> nurbs_weights = this->nurbs_weights();
const VArray<int8_t> nurbs_orders = this->nurbs_orders();
const Span<float> nurbs_weights = this->nurbs_weights();
this->ensure_nurbs_basis_cache();
threading::parallel_for(this->curves_range(), 128, [&](IndexRange curves_range) {
for (const int curve_index : curves_range) {
const IndexRange points = points_by_curve[curve_index];
const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index);
const IndexRange evaluated_points = evaluated_points_by_curve[curve_index];
switch (types[curve_index]) {
case CURVE_TYPE_CATMULL_ROM:
@ -633,22 +642,23 @@ Span<float3> CurvesGeometry::evaluated_positions() const
case CURVE_TYPE_POLY:
evaluated_positions.slice(evaluated_points).copy_from(positions.slice(points));
break;
case CURVE_TYPE_BEZIER:
case CURVE_TYPE_BEZIER: {
const IndexRange offsets = curves::per_curve_point_offsets_range(points, curve_index);
curves::bezier::calculate_evaluated_positions(
positions.slice(points),
handle_positions_left.slice(points),
handle_positions_right.slice(points),
bezier_evaluated_offsets.slice(points),
all_bezier_evaluated_offsets.slice(offsets),
evaluated_positions.slice(evaluated_points));
break;
case CURVE_TYPE_NURBS: {
}
case CURVE_TYPE_NURBS:
curves::nurbs::interpolate_to_evaluated(this->runtime->nurbs_basis_cache[curve_index],
nurbs_orders[curve_index],
nurbs_weights.slice_safe(points),
positions.slice(points),
evaluated_positions.slice(evaluated_points));
break;
}
default:
BLI_assert_unreachable();
break;
@ -662,6 +672,7 @@ Span<float3> CurvesGeometry::evaluated_positions() const
Span<float3> CurvesGeometry::evaluated_tangents() const
{
this->runtime->tangent_cache_mutex.ensure([&]() {
const OffsetIndices<int> evaluated_points_by_curve = this->evaluated_points_by_curve();
const Span<float3> evaluated_positions = this->evaluated_positions();
const VArray<bool> cyclic = this->cyclic();
@ -670,7 +681,7 @@ Span<float3> CurvesGeometry::evaluated_tangents() const
threading::parallel_for(this->curves_range(), 128, [&](IndexRange curves_range) {
for (const int curve_index : curves_range) {
const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index);
const IndexRange evaluated_points = evaluated_points_by_curve[curve_index];
curves::poly::calculate_tangents(evaluated_positions.slice(evaluated_points),
cyclic[curve_index],
tangents.slice(evaluated_points));
@ -694,7 +705,7 @@ Span<float3> CurvesGeometry::evaluated_tangents() const
continue;
}
const IndexRange points = points_by_curve[curve_index];
const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index);
const IndexRange evaluated_points = evaluated_points_by_curve[curve_index];
const float epsilon = 1e-6f;
if (!math::almost_equal_relative(
@ -729,7 +740,7 @@ static void evaluate_generic_data_for_curve(
const VArray<int8_t> &types,
const VArray<bool> &cyclic,
const VArray<int> &resolution,
const Span<int> bezier_evaluated_offsets,
const Span<int> all_bezier_evaluated_offsets,
const Span<curves::nurbs::BasisCache> nurbs_basis_cache,
const VArray<int8_t> &nurbs_orders,
const Span<float> nurbs_weights,
@ -744,9 +755,12 @@ static void evaluate_generic_data_for_curve(
case CURVE_TYPE_POLY:
dst.copy_from(src);
break;
case CURVE_TYPE_BEZIER:
curves::bezier::interpolate_to_evaluated(src, bezier_evaluated_offsets.slice(points), dst);
case CURVE_TYPE_BEZIER: {
const IndexRange offsets = curves::per_curve_point_offsets_range(points, curve_index);
curves::bezier::interpolate_to_evaluated(
src, all_bezier_evaluated_offsets.slice(offsets), dst);
break;
}
case CURVE_TYPE_NURBS:
curves::nurbs::interpolate_to_evaluated(nurbs_basis_cache[curve_index],
nurbs_orders[curve_index],
@ -761,6 +775,7 @@ Span<float3> CurvesGeometry::evaluated_normals() const
{
this->runtime->normal_cache_mutex.ensure([&]() {
const OffsetIndices<int> points_by_curve = this->points_by_curve();
const OffsetIndices<int> evaluated_points_by_curve = this->evaluated_points_by_curve();
const VArray<int8_t> types = this->curve_types();
const VArray<bool> cyclic = this->cyclic();
const VArray<int8_t> normal_mode = this->normal_mode();
@ -784,7 +799,7 @@ Span<float3> CurvesGeometry::evaluated_normals() const
Vector<float> evaluated_tilts;
for (const int curve_index : curves_range) {
const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index);
const IndexRange evaluated_points = evaluated_points_by_curve[curve_index];
switch (normal_mode[curve_index]) {
case NORMAL_MODE_Z_UP:
curves::poly::calculate_normals_z_up(evaluated_tangents.slice(evaluated_points),
@ -813,7 +828,7 @@ Span<float3> CurvesGeometry::evaluated_normals() const
types,
cyclic,
resolution,
this->runtime->bezier_evaluated_offsets.as_span(),
this->runtime->all_bezier_evaluated_offsets.as_span(),
this->runtime->nurbs_basis_cache.as_span(),
nurbs_orders,
nurbs_weights,
@ -839,13 +854,13 @@ void CurvesGeometry::interpolate_to_evaluated(const int curve_index,
const OffsetIndices points_by_curve = this->points_by_curve();
const IndexRange points = points_by_curve[curve_index];
BLI_assert(src.size() == points.size());
BLI_assert(dst.size() == this->evaluated_points_for_curve(curve_index).size());
BLI_assert(dst.size() == this->evaluated_points_by_curve().size(curve_index));
evaluate_generic_data_for_curve(curve_index,
points,
this->curve_types(),
this->cyclic(),
this->resolution(),
this->runtime->bezier_evaluated_offsets.as_span(),
this->runtime->all_bezier_evaluated_offsets.as_span(),
this->runtime->nurbs_basis_cache.as_span(),
this->nurbs_orders(),
this->nurbs_weights(),
@ -858,6 +873,7 @@ void CurvesGeometry::interpolate_to_evaluated(const GSpan src, GMutableSpan dst)
BLI_assert(this->runtime->offsets_cache_mutex.is_cached());
BLI_assert(this->runtime->nurbs_basis_cache_mutex.is_cached());
const OffsetIndices points_by_curve = this->points_by_curve();
const OffsetIndices evaluated_points_by_curve = this->evaluated_points_by_curve();
const VArray<int8_t> types = this->curve_types();
const VArray<int> resolution = this->resolution();
const VArray<bool> cyclic = this->cyclic();
@ -867,13 +883,13 @@ void CurvesGeometry::interpolate_to_evaluated(const GSpan src, GMutableSpan dst)
threading::parallel_for(this->curves_range(), 512, [&](IndexRange curves_range) {
for (const int curve_index : curves_range) {
const IndexRange points = points_by_curve[curve_index];
const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index);
const IndexRange evaluated_points = evaluated_points_by_curve[curve_index];
evaluate_generic_data_for_curve(curve_index,
points,
types,
cyclic,
resolution,
this->runtime->bezier_evaluated_offsets,
this->runtime->all_bezier_evaluated_offsets,
this->runtime->nurbs_basis_cache,
nurbs_orders,
nurbs_weights,
@ -892,13 +908,14 @@ void CurvesGeometry::ensure_evaluated_lengths() const
this->runtime->evaluated_length_cache.resize(total_num);
MutableSpan<float> evaluated_lengths = this->runtime->evaluated_length_cache;
Span<float3> evaluated_positions = this->evaluated_positions();
VArray<bool> curves_cyclic = this->cyclic();
const OffsetIndices<int> evaluated_points_by_curve = this->evaluated_points_by_curve();
const Span<float3> evaluated_positions = this->evaluated_positions();
const VArray<bool> curves_cyclic = this->cyclic();
threading::parallel_for(this->curves_range(), 128, [&](IndexRange curves_range) {
for (const int curve_index : curves_range) {
const bool cyclic = curves_cyclic[curve_index];
const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index);
const IndexRange evaluated_points = evaluated_points_by_curve[curve_index];
const IndexRange lengths_range = this->lengths_range_for_curve(curve_index, cyclic);
length_parameterize::accumulate_lengths(evaluated_positions.slice(evaluated_points),
cyclic,
@ -910,7 +927,7 @@ void CurvesGeometry::ensure_evaluated_lengths() const
void CurvesGeometry::ensure_can_interpolate_to_evaluated() const
{
this->ensure_evaluated_offsets();
this->evaluated_points_by_curve();
this->ensure_nurbs_basis_cache();
}

View File

@ -10,16 +10,16 @@
namespace blender::bke::curves {
void fill_curve_counts(const bke::CurvesGeometry &curves,
const Span<IndexRange> curve_ranges,
MutableSpan<int> counts)
void copy_curve_sizes(const bke::CurvesGeometry &curves,
const Span<IndexRange> curve_ranges,
MutableSpan<int> sizes)
{
const OffsetIndices points_by_curve = curves.points_by_curve();
threading::parallel_for(curve_ranges.index_range(), 512, [&](IndexRange ranges_range) {
for (const IndexRange curves_range : curve_ranges.slice(ranges_range)) {
threading::parallel_for(curves_range, 4096, [&](IndexRange range) {
for (const int i : range) {
counts[i] = points_by_curve.size(i);
sizes[i] = points_by_curve.size(i);
}
});
}

View File

@ -5285,7 +5285,6 @@ const blender::CPPType *custom_data_type_to_cpp_type(const eCustomDataType type)
default:
return nullptr;
}
return nullptr;
}
eCustomDataType cpp_type_to_custom_data_type(const blender::CPPType &type)

View File

@ -237,9 +237,11 @@ int BKE_object_data_transfer_dttype_to_srcdst_index(const int dtdata_type)
return DT_MULTILAYER_INDEX_UV;
case DT_TYPE_MPROPCOL_VERT:
case DT_TYPE_MLOOPCOL_VERT:
case DT_TYPE_MPROPCOL_VERT | DT_TYPE_MLOOPCOL_VERT:
return DT_MULTILAYER_INDEX_VCOL_VERT;
case DT_TYPE_MPROPCOL_LOOP:
case DT_TYPE_MLOOPCOL_LOOP:
case DT_TYPE_MPROPCOL_LOOP | DT_TYPE_MLOOPCOL_LOOP:
return DT_MULTILAYER_INDEX_VCOL_LOOP;
default:
return DT_MULTILAYER_INDEX_INVALID;

View File

@ -144,6 +144,7 @@ namespace blender::bke {
static Array<float3> curve_normal_point_domain(const bke::CurvesGeometry &curves)
{
const OffsetIndices points_by_curve = curves.points_by_curve();
const OffsetIndices evaluated_points_by_curve = curves.evaluated_points_by_curve();
const VArray<int8_t> types = curves.curve_types();
const VArray<int> resolutions = curves.resolution();
const VArray<bool> curves_cyclic = curves.cyclic();
@ -160,7 +161,7 @@ static Array<float3> curve_normal_point_domain(const bke::CurvesGeometry &curves
for (const int i_curve : range) {
const IndexRange points = points_by_curve[i_curve];
const IndexRange evaluated_points = curves.evaluated_points_for_curve(i_curve);
const IndexRange evaluated_points = evaluated_points_by_curve[i_curve];
MutableSpan<float3> curve_normals = results.as_mutable_span().slice(points);
@ -181,7 +182,7 @@ static Array<float3> curve_normal_point_domain(const bke::CurvesGeometry &curves
curve_normals.first() = normals.first();
const Span<int> offsets = curves.bezier_evaluated_offsets_for_curve(i_curve);
for (const int i : IndexRange(points.size()).drop_front(1)) {
curve_normals[i] = normals[offsets[i - 1]];
curve_normals[i] = normals[offsets[i]];
}
break;
}
@ -242,7 +243,7 @@ static VArray<float> construct_curve_length_gvarray(const CurvesGeometry &curves
{
curves.ensure_evaluated_lengths();
VArray<bool> cyclic = curves.cyclic();
const VArray<bool> cyclic = curves.cyclic();
VArray<float> lengths = VArray<float>::ForFunc(
curves.curves_num(), [&curves, cyclic = std::move(cyclic)](int64_t index) {
return curves.evaluated_length_total_for_curve(index, cyclic[index]);

View File

@ -1566,7 +1566,6 @@ bGPDlayer *BKE_gpencil_layer_active_get(bGPdata *gpd)
bGPDlayer *BKE_gpencil_layer_get_by_name(bGPdata *gpd, char *name, int first_if_not_found)
{
bGPDlayer *gpl;
int i = 0;
/* error checking */
if (ELEM(NULL, gpd, gpd->layers.first)) {
@ -1578,7 +1577,6 @@ bGPDlayer *BKE_gpencil_layer_get_by_name(bGPdata *gpd, char *name, int first_if_
if (STREQ(name, gpl->info)) {
return gpl;
}
i++;
}
/* no such layer */

View File

@ -971,7 +971,7 @@ static float *gpencil_stroke_points_from_editcurve_adaptive_resolu(
MEM_freeN(segment_point_lengths);
*r_points_len = points_len;
return (float(*))r_points;
return (float *)r_points;
}
/**
@ -1012,7 +1012,7 @@ static float *gpencil_stroke_points_from_editcurve_fixed_resolu(bGPDcurve_point
}
*r_points_len = points_len;
return (float(*))r_points;
return (float *)r_points;
}
void BKE_gpencil_stroke_update_geometry_from_editcurve(bGPDstroke *gps,

View File

@ -636,8 +636,6 @@ static bool layer_collection_hidden(ViewLayer *view_layer, LayerCollection *lc)
}
return false;
return false;
}
LayerCollection *BKE_layer_collection_from_index(ViewLayer *view_layer, const int index)
@ -1210,6 +1208,7 @@ static void layer_collection_sync(ViewLayer *view_layer,
layer_resync->layer->layer_collections = new_lb_layer;
BLI_assert(BLI_listbase_count(&layer_resync->collection->children) - skipped_children ==
BLI_listbase_count(&new_lb_layer));
UNUSED_VARS_NDEBUG(skipped_children);
/* Update bases etc. for objects. */
layer_collection_objects_sync(view_layer,

View File

@ -1521,6 +1521,30 @@ void BKE_nlastrip_recalculate_bounds(NlaStrip *strip)
nlastrip_fix_resize_overlaps(strip);
}
void BKE_nlastrip_recalculate_blend(NlaStrip *strip)
{
/* check if values need to be re-calculated. */
if (strip->blendin == 0 && strip->blendout == 0) {
return;
}
const double strip_len = strip->end - strip->start;
double blend_in = strip->blendin;
double blend_out = strip->blendout;
double blend_in_max = strip_len - blend_out;
CLAMP_MIN(blend_in_max, 0);
/* blend-out is limited to the length of the strip. */
CLAMP(blend_in, 0, blend_in_max);
CLAMP(blend_out, 0, strip_len - blend_in);
strip->blendin = blend_in;
strip->blendout = blend_out;
}
/* Animated Strips ------------------------------------------- */
bool BKE_nlatrack_has_animated_strips(NlaTrack *nlt)
@ -1854,6 +1878,7 @@ void BKE_nla_validate_state(AnimData *adt)
for (strip = nlt->strips.first; strip; strip = strip->next) {
/* auto-blending first */
BKE_nlastrip_validate_autoblends(nlt, strip);
BKE_nlastrip_recalculate_blend(strip);
}
}
}

View File

@ -0,0 +1,42 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2023 Blender Foundation. All rights reserved. */
#include "BKE_nla.h"
#include "DNA_anim_types.h"
#include "DNA_nla_types.h"
#include "MEM_guardedalloc.h"
#include "testing/testing.h"
namespace blender::bke::tests {
TEST(nla_strip, BKE_nlastrip_recalculate_blend)
{
NlaStrip strip{};
strip.blendin = 4.0;
strip.blendout = 5.0;
strip.start = 1;
strip.end = 10;
/* Scaling a strip up doesn't affect the blend in/out value */
strip.end = 20;
BKE_nlastrip_recalculate_blend(&strip);
EXPECT_FLOAT_EQ(strip.blendin, 4.0);
EXPECT_FLOAT_EQ(strip.blendout, 5.0);
/* Scaling a strip down affects the blend-in value before the blend-out value */
strip.end = 7;
BKE_nlastrip_recalculate_blend(&strip);
EXPECT_FLOAT_EQ(strip.blendin, 1.0);
EXPECT_FLOAT_EQ(strip.blendout, 5.0);
/* Scaling a strip down to nothing updates the blend in/out values accordingly */
strip.end = 1.1;
BKE_nlastrip_recalculate_blend(&strip);
EXPECT_FLOAT_EQ(strip.blendin, 0.0);
EXPECT_FLOAT_EQ(strip.blendout, 0.1);
}
} // namespace blender::bke::tests

View File

@ -2629,8 +2629,6 @@ bool BKE_sculpt_attribute_exists(Object *ob,
CustomData *cdata = sculpt_get_cdata(ob, domain);
return CustomData_get_named_layer_index(cdata, proptype, name) != -1;
return false;
}
static SculptAttribute *sculpt_alloc_attr(SculptSession *ss)

View File

@ -464,11 +464,11 @@ static void subdiv_vertex_orco_evaluate(const SubdivMeshContext *ctx,
if (ctx->orco) {
copy_v3_v3(ctx->orco[subdiv_vertex_index], vertex_data);
if (ctx->cloth_orco) {
copy_v3_v3(ctx->orco[subdiv_vertex_index], vertex_data + 3);
copy_v3_v3(ctx->cloth_orco[subdiv_vertex_index], vertex_data + 3);
}
}
else if (ctx->cloth_orco) {
copy_v3_v3(ctx->orco[subdiv_vertex_index], vertex_data);
copy_v3_v3(ctx->cloth_orco[subdiv_vertex_index], vertex_data);
}
}
}

View File

@ -39,6 +39,18 @@ template<typename T> class OffsetIndices {
return size;
}
/** Return the total number of elements in the the referenced arrays. */
T total_size() const
{
return offsets_.last();
}
/** Return the number of ranges encoded by the offsets. */
T ranges_num() const
{
return offsets_.size() - 1;
}
IndexRange operator[](const int64_t index) const
{
BLI_assert(index >= 0);
@ -56,6 +68,17 @@ template<typename T> class OffsetIndices {
const int64_t size = end - begin;
return IndexRange(begin, size);
}
/**
* Return a subset of the offsets desribing the specified range of source elements.
* This is a slice into the source ranges rather than the indexed elements described by the
* offset values.
*/
OffsetIndices slice(const IndexRange range) const
{
BLI_assert(offsets_.index_range().drop_back(1).contains(range.last()));
return OffsetIndices(offsets_.slice(range.start(), range.one_after_last()));
}
};
/**

View File

@ -361,7 +361,6 @@ bool BLI_scanfill_calc_self_isect(ScanFillContext *sf_ctx,
{
const uint poly_num = (uint)sf_ctx->poly_nr + 1;
uint eed_index = 0;
int totvert_new = 0;
bool changed = false;
PolyInfo *poly_info;
@ -453,7 +452,6 @@ bool BLI_scanfill_calc_self_isect(ScanFillContext *sf_ctx,
if (eve->user_flag != 1) {
BLI_remlink(&sf_ctx->fillvertbase, eve);
BLI_addtail(remvertbase, eve);
totvert_new--;
}
else {
eve->user_flag = 0;

View File

@ -196,11 +196,9 @@ TEST(task, MempoolIterTLS)
int i;
/* Add numbers negative `1..ITEMS_NUM` inclusive. */
int items_num = 0;
for (i = 0; i < ITEMS_NUM; i++) {
data[i] = (int *)BLI_mempool_alloc(mempool);
*data[i] = -(i + 1);
items_num++;
}
TaskParallelSettings settings;

View File

@ -179,12 +179,6 @@ if(WITH_BULLET)
${BULLET_INCLUDE_DIRS}
../../../intern/rigidbody
)
if(NOT WITH_SYSTEM_BULLET)
list(APPEND LIB
extern_bullet
)
endif()
list(APPEND LIB
${BULLET_LIBRARIES}
)

View File

@ -149,14 +149,12 @@ void BM_face_interp_from_face_ex(BMesh *bm,
float *w = BLI_array_alloca(w, f_src->len);
float co[2];
int i;
if (f_src != f_dst) {
BM_elem_attrs_copy(bm, bm, f_src, f_dst);
}
/* interpolate */
i = 0;
l_iter = l_first = BM_FACE_FIRST_LOOP(f_dst);
do {
mul_v2_m3v3(co, axis_mat, l_iter->v->co);
@ -165,7 +163,7 @@ void BM_face_interp_from_face_ex(BMesh *bm,
if (do_vertex) {
CustomData_bmesh_interp(&bm->vdata, blocks_v, w, NULL, f_src->len, l_iter->v->head.data);
}
} while ((void)i++, (l_iter = l_iter->next) != l_first);
} while ((l_iter = l_iter->next) != l_first);
}
void BM_face_interp_from_face(BMesh *bm, BMFace *f_dst, const BMFace *f_src, const bool do_vertex)

View File

@ -1342,10 +1342,9 @@ bool BM_mesh_intersect(BMesh *bm,
GHASH_ITER (gh_iter, s.face_edges) {
struct LinkBase *e_ls_base = BLI_ghashIterator_getValue(&gh_iter);
LinkNode **node_prev_p;
uint i;
node_prev_p = &e_ls_base->list;
for (i = 0, node = e_ls_base->list; node; i++, node = node->next) {
for (node = e_ls_base->list; node; node = node->next) {
BMEdge *e = node->link;
if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
/* allocated by arena, don't free */

View File

@ -16,6 +16,8 @@ set(INC
../../../../intern/guardedalloc
)
set(INC_SYS
)
set(SRC
intern/compile_state.cc

View File

@ -35,7 +35,6 @@ set(INC
# dna_type_offsets.h
${CMAKE_CURRENT_BINARY_DIR}/../makesdna/intern
${OPENSUBDIV_INCLUDE_DIRS}
)
set(SRC
@ -724,6 +723,12 @@ if(WITH_DRAW_DEBUG)
add_definitions(-DWITH_DRAW_DEBUG)
endif()
if(WITH_OPENSUBDIV)
list(APPEND INC_SYS
${OPENSUBDIV_INCLUDE_DIRS}
)
endif()
if(WITH_MOD_FLUID)
list(APPEND INC
../../../intern/mantaflow/extern

View File

@ -29,6 +29,8 @@
#include "GPU_texture.h"
#include "compositor_engine.h" /* Own include. */
namespace blender::draw::compositor {
class TexturePool : public realtime_compositor::TexturePool {

View File

@ -67,7 +67,6 @@ static const char *workbench_lighting_mode_to_str(int light)
return "_matcap";
case V3D_LIGHTING_FLAT:
return "_flat";
return "";
}
}

View File

@ -42,6 +42,7 @@ using blender::Array;
using blender::ColorGeometry4f;
using blender::float3;
using blender::IndexRange;
using blender::OffsetIndices;
using blender::Span;
/* See: edit_curve_point_vert.glsl for duplicate includes. */
@ -103,14 +104,14 @@ static void curve_eval_render_wire_verts_edges_len_get(const blender::bke::Curve
int *r_vert_len,
int *r_edge_len)
{
*r_curve_len = curves.curves_num();
*r_vert_len = curves.evaluated_points_num();
*r_edge_len = 0;
const OffsetIndices points_by_curve = curves.evaluated_points_by_curve();
const blender::VArray<bool> cyclic = curves.cyclic();
*r_curve_len = curves.curves_num();
*r_vert_len = points_by_curve.total_size();
*r_edge_len = 0;
for (const int i : curves.curves_range()) {
const IndexRange points = curves.evaluated_points_for_curve(i);
*r_edge_len += blender::bke::curves::segments_num(points.size(), cyclic[i]);
*r_edge_len += blender::bke::curves::segments_num(points_by_curve.size(i), cyclic[i]);
}
}
@ -480,6 +481,7 @@ static void curve_create_curves_pos(CurveRenderData *rdata, GPUVertBuf *vbo_curv
static void curve_create_attribute(CurveRenderData *rdata, GPUVertBuf *vbo_attr)
{
using namespace blender;
if (rdata->curve_eval == nullptr) {
return;
}
@ -493,18 +495,17 @@ static void curve_create_attribute(CurveRenderData *rdata, GPUVertBuf *vbo_attr)
GPU_vertbuf_init_with_format(vbo_attr, &format);
GPU_vertbuf_data_alloc(vbo_attr, vert_len);
const blender::bke::CurvesGeometry &curves = blender::bke::CurvesGeometry::wrap(
rdata->curve_eval->geometry);
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(rdata->curve_eval->geometry);
curves.ensure_can_interpolate_to_evaluated();
const blender::VArraySpan<ColorGeometry4f> colors = curves.attributes().lookup<ColorGeometry4f>(
const VArraySpan<ColorGeometry4f> colors = curves.attributes().lookup<ColorGeometry4f>(
".viewer", ATTR_DOMAIN_POINT);
ColorGeometry4f *vbo_data = static_cast<ColorGeometry4f *>(GPU_vertbuf_get_data(vbo_attr));
curves.interpolate_to_evaluated(colors,
blender::MutableSpan<ColorGeometry4f>{vbo_data, vert_len});
curves.interpolate_to_evaluated(colors, MutableSpan<ColorGeometry4f>{vbo_data, vert_len});
}
static void curve_create_curves_lines(CurveRenderData *rdata, GPUIndexBuf *ibo_curve_lines)
{
using namespace blender;
if (rdata->curve_eval == nullptr) {
return;
}
@ -518,11 +519,12 @@ static void curve_create_curves_lines(CurveRenderData *rdata, GPUIndexBuf *ibo_c
GPUIndexBufBuilder elb;
GPU_indexbuf_init_ex(&elb, GPU_PRIM_LINE_STRIP, index_len, vert_len);
const blender::bke::CurvesGeometry &curves = blender::bke::CurvesGeometry::wrap(
rdata->curve_eval->geometry);
const blender::VArray<bool> cyclic = curves.cyclic();
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(rdata->curve_eval->geometry);
const OffsetIndices points_by_curve = curves.evaluated_points_by_curve();
const VArray<bool> cyclic = curves.cyclic();
for (const int i : curves.curves_range()) {
const IndexRange points = curves.evaluated_points_for_curve(i);
const IndexRange points = points_by_curve[i];
if (cyclic[i] && points.size() > 1) {
GPU_indexbuf_add_generic_vert(&elb, points.last());
}

View File

@ -17,6 +17,8 @@ set(INC
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
set(INC_SYS
)
set(SRC
anim_channels_defines.c

View File

@ -343,8 +343,12 @@ static void fcurve_scene_coord_range_get(Scene *scene,
int end = fcu->totvert;
if (use_preview_only) {
start = scene->r.psfra;
end = min_ii(scene->r.pefra + 1, fcu->totvert);
/* Preview frame ranges need to be converted to bezt array indices. */
bool replace = false;
start = BKE_fcurve_bezt_binarysearch_index(
fcu->bezt, scene->r.psfra, fcu->totvert, &replace);
end = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, scene->r.pefra, fcu->totvert, &replace);
}
if (fcu->bezt) {

View File

@ -887,8 +887,7 @@ void ANIM_fmodifier_panels(const bContext *C,
if (!panels_match) {
UI_panels_free_instanced(C, region);
FModifier *fcm = fmodifiers->first;
for (int i = 0; fcm; i++, fcm = fcm->next) {
for (FModifier *fcm = fmodifiers->first; fcm; fcm = fcm->next) {
char panel_idname[MAX_NAME];
panel_id_fn(fcm, panel_idname);

View File

@ -19,6 +19,9 @@ set(INC
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
set(INC_SYS
)
set(SRC
armature_add.c
armature_edit.c

View File

@ -17,6 +17,9 @@ set(INC
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
set(INC_SYS
)
set(SRC
curve_ops.c
editcurve.c

View File

@ -18,6 +18,9 @@ set(INC
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
set(INC_SYS
)
set(SRC
gizmo_draw_utils.c
gizmo_geometry.h

View File

@ -18,6 +18,9 @@ set(INC
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
set(INC_SYS
)
set(SRC
annotate_draw.c
annotate_paint.c

View File

@ -26,6 +26,9 @@ set(INC
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
set(INC_SYS
)
set(SRC
eyedroppers/eyedropper_color.cc
eyedroppers/eyedropper_colorband.cc

View File

@ -4197,11 +4197,9 @@ static void ui_litem_layout_column_flow(uiLayout *litem)
/* compute max needed width and total height */
int toth = 0;
int totitem = 0;
LISTBASE_FOREACH (uiItem *, item, &litem->items) {
ui_item_size(item, &itemw, &itemh);
toth += itemh;
totitem++;
}
/* compute sizes */

View File

@ -2291,8 +2291,7 @@ void uiTemplateModifiers(uiLayout * /*layout*/, bContext *C)
if (!panels_match) {
UI_panels_free_instanced(C, region);
ModifierData *md = static_cast<ModifierData *>(modifiers->first);
for (int i = 0; md; i++, md = md->next) {
for (ModifierData *md = static_cast<ModifierData *>(modifiers->first); md; md = md->next) {
const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type));
if (mti->panelRegister == nullptr) {
continue;
@ -2451,9 +2450,10 @@ void uiTemplateConstraints(uiLayout * /*layout*/, bContext *C, bool use_bone_con
if (!panels_match) {
UI_panels_free_instanced(C, region);
bConstraint *con = (constraints == nullptr) ? nullptr :
static_cast<bConstraint *>(constraints->first);
for (int i = 0; con; i++, con = con->next) {
for (bConstraint *con =
(constraints == nullptr) ? nullptr : static_cast<bConstraint *>(constraints->first);
con;
con = con->next) {
/* Don't show invalid/legacy constraints. */
if (con->type == CONSTRAINT_TYPE_NULL) {
continue;
@ -2543,8 +2543,8 @@ void uiTemplateGpencilModifiers(uiLayout * /*layout*/, bContext *C)
if (!panels_match) {
UI_panels_free_instanced(C, region);
GpencilModifierData *md = static_cast<GpencilModifierData *>(modifiers->first);
for (int i = 0; md; i++, md = md->next) {
for (GpencilModifierData *md = static_cast<GpencilModifierData *>(modifiers->first); md;
md = md->next) {
const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(
GpencilModifierType(md->type));
if (mti->panelRegister == nullptr) {
@ -2617,8 +2617,7 @@ void uiTemplateShaderFx(uiLayout * /*layout*/, bContext *C)
if (!panels_match) {
UI_panels_free_instanced(C, region);
ShaderFxData *fx = static_cast<ShaderFxData *>(shaderfx->first);
for (int i = 0; fx; i++, fx = fx->next) {
for (ShaderFxData *fx = static_cast<ShaderFxData *>(shaderfx->first); fx; fx = fx->next) {
char panel_idname[MAX_NAME];
shaderfx_panel_id(fx, panel_idname);

View File

@ -13,6 +13,9 @@ set(INC
../../../../intern/guardedalloc
)
set(INC_SYS
)
set(SRC
mask_add.c
mask_draw.c

View File

@ -291,6 +291,7 @@ static EdgeLoopPair *edbm_ripsel_looptag_helper(BMesh *bm)
BM_edge_loop_pair(e_last, &lp->l_a, &lp->l_b);
BLI_assert(tot == uid_end - uid_start);
UNUSED_VARS_NDEBUG(tot);
#if 0
printf("%s: found contiguous edge loop of (%d)\n", __func__, uid_end - uid_start);

View File

@ -29,6 +29,9 @@ set(INC
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
set(INC_SYS
)
set(SRC
object_add.cc
object_bake.c

View File

@ -60,6 +60,11 @@ static const EnumPropertyItem DT_layer_items[] = {
{DT_TYPE_SKIN, "SKIN", 0, "Skin Weight", "Transfer skin weights"},
#endif
{DT_TYPE_BWEIGHT_VERT, "BEVEL_WEIGHT_VERT", 0, "Bevel Weight", "Transfer bevel weights"},
{DT_TYPE_MPROPCOL_VERT | DT_TYPE_MLOOPCOL_VERT,
"COLOR_VERTEX",
0,
"Colors",
"Color Attributes"},
RNA_ENUM_ITEM_HEADING(N_("Edge Data"), NULL),
{DT_TYPE_SHARP_EDGE, "SHARP_EDGE", 0, "Sharp", "Transfer sharp mark"},
@ -74,7 +79,11 @@ static const EnumPropertyItem DT_layer_items[] = {
RNA_ENUM_ITEM_HEADING(N_("Face Corner Data"), NULL),
{DT_TYPE_LNOR, "CUSTOM_NORMAL", 0, "Custom Normals", "Transfer custom normals"},
{DT_TYPE_MPROPCOL_LOOP | DT_TYPE_MLOOPCOL_LOOP, "VCOL", 0, "Colors", "Color Attributes"},
{DT_TYPE_MPROPCOL_LOOP | DT_TYPE_MLOOPCOL_LOOP,
"COLOR_CORNER",
0,
"Colors",
"Color Attributes"},
{DT_TYPE_UV, "UV", 0, "UVs", "Transfer UV layers"},
RNA_ENUM_ITEM_HEADING(N_("Face Data"), NULL),
@ -93,7 +102,7 @@ static void dt_add_vcol_layers(CustomData *cdata,
int *r_totitem)
{
int types[2] = {CD_PROP_COLOR, CD_PROP_BYTE_COLOR};
int idx = 0;
for (int i = 0; i < 2; i++) {
eCustomDataType type = types[i];
@ -106,9 +115,8 @@ static void dt_add_vcol_layers(CustomData *cdata,
RNA_enum_item_add_separator(r_item, r_totitem);
for (int j = 0; j < num_data; j++) {
EnumPropertyItem tmp_item;
tmp_item.value = j;
EnumPropertyItem tmp_item = {0};
tmp_item.value = idx++;
tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(cdata, type, j);
RNA_enum_item_add(r_item, r_totitem, &tmp_item);
}

View File

@ -17,6 +17,9 @@ set(INC
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
set(INC_SYS
)
set(SRC
dynamicpaint_ops.c
particle_boids.c

View File

@ -20,6 +20,9 @@ set(INC
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
set(INC_SYS
)
set(SRC
area.c
area_query.c

View File

@ -983,13 +983,6 @@ static void region_azone_tab_plus(ScrArea *area, AZone *az, ARegion *region)
const float tab_size_x = 0.7f * U.widget_unit;
const float tab_size_y = 0.4f * U.widget_unit;
int tot = 0;
LISTBASE_FOREACH (AZone *, azt, &area->actionzones) {
if (azt->edge == az->edge) {
tot++;
}
}
switch (az->edge) {
case AE_TOP_TO_BOTTOMRIGHT: {
int add = (region->winrct.ymax == area->totrct.ymin) ? 1 : 0;

View File

@ -30,15 +30,18 @@ set(LIB
)
if(WITH_AUDASPACE)
list(APPEND LIB
bf_intern_audaspace
)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
)
list(APPEND LIB
bf_intern_audaspace
${AUDASPACE_C_LIBRARIES}
${AUDASPACE_PY_LIBRARIES}
)
if(WITH_SYSTEM_AUDASPACE)
list(APPEND LIB
${AUDASPACE_C_LIBRARIES}
${AUDASPACE_PY_LIBRARIES}
)
endif()
add_definitions(-DWITH_AUDASPACE)
endif()

View File

@ -19,6 +19,9 @@ set(INC
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
set(INC_SYS
)
set(SRC
action_buttons.c
action_data.c

View File

@ -19,6 +19,9 @@ set(INC
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
set(INC_SYS
)
set(SRC
buttons_context.c
buttons_ops.c

View File

@ -22,6 +22,9 @@ set(INC
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
set(INC_SYS
)
set(SRC
clip_buttons.c
clip_dopesheet_draw.c

View File

@ -16,6 +16,9 @@ set(INC
${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern
)
set(INC_SYS
)
set(SRC
console_draw.c
console_ops.c

View File

@ -24,6 +24,9 @@ set(INC
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
set(INC_SYS
)
set(SRC
asset_catalog_tree_view.cc
file_draw.c

View File

@ -19,6 +19,9 @@ set(INC
${CMAKE_BINARY_DIR}/source/blender/makesrna
)
set(INC_SYS
)
set(SRC
graph_buttons.c
graph_draw.c
@ -39,15 +42,18 @@ set(LIB
)
if(WITH_AUDASPACE)
list(APPEND LIB
bf_intern_audaspace
)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
)
list(APPEND LIB
bf_intern_audaspace
${AUDASPACE_C_LIBRARIES}
${AUDASPACE_PY_LIBRARIES}
)
if(WITH_SYSTEM_AUDASPACE)
list(APPEND LIB
${AUDASPACE_C_LIBRARIES}
${AUDASPACE_PY_LIBRARIES}
)
endif()
add_definitions(-DWITH_AUDASPACE)
endif()

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