Merge branch 'master' into refactor-mesh-corners-generic
This commit is contained in:
commit
932a211f6c
|
@ -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()
|
||||
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}"
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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}
|
||||
)
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -29,6 +29,7 @@ enum AppleGPUArchitecture {
|
|||
APPLE_UNKNOWN,
|
||||
APPLE_M1,
|
||||
APPLE_M2,
|
||||
APPLE_M2_BIG,
|
||||
};
|
||||
|
||||
/* Contains static Metal helper functions. */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,9 @@ set(INC
|
|||
..
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
node.cpp
|
||||
node_type.cpp
|
||||
|
|
|
@ -5,6 +5,9 @@ set(INC
|
|||
..
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
adaptive_sampling.cpp
|
||||
denoiser.cpp
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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_;
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -5,6 +5,9 @@ set(INC
|
|||
..
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
buffers.cpp
|
||||
denoising.cpp
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
|
@ -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.
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)};
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 ********************* */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
|
@ -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
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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]]);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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}
|
||||
)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -16,6 +16,8 @@ set(INC
|
|||
../../../../intern/guardedalloc
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
intern/compile_state.cc
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
#include "GPU_texture.h"
|
||||
|
||||
#include "compositor_engine.h" /* Own include. */
|
||||
|
||||
namespace blender::draw::compositor {
|
||||
|
||||
class TexturePool : public realtime_compositor::TexturePool {
|
||||
|
|
|
@ -67,7 +67,6 @@ static const char *workbench_lighting_mode_to_str(int light)
|
|||
return "_matcap";
|
||||
case V3D_LIGHTING_FLAT:
|
||||
return "_flat";
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ set(INC
|
|||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
anim_channels_defines.c
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -19,6 +19,9 @@ set(INC
|
|||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
armature_add.c
|
||||
armature_edit.c
|
||||
|
|
|
@ -17,6 +17,9 @@ set(INC
|
|||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
curve_ops.c
|
||||
editcurve.c
|
||||
|
|
|
@ -18,6 +18,9 @@ set(INC
|
|||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
gizmo_draw_utils.c
|
||||
gizmo_geometry.h
|
||||
|
|
|
@ -18,6 +18,9 @@ set(INC
|
|||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
annotate_draw.c
|
||||
annotate_paint.c
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -13,6 +13,9 @@ set(INC
|
|||
../../../../intern/guardedalloc
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
mask_add.c
|
||||
mask_draw.c
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -29,6 +29,9 @@ set(INC
|
|||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
object_add.cc
|
||||
object_bake.c
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,9 @@ set(INC
|
|||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
dynamicpaint_ops.c
|
||||
particle_boids.c
|
||||
|
|
|
@ -20,6 +20,9 @@ set(INC
|
|||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
area.c
|
||||
area_query.c
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -19,6 +19,9 @@ set(INC
|
|||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
action_buttons.c
|
||||
action_data.c
|
||||
|
|
|
@ -19,6 +19,9 @@ set(INC
|
|||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
buttons_context.c
|
||||
buttons_ops.c
|
||||
|
|
|
@ -22,6 +22,9 @@ set(INC
|
|||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
clip_buttons.c
|
||||
clip_dopesheet_draw.c
|
||||
|
|
|
@ -16,6 +16,9 @@ set(INC
|
|||
${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
console_draw.c
|
||||
console_ops.c
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue