Compare commits

..

1 Commits

Author SHA1 Message Date
67b4829085 Atomics: Add 16 bit fetch + AND and fetch + OR signed integer operations
I could use a 16 bit atomic fetch + AND for D9719. The alternative would be to
turn a `short` into a `int` in DNA, which isn't a nice workaround.

Also adds tests for the new functions.
2020-12-04 16:57:32 +01:00
1667 changed files with 27372 additions and 44041 deletions

View File

@@ -347,21 +347,16 @@ if(UNIX AND NOT APPLE)
endif()
option(WITH_PYTHON_INSTALL "Copy system python into the blender install folder" ON)
if((WITH_AUDASPACE AND NOT WITH_SYSTEM_AUDASPACE) OR WITH_MOD_FLUID)
option(WITH_PYTHON_NUMPY "Include NumPy in Blender (used by Audaspace and Mantaflow)" ON)
endif()
if(WIN32 OR APPLE)
# Windows and macOS have this bundled with Python libraries.
elseif(WITH_PYTHON_INSTALL OR WITH_PYTHON_NUMPY)
elseif(WITH_PYTHON_INSTALL OR (WITH_AUDASPACE AND NOT WITH_SYSTEM_AUDASPACE))
set(PYTHON_NUMPY_PATH "" CACHE PATH "Path to python site-packages or dist-packages containing 'numpy' module")
mark_as_advanced(PYTHON_NUMPY_PATH)
set(PYTHON_NUMPY_INCLUDE_DIRS "" CACHE PATH "Path to the include directory of the NumPy module")
set(PYTHON_NUMPY_INCLUDE_DIRS ${PYTHON_NUMPY_PATH}/numpy/core/include CACHE PATH "Path to the include directory of the numpy module")
mark_as_advanced(PYTHON_NUMPY_INCLUDE_DIRS)
endif()
if(WITH_PYTHON_INSTALL)
option(WITH_PYTHON_INSTALL_NUMPY "Copy system NumPy into the blender install folder" ON)
option(WITH_PYTHON_INSTALL_NUMPY "Copy system numpy into the blender install folder" ON)
if(UNIX AND NOT APPLE)
option(WITH_PYTHON_INSTALL_REQUESTS "Copy system requests into the blender install folder" ON)
@@ -610,11 +605,6 @@ if(WIN32)
endif()
if(UNIX)
# See WITH_WINDOWS_SCCACHE for Windows.
option(WITH_COMPILER_CCACHE "Use ccache to improve rebuild times (Works with Ninja, Makefiles and Xcode)" OFF)
endif()
# The following only works with the Ninja generator in CMake >= 3.0.
if("${CMAKE_GENERATOR}" MATCHES "Ninja")
option(WITH_NINJA_POOL_JOBS
@@ -1631,16 +1621,19 @@ if(WITH_PYTHON)
if(WIN32 OR APPLE)
# Windows and macOS have this bundled with Python libraries.
elseif((WITH_PYTHON_INSTALL AND WITH_PYTHON_INSTALL_NUMPY) OR WITH_PYTHON_NUMPY)
elseif((WITH_PYTHON_INSTALL AND WITH_PYTHON_INSTALL_NUMPY) OR (WITH_AUDASPACE AND NOT WITH_SYSTEM_AUDASPACE))
if(("${PYTHON_NUMPY_PATH}" STREQUAL "") OR (${PYTHON_NUMPY_PATH} MATCHES NOTFOUND))
find_python_package(numpy "core/include")
find_python_package(numpy)
unset(PYTHON_NUMPY_INCLUDE_DIRS CACHE)
set(PYTHON_NUMPY_INCLUDE_DIRS ${PYTHON_NUMPY_PATH}/numpy/core/include CACHE PATH "Path to the include directory of the numpy module")
mark_as_advanced(PYTHON_NUMPY_INCLUDE_DIRS)
endif()
endif()
if(WIN32 OR APPLE)
# pass, we have this in lib/python/site-packages
elseif(WITH_PYTHON_INSTALL_REQUESTS)
find_python_package(requests "")
find_python_package(requests)
endif()
endif()
@@ -1773,10 +1766,6 @@ elseif(WITH_CYCLES_STANDALONE)
endif()
endif()
#-----------------------------------------------------------------------------
# Testing
add_subdirectory(tests)
#-----------------------------------------------------------------------------
# Blender Application
if(WITH_BLENDER)
@@ -1784,6 +1773,11 @@ if(WITH_BLENDER)
endif()
#-----------------------------------------------------------------------------
# Testing
add_subdirectory(tests)
#-----------------------------------------------------------------------------
# Define 'heavy' submodules (for Ninja builder when using pools).
setup_heavy_lib_pool()

View File

@@ -41,7 +41,6 @@ Convenience Targets
* developer: Enable faster builds, error checking and tests, recommended for developers.
* config: Run cmake configuration tool to set build options.
* ninja: Use ninja build tool for faster builds.
* ccache: Use ccache for faster rebuilds.
Note: passing the argument 'BUILD_DIR=path' when calling make will override the default build dir.
Note: passing the argument 'BUILD_CMAKE_ARGS=args' lets you add cmake arguments.
@@ -242,10 +241,6 @@ ifneq "$(findstring developer, $(MAKECMDGOALS))" ""
CMAKE_CONFIG_ARGS:=-C"$(BLENDER_DIR)/build_files/cmake/config/blender_developer.cmake" $(CMAKE_CONFIG_ARGS)
endif
ifneq "$(findstring ccache, $(MAKECMDGOALS))" ""
CMAKE_CONFIG_ARGS:=-DWITH_COMPILER_CCACHE=YES $(CMAKE_CONFIG_ARGS)
endif
# -----------------------------------------------------------------------------
# build tool
@@ -345,7 +340,6 @@ headless: all
bpy: all
developer: all
ninja: all
ccache: all
# -----------------------------------------------------------------------------
# Build dependencies

View File

@@ -17,14 +17,13 @@
# ***** END GPL LICENSE BLOCK *****
set(CLANG_EXTRA_ARGS
-DLLVM_DIR="${LIBDIR}/llvm/lib/cmake/llvm/"
-DCLANG_PATH_TO_LLVM_SOURCE=${BUILD_DIR}/ll/src/ll
-DCLANG_PATH_TO_LLVM_BUILD=${LIBDIR}/llvm
-DLLVM_USE_CRT_RELEASE=MD
-DLLVM_USE_CRT_DEBUG=MDd
-DLLVM_CONFIG=${LIBDIR}/llvm/bin/llvm-config
)
set(BUILD_CLANG_TOOLS OFF)
if(WIN32)
set(CLANG_GENERATOR "Ninja")
else()
@@ -32,32 +31,11 @@ else()
endif()
if(APPLE)
set(BUILD_CLANG_TOOLS ON)
set(CLANG_EXTRA_ARGS ${CLANG_EXTRA_ARGS}
-DLIBXML2_LIBRARY=${LIBDIR}/xml2/lib/libxml2.a
)
endif()
if(BUILD_CLANG_TOOLS)
# ExternalProject_Add does not allow multiple tarballs to be
# downloaded. Work around this by having an empty build action
# for the extra tools, and referring the clang build to the location
# of the clang-tools-extra source.
ExternalProject_Add(external_clang_tools
URL ${CLANG_TOOLS_URI}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH MD5=${CLANG_TOOLS_HASH}
INSTALL_DIR ${LIBDIR}/clang_tools
PREFIX ${BUILD_DIR}/clang_tools
CONFIGURE_COMMAND echo "."
BUILD_COMMAND echo "."
INSTALL_COMMAND echo "."
)
list(APPEND CLANG_EXTRA_ARGS
-DLLVM_EXTERNAL_CLANG_TOOLS_EXTRA_SOURCE_DIR=${BUILD_DIR}/clang_tools/src/external_clang_tools/
)
endif()
ExternalProject_Add(external_clang
URL ${CLANG_URI}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
@@ -87,14 +65,6 @@ add_dependencies(
ll
)
if(BUILD_CLANG_TOOLS)
# `external_clang_tools` is for downloading the source, not compiling it.
add_dependencies(
external_clang
external_clang_tools
)
endif()
# We currently do not build libxml2 on Windows.
if(NOT WIN32)
add_dependencies(

View File

@@ -98,10 +98,6 @@ harvest(jpg/include jpeg/include "*.h")
harvest(jpg/lib jpeg/lib "libjpeg.a")
harvest(lame/lib ffmpeg/lib "*.a")
harvest(clang/bin llvm/bin "clang-format")
if(BUILD_CLANG_TOOLS)
harvest(clang/bin llvm/bin "clang-tidy")
harvest(clang/share/clang llvm/share "run-clang-tidy.py")
endif()
harvest(clang/include llvm/include "*")
harvest(llvm/include llvm/include "*")
harvest(llvm/bin llvm/bin "llvm-config")

View File

@@ -120,9 +120,6 @@ set(LLVM_HASH 31eb9ce73dd2a0f8dcab8319fb03f8fc)
set(CLANG_URI https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}/clang-${LLVM_VERSION}.src.tar.xz)
set(CLANG_HASH 13468e4a44940efef1b75e8641752f90)
set(CLANG_TOOLS_URI https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}/clang-tools-extra-${LLVM_VERSION}.src.tar.xz)
set(CLANG_TOOLS_HASH c76293870b564c6a7968622b475b7646)
set(OPENMP_URI https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}/openmp-${LLVM_VERSION}.src.tar.xz)
set(OPENMP_HASH 6eade16057edbdecb3c4eef9daa2bfcf)

View File

@@ -2086,7 +2086,7 @@ compile_OIIO() {
cmake_d="$cmake_d -D USE_OPENCV=OFF"
cmake_d="$cmake_d -D BUILD_TESTING=OFF"
cmake_d="$cmake_d -D OIIO_BUILD_TESTS=OFF"
cmake_d="$cmake_d -D OIIO_BUILD_TOOLS=ON"
cmake_d="$cmake_d -D OIIO_BUILD_TOOLS=OFF"
cmake_d="$cmake_d -D TXT2MAN="
#cmake_d="$cmake_d -D CMAKE_EXPORT_COMPILE_COMMANDS=ON"
#cmake_d="$cmake_d -D CMAKE_VERBOSE_MAKEFILE=ON"
@@ -4072,7 +4072,7 @@ install_DEB() {
else
check_package_version_ge_lt_DEB libopenimageio-dev $OIIO_VERSION_MIN $OIIO_VERSION_MAX
if [ $? -eq 0 -a "$_with_built_openexr" = false ]; then
install_packages_DEB libopenimageio-dev openimageio-tools
install_packages_DEB libopenimageio-dev
clean_OIIO
else
compile_OIIO
@@ -4714,13 +4714,13 @@ install_RPM() {
INFO "Forced OpenImageIO building, as requested..."
compile_OIIO
else
check_package_version_ge_lt_RPM OpenImageIO-devel $OIIO_VERSION_MIN $OIIO_VERSION_MAX
if [ $? -eq 0 -a $_with_built_openexr == false ]; then
install_packages_RPM OpenImageIO-devel OpenImageIO-utils
clean_OIIO
else
#check_package_version_ge_lt_RPM OpenImageIO-devel $OIIO_VERSION_MIN $OIIO_VERSION_MAX
#if [ $? -eq 0 -a $_with_built_openexr == false ]; then
# install_packages_RPM OpenImageIO-devel
# clean_OIIO
#else
compile_OIIO
fi
#fi
fi

View File

@@ -42,7 +42,7 @@ def get_cmake_options(builder):
elif builder.platform == 'linux':
config_file = "build_files/buildbot/config/blender_linux.cmake"
optix_sdk_dir = os.path.join(builder.blender_dir, '..', '..', 'NVIDIA-Optix-SDK-7.1')
optix_sdk_dir = os.path.join(builder.blender_dir, '..', '..', 'NVIDIA-Optix-SDK')
options.append('-DOPTIX_ROOT_DIR:PATH=' + optix_sdk_dir)
# Workaround to build sm_30 kernels with CUDA 10, since CUDA 11 no longer supports that architecture

View File

@@ -330,9 +330,6 @@ function(gtest_add_tests)
set(gtest_case_name_regex ".*\\( *([A-Za-z_0-9]+) *, *([A-Za-z_0-9]+) *\\).*")
set(gtest_test_type_regex "(TYPED_TEST|TEST_?[FP]?)")
# This will get a filter for each test suite.
set(test_filters "")
foreach(source IN LISTS ARGS_SOURCES)
if(NOT ARGS_SKIP_DEPENDENCY)
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${source})
@@ -379,32 +376,175 @@ function(gtest_add_tests)
list(APPEND testList ${ctest_test_name})
endif()
else()
# BLENDER: collect tests named "suite.testcase" as list of "suite.*" filters.
string(REGEX REPLACE "\\..*$" "" gtest_suite_name ${gtest_test_name})
list(APPEND test_filters "${gtest_suite_name}.*")
set(ctest_test_name ${ARGS_TEST_PREFIX}${gtest_test_name}${ARGS_TEST_SUFFIX})
add_test(NAME ${ctest_test_name}
${workDir}
COMMAND ${ARGS_TARGET}
--gtest_filter=${gtest_test_name}
${ARGS_EXTRA_ARGS}
)
list(APPEND testList ${ctest_test_name})
endif()
endforeach()
endforeach()
# Join all found GTest suite names into one big filter.
list(REMOVE_DUPLICATES test_filters)
list(JOIN test_filters ":" gtest_filter)
add_test(NAME ${ARGS_TEST_PREFIX}
${workDir}
COMMAND ${ARGS_TARGET}
--gtest_filter=${gtest_filter}
${ARGS_EXTRA_ARGS}
)
list(APPEND testList ${ARGS_TEST_PREFIX})
if(ARGS_TEST_LIST)
set(${ARGS_TEST_LIST} ${testList} PARENT_SCOPE)
endif()
endfunction()
# BLENDER: remove the discovery function gtest_discover_tests(). It's not used,
# as it generates too many test invocations.
#------------------------------------------------------------------------------
function(gtest_discover_tests TARGET)
cmake_parse_arguments(
""
"NO_PRETTY_TYPES;NO_PRETTY_VALUES"
"TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;DISCOVERY_TIMEOUT;XML_OUTPUT_DIR;DISCOVERY_MODE"
"EXTRA_ARGS;PROPERTIES"
${ARGN}
)
if(NOT _WORKING_DIRECTORY)
set(_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
endif()
if(NOT _TEST_LIST)
set(_TEST_LIST ${TARGET}_TESTS)
endif()
if(NOT _DISCOVERY_TIMEOUT)
set(_DISCOVERY_TIMEOUT 5)
endif()
if(NOT _DISCOVERY_MODE)
if(NOT CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE)
set(CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE "POST_BUILD")
endif()
set(_DISCOVERY_MODE ${CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE})
endif()
get_property(
has_counter
TARGET ${TARGET}
PROPERTY CTEST_DISCOVERED_TEST_COUNTER
SET
)
if(has_counter)
get_property(
counter
TARGET ${TARGET}
PROPERTY CTEST_DISCOVERED_TEST_COUNTER
)
math(EXPR counter "${counter} + 1")
else()
set(counter 1)
endif()
set_property(
TARGET ${TARGET}
PROPERTY CTEST_DISCOVERED_TEST_COUNTER
${counter}
)
# Define rule to generate test list for aforementioned test executable
# Blender: use _ instead of [] to avoid problems with zsh regex.
set(ctest_file_base "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_${counter}_")
set(ctest_include_file "${ctest_file_base}_include.cmake")
set(ctest_tests_file "${ctest_file_base}_tests.cmake")
get_property(crosscompiling_emulator
TARGET ${TARGET}
PROPERTY CROSSCOMPILING_EMULATOR
)
if(_DISCOVERY_MODE STREQUAL "POST_BUILD")
add_custom_command(
TARGET ${TARGET} POST_BUILD
BYPRODUCTS "${ctest_tests_file}"
COMMAND "${CMAKE_COMMAND}"
-D "TEST_TARGET=${TARGET}"
-D "TEST_EXECUTABLE=$<TARGET_FILE:${TARGET}>"
-D "TEST_EXECUTOR=${crosscompiling_emulator}"
-D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}"
-D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}"
-D "TEST_PROPERTIES=${_PROPERTIES}"
-D "TEST_PREFIX=${_TEST_PREFIX}"
-D "TEST_SUFFIX=${_TEST_SUFFIX}"
-D "NO_PRETTY_TYPES=${_NO_PRETTY_TYPES}"
-D "NO_PRETTY_VALUES=${_NO_PRETTY_VALUES}"
-D "TEST_LIST=${_TEST_LIST}"
-D "CTEST_FILE=${ctest_tests_file}"
-D "TEST_DISCOVERY_TIMEOUT=${_DISCOVERY_TIMEOUT}"
-D "TEST_XML_OUTPUT_DIR=${_XML_OUTPUT_DIR}"
-P "${_GOOGLETEST_DISCOVER_TESTS_SCRIPT}"
VERBATIM
)
file(WRITE "${ctest_include_file}"
"if(EXISTS \"${ctest_tests_file}\")\n"
" include(\"${ctest_tests_file}\")\n"
"else()\n"
" add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)\n"
"endif()\n"
)
elseif(_DISCOVERY_MODE STREQUAL "PRE_TEST")
get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL
PROPERTY GENERATOR_IS_MULTI_CONFIG
)
if(GENERATOR_IS_MULTI_CONFIG)
set(ctest_tests_file "${ctest_file_base}_tests-$<CONFIG>.cmake")
endif()
string(CONCAT ctest_include_content
"if(EXISTS \"$<TARGET_FILE:${TARGET}>\")" "\n"
" if(\"$<TARGET_FILE:${TARGET}>\" IS_NEWER_THAN \"${ctest_tests_file}\")" "\n"
" include(\"${_GOOGLETEST_DISCOVER_TESTS_SCRIPT}\")" "\n"
" gtest_discover_tests_impl(" "\n"
" TEST_EXECUTABLE" " [==[" "$<TARGET_FILE:${TARGET}>" "]==]" "\n"
" TEST_EXECUTOR" " [==[" "${crosscompiling_emulator}" "]==]" "\n"
" TEST_WORKING_DIR" " [==[" "${_WORKING_DIRECTORY}" "]==]" "\n"
" TEST_EXTRA_ARGS" " [==[" "${_EXTRA_ARGS}" "]==]" "\n"
" TEST_PROPERTIES" " [==[" "${_PROPERTIES}" "]==]" "\n"
" TEST_PREFIX" " [==[" "${_TEST_PREFIX}" "]==]" "\n"
" TEST_SUFFIX" " [==[" "${_TEST_SUFFIX}" "]==]" "\n"
" NO_PRETTY_TYPES" " [==[" "${_NO_PRETTY_TYPES}" "]==]" "\n"
" NO_PRETTY_VALUES" " [==[" "${_NO_PRETTY_VALUES}" "]==]" "\n"
" TEST_LIST" " [==[" "${_TEST_LIST}" "]==]" "\n"
" CTEST_FILE" " [==[" "${ctest_tests_file}" "]==]" "\n"
" TEST_DISCOVERY_TIMEOUT" " [==[" "${_DISCOVERY_TIMEOUT}" "]==]" "\n"
" TEST_XML_OUTPUT_DIR" " [==[" "${_XML_OUTPUT_DIR}" "]==]" "\n"
" )" "\n"
" endif()" "\n"
" include(\"${ctest_tests_file}\")" "\n"
"else()" "\n"
" add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)" "\n"
"endif()" "\n"
)
if(GENERATOR_IS_MULTI_CONFIG)
foreach(_config ${CMAKE_CONFIGURATION_TYPES})
file(GENERATE OUTPUT "${ctest_file_base}_include-${_config}.cmake" CONTENT "${ctest_include_content}" CONDITION $<CONFIG:${_config}>)
endforeach()
file(WRITE "${ctest_include_file}" "include(\"${ctest_file_base}_include-\${CTEST_CONFIGURATION_TYPE}.cmake\")")
else()
file(GENERATE OUTPUT "${ctest_file_base}_include.cmake" CONTENT "${ctest_include_content}")
file(WRITE "${ctest_include_file}" "include(\"${ctest_file_base}_include.cmake\")")
endif()
else()
message(FATAL_ERROR "Unknown DISCOVERY_MODE: ${_DISCOVERY_MODE}")
endif()
# Add discovered tests to directory TEST_INCLUDE_FILES
set_property(DIRECTORY
APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}"
)
endfunction()
###############################################################################
set(_GOOGLETEST_DISCOVER_TESTS_SCRIPT
${CMAKE_CURRENT_LIST_DIR}/GTestAddTests.cmake
)
# Restore project's policies
cmake_policy(POP)

View File

