WIP: Rewrite Graph Editor drawing code #118662
|
@ -117,7 +117,7 @@ endif()
|
|||
# Embree needs to be included after dpcpp as it uses it for compiling with GPU support
|
||||
if(BLENDER_PLATFORM_WINDOWS_ARM)
|
||||
# WoA needs embree to be built with the VS Generator + LLVM,
|
||||
# put it in it's own file to avoid clutter.
|
||||
# put it in its own file to avoid clutter.
|
||||
include(cmake/embree_windows_arm.cmake)
|
||||
else()
|
||||
include(cmake/embree.cmake)
|
||||
|
|
|
@ -58,7 +58,7 @@ if(WIN32)
|
|||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${LIBDIR}/opensubdiv/lib/osdCPU.lib
|
||||
${HARVEST_TARGET}/opensubdiv/lib/osdCPU_d.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${LIBDIR}/opensubdiv/lib/osdGPU.lib
|
||||
${HARVEST_TARGET}/opensubdiv/lib/osdGPU_d.lib
|
||||
|
||||
|
|
|
@ -111,3 +111,5 @@ mark_as_advanced(
|
|||
AUDASPACE_PY_INCLUDE_DIR
|
||||
AUDASPACE_PY_INCLUDE_DIRS
|
||||
)
|
||||
|
||||
unset(_audaspace_SEARCH_DIRS)
|
||||
|
|
|
@ -64,3 +64,5 @@ mark_as_advanced(
|
|||
BLOSC_INCLUDE_DIR
|
||||
BLOSC_LIBRARY
|
||||
)
|
||||
|
||||
unset(_blosc_SEARCH_DIRS)
|
||||
|
|
|
@ -21,7 +21,7 @@ else()
|
|||
set(BROTLI_ROOT_DIR "")
|
||||
endif()
|
||||
|
||||
set(_BROTLI_SEARCH_DIRS
|
||||
set(_brotli_SEARCH_DIRS
|
||||
${BROTLI_ROOT_DIR}
|
||||
)
|
||||
|
||||
|
@ -29,7 +29,7 @@ find_path(BROTLI_INCLUDE_DIR
|
|||
NAMES
|
||||
brotli/decode.h
|
||||
HINTS
|
||||
${_BROTLI_SEARCH_DIRS}
|
||||
${_brotli_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
include
|
||||
DOC "Brotli header files"
|
||||
|
@ -41,7 +41,7 @@ find_library(BROTLI_LIBRARY_COMMON
|
|||
brotlicommon-static
|
||||
brotlicommon
|
||||
HINTS
|
||||
${_BROTLI_SEARCH_DIRS}
|
||||
${_brotli_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
lib64 lib lib/static
|
||||
DOC "Brotli static common library"
|
||||
|
@ -52,7 +52,7 @@ find_library(BROTLI_LIBRARY_DEC
|
|||
brotlidec-static
|
||||
brotlidec
|
||||
HINTS
|
||||
${_BROTLI_SEARCH_DIRS}
|
||||
${_brotli_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
lib64 lib lib/static
|
||||
DOC "Brotli static decode library"
|
||||
|
@ -81,4 +81,4 @@ mark_as_advanced(
|
|||
BROTLI_LIBRARY_DIR
|
||||
)
|
||||
|
||||
unset(_BROTLI_SEARCH_DIRS)
|
||||
unset(_brotli_SEARCH_DIRS)
|
||||
|
|
|
@ -36,7 +36,7 @@ if(NOT LLVM_ROOT_DIR)
|
|||
set(LLVM_ROOT_DIR ${LLVM_ROOT_DIR} CACHE PATH "Path to the LLVM installation")
|
||||
endif()
|
||||
|
||||
set(_CLANG_SEARCH_DIRS
|
||||
set(_clang_SEARCH_DIRS
|
||||
${CLANG_ROOT_DIR}
|
||||
${LLVM_ROOT_DIR}
|
||||
/opt/lib/clang
|
||||
|
@ -46,14 +46,14 @@ find_path(CLANG_INCLUDE_DIR
|
|||
NAMES
|
||||
AST/AST.h
|
||||
HINTS
|
||||
${_CLANG_SEARCH_DIRS}
|
||||
${_clang_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
include
|
||||
include/clang
|
||||
)
|
||||
|
||||
|
||||
set(_CLANG_FIND_COMPONENTS
|
||||
set(_clang_FIND_COMPONENTS
|
||||
clangDependencyScanning
|
||||
clangDynamicASTMatchers
|
||||
clangFrontendTool
|
||||
|
@ -87,20 +87,20 @@ set(_CLANG_FIND_COMPONENTS
|
|||
clangBasic
|
||||
)
|
||||
|
||||
set(_CLANG_LIBRARIES)
|
||||
foreach(COMPONENT ${_CLANG_FIND_COMPONENTS})
|
||||
set(_clang_LIBRARIES)
|
||||
foreach(COMPONENT ${_clang_FIND_COMPONENTS})
|
||||
string(TOUPPER ${COMPONENT} UPPERCOMPONENT)
|
||||
|
||||
find_library(CLANG_${UPPERCOMPONENT}_LIBRARY
|
||||
NAMES
|
||||
${COMPONENT}
|
||||
HINTS
|
||||
${_CLANG_SEARCH_DIRS}
|
||||
${_clang_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
lib64 lib
|
||||
)
|
||||
if(CLANG_${UPPERCOMPONENT}_LIBRARY)
|
||||
list(APPEND _CLANG_LIBRARIES "${CLANG_${UPPERCOMPONENT}_LIBRARY}")
|
||||
list(APPEND _clang_LIBRARIES "${CLANG_${UPPERCOMPONENT}_LIBRARY}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
|
@ -109,10 +109,10 @@ endforeach()
|
|||
# all listed variables are TRUE.
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Clang DEFAULT_MSG
|
||||
_CLANG_LIBRARIES CLANG_INCLUDE_DIR)
|
||||
_clang_LIBRARIES CLANG_INCLUDE_DIR)
|
||||
|
||||
if(CLANG_FOUND)
|
||||
set(CLANG_LIBRARIES ${_CLANG_LIBRARIES})
|
||||
set(CLANG_LIBRARIES ${_clang_LIBRARIES})
|
||||
set(CLANG_INCLUDE_DIRS ${CLANG_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
|
@ -120,11 +120,11 @@ mark_as_advanced(
|
|||
CLANG_INCLUDE_DIR
|
||||
)
|
||||
|
||||
foreach(COMPONENT ${_CLANG_FIND_COMPONENTS})
|
||||
foreach(COMPONENT ${_clang_FIND_COMPONENTS})
|
||||
string(TOUPPER ${COMPONENT} UPPERCOMPONENT)
|
||||
mark_as_advanced(CLANG_${UPPERCOMPONENT}_LIBRARY)
|
||||
endforeach()
|
||||
|
||||
unset(_CLANG_SEARCH_DIRS)
|
||||
unset(_CLANG_FIND_COMPONENTS)
|
||||
unset(_CLANG_LIBRARIES)
|
||||
unset(_clang_SEARCH_DIRS)
|
||||
unset(_clang_FIND_COMPONENTS)
|
||||
unset(_clang_LIBRARIES)
|
||||
|
|
|
@ -104,3 +104,5 @@ ${CLANG_TIDY_VERSION_PATCH}")
|
|||
else()
|
||||
set(CLANG_TIDY_FOUND FALSE)
|
||||
endif()
|
||||
|
||||
unset(_clang_tidy_SEARCH_DIRS)
|
||||
|
|
|
@ -47,3 +47,5 @@ endif()
|
|||
mark_as_advanced(
|
||||
EIGEN3_INCLUDE_DIR
|
||||
)
|
||||
|
||||
unset(_eigen3_SEARCH_DIRS)
|
||||
|
|
|
@ -66,6 +66,8 @@ foreach(_component ${FFMPEG_FIND_COMPONENTS})
|
|||
list(APPEND _ffmpeg_LIBRARIES ${FFMPEG_${_upper_COMPONENT}_LIBRARY})
|
||||
mark_as_advanced(FFMPEG_${_upper_COMPONENT}_LIBRARY)
|
||||
endforeach()
|
||||
unset(_component)
|
||||
unset(_upper_COMPONENT)
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set FFMPEG_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
|
|
|
@ -72,10 +72,12 @@ if(FFTW3_FOUND)
|
|||
set(FFTW3_INCLUDE_DIRS ${FFTW3_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
unset(_FFTW3_LIBRARIES)
|
||||
|
||||
mark_as_advanced(
|
||||
FFTW3_INCLUDE_DIR
|
||||
FFTW3_LIBRARY_F
|
||||
FFTW3_LIBRARY_D
|
||||
)
|
||||
|
||||
unset(_FFTW3_LIBRARIES)
|
||||
unset(_fftw3_SEARCH_DIRS)
|
||||
|
|
|
@ -55,3 +55,5 @@ MARK_AS_ADVANCED(
|
|||
LIBFRIBIDI_INCLUDE_DIR
|
||||
LIBFRIBIDI_LIBRARY
|
||||
)
|
||||
|
||||
unset(_fribidi_SEARCH_DIRS)
|
||||
|
|
|
@ -91,3 +91,5 @@ mark_as_advanced(
|
|||
GMPXX_INCLUDE_DIR
|
||||
GMPXX_LIBRARY
|
||||
)
|
||||
|
||||
unset(_gmp_SEARCH_DIRS)
|
||||
|
|
|
@ -101,3 +101,5 @@ include(FindPackageHandleStandardArgs)
|
|||
find_package_handle_standard_args(HIP
|
||||
REQUIRED_VARS HIP_HIPCC_EXECUTABLE
|
||||
VERSION_VAR HIP_VERSION)
|
||||
|
||||
unset(_hip_SEARCH_DIRS)
|
||||
|
|
|
@ -57,3 +57,5 @@ find_package_handle_standard_args(HIPRT DEFAULT_MSG
|
|||
mark_as_advanced(
|
||||
HIPRT_INCLUDE_DIR
|
||||
)
|
||||
|
||||
unset(_hiprt_SEARCH_DIRS)
|
||||
|
|
|
@ -55,3 +55,5 @@ MARK_AS_ADVANCED(
|
|||
LIBHARFBUZZ_INCLUDE_DIR
|
||||
LIBHARFBUZZ_LIBRARY
|
||||
)
|
||||
|
||||
unset(_harfbuzz_SEARCH_DIRS)
|
||||
|
|
|
@ -137,3 +137,5 @@ mark_as_advanced(
|
|||
ICU_LIBRARY_TU
|
||||
ICU_LIBRARY_UC
|
||||
)
|
||||
|
||||
unset(_icu_SEARCH_DIRS)
|
||||
|
|
|
@ -61,3 +61,5 @@ mark_as_advanced(
|
|||
JACK_INCLUDE_DIR
|
||||
JACK_LIBRARY
|
||||
)
|
||||
|
||||
unset(_jack_SEARCH_DIRS)
|
||||
|
|
|
@ -71,3 +71,5 @@ mark_as_advanced(
|
|||
JEMALLOC_INCLUDE_DIR
|
||||
JEMALLOC_LIBRARY
|
||||
)
|
||||
|
||||
unset(_jemalloc_SEARCH_DIRS)
|
||||
|
|
|
@ -59,3 +59,5 @@ mark_as_advanced(
|
|||
LZO_INCLUDE_DIR
|
||||
LZO_LIBRARY
|
||||
)
|
||||
|
||||
unset(_lzo_SEARCH_DIRS)
|
||||
|
|
|
@ -20,7 +20,7 @@ else()
|
|||
set(LEVEL_ZERO_ROOT_DIR "")
|
||||
endif()
|
||||
|
||||
set(_level_zero_search_dirs
|
||||
set(_level_zero_SEARCH_DIRS
|
||||
${LEVEL_ZERO_ROOT_DIR}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
|
@ -30,7 +30,7 @@ find_library(LEVEL_ZERO_LIBRARY
|
|||
NAMES
|
||||
ze_loader
|
||||
HINTS
|
||||
${_level_zero_search_dirs}
|
||||
${_level_zero_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
lib64 lib
|
||||
)
|
||||
|
@ -39,7 +39,7 @@ find_path(LEVEL_ZERO_INCLUDE_DIR
|
|||
NAMES
|
||||
level_zero/ze_api.h
|
||||
HINTS
|
||||
${_level_zero_search_dirs}
|
||||
${_level_zero_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
include
|
||||
)
|
||||
|
@ -60,3 +60,5 @@ mark_as_advanced(
|
|||
LEVEL_ZERO_LIBRARY
|
||||
LEVEL_ZERO_INCLUDE_DIR
|
||||
)
|
||||
|
||||
unset(_level_zero_SEARCH_DIRS)
|
||||
|
|
|
@ -125,7 +125,15 @@ mark_as_advanced(
|
|||
OSL_INCLUDE_DIR
|
||||
OSL_SHADER_DIR
|
||||
)
|
||||
|
||||
foreach(COMPONENT ${_osl_FIND_COMPONENTS})
|
||||
string(TOUPPER ${COMPONENT} UPPERCOMPONENT)
|
||||
mark_as_advanced(OSL_${UPPERCOMPONENT}_LIBRARY)
|
||||
endforeach()
|
||||
|
||||
unset(COMPONENT)
|
||||
unset(UPPERCOMPONENT)
|
||||
|
||||
unset(_osl_FIND_COMPONENTS)
|
||||
unset(_osl_LIBRARIES)
|
||||
unset(_osl_SEARCH_DIRS)
|
||||
|
|
|
@ -134,5 +134,9 @@ endif()
|
|||
|
||||
unset(COMPONENT)
|
||||
unset(UPPERCOMPONENT)
|
||||
unset(_opencollada_LIBRARIES)
|
||||
unset(_opencollada_FIND_COMPONENTS)
|
||||
unset(_opencollada_FIND_INCLUDES)
|
||||
unset(_opencollada_FIND_STATIC_COMPONENTS)
|
||||
unset(_opencollada_INCLUDES)
|
||||
unset(_opencollada_LIBRARIES)
|
||||
unset(_opencollada_SEARCH_DIRS)
|
||||
|
|
|
@ -72,6 +72,7 @@ if(EXISTS "${OPENCOLORIO_INCLUDE_DIR}/OpenColorIO/OpenColorABI.h")
|
|||
REGEX "^#define OCIO_VERSION[ \t].*$")
|
||||
endif()
|
||||
string(REGEX MATCHALL "[0-9]+[.0-9]+" OPENCOLORIO_VERSION ${_opencolorio_version})
|
||||
unset(_opencolorio_version)
|
||||
endif()
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set OPENCOLORIO_FOUND to TRUE if
|
||||
|
|
|
@ -119,6 +119,10 @@ foreach(COMPONENT ${_openimagedenoise_FIND_COMPONENTS})
|
|||
mark_as_advanced(OPENIMAGEDENOISE_${UPPERCOMPONENT}_LIBRARY)
|
||||
endforeach()
|
||||
|
||||
unset(_openimagedenoise_SEARCH_DIRS)
|
||||
unset(COMPONENT)
|
||||
unset(UPPERCOMPONENT)
|
||||
|
||||
unset(_openimagedenoise_FIND_COMPONENTS)
|
||||
unset(_openimagedenoise_FIND_STATIC_COMPONENTS)
|
||||
unset(_openimagedenoise_LIBRARIES)
|
||||
unset(_openimagedenoise_SEARCH_DIRS)
|
||||
|
|
|
@ -85,3 +85,10 @@ foreach(COMPONENT ${_opensubdiv_FIND_COMPONENTS})
|
|||
string(TOUPPER ${COMPONENT} UPPERCOMPONENT)
|
||||
mark_as_advanced(OPENSUBDIV_${UPPERCOMPONENT}_LIBRARY)
|
||||
endforeach()
|
||||
|
||||
unset(COMPONENT)
|
||||
unset(UPPERCOMPONENT)
|
||||
|
||||
unset(_opensubdiv_FIND_COMPONENTS)
|
||||
unset(_opensubdiv_SEARCH_DIRS)
|
||||
unset(_opensubdiv_LIBRARIES)
|
||||
|
|
|
@ -64,3 +64,5 @@ mark_as_advanced(
|
|||
PCRE_INCLUDE_DIR
|
||||
PCRE_LIBRARY
|
||||
)
|
||||
|
||||
unset(_pcre_SEARCH_DIRS)
|
||||
|
|
|
@ -64,3 +64,5 @@ mark_as_advanced(
|
|||
POTRACE_INCLUDE_DIR
|
||||
POTRACE_LIBRARY
|
||||
)
|
||||
|
||||
unset(_potrace_SEARCH_DIRS)
|
||||
|
|
|
@ -64,3 +64,5 @@ mark_as_advanced(
|
|||
PUGIXML_INCLUDE_DIR
|
||||
PUGIXML_LIBRARY
|
||||
)
|
||||
|
||||
unset(_pugixml_SEARCH_DIRS)
|
||||
|
|
|
@ -59,3 +59,5 @@ mark_as_advanced(
|
|||
LIBPULSE_INCLUDE_DIR
|
||||
LIBPULSE_LIBRARY
|
||||
)
|
||||
|
||||
unset(_pulse_SEARCH_DIRS)
|
||||
|
|
|
@ -256,10 +256,6 @@ if(PYTHONLIBSUNIX_FOUND)
|
|||
)
|
||||
endif()
|
||||
|
||||
unset(_PYTHON_ABI_FLAGS)
|
||||
unset(_PYTHON_VERSION_SUPPORTED)
|
||||
unset(_python_SEARCH_DIRS)
|
||||
|
||||
mark_as_advanced(
|
||||
PYTHON_INCLUDE_DIR
|
||||
PYTHON_INCLUDE_CONFIG_DIR
|
||||
|
@ -268,3 +264,7 @@ mark_as_advanced(
|
|||
PYTHON_SITE_PACKAGES
|
||||
PYTHON_EXECUTABLE
|
||||
)
|
||||
|
||||
unset(_PYTHON_ABI_FLAGS)
|
||||
unset(_PYTHON_VERSION_SUPPORTED)
|
||||
unset(_python_SEARCH_DIRS)
|
||||
|
|
|
@ -60,3 +60,5 @@ mark_as_advanced(
|
|||
SDL2_INCLUDE_DIR
|
||||
SDL2_LIBRARY
|
||||
)
|
||||
|
||||
unset(_sdl2_SEARCH_DIRS)
|
||||
|
|
|
@ -22,7 +22,7 @@ elseif(DEFINED ENV{SYCL_ROOT_DIR} AND NOT $ENV{SYCL_ROOT_DIR} STREQUAL "")
|
|||
set(SYCL_ROOT_DIR $ENV{SYCL_ROOT_DIR})
|
||||
endif()
|
||||
|
||||
set(_sycl_search_dirs
|
||||
set(_sycl_SEARCH_DIRS
|
||||
${SYCL_ROOT_DIR}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
|
@ -41,7 +41,7 @@ find_program(SYCL_COMPILER
|
|||
dpcpp
|
||||
clang++
|
||||
HINTS
|
||||
${_sycl_search_dirs}
|
||||
${_sycl_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
bin
|
||||
NO_CMAKE_FIND_ROOT_PATH
|
||||
|
@ -56,7 +56,7 @@ if(NOT SYCL_COMPILER)
|
|||
icpx
|
||||
dpcpp
|
||||
HINTS
|
||||
${_sycl_search_dirs}
|
||||
${_sycl_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
bin
|
||||
)
|
||||
|
@ -68,7 +68,7 @@ find_library(SYCL_LIBRARY
|
|||
sycl6
|
||||
sycl
|
||||
HINTS
|
||||
${_sycl_search_dirs}
|
||||
${_sycl_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
lib64 lib
|
||||
)
|
||||
|
@ -80,7 +80,7 @@ if(WIN32)
|
|||
sycl6d
|
||||
sycld
|
||||
HINTS
|
||||
${_sycl_search_dirs}
|
||||
${_sycl_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
lib64 lib
|
||||
)
|
||||
|
@ -90,7 +90,7 @@ find_path(SYCL_INCLUDE_DIR
|
|||
NAMES
|
||||
sycl/sycl.hpp
|
||||
HINTS
|
||||
${_sycl_search_dirs}
|
||||
${_sycl_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
include
|
||||
)
|
||||
|
@ -129,3 +129,5 @@ mark_as_advanced(
|
|||
SYCL_INCLUDE_DIR
|
||||
SYCL_LIBRARY
|
||||
)
|
||||
|
||||
unset(_sycl_SEARCH_DIRS)
|
||||
|
|
|
@ -59,3 +59,5 @@ mark_as_advanced(
|
|||
LIBSNDFILE_INCLUDE_DIR
|
||||
LIBSNDFILE_LIBRARY
|
||||
)
|
||||
|
||||
unset(_sndfile_SEARCH_DIRS)
|
||||
|
|
|
@ -61,3 +61,5 @@ mark_as_advanced(
|
|||
SPACENAV_INCLUDE_DIR
|
||||
SPACENAV_LIBRARY
|
||||
)
|
||||
|
||||
unset(_spacenav_SEARCH_DIRS)
|
||||
|
|
|
@ -64,3 +64,5 @@ mark_as_advanced(
|
|||
TBB_INCLUDE_DIR
|
||||
TBB_LIBRARY
|
||||
)
|
||||
|
||||
unset(_tbb_SEARCH_DIRS)
|
||||
|
|
|
@ -89,3 +89,7 @@ mark_as_advanced(
|
|||
WEBP_WEBP_LIBRARY
|
||||
WEBP_SHARPYUV_LIBRARY
|
||||
)
|
||||
|
||||
unset(_webp_FIND_COMPONENTS)
|
||||
unset(_webp_LIBRARIES)
|
||||
unset(_webp_SEARCH_DIRS)
|
||||
|
|
|
@ -59,3 +59,5 @@ mark_as_advanced(
|
|||
XML2_INCLUDE_DIR
|
||||
XML2_LIBRARY
|
||||
)
|
||||
|
||||
unset(_xml2_SEARCH_DIRS)
|
||||
|
|
|
@ -70,3 +70,5 @@ mark_as_advanced(
|
|||
XR_OPENXR_SDK_INCLUDE_DIR
|
||||
XR_OPENXR_SDK_LOADER_LIBRARY
|
||||
)
|
||||
|
||||
unset(_xr_openxr_sdk_SEARCH_DIRS)
|
||||
|
|
|
@ -61,3 +61,5 @@ mark_as_advanced(
|
|||
ZSTD_INCLUDE_DIR
|
||||
ZSTD_LIBRARY
|
||||
)
|
||||
|
||||
unset(_zstd_SEARCH_DIRS)
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
"""
|
||||
Using Python Argument Parsing
|
||||
-----------------------------
|
||||
|
||||
This example shows how the Python ``argparse`` module can be used with a custom command.
|
||||
|
||||
Using ``argparse`` is generally recommended as it has many useful utilities and
|
||||
generates a ``--help`` message for your command.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
def argparse_create():
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
prog=os.path.basename(sys.argv[0]) + " --command keyconfig_export",
|
||||
description="Write key-configuration to a file.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-o", "--output",
|
||||
dest="output",
|
||||
metavar='OUTPUT',
|
||||
type=str,
|
||||
help="The path to write the keymap to.",
|
||||
required=True,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-a", "--all",
|
||||
dest="all",
|
||||
action="store_true",
|
||||
help="Write all key-maps (not only customized key-maps).",
|
||||
required=False,
|
||||
)
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
def keyconfig_export(argv):
|
||||
parser = argparse_create()
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
# Ensure the key configuration is loaded in background mode.
|
||||
bpy.utils.keyconfig_init()
|
||||
|
||||
bpy.ops.preferences.keyconfig_export(
|
||||
filepath=args.output,
|
||||
all=args.all,
|
||||
)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
cli_commands = []
|
||||
|
||||
|
||||
def register():
|
||||
cli_commands.append(bpy.utils.register_cli_command("keyconfig_export", keyconfig_export))
|
||||
|
||||
|
||||
def unregister():
|
||||
for cmd in cli_commands:
|
||||
bpy.utils.unregister_cli_command(cmd)
|
||||
cli_commands.clear()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
|
@ -0,0 +1,43 @@
|
|||
"""
|
||||
Custom Commands
|
||||
---------------
|
||||
|
||||
Registering commands makes it possible to conveniently expose command line
|
||||
functionality via commands passed to (``-c`` / ``--command``).
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
||||
def sysinfo_command(argv):
|
||||
import tempfile
|
||||
import sys_info
|
||||
|
||||
if argv and argv[0] == "--help":
|
||||
print("Print system information & exit!")
|
||||
return 0
|
||||
|
||||
with tempfile.TemporaryDirectory() as tempdir:
|
||||
filepath = os.path.join(tempdir, "system_info.txt")
|
||||
sys_info.write_sysinfo(filepath)
|
||||
with open(filepath, "r", encoding="utf-8") as fh:
|
||||
sys.stdout.write(fh.read())
|
||||
return 0
|
||||
|
||||
|
||||
cli_commands = []
|
||||
|
||||
|
||||
def register():
|
||||
cli_commands.append(bpy.utils.register_cli_command("sysinfo", sysinfo_command))
|
||||
|
||||
|
||||
def unregister():
|
||||
for cmd in cli_commands:
|
||||
bpy.utils.unregister_cli_command(cmd)
|
||||
cli_commands.clear()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
|
@ -21,6 +21,8 @@ __all__ = (
|
|||
"refresh_script_paths",
|
||||
"app_template_paths",
|
||||
"register_class",
|
||||
"register_cli_command",
|
||||
"unregister_cli_command",
|
||||
"register_manual_map",
|
||||
"unregister_manual_map",
|
||||
"register_classes_factory",
|
||||
|
@ -49,9 +51,11 @@ from _bpy import (
|
|||
flip_name,
|
||||
unescape_identifier,
|
||||
register_class,
|
||||
register_cli_command,
|
||||
resource_path,
|
||||
script_paths as _bpy_script_paths,
|
||||
unregister_class,
|
||||
unregister_cli_command,
|
||||
user_resource as _user_resource,
|
||||
system_resource,
|
||||
)
|
||||
|
|
|
@ -317,6 +317,8 @@ class ZoneOperator:
|
|||
@classmethod
|
||||
def get_node(cls, context):
|
||||
node = context.active_node
|
||||
if node is None:
|
||||
return None
|
||||
if node.bl_idname == cls.output_node_type:
|
||||
return node
|
||||
if node.bl_idname == cls.input_node_type:
|
||||
|
@ -337,6 +339,8 @@ class NodeOperator:
|
|||
@classmethod
|
||||
def get_node(cls, context):
|
||||
node = context.active_node
|
||||
if node is None:
|
||||
return None
|
||||
if node.bl_idname == cls.node_type:
|
||||
return node
|
||||
|
||||
|
|
|
@ -0,0 +1,297 @@
|
|||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup animrig
|
||||
*
|
||||
* \brief Animation data-block functionality.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ANIM_fcurve.hh"
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
|
||||
#include "BLI_math_vector.hh"
|
||||
#include "BLI_set.hh"
|
||||
#include "BLI_string_ref.hh"
|
||||
|
||||
struct AnimationEvalContext;
|
||||
struct FCurve;
|
||||
struct ID;
|
||||
struct Main;
|
||||
struct PointerRNA;
|
||||
|
||||
namespace blender::animrig {
|
||||
|
||||
/* Forward declarations for the types defined later in this file. */
|
||||
class Layer;
|
||||
class Strip;
|
||||
class Binding;
|
||||
|
||||
/* Use an alias for the Binding handle type to help disambiguate function parameters. */
|
||||
using binding_handle_t = decltype(::AnimationBinding::handle);
|
||||
|
||||
/**
|
||||
* Container of animation data for one or more animated IDs.
|
||||
*
|
||||
* Broadly an Animation consists of Layers, each Layer has Strips, and it's the
|
||||
* Strips that eventually contain the animation data.
|
||||
*
|
||||
* Temporary limitation: each Animation can only contain one Layer.
|
||||
*
|
||||
* Which sub-set of that data drives the animation of which ID is determined by
|
||||
* which Binding is associated with that ID.
|
||||
*
|
||||
* \see AnimData::animation
|
||||
* \see AnimData::binding_handle
|
||||
*/
|
||||
class Animation : public ::Animation {
|
||||
public:
|
||||
Animation() = default;
|
||||
/**
|
||||
* Copy constructor is deleted, as code should use regular ID library
|
||||
* management functions to duplicate this data-block.
|
||||
*/
|
||||
Animation(const Animation &other) = delete;
|
||||
|
||||
/* Animation Layers access. */
|
||||
blender::Span<const Layer *> layers() const;
|
||||
blender::MutableSpan<Layer *> layers();
|
||||
const Layer *layer(int64_t index) const;
|
||||
Layer *layer(int64_t index);
|
||||
|
||||
/* Animation Binding access. */
|
||||
blender::Span<const Binding *> bindings() const;
|
||||
blender::MutableSpan<Binding *> bindings();
|
||||
const Binding *binding(int64_t index) const;
|
||||
Binding *binding(int64_t index);
|
||||
|
||||
/** Free all data in the `Animation`. Doesn't delete the `Animation` itself. */
|
||||
void free_data();
|
||||
};
|
||||
static_assert(sizeof(Animation) == sizeof(::Animation),
|
||||
"DNA struct and its C++ wrapper must have the same size");
|
||||
|
||||
/**
|
||||
* Strips contain the actual animation data.
|
||||
*
|
||||
* Although the data model allows for different strip types, currently only a
|
||||
* single type is implemented: keyframe strips.
|
||||
*/
|
||||
class Strip : public ::AnimationStrip {
|
||||
public:
|
||||
Strip() = default;
|
||||
/**
|
||||
* Strip cannot be duplicated via the copy constructor. Either use a concrete
|
||||
* strip type's copy constructor, or use Strip::duplicate().
|
||||
*
|
||||
* The reason why the copy constructor won't work is due to the double nature
|
||||
* of the inheritance at play here:
|
||||
*
|
||||
* C-style inheritance: `KeyframeAnimationStrip` "inherits" `AnimationStrip"
|
||||
* by embedding the latter. This means that any `KeyframeAnimationStrip *`
|
||||
* can be reinterpreted as `AnimationStrip *`.
|
||||
*
|
||||
* C++-style inheritance: the C++ wrappers inherit the DNA structs, so
|
||||
* `animrig::Strip` inherits `::AnimationStrip`, and
|
||||
* `animrig::KeyframeStrip` inherits `::KeyframeAnimationStrip`.
|
||||
*/
|
||||
Strip(const Strip &other) = delete;
|
||||
~Strip();
|
||||
|
||||
Strip *duplicate(StringRefNull allocation_name) const;
|
||||
|
||||
enum class Type : int8_t { Keyframe = 0 };
|
||||
|
||||
/**
|
||||
* Strip type, so it's known which subclass this can be wrapped in without
|
||||
* having to rely on C++ RTTI.
|
||||
*/
|
||||
Type type() const
|
||||
{
|
||||
return Type(this->strip_type);
|
||||
}
|
||||
|
||||
template<typename T> bool is() const;
|
||||
template<typename T> T &as();
|
||||
template<typename T> const T &as() const;
|
||||
};
|
||||
static_assert(sizeof(Strip) == sizeof(::AnimationStrip),
|
||||
"DNA struct and its C++ wrapper must have the same size");
|
||||
|
||||
/**
|
||||
* Layers can be stacked on top of each other to define the animation. Each
|
||||
* layer has a mix mode and an influence (0-1), which define how it is mixed
|
||||
* with the layers below it.
|
||||
*
|
||||
* Layers contain one or more Strips, which in turn contain the animation data
|
||||
* itself.
|
||||
*
|
||||
* Temporary limitation: at most one strip may exist on a layer, and it extends
|
||||
* from negative to positive infinity.
|
||||
*/
|
||||
class Layer : public ::AnimationLayer {
|
||||
public:
|
||||
Layer() = default;
|
||||
Layer(const Layer &other);
|
||||
~Layer();
|
||||
|
||||
enum class Flags : uint8_t {
|
||||
/* Set by default, cleared to mute. */
|
||||
Enabled = (1 << 0),
|
||||
/* When adding/removing a flag, also update the ENUM_OPERATORS() invocation below. */
|
||||
};
|
||||
|
||||
Flags flags() const
|
||||
{
|
||||
return static_cast<Flags>(this->layer_flags);
|
||||
}
|
||||
|
||||
enum class MixMode : int8_t {
|
||||
/** Channels in this layer override the same channels from underlying layers. */
|
||||
Replace = 0,
|
||||
/** Channels in this layer are added to underlying layers as sequential operations. */
|
||||
Offset = 1,
|
||||
/** Channels in this layer are added to underlying layers on a per-channel basis. */
|
||||
Add = 2,
|
||||
/** Channels in this layer are subtracted to underlying layers on a per-channel basis. */
|
||||
Subtract = 3,
|
||||
/** Channels in this layer are multiplied with underlying layers on a per-channel basis. */
|
||||
Multiply = 4,
|
||||
};
|
||||
|
||||
MixMode mix_mode() const
|
||||
{
|
||||
return static_cast<MixMode>(this->layer_mix_mode);
|
||||
}
|
||||
|
||||
/* Strip access. */
|
||||
blender::Span<const Strip *> strips() const;
|
||||
blender::MutableSpan<Strip *> strips();
|
||||
const Strip *strip(int64_t index) const;
|
||||
Strip *strip(int64_t index);
|
||||
};
|
||||
static_assert(sizeof(Layer) == sizeof(::AnimationLayer),
|
||||
"DNA struct and its C++ wrapper must have the same size");
|
||||
|
||||
ENUM_OPERATORS(Layer::Flags, Layer::Flags::Enabled);
|
||||
|
||||
/**
|
||||
* Identifier for a sub-set of the animation data inside an Animation data-block.
|
||||
*
|
||||
* An animatable ID specifies both an `Animation*` and an `AnimationBinding::handle`
|
||||
* to identify which F-Curves (and in the future other animation data) it will
|
||||
* be animated by.
|
||||
*
|
||||
* This is called an 'binding' because it acts like an binding socket of the
|
||||
* Animation data-block, into which an animatable ID can be noodled.
|
||||
*
|
||||
* \see AnimData::binding_handle
|
||||
*/
|
||||
class Binding : public ::AnimationBinding {
|
||||
public:
|
||||
Binding() = default;
|
||||
Binding(const Binding &other) = default;
|
||||
~Binding() = default;
|
||||
};
|
||||
static_assert(sizeof(Binding) == sizeof(::AnimationBinding),
|
||||
"DNA struct and its C++ wrapper must have the same size");
|
||||
|
||||
/**
|
||||
* KeyframeStrips effectively contain a bag of F-Curves for each Binding.
|
||||
*/
|
||||
class KeyframeStrip : public ::KeyframeAnimationStrip {
|
||||
public:
|
||||
KeyframeStrip() = default;
|
||||
KeyframeStrip(const KeyframeStrip &other);
|
||||
~KeyframeStrip();
|
||||
|
||||
/* ChannelBag array access. */
|
||||
blender::Span<const ChannelBag *> channelbags() const;
|
||||
blender::MutableSpan<ChannelBag *> channelbags();
|
||||
const ChannelBag *channelbag(int64_t index) const;
|
||||
ChannelBag *channelbag(int64_t index);
|
||||
};
|
||||
static_assert(sizeof(KeyframeStrip) == sizeof(::KeyframeAnimationStrip),
|
||||
"DNA struct and its C++ wrapper must have the same size");
|
||||
|
||||
template<> KeyframeStrip &Strip::as<KeyframeStrip>();
|
||||
template<> const KeyframeStrip &Strip::as<KeyframeStrip>() const;
|
||||
|
||||
/**
|
||||
* Collection of F-Curves, intended for a specific Binding handle.
|
||||
*/
|
||||
class ChannelBag : public ::AnimationChannelBag {
|
||||
public:
|
||||
ChannelBag() = default;
|
||||
ChannelBag(const ChannelBag &other);
|
||||
~ChannelBag();
|
||||
|
||||
/* FCurves access. */
|
||||
blender::Span<const FCurve *> fcurves() const;
|
||||
blender::MutableSpan<FCurve *> fcurves();
|
||||
const FCurve *fcurve(int64_t index) const;
|
||||
FCurve *fcurve(int64_t index);
|
||||
};
|
||||
static_assert(sizeof(ChannelBag) == sizeof(::AnimationChannelBag),
|
||||
"DNA struct and its C++ wrapper must have the same size");
|
||||
|
||||
} // namespace blender::animrig
|
||||
|
||||
/* Wrap functions for the DNA structs. */
|
||||
|
||||
inline blender::animrig::Animation &Animation::wrap()
|
||||
{
|
||||
return *reinterpret_cast<blender::animrig::Animation *>(this);
|
||||
}
|
||||
inline const blender::animrig::Animation &Animation::wrap() const
|
||||
{
|
||||
return *reinterpret_cast<const blender::animrig::Animation *>(this);
|
||||
}
|
||||
|
||||
inline blender::animrig::Layer &AnimationLayer::wrap()
|
||||
{
|
||||
return *reinterpret_cast<blender::animrig::Layer *>(this);
|
||||
}
|
||||
inline const blender::animrig::Layer &AnimationLayer::wrap() const
|
||||
{
|
||||
return *reinterpret_cast<const blender::animrig::Layer *>(this);
|
||||
}
|
||||
|
||||
inline blender::animrig::Binding &AnimationBinding::wrap()
|
||||
{
|
||||
return *reinterpret_cast<blender::animrig::Binding *>(this);
|
||||
}
|
||||
inline const blender::animrig::Binding &AnimationBinding::wrap() const
|
||||
{
|
||||
return *reinterpret_cast<const blender::animrig::Binding *>(this);
|
||||
}
|
||||
|
||||
inline blender::animrig::Strip &AnimationStrip::wrap()
|
||||
{
|
||||
return *reinterpret_cast<blender::animrig::Strip *>(this);
|
||||
}
|
||||
inline const blender::animrig::Strip &AnimationStrip::wrap() const
|
||||
{
|
||||
return *reinterpret_cast<const blender::animrig::Strip *>(this);
|
||||
}
|
||||
|
||||
inline blender::animrig::KeyframeStrip &KeyframeAnimationStrip::wrap()
|
||||
{
|
||||
return *reinterpret_cast<blender::animrig::KeyframeStrip *>(this);
|
||||
}
|
||||
inline const blender::animrig::KeyframeStrip &KeyframeAnimationStrip::wrap() const
|
||||
{
|
||||
return *reinterpret_cast<const blender::animrig::KeyframeStrip *>(this);
|
||||
}
|
||||
|
||||
inline blender::animrig::ChannelBag &AnimationChannelBag::wrap()
|
||||
{
|
||||
return *reinterpret_cast<blender::animrig::ChannelBag *>(this);
|
||||
}
|
||||
inline const blender::animrig::ChannelBag &AnimationChannelBag::wrap() const
|
||||
{
|
||||
return *reinterpret_cast<const blender::animrig::ChannelBag *>(this);
|
||||
}
|
|
@ -11,6 +11,7 @@ set(INC
|
|||
../editors/include
|
||||
../makesrna
|
||||
../windowmanager
|
||||
../../../extern/fmtlib/include
|
||||
# RNA_prototypes.h
|
||||
${CMAKE_BINARY_DIR}/source/blender/makesrna
|
||||
)
|
||||
|
@ -21,6 +22,7 @@ set(INC_SYS
|
|||
set(SRC
|
||||
intern/action.cc
|
||||
intern/anim_rna.cc
|
||||
intern/animation.cc
|
||||
intern/animdata.cc
|
||||
intern/bone_collections.cc
|
||||
intern/bonecolor.cc
|
||||
|
@ -31,6 +33,7 @@ set(SRC
|
|||
intern/visualkey.cc
|
||||
|
||||
ANIM_action.hh
|
||||
ANIM_animation.hh
|
||||
ANIM_animdata.hh
|
||||
ANIM_armature_iter.hh
|
||||
ANIM_bone_collections.hh
|
||||
|
@ -50,6 +53,7 @@ set(LIB
|
|||
bf::dna
|
||||
PRIVATE bf_editor_interface
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
PRIVATE bf::intern::atomic
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,260 @@
|
|||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "DNA_anim_defaults.h"
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_defaults.h"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_listbase_wrapper.hh"
|
||||
#include "BLI_math_base.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_string_utf8.h"
|
||||
#include "BLI_string_utils.hh"
|
||||
|
||||
#include "BKE_anim_data.hh"
|
||||
#include "BKE_animation.hh"
|
||||
#include "BKE_fcurve.hh"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_main.hh"
|
||||
|
||||
#include "ED_keyframing.hh"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "atomic_ops.h"
|
||||
|
||||
#include "ANIM_animation.hh"
|
||||
#include "ANIM_fcurve.hh"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
namespace blender::animrig {
|
||||
|
||||
/* ----- Animation implementation ----------- */
|
||||
|
||||
blender::Span<const Layer *> Animation::layers() const
|
||||
{
|
||||
return blender::Span<Layer *>{reinterpret_cast<Layer **>(this->layer_array),
|
||||
this->layer_array_num};
|
||||
}
|
||||
blender::MutableSpan<Layer *> Animation::layers()
|
||||
{
|
||||
return blender::MutableSpan<Layer *>{reinterpret_cast<Layer **>(this->layer_array),
|
||||
this->layer_array_num};
|
||||
}
|
||||
const Layer *Animation::layer(const int64_t index) const
|
||||
{
|
||||
return &this->layer_array[index]->wrap();
|
||||
}
|
||||
Layer *Animation::layer(const int64_t index)
|
||||
{
|
||||
return &this->layer_array[index]->wrap();
|
||||
}
|
||||
|
||||
blender::Span<const Binding *> Animation::bindings() const
|
||||
{
|
||||
return blender::Span<Binding *>{reinterpret_cast<Binding **>(this->binding_array),
|
||||
this->binding_array_num};
|
||||
}
|
||||
blender::MutableSpan<Binding *> Animation::bindings()
|
||||
{
|
||||
return blender::MutableSpan<Binding *>{reinterpret_cast<Binding **>(this->binding_array),
|
||||
this->binding_array_num};
|
||||
}
|
||||
const Binding *Animation::binding(const int64_t index) const
|
||||
{
|
||||
return &this->binding_array[index]->wrap();
|
||||
}
|
||||
Binding *Animation::binding(const int64_t index)
|
||||
{
|
||||
return &this->binding_array[index]->wrap();
|
||||
}
|
||||
|
||||
void Animation::free_data()
|
||||
{
|
||||
/* Free layers. */
|
||||
for (Layer *layer : this->layers()) {
|
||||
MEM_delete(layer);
|
||||
}
|
||||
MEM_SAFE_FREE(this->layer_array);
|
||||
this->layer_array_num = 0;
|
||||
|
||||
/* Free bindings. */
|
||||
for (Binding *binding : this->bindings()) {
|
||||
MEM_delete(binding);
|
||||
}
|
||||
MEM_SAFE_FREE(this->binding_array);
|
||||
this->binding_array_num = 0;
|
||||
}
|
||||
|
||||
/* ----- AnimationLayer implementation ----------- */
|
||||
|
||||
Layer::Layer(const Layer &other)
|
||||
{
|
||||
memcpy(this, &other, sizeof(*this));
|
||||
|
||||
/* Strips. */
|
||||
this->strip_array = MEM_cnew_array<AnimationStrip *>(other.strip_array_num, __func__);
|
||||
for (int i : other.strips().index_range()) {
|
||||
this->strip_array[i] = other.strip(i)->duplicate(__func__);
|
||||
}
|
||||
}
|
||||
|
||||
Layer::~Layer()
|
||||
{
|
||||
for (Strip *strip : this->strips()) {
|
||||
MEM_delete(strip);
|
||||
}
|
||||
MEM_SAFE_FREE(this->strip_array);
|
||||
this->strip_array_num = 0;
|
||||
}
|
||||
|
||||
blender::Span<const Strip *> Layer::strips() const
|
||||
{
|
||||
return blender::Span<Strip *>{reinterpret_cast<Strip **>(this->strip_array),
|
||||
this->strip_array_num};
|
||||
}
|
||||
blender::MutableSpan<Strip *> Layer::strips()
|
||||
{
|
||||
return blender::MutableSpan<Strip *>{reinterpret_cast<Strip **>(this->strip_array),
|
||||
this->strip_array_num};
|
||||
}
|
||||
const Strip *Layer::strip(const int64_t index) const
|
||||
{
|
||||
return &this->strip_array[index]->wrap();
|
||||
}
|
||||
Strip *Layer::strip(const int64_t index)
|
||||
{
|
||||
return &this->strip_array[index]->wrap();
|
||||
}
|
||||
|
||||
/* ----- AnimationBinding implementation ----------- */
|
||||
|
||||
/* ----- AnimationStrip implementation ----------- */
|
||||
|
||||
Strip *Strip::duplicate(const StringRefNull allocation_name) const
|
||||
{
|
||||
switch (this->type()) {
|
||||
case Type::Keyframe: {
|
||||
const KeyframeStrip &source = this->as<KeyframeStrip>();
|
||||
KeyframeStrip *copy = MEM_new<KeyframeStrip>(allocation_name.c_str(), source);
|
||||
return ©->strip.wrap();
|
||||
}
|
||||
}
|
||||
BLI_assert_unreachable();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Strip::~Strip()
|
||||
{
|
||||
switch (this->type()) {
|
||||
case Type::Keyframe:
|
||||
this->as<KeyframeStrip>().~KeyframeStrip();
|
||||
return;
|
||||
}
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
|
||||
/* ----- KeyframeAnimationStrip implementation ----------- */
|
||||
|
||||
KeyframeStrip::KeyframeStrip(const KeyframeStrip &other)
|
||||
{
|
||||
memcpy(this, &other, sizeof(*this));
|
||||
|
||||
this->channelbags_array = MEM_cnew_array<AnimationChannelBag *>(other.channelbags_array_num,
|
||||
__func__);
|
||||
Span<const ChannelBag *> channelbags_src = other.channelbags();
|
||||
for (int i : channelbags_src.index_range()) {
|
||||
this->channelbags_array[i] = MEM_new<animrig::ChannelBag>(__func__, *other.channelbag(i));
|
||||
}
|
||||
}
|
||||
|
||||
KeyframeStrip::~KeyframeStrip()
|
||||
{
|
||||
for (ChannelBag *channelbag_for_binding : this->channelbags()) {
|
||||
MEM_delete(channelbag_for_binding);
|
||||
}
|
||||
MEM_SAFE_FREE(this->channelbags_array);
|
||||
this->channelbags_array_num = 0;
|
||||
}
|
||||
|
||||
template<> bool Strip::is<KeyframeStrip>() const
|
||||
{
|
||||
return this->type() == Type::Keyframe;
|
||||
}
|
||||
|
||||
template<> KeyframeStrip &Strip::as<KeyframeStrip>()
|
||||
{
|
||||
BLI_assert_msg(this->is<KeyframeStrip>(), "Strip is not a KeyframeStrip");
|
||||
return *reinterpret_cast<KeyframeStrip *>(this);
|
||||
}
|
||||
|
||||
template<> const KeyframeStrip &Strip::as<KeyframeStrip>() const
|
||||
{
|
||||
BLI_assert_msg(this->is<KeyframeStrip>(), "Strip is not a KeyframeStrip");
|
||||
return *reinterpret_cast<const KeyframeStrip *>(this);
|
||||
}
|
||||
|
||||
blender::Span<const ChannelBag *> KeyframeStrip::channelbags() const
|
||||
{
|
||||
return blender::Span<ChannelBag *>{reinterpret_cast<ChannelBag **>(this->channelbags_array),
|
||||
this->channelbags_array_num};
|
||||
}
|
||||
blender::MutableSpan<ChannelBag *> KeyframeStrip::channelbags()
|
||||
{
|
||||
return blender::MutableSpan<ChannelBag *>{
|
||||
reinterpret_cast<ChannelBag **>(this->channelbags_array), this->channelbags_array_num};
|
||||
}
|
||||
const ChannelBag *KeyframeStrip::channelbag(const int64_t index) const
|
||||
{
|
||||
return &this->channelbags_array[index]->wrap();
|
||||
}
|
||||
ChannelBag *KeyframeStrip::channelbag(const int64_t index)
|
||||
{
|
||||
return &this->channelbags_array[index]->wrap();
|
||||
}
|
||||
|
||||
/* AnimationChannelBag implementation. */
|
||||
|
||||
ChannelBag::ChannelBag(const ChannelBag &other)
|
||||
{
|
||||
this->binding_handle = other.binding_handle;
|
||||
this->fcurve_array_num = other.fcurve_array_num;
|
||||
|
||||
this->fcurve_array = MEM_cnew_array<FCurve *>(other.fcurve_array_num, __func__);
|
||||
for (int i = 0; i < other.fcurve_array_num; i++) {
|
||||
const FCurve *fcu_src = other.fcurve_array[i];
|
||||
this->fcurve_array[i] = BKE_fcurve_copy(fcu_src);
|
||||
}
|
||||
}
|
||||
|
||||
ChannelBag::~ChannelBag()
|
||||
{
|
||||
for (FCurve *fcu : this->fcurves()) {
|
||||
BKE_fcurve_free(fcu);
|
||||
}
|
||||
MEM_SAFE_FREE(this->fcurve_array);
|
||||
this->fcurve_array_num = 0;
|
||||
}
|
||||
|
||||
blender::Span<const FCurve *> ChannelBag::fcurves() const
|
||||
{
|
||||
return blender::Span<FCurve *>{this->fcurve_array, this->fcurve_array_num};
|
||||
}
|
||||
blender::MutableSpan<FCurve *> ChannelBag::fcurves()
|
||||
{
|
||||
return blender::MutableSpan<FCurve *>{this->fcurve_array, this->fcurve_array_num};
|
||||
}
|
||||
const FCurve *ChannelBag::fcurve(const int64_t index) const
|
||||
{
|
||||
return this->fcurve_array[index];
|
||||
}
|
||||
FCurve *ChannelBag::fcurve(const int64_t index)
|
||||
{
|
||||
return this->fcurve_array[index];
|
||||
}
|
||||
|
||||
} // namespace blender::animrig
|
|
@ -10,6 +10,8 @@
|
|||
#include <cmath>
|
||||
#include <string>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "ANIM_action.hh"
|
||||
#include "ANIM_animdata.hh"
|
||||
#include "ANIM_fcurve.hh"
|
||||
|
@ -46,6 +48,45 @@
|
|||
|
||||
namespace blender::animrig {
|
||||
|
||||
enum class SingleKeyingResult {
|
||||
SUCCESS = 0,
|
||||
CANNOT_CREATE_FCURVE,
|
||||
FCURVE_NOT_KEYFRAMEABLE,
|
||||
NO_KEY_NEEDED,
|
||||
/* Make sure to always keep this at the end of the enum. */
|
||||
_KEYING_RESULT_MAX,
|
||||
};
|
||||
|
||||
class CombinedKeyingResult {
|
||||
private:
|
||||
/* The index to the array maps a `SingleKeyingResult` to the number of times this result has
|
||||
* occurred. */
|
||||
std::array<int, int(SingleKeyingResult::_KEYING_RESULT_MAX)> result_counter{0};
|
||||
|
||||
public:
|
||||
void add(const SingleKeyingResult result)
|
||||
{
|
||||
result_counter[int(result)]++;
|
||||
}
|
||||
|
||||
int get_count(const SingleKeyingResult result) const
|
||||
{
|
||||
return result_counter[int(result)];
|
||||
}
|
||||
|
||||
bool has_errors() const
|
||||
{
|
||||
/* For loop starts at 1 to skip the SUCCESS flag. Assumes that SUCCESS is 0 and the rest of the
|
||||
* enum are sequential values. */
|
||||
for (int i = 1; i < result_counter.size(); i++) {
|
||||
if (result_counter[i] > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
void update_autoflags_fcurve_direct(FCurve *fcu, PropertyRNA *prop)
|
||||
{
|
||||
/* Set additional flags for the F-Curve (i.e. only integer values). */
|
||||
|
@ -309,11 +350,11 @@ static float nla_time_remap(const AnimationEvalContext *anim_eval_context,
|
|||
}
|
||||
|
||||
/* Insert the specified keyframe value into a single F-Curve. */
|
||||
static bool insert_keyframe_value(
|
||||
static SingleKeyingResult insert_keyframe_value(
|
||||
FCurve *fcu, float cfra, float curval, eBezTriple_KeyframeType keytype, eInsertKeyFlags flag)
|
||||
{
|
||||
if (!BKE_fcurve_is_keyframable(fcu)) {
|
||||
return false;
|
||||
return SingleKeyingResult::FCURVE_NOT_KEYFRAMEABLE;
|
||||
}
|
||||
|
||||
/* Adjust coordinates for cycle aware insertion. */
|
||||
|
@ -329,17 +370,19 @@ static bool insert_keyframe_value(
|
|||
|
||||
if (flag & INSERTKEY_NEEDED) {
|
||||
if (!new_key_needed(fcu, cfra, curval)) {
|
||||
return false;
|
||||
return SingleKeyingResult::NO_KEY_NEEDED;
|
||||
}
|
||||
|
||||
if (insert_vert_fcurve(fcu, {cfra, curval}, settings, flag) < 0) {
|
||||
return false;
|
||||
return SingleKeyingResult::FCURVE_NOT_KEYFRAMEABLE;
|
||||
}
|
||||
|
||||
return true;
|
||||
return SingleKeyingResult::SUCCESS;
|
||||
}
|
||||
|
||||
return insert_vert_fcurve(fcu, {cfra, curval}, settings, flag) >= 0;
|
||||
if (insert_vert_fcurve(fcu, {cfra, curval}, settings, flag) < 0) {
|
||||
return SingleKeyingResult::FCURVE_NOT_KEYFRAMEABLE;
|
||||
}
|
||||
|
||||
return SingleKeyingResult::SUCCESS;
|
||||
}
|
||||
|
||||
bool insert_keyframe_direct(ReportList *reports,
|
||||
|
@ -401,9 +444,9 @@ bool insert_keyframe_direct(ReportList *reports,
|
|||
}
|
||||
|
||||
const float cfra = anim_eval_context->eval_time;
|
||||
const bool success = insert_keyframe_value(fcu, cfra, current_value, keytype, flag);
|
||||
const SingleKeyingResult result = insert_keyframe_value(fcu, cfra, current_value, keytype, flag);
|
||||
|
||||
if (!success) {
|
||||
if (result != SingleKeyingResult::SUCCESS) {
|
||||
BKE_reportf(reports,
|
||||
RPT_ERROR,
|
||||
"Failed to insert keys on F-Curve with path '%s[%d]', ensure that it is not "
|
||||
|
@ -411,22 +454,21 @@ bool insert_keyframe_direct(ReportList *reports,
|
|||
fcu->rna_path,
|
||||
fcu->array_index);
|
||||
}
|
||||
return success;
|
||||
return result == SingleKeyingResult::SUCCESS;
|
||||
}
|
||||
|
||||
/** Find or create the FCurve based on the given path, and insert the specified value into it. */
|
||||
static bool insert_keyframe_fcurve_value(Main *bmain,
|
||||
ReportList *reports,
|
||||
PointerRNA *ptr,
|
||||
PropertyRNA *prop,
|
||||
bAction *act,
|
||||
const char group[],
|
||||
const char rna_path[],
|
||||
int array_index,
|
||||
const float fcurve_frame,
|
||||
float curval,
|
||||
eBezTriple_KeyframeType keytype,
|
||||
eInsertKeyFlags flag)
|
||||
static SingleKeyingResult insert_keyframe_fcurve_value(Main *bmain,
|
||||
PointerRNA *ptr,
|
||||
PropertyRNA *prop,
|
||||
bAction *act,
|
||||
const char group[],
|
||||
const char rna_path[],
|
||||
int array_index,
|
||||
const float fcurve_frame,
|
||||
float curval,
|
||||
eBezTriple_KeyframeType keytype,
|
||||
eInsertKeyFlags flag)
|
||||
{
|
||||
/* Make sure the F-Curve exists.
|
||||
* - if we're replacing keyframes only, DO NOT create new F-Curves if they do not exist yet
|
||||
|
@ -439,7 +481,7 @@ static bool insert_keyframe_fcurve_value(Main *bmain,
|
|||
|
||||
/* We may not have a F-Curve when we're replacing only. */
|
||||
if (!fcu) {
|
||||
return false;
|
||||
return SingleKeyingResult::CANNOT_CREATE_FCURVE;
|
||||
}
|
||||
|
||||
const bool is_new_curve = (fcu->totvert == 0);
|
||||
|
@ -454,23 +496,51 @@ static bool insert_keyframe_fcurve_value(Main *bmain,
|
|||
/* Update F-Curve flags to ensure proper behavior for property type. */
|
||||
update_autoflags_fcurve_direct(fcu, prop);
|
||||
|
||||
const bool success = insert_keyframe_value(fcu, fcurve_frame, curval, keytype, flag);
|
||||
|
||||
if (!success && reports != nullptr) {
|
||||
BKE_reportf(reports,
|
||||
RPT_ERROR,
|
||||
"Failed to insert keys on F-Curve with path '%s[%d]', ensure that it is not "
|
||||
"locked or sampled, and try removing F-Modifiers",
|
||||
fcu->rna_path,
|
||||
fcu->array_index);
|
||||
}
|
||||
const SingleKeyingResult result = insert_keyframe_value(
|
||||
fcu, fcurve_frame, curval, keytype, flag);
|
||||
|
||||
/* If the curve is new, make it cyclic if appropriate. */
|
||||
if (is_cyclic_action && is_new_curve) {
|
||||
make_new_fcurve_cyclic(fcu, {act->frame_start, act->frame_end});
|
||||
}
|
||||
|
||||
return success;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void generate_keyframe_reports_from_result(ReportList *reports,
|
||||
const CombinedKeyingResult &result)
|
||||
{
|
||||
std::string error = "Inserting keyframes failed due to the following reasons:";
|
||||
|
||||
if (result.get_count(SingleKeyingResult::CANNOT_CREATE_FCURVE) > 0) {
|
||||
const int error_count = result.get_count(SingleKeyingResult::CANNOT_CREATE_FCURVE);
|
||||
error.append(
|
||||
fmt::format("\n- Could not create {} F-Curve{}. This can happen when only inserting to "
|
||||
"available F-Curves.",
|
||||
error_count,
|
||||
error_count > 1 ? "s" : ""));
|
||||
}
|
||||
|
||||
if (result.get_count(SingleKeyingResult::FCURVE_NOT_KEYFRAMEABLE) > 0) {
|
||||
const int error_count = result.get_count(SingleKeyingResult::FCURVE_NOT_KEYFRAMEABLE);
|
||||
if (error_count == 1) {
|
||||
error.append("\n- One F-Curve is not keyframeable. It might be locked or sampled.");
|
||||
}
|
||||
else {
|
||||
error.append(fmt::format(
|
||||
"\n- {} F-Curves are not keyframeable. They might be locked or sampled.", error_count));
|
||||
}
|
||||
}
|
||||
|
||||
if (result.get_count(SingleKeyingResult::NO_KEY_NEEDED) > 0) {
|
||||
const int error_count = result.get_count(SingleKeyingResult::NO_KEY_NEEDED);
|
||||
error.append(fmt::format(
|
||||
"\n- Due to the setting 'Only Insert Needed', {} keyframe{} not been inserted.",
|
||||
error_count,
|
||||
error_count > 1 ? "s have" : " has"));
|
||||
}
|
||||
|
||||
BKE_reportf(reports, RPT_ERROR, "%s", error.c_str());
|
||||
}
|
||||
|
||||
int insert_keyframe(Main *bmain,
|
||||
|
@ -540,6 +610,8 @@ int insert_keyframe(Main *bmain,
|
|||
&force_all,
|
||||
successful_remaps);
|
||||
|
||||
CombinedKeyingResult combined_result;
|
||||
|
||||
/* Key the entire array. */
|
||||
int key_count = 0;
|
||||
if (array_index == -1 || force_all) {
|
||||
|
@ -551,20 +623,19 @@ int insert_keyframe(Main *bmain,
|
|||
if (!successful_remaps[array_index]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (insert_keyframe_fcurve_value(bmain,
|
||||
reports,
|
||||
&ptr,
|
||||
prop,
|
||||
act,
|
||||
group,
|
||||
rna_path,
|
||||
array_index,
|
||||
nla_mapped_frame,
|
||||
values[array_index],
|
||||
keytype,
|
||||
flag))
|
||||
{
|
||||
const SingleKeyingResult result = insert_keyframe_fcurve_value(bmain,
|
||||
&ptr,
|
||||
prop,
|
||||
act,
|
||||
group,
|
||||
rna_path,
|
||||
array_index,
|
||||
nla_mapped_frame,
|
||||
values[array_index],
|
||||
keytype,
|
||||
flag);
|
||||
combined_result.add(result);
|
||||
if (result == SingleKeyingResult::SUCCESS) {
|
||||
key_count++;
|
||||
exclude = array_index;
|
||||
break;
|
||||
|
@ -580,18 +651,21 @@ int insert_keyframe(Main *bmain,
|
|||
}
|
||||
|
||||
if (array_index != exclude) {
|
||||
key_count += insert_keyframe_fcurve_value(bmain,
|
||||
reports,
|
||||
&ptr,
|
||||
prop,
|
||||
act,
|
||||
group,
|
||||
rna_path,
|
||||
array_index,
|
||||
nla_mapped_frame,
|
||||
values[array_index],
|
||||
keytype,
|
||||
flag);
|
||||
const SingleKeyingResult result = insert_keyframe_fcurve_value(bmain,
|
||||
&ptr,
|
||||
prop,
|
||||
act,
|
||||
group,
|
||||
rna_path,
|
||||
array_index,
|
||||
nla_mapped_frame,
|
||||
values[array_index],
|
||||
keytype,
|
||||
flag);
|
||||
combined_result.add(result);
|
||||
if (result == SingleKeyingResult::SUCCESS) {
|
||||
key_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -603,36 +677,42 @@ int insert_keyframe(Main *bmain,
|
|||
continue;
|
||||
}
|
||||
|
||||
key_count += insert_keyframe_fcurve_value(bmain,
|
||||
reports,
|
||||
&ptr,
|
||||
prop,
|
||||
act,
|
||||
group,
|
||||
rna_path,
|
||||
array_index,
|
||||
nla_mapped_frame,
|
||||
values[array_index],
|
||||
keytype,
|
||||
flag);
|
||||
const SingleKeyingResult result = insert_keyframe_fcurve_value(bmain,
|
||||
&ptr,
|
||||
prop,
|
||||
act,
|
||||
group,
|
||||
rna_path,
|
||||
array_index,
|
||||
nla_mapped_frame,
|
||||
values[array_index],
|
||||
keytype,
|
||||
flag);
|
||||
combined_result.add(result);
|
||||
if (result == SingleKeyingResult::SUCCESS) {
|
||||
key_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Key a single index. */
|
||||
else {
|
||||
if (array_index >= 0 && array_index < values.size() && successful_remaps[array_index]) {
|
||||
key_count += insert_keyframe_fcurve_value(bmain,
|
||||
reports,
|
||||
&ptr,
|
||||
prop,
|
||||
act,
|
||||
group,
|
||||
rna_path,
|
||||
array_index,
|
||||
nla_mapped_frame,
|
||||
values[array_index],
|
||||
keytype,
|
||||
flag);
|
||||
const SingleKeyingResult result = insert_keyframe_fcurve_value(bmain,
|
||||
&ptr,
|
||||
prop,
|
||||
act,
|
||||
group,
|
||||
rna_path,
|
||||
array_index,
|
||||
nla_mapped_frame,
|
||||
values[array_index],
|
||||
keytype,
|
||||
flag);
|
||||
combined_result.add(result);
|
||||
if (result == SingleKeyingResult::SUCCESS) {
|
||||
key_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -647,6 +727,10 @@ int insert_keyframe(Main *bmain,
|
|||
}
|
||||
}
|
||||
|
||||
if (key_count == 0) {
|
||||
generate_keyframe_reports_from_result(reports, combined_result);
|
||||
}
|
||||
|
||||
return key_count;
|
||||
}
|
||||
|
||||
|
@ -872,19 +956,18 @@ int insert_key_action(Main *bmain,
|
|||
property_array_index++;
|
||||
continue;
|
||||
}
|
||||
const bool inserted_key = insert_keyframe_fcurve_value(bmain,
|
||||
nullptr,
|
||||
ptr,
|
||||
prop,
|
||||
action,
|
||||
group.c_str(),
|
||||
rna_path.c_str(),
|
||||
property_array_index,
|
||||
frame,
|
||||
value,
|
||||
key_type,
|
||||
insert_key_flag);
|
||||
if (inserted_key) {
|
||||
const SingleKeyingResult inserted_key = insert_keyframe_fcurve_value(bmain,
|
||||
ptr,
|
||||
prop,
|
||||
action,
|
||||
group.c_str(),
|
||||
rna_path.c_str(),
|
||||
property_array_index,
|
||||
frame,
|
||||
value,
|
||||
key_type,
|
||||
insert_key_flag);
|
||||
if (inserted_key == SingleKeyingResult::SUCCESS) {
|
||||
inserted_keys++;
|
||||
}
|
||||
property_array_index++;
|
||||
|
@ -984,6 +1067,7 @@ void insert_key_rna(PointerRNA *rna_pointer,
|
|||
key_type,
|
||||
successful_remaps);
|
||||
}
|
||||
BKE_animsys_free_nla_keyframing_context_cache(&nla_cache);
|
||||
|
||||
if (insert_key_count == 0) {
|
||||
BKE_reportf(reports, RPT_ERROR, "Failed to insert any keys");
|
||||
|
|
|
@ -176,7 +176,7 @@ AssetLibrary::AssetLibrary(eAssetLibraryType library_type, StringRef name, Strin
|
|||
AssetLibrary::~AssetLibrary()
|
||||
{
|
||||
if (on_save_callback_store_.func) {
|
||||
on_blend_save_handler_unregister();
|
||||
this->on_blend_save_handler_unregister();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ bool AllAssetLibrary::is_catalogs_dirty() const
|
|||
|
||||
void AllAssetLibrary::refresh_catalogs()
|
||||
{
|
||||
rebuild_catalogs_from_nested(/*reload_nested_catalogs=*/true);
|
||||
this->rebuild_catalogs_from_nested(/*reload_nested_catalogs=*/true);
|
||||
}
|
||||
|
||||
} // namespace blender::asset_system
|
||||
|
|
|
@ -20,7 +20,7 @@ OnDiskAssetLibrary::OnDiskAssetLibrary(eAssetLibraryType library_type,
|
|||
|
||||
void OnDiskAssetLibrary::refresh_catalogs()
|
||||
{
|
||||
catalog_service().reload_catalogs();
|
||||
this->catalog_service().reload_catalogs();
|
||||
}
|
||||
|
||||
} // namespace blender::asset_system
|
||||
|
|
|
@ -43,20 +43,24 @@ class RuntimeAssetLibrary;
|
|||
class AssetLibraryService {
|
||||
static std::unique_ptr<AssetLibraryService> instance_;
|
||||
|
||||
/** Identify libraries with the library type, and the absolute path of the library's root path
|
||||
/**
|
||||
* Identify libraries with the library type, and the absolute path of the library's root path
|
||||
* (normalize with #normalize_directory_path()!). The type is relevant since the current file
|
||||
* library may point to the same path as a custom library. */
|
||||
* library may point to the same path as a custom library.
|
||||
*/
|
||||
using OnDiskLibraryIdentifier = std::pair<eAssetLibraryType, std::string>;
|
||||
/* Mapping of a (type, root path) pair to the AssetLibrary instance. */
|
||||
/** Mapping of a (type, root path) pair to the AssetLibrary instance. */
|
||||
Map<OnDiskLibraryIdentifier, std::unique_ptr<OnDiskAssetLibrary>> on_disk_libraries_;
|
||||
/** Library without a known path, i.e. the "Current File" library if the file isn't saved yet. If
|
||||
/**
|
||||
* Library without a known path, i.e. the "Current File" library if the file isn't saved yet. If
|
||||
* the file was saved, a valid path for the library can be determined and #on_disk_libraries_
|
||||
* above should be used. */
|
||||
* above should be used.
|
||||
*/
|
||||
std::unique_ptr<RuntimeAssetLibrary> current_file_library_;
|
||||
/** The "all" asset library, merging all other libraries into one. */
|
||||
std::unique_ptr<AllAssetLibrary> all_library_;
|
||||
|
||||
/* Handlers for managing the life cycle of the AssetLibraryService instance. */
|
||||
/** Handlers for managing the life cycle of the AssetLibraryService instance. */
|
||||
bCallbackFuncStore on_load_callback_store_;
|
||||
static bool atexit_handler_registered_;
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ bool AssetStorage::remove_asset(AssetRepresentation &asset)
|
|||
|
||||
void AssetStorage::remap_ids_and_remove_invalid(const blender::bke::id::IDRemapper &mappings)
|
||||
{
|
||||
Set<AssetRepresentation *> removed_assets{};
|
||||
Set<AssetRepresentation *> removed_assets;
|
||||
|
||||
for (auto &asset_ptr : local_id_assets_) {
|
||||
AssetRepresentation &asset = *asset_ptr;
|
||||
|
|
|
@ -49,7 +49,7 @@ static blender::Vector<uint8_t> filtered_rows_from_thumb(const Thumbnail *thumb)
|
|||
/* In the image data sent to the compression step, each scan-line is preceded by a filter type
|
||||
* byte containing the numeric code of the filter algorithm used for that scan-line. */
|
||||
const size_t line_size = thumb->width * 4;
|
||||
blender::Vector<uint8_t> filtered{};
|
||||
blender::Vector<uint8_t> filtered;
|
||||
size_t final_size = thumb->height * (line_size + 1);
|
||||
filtered.reserve(final_size);
|
||||
for (int i = 0; i < thumb->height; i++) {
|
||||
|
@ -88,7 +88,7 @@ std::optional<blender::Vector<uint8_t>> blendthumb_create_png_data_from_thumb(
|
|||
}
|
||||
|
||||
/* Create `IDAT` chunk data. */
|
||||
blender::Vector<uint8_t> image_data{};
|
||||
blender::Vector<uint8_t> image_data;
|
||||
{
|
||||
auto image_data_opt = zlib_compress(filtered_rows_from_thumb(thumb));
|
||||
if (image_data_opt == std::nullopt) {
|
||||
|
@ -98,7 +98,7 @@ std::optional<blender::Vector<uint8_t>> blendthumb_create_png_data_from_thumb(
|
|||
}
|
||||
|
||||
/* Create the IHDR chunk data. */
|
||||
blender::Vector<uint8_t> ihdr_data{};
|
||||
blender::Vector<uint8_t> ihdr_data;
|
||||
{
|
||||
const size_t ihdr_data_final_size = 4 + 4 + 5;
|
||||
ihdr_data.reserve(ihdr_data_final_size);
|
||||
|
@ -115,7 +115,7 @@ std::optional<blender::Vector<uint8_t>> blendthumb_create_png_data_from_thumb(
|
|||
}
|
||||
|
||||
/* Join it all together to create a PNG image. */
|
||||
blender::Vector<uint8_t> png_buf{};
|
||||
blender::Vector<uint8_t> png_buf;
|
||||
{
|
||||
const size_t png_buf_final_size = (
|
||||
/* Header. */
|
||||
|
|
|
@ -950,7 +950,7 @@ char *BLF_display_name_from_file(const char *filepath)
|
|||
{
|
||||
/* While listing font directories this function can be called simultaneously from a greater
|
||||
* number of threads than we want the FreeType cache to keep open at a time. Therefore open
|
||||
* with own FT_Library object and use FreeType calls directly to avoid any contention. */
|
||||
* with a separate FT_Library object and use FreeType calls directly to avoid any contention. */
|
||||
char *name = nullptr;
|
||||
FT_Library ft_library;
|
||||
if (FT_Init_FreeType(&ft_library) == FT_Err_Ok) {
|
||||
|
|
|
@ -58,7 +58,6 @@ struct CCGElem;
|
|||
struct CCGKey;
|
||||
struct CustomData_MeshMasks;
|
||||
struct Depsgraph;
|
||||
struct MFace;
|
||||
struct Mesh;
|
||||
struct ModifierData;
|
||||
struct Object;
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
struct AnimData;
|
||||
struct BlendDataReader;
|
||||
struct BlendLibReader;
|
||||
struct BlendWriter;
|
||||
struct ID;
|
||||
struct Library;
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup bke
|
||||
*
|
||||
* This file only contains the memory management functions for the Animation
|
||||
* data-block. For all other functionality, see `source/blender/animrig`.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
struct Animation;
|
||||
struct Main;
|
||||
|
||||
Animation *BKE_animation_add(Main *bmain, const char name[]);
|
|
@ -18,7 +18,6 @@ extern "C" {
|
|||
|
||||
struct AnimData;
|
||||
struct BlendDataReader;
|
||||
struct BlendLibReader;
|
||||
struct BlendWriter;
|
||||
struct Depsgraph;
|
||||
struct FCurve;
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
/** \file
|
||||
* \ingroup bke
|
||||
* \brief Blender CLI Generic `--command` Support.
|
||||
*
|
||||
* \note all registered commands must print help to the STDOUT & exit with a zero exit-code
|
||||
* when `--help` is passed in as the first argument to a command.
|
||||
*/
|
||||
|
||||
#include "BLI_utility_mixins.hh"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* Each instance of this class can run the command with an argument list.
|
||||
* The arguments begin at the first argument after the command identifier.
|
||||
*/
|
||||
class CommandHandler : blender::NonCopyable, blender::NonMovable {
|
||||
public:
|
||||
CommandHandler(const std::string &id) : id(id) {}
|
||||
virtual ~CommandHandler() = default;
|
||||
|
||||
/** Matched against `--command {id}`. */
|
||||
const std::string id;
|
||||
|
||||
/**
|
||||
* The main execution function.
|
||||
* The return value is used as the commands exit-code.
|
||||
*/
|
||||
virtual int exec(struct bContext *C, int argc, const char **argv) = 0;
|
||||
|
||||
/** True when one or more registered commands share an ID. */
|
||||
bool is_duplicate = false;
|
||||
};
|
||||
/**
|
||||
* \param cmd: The memory for a command type (ownership is transferred).
|
||||
*/
|
||||
void BKE_blender_cli_command_register(std::unique_ptr<CommandHandler> cmd);
|
||||
|
||||
/**
|
||||
* Unregister a previously registered command.
|
||||
*/
|
||||
bool BKE_blender_cli_command_unregister(CommandHandler *cmd);
|
||||
|
||||
/**
|
||||
* Run the command by `id`, passing in the argument list & context.
|
||||
* The argument list must begin after the command identifier.
|
||||
*/
|
||||
int BKE_blender_cli_command_exec(struct bContext *C,
|
||||
const char *id,
|
||||
const int argc,
|
||||
const char **argv);
|
||||
|
||||
/**
|
||||
* Print all known commands (used for passing `--command help` in the command-line).
|
||||
*/
|
||||
void BKE_blender_cli_command_print_help();
|
||||
/**
|
||||
* Frees all commands (using their #CommandFreeFn call-backs).
|
||||
*/
|
||||
void BKE_blender_cli_command_free_all();
|
|
@ -88,8 +88,8 @@ BlendFileData *BKE_blendfile_read(const char *filepath,
|
|||
* \return Blend file data, this must be passed to
|
||||
* #BKE_blendfile_read_setup_readfile/#BKE_blendfile_read_setup_undo when non-NULL.
|
||||
*/
|
||||
BlendFileData *BKE_blendfile_read_from_memory(const void *filebuf,
|
||||
int filelength,
|
||||
BlendFileData *BKE_blendfile_read_from_memory(const void *file_buf,
|
||||
int file_buf_size,
|
||||
const BlendFileReadParams *params,
|
||||
ReportList *reports);
|
||||
|
||||
|
@ -113,8 +113,8 @@ void BKE_blendfile_read_make_empty(bContext *C);
|
|||
* Only read the #UserDef from a .blend.
|
||||
*/
|
||||
UserDef *BKE_blendfile_userdef_read(const char *filepath, ReportList *reports);
|
||||
UserDef *BKE_blendfile_userdef_read_from_memory(const void *filebuf,
|
||||
int filelength,
|
||||
UserDef *BKE_blendfile_userdef_read_from_memory(const void *file_buf,
|
||||
int file_buf_size,
|
||||
ReportList *reports);
|
||||
UserDef *BKE_blendfile_userdef_from_defaults();
|
||||
|
||||
|
@ -135,8 +135,8 @@ bool BKE_blendfile_userdef_write_app_template(const char *filepath, ReportList *
|
|||
bool BKE_blendfile_userdef_write_all(ReportList *reports);
|
||||
|
||||
WorkspaceConfigFileData *BKE_blendfile_workspace_config_read(const char *filepath,
|
||||
const void *filebuf,
|
||||
int filelength,
|
||||
const void *file_buf,
|
||||
int file_buf_size,
|
||||
ReportList *reports);
|
||||
bool BKE_blendfile_workspace_config_write(Main *bmain, const char *filepath, ReportList *reports);
|
||||
void BKE_blendfile_workspace_config_data_free(WorkspaceConfigFileData *workspace_config);
|
||||
|
|
|
@ -173,8 +173,8 @@ struct CameraBGImage *BKE_camera_background_image_new(struct Camera *cam);
|
|||
* \param copy_flag: The usual ID copying flags, see `LIB_ID_CREATE_`/`LIB_ID_COPY_` enums in
|
||||
* `BKE_lib_id.hh`.
|
||||
*/
|
||||
struct CameraBGImage *BKE_camera_background_image_copy(struct CameraBGImage *bgpic_src,
|
||||
const int copy_flag);
|
||||
struct CameraBGImage *BKE_camera_background_image_copy(const struct CameraBGImage *bgpic_src,
|
||||
int copy_flag);
|
||||
void BKE_camera_background_image_remove(struct Camera *cam, struct CameraBGImage *bgpic);
|
||||
void BKE_camera_background_image_clear(struct Camera *cam);
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ struct ClothSolverResult {
|
|||
*
|
||||
* The m and n members of this structure represent the assumed
|
||||
* rectangular ordered grid for which the original paper is written.
|
||||
* At some point they need to disappear and we need to determine out
|
||||
* At some point they need to disappear and we need to determine our
|
||||
* own connectivity of the mesh based on the actual edges in the mesh.
|
||||
*/
|
||||
struct Cloth {
|
||||
|
|
|
@ -20,12 +20,9 @@
|
|||
struct BLI_Iterator;
|
||||
struct Base;
|
||||
struct BlendDataReader;
|
||||
struct BlendLibReader;
|
||||
struct BlendWriter;
|
||||
struct Collection;
|
||||
struct Depsgraph;
|
||||
struct ID;
|
||||
struct Library;
|
||||
struct Main;
|
||||
struct Object;
|
||||
struct Scene;
|
||||
|
@ -276,6 +273,11 @@ bool BKE_collection_cycles_fix(Main *bmain, Collection *collection);
|
|||
|
||||
bool BKE_collection_has_collection(const Collection *parent, const Collection *collection);
|
||||
|
||||
/**
|
||||
* Return parent collection which is not linked.
|
||||
*/
|
||||
Collection *BKE_collection_parent_editable_find_recursive(const ViewLayer *view_layer,
|
||||
Collection *collection);
|
||||
/**
|
||||
* Rebuild parent relationships from child ones, for all children of given \a collection.
|
||||
*
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
*/
|
||||
|
||||
struct BlendDataReader;
|
||||
struct BlendLibReader;
|
||||
struct BlendWriter;
|
||||
struct Depsgraph;
|
||||
struct ID;
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
struct BezTriple;
|
||||
struct BezTriple;
|
||||
struct BMEditMesh;
|
||||
struct BoundBox;
|
||||
struct BPoint;
|
||||
struct Curve;
|
||||
struct Depsgraph;
|
||||
|
|
|
@ -17,7 +17,6 @@ extern "C" {
|
|||
struct Depsgraph;
|
||||
struct Object;
|
||||
struct ReportList;
|
||||
struct Scene;
|
||||
struct SpaceTransform;
|
||||
|
||||
/* Warning, those def are stored in files (TransferData modifier), *DO NOT* modify those values. */
|
||||
|
|
|
@ -21,7 +21,6 @@ struct AnimData;
|
|||
struct AnimationEvalContext;
|
||||
struct BezTriple;
|
||||
struct BlendDataReader;
|
||||
struct BlendLibReader;
|
||||
struct BlendWriter;
|
||||
struct LibraryForeachIDData;
|
||||
struct PathResolvedRNA;
|
||||
|
|
|
@ -16,6 +16,13 @@
|
|||
|
||||
struct Main;
|
||||
|
||||
/**
|
||||
* Global data, typically accessed from #G.
|
||||
* See: #BKE_blender_globals_init & #BKE_blender_globals_clear.
|
||||
*
|
||||
* \note This is run-time only but some global data is written
|
||||
* to #FileGlobal which is used to initialize members of #Global.
|
||||
*/
|
||||
struct Global {
|
||||
|
||||
/**
|
||||
|
@ -58,6 +65,14 @@ struct Global {
|
|||
*/
|
||||
bool background;
|
||||
|
||||
/**
|
||||
* When true, suppress any non-error print messages such as files saves, loaded, quitting etc.
|
||||
* This is used so command line tools can control output without unnecessary noise.
|
||||
*
|
||||
* \note This should only be used to suppress printing (not reports or other kinds of logging).
|
||||
*/
|
||||
bool quiet;
|
||||
|
||||
/**
|
||||
* Skip reading the startup file and user preferences.
|
||||
* Also disable saving the preferences on exit (see #G_FLAG_USERPREF_NO_SAVE_ON_EXIT),
|
||||
|
|
|
@ -16,7 +16,6 @@ extern "C" {
|
|||
|
||||
struct ARegionType;
|
||||
struct BlendDataReader;
|
||||
struct BlendLibReader;
|
||||
struct BlendWriter;
|
||||
struct Depsgraph;
|
||||
struct GpencilModifierData;
|
||||
|
|
|
@ -74,8 +74,6 @@ struct Icon_Geom {
|
|||
|
||||
typedef struct Icon Icon;
|
||||
|
||||
struct BlendDataReader;
|
||||
struct BlendWriter;
|
||||
struct ID;
|
||||
struct ImBuf;
|
||||
struct PreviewImage;
|
||||
|
|
|
@ -16,13 +16,11 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
struct BlendDataReader;
|
||||
struct BlendLibReader;
|
||||
struct BlendWriter;
|
||||
struct ID;
|
||||
struct IDProperty;
|
||||
struct IDPropertyUIData;
|
||||
struct IDPropertyUIDataEnumItem;
|
||||
struct Library;
|
||||
|
||||
typedef union IDPropertyTemplate {
|
||||
int i;
|
||||
|
|
|
@ -273,6 +273,7 @@ extern IDTypeInfo IDType_ID_CV;
|
|||
extern IDTypeInfo IDType_ID_PT;
|
||||
extern IDTypeInfo IDType_ID_VO;
|
||||
extern IDTypeInfo IDType_ID_GP;
|
||||
extern IDTypeInfo IDType_ID_AN;
|
||||
|
||||
/** Empty shell mostly, but needed for read code. */
|
||||
extern IDTypeInfo IDType_ID_LINK_PLACEHOLDER;
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include "BLI_sys_types.h"
|
||||
|
||||
struct BMEditMesh;
|
||||
struct BoundBox;
|
||||
struct BPoint;
|
||||
struct Depsgraph;
|
||||
struct Lattice;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
#include "BLI_compiler_attrs.h"
|
||||
#include "BLI_function_ref.hh"
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_set.hh"
|
||||
#include "BLI_span.hh"
|
||||
|
@ -265,14 +266,14 @@ using IDTypeFilter = uint64_t;
|
|||
namespace blender::bke::id {
|
||||
|
||||
class IDRemapper {
|
||||
blender::Map<ID *, ID *> mappings_;
|
||||
Map<ID *, ID *> mappings_;
|
||||
IDTypeFilter source_types_ = 0;
|
||||
|
||||
/**
|
||||
* Store all IDs using another ID with the 'NEVER_NULL' flag, which have (or
|
||||
* should have been) remapped to `nullptr`.
|
||||
*/
|
||||
blender::Set<ID *> never_null_users_;
|
||||
Set<ID *> never_null_users_;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
@ -282,14 +283,14 @@ class IDRemapper {
|
|||
bool allow_idtype_mismatch = false;
|
||||
|
||||
public:
|
||||
void clear(void)
|
||||
void clear()
|
||||
{
|
||||
mappings_.clear();
|
||||
never_null_users_.clear();
|
||||
source_types_ = 0;
|
||||
}
|
||||
|
||||
bool is_empty(void) const
|
||||
bool is_empty() const
|
||||
{
|
||||
return mappings_.is_empty();
|
||||
}
|
||||
|
@ -326,24 +327,24 @@ class IDRemapper {
|
|||
never_null_users_.add(id);
|
||||
}
|
||||
|
||||
const blender::Set<ID *> &never_null_users(void) const
|
||||
const Set<ID *> &never_null_users() const
|
||||
{
|
||||
return never_null_users_;
|
||||
}
|
||||
|
||||
/** Iterate over all remapping pairs in the remapper, and call the callback function on them. */
|
||||
void iter(IDRemapperIterFunction func, void *user_data) const
|
||||
void iter(FunctionRef<void(ID *old_id, ID *new_id)> func) const
|
||||
{
|
||||
for (auto item : mappings_.items()) {
|
||||
func(item.key, item.value, user_data);
|
||||
func(item.key, item.value);
|
||||
}
|
||||
}
|
||||
|
||||
/** Return a readable string for the given result. Can be used for debugging purposes. */
|
||||
static const blender::StringRefNull result_to_string(const IDRemapperApplyResult result);
|
||||
static const StringRefNull result_to_string(const IDRemapperApplyResult result);
|
||||
|
||||
/** Print out the rules inside the given id_remapper. Can be used for debugging purposes. */
|
||||
void print(void) const;
|
||||
void print() const;
|
||||
};
|
||||
|
||||
} // namespace blender::bke::id
|
||||
|
|
|
@ -210,6 +210,7 @@ struct Main {
|
|||
ListBase collections;
|
||||
ListBase armatures;
|
||||
ListBase actions;
|
||||
ListBase animations;
|
||||
ListBase nodetrees;
|
||||
ListBase brushes;
|
||||
ListBase particles;
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
|
||||
#include "BKE_mesh_mapping.hh"
|
||||
|
||||
struct CustomData;
|
||||
struct CustomData_MeshMasks;
|
||||
struct MemArena;
|
||||
struct Mesh;
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ struct Speaker;
|
|||
struct bAction;
|
||||
|
||||
struct BlendDataReader;
|
||||
struct BlendLibReader;
|
||||
struct BlendWriter;
|
||||
struct PointerRNA;
|
||||
struct PropertyRNA;
|
||||
|
@ -432,11 +431,11 @@ void BKE_nlastrip_validate_name(struct AnimData *adt, struct NlaStrip *strip);
|
|||
/* ............ */
|
||||
|
||||
/**
|
||||
* Check if the given NLA-Track has any strips with own F-Curves.
|
||||
* Check if the given NLA-Track has any strips with their own F-Curves.
|
||||
*/
|
||||
bool BKE_nlatrack_has_animated_strips(struct NlaTrack *nlt);
|
||||
/**
|
||||
* Check if given NLA-Tracks have any strips with own F-Curves.
|
||||
* Check if given NLA-Tracks have any strips with their own F-Curves.
|
||||
*/
|
||||
bool BKE_nlatracks_have_animated_strips(ListBase *tracks);
|
||||
/**
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#define MAX_SOCKET 512
|
||||
|
||||
struct BlendDataReader;
|
||||
struct BlendLibReader;
|
||||
struct BlendWriter;
|
||||
struct FreestyleLineStyle;
|
||||
struct GPUMaterial;
|
||||
|
|
|
@ -30,7 +30,6 @@ struct FieldInferencingInterface;
|
|||
class NodeDeclaration;
|
||||
struct GeometryNodesLazyFunctionGraphInfo;
|
||||
namespace anonymous_attribute_lifetime {
|
||||
struct RelationsInNode;
|
||||
}
|
||||
namespace aal = anonymous_attribute_lifetime;
|
||||
} // namespace blender::nodes
|
||||
|
|
|
@ -336,7 +336,7 @@ void BKE_object_where_is_calc_time(Depsgraph *depsgraph, Scene *scene, Object *o
|
|||
*/
|
||||
void BKE_object_where_is_calc_mat4(Object *ob, float r_obmat[4][4]);
|
||||
|
||||
/* Possibly belong in own module? */
|
||||
/* Possibly belong in its own module? */
|
||||
|
||||
void BKE_boundbox_init_from_minmax(BoundBox *bb, const float min[3], const float max[3]);
|
||||
void BKE_boundbox_minmax(const BoundBox *bb,
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
#include "DNA_customdata_types.h" /* #CustomData_MeshMasks. */
|
||||
|
||||
struct BoundBox;
|
||||
struct bGPdata;
|
||||
struct Curve;
|
||||
struct CurveCache;
|
||||
|
|
|
@ -26,7 +26,6 @@ struct BMFace;
|
|||
struct BMLog;
|
||||
struct BMesh;
|
||||
struct BlendDataReader;
|
||||
struct BlendLibReader;
|
||||
struct BlendWriter;
|
||||
struct Brush;
|
||||
struct CustomDataLayer;
|
||||
|
@ -53,7 +52,6 @@ struct Image;
|
|||
struct ImagePool;
|
||||
struct ImageUser;
|
||||
struct KeyBlock;
|
||||
struct ListBase;
|
||||
struct Main;
|
||||
struct Mesh;
|
||||
struct MDeformVert;
|
||||
|
|
|
@ -225,7 +225,7 @@ struct ARegionType {
|
|||
|
||||
/* register operator types on startup */
|
||||
void (*operatortypes)();
|
||||
/* add own items to keymap */
|
||||
/* add items to keymap */
|
||||
void (*keymap)(wmKeyConfig *keyconf);
|
||||
/* allows default cursor per region */
|
||||
void (*cursor)(wmWindow *win, ScrArea *area, ARegion *region);
|
||||
|
|
|
@ -16,7 +16,6 @@ extern "C" {
|
|||
|
||||
struct ARegionType;
|
||||
struct BlendDataReader;
|
||||
struct BlendLibReader;
|
||||
struct BlendWriter;
|
||||
struct ID;
|
||||
struct ListBase;
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
*/
|
||||
|
||||
struct BVHTree;
|
||||
struct GreasePencilShrinkwrapModifierData;
|
||||
struct MDeformVert;
|
||||
struct Mesh;
|
||||
struct ModifierEvalContext;
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include "BKE_DerivedMesh.hh"
|
||||
|
||||
struct CCGElem;
|
||||
struct CCGFace;
|
||||
struct CCGKey;
|
||||
struct Mesh;
|
||||
struct Subdiv;
|
||||
|
|
|
@ -26,9 +26,7 @@
|
|||
|
||||
struct BlendWriter;
|
||||
struct BlendDataReader;
|
||||
struct BlendLibReader;
|
||||
struct LibraryForeachIDData;
|
||||
struct Library;
|
||||
|
||||
namespace blender::bke::id {
|
||||
class IDRemapper;
|
||||
|
|
|
@ -55,6 +55,7 @@ set(SRC
|
|||
intern/anim_path.cc
|
||||
intern/anim_sys.cc
|
||||
intern/anim_visualization.cc
|
||||
intern/animation.cc
|
||||
intern/anonymous_attribute_id.cc
|
||||
intern/appdir.cc
|
||||
intern/armature.cc
|
||||
|
@ -75,6 +76,7 @@ set(SRC
|
|||
intern/bake_items_serialize.cc
|
||||
intern/bake_items_socket.cc
|
||||
intern/blender.cc
|
||||
intern/blender_cli_command.cc
|
||||
intern/blender_copybuffer.cc
|
||||
intern/blender_undo.cc
|
||||
intern/blender_user_menu.cc
|
||||
|
@ -327,6 +329,7 @@ set(SRC
|
|||
BKE_anim_data.hh
|
||||
BKE_anim_path.h
|
||||
BKE_anim_visualization.h
|
||||
BKE_animation.hh
|
||||
BKE_animsys.h
|
||||
BKE_anonymous_attribute_id.hh
|
||||
BKE_appdir.hh
|
||||
|
@ -343,6 +346,7 @@ set(SRC
|
|||
BKE_bake_items_serialize.hh
|
||||
BKE_bake_items_socket.hh
|
||||
BKE_blender.hh
|
||||
BKE_blender_cli_command.hh
|
||||
BKE_blender_copybuffer.hh
|
||||
BKE_blender_undo.hh
|
||||
BKE_blender_user_menu.hh
|
||||
|
|
|
@ -82,9 +82,6 @@ CCGAllocatorIFC *ccg_getStandardAllocatorIFC(void);
|
|||
* Catmull-Clark Gridding Subdivision Surface.
|
||||
*/
|
||||
|
||||
/* TODO(sergey): Get rid of this, it's more or less a bad level call. */
|
||||
struct DerivedMesh;
|
||||
|
||||
/* ** Data structures, constants. enums ** */
|
||||
|
||||
enum {
|
||||
|
@ -256,8 +253,6 @@ void ccgSubSurf__effectedFaceNeighbors(CCGSubSurf *ss,
|
|||
|
||||
void ccgSubSurf__sync_legacy(CCGSubSurf *ss);
|
||||
|
||||
struct OpenSubdiv_Converter;
|
||||
|
||||
/* `CCGSubSurf_util.cc` */
|
||||
|
||||
#ifdef DUMP_RESULT_GRIDS
|
||||
|
|
|
@ -292,6 +292,7 @@ void BKE_animdata_foreach_id(AnimData *adt, LibraryForeachIDData *data)
|
|||
BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data, BKE_fcurve_foreach_id(fcu, data));
|
||||
}
|
||||
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, adt->animation, IDWALK_CB_USER);
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, adt->action, IDWALK_CB_USER);
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, adt->tmpact, IDWALK_CB_USER);
|
||||
|
||||
|
|
|
@ -0,0 +1,255 @@
|
|||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file Animation data-block.
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_string_utf8.h"
|
||||
|
||||
#include "BLO_read_write.hh"
|
||||
|
||||
#include "BKE_animation.hh"
|
||||
#include "BKE_fcurve.hh"
|
||||
#include "BKE_idtype.hh"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_lib_query.hh"
|
||||
#include "BKE_main.hh"
|
||||
|
||||
#include "ANIM_animation.hh"
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_defaults.h"
|
||||
|
||||
#include "BLT_translation.hh"
|
||||
|
||||
struct BlendWriter;
|
||||
struct BlendDataReader;
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
static void animation_copy_data(Main * /*bmain*/,
|
||||
std::optional<Library *> /*owner_library*/,
|
||||
ID *id_dst,
|
||||
const ID *id_src,
|
||||
const int /*flag*/)
|
||||
{
|
||||
Animation *dna_anim_dst = reinterpret_cast<Animation *>(id_dst);
|
||||
animrig::Animation &anim_dst = dna_anim_dst->wrap();
|
||||
|
||||
const Animation *dna_anim_src = reinterpret_cast<const Animation *>(id_src);
|
||||
const animrig::Animation &anim_src = dna_anim_src->wrap();
|
||||
|
||||
/* Copy all simple properties. */
|
||||
anim_dst.layer_array_num = anim_src.layer_array_num;
|
||||
anim_dst.layer_active_index = anim_src.layer_active_index;
|
||||
anim_dst.binding_array_num = anim_src.binding_array_num;
|
||||
anim_dst.last_binding_handle = anim_src.last_binding_handle;
|
||||
|
||||
/* Layers. */
|
||||
anim_dst.layer_array = MEM_cnew_array<AnimationLayer *>(anim_src.layer_array_num, __func__);
|
||||
for (int i : anim_src.layers().index_range()) {
|
||||
anim_dst.layer_array[i] = MEM_new<animrig::Layer>(__func__, *anim_src.layer(i));
|
||||
}
|
||||
|
||||
/* Bindings. */
|
||||
anim_dst.binding_array = MEM_cnew_array<AnimationBinding *>(anim_src.binding_array_num,
|
||||
__func__);
|
||||
for (int i : anim_src.bindings().index_range()) {
|
||||
anim_dst.binding_array[i] = MEM_new<animrig::Binding>(__func__, *anim_src.binding(i));
|
||||
}
|
||||
}
|
||||
|
||||
/** Free (or release) any data used by this animation (does not free the animation itself). */
|
||||
static void animation_free_data(ID *id)
|
||||
{
|
||||
reinterpret_cast<Animation *>(id)->wrap().free_data();
|
||||
}
|
||||
|
||||
static void animation_foreach_id(ID *id, LibraryForeachIDData *data)
|
||||
{
|
||||
animrig::Animation &anim = reinterpret_cast<Animation *>(id)->wrap();
|
||||
|
||||
for (animrig::Layer *layer : anim.layers()) {
|
||||
for (animrig::Strip *strip : layer->strips()) {
|
||||
switch (strip->type()) {
|
||||
case animrig::Strip::Type::Keyframe: {
|
||||
auto &key_strip = strip->as<animrig::KeyframeStrip>();
|
||||
for (animrig::ChannelBag *channelbag_for_binding : key_strip.channelbags()) {
|
||||
for (FCurve *fcurve : channelbag_for_binding->fcurves()) {
|
||||
BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data, BKE_fcurve_foreach_id(fcurve, data));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void write_channelbag(BlendWriter *writer, animrig::ChannelBag &channelbag)
|
||||
{
|
||||
BLO_write_struct(writer, AnimationChannelBag, &channelbag);
|
||||
|
||||
Span<FCurve *> fcurves = channelbag.fcurves();
|
||||
BLO_write_pointer_array(writer, fcurves.size(), fcurves.data());
|
||||
|
||||
for (FCurve *fcurve : fcurves) {
|
||||
BLO_write_struct(writer, FCurve, fcurve);
|
||||
BKE_fcurve_blend_write_data(writer, fcurve);
|
||||
}
|
||||
}
|
||||
|
||||
static void write_keyframe_strip(BlendWriter *writer, animrig::KeyframeStrip &key_strip)
|
||||
{
|
||||
BLO_write_struct(writer, KeyframeAnimationStrip, &key_strip);
|
||||
|
||||
auto channelbags = key_strip.channelbags();
|
||||
BLO_write_pointer_array(writer, channelbags.size(), channelbags.data());
|
||||
|
||||
for (animrig::ChannelBag *channelbag : channelbags) {
|
||||
write_channelbag(writer, *channelbag);
|
||||
}
|
||||
}
|
||||
|
||||
static void write_strips(BlendWriter *writer, Span<animrig::Strip *> strips)
|
||||
{
|
||||
BLO_write_pointer_array(writer, strips.size(), strips.data());
|
||||
|
||||
for (animrig::Strip *strip : strips) {
|
||||
switch (strip->type()) {
|
||||
case animrig::Strip::Type::Keyframe: {
|
||||
auto &key_strip = strip->as<animrig::KeyframeStrip>();
|
||||
write_keyframe_strip(writer, key_strip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void write_layers(BlendWriter *writer, Span<animrig::Layer *> layers)
|
||||
{
|
||||
BLO_write_pointer_array(writer, layers.size(), layers.data());
|
||||
|
||||
for (animrig::Layer *layer : layers) {
|
||||
BLO_write_struct(writer, AnimationLayer, layer);
|
||||
write_strips(writer, layer->strips());
|
||||
}
|
||||
}
|
||||
|
||||
static void write_bindings(BlendWriter *writer, Span<animrig::Binding *> bindings)
|
||||
{
|
||||
BLO_write_pointer_array(writer, bindings.size(), bindings.data());
|
||||
for (animrig::Binding *binding : bindings) {
|
||||
BLO_write_struct(writer, AnimationBinding, binding);
|
||||
}
|
||||
}
|
||||
|
||||
static void animation_blend_write(BlendWriter *writer, ID *id, const void *id_address)
|
||||
{
|
||||
animrig::Animation &anim = reinterpret_cast<Animation *>(id)->wrap();
|
||||
|
||||
BLO_write_id_struct(writer, Animation, id_address, &anim.id);
|
||||
BKE_id_blend_write(writer, &anim.id);
|
||||
|
||||
write_layers(writer, anim.layers());
|
||||
write_bindings(writer, anim.bindings());
|
||||
}
|
||||
|
||||
static void read_channelbag(BlendDataReader *reader, animrig::ChannelBag &channelbag)
|
||||
{
|
||||
BLO_read_pointer_array(reader, reinterpret_cast<void **>(&channelbag.fcurve_array));
|
||||
|
||||
for (int i = 0; i < channelbag.fcurve_array_num; i++) {
|
||||
BLO_read_data_address(reader, &channelbag.fcurve_array[i]);
|
||||
BKE_fcurve_blend_read_data(reader, channelbag.fcurve_array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void read_keyframe_strip(BlendDataReader *reader, animrig::KeyframeStrip &strip)
|
||||
{
|
||||
BLO_read_pointer_array(reader, reinterpret_cast<void **>(&strip.channelbags_array));
|
||||
|
||||
for (int i = 0; i < strip.channelbags_array_num; i++) {
|
||||
BLO_read_data_address(reader, &strip.channelbags_array[i]);
|
||||
AnimationChannelBag *channelbag = strip.channelbags_array[i];
|
||||
read_channelbag(reader, channelbag->wrap());
|
||||
}
|
||||
}
|
||||
|
||||
static void read_animation_layers(BlendDataReader *reader, animrig::Animation &anim)
|
||||
{
|
||||
BLO_read_pointer_array(reader, reinterpret_cast<void **>(&anim.layer_array));
|
||||
|
||||
for (int layer_idx = 0; layer_idx < anim.layer_array_num; layer_idx++) {
|
||||
BLO_read_data_address(reader, &anim.layer_array[layer_idx]);
|
||||
AnimationLayer *layer = anim.layer_array[layer_idx];
|
||||
|
||||
BLO_read_pointer_array(reader, reinterpret_cast<void **>(&layer->strip_array));
|
||||
for (int strip_idx = 0; strip_idx < layer->strip_array_num; strip_idx++) {
|
||||
BLO_read_data_address(reader, &layer->strip_array[strip_idx]);
|
||||
AnimationStrip *dna_strip = layer->strip_array[strip_idx];
|
||||
animrig::Strip &strip = dna_strip->wrap();
|
||||
|
||||
switch (strip.type()) {
|
||||
case animrig::Strip::Type::Keyframe: {
|
||||
read_keyframe_strip(reader, strip.as<animrig::KeyframeStrip>());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void read_animation_bindings(BlendDataReader *reader, animrig::Animation &anim)
|
||||
{
|
||||
BLO_read_pointer_array(reader, reinterpret_cast<void **>(&anim.binding_array));
|
||||
|
||||
for (int i = 0; i < anim.binding_array_num; i++) {
|
||||
BLO_read_data_address(reader, &anim.binding_array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void animation_blend_read_data(BlendDataReader *reader, ID *id)
|
||||
{
|
||||
animrig::Animation &animation = reinterpret_cast<Animation *>(id)->wrap();
|
||||
read_animation_layers(reader, animation);
|
||||
read_animation_bindings(reader, animation);
|
||||
}
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
IDTypeInfo IDType_ID_AN = {
|
||||
/*id_code*/ ID_AN,
|
||||
/*id_filter*/ FILTER_ID_AN,
|
||||
/*dependencies_id_types*/ 0,
|
||||
/*main_listbase_index*/ INDEX_ID_AN,
|
||||
/*struct_size*/ sizeof(Animation),
|
||||
/*name*/ "Animation",
|
||||
/*name_plural*/ N_("animations"),
|
||||
/*translation_context*/ BLT_I18NCONTEXT_ID_ANIMATION,
|
||||
/*flags*/ IDTYPE_FLAGS_NO_ANIMDATA,
|
||||
/*asset_type_info*/ nullptr,
|
||||
|
||||
/*init_data*/ nullptr,
|
||||
/*copy_data*/ blender::bke::animation_copy_data,
|
||||
/*free_data*/ blender::bke::animation_free_data,
|
||||
/*make_local*/ nullptr,
|
||||
/*foreach_id*/ blender::bke::animation_foreach_id,
|
||||
/*foreach_cache*/ nullptr,
|
||||
/*foreach_path*/ nullptr,
|
||||
/*owner_pointer_get*/ nullptr,
|
||||
|
||||
/*blend_write*/ blender::bke::animation_blend_write,
|
||||
/*blend_read_data*/ blender::bke::animation_blend_read_data,
|
||||
/*blend_read_after_liblink*/ nullptr,
|
||||
|
||||
/*blend_read_undo_preserve*/ nullptr,
|
||||
|
||||
/*lib_override_apply_post*/ nullptr,
|
||||
};
|
||||
|
||||
Animation *BKE_animation_add(Main *bmain, const char name[])
|
||||
{
|
||||
Animation *anim = static_cast<Animation *>(BKE_id_new(bmain, ID_AN, name));
|
||||
return anim;
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup bke
|
||||
*
|
||||
* Generic CLI "--command" declarations.
|
||||
*
|
||||
* Duplicate Commands
|
||||
* ==================
|
||||
*
|
||||
* When two or more commands share the same identifier, a warning is printed and both are disabled.
|
||||
*
|
||||
* This is done because command-line actions may be destructive so the down-side of running the
|
||||
* wrong command could be severe. The reason this is not considered an error is we can't prevent
|
||||
* it so easily, unlike operator ID's which may be longer, commands are typically short terms
|
||||
* which wont necessarily include an add-ons identifier as a prefix for e.g.
|
||||
* Further, an error would break loading add-ons who's primary is *not*
|
||||
* necessarily to provide command-line access.
|
||||
* An alternative solution could be to generate unique names (number them for example)
|
||||
* but this isn't reliable as it would depend on it the order add-ons are loaded which
|
||||
* isn't under user control.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "BKE_blender_cli_command.hh" /* own include */
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Internal API
|
||||
* \{ */
|
||||
|
||||
using CommandHandlerPtr = std::unique_ptr<CommandHandler>;
|
||||
|
||||
/**
|
||||
* All registered command handlers.
|
||||
* \note the order doesn't matter as duplicates are detected and prevented from running.
|
||||
*/
|
||||
blender::Vector<CommandHandlerPtr> g_command_handlers;
|
||||
|
||||
static CommandHandler *blender_cli_command_lookup(const std::string &id)
|
||||
{
|
||||
for (CommandHandlerPtr &cmd_iter : g_command_handlers) {
|
||||
if (id == cmd_iter->id) {
|
||||
return cmd_iter.get();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static int blender_cli_command_index(const CommandHandler *cmd)
|
||||
{
|
||||
int index = 0;
|
||||
for (CommandHandlerPtr &cmd_iter : g_command_handlers) {
|
||||
if (cmd_iter.get() == cmd) {
|
||||
return index;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Public API
|
||||
* \{ */
|
||||
|
||||
void BKE_blender_cli_command_register(std::unique_ptr<CommandHandler> cmd)
|
||||
{
|
||||
bool is_duplicate = false;
|
||||
if (CommandHandler *cmd_exists = blender_cli_command_lookup(cmd->id)) {
|
||||
std::cerr << "warning: registered duplicate command \"" << cmd->id
|
||||
<< "\", this will be inaccessible" << std::endl;
|
||||
cmd_exists->is_duplicate = true;
|
||||
is_duplicate = true;
|
||||
}
|
||||
cmd->is_duplicate = is_duplicate;
|
||||
g_command_handlers.append(std::move(cmd));
|
||||
}
|
||||
|
||||
bool BKE_blender_cli_command_unregister(CommandHandler *cmd)
|
||||
{
|
||||
const int cmd_index = blender_cli_command_index(cmd);
|
||||
if (cmd_index == -1) {
|
||||
std::cerr << "failed to unregister command handler" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Update duplicates after removal. */
|
||||
if (cmd->is_duplicate) {
|
||||
CommandHandler *cmd_other = nullptr;
|
||||
for (CommandHandlerPtr &cmd_iter : g_command_handlers) {
|
||||
/* Skip self. */
|
||||
if (cmd == cmd_iter.get()) {
|
||||
continue;
|
||||
}
|
||||
if (cmd_iter->is_duplicate && (cmd_iter->id == cmd->id)) {
|
||||
if (cmd_other) {
|
||||
/* Two or more found, clear and break. */
|
||||
cmd_other = nullptr;
|
||||
break;
|
||||
}
|
||||
cmd_other = cmd_iter.get();
|
||||
}
|
||||
}
|
||||
if (cmd_other) {
|
||||
cmd_other->is_duplicate = false;
|
||||
}
|
||||
}
|
||||
|
||||
g_command_handlers.remove_and_reorder(cmd_index);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int BKE_blender_cli_command_exec(bContext *C, const char *id, const int argc, const char **argv)
|
||||
{
|
||||
CommandHandler *cmd = blender_cli_command_lookup(id);
|
||||
if (cmd == nullptr) {
|
||||
std::cerr << "Unrecognized command: \"" << id << "\"" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (cmd->is_duplicate) {
|
||||
std::cerr << "Command: \"" << id
|
||||
<< "\" was registered multiple times, must be resolved, aborting!" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return cmd->exec(C, argc, argv);
|
||||
}
|
||||
|
||||
void BKE_blender_cli_command_print_help()
|
||||
{
|
||||
/* As this is isn't ordered sorting in-place is acceptable,
|
||||
* sort alphabetically for display purposes only. */
|
||||
std::sort(g_command_handlers.begin(),
|
||||
g_command_handlers.end(),
|
||||
[](const CommandHandlerPtr &a, const CommandHandlerPtr &b) { return a->id < b->id; });
|
||||
|
||||
for (int pass = 0; pass < 2; pass++) {
|
||||
std::cout << ((pass == 0) ? "Blender Command Listing:" :
|
||||
"Duplicate Command Listing (ignored):")
|
||||
<< std::endl;
|
||||
|
||||
const bool is_duplicate = pass > 0;
|
||||
bool found = false;
|
||||
bool has_duplicate = false;
|
||||
for (CommandHandlerPtr &cmd_iter : g_command_handlers) {
|
||||
if (cmd_iter->is_duplicate) {
|
||||
has_duplicate = true;
|
||||
}
|
||||
if (cmd_iter->is_duplicate != is_duplicate) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::cout << "\t" << cmd_iter->id << std::endl;
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
std::cout << "\tNone found" << std::endl;
|
||||
}
|
||||
/* Don't print that no duplicates are found as it's not helpful. */
|
||||
if (pass == 0 && !has_duplicate) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_blender_cli_command_free_all()
|
||||
{
|
||||
g_command_handlers.clear();
|
||||
}
|
||||
|
||||
/** \} */
|
|
@ -1046,7 +1046,9 @@ BlendFileData *BKE_blendfile_read(const char *filepath,
|
|||
{
|
||||
/* Don't print startup file loading. */
|
||||
if (params->is_startup == false) {
|
||||
printf("Read blend: \"%s\"\n", filepath);
|
||||
if (!G.quiet) {
|
||||
printf("Read blend: \"%s\"\n", filepath);
|
||||
}
|
||||
}
|
||||
|
||||
BlendFileData *bfd = BLO_read_from_file(filepath, eBLOReadSkip(params->skip_flags), reports);
|
||||
|
@ -1063,13 +1065,13 @@ BlendFileData *BKE_blendfile_read(const char *filepath,
|
|||
return bfd;
|
||||
}
|
||||
|
||||
BlendFileData *BKE_blendfile_read_from_memory(const void *filebuf,
|
||||
int filelength,
|
||||
BlendFileData *BKE_blendfile_read_from_memory(const void *file_buf,
|
||||
int file_buf_size,
|
||||
const BlendFileReadParams *params,
|
||||
ReportList *reports)
|
||||
{
|
||||
BlendFileData *bfd = BLO_read_from_memory(
|
||||
filebuf, filelength, eBLOReadSkip(params->skip_flags), reports);
|
||||
file_buf, file_buf_size, eBLOReadSkip(params->skip_flags), reports);
|
||||
if (bfd && bfd->main->is_read_invalid) {
|
||||
BLO_blendfiledata_free(bfd);
|
||||
bfd = nullptr;
|
||||
|
@ -1167,15 +1169,15 @@ UserDef *BKE_blendfile_userdef_read(const char *filepath, ReportList *reports)
|
|||
return userdef;
|
||||
}
|
||||
|
||||
UserDef *BKE_blendfile_userdef_read_from_memory(const void *filebuf,
|
||||
int filelength,
|
||||
UserDef *BKE_blendfile_userdef_read_from_memory(const void *file_buf,
|
||||
int file_buf_size,
|
||||
ReportList *reports)
|
||||
{
|
||||
BlendFileData *bfd;
|
||||
UserDef *userdef = nullptr;
|
||||
|
||||
bfd = BLO_read_from_memory(
|
||||
filebuf, filelength, BLO_READ_SKIP_ALL & ~BLO_READ_SKIP_USERDEF, reports);
|
||||
file_buf, file_buf_size, BLO_READ_SKIP_ALL & ~BLO_READ_SKIP_USERDEF, reports);
|
||||
if (bfd) {
|
||||
if (bfd->user) {
|
||||
userdef = bfd->user;
|
||||
|
@ -1332,12 +1334,18 @@ bool BKE_blendfile_userdef_write_all(ReportList *reports)
|
|||
/* Also save app-template preferences. */
|
||||
BLI_path_join(filepath, sizeof(filepath), cfgdir->c_str(), BLENDER_USERPREF_FILE);
|
||||
|
||||
printf("Writing userprefs app-template: \"%s\" ", filepath);
|
||||
if (!G.quiet) {
|
||||
printf("Writing userprefs app-template: \"%s\" ", filepath);
|
||||
}
|
||||
if (BKE_blendfile_userdef_write(filepath, reports) != 0) {
|
||||
printf("ok\n");
|
||||
if (!G.quiet) {
|
||||
printf("ok\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("fail\n");
|
||||
if (!G.quiet) {
|
||||
printf("fail\n");
|
||||
}
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
|
@ -1360,8 +1368,8 @@ bool BKE_blendfile_userdef_write_all(ReportList *reports)
|
|||
* \{ */
|
||||
|
||||
WorkspaceConfigFileData *BKE_blendfile_workspace_config_read(const char *filepath,
|
||||
const void *filebuf,
|
||||
int filelength,
|
||||
const void *file_buf,
|
||||
int file_buf_size,
|
||||
ReportList *reports)
|
||||
{
|
||||
BlendFileData *bfd;
|
||||
|
@ -1373,7 +1381,7 @@ WorkspaceConfigFileData *BKE_blendfile_workspace_config_read(const char *filepat
|
|||
bfd = BLO_read_from_file(filepath, BLO_READ_SKIP_USERDEF, &blend_file_read_reports);
|
||||
}
|
||||
else {
|
||||
bfd = BLO_read_from_memory(filebuf, filelength, BLO_READ_SKIP_USERDEF, reports);
|
||||
bfd = BLO_read_from_memory(file_buf, file_buf_size, BLO_READ_SKIP_USERDEF, reports);
|
||||
}
|
||||
|
||||
if (bfd) {
|
||||
|
|
|
@ -520,11 +520,13 @@ static void loose_data_instantiate_ensure_active_collection(
|
|||
Scene *scene = instantiate_context->lapp_context->params->context.scene;
|
||||
ViewLayer *view_layer = instantiate_context->lapp_context->params->context.view_layer;
|
||||
|
||||
/* Find or add collection as needed. */
|
||||
/* Find or add collection as needed. When `active_collection` is non-null, it is assumed to be
|
||||
* editable. */
|
||||
if (instantiate_context->active_collection == nullptr) {
|
||||
if (lapp_context->params->flag & FILE_ACTIVE_COLLECTION) {
|
||||
LayerCollection *lc = BKE_layer_collection_get_active(view_layer);
|
||||
instantiate_context->active_collection = lc->collection;
|
||||
instantiate_context->active_collection = BKE_collection_parent_editable_find_recursive(
|
||||
view_layer, lc->collection);
|
||||
}
|
||||
else {
|
||||
if (lapp_context->params->flag & FILE_LINK) {
|
||||
|
|
|
@ -282,7 +282,7 @@ static bool rule_avoid_collision(BoidRule *rule,
|
|||
}
|
||||
}
|
||||
|
||||
/* Check boids in own system. */
|
||||
/* Check boids in their own system. */
|
||||
if (acbr->options & BRULE_ACOLL_WITH_BOIDS) {
|
||||
neighbors = BLI_kdtree_3d_range_search_with_len_squared_cb(bbd->sim->psys->tree,
|
||||
pa->prev_state.co,
|
||||
|
@ -690,7 +690,7 @@ static bool rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Part
|
|||
int n;
|
||||
bool ret = false;
|
||||
|
||||
/* calculate own group strength */
|
||||
/* calculate its own group strength */
|
||||
int neighbors = BLI_kdtree_3d_range_search(
|
||||
bbd->sim->psys->tree, pa->prev_state.co, &ptn, fbr->distance);
|
||||
for (n = 0; n < neighbors; n++) {
|
||||
|
|
|
@ -78,7 +78,7 @@ static void camera_copy_data(Main * /*bmain*/,
|
|||
Camera *cam_dst = (Camera *)id_dst;
|
||||
const Camera *cam_src = (const Camera *)id_src;
|
||||
|
||||
/* We never handle user-count here for own data. */
|
||||
/* We never handle user-count here for owned data. */
|
||||
const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
|
||||
|
||||
BLI_listbase_clear(&cam_dst->bg_images);
|
||||
|
@ -278,7 +278,7 @@ void *BKE_camera_add(Main *bmain, const char *name)
|
|||
|
||||
float BKE_camera_object_dof_distance(const Object *ob)
|
||||
{
|
||||
Camera *cam = (Camera *)ob->data;
|
||||
const Camera *cam = (const Camera *)ob->data;
|
||||
if (ob->type != OB_CAMERA) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
@ -355,7 +355,7 @@ void BKE_camera_params_from_object(CameraParams *params, const Object *cam_ob)
|
|||
|
||||
if (cam_ob->type == OB_CAMERA) {
|
||||
/* camera object */
|
||||
Camera *cam = static_cast<Camera *>(cam_ob->data);
|
||||
const Camera *cam = static_cast<const Camera *>(cam_ob->data);
|
||||
|
||||
if (cam->type == CAM_ORTHO) {
|
||||
params->is_ortho = true;
|
||||
|
@ -899,7 +899,7 @@ static void camera_stereo3d_model_matrix(const Object *camera,
|
|||
const bool is_left,
|
||||
float r_modelmat[4][4])
|
||||
{
|
||||
Camera *data = (Camera *)camera->data;
|
||||
const Camera *data = (const Camera *)camera->data;
|
||||
float interocular_distance, convergence_distance;
|
||||
short convergence_mode, pivot;
|
||||
float sizemat[4][4];
|
||||
|
@ -1060,7 +1060,6 @@ void BKE_camera_multiview_window_matrix(const RenderData *rd,
|
|||
|
||||
bool BKE_camera_multiview_spherical_stereo(const RenderData *rd, const Object *camera)
|
||||
{
|
||||
Camera *cam;
|
||||
const bool is_multiview = (rd && rd->scemode & R_MULTIVIEW) != 0;
|
||||
|
||||
if (!is_multiview) {
|
||||
|
@ -1071,7 +1070,7 @@ bool BKE_camera_multiview_spherical_stereo(const RenderData *rd, const Object *c
|
|||
return false;
|
||||
}
|
||||
|
||||
cam = static_cast<Camera *>(camera->data);
|
||||
const Camera *cam = static_cast<const Camera *>(camera->data);
|
||||
|
||||
if ((rd->views_format == SCE_VIEWS_FORMAT_STEREO_3D) && ELEM(cam->type, CAM_PANO, CAM_PERSP) &&
|
||||
((cam->stereo.flag & CAM_S3D_SPHERICAL) != 0))
|
||||
|
@ -1132,7 +1131,7 @@ Object *BKE_camera_multiview_render(const Scene *scene, Object *camera, const ch
|
|||
|
||||
static float camera_stereo3d_shift_x(const Object *camera, const char *viewname)
|
||||
{
|
||||
Camera *data = static_cast<Camera *>(camera->data);
|
||||
const Camera *data = static_cast<const Camera *>(camera->data);
|
||||
float shift = data->shiftx;
|
||||
float interocular_distance, convergence_distance;
|
||||
short convergence_mode, pivot;
|
||||
|
@ -1174,7 +1173,7 @@ float BKE_camera_multiview_shift_x(const RenderData *rd,
|
|||
const char *viewname)
|
||||
{
|
||||
const bool is_multiview = (rd && rd->scemode & R_MULTIVIEW) != 0;
|
||||
Camera *data = static_cast<Camera *>(camera->data);
|
||||
const Camera *data = static_cast<const Camera *>(camera->data);
|
||||
|
||||
BLI_assert(camera->type == OB_CAMERA);
|
||||
|
||||
|
@ -1222,7 +1221,7 @@ CameraBGImage *BKE_camera_background_image_new(Camera *cam)
|
|||
return bgpic;
|
||||
}
|
||||
|
||||
CameraBGImage *BKE_camera_background_image_copy(CameraBGImage *bgpic_src, const int flag)
|
||||
CameraBGImage *BKE_camera_background_image_copy(const CameraBGImage *bgpic_src, const int flag)
|
||||
{
|
||||
CameraBGImage *bgpic_dst = static_cast<CameraBGImage *>(MEM_dupallocN(bgpic_src));
|
||||
|
||||
|
|
|
@ -1239,8 +1239,8 @@ static void collection_gobject_assert_internal_consistency(Collection *collectio
|
|||
}
|
||||
}
|
||||
|
||||
static Collection *collection_parent_editable_find_recursive(const ViewLayer *view_layer,
|
||||
Collection *collection)
|
||||
Collection *BKE_collection_parent_editable_find_recursive(const ViewLayer *view_layer,
|
||||
Collection *collection)
|
||||
{
|
||||
if (!ID_IS_LINKED(collection) && !ID_IS_OVERRIDE_LIBRARY(collection) &&
|
||||
(view_layer == nullptr || BKE_view_layer_has_collection(view_layer, collection)))
|
||||
|
@ -1265,7 +1265,7 @@ static Collection *collection_parent_editable_find_recursive(const ViewLayer *vi
|
|||
}
|
||||
return collection_parent->collection;
|
||||
}
|
||||
Collection *editable_collection = collection_parent_editable_find_recursive(
|
||||
Collection *editable_collection = BKE_collection_parent_editable_find_recursive(
|
||||
view_layer, collection_parent->collection);
|
||||
if (editable_collection != nullptr) {
|
||||
return editable_collection;
|
||||
|
@ -1393,7 +1393,7 @@ bool BKE_collection_viewlayer_object_add(Main *bmain,
|
|||
return false;
|
||||
}
|
||||
|
||||
collection = collection_parent_editable_find_recursive(view_layer, collection);
|
||||
collection = BKE_collection_parent_editable_find_recursive(view_layer, collection);
|
||||
|
||||
if (collection == nullptr) {
|
||||
return false;
|
||||
|
|
|
@ -474,7 +474,7 @@ static void build_mesh_positions(const CurvesInfo &curves_info,
|
|||
}
|
||||
const Span<float3> tangents = curves_info.main.evaluated_tangents();
|
||||
const Span<float3> normals = curves_info.main.evaluated_normals();
|
||||
Span<float> radii_eval = {};
|
||||
Span<float> radii_eval;
|
||||
if (const GVArray radii = *curves_info.main.attributes().lookup("radius", AttrDomain::Point)) {
|
||||
radii_eval = evaluate_attribute(radii, curves_info.main, eval_buffer).typed<float>();
|
||||
}
|
||||
|
|
|
@ -717,6 +717,13 @@ static ModifierData &legacy_object_modifier_common(Object &object,
|
|||
/* Convert animation data if needed. */
|
||||
AnimData *anim_data = BKE_animdata_from_id(&object.id);
|
||||
if (anim_data) {
|
||||
char legacy_name_esc[MAX_NAME * 2];
|
||||
BLI_str_escape(legacy_name_esc, legacy_md.name, sizeof(legacy_name_esc));
|
||||
const std::string legacy_root_path = fmt::format("grease_pencil_modifiers[\"{}\"]",
|
||||
legacy_name_esc);
|
||||
char new_name_esc[MAX_NAME * 2];
|
||||
BLI_str_escape(new_name_esc, new_md.name, sizeof(new_name_esc));
|
||||
|
||||
auto modifier_path_update = [&](FCurve *fcurve) -> bool {
|
||||
/* NOTE: This logic will likely need to be re-used in other similar conditions for other
|
||||
* areas, should be put into its own util then. */
|
||||
|
@ -724,15 +731,9 @@ static ModifierData &legacy_object_modifier_common(Object &object,
|
|||
return false;
|
||||
}
|
||||
StringRefNull rna_path = fcurve->rna_path;
|
||||
char legacy_name_esc[MAX_NAME * 2];
|
||||
BLI_str_escape(legacy_name_esc, legacy_md.name, sizeof(legacy_name_esc));
|
||||
const std::string legacy_root_path = fmt::format("grease_pencil_modifiers[\"{}\"]",
|
||||
legacy_name_esc);
|
||||
if (!rna_path.startswith(legacy_root_path)) {
|
||||
return false;
|
||||
}
|
||||
char new_name_esc[MAX_NAME * 2];
|
||||
BLI_str_escape(new_name_esc, new_md.name, sizeof(new_name_esc));
|
||||
const std::string new_rna_path = fmt::format(
|
||||
"modifiers[\"{}\"]{}", new_name_esc, rna_path.substr(int64_t(legacy_root_path.size())));
|
||||
MEM_freeN(fcurve->rna_path);
|
||||
|
|
|
@ -83,6 +83,7 @@ static void id_type_init()
|
|||
INIT_TYPE(ID_GR);
|
||||
INIT_TYPE(ID_AR);
|
||||
INIT_TYPE(ID_AC);
|
||||
INIT_TYPE(ID_AN);
|
||||
INIT_TYPE(ID_NT);
|
||||
INIT_TYPE(ID_BR);
|
||||
INIT_TYPE(ID_PA);
|
||||
|
@ -225,6 +226,7 @@ int BKE_idtype_idcode_to_index(const short idcode)
|
|||
|
||||
switch ((ID_Type)idcode) {
|
||||
CASE_IDINDEX(AC);
|
||||
CASE_IDINDEX(AN);
|
||||
CASE_IDINDEX(AR);
|
||||
CASE_IDINDEX(BR);
|
||||
CASE_IDINDEX(CA);
|
||||
|
@ -284,6 +286,7 @@ int BKE_idtype_idfilter_to_index(const uint64_t id_filter)
|
|||
|
||||
switch (id_filter) {
|
||||
CASE_IDINDEX(AC);
|
||||
CASE_IDINDEX(AN);
|
||||
CASE_IDINDEX(AR);
|
||||
CASE_IDINDEX(BR);
|
||||
CASE_IDINDEX(CA);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue