From 61050f75b13ef706d3a80b86137436d3fb0bfa93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dietrich?= Date: Sat, 6 Aug 2016 06:20:37 +0200 Subject: Basic Alembic support All in all, this patch adds an Alembic importer, an Alembic exporter, and a new CacheFile data block which, for now, wraps around an Alembic archive. This data block is made available through a new modifier ("Mesh Sequence Cache") as well as a new constraint ("Transform Cache") to somewhat properly support respectively geometric and transformation data streaming from alembic caches. A more in-depth documentation is to be found on the wiki, as well as a guide to compile alembic: https://wiki.blender.org/index.php/ User:Kevindietrich/AlembicBasicIo. Many thanks to everyone involved in this little project, and huge shout out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the custom builds and compile fixes. Reviewers: sergey, campbellbarton, mont29 Reviewed By: sergey, campbellbarton, mont29 Differential Revision: https://developer.blender.org/D2060 --- build_files/build_environment/install_deps.sh | 187 +++++++++++++++++++++++++- build_files/cmake/Modules/FindAlembic.cmake | 70 ++++++++++ build_files/cmake/Modules/FindHDF5.cmake | 69 ++++++++++ build_files/cmake/config/blender_full.cmake | 1 + build_files/cmake/config/blender_lite.cmake | 1 + build_files/cmake/config/bpy_module.cmake | 1 + build_files/cmake/macros.cmake | 9 ++ 7 files changed, 331 insertions(+), 7 deletions(-) create mode 100644 build_files/cmake/Modules/FindAlembic.cmake create mode 100644 build_files/cmake/Modules/FindHDF5.cmake (limited to 'build_files') diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index 068ac665623..7230fc47105 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -29,13 +29,13 @@ getopt \ ver-ocio:,ver-oiio:,ver-llvm:,ver-osl:,ver-osd:,ver-openvdb:,\ force-all,force-python,force-numpy,force-boost,\ force-ocio,force-openexr,force-oiio,force-llvm,force-osl,force-osd,force-openvdb,\ -force-ffmpeg,force-opencollada,\ +force-ffmpeg,force-opencollada,force-alembic,\ build-all,build-python,build-numpy,build-boost,\ build-ocio,build-openexr,build-oiio,build-llvm,build-osl,build-osd,build-openvdb,\ -build-ffmpeg,build-opencollada,\ +build-ffmpeg,build-opencollada,build-alembic,\ skip-python,skip-numpy,skip-boost,\ skip-ocio,skip-openexr,skip-oiio,skip-llvm,skip-osl,skip-osd,skip-openvdb,\ -skip-ffmpeg,skip-opencollada \ +skip-ffmpeg,skip-opencollada,skip-alembic \ -- "$@" \ ) @@ -167,6 +167,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS: --build-openvdb Force the build of OpenVDB. + --build-alembic + Force the build of Alembic. + --build-opencollada Force the build of OpenCOLLADA. @@ -216,6 +219,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS: --force-openvdb Force the rebuild of OpenVDB. + --force-alembic + Force the rebuild of Alembic. + --force-opencollada Force the rebuild of OpenCOLLADA. @@ -258,6 +264,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS: --skip-openvdb Unconditionally skip OpenVDB installation/building. + --skip-alembic + Unconditionally skip Alembic installation/building. + --skip-opencollada Unconditionally skip OpenCOLLADA installation/building. @@ -343,6 +352,13 @@ OPENVDB_FORCE_BUILD=false OPENVDB_FORCE_REBUILD=false OPENVDB_SKIP=false +# Alembic needs to be compiled for now +ALEMBIC_VERSION="1.6.0" +ALEMBIC_VERSION_MIN=$ALEMBIC_VERSION +ALEMBIC_FORCE_BUILD=false +ALEMBIC_FORCE_REBUILD=false +ALEMBIC_SKIP=false + # Version?? OPENCOLLADA_VERSION="1.3" OPENCOLLADA_FORCE_BUILD=false @@ -525,6 +541,7 @@ while true; do OPENVDB_FORCE_BUILD=true OPENCOLLADA_FORCE_BUILD=true FFMPEG_FORCE_BUILD=true + ALEMBIC_FORCE_BUILD=true shift; continue ;; --build-python) @@ -567,6 +584,9 @@ while true; do --build-ffmpeg) FFMPEG_FORCE_BUILD=true; shift; continue ;; + --build-alembic) + ALEMBIC_FORCE_BUILD=true; shift; continue + ;; --force-all) PYTHON_FORCE_REBUILD=true NUMPY_FORCE_REBUILD=true @@ -580,6 +600,7 @@ while true; do OPENVDB_FORCE_REBUILD=true OPENCOLLADA_FORCE_REBUILD=true FFMPEG_FORCE_REBUILD=true + ALEMBIC_FORCE_REBUILD=true shift; continue ;; --force-python) @@ -620,6 +641,9 @@ while true; do --force-ffmpeg) FFMPEG_FORCE_REBUILD=true; shift; continue ;; + --force-alembic) + ALEMBIC_FORCE_REBUILD=true; shift; continue + ;; --skip-python) PYTHON_SKIP=true; shift; continue ;; @@ -656,6 +680,9 @@ while true; do --skip-ffmpeg) FFMPEG_SKIP=true; shift; continue ;; + --skip-alembic) + ALEMBIC_SKIP=true; shift; continue + ;; --) # no more arguments to parse break @@ -683,7 +710,7 @@ NUMPY_SOURCE=( "http://sourceforge.net/projects/numpy/files/NumPy/$NUMPY_VERSION _boost_version_nodots=`echo "$BOOST_VERSION" | sed -r 's/\./_/g'` BOOST_SOURCE=( "http://sourceforge.net/projects/boost/files/boost/$BOOST_VERSION/boost_$_boost_version_nodots.tar.bz2/download" ) -BOOST_BUILD_MODULES="--with-system --with-filesystem --with-thread --with-regex --with-locale --with-date_time --with-wave --with-iostreams" +BOOST_BUILD_MODULES="--with-system --with-filesystem --with-thread --with-regex --with-locale --with-date_time --with-wave --with-iostreams --with-python --with-program_options" OCIO_SOURCE=( "https://github.com/imageworks/OpenColorIO/tarball/v$OCIO_VERSION" ) @@ -727,6 +754,12 @@ OPENVDB_SOURCE=( "https://github.com/dreamworksanimation/openvdb/archive/v${OPEN #~ OPENVDB_SOURCE_REPO_UID="404659fffa659da075d1c9416e4fc939139a84ee" #~ OPENVDB_SOURCE_REPO_BRANCH="dev" +ALEMBIC_USE_REPO=false +ALEMBIC_SOURCE=( "https://github.com/alembic/alembic/archive/${ALEMBIC_VERSION}.tar.gz" ) +# ALEMBIC_SOURCE_REPO=( "https://github.com/alembic/alembic.git" ) +# ALEMBIC_SOURCE_REPO_UID="e6c90d4faa32c4550adeaaf3f556dad4b73a92bb" +# ALEMBIC_SOURCE_REPO_BRANCH="master" + OPENCOLLADA_SOURCE=( "https://github.com/KhronosGroup/OpenCOLLADA.git" ) OPENCOLLADA_REPO_UID="3335ac164e68b2512a40914b14c74db260e6ff7d" OPENCOLLADA_REPO_BRANCH="master" @@ -767,7 +800,8 @@ You may also want to build them yourself (optional ones are [between brackets]): * [OpenShadingLanguage $OSL_VERSION_MIN] (from $OSL_SOURCE_REPO, branch $OSL_SOURCE_REPO_BRANCH, commit $OSL_SOURCE_REPO_UID). * [OpenSubDiv $OSD_VERSION_MIN] (from $OSD_SOURCE_REPO, branch $OSD_SOURCE_REPO_BRANCH, commit $OSD_SOURCE_REPO_UID). * [OpenVDB $OPENVDB_VERSION_MIN] (from $OPENVDB_SOURCE), [Blosc $OPENVDB_BLOSC_VERSION] (from $OPENVDB_BLOSC_SOURCE). - * [OpenCollada] (from $OPENCOLLADA_SOURCE, branch $OPENCOLLADA_REPO_BRANCH, commit $OPENCOLLADA_REPO_UID).\"" + * [OpenCollada] (from $OPENCOLLADA_SOURCE, branch $OPENCOLLADA_REPO_BRANCH, commit $OPENCOLLADA_REPO_UID). + * [Alembic $ALEMBIC_VERSION] (from $ALEMBIC_SOURCE).\"" if [ "$DO_SHOW_DEPS" = true ]; then PRINT "" @@ -1118,7 +1152,7 @@ compile_Boost() { fi # To be changed each time we make edits that would modify the compiled result! - boost_magic=10 + boost_magic=11 _init_boost @@ -2138,6 +2172,102 @@ compile_OPENVDB() { run_ldconfig "openvdb" } +#### Build Alembic #### +_init_alembic() { + _src=$SRC/alembic-$ALEMBIC_VERSION + _git=false + _inst=$INST/alembic-$ALEMBIC_VERSION + _inst_shortcut=$INST/alembic +} + +clean_ALEMBIC() { + _init_alembic + _clean +} + +compile_ALEMBIC() { + if [ "$NO_BUILD" = true ]; then + WARNING "--no-build enabled, Alembic will not be compiled!" + return + fi + + compile_HDF5 + PRINT "" + + # To be changed each time we make edits that would modify the compiled result! + alembic_magic=2 + _init_alembic + + # Clean install if needed! + magic_compile_check alembic-$ALEMBIC_VERSION $alembic_magic + if [ $? -eq 1 -o "$ALEMBIC_FORCE_REBUILD" = true ]; then + clean_ALEMBIC + fi + + if [ ! -d $_inst ]; then + INFO "Building Alembic-$ALEMBIC_VERSION" + + prepare_opt + + if [ ! -d $_src -o true ]; then + mkdir -p $SRC + download ALEMBIC_SOURCE[@] "$_src.tar.gz" + + INFO "Unpacking Alembic-$ALEMBIC_VERSION" + tar -C $SRC -xf $_src.tar.gz + fi + + cd $_src + + cmake_d="-D CMAKE_INSTALL_PREFIX=$_inst" + + if [ -d $INST/boost ]; then + cmake_d="$cmake_d -D BOOST_ROOT=$INST/boost" + cmake_d="$cmake_d -D USE_STATIC_BOOST=ON" + else + cmake_d="$cmake_d -D USE_STATIC_BOOST=OFF" + fi + + if [ "$_with_built_openexr" = true ]; then + cmake_d="$cmake_d -D ILMBASE_ROOT=$INST/openexr" + cmake_d="$cmake_d -D USE_ARNOLD=OFF" + cmake_d="$cmake_d -D USE_BINARIES=OFF" + cmake_d="$cmake_d -D USE_EXAMPLES=OFF" + cmake_d="$cmake_d -D USE_HDF5=OFF" + cmake_d="$cmake_d -D USE_MAYA=OFF" + cmake_d="$cmake_d -D USE_PRMAN=OFF" + cmake_d="$cmake_d -D USE_PYALEMBIC=OFF" + cmake_d="$cmake_d -D USE_STATIC_HDF5=OFF" + cmake_d="$cmake_d -D ALEMBIC_ILMBASE_LINK_STATIC=OFF" + cmake_d="$cmake_d -D ALEMBIC_SHARED_LIBS=OFF" + cmake_d="$cmake_d -D ALEMBIC_LIB_USES_BOOST=ON" + cmake_d="$cmake_d -D ALEMBIC_LIB_USES_TR1=OFF" + INFO "ILMBASE_ROOT=$INST/openexr" + fi + + cmake $cmake_d ./ + make -j$THREADS install + make clean + + if [ -d $_inst ]; then + _create_inst_shortcut + else + ERROR "Alembic-$ALEMBIC_VERSION failed to compile, exiting" + exit 1 + fi + + magic_compile_set alembic-$ALEMBIC_VERSION $alembic_magic + + cd $CWD + INFO "Done compiling Alembic-$ALEMBIC_VERSION!" + else + INFO "Own Alembic-$ALEMBIC_VERSION is up to date, nothing to do!" + INFO "If you want to force rebuild of this lib, use the --force-alembic option." + fi + + run_ldconfig "alembic" +} + #### Build OpenCOLLADA #### _init_opencollada() { _src=$SRC/OpenCOLLADA-$OPENCOLLADA_VERSION @@ -2746,6 +2876,17 @@ install_DEB() { fi fi + PRINT "" + if [ "$ALEMBIC_SKIP" = true ]; then + WARNING "Skipping Alembic installation, as requested..." + elif [ "$ALEMBIC_FORCE_BUILD" = true ]; then + INFO "Forced Alembic building, as requested..." + compile_ALEMBIC + else + # No package currently, only HDF5! + compile_ALEMBIC + fi + if [ "$WITH_OPENCOLLADA" = true ]; then _do_compile_collada=false @@ -3283,6 +3424,17 @@ install_RPM() { compile_OPENVDB fi + PRINT "" + if [ "$ALEMBIC_SKIP" = true ]; then + WARNING "Skipping Alembic installation, as requested..." + elif [ "$ALEMBIC_FORCE_BUILD" = true ]; then + INFO "Forced Alembic building, as requested..." + compile_ALEMBIC + else + # No package currently! + compile_ALEMBIC + fi + if [ "$WITH_OPENCOLLADA" = true ]; then PRINT "" @@ -3693,6 +3845,16 @@ install_ARCH() { fi fi + PRINT "" + if [ "$ALEMBIC_SKIP" = true ]; then + WARNING "Skipping Alembic installation, as requested..." + elif [ "$ALEMBIC_FORCE_BUILD" = true ]; then + INFO "Forced Alembic building, as requested..." + compile_ALEMBIC + else + compile_ALEMBIC + fi + if [ "$WITH_OPENCOLLADA" = true ]; then PRINT "" @@ -4000,7 +4162,7 @@ print_info() { _buildargs="-U *SNDFILE* -U *PYTHON* -U *BOOST* -U *Boost*" _buildargs="$_buildargs -U *OPENCOLORIO* -U *OPENEXR* -U *OPENIMAGEIO* -U *LLVM* -U *CYCLES*" - _buildargs="$_buildargs -U *OPENSUBDIV* -U *OPENVDB* -U *COLLADA* -U *FFMPEG*" + _buildargs="$_buildargs -U *OPENSUBDIV* -U *OPENVDB* -U *COLLADA* -U *FFMPEG* -U *ALEMBIC*" _1="-D WITH_CODEC_SNDFILE=ON" PRINT " $_1" @@ -4106,6 +4268,17 @@ print_info() { _buildargs="$_buildargs $_1" fi + if [ "$ALEMBIC_SKIP" = false ]; then + _1="-D WITH_ALEMBIC=ON" + PRINT " $_1" + _buildargs="$_buildargs $_1" + if [ -d $INST/alembic ]; then + _1="-D ALEMBIC_ROOT_DIR=$INST/alembic" + PRINT " $_1" + _buildargs="$_buildargs $_1" + fi + fi + if [ "$NO_SYSTEM_GLEW" = true ]; then _1="-D WITH_SYSTEM_GLEW=OFF" PRINT " $_1" diff --git a/build_files/cmake/Modules/FindAlembic.cmake b/build_files/cmake/Modules/FindAlembic.cmake new file mode 100644 index 00000000000..1f61b5ef462 --- /dev/null +++ b/build_files/cmake/Modules/FindAlembic.cmake @@ -0,0 +1,70 @@ +# - Find Alembic library +# Find the native Alembic includes and libraries +# This module defines +# ALEMBIC_INCLUDE_DIRS, where to find Alembic headers, Set when +# ALEMBIC_INCLUDE_DIR is found. +# ALEMBIC_LIBRARIES, libraries to link against to use Alembic. +# ALEMBIC_ROOT_DIR, The base directory to search for Alembic. +# This can also be an environment variable. +# ALEMBIC_FOUND, If false, do not try to use Alembic. +# + +#============================================================================= +# Copyright 2016 Blender Foundation. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= + +# If ALEMBIC_ROOT_DIR was defined in the environment, use it. +IF(NOT ALEMBIC_ROOT_DIR AND NOT $ENV{ALEMBIC_ROOT_DIR} STREQUAL "") + SET(ALEMBIC_ROOT_DIR $ENV{ALEMBIC_ROOT_DIR}) +ENDIF() + +SET(_alembic_SEARCH_DIRS + ${ALEMBIC_ROOT_DIR} + /usr/local + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt/lib/alembic +) + +FIND_PATH(ALEMBIC_INCLUDE_DIR + NAMES + Alembic/Abc/All.h + HINTS + ${_alembic_SEARCH_DIRS} + PATH_SUFFIXES + include +) + +FIND_LIBRARY(ALEMBIC_LIBRARY + NAMES + Alembic + HINTS + ${_alembic_SEARCH_DIRS} + PATH_SUFFIXES + lib64 lib lib/static +) + +# handle the QUIETLY and REQUIRED arguments and set ALEMBIC_FOUND to TRUE if +# all listed variables are TRUE +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(ALEMBIC DEFAULT_MSG ALEMBIC_LIBRARY ALEMBIC_INCLUDE_DIR) + +IF(ALEMBIC_FOUND) + SET(ALEMBIC_LIBRARIES ${ALEMBIC_LIBRARY}) + SET(ALEMBIC_INCLUDE_DIRS ${ALEMBIC_INCLUDE_DIR}) +ENDIF(ALEMBIC_FOUND) + +MARK_AS_ADVANCED( + ALEMBIC_INCLUDE_DIR + ALEMBIC_LIBRARY +) + +UNSET(_alembic_SEARCH_DIRS) diff --git a/build_files/cmake/Modules/FindHDF5.cmake b/build_files/cmake/Modules/FindHDF5.cmake new file mode 100644 index 00000000000..56ceda8fb5e --- /dev/null +++ b/build_files/cmake/Modules/FindHDF5.cmake @@ -0,0 +1,69 @@ +# - Find HDF5 library +# Find the native HDF5 includes and libraries +# This module defines +# HDF5_INCLUDE_DIRS, where to find hdf5.h, Set when HDF5_INCLUDE_DIR is found. +# HDF5_LIBRARIES, libraries to link against to use HDF5. +# HDF5_ROOT_DIR, The base directory to search for HDF5. +# This can also be an environment variable. +# HDF5_FOUND, If false, do not try to use HDF5. +# + +#============================================================================= +# Copyright 2016 Blender Foundation. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= + +# If HDF5_ROOT_DIR was defined in the environment, use it. +IF(NOT HDF5_ROOT_DIR AND NOT $ENV{HDF5_ROOT_DIR} STREQUAL "") + SET(HDF5_ROOT_DIR $ENV{HDF5_ROOT_DIR}) +ENDIF() + +SET(_hdf5_SEARCH_DIRS + ${HDF5_ROOT_DIR} + /usr/local + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt/lib/hdf5 +) + +FIND_LIBRARY(HDF5_LIBRARY + NAMES + hdf5 + HINTS + ${_hdf5_SEARCH_DIRS} + PATH_SUFFIXES + lib64 lib +) + +FIND_PATH(HDF5_INCLUDE_DIR + NAMES + hdf5.h + HINTS + ${_hdf5_SEARCH_DIRS} + PATH_SUFFIXES + include +) + +# handle the QUIETLY and REQUIRED arguments and set HDF5_FOUND to TRUE if +# all listed variables are TRUE +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(HDF5 DEFAULT_MSG HDF5_LIBRARY HDF5_INCLUDE_DIR) + +IF(HDF5_FOUND) + SET(HDF5_LIBRARIES ${HDF5_LIBRARY}) + SET(HDF5_INCLUDE_DIRS ${HDF5_INCLUDE_DIR}) +ENDIF(HDF5_FOUND) + +MARK_AS_ADVANCED( + HDF5_INCLUDE_DIR + HDF5_LIBRARY +) + +UNSET(_hdf5_SEARCH_DIRS) diff --git a/build_files/cmake/config/blender_full.cmake b/build_files/cmake/config/blender_full.cmake index b50b42416fb..634d4f431d4 100644 --- a/build_files/cmake/config/blender_full.cmake +++ b/build_files/cmake/config/blender_full.cmake @@ -4,6 +4,7 @@ # cmake -C../blender/build_files/cmake/config/blender_full.cmake ../blender # +set(WITH_ALEMBIC ON CACHE BOOL "" FORCE) set(WITH_BUILDINFO ON CACHE BOOL "" FORCE) set(WITH_BULLET ON CACHE BOOL "" FORCE) set(WITH_CODEC_AVI ON CACHE BOOL "" FORCE) diff --git a/build_files/cmake/config/blender_lite.cmake b/build_files/cmake/config/blender_lite.cmake index 3c53ee7ae23..46b7d48b494 100644 --- a/build_files/cmake/config/blender_lite.cmake +++ b/build_files/cmake/config/blender_lite.cmake @@ -8,6 +8,7 @@ set(WITH_INSTALL_PORTABLE ON CACHE BOOL "" FORCE) set(WITH_SYSTEM_GLEW ON CACHE BOOL "" FORCE) +set(WITH_ALEMBIC OFF CACHE BOOL "" FORCE) set(WITH_BUILDINFO OFF CACHE BOOL "" FORCE) set(WITH_BULLET OFF CACHE BOOL "" FORCE) set(WITH_CODEC_AVI OFF CACHE BOOL "" FORCE) diff --git a/build_files/cmake/config/bpy_module.cmake b/build_files/cmake/config/bpy_module.cmake index 41140151f04..854d6e49370 100644 --- a/build_files/cmake/config/bpy_module.cmake +++ b/build_files/cmake/config/bpy_module.cmake @@ -32,3 +32,4 @@ set(WITH_OPENCOLLADA OFF CACHE BOOL "" FORCE) set(WITH_INTERNATIONAL OFF CACHE BOOL "" FORCE) set(WITH_BULLET OFF CACHE BOOL "" FORCE) set(WITH_OPENVDB OFF CACHE BOOL "" FORCE) +set(WITH_ALEMBIC OFF CACHE BOOL "" FORCE) diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index f57a6952164..c4e1c56699e 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -333,6 +333,11 @@ function(SETUP_LIBDIRS) link_directories(${LLVM_LIBPATH}) endif() + if(WITH_ALEMBIC) + link_directories(${ALEMBIC_LIBPATH}) + link_directories(${HDF5_LIBPATH}) + endif() + if(WIN32 AND NOT UNIX) link_directories(${PTHREADS_LIBPATH}) endif() @@ -434,6 +439,9 @@ function(setup_liblinks endif() endif() target_link_libraries(${target} ${JPEG_LIBRARIES}) + if(WITH_ALEMBIC) + target_link_libraries(${target} ${ALEMBIC_LIBRARIES} ${HDF5_LIBRARIES}) + endif() if(WITH_IMAGE_OPENEXR) target_link_libraries(${target} ${OPENEXR_LIBRARIES}) endif() @@ -607,6 +615,7 @@ function(SETUP_BLENDER_SORTED_LIBS) bf_imbuf_openimageio bf_imbuf_dds bf_collada + bf_alembic bf_intern_elbeem bf_intern_memutil bf_intern_guardedalloc -- cgit v1.2.3