@@ -0,0 +1,194 @@
# Distributed under the OSI-approved BSD 3-Clause License,
# see accompanying file BSD-3-Clause-license.txt for details.
# Changes made to this script have been marked with "BLENDER".
# BLENDER: disable ASAN leak detection when trying to discover tests.
set(ENV{ASAN_OPTIONS} "detect_leaks=0")
cmake_minimum_required(VERSION ${CMAKE_VERSION})
# Overwrite possibly existing ${_CTEST_FILE} with empty file
set(flush_tests_MODE WRITE)
# Flushes script to ${_CTEST_FILE}
macro(flush_script)
file(${flush_tests_MODE} "${_CTEST_FILE}" "${script}")
set(flush_tests_MODE APPEND)
set(script "")
endmacro()
# Flushes tests_buffer to tests
macro(flush_tests_buffer)
list(APPEND tests "${tests_buffer}")
set(tests_buffer "")
endmacro()
macro(add_command NAME)
set(_args "")
foreach(_arg ${ARGN})
if(_arg MATCHES "[^-./:a-zA-Z0-9_]")
string(APPEND _args " [==[${_arg}]==]")
else()
string(APPEND _args " ${_arg}")
endif()
endforeach()
string(APPEND script "${NAME}(${_args})\n")
string(LENGTH "${script}" _script_len)
if(${_script_len} GREATER "50000")
flush_script()
endif()
# Unsets macro local variables to prevent leakage outside of this macro.
unset(_args)
unset(_script_len)
endmacro()
function(gtest_discover_tests_impl)
cmake_parse_arguments(
""
""
"NO_PRETTY_TYPES;NO_PRETTY_VALUES;TEST_EXECUTABLE;TEST_EXECUTOR;TEST_WORKING_DIR;TEST_PREFIX;TEST_SUFFIX;TEST_LIST;CTEST_FILE;TEST_DISCOVERY_TIMEOUT;TEST_XML_OUTPUT_DIR"
"TEST_EXTRA_ARGS;TEST_PROPERTIES"
${ARGN}
)
set(prefix "${_TEST_PREFIX}")
set(suffix "${_TEST_SUFFIX}")
set(extra_args ${_TEST_EXTRA_ARGS})
set(properties ${_TEST_PROPERTIES})
set(script)
set(suite)
set(tests)
set(tests_buffer)
# Run test executable to get list of available tests
if(NOT EXISTS "${_TEST_EXECUTABLE}")
message(FATAL_ERROR
"Specified test executable does not exist.\n"
" Path: '${_TEST_EXECUTABLE}'"
)
endif()
execute_process(
COMMAND ${_TEST_EXECUTOR} "${_TEST_EXECUTABLE}" --gtest_list_tests
WORKING_DIRECTORY "${_TEST_WORKING_DIR}"
TIMEOUT ${_TEST_DISCOVERY_TIMEOUT}
OUTPUT_VARIABLE output
RESULT_VARIABLE result
)
if(NOT ${result} EQUAL 0)
string(REPLACE "\n" "\n " output "${output}")
message(FATAL_ERROR
"Error running test executable.\n"
" Path: '${_TEST_EXECUTABLE}'\n"
" Result: ${result}\n"
" Output:\n"
" ${output}\n"
)
endif()
# Preserve semicolon in test-parameters
string(REPLACE [[;]] [[\;]] output "${output}")
string(REPLACE "\n" ";" output "${output}")
# Parse output
foreach(line ${output})
# Skip header
if(NOT line MATCHES "gtest_main\\.cc")
# Do we have a module name or a test name?
if(NOT line MATCHES "^ ")
# Module; remove trailing '.' to get just the name...
string(REGEX REPLACE "\\.( *#.*)?" "" suite "${line}")
if(line MATCHES "#" AND NOT _NO_PRETTY_TYPES)
string(REGEX REPLACE "/[0-9]\\.+ +#.*= +" "/" pretty_suite "${line}")
else()
set(pretty_suite "${suite}")
endif()
string(REGEX REPLACE "^DISABLED_" "" pretty_suite "${pretty_suite}")
else()
# Test name; strip spaces and comments to get just the name...
string(REGEX REPLACE " +" "" test "${line}")
if(test MATCHES "#" AND NOT _NO_PRETTY_VALUES)
string(REGEX REPLACE "/[0-9]+#GetParam..=" "/" pretty_test "${test}")
else()
string(REGEX REPLACE "#.*" "" pretty_test "${test}")
endif()
string(REGEX REPLACE "^DISABLED_" "" pretty_test "${pretty_test}")
string(REGEX REPLACE "#.*" "" test "${test}")
if(NOT "${_TEST_XML_OUTPUT_DIR}" STREQUAL "")
set(TEST_XML_OUTPUT_PARAM "--gtest_output=xml:${_TEST_XML_OUTPUT_DIR}/${prefix}${suite}.${test}${suffix}.xml")
else()
unset(TEST_XML_OUTPUT_PARAM)
endif()
# sanitize test name for further processing downstream
set(testname "${prefix}${pretty_suite}.${pretty_test}${suffix}")
# escape \
string(REPLACE [[\]] [[\\]] testname "${testname}")
# escape ;
string(REPLACE [[;]] [[\;]] testname "${testname}")
# escape $
string(REPLACE [[$]] [[\$]] testname "${testname}")
# ...and add to script
add_command(add_test
"${testname}"
${_TEST_EXECUTOR}
"${_TEST_EXECUTABLE}"
"--gtest_filter=${suite}.${test}"
"--gtest_also_run_disabled_tests"
${TEST_XML_OUTPUT_PARAM}
${extra_args}
)
if(suite MATCHES "^DISABLED" OR test MATCHES "^DISABLED")
add_command(set_tests_properties
"${testname}"
PROPERTIES DISABLED TRUE
)
endif()
add_command(set_tests_properties
"${testname}"
PROPERTIES
WORKING_DIRECTORY "${_TEST_WORKING_DIR}"
SKIP_REGULAR_EXPRESSION "\\\\[ SKIPPED \\\\]"
${properties}
)
list(APPEND tests_buffer "${testname}")
list(LENGTH tests_buffer tests_buffer_length)
if(${tests_buffer_length} GREATER "250")
flush_tests_buffer()
endif()
endif()
endif()
endforeach()
# Create a list of all discovered tests, which users may use to e.g. set
# properties on the tests
flush_tests_buffer()
add_command(set ${_TEST_LIST} ${tests})
# Write CTest script
flush_script()
endfunction()
if(CMAKE_SCRIPT_MODE_FILE)
gtest_discover_tests_impl(
NO_PRETTY_TYPES ${NO_PRETTY_TYPES}
NO_PRETTY_VALUES ${NO_PRETTY_VALUES}
TEST_EXECUTABLE ${TEST_EXECUTABLE}
TEST_EXECUTOR ${TEST_EXECUTOR}
TEST_WORKING_DIR ${TEST_WORKING_DIR}
TEST_PREFIX ${TEST_PREFIX}
TEST_SUFFIX ${TEST_SUFFIX}
TEST_LIST ${TEST_LIST}
CTEST_FILE ${CTEST_FILE}
TEST_DISCOVERY_TIMEOUT ${TEST_DISCOVERY_TIMEOUT}
TEST_XML_OUTPUT_DIR ${TEST_XML_OUTPUT_DIR}
TEST_EXTRA_ARGS ${TEST_EXTRA_ARGS}
TEST_PROPERTIES ${TEST_PROPERTIES}
)
endif()

View File

@@ -8,17 +8,6 @@
#
#=============================================================================
function(GET_BLENDER_TEST_INSTALL_DIR VARIABLE_NAME)
get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(GENERATOR_IS_MULTI_CONFIG)
string(REPLACE "\${BUILD_TYPE}" "$<CONFIG>" TEST_INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
else()
string(REPLACE "\${BUILD_TYPE}" "" TEST_INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
endif()
set(${VARIABLE_NAME} "${TEST_INSTALL_DIR}" PARENT_SCOPE)
endfunction()
macro(BLENDER_SRC_GTEST_EX)
if(WITH_GTESTS)
set(options SKIP_ADD_TEST)
@@ -86,7 +75,13 @@ macro(BLENDER_SRC_GTEST_EX)
target_link_libraries(${TARGET_NAME} ${GMP_LIBRARIES})
endif()
GET_BLENDER_TEST_INSTALL_DIR(TEST_INSTALL_DIR)
get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(GENERATOR_IS_MULTI_CONFIG)
string(REPLACE "\${BUILD_TYPE}" "$<CONFIG>" TEST_INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
else()
string(REPLACE "\${BUILD_TYPE}" "" TEST_INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
endif()
set_target_properties(${TARGET_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${TESTS_OUTPUT_DIR}"
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${TESTS_OUTPUT_DIR}"

View File

@@ -13,7 +13,7 @@ Invocation:
export CLANG_BIND_DIR="/dsk/src/llvm/tools/clang/bindings/python"
export CLANG_LIB_DIR="/opt/llvm/lib"
python clang_array_check.py somefile.c -DSOME_DEFINE -I/some/include
python2 clang_array_check.py somefile.c -DSOME_DEFINE -I/some/include
... defines and includes are optional
@@ -76,32 +76,6 @@ defs_precalc = {
"glNormal3bv": {0: 3},
"glNormal3iv": {0: 3},
"glNormal3sv": {0: 3},
# GPU immediate mode.
"immVertex2iv": {1: 2},
"immVertex2fv": {1: 2},
"immVertex3fv": {1: 3},
"immAttr2fv": {1: 2},
"immAttr3fv": {1: 3},
"immAttr4fv": {1: 4},
"immAttr3ubv": {1: 3},
"immAttr4ubv": {1: 4},
"immUniform2fv": {1: 2},
"immUniform3fv": {1: 3},
"immUniform4fv": {1: 4},
"immUniformColor3fv": {0: 3},
"immUniformColor4fv": {0: 4},
"immUniformColor3ubv": {1: 3},
"immUniformColor4ubv": {1: 4},
"immUniformColor3fvAlpha": {0: 3},
"immUniformColor4fvAlpha": {0: 4},
}
# -----------------------------------------------------------------------------
@@ -126,8 +100,7 @@ else:
if CLANG_LIB_DIR is None:
print("$CLANG_LIB_DIR clang lib dir not set")
if CLANG_BIND_DIR:
sys.path.append(CLANG_BIND_DIR)
sys.path.append(CLANG_BIND_DIR)
import clang
import clang.cindex
@@ -135,8 +108,7 @@ from clang.cindex import (CursorKind,
TypeKind,
TokenKind)
if CLANG_LIB_DIR:
clang.cindex.Config.set_library_path(CLANG_LIB_DIR)
clang.cindex.Config.set_library_path(CLANG_LIB_DIR)
index = clang.cindex.Index.create()

View File

@@ -32,7 +32,7 @@ CHECKER_IGNORE_PREFIX = [
"intern/moto",
]
CHECKER_BIN = "python3"
CHECKER_BIN = "python2"
CHECKER_ARGS = [
os.path.join(os.path.dirname(__file__), "clang_array_check.py"),

View File

@@ -388,43 +388,6 @@ function(blender_add_lib
set_property(GLOBAL APPEND PROPERTY BLENDER_LINK_LIBS ${name})
endfunction()
function(blender_add_test_suite)
if (ARGC LESS 1)
message(FATAL_ERROR "No arguments supplied to blender_add_test_suite()")
endif()
# Parse the arguments
set(oneValueArgs TARGET SUITE_NAME)
set(multiValueArgs SOURCES)
cmake_parse_arguments(ARGS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
# Figure out the release dir, as some tests need files from there.
GET_BLENDER_TEST_INSTALL_DIR(TEST_INSTALL_DIR)
if(APPLE)
set(_test_release_dir ${TEST_INSTALL_DIR}/Blender.app/Contents/Resources/${BLENDER_VERSION})
else()
if(WIN32 OR WITH_INSTALL_PORTABLE)
set(_test_release_dir ${TEST_INSTALL_DIR}/${BLENDER_VERSION})
else()
set(_test_release_dir ${TEST_INSTALL_DIR}/share/blender/${BLENDER_VERSION})
endif()
endif()
# Define a test case with our custom gtest_add_tests() command.
include(GTest)
gtest_add_tests(
TARGET ${ARGS_TARGET}
SOURCES "${ARGS_SOURCES}"
TEST_PREFIX ${ARGS_SUITE_NAME}
WORKING_DIRECTORY "${TEST_INSTALL_DIR}"
EXTRA_ARGS
--test-assets-dir "${CMAKE_SOURCE_DIR}/../lib/tests"
--test-release-dir "${_test_release_dir}"
)
unset(_test_release_dir)
endfunction()
# Add tests for a Blender library, to be called in tandem with blender_add_lib().
# The tests will be part of the blender_test executable (see tests/gtests/runner).
function(blender_add_test_lib
@@ -458,12 +421,6 @@ function(blender_add_test_lib
blender_add_lib__impl(${name} "${sources}" "${includes}" "${includes_sys}" "${library_deps}")
set_property(GLOBAL APPEND PROPERTY BLENDER_TEST_LIBS ${name})
blender_add_test_suite(
TARGET blender_test
SUITE_NAME ${name}
SOURCES "${sources}"
)
endfunction()
@@ -497,10 +454,14 @@ function(blender_add_test_executable
SKIP_ADD_TEST
)
blender_add_test_suite(
TARGET ${name}_test
SUITE_NAME ${name}
SOURCES "${sources}"
include(GTest)
set(_GOOGLETEST_DISCOVER_TESTS_SCRIPT
${CMAKE_SOURCE_DIR}/build_files/cmake/Modules/GTestAddTests.cmake
)
gtest_discover_tests(${name}_test
DISCOVERY_MODE PRE_TEST
WORKING_DIRECTORY "${TEST_INSTALL_DIR}"
)
endfunction()
@@ -1178,7 +1139,6 @@ endfunction()
function(find_python_package
package
relative_include_dir
)
string(TOUPPER ${package} _upper_package)
@@ -1210,10 +1170,7 @@ function(find_python_package
dist-packages
vendor-packages
NO_DEFAULT_PATH
DOC
"Path to python site-packages or dist-packages containing '${package}' module"
)
mark_as_advanced(PYTHON_${_upper_package}_PATH)
if(NOT EXISTS "${PYTHON_${_upper_package}_PATH}")
message(WARNING
@@ -1231,50 +1188,6 @@ function(find_python_package
set(WITH_PYTHON_INSTALL_${_upper_package} OFF PARENT_SCOPE)
else()
message(STATUS "${package} found at '${PYTHON_${_upper_package}_PATH}'")
if(NOT "${relative_include_dir}" STREQUAL "")
set(_relative_include_dir "${package}/${relative_include_dir}")
unset(PYTHON_${_upper_package}_INCLUDE_DIRS CACHE)
find_path(PYTHON_${_upper_package}_INCLUDE_DIRS
NAMES
"${_relative_include_dir}"
HINTS
"${PYTHON_LIBPATH}/"
"${PYTHON_LIBPATH}/python${PYTHON_VERSION}/"
"${PYTHON_LIBPATH}/python${_PY_VER_MAJOR}/"
PATH_SUFFIXES
"site-packages/"
"dist-packages/"
"vendor-packages/"
NO_DEFAULT_PATH
DOC
"Path to python site-packages or dist-packages containing '${package}' module header files"
)
mark_as_advanced(PYTHON_${_upper_package}_INCLUDE_DIRS)
if(NOT EXISTS "${PYTHON_${_upper_package}_INCLUDE_DIRS}")
message(WARNING
"Python package '${package}' include dir path could not be found in:\n"
"'${PYTHON_LIBPATH}/python${PYTHON_VERSION}/site-packages/${_relative_include_dir}', "
"'${PYTHON_LIBPATH}/python${_PY_VER_MAJOR}/site-packages/${_relative_include_dir}', "
"'${PYTHON_LIBPATH}/python${PYTHON_VERSION}/dist-packages/${_relative_include_dir}', "
"'${PYTHON_LIBPATH}/python${_PY_VER_MAJOR}/dist-packages/${_relative_include_dir}', "
"'${PYTHON_LIBPATH}/python${PYTHON_VERSION}/vendor-packages/${_relative_include_dir}', "
"'${PYTHON_LIBPATH}/python${_PY_VER_MAJOR}/vendor-packages/${_relative_include_dir}', "
"\n"
"The 'WITH_PYTHON_${_upper_package}' option will be disabled.\n"
"The build will be usable, only add-ons that depend on this package won't be functional."
)
set(WITH_PYTHON_${_upper_package} OFF PARENT_SCOPE)
else()
set(_temp "${PYTHON_${_upper_package}_INCLUDE_DIRS}/${package}/${relative_include_dir}")
unset(PYTHON_${_upper_package}_INCLUDE_DIRS CACHE)
set(PYTHON_${_upper_package}_INCLUDE_DIRS "${_temp}"
CACHE PATH "Path to the include directory of the ${package} module")
message(STATUS "${package} include files found at '${PYTHON_${_upper_package}_INCLUDE_DIRS}'")
endif()
endif()
endif()
endif()
endfunction()

View File

@@ -470,17 +470,3 @@ set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
set(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
set(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
if(WITH_COMPILER_CCACHE)
if(NOT CMAKE_GENERATOR STREQUAL "Xcode")
find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
# Makefiles and ninja
set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" CACHE STRING "" FORCE)
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" CACHE STRING "" FORCE)
else()
message(WARNING "Ccache NOT found, disabling WITH_COMPILER_CCACHE")
set(WITH_COMPILER_CCACHE OFF)
endif()
endif()
endif()

View File

@@ -154,32 +154,3 @@ if(NOT ${CMAKE_GENERATOR} MATCHES "Xcode")
string(APPEND CMAKE_CXX_FLAGS " -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
add_definitions("-DMACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}")
endif()
if(WITH_COMPILER_CCACHE)
if(CMAKE_GENERATOR STREQUAL "Xcode")
find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
get_filename_component(ccompiler "${CMAKE_C_COMPILER}" NAME)
get_filename_component(cxxcompiler "${CMAKE_CXX_COMPILER}" NAME)
# Ccache can figure out which compiler to use if it's invoked from
# a symlink with the name of the compiler.
# https://ccache.dev/manual/4.1.html#_run_modes
set(_fake_compiler_dir "${CMAKE_BINARY_DIR}/ccache")
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${_fake_compiler_dir})
set(_fake_C_COMPILER "${_fake_compiler_dir}/${ccompiler}")
set(_fake_CXX_COMPILER "${_fake_compiler_dir}/${cxxcompiler}")
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CCACHE_PROGRAM}" ${_fake_C_COMPILER})
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CCACHE_PROGRAM}" ${_fake_CXX_COMPILER})
set(CMAKE_XCODE_ATTRIBUTE_CC ${_fake_C_COMPILER} CACHE STRING "" FORCE)
set(CMAKE_XCODE_ATTRIBUTE_CXX ${_fake_CXX_COMPILER} CACHE STRING "" FORCE)
set(CMAKE_XCODE_ATTRIBUTE_LD ${_fake_C_COMPILER} CACHE STRING "" FORCE)
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS ${_fake_CXX_COMPILER} CACHE STRING "" FORCE)
unset(_fake_compiler_dir)
unset(_fake_C_COMPILER)
unset(_fake_CXX_COMPILER)
else()
message(WARNING "Ccache NOT found, disabling WITH_COMPILER_CCACHE")
set(WITH_COMPILER_CCACHE OFF)
endif()
endif()
endif()

View File

@@ -684,15 +684,3 @@ set(PLATFORM_LINKFLAGS
if(WITH_INSTALL_PORTABLE)
string(APPEND CMAKE_EXE_LINKER_FLAGS " -no-pie")
endif()
if(WITH_COMPILER_CCACHE)
find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
# Makefiles and ninja
set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" CACHE STRING "" FORCE)
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" CACHE STRING "" FORCE)
else()
message(WARNING "Ccache NOT found, disabling WITH_COMPILER_CCACHE")
set(WITH_COMPILER_CCACHE OFF)
endif()
endif()

View File

@@ -739,7 +739,7 @@ if(WINDOWS_PYTHON_DEBUG)
string(REPLACE "/" "\\" _group_path "${_source_path}")
source_group("${_group_path}" FILES "${_source}")
endforeach()
# If the user scripts env var is set, include scripts from there otherwise
# include user scripts in the profile folder.
if(DEFINED ENV{BLENDER_USER_SCRIPTS})
@@ -750,7 +750,7 @@ if(WINDOWS_PYTHON_DEBUG)
# Include the user scripts from the profile folder in the blender_python_user_scripts project.
set(USER_SCRIPTS_ROOT "$ENV{appdata}/blender foundation/blender/${BLENDER_VERSION}/scripts")
endif()
file(TO_CMAKE_PATH ${USER_SCRIPTS_ROOT} USER_SCRIPTS_ROOT)
FILE(GLOB_RECURSE inFiles "${USER_SCRIPTS_ROOT}/*.*" )
ADD_CUSTOM_TARGET(blender_python_user_scripts SOURCES ${inFiles})

View File

@@ -453,7 +453,7 @@ TYPEDEF_HIDES_STRUCT = NO
# the optimal cache size from a speed point of view.
# Minimum value: 0, maximum value: 9, default value: 0.
LOOKUP_CACHE_SIZE = 3
LOOKUP_CACHE_SIZE = 0
#---------------------------------------------------------------------------
# Build related configuration options
@@ -1321,7 +1321,7 @@ DOCSET_PUBLISHER_NAME = Publisher
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_HTMLHELP = NO
GENERATE_HTMLHELP = YES
# The CHM_FILE tag can be used to specify the file name of the resulting .chm
# file. You can add a path in front of the file if the result should not be

View File

@@ -121,10 +121,6 @@
* \ingroup editors
*/
/** \defgroup edasset asset
* \ingroup editors
*/
/** \defgroup edcurve curve
* \ingroup editors
*/

View File

@@ -1,30 +0,0 @@
"""
.. note::
Properties defined at run-time store the values of the properties as custom-properties.
This method checks if the underlying data exists, causing the property to be considered *set*.
A common pattern for operators is to calculate a value for the properties
that have not had their values explicitly set by the caller
(where the caller could be a key-binding, menu-items or Python script for example).
In the case of executing operators multiple times, values are re-used from the previous execution.
For example: subdividing a mesh with a smooth value of 1.0 will keep using
that value on subsequent calls to subdivision, unless the operator is called with
that property set to a different value.
This behavior can be disabled using the ``SKIP_SAVE`` option when the property is declared (see: :mod:`bpy.props`).
The ``ghost`` argument allows detecting how a value from a previous execution is handled.
- When true: The property is considered unset even if the value from a previous call is used.
- When false: The existence of any values causes ``is_property_set`` to return true.
While this argument should typically be omitted, there are times when
it's important to know if a value is anything besides the default.
For example, the previous value may have been scaled by the scene's unit scale.
In this case scaling the value multiple times would cause problems, so the ``ghost`` argument should be false.
"""

View File

@@ -163,13 +163,13 @@ Now in the button's context menu select *Copy Data Path*, then paste the result
.. code-block:: python
bpy.context.active_object.modifiers["Subdivision"].levels
bpy.context.active_object.modifiers["Subsurf"].levels
Press :kbd:`Return` and you'll get the current value of 1. Now try changing the value to 2:
.. code-block:: python
bpy.context.active_object.modifiers["Subdivision"].levels = 2
bpy.context.active_object.modifiers["Subsurf"].levels = 2
You can see the value update in the Subdivision Surface modifier's UI as well as the cube.
@@ -185,31 +185,43 @@ For example, if you want to access the texture of a brush via Python to adjust i
#. Start in the default scene and enable Sculpt Mode from the 3D Viewport header.
#. From the Sidebar expand the Brush Settings panel's *Texture* subpanel and add a new texture.
*Notice the texture data-block menu itself doesn't have very useful links (you can check the tooltips).*
#. The contrast setting isn't exposed in the Sidebar, so view the texture in the
:ref:`Properties Editor <blender_manual:bpy.types.Texture.contrast`
#. The contrast setting isn't exposed in the Sidebar, so view the texture in the properties editor:
- In the properties editor select the Texture tab.
- Select brush texture.
- Expand the *Colors* panel to locate the *Contrast* number field.
#. Open the context menu of the contrast field and select *Online Python Reference*.
This takes you to ``bpy.types.Texture.contrast``. Now you can see that ``contrast`` is a property of texture.
#. To find out how to access the texture from the brush check on the references at the bottom of the page.
Sometimes there are many references, and it may take some guesswork to find the right one,
but in this case it's ``tool_settings.sculpt.brush.texture``.
but in this case it's ``Brush.texture``.
#. Now you know that the texture can be accessed from ``bpy.data.brushes["BrushName"].texture``
but normally you *won't* want to access the brush by name, instead you want to access the active brush.
So the next step is to check on where brushes are accessed from via the references.
In this case there it is simply ``bpy.context.brush``.
Now you can use the Python console to form the nested properties needed to access brush textures contrast:
:menuselection:`Context --> Tool Settings --> Sculpt --> Brush --> Texture --> Contrast`.
*Context -> Brush -> Texture -> Contrast*.
Since the attribute for each is given along the way you can compose the data path in the Python console:
.. code-block:: python
bpy.context.tool_settings.sculpt.brush.texture.contrast
bpy.context.brush.texture.contrast
There can be multiple ways to access the same data, which you choose often depends on the task.
An alternate path to access the same setting is:
.. code-block:: python
bpy.context.sculpt.brush.texture.contrast
Or access the brush directly:
.. code-block:: python
bpy.data.textures["Texture"].contrast
bpy.data.brushes["BrushName"].texture.contrast
If you are writing a user tool normally you want to use the :mod:`bpy.context` since the user normally expects

View File

@@ -35,13 +35,12 @@ but not to fully cover each topic.
A quick list of helpful things to know before starting:
- Enable :ref:`Developer Extra <blender_manual:prefs-interface-dev-extras`
and :ref:`Python Tooltips <blender_manual:prefs-interface-tooltips-python>`.
- The :ref:`Python Console <blender_manual:bpy.types.SpaceConsole>`
is great for testing one-liners; it has autocompletion so you can inspect the API quickly.
- Button tooltips show Python attributes and operator names (when enabled see above).
- The context menu of buttons directly links to this API documentation (when enabled see above).
- Many python examples can be found in the text editor's template menu.
- Blender uses Python 3.x; some online documentation still assumes version 2.x.
- The interactive console is great for testing one-liners.
It also has autocompletion so you can inspect the API quickly.
- Button tooltips show Python attributes and operator names.
- The context menu of buttons directly links to this API documentation.
- More operator examples can be found in the text editor's template menu.
- To examine further scripts distributed with Blender, see:
- ``scripts/startup/bl_ui`` for the user interface.
@@ -238,7 +237,7 @@ Examples:
{'FINISHED'}
>>> bpy.ops.mesh.hide(unselected=False)
{'FINISHED'}
>>> bpy.ops.object.transform_apply()
>>> bpy.ops.object.scale_apply()
{'FINISHED'}
.. tip::

View File

@@ -24,9 +24,10 @@ The three main use cases for the terminal are:
- If the script runs for too long or you accidentally enter an infinite loop,
:kbd:`Ctrl-C` in the terminal (:kbd:`Ctrl-Break` on Windows) will quit the script early.
.. seealso::
.. note::
:ref:`blender_manual:command_line-launch-index`.
For Linux and macOS users this means starting the terminal first, then running Blender from within it.
On Windows the terminal can be enabled from the Help menu.
Interface Tricks

View File

@@ -551,7 +551,7 @@ def example_extract_docstring(filepath):
file.close()
return "", 0
for line in file:
for line in file.readlines():
line_no += 1
if line.startswith('"""'):
break
@@ -559,13 +559,6 @@ def example_extract_docstring(filepath):
text.append(line.rstrip())
line_no += 1
# Skip over blank lines so the Python code doesn't have blank lines at the top.
for line in file:
if line.strip():
break
line_no += 1
file.close()
return "\n".join(text), line_no

View File

@@ -1,5 +1,7 @@
/* T76453: Prevent Long enum lists */
.field-list li {
/* Prevent Long enum lists */
.field-body {
display: block;
width: 100%;
max-height: 245px;
overflow-y: auto !important;
}

4
extern/README vendored
View File

@@ -1,4 +0,0 @@
When updating a library remember to:
* Update the README.blender with the corresponding version.
* Update the THIRD-PARTY-LICENSE.txt document

View File

@@ -1,5 +0,0 @@
Project: Audaspace
URL: https://audaspace.github.io/
License: Apache 2.0
Upstream version: 1.3 (Last Release)
Local modifications: None

View File

@@ -24,6 +24,6 @@ set(JACK_FOUND ${WITH_JACK})
set(LIBSNDFILE_FOUND ${WITH_CODEC_SNDFILE})
set(OPENAL_FOUND ${WITH_OPENAL})
set(PYTHONLIBS_FOUND TRUE)
set(NUMPY_FOUND ${WITH_PYTHON_NUMPY})
set(NUMPY_FOUND TRUE)
set(NUMPY_INCLUDE_DIRS ${PYTHON_NUMPY_INCLUDE_DIRS})
set(SDL_FOUND ${WITH_SDL})

View File

@@ -72,9 +72,6 @@ protected:
/// The channel mapper reader in between.
std::shared_ptr<ChannelMapperReader> m_mapper;
/// Whether the source is being read for the first time.
bool m_first_reading;
/// Whether to keep the source if end of it is reached.
bool m_keep;

View File

@@ -78,7 +78,7 @@ bool SoftwareDevice::SoftwareHandle::pause(bool keep)
}
SoftwareDevice::SoftwareHandle::SoftwareHandle(SoftwareDevice* device, std::shared_ptr<IReader> reader, std::shared_ptr<PitchReader> pitch, std::shared_ptr<ResampleReader> resampler, std::shared_ptr<ChannelMapperReader> mapper, bool keep) :
m_reader(reader), m_pitch(pitch), m_resampler(resampler), m_mapper(mapper), m_first_reading(true), m_keep(keep), m_user_pitch(1.0f), m_user_volume(1.0f), m_user_pan(0.0f), m_volume(0.0f), m_old_volume(0.0f), m_loopcount(0),
m_reader(reader), m_pitch(pitch), m_resampler(resampler), m_mapper(mapper), m_keep(keep), m_user_pitch(1.0f), m_user_volume(1.0f), m_user_pan(0.0f), m_volume(0.0f), m_old_volume(0.0f), m_loopcount(0),
m_relative(true), m_volume_max(1.0f), m_volume_min(0), m_distance_max(std::numeric_limits<float>::max()),
m_distance_reference(1.0f), m_attenuation(1.0f), m_cone_angle_outer(M_PI), m_cone_angle_inner(M_PI), m_cone_volume_outer(0),
m_flags(RENDER_CONE), m_stop(nullptr), m_stop_data(nullptr), m_status(STATUS_PLAYING), m_device(device)
@@ -106,14 +106,6 @@ void SoftwareDevice::SoftwareHandle::update()
if(m_pitch->getSpecs().channels != CHANNELS_MONO)
{
m_volume = m_user_volume;
// we don't know a previous volume if this source has never been read before
if(m_first_reading)
{
m_old_volume = m_volume;
m_first_reading = false;
}
m_pitch->setPitch(m_user_pitch);
return;
}
@@ -222,13 +214,6 @@ void SoftwareDevice::SoftwareHandle::update()
m_volume *= m_user_volume;
}
// we don't know a previous volume if this source has never been read before
if(m_first_reading)
{
m_old_volume = m_volume;
m_first_reading = false;
}
// 3D Cue
Quaternion orientation;
@@ -769,8 +754,6 @@ void SoftwareDevice::mix(data_t* buffer, int length)
{
m_mixer->mix(buf, pos, len, sound->m_volume, sound->m_old_volume);
sound->m_old_volume = sound->m_volume;
pos += len;
if(sound->m_loopcount > 0)

View File

@@ -22,7 +22,6 @@
#include <mutex>
#define KEEP_TIME 10
#define POSITION_EPSILON (1.0 / static_cast<double>(RATE_48000))
AUD_NAMESPACE_BEGIN
@@ -65,7 +64,7 @@ bool SequenceHandle::updatePosition(double position)
if(m_handle.get())
{
// we currently have a handle, let's check where we are
if(position - POSITION_EPSILON >= m_entry->m_end)
if(position >= m_entry->m_end)
{
if(position >= m_entry->m_end + KEEP_TIME)
// far end, stopping
@@ -77,7 +76,7 @@ bool SequenceHandle::updatePosition(double position)
return true;
}
}
else if(position + POSITION_EPSILON >= m_entry->m_begin)
else if(position >= m_entry->m_begin)
{
// inside, resuming
m_handle->resume();
@@ -99,7 +98,7 @@ bool SequenceHandle::updatePosition(double position)
else
{
// we don't have a handle, let's start if we should be playing
if(position + POSITION_EPSILON >= m_entry->m_begin && position - POSITION_EPSILON <= m_entry->m_end)
if(position >= m_entry->m_begin && position <= m_entry->m_end)
{
start();
return m_valid;

View File

@@ -1,5 +0,0 @@
Project: Bullet Continuous Collision Detection and Physics Library
URL: http://bulletphysics.org
License: zlib
Upstream version: 3.07
Local modifications: Fixed inertia

View File

@@ -1,5 +1,4 @@
Project: Ceres Solver
URL: http://ceres-solver.org/
License: BSD 3-Clause
Upstream version 2.0.0
Local modifications: None

View File

@@ -1,5 +1,5 @@
Project: Curve-Fit-nD
URL: https://github.com/ideasman42/curve-fit-nd
License: BSD 3-Clause
Upstream version: ddcd5bd (Last Release)
Upstream version: Unknown (Last Release)
Local modifications: None

View File

@@ -19,24 +19,20 @@
# ***** END GPL LICENSE BLOCK *****
# Build Draco library.
add_subdirectory(draco)
add_subdirectory(dracoenc)
# Build Draco-Blender bridging module.
# Build blender-draco-exporter module.
set(SRC
src/common.cpp
src/common.h
src/decoder.cpp
src/decoder.h
src/encoder.cpp
src/encoder.h
src/draco-compressor.cpp
src/draco-compressor.h
)
set(INC
draco/src
dracoenc/src
)
set(LIB
draco
dracoenc
)
add_library(extern_draco SHARED "${SRC}")

View File

@@ -1,5 +0,0 @@
Project: Draco
URL: https://google.github.io/draco/
License: Apache 2.0
Upstream version: 1.3.6
Local modifications: None

View File

@@ -1,10 +0,0 @@
#ifndef DRACO_FEATURES_H_
#define DRACO_FEATURES_H_
#define DRACO_MESH_COMPRESSION_SUPPORTED
#define DRACO_NORMAL_ENCODING_SUPPORTED
#define DRACO_STANDARD_EDGEBREAKER_SUPPORTED
#define DRACO_ATTRIBUTE_INDICES_DEDUPLICATION_SUPPORTED
#define DRACO_ATTRIBUTE_VALUES_DEDUPLICATION_SUPPORTED
#endif // DRACO_FEATURES_H_

View File

@@ -2,165 +2,103 @@ remove_strict_flags()
set(SRC
src/draco/animation/keyframe_animation.cc
src/draco/animation/keyframe_animation.h
src/draco/animation/keyframe_animation_decoder.cc
src/draco/animation/keyframe_animation_decoder.h
src/draco/animation/keyframe_animation_encoder.cc
src/draco/animation/keyframe_animation_encoder.h
src/draco/animation/keyframe_animation.h
src/draco/attributes/attribute_octahedron_transform.cc
src/draco/attributes/attribute_octahedron_transform.h
src/draco/attributes/attribute_quantization_transform.cc
src/draco/attributes/attribute_quantization_transform.h
src/draco/attributes/attribute_transform.cc
src/draco/attributes/attribute_transform.h
src/draco/attributes/attribute_transform_data.h
src/draco/attributes/attribute_transform.h
src/draco/attributes/attribute_transform_type.h
src/draco/attributes/geometry_attribute.cc
src/draco/attributes/geometry_attribute.h
src/draco/attributes/geometry_indices.h
src/draco/attributes/point_attribute.cc
src/draco/attributes/point_attribute.h
src/draco/compression/attributes/attributes_decoder.cc
src/draco/compression/attributes/attributes_decoder.h
src/draco/compression/attributes/attributes_decoder_interface.h
src/draco/compression/attributes/attributes_encoder.cc
src/draco/compression/attributes/attributes_encoder.h
src/draco/compression/attributes/kd_tree_attributes_decoder.cc
src/draco/compression/attributes/kd_tree_attributes_decoder.h
src/draco/compression/attributes/kd_tree_attributes_encoder.cc
src/draco/compression/attributes/kd_tree_attributes_encoder.h
src/draco/compression/attributes/kd_tree_attributes_shared.h
src/draco/compression/attributes/linear_sequencer.h
src/draco/compression/attributes/mesh_attribute_indices_encoding_data.h
src/draco/compression/attributes/normal_compression_utils.h
src/draco/compression/attributes/point_d_vector.h
src/draco/compression/attributes/points_sequencer.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_shared.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_data.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_area.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_geometric_normal_predictor_base.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_multi_parallelogram_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_decoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_encoder.h
src/draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_tex_coords_portable_predictor.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_factory.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoder_interface.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_decoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_decoder.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_delta_encoder.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.cc
src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_factory.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoder_interface.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_encoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_factory.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_interface.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_decoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_encoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_canonicalized_transform_base.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_decoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_encoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_normal_octahedron_transform_base.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_decoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_encoding_transform.h
src/draco/compression/attributes/prediction_schemes/prediction_scheme_wrap_transform_base.h
src/draco/compression/attributes/sequential_attribute_decoder.cc
src/draco/compression/attributes/sequential_attribute_decoder.h
src/draco/compression/attributes/sequential_attribute_decoders_controller.cc
src/draco/compression/attributes/sequential_attribute_decoders_controller.h
src/draco/compression/attributes/sequential_attribute_encoder.cc
src/draco/compression/attributes/sequential_attribute_encoder.h
src/draco/compression/attributes/sequential_attribute_encoders_controller.cc
src/draco/compression/attributes/sequential_attribute_encoders_controller.h
src/draco/compression/attributes/sequential_integer_attribute_decoder.cc
src/draco/compression/attributes/sequential_integer_attribute_decoder.h
src/draco/compression/attributes/sequential_integer_attribute_encoder.cc
src/draco/compression/attributes/sequential_integer_attribute_encoder.h
src/draco/compression/attributes/sequential_normal_attribute_decoder.cc
src/draco/compression/attributes/sequential_normal_attribute_decoder.h
src/draco/compression/attributes/sequential_normal_attribute_encoder.cc
src/draco/compression/attributes/sequential_normal_attribute_encoder.h
src/draco/compression/attributes/sequential_quantization_attribute_decoder.cc
src/draco/compression/attributes/sequential_quantization_attribute_decoder.h
src/draco/compression/attributes/sequential_quantization_attribute_encoder.cc
src/draco/compression/attributes/sequential_quantization_attribute_encoder.h
src/draco/compression/bit_coders/adaptive_rans_bit_coding_shared.h
src/draco/compression/bit_coders/adaptive_rans_bit_decoder.cc
src/draco/compression/bit_coders/adaptive_rans_bit_decoder.h
src/draco/compression/bit_coders/adaptive_rans_bit_encoder.cc
src/draco/compression/bit_coders/adaptive_rans_bit_encoder.h
src/draco/compression/bit_coders/direct_bit_decoder.cc
src/draco/compression/bit_coders/direct_bit_decoder.h
src/draco/compression/bit_coders/direct_bit_encoder.cc
src/draco/compression/bit_coders/direct_bit_encoder.h
src/draco/compression/bit_coders/folded_integer_bit_decoder.h
src/draco/compression/bit_coders/folded_integer_bit_encoder.h
src/draco/compression/bit_coders/rans_bit_decoder.cc
src/draco/compression/bit_coders/rans_bit_decoder.h
src/draco/compression/bit_coders/rans_bit_encoder.cc
src/draco/compression/bit_coders/rans_bit_encoder.h
src/draco/compression/bit_coders/symbol_bit_decoder.cc
src/draco/compression/bit_coders/symbol_bit_decoder.h
src/draco/compression/bit_coders/symbol_bit_encoder.cc
src/draco/compression/bit_coders/symbol_bit_encoder.h
src/draco/compression/config/compression_shared.h
src/draco/compression/config/decoder_options.h
src/draco/compression/config/draco_options.h
src/draco/compression/config/encoder_options.h
src/draco/compression/config/encoding_features.h
src/draco/compression/decode.cc
src/draco/compression/decode.h
src/draco/compression/encode_base.h
src/draco/compression/encode.cc
src/draco/compression/encode.h
src/draco/compression/encode_base.h
src/draco/compression/entropy/ans.h
src/draco/compression/entropy/rans_symbol_coding.h
src/draco/compression/entropy/rans_symbol_decoder.h
src/draco/compression/entropy/rans_symbol_encoder.h
src/draco/compression/entropy/shannon_entropy.cc
src/draco/compression/entropy/shannon_entropy.h
src/draco/compression/entropy/symbol_decoding.cc
src/draco/compression/entropy/symbol_decoding.h
src/draco/compression/entropy/symbol_encoding.cc
src/draco/compression/entropy/symbol_encoding.h
src/draco/compression/expert_encode.cc
src/draco/compression/expert_encode.h
src/draco/compression/mesh/mesh_decoder.cc
src/draco/compression/mesh/mesh_decoder.h
src/draco/compression/mesh/mesh_edgebreaker_decoder.cc
src/draco/compression/mesh/mesh_edgebreaker_decoder.h
src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.cc
src/draco/compression/mesh/mesh_edgebreaker_decoder_impl.h
src/draco/compression/mesh/mesh_edgebreaker_decoder_impl_interface.h
src/draco/compression/mesh/mesh_edgebreaker_encoder.cc
src/draco/compression/mesh/mesh_edgebreaker_encoder.h
src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.cc
src/draco/compression/mesh/mesh_edgebreaker_encoder_impl.h
src/draco/compression/mesh/mesh_edgebreaker_encoder_impl_interface.h
src/draco/compression/mesh/mesh_edgebreaker_shared.h
src/draco/compression/mesh/mesh_edgebreaker_traversal_decoder.h
src/draco/compression/mesh/mesh_edgebreaker_traversal_encoder.h
src/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_decoder.h
src/draco/compression/mesh/mesh_edgebreaker_traversal_predictive_encoder.h
src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_decoder.h
src/draco/compression/mesh/mesh_edgebreaker_traversal_valence_encoder.h
src/draco/compression/mesh/mesh_encoder.cc
src/draco/compression/mesh/mesh_encoder.h
src/draco/compression/mesh/mesh_sequential_decoder.cc
src/draco/compression/mesh/mesh_sequential_decoder.h
src/draco/compression/mesh/mesh_encoder_helpers.h
src/draco/compression/mesh/mesh_sequential_encoder.cc
src/draco/compression/mesh/mesh_sequential_encoder.h
src/draco/compression/mesh/traverser/depth_first_traverser.h
@@ -168,32 +106,18 @@ set(SRC
src/draco/compression/mesh/traverser/mesh_attribute_indices_encoding_observer.h
src/draco/compression/mesh/traverser/mesh_traversal_sequencer.h
src/draco/compression/mesh/traverser/traverser_base.h
src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.cc
src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.h
src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.cc
src/draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.h
src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.cc
src/draco/compression/point_cloud/algorithms/float_points_tree_decoder.h
src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.cc
src/draco/compression/point_cloud/algorithms/float_points_tree_encoder.h
src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.cc
src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_decoder.h
src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.cc
src/draco/compression/point_cloud/algorithms/integer_points_kd_tree_encoder.h
src/draco/compression/point_cloud/algorithms/point_cloud_compression_method.h
src/draco/compression/point_cloud/algorithms/point_cloud_types.h
src/draco/compression/point_cloud/algorithms/quantize_points_3.h
src/draco/compression/point_cloud/algorithms/queuing_policy.h
src/draco/compression/point_cloud/point_cloud_decoder.cc
src/draco/compression/point_cloud/point_cloud_decoder.h
src/draco/compression/point_cloud/point_cloud_encoder.cc
src/draco/compression/point_cloud/point_cloud_encoder.h
src/draco/compression/point_cloud/point_cloud_kd_tree_decoder.cc
src/draco/compression/point_cloud/point_cloud_kd_tree_decoder.h
src/draco/compression/point_cloud/point_cloud_kd_tree_encoder.cc
src/draco/compression/point_cloud/point_cloud_kd_tree_encoder.h
src/draco/compression/point_cloud/point_cloud_sequential_decoder.cc
src/draco/compression/point_cloud/point_cloud_sequential_decoder.h
src/draco/compression/point_cloud/point_cloud_sequential_encoder.cc
src/draco/compression/point_cloud/point_cloud_sequential_encoder.h
src/draco/core/bit_utils.cc
@@ -204,15 +128,12 @@ set(SRC
src/draco/core/cycle_timer.h
src/draco/core/data_buffer.cc
src/draco/core/data_buffer.h
src/draco/core/decoder_buffer.cc
src/draco/core/decoder_buffer.h
src/draco/core/divide.cc
src/draco/core/divide.h
src/draco/core/draco_index_type.h
src/draco/core/draco_index_type_vector.h
src/draco/core/draco_types.cc
src/draco/core/draco_types.h
src/draco/core/draco_version.h
src/draco/core/encoder_buffer.cc
src/draco/core/encoder_buffer.h
src/draco/core/hash_utils.cc
@@ -224,21 +145,20 @@ set(SRC
src/draco/core/quantization_utils.cc
src/draco/core/quantization_utils.h
src/draco/core/status.h
src/draco/core/status_or.h
src/draco/core/varint_decoding.h
src/draco/core/statusor.h
src/draco/core/varint_encoding.h
src/draco/core/vector_d.h
src/draco/mesh/corner_table.cc
src/draco/mesh/corner_table.h
src/draco/mesh/corner_table_iterators.h
src/draco/mesh/mesh.cc
src/draco/mesh/mesh.h
src/draco/mesh/mesh_are_equivalent.cc
src/draco/mesh/mesh_are_equivalent.h
src/draco/mesh/mesh_attribute_corner_table.cc
src/draco/mesh/mesh_attribute_corner_table.h
src/draco/mesh/mesh.cc
src/draco/mesh/mesh_cleanup.cc
src/draco/mesh/mesh_cleanup.h
src/draco/mesh/mesh.h
src/draco/mesh/mesh_misc_functions.cc
src/draco/mesh/mesh_misc_functions.h
src/draco/mesh/mesh_stripifier.cc
@@ -249,15 +169,13 @@ set(SRC
src/draco/metadata/geometry_metadata.cc
src/draco/metadata/geometry_metadata.h
src/draco/metadata/metadata.cc
src/draco/metadata/metadata.h
src/draco/metadata/metadata_decoder.cc
src/draco/metadata/metadata_decoder.h
src/draco/metadata/metadata_encoder.cc
src/draco/metadata/metadata_encoder.h
src/draco/point_cloud/point_cloud.cc
src/draco/point_cloud/point_cloud.h
src/draco/metadata/metadata.h
src/draco/point_cloud/point_cloud_builder.cc
src/draco/point_cloud/point_cloud_builder.h
src/draco/point_cloud/point_cloud.cc
src/draco/point_cloud/point_cloud.h
)
set(LIB
@@ -267,4 +185,4 @@ set(INC
src
)
blender_add_lib(draco "${SRC}" "${INC}" "" "${LIB}")
blender_add_lib(dracoenc "${SRC}" "${INC}" "" "${LIB}")

View File

@@ -0,0 +1,3 @@
@PACKAGE_INIT@
set_and_check(draco_INCLUDE_DIR "@PACKAGE_draco_include_install_dir@")
set_and_check(draco_LIBRARY_DIR "@PACKAGE_draco_lib_install_dir@")

View File

@@ -0,0 +1,58 @@
# Finddraco
#
# Locates draco and sets the following variables:
#
# draco_FOUND
# draco_INCLUDE_DIRS
# draco_LIBARY_DIRS
# draco_LIBRARIES
# draco_VERSION_STRING
#
# draco_FOUND is set to YES only when all other variables are successfully
# configured.
unset(draco_FOUND)
unset(draco_INCLUDE_DIRS)
unset(draco_LIBRARY_DIRS)
unset(draco_LIBRARIES)
unset(draco_VERSION_STRING)
mark_as_advanced(draco_FOUND)
mark_as_advanced(draco_INCLUDE_DIRS)
mark_as_advanced(draco_LIBRARY_DIRS)
mark_as_advanced(draco_LIBRARIES)
mark_as_advanced(draco_VERSION_STRING)
set(draco_version_file_no_prefix "draco/src/draco/core/draco_version.h")
# Set draco_INCLUDE_DIRS
find_path(draco_INCLUDE_DIRS NAMES "${draco_version_file_no_prefix}")
# Extract the version string from draco_version.h.
if (draco_INCLUDE_DIRS)
set(draco_version_file
"${draco_INCLUDE_DIRS}/draco/src/draco/core/draco_version.h")
file(STRINGS "${draco_version_file}" draco_version
REGEX "kdracoVersion")
list(GET draco_version 0 draco_version)
string(REPLACE "static const char kdracoVersion[] = " "" draco_version
"${draco_version}")
string(REPLACE ";" "" draco_version "${draco_version}")
string(REPLACE "\"" "" draco_version "${draco_version}")
set(draco_VERSION_STRING ${draco_version})
endif ()
# Find the library.
if (BUILD_SHARED_LIBS)
find_library(draco_LIBRARIES NAMES draco.dll libdraco.dylib libdraco.so)
else ()
find_library(draco_LIBRARIES NAMES draco.lib libdraco.a)
endif ()
# Store path to library.
get_filename_component(draco_LIBRARY_DIRS ${draco_LIBRARIES} DIRECTORY)
if (draco_INCLUDE_DIRS AND draco_LIBRARY_DIRS AND draco_LIBRARIES AND
draco_VERSION_STRING)
set(draco_FOUND YES)
endif ()

View File

@@ -0,0 +1,216 @@
if (NOT DRACO_CMAKE_COMPILER_FLAGS_CMAKE_)
set(DRACO_CMAKE_COMPILER_FLAGS_CMAKE_ 1)
include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag)
include("${draco_root}/cmake/compiler_tests.cmake")
# Strings used to cache failed C/CXX flags.
set(DRACO_FAILED_C_FLAGS)
set(DRACO_FAILED_CXX_FLAGS)
# Checks C compiler for support of $c_flag. Adds $c_flag to $CMAKE_C_FLAGS when
# the compile test passes. Caches $c_flag in $DRACO_FAILED_C_FLAGS when the test
# fails.
macro (add_c_flag_if_supported c_flag)
unset(C_FLAG_FOUND CACHE)
string(FIND "${CMAKE_C_FLAGS}" "${c_flag}" C_FLAG_FOUND)
unset(C_FLAG_FAILED CACHE)
string(FIND "${DRACO_FAILED_C_FLAGS}" "${c_flag}" C_FLAG_FAILED)
if (${C_FLAG_FOUND} EQUAL -1 AND ${C_FLAG_FAILED} EQUAL -1)
unset(C_FLAG_SUPPORTED CACHE)
message("Checking C compiler flag support for: " ${c_flag})
check_c_compiler_flag("${c_flag}" C_FLAG_SUPPORTED)
if (${C_FLAG_SUPPORTED})
string(APPEND CMAKE_C_FLAGS " ${c_flag}" CACHE STRING "")
else ()
string(APPEND DRACO_FAILED_C_FLAGS " ${c_flag}" CACHE STRING
"" FORCE)
endif ()
endif ()
endmacro ()
# Checks C++ compiler for support of $cxx_flag. Adds $cxx_flag to
# $CMAKE_CXX_FLAGS when the compile test passes. Caches $c_flag in
# $DRACO_FAILED_CXX_FLAGS when the test fails.
macro (add_cxx_flag_if_supported cxx_flag)
unset(CXX_FLAG_FOUND CACHE)
string(FIND "${CMAKE_CXX_FLAGS}" "${cxx_flag}" CXX_FLAG_FOUND)
unset(CXX_FLAG_FAILED CACHE)
string(FIND "${DRACO_FAILED_CXX_FLAGS}" "${cxx_flag}" CXX_FLAG_FAILED)
if (${CXX_FLAG_FOUND} EQUAL -1 AND ${CXX_FLAG_FAILED} EQUAL -1)
unset(CXX_FLAG_SUPPORTED CACHE)
message("Checking CXX compiler flag support for: " ${cxx_flag})
check_cxx_compiler_flag("${cxx_flag}" CXX_FLAG_SUPPORTED)
if (${CXX_FLAG_SUPPORTED})
string(APPEND CMAKE_CXX_FLAGS " ${cxx_flag}" CACHE STRING "")
else()
string(APPEND DRACO_FAILED_CXX_FLAGS " ${cxx_flag}" CACHE
STRING "" FORCE)
endif ()
endif ()
endmacro ()
# Convenience method for adding a flag to both the C and C++ compiler command
# lines.
macro (add_compiler_flag_if_supported flag)
add_c_flag_if_supported(${flag})
add_cxx_flag_if_supported(${flag})
endmacro ()
# Checks C compiler for support of $c_flag and terminates generation when
# support is not present.
macro (require_c_flag c_flag update_c_flags)
unset(C_FLAG_FOUND CACHE)
string(FIND "${CMAKE_C_FLAGS}" "${c_flag}" C_FLAG_FOUND)
if (${C_FLAG_FOUND} EQUAL -1)
unset(HAVE_C_FLAG CACHE)
message("Checking C compiler flag support for: " ${c_flag})
check_c_compiler_flag("${c_flag}" HAVE_C_FLAG)
if (NOT ${HAVE_C_FLAG})
message(FATAL_ERROR
"${PROJECT_NAME} requires support for C flag: ${c_flag}.")
endif ()
if (${update_c_flags})
set(CMAKE_C_FLAGS "${c_flag} ${CMAKE_C_FLAGS}" CACHE STRING "" FORCE)
endif ()
endif ()
endmacro ()
# Checks CXX compiler for support of $cxx_flag and terminates generation when
# support is not present.
macro (require_cxx_flag cxx_flag update_cxx_flags)
unset(CXX_FLAG_FOUND CACHE)
string(FIND "${CMAKE_CXX_FLAGS}" "${cxx_flag}" CXX_FLAG_FOUND)
if (${CXX_FLAG_FOUND} EQUAL -1)
unset(HAVE_CXX_FLAG CACHE)
message("Checking CXX compiler flag support for: " ${cxx_flag})
check_cxx_compiler_flag("${cxx_flag}" HAVE_CXX_FLAG)
if (NOT ${HAVE_CXX_FLAG})
message(FATAL_ERROR
"${PROJECT_NAME} requires support for CXX flag: ${cxx_flag}.")
endif ()
if (${update_cxx_flags})
set(CMAKE_CXX_FLAGS "${cxx_flag} ${CMAKE_CXX_FLAGS}" CACHE STRING ""
FORCE)
endif ()
endif ()
endmacro ()
# Checks for support of $flag by both the C and CXX compilers. Terminates
# generation when support is not present in both compilers.
macro (require_compiler_flag flag update_cmake_flags)
require_c_flag(${flag} ${update_cmake_flags})
require_cxx_flag(${flag} ${update_cmake_flags})
endmacro ()
# Checks only non-MSVC targets for support of $c_flag and terminates generation
# when support is not present.
macro (require_c_flag_nomsvc c_flag update_c_flags)
if (NOT MSVC)
require_c_flag(${c_flag} ${update_c_flags})
endif ()
endmacro ()
# Checks only non-MSVC targets for support of $cxx_flag and terminates
# generation when support is not present.
macro (require_cxx_flag_nomsvc cxx_flag update_cxx_flags)
if (NOT MSVC)
require_cxx_flag(${cxx_flag} ${update_cxx_flags})
endif ()
endmacro ()
# Checks only non-MSVC targets for support of $flag by both the C and CXX
# compilers. Terminates generation when support is not present in both
# compilers.
macro (require_compiler_flag_nomsvc flag update_cmake_flags)
require_c_flag_nomsvc(${flag} ${update_cmake_flags})
require_cxx_flag_nomsvc(${flag} ${update_cmake_flags})
endmacro ()
# Adds $flag to assembler command line.
macro (append_as_flag flag)
unset(AS_FLAG_FOUND CACHE)
string(FIND "${DRACO_AS_FLAGS}" "${flag}" AS_FLAG_FOUND)
if (${AS_FLAG_FOUND} EQUAL -1)
string(APPEND DRACO_AS_FLAGS " ${flag}")
endif ()
endmacro ()
# Adds $flag to the C compiler command line.
macro (append_c_flag flag)
unset(C_FLAG_FOUND CACHE)
string(FIND "${CMAKE_C_FLAGS}" "${flag}" C_FLAG_FOUND)
if (${C_FLAG_FOUND} EQUAL -1)
string(APPEND CMAKE_C_FLAGS " ${flag}")
endif ()
endmacro ()
# Adds $flag to the CXX compiler command line.
macro (append_cxx_flag flag)
unset(CXX_FLAG_FOUND CACHE)
string(FIND "${CMAKE_CXX_FLAGS}" "${flag}" CXX_FLAG_FOUND)
if (${CXX_FLAG_FOUND} EQUAL -1)
string(APPEND CMAKE_CXX_FLAGS " ${flag}")
endif ()
endmacro ()
# Adds $flag to the C and CXX compiler command lines.
macro (append_compiler_flag flag)
append_c_flag(${flag})
append_cxx_flag(${flag})
endmacro ()
# Adds $flag to the executable linker command line.
macro (append_exe_linker_flag flag)
unset(LINKER_FLAG_FOUND CACHE)
string(FIND "${CMAKE_EXE_LINKER_FLAGS}" "${flag}" LINKER_FLAG_FOUND)
if (${LINKER_FLAG_FOUND} EQUAL -1)
string(APPEND CMAKE_EXE_LINKER_FLAGS " ${flag}")
endif ()
endmacro ()
# Adds $flag to the link flags for $target.
function (append_link_flag_to_target target flags)
unset(target_link_flags)
get_target_property(target_link_flags ${target} LINK_FLAGS)
if (target_link_flags)
unset(link_flag_found)
string(FIND "${target_link_flags}" "${flags}" link_flag_found)
if (NOT ${link_flag_found} EQUAL -1)
return()
endif ()
string(APPEND target_link_flags " ${flags}")
else ()
set(target_link_flags "${flags}")
endif ()
set_target_properties(${target} PROPERTIES LINK_FLAGS ${target_link_flags})
endfunction ()
# Adds $flag to executable linker flags, and makes sure C/CXX builds still work.
macro (require_linker_flag flag)
append_exe_linker_flag(${flag})
unset(c_passed)
draco_check_c_compiles("LINKER_FLAG_C_TEST(${flag})" "" c_passed)
unset(cxx_passed)
draco_check_cxx_compiles("LINKER_FLAG_CXX_TEST(${flag})" "" cxx_passed)
if (NOT c_passed OR NOT cxx_passed)
message(FATAL_ERROR "Linker flag test for ${flag} failed.")
endif ()
endmacro ()
endif () # DRACO_CMAKE_COMPILER_FLAGS_CMAKE_

View File

@@ -0,0 +1,124 @@
if (NOT DRACO_CMAKE_COMPILER_TESTS_CMAKE_)
set(DRACO_CMAKE_COMPILER_TESTS_CMAKE_ 1)
include(CheckCSourceCompiles)
include(CheckCXXSourceCompiles)
# The basic main() macro used in all compile tests.
set(DRACO_C_MAIN "\nint main(void) { return 0; }")
set(DRACO_CXX_MAIN "\nint main() { return 0; }")
# Strings containing the names of passed and failed tests.
set(DRACO_C_PASSED_TESTS)
set(DRACO_C_FAILED_TESTS)
set(DRACO_CXX_PASSED_TESTS)
set(DRACO_CXX_FAILED_TESTS)
macro(draco_push_var var new_value)
set(SAVED_${var} ${var})
set(${var} ${new_value})
endmacro ()
macro(draco_pop_var var)
set(var ${SAVED_${var}})
unset(SAVED_${var})
endmacro ()
# Confirms $test_source compiles and stores $test_name in one of
# $DRACO_C_PASSED_TESTS or $DRACO_C_FAILED_TESTS depending on out come. When the
# test passes $result_var is set to 1. When it fails $result_var is unset.
# The test is not run if the test name is found in either of the passed or
# failed test variables.
macro(draco_check_c_compiles test_name test_source result_var)
unset(C_TEST_PASSED CACHE)
unset(C_TEST_FAILED CACHE)
string(FIND "${DRACO_C_PASSED_TESTS}" "${test_name}" C_TEST_PASSED)
string(FIND "${DRACO_C_FAILED_TESTS}" "${test_name}" C_TEST_FAILED)
if (${C_TEST_PASSED} EQUAL -1 AND ${C_TEST_FAILED} EQUAL -1)
unset(C_TEST_COMPILED CACHE)
message("Running C compiler test: ${test_name}")
check_c_source_compiles("${test_source} ${DRACO_C_MAIN}" C_TEST_COMPILED)
set(${result_var} ${C_TEST_COMPILED})
if (${C_TEST_COMPILED})
string(APPEND DRACO_C_PASSED_TESTS " ${test_name}")
else ()
string(APPEND DRACO_C_FAILED_TESTS " ${test_name}")
message("C Compiler test ${test_name} failed.")
endif ()
elseif (NOT ${C_TEST_PASSED} EQUAL -1)
set(${result_var} 1)
else () # ${C_TEST_FAILED} NOT EQUAL -1
unset(${result_var})
endif ()
endmacro ()
# Confirms $test_source compiles and stores $test_name in one of
# $DRACO_CXX_PASSED_TESTS or $DRACO_CXX_FAILED_TESTS depending on out come. When
# the test passes $result_var is set to 1. When it fails $result_var is unset.
# The test is not run if the test name is found in either of the passed or
# failed test variables.
macro(draco_check_cxx_compiles test_name test_source result_var)
unset(CXX_TEST_PASSED CACHE)
unset(CXX_TEST_FAILED CACHE)
string(FIND "${DRACO_CXX_PASSED_TESTS}" "${test_name}" CXX_TEST_PASSED)
string(FIND "${DRACO_CXX_FAILED_TESTS}" "${test_name}" CXX_TEST_FAILED)
if (${CXX_TEST_PASSED} EQUAL -1 AND ${CXX_TEST_FAILED} EQUAL -1)
unset(CXX_TEST_COMPILED CACHE)
message("Running CXX compiler test: ${test_name}")
check_cxx_source_compiles("${test_source} ${DRACO_CXX_MAIN}"
CXX_TEST_COMPILED)
set(${result_var} ${CXX_TEST_COMPILED})
if (${CXX_TEST_COMPILED})
string(APPEND DRACO_CXX_PASSED_TESTS " ${test_name}")
else ()
string(APPEND DRACO_CXX_FAILED_TESTS " ${test_name}")
message("CXX Compiler test ${test_name} failed.")
endif ()
elseif (NOT ${CXX_TEST_PASSED} EQUAL -1)
set(${result_var} 1)
else () # ${CXX_TEST_FAILED} NOT EQUAL -1
unset(${result_var})
endif ()
endmacro ()
# Convenience macro that confirms $test_source compiles as C and C++.
# $result_var is set to 1 when both tests are successful, and 0 when one or both
# tests fail.
# Note: This macro is intended to be used to write to result variables that
# are expanded via configure_file(). $result_var is set to 1 or 0 to allow
# direct usage of the value in generated source files.
macro(draco_check_source_compiles test_name test_source result_var)
unset(C_PASSED)
unset(CXX_PASSED)
draco_check_c_compiles(${test_name} ${test_source} C_PASSED)
draco_check_cxx_compiles(${test_name} ${test_source} CXX_PASSED)
if (${C_PASSED} AND ${CXX_PASSED})
set(${result_var} 1)
else ()
set(${result_var} 0)
endif ()
endmacro ()
# When inline support is detected for the current compiler the supported
# inlining keyword is written to $result in caller scope.
macro (draco_get_inline result)
draco_check_source_compiles("inline_check_1"
"static inline void macro(void) {}"
HAVE_INLINE_1)
if (HAVE_INLINE_1 EQUAL 1)
set(${result} "inline")
return()
endif ()
# Check __inline.
draco_check_source_compiles("inline_check_2"
"static __inline void macro(void) {}"
HAVE_INLINE_2)
if (HAVE_INLINE_2 EQUAL 1)
set(${result} "__inline")
endif ()
endmacro ()
endif () # DRACO_CMAKE_COMPILER_TESTS_CMAKE_

View File

@@ -0,0 +1,57 @@
if (NOT DRACO_CMAKE_DRACO_FEATURES_CMAKE_)
set(DRACO_CMAKE_DRACO_FEATURES_CMAKE_ 1)
set(draco_features_file_name "${draco_build_dir}/draco/draco_features.h")
set(draco_features_list)
# Macro that handles tracking of Draco preprocessor symbols for the purpose of
# producing draco_features.h.
#
# draco_enable_feature(FEATURE <feature_name> [TARGETS <target_name>])
# FEATURE is required. It should be a Draco preprocessor symbol.
# TARGETS is optional. It can be one or more draco targets.
#
# When the TARGETS argument is not present the preproc symbol is added to
# draco_features.h. When it is draco_features.h is unchanged, and
# target_compile_options() is called for each target specified.
macro (draco_enable_feature)
set(def_flags)
set(def_single_arg_opts FEATURE)
set(def_multi_arg_opts TARGETS)
cmake_parse_arguments(DEF "${def_flags}" "${def_single_arg_opts}"
"${def_multi_arg_opts}" ${ARGN})
if ("${DEF_FEATURE}" STREQUAL "")
message(FATAL_ERROR "Empty FEATURE passed to draco_enable_feature().")
endif ()
# Do nothing/return early if $DEF_FEATURE is already in the list.
list(FIND draco_features_list ${DEF_FEATURE} df_index)
if (NOT df_index EQUAL -1)
return ()
endif ()
list(LENGTH DEF_TARGETS df_targets_list_length)
if (${df_targets_list_length} EQUAL 0)
list(APPEND draco_features_list ${DEF_FEATURE})
else ()
foreach (target ${DEF_TARGETS})
target_compile_definitions(${target} PRIVATE ${DEF_FEATURE})
endforeach ()
endif ()
endmacro ()
# Function for generating draco_features.h.
function (draco_generate_features_h)
file(WRITE "${draco_features_file_name}"
"// GENERATED FILE -- DO NOT EDIT\n\n"
"#ifndef DRACO_FEATURES_H_\n"
"#define DRACO_FEATURES_H_\n\n")
foreach (feature ${draco_features_list})
file(APPEND "${draco_features_file_name}" "#define ${feature}\n")
endforeach ()
file(APPEND "${draco_features_file_name}" "\n#endif // DRACO_FEATURES_H_")
endfunction ()
endif () # DRACO_CMAKE_DRACO_FEATURES_CMAKE_

View File

@@ -0,0 +1,13 @@
#ifndef DRACO_TESTING_DRACO_TEST_CONFIG_H_
#define DRACO_TESTING_DRACO_TEST_CONFIG_H_
// If this file is named draco_test_config.h.cmake:
// This file is used as input at cmake generation time.
// If this file is named draco_test_config.h:
// GENERATED FILE, DO NOT EDIT. SEE ABOVE.
#define DRACO_TEST_DATA_DIR "${DRACO_TEST_DATA_DIR}"
#define DRACO_TEST_TEMP_DIR "${DRACO_TEST_TEMP_DIR}"
#endif // DRACO_TESTING_DRACO_TEST_CONFIG_H_

View File

@@ -0,0 +1,21 @@
// If this file is named draco_version.cc.cmake:
// This file is used as input at cmake generation time.
// If this file is named draco_version.cc:
// GENERATED FILE, DO NOT EDIT. SEE ABOVE.
#include "draco_version.h"
static const char kDracoGitHash[] = "${draco_git_hash}";
static const char kDracoGitDesc[] = "${draco_git_desc}";
const char *draco_git_hash() {
return kDracoGitHash;
}
const char *draco_git_version() {
return kDracoGitDesc;
}
const char* draco_version() {
return draco::Version();
}

View File

@@ -0,0 +1,21 @@
// If this file is named draco_version.h.cmake:
// This file is used as input at cmake generation time.
// If this file is named draco_version.h:
// GENERATED FILE, DO NOT EDIT. SEE ABOVE.
#ifndef DRACO_DRACO_VERSION_H_
#define DRACO_DRACO_VERSION_H_
#include "draco/core/draco_version.h"
// Returns git hash of Draco git repository.
const char *draco_git_hash();
// Returns the output of the git describe command when run from the Draco git
// repository.
const char *draco_git_version();
// Returns the version string from core/draco_version.h.
const char* draco_version();
#endif // DRACO_DRACO_VERSION_H_

View File

@@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.2)
if (MSVC)
# Use statically linked versions of the MS standard libraries.
if (NOT "${MSVC_RUNTIME}" STREQUAL "dll")
foreach (flag_var
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if (${flag_var} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
endif ()
endforeach ()
endif ()
endif ()

View File

@@ -0,0 +1,19 @@
if (NOT DRACO_CMAKE_SANITIZERS_CMAKE_)
set(DRACO_CMAKE_SANITIZERS_CMAKE_ 1)
if (MSVC OR NOT SANITIZE)
return ()
endif ()
include("${draco_root}/cmake/compiler_flags.cmake")
string(TOLOWER ${SANITIZE} SANITIZE)
# Require the sanitizer requested.
require_linker_flag("-fsanitize=${SANITIZE}")
require_compiler_flag("-fsanitize=${SANITIZE}" YES)
# Make callstacks accurate.
require_compiler_flag("-fno-omit-frame-pointer -fno-optimize-sibling-calls" YES)
endif() # DRACO_CMAKE_SANITIZERS_CMAKE_

View File

@@ -0,0 +1,13 @@
if (NOT DRACO_CMAKE_TOOLCHAINS_ARM_IOS_COMMON_CMAKE_)
set(DRACO_CMAKE_ARM_IOS_COMMON_CMAKE_ 1)
set(CMAKE_SYSTEM_NAME "Darwin")
set(CMAKE_OSX_SYSROOT iphoneos)
set(CMAKE_C_COMPILER clang)
set(CMAKE_C_COMPILER_ARG1 "-arch ${CMAKE_SYSTEM_PROCESSOR}")
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_CXX_COMPILER_ARG1 "-arch ${CMAKE_SYSTEM_PROCESSOR}")
# TODO(tomfinegan): Handle bit code embedding.
endif () # DRACO_CMAKE_TOOLCHAINS_ARM_IOS_COMMON_CMAKE_

View File

@@ -0,0 +1,12 @@
if (NOT DRACO_CMAKE_TOOLCHAINS_ARM64_ANDROID_NDK_LIBCPP_CMAKE_)
set(DRACO_CMAKE_TOOLCHAINS_ARM64_ANDROID_NDK_LIBCPP_CMAKE_ 1)
include("${CMAKE_CURRENT_LIST_DIR}/../util.cmake")
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)
require_variable(CMAKE_ANDROID_NDK)
set_variable_if_unset(CMAKE_SYSTEM_VERSION 21)
set_variable_if_unset(CMAKE_ANDROID_STL_TYPE c++_static)
endif () # DRACO_CMAKE_TOOLCHAINS_ARM64_ANDROID_NDK_LIBCPP_CMAKE_

View File

@@ -0,0 +1,14 @@
if (NOT DRACO_CMAKE_TOOLCHAINS_ARM64_IOS_CMAKE_)
set(DRACO_CMAKE_TOOLCHAINS_ARM64_IOS_CMAKE_ 1)
if (XCODE)
# TODO(tomfinegan): Handle arm builds in Xcode.
message(FATAL_ERROR "This toolchain does not support Xcode.")
endif ()
set(CMAKE_SYSTEM_PROCESSOR "arm64")
set(CMAKE_OSX_ARCHITECTURES "arm64")
include("${CMAKE_CURRENT_LIST_DIR}/arm-ios-common.cmake")
endif () # DRACO_CMAKE_TOOLCHAINS_ARM64_IOS_CMAKE_

View File

@@ -0,0 +1,18 @@
if (NOT DRACO_CMAKE_TOOLCHAINS_ARM64_LINUX_GCC_CMAKE_)
set(DRACO_CMAKE_TOOLCHAINS_ARM64_LINUX_GCC_CMAKE_ 1)
set(CMAKE_SYSTEM_NAME "Linux")
if ("${CROSS}" STREQUAL "")
# Default the cross compiler prefix to something known to work.
set(CROSS aarch64-linux-gnu-)
endif ()
set(CMAKE_C_COMPILER ${CROSS}gcc)
set(CMAKE_CXX_COMPILER ${CROSS}g++)
set(AS_EXECUTABLE ${CROSS}as)
set(CMAKE_C_COMPILER_ARG1 "-march=armv8-a")
set(CMAKE_CXX_COMPILER_ARG1 "-march=armv8-a")
set(CMAKE_SYSTEM_PROCESSOR "arm64")
endif () # DRACO_CMAKE_TOOLCHAINS_ARM64_LINUX_GCC_CMAKE_

View File

@@ -0,0 +1,12 @@
if (NOT DRACO_CMAKE_TOOLCHAINS_ARMV7_ANDROID_NDK_LIBCPP_CMAKE_)
set(DRACO_CMAKE_TOOLCHAINS_ARMV7_ANDROID_NDK_LIBCPP_CMAKE_ 1)
include("${CMAKE_CURRENT_LIST_DIR}/../util.cmake")
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_ANDROID_ARCH_ABI armeabi-v7a)
require_variable(CMAKE_ANDROID_NDK)
set_variable_if_unset(CMAKE_SYSTEM_VERSION 18)
set_variable_if_unset(CMAKE_ANDROID_STL_TYPE c++_static)
endif () # DRACO_CMAKE_TOOLCHAINS_ARMV7_ANDROID_NDK_LIBCPP_CMAKE_

View File

@@ -0,0 +1,14 @@
if (NOT DRACO_CMAKE_TOOLCHAINS_ARMV7_IOS_CMAKE_)
set(DRACO_CMAKE_TOOLCHAINS_ARMV7_IOS_CMAKE_ 1)
if (XCODE)
# TODO(tomfinegan): Handle arm builds in Xcode.
message(FATAL_ERROR "This toolchain does not support Xcode.")
endif ()
set(CMAKE_SYSTEM_PROCESSOR "armv7")
set(CMAKE_OSX_ARCHITECTURES "armv7")
include("${CMAKE_CURRENT_LIST_DIR}/arm-ios-common.cmake")
endif () # DRACO_CMAKE_TOOLCHAINS_ARMV7_IOS_CMAKE_

View File

@@ -0,0 +1,24 @@
if (NOT DRACO_CMAKE_TOOLCHAINS_ARMV7_LINUX_GCC_CMAKE_)
set(DRACO_CMAKE_TOOLCHAINS_ARMV7_LINUX_GCC_CMAKE_ 1)
set(CMAKE_SYSTEM_NAME "Linux")
if ("${CROSS}" STREQUAL "")
# Default the cross compiler prefix to something known to work.
set(CROSS arm-linux-gnueabihf-)
endif ()
if (NOT ${CROSS} MATCHES hf-$)
set(DRACO_EXTRA_TOOLCHAIN_FLAGS "-mfloat-abi=softfp")
endif ()
set(CMAKE_C_COMPILER ${CROSS}gcc)
set(CMAKE_CXX_COMPILER ${CROSS}g++)
set(AS_EXECUTABLE ${CROSS}as)
set(CMAKE_C_COMPILER_ARG1
"-march=armv7-a -mfpu=neon ${DRACO_EXTRA_TOOLCHAIN_FLAGS}")
set(CMAKE_CXX_COMPILER_ARG1
"-march=armv7-a -mfpu=neon ${DRACO_EXTRA_TOOLCHAIN_FLAGS}")
set(CMAKE_SYSTEM_PROCESSOR "armv7")
endif () # DRACO_CMAKE_TOOLCHAINS_ARMV7_LINUX_GCC_CMAKE_

View File

@@ -0,0 +1,14 @@
if (NOT DRACO_CMAKE_TOOLCHAINS_ARMV7S_IOS_CMAKE_)
set(DRACO_CMAKE_TOOLCHAINS_ARMV7S_IOS_CMAKE_ 1)
if (XCODE)
# TODO(tomfinegan): Handle arm builds in Xcode.
message(FATAL_ERROR "This toolchain does not support Xcode.")
endif ()
set(CMAKE_SYSTEM_PROCESSOR "armv7s")
set(CMAKE_OSX_ARCHITECTURES "armv7s")
include("${CMAKE_CURRENT_LIST_DIR}/arm-ios-common.cmake")
endif () # DRACO_CMAKE_TOOLCHAINS_ARMV7S_IOS_CMAKE_

View File

@@ -0,0 +1,12 @@
if (NOT DRACO_CMAKE_TOOLCHAINS_X86_ANDROID_NDK_LIBCPP_CMAKE_)
set(DRACO_CMAKE_TOOLCHAINS_X86_ANDROID_NDK_LIBCPP_CMAKE_ 1)
include("${CMAKE_CURRENT_LIST_DIR}/../util.cmake")
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_ANDROID_ARCH_ABI x86)
require_variable(CMAKE_ANDROID_NDK)
set_variable_if_unset(CMAKE_SYSTEM_VERSION 18)
set_variable_if_unset(CMAKE_ANDROID_STL_TYPE c++_static)
endif () # DRACO_CMAKE_TOOLCHAINS_X86_ANDROID_NDK_LIBCPP_CMAKE_

View File

@@ -0,0 +1,12 @@
if (NOT DRACO_CMAKE_TOOLCHAINS_X86_64_ANDROID_NDK_LIBCPP_CMAKE_)
set(DRACO_CMAKE_TOOLCHAINS_X86_64_ANDROID_NDK_LIBCPP_CMAKE_ 1)
include("${CMAKE_CURRENT_LIST_DIR}/../util.cmake")
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_ANDROID_ARCH_ABI x86_64)
require_variable(CMAKE_ANDROID_NDK)
set_variable_if_unset(CMAKE_SYSTEM_VERSION 21)
set_variable_if_unset(CMAKE_ANDROID_STL_TYPE c++_static)
endif () # DRACO_CMAKE_TOOLCHAINS_X86_64_ANDROID_NDK_LIBCPP_CMAKE_

73
extern/draco/dracoenc/cmake/util.cmake vendored Normal file
View File

@@ -0,0 +1,73 @@
if (NOT DRACO_CMAKE_UTIL_CMAKE_)
set(DRACO_CMAKE_UTIL_CMAKE_ 1)
# Creates dummy source file in $draco_build_dir named $basename.$extension and
# returns the full path to the dummy source file via the $out_file_path
# parameter.
function (create_dummy_source_file basename extension out_file_path)
set(dummy_source_file "${draco_build_dir}/${basename}.${extension}")
file(WRITE "${dummy_source_file}"
"// Generated file. DO NOT EDIT!\n"
"// ${target_name} needs a ${extension} file to force link language, \n"
"// or to silence a harmless CMake warning: Ignore me.\n"
"void ${target_name}_dummy_function(void) {}\n")
set(${out_file_path} ${dummy_source_file} PARENT_SCOPE)
endfunction ()
# Convenience function for adding a dummy source file to $target_name using
# $extension as the file extension. Wraps create_dummy_source_file().
function (add_dummy_source_file_to_target target_name extension)
create_dummy_source_file("${target_name}" "${extension}" "dummy_source_file")
target_sources(${target_name} PRIVATE ${dummy_source_file})
endfunction ()
# Extracts the version number from $version_file and returns it to the user via
# $version_string_out_var. This is achieved by finding the first instance of
# the kDracoVersion variable and then removing everything but the string literal
# assigned to the variable. Quotes and semicolon are stripped from the returned
# string.
function (extract_version_string version_file version_string_out_var)
file(STRINGS "${version_file}" draco_version REGEX "kDracoVersion")
list(GET draco_version 0 draco_version)
string(REPLACE "static const char kDracoVersion[] = " "" draco_version
"${draco_version}")
string(REPLACE ";" "" draco_version "${draco_version}")
string(REPLACE "\"" "" draco_version "${draco_version}")
set("${version_string_out_var}" "${draco_version}" PARENT_SCOPE)
endfunction ()
# Sets CMake compiler launcher to $launcher_name when $launcher_name is found in
# $PATH. Warns user about ignoring build flag $launcher_flag when $launcher_name
# is not found in $PATH.
function (set_compiler_launcher launcher_flag launcher_name)
find_program(launcher_path "${launcher_name}")
if (launcher_path)
set(CMAKE_C_COMPILER_LAUNCHER "${launcher_path}" PARENT_SCOPE)
set(CMAKE_CXX_COMPILER_LAUNCHER "${launcher_path}" PARENT_SCOPE)
message("--- Using ${launcher_name} as compiler launcher.")
else ()
message(WARNING
"--- Cannot find ${launcher_name}, ${launcher_flag} ignored.")
endif ()
endfunction ()
# Terminates CMake execution when $var_name is unset in the environment. Sets
# CMake variable to the value of the environment variable when the variable is
# present in the environment.
macro(require_variable var_name)
if ("$ENV{${var_name}}" STREQUAL "")
message(FATAL_ERROR "${var_name} must be set in environment.")
endif ()
set_variable_if_unset(${var_name} "")
endmacro ()
# Sets $var_name to $default_value if not already set in the environment.
macro (set_variable_if_unset var_name default_value)
if (NOT "$ENV{${var_name}}" STREQUAL "")
set(${var_name} $ENV{${var_name}})
else ()
set(${var_name} ${default_value})
endif ()
endmacro ()
endif() # DRACO_CMAKE_UTIL_CMAKE_

View File

@@ -29,9 +29,8 @@ bool KeyframeAnimation::SetTimestamps(
} else {
// Check if the number of frames is consistent with
// the existing keyframes.
if (num_frames != num_points()) {
if (num_frames != num_points())
return false;
}
}
} else {
// This is the first attribute.
@@ -41,8 +40,10 @@ bool KeyframeAnimation::SetTimestamps(
// Add attribute for time stamp data.
std::unique_ptr<PointAttribute> timestamp_att =
std::unique_ptr<PointAttribute>(new PointAttribute());
timestamp_att->Init(GeometryAttribute::GENERIC, 1, DT_FLOAT32, false,
num_frames);
timestamp_att->Init(GeometryAttribute::GENERIC, nullptr, 1, DT_FLOAT32, false,
sizeof(float), 0);
timestamp_att->SetIdentityMapping();
timestamp_att->Reset(num_frames);
for (PointIndex i(0); i < num_frames; ++i) {
timestamp_att->SetAttributeValue(timestamp_att->mapped_index(i),
&timestamp[i.value()]);

View File

@@ -71,29 +71,30 @@ int32_t KeyframeAnimation::AddKeyframes(DataType data_type,
uint32_t num_components,
const std::vector<T> &data) {
// TODO(draco-eng): Verify T is consistent with |data_type|.
if (num_components == 0) {
if (num_components == 0)
return -1;
}
// If timestamps is not added yet, then reserve attribute 0 for timestamps.
if (!num_attributes()) {
// Add a temporary attribute with 0 points to fill attribute id 0.
std::unique_ptr<PointAttribute> temp_att =
std::unique_ptr<PointAttribute>(new PointAttribute());
temp_att->Init(GeometryAttribute::GENERIC, num_components, data_type, false,
0);
temp_att->Init(GeometryAttribute::GENERIC, nullptr, num_components,
data_type, false, DataTypeLength(data_type), 0);
temp_att->Reset(0);
this->AddAttribute(std::move(temp_att));
set_num_frames(data.size() / num_components);
}
if (data.size() != num_components * num_frames()) {
if (data.size() != num_components * num_frames())
return -1;
}
std::unique_ptr<PointAttribute> keyframe_att =
std::unique_ptr<PointAttribute>(new PointAttribute());
keyframe_att->Init(GeometryAttribute::GENERIC, num_components, data_type,
false, num_frames());
keyframe_att->Init(GeometryAttribute::GENERIC, nullptr, num_components,
data_type, false, DataTypeLength(data_type), 0);
keyframe_att->SetIdentityMapping();
keyframe_att->Reset(num_frames());
const size_t stride = num_components;
for (PointIndex i(0); i < num_frames(); ++i) {
keyframe_att->SetAttributeValue(keyframe_att->mapped_index(i),

View File

@@ -21,9 +21,8 @@ Status KeyframeAnimationDecoder::Decode(const DecoderOptions &options,
KeyframeAnimation *animation) {
const auto status = PointCloudSequentialDecoder::Decode(
options, in_buffer, static_cast<PointCloud *>(animation));
if (!status.ok()) {
if (!status.ok())
return status;
}
return OkStatus();
}

View File

@@ -0,0 +1,168 @@
// Copyright 2017 The Draco Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "draco/animation/keyframe_animation.h"
#include "draco/animation/keyframe_animation_decoder.h"
#include "draco/animation/keyframe_animation_encoder.h"
#include "draco/core/draco_test_base.h"
#include "draco/core/draco_test_utils.h"
namespace draco {
class KeyframeAnimationEncodingTest : public ::testing::Test {
protected:
KeyframeAnimationEncodingTest() {}
bool CreateAndAddTimestamps(int32_t num_frames) {
timestamps_.resize(num_frames);
for (int i = 0; i < timestamps_.size(); ++i)
timestamps_[i] = static_cast<draco::KeyframeAnimation::TimestampType>(i);
return keyframe_animation_.SetTimestamps(timestamps_);
}
int32_t CreateAndAddAnimationData(int32_t num_frames,
uint32_t num_components) {
// Create and add animation data with.
animation_data_.resize(num_frames * num_components);
for (int i = 0; i < animation_data_.size(); ++i)
animation_data_[i] = static_cast<float>(i);
return keyframe_animation_.AddKeyframes(draco::DT_FLOAT32, num_components,
animation_data_);
}
template <int num_components_t>
void CompareAnimationData(const KeyframeAnimation &animation0,
const KeyframeAnimation &animation1,
bool quantized) {
ASSERT_EQ(animation0.num_frames(), animation1.num_frames());
ASSERT_EQ(animation0.num_animations(), animation1.num_animations());
if (quantized) {
// TODO(hemmer) : Add test for stable quantization.
// Quantization will result in slightly different values.
// Skip comparing values.
return;
}
// Compare time stamp.
const auto timestamp_att0 = animation0.timestamps();
const auto timestamp_att1 = animation0.timestamps();
for (int i = 0; i < animation0.num_frames(); ++i) {
std::array<float, 1> att_value0;
std::array<float, 1> att_value1;
ASSERT_TRUE((timestamp_att0->GetValue<float, 1>(
draco::AttributeValueIndex(i), &att_value0)));
ASSERT_TRUE((timestamp_att1->GetValue<float, 1>(
draco::AttributeValueIndex(i), &att_value1)));
ASSERT_FLOAT_EQ(att_value0[0], att_value1[0]);
}
for (int animation_id = 1; animation_id < animation0.num_animations();
++animation_id) {
// Compare keyframe data.
const auto keyframe_att0 = animation0.keyframes(animation_id);
const auto keyframe_att1 = animation1.keyframes(animation_id);
ASSERT_EQ(keyframe_att0->num_components(),
keyframe_att1->num_components());
for (int i = 0; i < animation0.num_frames(); ++i) {
std::array<float, num_components_t> att_value0;
std::array<float, num_components_t> att_value1;
ASSERT_TRUE((keyframe_att0->GetValue<float, num_components_t>(
draco::AttributeValueIndex(i), &att_value0)));
ASSERT_TRUE((keyframe_att1->GetValue<float, num_components_t>(
draco::AttributeValueIndex(i), &att_value1)));
for (int j = 0; j < att_value0.size(); ++j) {
ASSERT_FLOAT_EQ(att_value0[j], att_value1[j]);
}
}
}
}
template <int num_components_t>
void TestKeyframeAnimationEncoding() {
TestKeyframeAnimationEncoding<num_components_t>(false);
}
template <int num_components_t>
void TestKeyframeAnimationEncoding(bool quantized) {
// Encode animation class.
draco::EncoderBuffer buffer;
draco::KeyframeAnimationEncoder encoder;
EncoderOptions options = EncoderOptions::CreateDefaultOptions();
if (quantized) {
// Set quantization for timestamps.
options.SetAttributeInt(0, "quantization_bits", 20);
// Set quantization for keyframes.
for (int i = 1; i <= keyframe_animation_.num_animations(); ++i) {
options.SetAttributeInt(i, "quantization_bits", 20);
}
}
ASSERT_TRUE(
encoder.EncodeKeyframeAnimation(keyframe_animation_, options, &buffer)
.ok());
draco::DecoderBuffer dec_decoder;
draco::KeyframeAnimationDecoder decoder;
DecoderBuffer dec_buffer;
dec_buffer.Init(buffer.data(), buffer.size());
// Decode animation class.
std::unique_ptr<KeyframeAnimation> decoded_animation(
new KeyframeAnimation());
DecoderOptions dec_options;
ASSERT_TRUE(
decoder.Decode(dec_options, &dec_buffer, decoded_animation.get()).ok());
// Verify if animation before and after compression is identical.
CompareAnimationData<num_components_t>(keyframe_animation_,
*decoded_animation, quantized);
}
draco::KeyframeAnimation keyframe_animation_;
std::vector<draco::KeyframeAnimation::TimestampType> timestamps_;
std::vector<float> animation_data_;
};
TEST_F(KeyframeAnimationEncodingTest, OneComponent) {
const int num_frames = 1;
ASSERT_TRUE(CreateAndAddTimestamps(num_frames));
ASSERT_EQ(CreateAndAddAnimationData(num_frames, 1), 1);
TestKeyframeAnimationEncoding<1>();
}
TEST_F(KeyframeAnimationEncodingTest, ManyComponents) {
const int num_frames = 100;
ASSERT_TRUE(CreateAndAddTimestamps(num_frames));
ASSERT_EQ(CreateAndAddAnimationData(num_frames, 100), 1);
TestKeyframeAnimationEncoding<100>();
}
TEST_F(KeyframeAnimationEncodingTest, ManyComponentsWithQuantization) {
const int num_frames = 100;
ASSERT_TRUE(CreateAndAddTimestamps(num_frames));
ASSERT_EQ(CreateAndAddAnimationData(num_frames, 4), 1);
// Test compression with quantization.
TestKeyframeAnimationEncoding<4>(true);
}
TEST_F(KeyframeAnimationEncodingTest, MultipleAnimations) {
const int num_frames = 5;
ASSERT_TRUE(CreateAndAddTimestamps(num_frames));
ASSERT_EQ(CreateAndAddAnimationData(num_frames, 3), 1);
ASSERT_EQ(CreateAndAddAnimationData(num_frames, 3), 2);
TestKeyframeAnimationEncoding<3>();
}
} // namespace draco

View File

@@ -0,0 +1,102 @@
// Copyright 2017 The Draco Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "draco/animation/keyframe_animation.h"
#include "draco/core/draco_test_base.h"
namespace {
class KeyframeAnimationTest : public ::testing::Test {
protected:
KeyframeAnimationTest() {}
bool CreateAndAddTimestamps(int32_t num_frames) {
timestamps_.resize(num_frames);
for (int i = 0; i < timestamps_.size(); ++i)
timestamps_[i] = static_cast<draco::KeyframeAnimation::TimestampType>(i);
return keyframe_animation_.SetTimestamps(timestamps_);
}
int32_t CreateAndAddAnimationData(int32_t num_frames,
uint32_t num_components) {
// Create and add animation data with.
animation_data_.resize(num_frames * num_components);
for (int i = 0; i < animation_data_.size(); ++i)
animation_data_[i] = static_cast<float>(i);
return keyframe_animation_.AddKeyframes(draco::DT_FLOAT32, num_components,
animation_data_);
}
template <int num_components_t>
void CompareAnimationData() {
// Compare time stamp.
const auto timestamp_att = keyframe_animation_.timestamps();
for (int i = 0; i < timestamps_.size(); ++i) {
std::array<float, 1> att_value;
ASSERT_TRUE((timestamp_att->GetValue<float, 1>(
draco::AttributeValueIndex(i), &att_value)));
ASSERT_FLOAT_EQ(att_value[0], i);
}
// Compare keyframe data.
const auto keyframe_att = keyframe_animation_.keyframes(1);
for (int i = 0; i < animation_data_.size() / num_components_t; ++i) {
std::array<float, num_components_t> att_value;
ASSERT_TRUE((keyframe_att->GetValue<float, num_components_t>(
draco::AttributeValueIndex(i), &att_value)));
for (int j = 0; j < num_components_t; ++j) {
ASSERT_FLOAT_EQ(att_value[j], i * num_components_t + j);
}
}
}
template <int num_components_t>
void TestKeyframeAnimation(int32_t num_frames) {
ASSERT_TRUE(CreateAndAddTimestamps(num_frames));
ASSERT_EQ(CreateAndAddAnimationData(num_frames, num_components_t), 1);
CompareAnimationData<num_components_t>();
}
draco::KeyframeAnimation keyframe_animation_;
std::vector<draco::KeyframeAnimation::TimestampType> timestamps_;
std::vector<float> animation_data_;
};
// Test animation with 1 component and 10 frames.
TEST_F(KeyframeAnimationTest, OneComponent) { TestKeyframeAnimation<1>(10); }
// Test animation with 4 component and 10 frames.
TEST_F(KeyframeAnimationTest, FourComponent) { TestKeyframeAnimation<4>(10); }
// Test adding animation data before timestamp.
TEST_F(KeyframeAnimationTest, AddingAnimationFirst) {
ASSERT_EQ(CreateAndAddAnimationData(5, 1), 1);
ASSERT_TRUE(CreateAndAddTimestamps(5));
}
// Test adding timestamp more than once.
TEST_F(KeyframeAnimationTest, ErrorAddingTimestampsTwice) {
ASSERT_TRUE(CreateAndAddTimestamps(5));
ASSERT_FALSE(CreateAndAddTimestamps(5));
}
// Test animation with multiple animation data.
TEST_F(KeyframeAnimationTest, MultipleAnimationData) {
const int num_frames = 5;
ASSERT_TRUE(CreateAndAddTimestamps(num_frames));
ASSERT_EQ(CreateAndAddAnimationData(num_frames, 1), 1);
ASSERT_EQ(CreateAndAddAnimationData(num_frames, 2), 2);
}
} // namespace

View File

@@ -25,9 +25,8 @@ bool AttributeOctahedronTransform::InitFromAttribute(
const AttributeTransformData *const transform_data =
attribute.GetAttributeTransformData();
if (!transform_data ||
transform_data->transform_type() != ATTRIBUTE_OCTAHEDRON_TRANSFORM) {
transform_data->transform_type() != ATTRIBUTE_OCTAHEDRON_TRANSFORM)
return false; // Wrong transform type.
}
quantization_bits_ = transform_data->GetParameterValue<int32_t>(0);
return true;
}
@@ -69,9 +68,8 @@ AttributeOctahedronTransform::GeneratePortableAttribute(
float att_val[3];
int32_t dst_index = 0;
OctahedronToolBox converter;
if (!converter.SetQuantizationBits(quantization_bits_)) {
if (!converter.SetQuantizationBits(quantization_bits_))
return nullptr;
}
for (uint32_t i = 0; i < point_ids.size(); ++i) {
const AttributeValueIndex att_val_id = attribute.mapped_index(point_ids[i]);
attribute.GetValue(att_val_id, att_val);

View File

@@ -25,9 +25,8 @@ bool AttributeQuantizationTransform::InitFromAttribute(
const AttributeTransformData *const transform_data =
attribute.GetAttributeTransformData();
if (!transform_data ||
transform_data->transform_type() != ATTRIBUTE_QUANTIZATION_TRANSFORM) {
transform_data->transform_type() != ATTRIBUTE_QUANTIZATION_TRANSFORM)
return false; // Wrong transform type.
}
int32_t byte_offset = 0;
quantization_bits_ = transform_data->GetParameterValue<int32_t>(byte_offset);
byte_offset += 4;
@@ -81,30 +80,22 @@ bool AttributeQuantizationTransform::ComputeParameters(
++i) {
attribute.GetValue(i, att_val.get());
for (int c = 0; c < num_components; ++c) {
if (min_values_[c] > att_val[c]) {
if (min_values_[c] > att_val[c])
min_values_[c] = att_val[c];
}
if (max_values[c] < att_val[c]) {
if (max_values[c] < att_val[c])
max_values[c] = att_val[c];
}
}
}
for (int c = 0; c < num_components; ++c) {
if (std::isnan(min_values_[c]) || std::isinf(min_values_[c]) ||
std::isnan(max_values[c]) || std::isinf(max_values[c])) {
return false;
}
const float dif = max_values[c] - min_values_[c];
if (dif > range_) {
if (dif > range_)
range_ = dif;
}
}
// In case all values are the same, initialize the range to unit length. This
// will ensure that all values are quantized properly to the same value.
if (range_ == 0.f) {
if (range_ == 0.f)
range_ = 1.f;
}
return true;
}

View File

@@ -14,6 +14,8 @@
//
#include "draco/attributes/geometry_attribute.h"
using std::array;
namespace draco {
GeometryAttribute::GeometryAttribute()
@@ -43,9 +45,8 @@ void GeometryAttribute::Init(GeometryAttribute::Type attribute_type,
}
bool GeometryAttribute::CopyFrom(const GeometryAttribute &src_att) {
if (buffer_ == nullptr || src_att.buffer_ == nullptr) {
if (buffer_ == nullptr || src_att.buffer_ == nullptr)
return false;
}
buffer_->Update(src_att.buffer_->data(), src_att.buffer_->data_size());
num_components_ = src_att.num_components_;
data_type_ = src_att.data_type_;
@@ -54,35 +55,27 @@ bool GeometryAttribute::CopyFrom(const GeometryAttribute &src_att) {
byte_offset_ = src_att.byte_offset_;
attribute_type_ = src_att.attribute_type_;
buffer_descriptor_ = src_att.buffer_descriptor_;
unique_id_ = src_att.unique_id_;
return true;
}
bool GeometryAttribute::operator==(const GeometryAttribute &va) const {
if (attribute_type_ != va.attribute_type_) {
if (attribute_type_ != va.attribute_type_)
return false;
}
// It's OK to compare just the buffer descriptors here. We don't need to
// compare the buffers themselves.
if (buffer_descriptor_.buffer_id != va.buffer_descriptor_.buffer_id) {
if (buffer_descriptor_.buffer_id != va.buffer_descriptor_.buffer_id)
return false;
}
if (buffer_descriptor_.buffer_update_count !=
va.buffer_descriptor_.buffer_update_count) {
va.buffer_descriptor_.buffer_update_count)
return false;
}
if (num_components_ != va.num_components_) {
if (num_components_ != va.num_components_)
return false;
}
if (data_type_ != va.data_type_) {
if (data_type_ != va.data_type_)
return false;
}
if (byte_stride_ != va.byte_stride_) {
if (byte_stride_ != va.byte_stride_)
return false;
}
if (byte_offset_ != va.byte_offset_) {
if (byte_offset_ != va.byte_offset_)
return false;
}
return true;
}

View File

@@ -91,9 +91,8 @@ class GeometryAttribute {
// Byte address of the attribute index.
const int64_t byte_pos = byte_offset_ + byte_stride_ * att_index.value();
// Check we are not reading past end of data.
if (byte_pos + sizeof(*out) > buffer_->data_size()) {
if (byte_pos + sizeof(*out) > buffer_->data_size())
return false;
}
buffer_->Read(byte_pos, &((*out)[0]), sizeof(*out));
return true;
}
@@ -119,13 +118,6 @@ class GeometryAttribute {
buffer_->Read(byte_pos, out_data, byte_stride_);
}
// Sets a value of an attribute entry. The input value must be allocated to
// cover all components of a single attribute entry.
void SetAttributeValue(AttributeValueIndex entry_index, const void *value) {
const int64_t byte_pos = entry_index.value() * byte_stride();
buffer_->Write(byte_pos, value, byte_stride());
}
// DEPRECATED: Use
// ConvertValue(AttributeValueIndex att_id,
// int out_num_components,
@@ -147,9 +139,8 @@ class GeometryAttribute {
template <typename OutT>
bool ConvertValue(AttributeValueIndex att_id, int8_t out_num_components,
OutT *out_val) const {
if (out_val == nullptr) {
if (out_val == nullptr)
return false;
}
switch (data_type_) {
case DT_INT8:
return ConvertTypedValue<int8_t, OutT>(att_id, out_num_components,
@@ -200,26 +191,6 @@ class GeometryAttribute {
return ConvertValue<OutT>(att_index, num_components_, out_value);
}
// Utility function. Returns |attribute_type| as std::string.
static std::string TypeToString(Type attribute_type) {
switch (attribute_type) {
case INVALID:
return "INVALID";
case POSITION:
return "POSITION";
case NORMAL:
return "NORMAL";
case COLOR:
return "COLOR";
case TEX_COORD:
return "TEX_COORD";
case GENERIC:
return "GENERIC";
default:
return "UNKNOWN";
}
}
bool operator==(const GeometryAttribute &va) const;
// Returns the type of the attribute indicating the nature of the attribute.
@@ -314,8 +285,8 @@ struct GeometryAttributeHasher {
size_t hash = HashCombine(va.buffer_descriptor_.buffer_id,
va.buffer_descriptor_.buffer_update_count);
hash = HashCombine(va.num_components_, hash);
hash = HashCombine(static_cast<int8_t>(va.data_type_), hash);
hash = HashCombine(static_cast<int8_t>(va.attribute_type_), hash);
hash = HashCombine((int8_t)va.data_type_, hash);
hash = HashCombine((int8_t)va.attribute_type_, hash);
hash = HashCombine(va.byte_stride_, hash);
return HashCombine(va.byte_offset_, hash);
}

View File

@@ -32,32 +32,20 @@ PointAttribute::PointAttribute(const GeometryAttribute &att)
num_unique_entries_(0),
identity_mapping_(false) {}
void PointAttribute::Init(Type attribute_type, int8_t num_components,
DataType data_type, bool normalized,
size_t num_attribute_values) {
attribute_buffer_ = std::unique_ptr<DataBuffer>(new DataBuffer());
GeometryAttribute::Init(attribute_type, attribute_buffer_.get(),
num_components, data_type, normalized,
DataTypeLength(data_type) * num_components, 0);
Reset(num_attribute_values);
SetIdentityMapping();
}
void PointAttribute::CopyFrom(const PointAttribute &src_att) {
if (buffer() == nullptr) {
// If the destination attribute doesn't have a valid buffer, create it.
attribute_buffer_ = std::unique_ptr<DataBuffer>(new DataBuffer());
ResetBuffer(attribute_buffer_.get(), 0, 0);
}
if (!GeometryAttribute::CopyFrom(src_att)) {
if (!GeometryAttribute::CopyFrom(src_att))
return;
}
identity_mapping_ = src_att.identity_mapping_;
num_unique_entries_ = src_att.num_unique_entries_;
indices_map_ = src_att.indices_map_;
if (src_att.attribute_transform_data_) {
attribute_transform_data_ = std::unique_ptr<AttributeTransformData>(
new AttributeTransformData(*src_att.attribute_transform_data_));
new AttributeTransformData(*src_att.attribute_transform_data_.get()));
} else {
attribute_transform_data_ = nullptr;
}
@@ -68,20 +56,14 @@ bool PointAttribute::Reset(size_t num_attribute_values) {
attribute_buffer_ = std::unique_ptr<DataBuffer>(new DataBuffer());
}
const int64_t entry_size = DataTypeLength(data_type()) * num_components();
if (!attribute_buffer_->Update(nullptr, num_attribute_values * entry_size)) {
if (!attribute_buffer_->Update(nullptr, num_attribute_values * entry_size))
return false;
}
// Assign the new buffer to the parent attribute.
ResetBuffer(attribute_buffer_.get(), entry_size, 0);
num_unique_entries_ = static_cast<uint32_t>(num_attribute_values);
return true;
}
void PointAttribute::Resize(size_t new_num_unique_entries) {
num_unique_entries_ = static_cast<uint32_t>(new_num_unique_entries);
attribute_buffer_->Resize(new_num_unique_entries * byte_stride());
}
#ifdef DRACO_ATTRIBUTE_VALUES_DEDUPLICATION_SUPPORTED
AttributeValueIndex::ValueType PointAttribute::DeduplicateValues(
const GeometryAttribute &in_att) {
@@ -118,9 +100,8 @@ AttributeValueIndex::ValueType PointAttribute::DeduplicateValues(
default:
return -1; // Unsupported data type.
}
if (unique_vals == 0) {
if (unique_vals == 0)
return -1; // Unexpected error.
}
return unique_vals;
}
@@ -200,9 +181,8 @@ AttributeValueIndex::ValueType PointAttribute::DeduplicateFormattedValues(
++unique_vals;
}
}
if (unique_vals == num_unique_entries_) {
if (unique_vals == num_unique_entries_)
return unique_vals.value(); // Nothing has changed.
}
if (is_mapping_identity()) {
// Change identity mapping to the explicit one.
// The number of points is equal to the number of old unique values.

View File

@@ -17,12 +17,13 @@
#include <memory>
#include "draco/draco_features.h"
#include "draco/attributes/attribute_transform_data.h"
#include "draco/attributes/geometry_attribute.h"
#include "draco/core/draco_index_type_vector.h"
#include "draco/core/hash_utils.h"
#include "draco/core/macros.h"
#include "draco/draco_features.h"
namespace draco {
@@ -40,12 +41,6 @@ class PointAttribute : public GeometryAttribute {
PointAttribute(PointAttribute &&attribute) = default;
PointAttribute &operator=(PointAttribute &&attribute) = default;
// Initializes a point attribute. By default the attribute will be set to
// identity mapping between point indices and attribute values. To set custom
// mapping use SetExplicitMapping() function.
void Init(Type attribute_type, int8_t num_components, DataType data_type,
bool normalized, size_t num_attribute_values);
// Copies attribute data from the provided |src_att| attribute.
void CopyFrom(const PointAttribute &src_att);
@@ -54,17 +49,15 @@ class PointAttribute : public GeometryAttribute {
size_t size() const { return num_unique_entries_; }
AttributeValueIndex mapped_index(PointIndex point_index) const {
if (identity_mapping_) {
if (identity_mapping_)
return AttributeValueIndex(point_index.value());
}
return indices_map_[point_index];
}
DataBuffer *buffer() const { return attribute_buffer_.get(); }
bool is_mapping_identity() const { return identity_mapping_; }
size_t indices_map_size() const {
if (is_mapping_identity()) {
if (is_mapping_identity())
return 0;
}
return indices_map_.size();
}
@@ -72,14 +65,10 @@ class PointAttribute : public GeometryAttribute {
return GetAddress(mapped_index(point_index));
}
// Sets the new number of unique attribute entries for the attribute. The
// function resizes the attribute storage to hold |num_attribute_values|
// entries.
// All previous entries with AttributeValueIndex < |num_attribute_values|
// are preserved. Caller needs to ensure that the PointAttribute is still
// valid after the resizing operation (that is, each point is mapped to a
// valid attribute value).
void Resize(size_t new_num_unique_entries);
// Sets the new number of unique attribute entries for the attribute.
void Resize(size_t new_num_unique_entries) {
num_unique_entries_ = static_cast<uint32_t>(new_num_unique_entries);
}
// Functions for setting the type of mapping between point indices and
// attribute entry ids.
@@ -103,6 +92,13 @@ class PointAttribute : public GeometryAttribute {
indices_map_[point_index] = entry_index;
}
// Sets a value of an attribute entry. The input value must be allocated to
// cover all components of a single attribute entry.
void SetAttributeValue(AttributeValueIndex entry_index, const void *value) {
const int64_t byte_pos = entry_index.value() * byte_stride();
buffer()->Write(byte_pos, value, byte_stride());
}
// Same as GeometryAttribute::GetValue(), but using point id as the input.
// Mapping to attribute value index is performed automatically.
void GetMappedValue(PointIndex point_index, void *out_data) const {
@@ -169,7 +165,7 @@ struct PointAttributeHasher {
hash = HashCombine(attribute.identity_mapping_, hash);
hash = HashCombine(attribute.num_unique_entries_, hash);
hash = HashCombine(attribute.indices_map_.size(), hash);
if (!attribute.indices_map_.empty()) {
if (attribute.indices_map_.size() > 0) {
const uint64_t indices_hash = FingerprintString(
reinterpret_cast<const char *>(attribute.indices_map_.data()),
attribute.indices_map_.size());

View File

@@ -0,0 +1,129 @@
// Copyright 2017 The Draco Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "draco/attributes/point_attribute.h"
#include "draco/core/draco_test_base.h"
namespace {
class PointAttributeTest : public ::testing::Test {
protected:
PointAttributeTest() {}
};
TEST_F(PointAttributeTest, TestCopy) {
// This test verifies that PointAttribute can copy data from another point
// attribute.
draco::GeometryAttribute pos_att;
pos_att.Init(draco::GeometryAttribute::POSITION, nullptr, 1, draco::DT_INT32,
false, 4, 0);
draco::PointAttribute pa(pos_att);
pa.SetIdentityMapping();
pa.Reset(10);
for (int32_t i = 0; i < 10; ++i) {
pa.SetAttributeValue(draco::AttributeValueIndex(i), &i);
}
draco::PointAttribute other_pa;
other_pa.CopyFrom(pa);
draco::PointAttributeHasher hasher;
ASSERT_EQ(hasher(pa), hasher(other_pa));
// The hash function does not actually compute the hash from attribute values,
// so ensure the data got copied correctly as well.
for (int32_t i = 0; i < 10; ++i) {
int32_t data;
other_pa.GetValue(draco::AttributeValueIndex(i), &data);
ASSERT_EQ(data, i);
}
}
TEST_F(PointAttributeTest, TestGetValueFloat) {
draco::GeometryAttribute pos_att;
pos_att.Init(draco::GeometryAttribute::POSITION, nullptr, 3,
draco::DT_FLOAT32, false, 4, 0);
draco::PointAttribute pa(pos_att);
pa.SetIdentityMapping();
pa.Reset(5);
float points[3];
for (int32_t i = 0; i < 5; ++i) {
points[0] = i * 3.0;
points[1] = (i * 3.0) + 1.0;
points[2] = (i * 3.0) + 2.0;
pa.SetAttributeValue(draco::AttributeValueIndex(i), &points);
}
for (int32_t i = 0; i < 5; ++i) {
pa.GetValue(draco::AttributeValueIndex(i), &points);
ASSERT_FLOAT_EQ(points[0], i * 3.0);
ASSERT_FLOAT_EQ(points[1], (i * 3.0) + 1.0);
ASSERT_FLOAT_EQ(points[2], (i * 3.0) + 2.0);
}
}
TEST_F(PointAttributeTest, TestGetArray) {
draco::GeometryAttribute pos_att;
pos_att.Init(draco::GeometryAttribute::POSITION, nullptr, 3,
draco::DT_FLOAT32, false, 4, 0);
draco::PointAttribute pa(pos_att);
pa.SetIdentityMapping();
pa.Reset(5);
float points[3];
for (int32_t i = 0; i < 5; ++i) {
points[0] = i * 3.0;
points[1] = (i * 3.0) + 1.0;
points[2] = (i * 3.0) + 2.0;
pa.SetAttributeValue(draco::AttributeValueIndex(i), &points);
}
for (int32_t i = 0; i < 5; ++i) {
std::array<float, 3> att_value;
att_value = pa.GetValue<float, 3>(draco::AttributeValueIndex(i));
ASSERT_FLOAT_EQ(att_value[0], i * 3.0);
ASSERT_FLOAT_EQ(att_value[1], (i * 3.0) + 1.0);
ASSERT_FLOAT_EQ(att_value[2], (i * 3.0) + 2.0);
}
for (int32_t i = 0; i < 5; ++i) {
std::array<float, 3> att_value;
EXPECT_TRUE(
(pa.GetValue<float, 3>(draco::AttributeValueIndex(i), &att_value)));
ASSERT_FLOAT_EQ(att_value[0], i * 3.0);
ASSERT_FLOAT_EQ(att_value[1], (i * 3.0) + 1.0);
ASSERT_FLOAT_EQ(att_value[2], (i * 3.0) + 2.0);
}
}
TEST_F(PointAttributeTest, TestArrayReadError) {
draco::GeometryAttribute pos_att;
pos_att.Init(draco::GeometryAttribute::POSITION, nullptr, 3,
draco::DT_FLOAT32, false, 4, 0);
draco::PointAttribute pa(pos_att);
pa.SetIdentityMapping();
pa.Reset(5);
float points[3];
for (int32_t i = 0; i < 5; ++i) {
points[0] = i * 3.0;
points[1] = (i * 3.0) + 1.0;
points[2] = (i * 3.0) + 2.0;
pa.SetAttributeValue(draco::AttributeValueIndex(i), &points);
}
std::array<float, 3> att_value;
EXPECT_FALSE(
(pa.GetValue<float, 3>(draco::AttributeValueIndex(5), &att_value)));
}
} // namespace

View File

@@ -33,42 +33,31 @@ bool AttributesDecoder::DecodeAttributesDecoderData(DecoderBuffer *in_buffer) {
#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
if (point_cloud_decoder_->bitstream_version() <
DRACO_BITSTREAM_VERSION(2, 0)) {
if (!in_buffer->Decode(&num_attributes)) {
if (!in_buffer->Decode(&num_attributes))
return false;
}
} else
#endif
{
if (!DecodeVarint(&num_attributes, in_buffer)) {
if (!DecodeVarint(&num_attributes, in_buffer))
return false;
}
}
if (num_attributes == 0) {
if (num_attributes == 0)
return false;
}
point_attribute_ids_.resize(num_attributes);
PointCloud *pc = point_cloud_;
for (uint32_t i = 0; i < num_attributes; ++i) {
// Decode attribute descriptor data.
uint8_t att_type, data_type, num_components, normalized;
if (!in_buffer->Decode(&att_type)) {
if (!in_buffer->Decode(&att_type))
return false;
}
if (!in_buffer->Decode(&data_type)) {
if (!in_buffer->Decode(&data_type))
return false;
}
if (!in_buffer->Decode(&num_components)) {
if (!in_buffer->Decode(&num_components))
return false;
}
if (!in_buffer->Decode(&normalized)) {
if (!in_buffer->Decode(&normalized))
return false;
}
if (att_type >= GeometryAttribute::NAMED_ATTRIBUTES_COUNT) {
if (data_type <= DT_INVALID || data_type >= DT_TYPES_COUNT)
return false;
}
if (data_type == DT_INVALID || data_type >= DT_TYPES_COUNT) {
return false;
}
const DataType draco_dt = static_cast<DataType>(data_type);
// Add the attribute to the point cloud
@@ -81,9 +70,8 @@ bool AttributesDecoder::DecodeAttributesDecoderData(DecoderBuffer *in_buffer) {
if (point_cloud_decoder_->bitstream_version() <
DRACO_BITSTREAM_VERSION(1, 3)) {
uint16_t custom_id;
if (!in_buffer->Decode(&custom_id)) {
if (!in_buffer->Decode(&custom_id))
return false;
}
// TODO(draco-eng): Add "custom_id" to attribute metadata.
unique_id = static_cast<uint32_t>(custom_id);
ga.set_unique_id(unique_id);
@@ -99,10 +87,8 @@ bool AttributesDecoder::DecodeAttributesDecoderData(DecoderBuffer *in_buffer) {
point_attribute_ids_[i] = att_id;
// Update the inverse map.
if (att_id >=
static_cast<int32_t>(point_attribute_to_local_id_map_.size())) {
if (att_id >= static_cast<int32_t>(point_attribute_to_local_id_map_.size()))
point_attribute_to_local_id_map_.resize(att_id + 1, -1);
}
point_attribute_to_local_id_map_[att_id] = i;
}
return true;

View File

@@ -17,10 +17,11 @@
#include <vector>
#include "draco/draco_features.h"
#include "draco/compression/attributes/attributes_decoder_interface.h"
#include "draco/compression/point_cloud/point_cloud_decoder.h"
#include "draco/core/decoder_buffer.h"
#include "draco/draco_features.h"
#include "draco/point_cloud/point_cloud.h"
namespace draco {
@@ -53,15 +54,12 @@ class AttributesDecoder : public AttributesDecoderInterface {
// Decodes attribute data from the source buffer.
bool DecodeAttributes(DecoderBuffer *in_buffer) override {
if (!DecodePortableAttributes(in_buffer)) {
if (!DecodePortableAttributes(in_buffer))
return false;
}
if (!DecodeDataNeededByPortableTransforms(in_buffer)) {
if (!DecodeDataNeededByPortableTransforms(in_buffer))
return false;
}
if (!TransformAttributesToOriginalFormat()) {
if (!TransformAttributesToOriginalFormat())
return false;
}
return true;
}
@@ -69,9 +67,8 @@ class AttributesDecoder : public AttributesDecoderInterface {
int32_t GetLocalIdForPointAttribute(int32_t point_attribute_id) const {
const int id_map_size =
static_cast<int>(point_attribute_to_local_id_map_.size());
if (point_attribute_id >= id_map_size) {
if (point_attribute_id >= id_map_size)
return -1;
}
return point_attribute_to_local_id_map_[point_attribute_id];
}
virtual bool DecodePortableAttributes(DecoderBuffer *in_buffer) = 0;

View File

@@ -48,18 +48,15 @@ class AttributesEncoder {
// Encode attribute data to the target buffer.
virtual bool EncodeAttributes(EncoderBuffer *out_buffer) {
if (!TransformAttributesToPortableFormat()) {
if (!TransformAttributesToPortableFormat())
return false;
}
if (!EncodePortableAttributes(out_buffer)) {
if (!EncodePortableAttributes(out_buffer))
return false;
}
// Encode data needed by portable transforms after the attribute is encoded.
// This corresponds to the order in which the data is going to be decoded by
// the decoder.
if (!EncodeDataNeededByPortableTransforms(out_buffer)) {
if (!EncodeDataNeededByPortableTransforms(out_buffer))
return false;
}
return true;
}
@@ -90,9 +87,8 @@ class AttributesEncoder {
void AddAttributeId(int32_t id) {
point_attribute_ids_.push_back(id);
if (id >= static_cast<int32_t>(point_attribute_to_local_id_map_.size())) {
if (id >= static_cast<int32_t>(point_attribute_to_local_id_map_.size()))
point_attribute_to_local_id_map_.resize(id + 1, -1);
}
point_attribute_to_local_id_map_[id] =
static_cast<int32_t>(point_attribute_ids_.size()) - 1;
}
@@ -131,9 +127,8 @@ class AttributesEncoder {
int32_t GetLocalIdForPointAttribute(int32_t point_attribute_id) const {
const int id_map_size =
static_cast<int>(point_attribute_to_local_id_map_.size());
if (point_attribute_id >= id_map_size) {
if (point_attribute_id >= id_map_size)
return -1;
}
return point_attribute_to_local_id_map_[point_attribute_id];
}

View File

@@ -13,7 +13,6 @@
// limitations under the License.
//
#include "draco/compression/attributes/kd_tree_attributes_decoder.h"
#include "draco/compression/attributes/kd_tree_attributes_shared.h"
#include "draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_decoder.h"
#include "draco/compression/point_cloud/algorithms/float_points_tree_decoder.h"
@@ -93,7 +92,7 @@ class PointAttributeVectorOutputIterator {
const uint32_t &data_size = std::get<3>(att);
const uint32_t &num_components = std::get<4>(att);
const uint32_t *data_source = val.data() + offset;
if (data_size < 4) { // handle uint16_t, uint8_t
if (data_size != 4) { // handle uint16_t, uint8_t
// selectively copy data bytes
uint8_t *data_counter = data_;
for (uint32_t index = 0; index < num_components;
@@ -104,9 +103,8 @@ class PointAttributeVectorOutputIterator {
data_source = reinterpret_cast<uint32_t *>(data_);
}
const AttributeValueIndex avi = attribute->mapped_index(point_id_);
if (avi >= static_cast<uint32_t>(attribute->size())) {
if (avi >= static_cast<uint32_t>(attribute->size()))
return *this;
}
attribute->SetAttributeValue(avi, data_source);
}
return *this;
@@ -136,9 +134,8 @@ bool KdTreeAttributesDecoder::DecodePortableAttributes(
return true;
}
uint8_t compression_level = 0;
if (!in_buffer->Decode(&compression_level)) {
if (!in_buffer->Decode(&compression_level))
return false;
}
const int32_t num_points = GetDecoder()->point_cloud()->num_points();
// Decode data using the kd tree decoding into integer (portable) attributes.
@@ -200,51 +197,44 @@ bool KdTreeAttributesDecoder::DecodePortableAttributes(
switch (compression_level) {
case 0: {
DynamicIntegerPointsKdTreeDecoder<0> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 1: {
DynamicIntegerPointsKdTreeDecoder<1> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 2: {
DynamicIntegerPointsKdTreeDecoder<2> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 3: {
DynamicIntegerPointsKdTreeDecoder<3> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 4: {
DynamicIntegerPointsKdTreeDecoder<4> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 5: {
DynamicIntegerPointsKdTreeDecoder<5> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 6: {
DynamicIntegerPointsKdTreeDecoder<6> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
default:
@@ -266,26 +256,22 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
if (att->data_type() == DT_FLOAT32) {
const int num_components = att->num_components();
min_value.resize(num_components);
if (!in_buffer->Decode(&min_value[0], sizeof(float) * num_components)) {
if (!in_buffer->Decode(&min_value[0], sizeof(float) * num_components))
return false;
}
float max_value_dif;
if (!in_buffer->Decode(&max_value_dif)) {
if (!in_buffer->Decode(&max_value_dif))
return false;
}
uint8_t quantization_bits;
if (!in_buffer->Decode(&quantization_bits) || quantization_bits > 31) {
if (!in_buffer->Decode(&quantization_bits) || quantization_bits > 31)
return false;
}
AttributeQuantizationTransform transform;
transform.SetParameters(quantization_bits, min_value.data(),
num_components, max_value_dif);
const int num_transforms =
static_cast<int>(attribute_quantization_transforms_.size());
if (!transform.TransferToAttribute(
quantized_portable_attributes_[num_transforms].get())) {
quantized_portable_attributes_[num_transforms].get()))
return false;
}
attribute_quantization_transforms_.push_back(transform);
}
}
@@ -313,10 +299,6 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
const DataType data_type = att->data_type();
const uint32_t data_size = (std::max)(0, DataTypeLength(data_type));
const uint32_t num_components = att->num_components();
if (data_size > 4) {
return false;
}
atts[attribute_index] = std::make_tuple(
att, total_dimensionality, data_type, data_size, num_components);
// everything is treated as 32bit in the encoder.
@@ -328,30 +310,24 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
att->SetIdentityMapping();
// Decode method
uint8_t method;
if (!in_buffer->Decode(&method)) {
if (!in_buffer->Decode(&method))
return false;
}
if (method == KdTreeAttributesEncodingMethod::kKdTreeQuantizationEncoding) {
uint8_t compression_level = 0;
if (!in_buffer->Decode(&compression_level)) {
if (!in_buffer->Decode(&compression_level))
return false;
}
uint32_t num_points = 0;
if (!in_buffer->Decode(&num_points)) {
if (!in_buffer->Decode(&num_points))
return false;
}
att->Reset(num_points);
FloatPointsTreeDecoder decoder;
decoder.set_num_points_from_header(num_points);
PointAttributeVectorOutputIterator<float> out_it(atts);
if (!decoder.DecodePointCloud(in_buffer, out_it)) {
if (!decoder.DecodePointCloud(in_buffer, out_it))
return false;
}
} else if (method == KdTreeAttributesEncodingMethod::kKdTreeIntegerEncoding) {
uint8_t compression_level = 0;
if (!in_buffer->Decode(&compression_level)) {
if (!in_buffer->Decode(&compression_level))
return false;
}
if (6 < compression_level) {
LOGE("KdTreeAttributesDecoder: compression level %i not supported.\n",
compression_level);
@@ -359,9 +335,8 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
}
uint32_t num_points;
if (!in_buffer->Decode(&num_points)) {
if (!in_buffer->Decode(&num_points))
return false;
}
for (auto attribute_index = 0;
static_cast<uint32_t>(attribute_index) < attribute_count;
@@ -378,51 +353,44 @@ bool KdTreeAttributesDecoder::DecodeDataNeededByPortableTransforms(
switch (compression_level) {
case 0: {
DynamicIntegerPointsKdTreeDecoder<0> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 1: {
DynamicIntegerPointsKdTreeDecoder<1> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 2: {
DynamicIntegerPointsKdTreeDecoder<2> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 3: {
DynamicIntegerPointsKdTreeDecoder<3> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 4: {
DynamicIntegerPointsKdTreeDecoder<4> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 5: {
DynamicIntegerPointsKdTreeDecoder<5> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
case 6: {
DynamicIntegerPointsKdTreeDecoder<6> decoder(total_dimensionality);
if (!decoder.DecodePoints(in_buffer, out_it)) {
if (!decoder.DecodePoints(in_buffer, out_it))
return false;
}
break;
}
default:
@@ -477,19 +445,16 @@ bool KdTreeAttributesDecoder::TransformAttributesToOriginalFormat() {
// Values are stored as unsigned in the attribute, make them signed again.
if (att->data_type() == DT_INT32) {
if (!TransformAttributeBackToSignedType<int32_t>(
att, num_processed_signed_components)) {
att, num_processed_signed_components))
return false;
}
} else if (att->data_type() == DT_INT16) {
if (!TransformAttributeBackToSignedType<int16_t>(
att, num_processed_signed_components)) {
att, num_processed_signed_components))
return false;
}
} else if (att->data_type() == DT_INT8) {
if (!TransformAttributeBackToSignedType<int8_t>(
att, num_processed_signed_components)) {
att, num_processed_signed_components))
return false;
}
}
num_processed_signed_components += att->num_components();
} else if (att->data_type() == DT_FLOAT32) {
@@ -526,9 +491,8 @@ bool KdTreeAttributesDecoder::TransformAttributesToOriginalFormat() {
int quant_val_id = 0;
int out_byte_pos = 0;
Dequantizer dequantizer;
if (!dequantizer.Init(transform.range(), max_quantized_value)) {
if (!dequantizer.Init(transform.range(), max_quantized_value))
return false;
}
const uint32_t *const portable_attribute_data =
reinterpret_cast<const uint32_t *>(
src_att->GetAddress(AttributeValueIndex(0)));

View File

@@ -13,7 +13,6 @@
// limitations under the License.
//
#include "draco/compression/attributes/kd_tree_attributes_encoder.h"
#include "draco/compression/attributes/kd_tree_attributes_shared.h"
#include "draco/compression/attributes/point_d_vector.h"
#include "draco/compression/point_cloud/algorithms/dynamic_integer_points_kd_tree_encoder.h"
@@ -51,9 +50,8 @@ bool KdTreeAttributesEncoder::TransformAttributesToPortableFormat() {
AttributeQuantizationTransform attribute_quantization_transform;
const int quantization_bits = encoder()->options()->GetAttributeInt(
att_id, "quantization_bits", -1);
if (quantization_bits < 1) {
if (quantization_bits < 1)
return false;
}
if (encoder()->options()->IsAttributeOptionSet(att_id,
"quantization_origin") &&
encoder()->options()->IsAttributeOptionSet(att_id,
@@ -93,9 +91,8 @@ bool KdTreeAttributesEncoder::TransformAttributesToPortableFormat() {
++avi) {
att->ConvertValue<int32_t>(avi, &act_value[0]);
for (int c = 0; c < att->num_components(); ++c) {
if (min_value[c] > act_value[c]) {
if (min_value[c] > act_value[c])
min_value[c] = act_value[c];
}
}
}
for (int c = 0; c < att->num_components(); ++c) {
@@ -170,9 +167,8 @@ bool KdTreeAttributesEncoder::EncodePortableAttributes(
return false;
}
if (source_att == nullptr) {
if (source_att == nullptr)
return false;
}
// Copy source_att to the vector.
if (source_att->data_type() == DT_UINT32) {
@@ -237,57 +233,50 @@ bool KdTreeAttributesEncoder::EncodePortableAttributes(
case 6: {
DynamicIntegerPointsKdTreeEncoder<6> points_encoder(num_components_);
if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(),
num_bits, out_buffer)) {
num_bits, out_buffer))
return false;
}
break;
}
case 5: {
DynamicIntegerPointsKdTreeEncoder<5> points_encoder(num_components_);
if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(),
num_bits, out_buffer)) {
num_bits, out_buffer))
return false;
}
break;
}
case 4: {
DynamicIntegerPointsKdTreeEncoder<4> points_encoder(num_components_);
if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(),
num_bits, out_buffer)) {
num_bits, out_buffer))
return false;
}
break;
}
case 3: {
DynamicIntegerPointsKdTreeEncoder<3> points_encoder(num_components_);
if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(),
num_bits, out_buffer)) {
num_bits, out_buffer))
return false;
}
break;
}
case 2: {
DynamicIntegerPointsKdTreeEncoder<2> points_encoder(num_components_);
if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(),
num_bits, out_buffer)) {
num_bits, out_buffer))
return false;
}
break;
}
case 1: {
DynamicIntegerPointsKdTreeEncoder<1> points_encoder(num_components_);
if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(),
num_bits, out_buffer)) {
num_bits, out_buffer))
return false;
}
break;
}
case 0: {
DynamicIntegerPointsKdTreeEncoder<0> points_encoder(num_components_);
if (!points_encoder.EncodePoints(point_vector.begin(), point_vector.end(),
num_bits, out_buffer)) {
num_bits, out_buffer))
return false;
}
break;
}
// Compression level and/or encoding speed seem wrong.

View File

@@ -32,9 +32,8 @@ class LinearSequencer : public PointsSequencer {
protected:
bool GenerateSequenceInternal() override {
if (num_points_ < 0) {
if (num_points_ < 0)
return false;
}
out_point_ids()->resize(num_points_);
for (int i = 0; i < num_points_; ++i) {
out_point_ids()->at(i) = PointIndex(i);

View File

@@ -39,7 +39,6 @@
#define DRACO_COMPRESSION_ATTRIBUTES_NORMAL_COMPRESSION_UTILS_H_
#include <inttypes.h>
#include <algorithm>
#include <cmath>
@@ -56,9 +55,8 @@ class OctahedronToolBox {
center_value_(-1) {}
bool SetQuantizationBits(int32_t q) {
if (q < 2 || q > 30) {
if (q < 2 || q > 30)
return false;
}
quantization_bits_ = q;
max_quantized_value_ = (1 << quantization_bits_) - 1;
max_value_ = max_quantized_value_ - 1;
@@ -159,9 +157,8 @@ class OctahedronToolBox {
int_vec[2] = 0;
}
// Take care of the sign.
if (scaled_vector[2] < 0) {
if (scaled_vector[2] < 0)
int_vec[2] *= -1;
}
IntegerVectorToQuantizedOctahedralCoords(int_vec, out_s, out_t);
}
@@ -192,8 +189,6 @@ class OctahedronToolBox {
}
}
// TODO(b/149328891): Change function to not use templates as |T| is only
// float.
template <typename T>
void OctaherdalCoordsToUnitVector(T in_s, T in_t, T *out_vector) const {
DRACO_DCHECK_GE(in_s, 0);
@@ -309,21 +304,18 @@ class OctahedronToolBox {
// For correction values.
int32_t ModMax(int32_t x) const {
if (x > this->center_value()) {
if (x > this->center_value())
return x - this->max_quantized_value();
}
if (x < -this->center_value()) {
if (x < -this->center_value())
return x + this->max_quantized_value();
}
return x;
}
// For correction values.
int32_t MakePositive(int32_t x) const {
DRACO_DCHECK_LE(x, this->center_value() * 2);
if (x < 0) {
if (x < 0)
return x + this->max_quantized_value();
}
return x;
}

View File

@@ -19,7 +19,6 @@
#include <cstring>
#include <memory>
#include <vector>
#include "draco/core/macros.h"
namespace draco {
@@ -43,9 +42,8 @@ class PseudoPointD {
// Specifically copies referenced memory
void swap(PseudoPointD &other) noexcept {
for (internal_t dim = 0; dim < dimension_; dim += 1) {
for (internal_t dim = 0; dim < dimension_; dim += 1)
std::swap(mem_[dim], other.mem_[dim]);
}
}
PseudoPointD(const PseudoPointD &other)
@@ -61,11 +59,9 @@ class PseudoPointD {
}
bool operator==(const PseudoPointD &other) const {
for (auto dim = 0; dim < dimension_; dim += 1) {
if (mem_[dim] != other.mem_[dim]) {
for (auto dim = 0; dim < dimension_; dim += 1)
if (mem_[dim] != other.mem_[dim])
return false;
}
}
return true;
}
bool operator!=(const PseudoPointD &other) const {

View File

@@ -0,0 +1,359 @@
// Copyright 2018 The Draco Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "draco/compression/attributes/point_d_vector.h"
#include "draco/compression/point_cloud/algorithms/point_cloud_types.h"
#include "draco/core/draco_test_base.h"
namespace draco {
class PointDVectorTest : public ::testing::Test {
protected:
template <typename PT>
void TestIntegrity() {}
template <typename PT>
void TestSize() {
for (uint32_t n_items = 0; n_items <= 10; ++n_items) {
for (uint32_t dimensionality = 1; dimensionality <= 10;
++dimensionality) {
draco::PointDVector<PT> var(n_items, dimensionality);
ASSERT_EQ(n_items, var.size());
ASSERT_EQ(n_items * dimensionality, var.GetBufferSize());
}
}
}
template <typename PT>
void TestContentsContiguous() {
for (uint32_t n_items = 1; n_items <= 1000; n_items *= 10) {
for (uint32_t dimensionality = 1; dimensionality < 10;
dimensionality += 2) {
for (uint32_t att_dimensionality = 1;
att_dimensionality <= dimensionality; att_dimensionality += 2) {
for (uint32_t offset_dimensionality = 0;
offset_dimensionality < dimensionality - att_dimensionality;
++offset_dimensionality) {
PointDVector<PT> var(n_items, dimensionality);
std::vector<PT> att(n_items * att_dimensionality);
for (PT val = 0; val < n_items; val += 1) {
for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
att[val * att_dimensionality + att_dim] = val;
}
}
const PT *const attribute_data = att.data();
var.CopyAttribute(att_dimensionality, offset_dimensionality,
attribute_data);
for (PT val = 0; val < n_items; val += 1) {
for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
ASSERT_EQ(var[val][offset_dimensionality + att_dim], val);
}
}
}
}
}
}
}
template <typename PT>
void TestContentsDiscrete() {
for (uint32_t n_items = 1; n_items <= 1000; n_items *= 10) {
for (uint32_t dimensionality = 1; dimensionality < 10;
dimensionality += 2) {
for (uint32_t att_dimensionality = 1;
att_dimensionality <= dimensionality; att_dimensionality += 2) {
for (uint32_t offset_dimensionality = 0;
offset_dimensionality < dimensionality - att_dimensionality;
++offset_dimensionality) {
PointDVector<PT> var(n_items, dimensionality);
std::vector<PT> att(n_items * att_dimensionality);
for (PT val = 0; val < n_items; val += 1) {
for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
att[val * att_dimensionality + att_dim] = val;
}
}
const PT *const attribute_data = att.data();
for (PT item = 0; item < n_items; item += 1) {
var.CopyAttribute(att_dimensionality, offset_dimensionality, item,
attribute_data + item * att_dimensionality);
}
for (PT val = 0; val < n_items; val += 1) {
for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
ASSERT_EQ(var[val][offset_dimensionality + att_dim], val);
}
}
}
}
}
}
}
template <typename PT>
void TestContentsCopy() {
for (uint32_t n_items = 1; n_items <= 1000; n_items *= 10) {
for (uint32_t dimensionality = 1; dimensionality < 10;
dimensionality += 2) {
for (uint32_t att_dimensionality = 1;
att_dimensionality <= dimensionality; att_dimensionality += 2) {
for (uint32_t offset_dimensionality = 0;
offset_dimensionality < dimensionality - att_dimensionality;
++offset_dimensionality) {
PointDVector<PT> var(n_items, dimensionality);
PointDVector<PT> dest(n_items, dimensionality);
std::vector<PT> att(n_items * att_dimensionality);
for (PT val = 0; val < n_items; val += 1) {
for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
att[val * att_dimensionality + att_dim] = val;
}
}
const PT *const attribute_data = att.data();
var.CopyAttribute(att_dimensionality, offset_dimensionality,
attribute_data);
for (PT item = 0; item < n_items; item += 1) {
dest.CopyItem(var, item, item);
}
for (PT val = 0; val < n_items; val += 1) {
for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
ASSERT_EQ(var[val][offset_dimensionality + att_dim], val);
ASSERT_EQ(dest[val][offset_dimensionality + att_dim], val);
}
}
}
}
}
}
}
template <typename PT>
void TestIterator() {
for (uint32_t n_items = 1; n_items <= 1000; n_items *= 10) {
for (uint32_t dimensionality = 1; dimensionality < 10;
dimensionality += 2) {
for (uint32_t att_dimensionality = 1;
att_dimensionality <= dimensionality; att_dimensionality += 2) {
for (uint32_t offset_dimensionality = 0;
offset_dimensionality < dimensionality - att_dimensionality;
++offset_dimensionality) {
PointDVector<PT> var(n_items, dimensionality);
PointDVector<PT> dest(n_items, dimensionality);
std::vector<PT> att(n_items * att_dimensionality);
for (PT val = 0; val < n_items; val += 1) {
for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
att[val * att_dimensionality + att_dim] = val;
}
}
const PT *const attribute_data = att.data();
var.CopyAttribute(att_dimensionality, offset_dimensionality,
attribute_data);
for (PT item = 0; item < n_items; item += 1) {
dest.CopyItem(var, item, item);
}
auto V0 = var.begin();
auto VE = var.end();
auto D0 = dest.begin();
auto DE = dest.end();
while (V0 != VE && D0 != DE) {
ASSERT_EQ(*D0, *V0); // compare PseudoPointD
// verify elemental values
for (auto index = 0; index < dimensionality; index += 1) {
ASSERT_EQ((*D0)[index], (*V0)[index]);
}
++V0;
++D0;
}
for (PT val = 0; val < n_items; val += 1) {
for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
ASSERT_EQ(var[val][offset_dimensionality + att_dim], val);
ASSERT_EQ(dest[val][offset_dimensionality + att_dim], val);
}
}
}
}
}
}
}
template <typename PT>
void TestPoint3Iterator() {
for (uint32_t n_items = 1; n_items <= 1000; n_items *= 10) {
const uint32_t dimensionality = 3;
// for (uint32_t dimensionality = 1; dimensionality < 10;
// dimensionality += 2) {
const uint32_t att_dimensionality = 3;
// for (uint32_t att_dimensionality = 1;
// att_dimensionality <= dimensionality; att_dimensionality += 2) {
for (uint32_t offset_dimensionality = 0;
offset_dimensionality < dimensionality - att_dimensionality;
++offset_dimensionality) {
PointDVector<PT> var(n_items, dimensionality);
PointDVector<PT> dest(n_items, dimensionality);
std::vector<PT> att(n_items * att_dimensionality);
std::vector<draco::Point3ui> att3(n_items);
for (PT val = 0; val < n_items; val += 1) {
att3[val][0] = val;
att3[val][1] = val;
att3[val][2] = val;
for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
att[val * att_dimensionality + att_dim] = val;
}
}
const PT *const attribute_data = att.data();
var.CopyAttribute(att_dimensionality, offset_dimensionality,
attribute_data);
for (PT item = 0; item < n_items; item += 1) {
dest.CopyItem(var, item, item);
}
auto aV0 = att3.begin();
auto aVE = att3.end();
auto V0 = var.begin();
auto VE = var.end();
auto D0 = dest.begin();
auto DE = dest.end();
while (aV0 != aVE && V0 != VE && D0 != DE) {
ASSERT_EQ(*D0, *V0); // compare PseudoPointD
// verify elemental values
for (auto index = 0; index < dimensionality; index += 1) {
ASSERT_EQ((*D0)[index], (*V0)[index]);
ASSERT_EQ((*D0)[index], (*aV0)[index]);
ASSERT_EQ((*aV0)[index], (*V0)[index]);
}
++aV0;
++V0;
++D0;
}
for (PT val = 0; val < n_items; val += 1) {
for (PT att_dim = 0; att_dim < att_dimensionality; att_dim += 1) {
ASSERT_EQ(var[val][offset_dimensionality + att_dim], val);
ASSERT_EQ(dest[val][offset_dimensionality + att_dim], val);
}
}
}
}
}
void TestPseudoPointDSwap() {
draco::Point3ui val = {0, 1, 2};
draco::Point3ui dest = {10, 11, 12};
draco::PseudoPointD<uint32_t> val_src1(&val[0], 3);
draco::PseudoPointD<uint32_t> dest_src1(&dest[0], 3);
ASSERT_EQ(val_src1[0], 0);
ASSERT_EQ(val_src1[1], 1);
ASSERT_EQ(val_src1[2], 2);
ASSERT_EQ(dest_src1[0], 10);
ASSERT_EQ(dest_src1[1], 11);
ASSERT_EQ(dest_src1[2], 12);
ASSERT_NE(val_src1, dest_src1);
swap(val_src1, dest_src1);
ASSERT_EQ(dest_src1[0], 0);
ASSERT_EQ(dest_src1[1], 1);
ASSERT_EQ(dest_src1[2], 2);
ASSERT_EQ(val_src1[0], 10);
ASSERT_EQ(val_src1[1], 11);
ASSERT_EQ(val_src1[2], 12);
ASSERT_NE(val_src1, dest_src1);
}
void TestPseudoPointDEquality() {
draco::Point3ui val = {0, 1, 2};
draco::Point3ui dest = {0, 1, 2};
draco::PseudoPointD<uint32_t> val_src1(&val[0], 3);
draco::PseudoPointD<uint32_t> val_src2(&val[0], 3);
draco::PseudoPointD<uint32_t> dest_src1(&dest[0], 3);
draco::PseudoPointD<uint32_t> dest_src2(&dest[0], 3);
ASSERT_EQ(val_src1, val_src1);
ASSERT_EQ(val_src1, val_src2);
ASSERT_EQ(dest_src1, val_src1);
ASSERT_EQ(dest_src1, val_src2);
ASSERT_EQ(val_src2, val_src1);
ASSERT_EQ(val_src2, val_src2);
ASSERT_EQ(dest_src2, val_src1);
ASSERT_EQ(dest_src2, val_src2);
for (auto i = 0; i < 3; i++) {
ASSERT_EQ(val_src1[i], val_src1[i]);
ASSERT_EQ(val_src1[i], val_src2[i]);
ASSERT_EQ(dest_src1[i], val_src1[i]);
ASSERT_EQ(dest_src1[i], val_src2[i]);
ASSERT_EQ(val_src2[i], val_src1[i]);
ASSERT_EQ(val_src2[i], val_src2[i]);
ASSERT_EQ(dest_src2[i], val_src1[i]);
ASSERT_EQ(dest_src2[i], val_src2[i]);
}
}
void TestPseudoPointDInequality() {
draco::Point3ui val = {0, 1, 2};
draco::Point3ui dest = {1, 2, 3};
draco::PseudoPointD<uint32_t> val_src1(&val[0], 3);
draco::PseudoPointD<uint32_t> val_src2(&val[0], 3);
draco::PseudoPointD<uint32_t> dest_src1(&dest[0], 3);
draco::PseudoPointD<uint32_t> dest_src2(&dest[0], 3);
ASSERT_EQ(val_src1, val_src1);
ASSERT_EQ(val_src1, val_src2);
ASSERT_NE(dest_src1, val_src1);
ASSERT_NE(dest_src1, val_src2);
ASSERT_EQ(val_src2, val_src1);
ASSERT_EQ(val_src2, val_src2);
ASSERT_NE(dest_src2, val_src1);
ASSERT_NE(dest_src2, val_src2);
for (auto i = 0; i < 3; i++) {
ASSERT_EQ(val_src1[i], val_src1[i]);
ASSERT_EQ(val_src1[i], val_src2[i]);
ASSERT_NE(dest_src1[i], val_src1[i]);
ASSERT_NE(dest_src1[i], val_src2[i]);
ASSERT_EQ(val_src2[i], val_src1[i]);
ASSERT_EQ(val_src2[i], val_src2[i]);
ASSERT_NE(dest_src2[i], val_src1[i]);
ASSERT_NE(dest_src2[i], val_src2[i]);
}
}
};
TEST_F(PointDVectorTest, VectorTest) {
TestSize<uint32_t>();
TestContentsDiscrete<uint32_t>();
TestContentsContiguous<uint32_t>();
TestContentsCopy<uint32_t>();
TestIterator<uint32_t>();
TestPoint3Iterator<uint32_t>();
}
TEST_F(PointDVectorTest, PseudoPointDTest) {
TestPseudoPointDSwap();
TestPseudoPointDEquality();
TestPseudoPointDInequality();
}
} // namespace draco

View File

@@ -18,12 +18,13 @@
#include <algorithm>
#include <cmath>
#include "draco/draco_features.h"
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_constrained_multi_parallelogram_shared.h"
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_decoder.h"
#include "draco/compression/attributes/prediction_schemes/mesh_prediction_scheme_parallelogram_shared.h"
#include "draco/compression/bit_coders/rans_bit_decoder.h"
#include "draco/core/varint_decoding.h"
#include "draco/draco_features.h"
namespace draco {
@@ -122,9 +123,8 @@ bool MeshPredictionSchemeConstrainedMultiParallelogramDecoder<
++num_parallelograms;
// Stop processing when we reach the maximum number of allowed
// parallelograms.
if (num_parallelograms == kMaxNumParallelograms) {
if (num_parallelograms == kMaxNumParallelograms)
break;
}
}
// Proceed to the next corner attached to the vertex. First swing left
@@ -154,9 +154,8 @@ bool MeshPredictionSchemeConstrainedMultiParallelogramDecoder<
for (int i = 0; i < num_parallelograms; ++i) {
const int context = num_parallelograms - 1;
const int pos = is_crease_edge_pos[context]++;
if (is_crease_edge_[context].size() <= pos) {
if (is_crease_edge_[context].size() <= pos)
return false;
}
const bool is_crease = is_crease_edge_[context][pos];
if (!is_crease) {
++num_used_parallelograms;
@@ -207,15 +206,12 @@ bool MeshPredictionSchemeConstrainedMultiParallelogramDecoder<
// Encode selected edges using separate rans bit coder for each context.
for (int i = 0; i < kMaxNumParallelograms; ++i) {
uint32_t num_flags;
if (!DecodeVarint<uint32_t>(&num_flags, buffer)) {
return false;
}
DecodeVarint<uint32_t>(&num_flags, buffer);
if (num_flags > 0) {
is_crease_edge_[i].resize(num_flags);
RAnsBitDecoder decoder;
if (!decoder.StartDecoding(buffer)) {
if (!decoder.StartDecoding(buffer))
return false;
}
for (uint32_t j = 0; j < num_flags; ++j) {
is_crease_edge_[i][j] = decoder.DecodeNextBit();
}

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