svn merge ^/trunk/blender -r48592:HEAD
This commit is contained in:
454
CMakeLists.txt
454
CMakeLists.txt
@@ -120,17 +120,20 @@ option(WITH_INTERNATIONAL "Enable I18N (International fonts and text)" ON)
|
||||
option(WITH_PYTHON "Enable Embedded Python API (only disable for development)" ON)
|
||||
option(WITH_PYTHON_SECURITY "Disables execution of scripts within blend files by default (recommend to leave off)" OFF)
|
||||
mark_as_advanced(WITH_PYTHON) # dont want people disabling this unless they really know what they are doing.
|
||||
mark_as_advanced(WITH_PYTHON_SECURITY) # some distrobutions see this as a security issue, rather than have them patch it, make a build option.
|
||||
mark_as_advanced(WITH_PYTHON_SECURITY) # some distributions see this as a security issue, rather than have them patch it, make a build option.
|
||||
|
||||
option(WITH_PYTHON_SAFETY "Enable internal API error checking to track invalid data to prevent crash on access (at the expense of some effeciency, only enable for development)." OFF)
|
||||
option(WITH_PYTHON_MODULE "Enable building as a python module which runs without a user interface, like running regular blender in background mode (experimental, only enable for development)" OFF)
|
||||
option(WITH_BUILDINFO "Include extra build details (only disable for development & faster builds)" ON)
|
||||
option(WITH_IK_ITASC "Enable ITASC IK solver (only disable for development & for incompatible C++ compilers)" ON)
|
||||
option(WITH_IK_SOLVER "Enable Legacy IK solver (only disable for development)" ON)
|
||||
option(WITH_FFTW3 "Enable FFTW3 support (Used for smoke and audio effects)" OFF)
|
||||
option(WITH_BULLET "Enable Bullet (Physics Engine)" ON)
|
||||
option(WITH_GAMEENGINE "Enable Game Engine" ON)
|
||||
option(WITH_PLAYER "Build Player" OFF)
|
||||
option(WITH_OPENCOLORIO "Enable OpenColorIO color management" ON)
|
||||
option(WITH_COMPOSITOR "Enable the tile based nodal compositor" ON)
|
||||
option(WITH_COMPOSITOR_LEGACY "Enable legacy compositor" OFF)
|
||||
|
||||
# GHOST Windowing Library Options
|
||||
option(WITH_GHOST_DEBUG "Enable debugging output for the GHOST library" OFF)
|
||||
@@ -148,7 +151,7 @@ mark_as_advanced(WITH_AUDASPACE)
|
||||
|
||||
|
||||
# (unix defaults to OpenMP On)
|
||||
if(UNIX AND NOT APPLE)
|
||||
if((UNIX AND NOT APPLE) OR (MINGW))
|
||||
set(PLATFORM_DEFAULT ON)
|
||||
else()
|
||||
set(PLATFORM_DEFAULT OFF)
|
||||
@@ -203,6 +206,7 @@ option(WITH_IMAGE_REDCODE "Enable RedCode Image Support" OFF)
|
||||
option(WITH_IMAGE_FRAMESERVER "Enable image FrameServer Support for rendering" ON)
|
||||
|
||||
# Audio/Video format support
|
||||
option(WITH_CODEC_AVI "Enable Blenders own AVI file support (raw/jpeg)" ON)
|
||||
option(WITH_CODEC_FFMPEG "Enable FFMPeg Support (http://ffmpeg.org)" OFF)
|
||||
|
||||
option(WITH_CODEC_SNDFILE "Enable libsndfile Support (http://www.mega-nerd.com/libsndfile)" OFF)
|
||||
@@ -226,9 +230,6 @@ option(WITH_LZMA "Enable best LZMA compression, (used for pointcache)"
|
||||
# Camera/motion tracking
|
||||
option(WITH_LIBMV "Enable libmv structure from motion library" ON)
|
||||
|
||||
# Mesh boolean lib
|
||||
option(WITH_CARVE "Enable Carve library to handle mesh boolean operations" ON)
|
||||
|
||||
# Misc
|
||||
option(WITH_INPUT_NDOF "Enable NDOF input devices (SpaceNavigator and friends)" ON)
|
||||
option(WITH_RAYOPTIMIZATION "Enable use of SIMD (SSE) optimizations for the raytracer" ON)
|
||||
@@ -250,10 +251,13 @@ option(WITH_CYCLES "Enable cycles Render Engine" ON)
|
||||
option(WITH_CYCLES_TEST "Build cycles test application" OFF)
|
||||
option(WITH_CYCLES_OSL "Build Cycles with OSL support" OFF)
|
||||
option(WITH_CYCLES_CUDA_BINARIES "Build cycles CUDA binaries" OFF)
|
||||
set(CYCLES_CUDA_BINARIES_ARCH sm_13 sm_20 sm_21 CACHE STRING "CUDA architectures to build binaries for")
|
||||
set(CYCLES_CUDA_BINARIES_ARCH sm_13 sm_20 sm_21 sm_30 CACHE STRING "CUDA architectures to build binaries for")
|
||||
mark_as_advanced(CYCLES_CUDA_BINARIES_ARCH)
|
||||
unset(PLATFORM_DEFAULT)
|
||||
|
||||
# LLVM
|
||||
option(WITH_LLVM "Use LLVM" OFF)
|
||||
|
||||
# disable for now, but plan to support on all platforms eventually
|
||||
option(WITH_MEM_JEMALLOC "Enable malloc replacement (http://www.canonware.com/jemalloc)" OFF)
|
||||
mark_as_advanced(WITH_MEM_JEMALLOC)
|
||||
@@ -274,7 +278,9 @@ if(APPLE)
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND uname -r OUTPUT_VARIABLE MAC_SYS) # check for actual system-version
|
||||
if (${MAC_SYS} MATCHES 11)
|
||||
if (${MAC_SYS} MATCHES 12)
|
||||
set(OSX_SYSTEM 10.8)
|
||||
elseif (${MAC_SYS} MATCHES 11)
|
||||
set(OSX_SYSTEM 10.7)
|
||||
elseif(${MAC_SYS} MATCHES 10)
|
||||
set(OSX_SYSTEM 10.6)
|
||||
@@ -314,6 +320,9 @@ if(APPLE)
|
||||
option(WITH_COCOA "Use Cocoa framework instead of deprecated Carbon" ON)
|
||||
option(USE_QTKIT "Use QtKit instead of Carbon quicktime (needed for having partial quicktime for 64bit)" OFF)
|
||||
option(WITH_LIBS10.5 "Use 10.5 libs (needed for 64bit builds)" OFF)
|
||||
if(CMAKE_OSX_ARCHITECTURES MATCHES x86_64)
|
||||
set(USE_QTKIT ON CACHE BOOL "ON" FORCE) # no Quicktime in 64bit
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -364,18 +373,25 @@ if(WITH_CYCLES)
|
||||
set(WITH_OPENIMAGEIO ON)
|
||||
endif()
|
||||
|
||||
# auto enable boost for cycles and carve
|
||||
if(WITH_CYCLES OR WITH_CARVE)
|
||||
# auto enable boost for cycles and booleans
|
||||
if(WITH_CYCLES OR WITH_MOD_BOOLEAN)
|
||||
set(WITH_BOOST ON)
|
||||
endif()
|
||||
|
||||
# don't store paths to libs for portable distrobution
|
||||
# auto enable llvm for cycles_osl
|
||||
if(WITH_CYCLES_OSL)
|
||||
set(WITH_LLVM ON CACHE BOOL "ON" FORCE)
|
||||
endif()
|
||||
|
||||
# don't store paths to libs for portable distribution
|
||||
if(WITH_INSTALL_PORTABLE)
|
||||
set(CMAKE_SKIP_BUILD_RPATH TRUE)
|
||||
endif()
|
||||
|
||||
if(WITH_GHOST_SDL OR WITH_HEADLESS)
|
||||
set(WITH_GHOST_XDND OFF)
|
||||
set(WITH_X11_XF86VMODE OFF)
|
||||
set(WITH_X11_XINPUT OFF)
|
||||
endif()
|
||||
|
||||
if(MINGW)
|
||||
@@ -561,7 +577,14 @@ if(UNIX AND NOT APPLE)
|
||||
endif()
|
||||
|
||||
mark_as_advanced(FFMPEG)
|
||||
set(FFMPEG_INCLUDE_DIRS ${FFMPEG}/include ${FFMPEG}/include/ffmpeg)
|
||||
|
||||
# lame, but until we have proper find module for ffmpeg
|
||||
set(FFMPEG_INCLUDE_DIRS ${FFMPEG}/include)
|
||||
if(EXISTS "${FFMPEG}/include/ffmpeg/")
|
||||
list(APPEND FFMPEG_INCLUDE_DIRS "${FFMPEG}/include/ffmpeg")
|
||||
endif()
|
||||
# end lameness
|
||||
|
||||
mark_as_advanced(FFMPEG_LIBRARIES)
|
||||
set(FFMPEG_LIBPATH ${FFMPEG}/lib)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__STDC_CONSTANT_MACROS")
|
||||
@@ -636,7 +659,11 @@ if(UNIX AND NOT APPLE)
|
||||
else()
|
||||
set(Boost_USE_MULTITHREADED ON)
|
||||
endif()
|
||||
find_package(Boost 1.34 COMPONENTS filesystem regex system thread)
|
||||
if(WITH_CYCLES_OSL)
|
||||
find_package(Boost 1.34 COMPONENTS filesystem python3 regex system thread) # osl_nodes uses boost_python
|
||||
else()
|
||||
find_package(Boost 1.34 COMPONENTS filesystem regex system thread)
|
||||
endif()
|
||||
mark_as_advanced(Boost_DIR) # why doesnt boost do this?
|
||||
endif()
|
||||
|
||||
@@ -671,6 +698,100 @@ if(UNIX AND NOT APPLE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_OPENCOLORIO)
|
||||
# use lib dir if available and nothing else specified
|
||||
if(LIBDIR AND NOT OPENCOLORIO_ROOT_DIR)
|
||||
set(OPENCOLORIO_ROOT_DIR ${LIBDIR}/ocio)
|
||||
endif()
|
||||
|
||||
find_package(OpenColorIO)
|
||||
|
||||
set(OPENCOLORIO_LIBRARIES ${OPENCOLORIO_LIBRARIES})
|
||||
set(OPENCOLORIO_LIBPATH) # TODO, remove and reference the absolute path everywhere
|
||||
set(OPENCOLORIO_DEFINITIONS)
|
||||
|
||||
if(NOT OPENCOLORIO_FOUND)
|
||||
set(WITH_OPENCOLORIO OFF)
|
||||
message(STATUS "OpenColorIO not found")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_LLVM)
|
||||
set(LLVM_DIRECTORY ${LIBDIR}/llvm CACHE PATH "Path to the LLVM installation")
|
||||
set(LLVM_VERSION "3.0" CACHE STRING "Version of LLVM to use" "")
|
||||
set(LLVM_STATIC YES)
|
||||
if(LLVM_DIRECTORY)
|
||||
set(LLVM_CONFIG "${LLVM_DIRECTORY}/bin/llvm-config")
|
||||
else()
|
||||
set(LLVM_CONFIG llvm-config)
|
||||
endif()
|
||||
execute_process(COMMAND ${LLVM_CONFIG} --version
|
||||
OUTPUT_VARIABLE LLVM_VERSION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${LLVM_CONFIG} --prefix
|
||||
OUTPUT_VARIABLE LLVM_DIRECTORY
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${LLVM_CONFIG} --libdir
|
||||
OUTPUT_VARIABLE LLVM_LIB_DIR
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${LLVM_CONFIG} --includedir
|
||||
OUTPUT_VARIABLE LLVM_INCLUDES
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
find_library(LLVM_LIBRARY
|
||||
NAMES libLLVMAnalysis.a # first of a whole bunch of libs to get
|
||||
PATHS ${LLVM_LIB_DIR})
|
||||
message(STATUS "LLVM version = ${LLVM_VERSION}")
|
||||
message(STATUS "LLVM dir = ${LLVM_DIRECTORY}")
|
||||
message(STATUS "LLVM includes = ${LLVM_INCLUDES}")
|
||||
message(STATUS "LLVM lib dir = ${LLVM_LIB_DIR}")
|
||||
|
||||
if(LLVM_LIBRARY AND LLVM_INCLUDES AND LLVM_DIRECTORY AND LLVM_LIB_DIR)
|
||||
# ensure include directory is added (in case of non-standard locations
|
||||
include_directories(BEFORE "${LLVM_INCLUDES}")
|
||||
string(REGEX REPLACE "\\." "" OSL_LLVM_VERSION ${LLVM_VERSION})
|
||||
message(STATUS "LLVM OSL_LLVM_VERSION = ${OSL_LLVM_VERSION}")
|
||||
add_definitions("-DOSL_LLVM_VERSION=${OSL_LLVM_VERSION}")
|
||||
if(LLVM_STATIC)
|
||||
# if static LLVM libraries were requested, use llvm-config to generate
|
||||
# the list of what libraries we need, and substitute that in the right
|
||||
# way for LLVM_LIBRARY.
|
||||
execute_process(COMMAND ${LLVM_CONFIG} --libfiles
|
||||
OUTPUT_VARIABLE LLVM_LIBRARY
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
string(REPLACE " " ";" LLVM_LIBRARY ${LLVM_LIBRARY})
|
||||
endif()
|
||||
message(STATUS "LLVM library = ${LLVM_LIBRARY}")
|
||||
else()
|
||||
message(FATAL_ERROR "LLVM not found.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_OSL)
|
||||
set(CYCLES_OSL ${LIBDIR}/osl CACHE PATH "Path to OpenShadingLanguage installation")
|
||||
|
||||
message(STATUS "CYCLES_OSL = ${CYCLES_OSL}")
|
||||
|
||||
find_library(OSL_LIB_EXEC NAMES oslexec PATHS ${CYCLES_OSL}/lib)
|
||||
find_library(OSL_LIB_COMP NAMES oslcomp PATHS ${CYCLES_OSL}/lib)
|
||||
find_library(OSL_LIB_QUERY NAMES oslquery PATHS ${CYCLES_OSL}/lib)
|
||||
# Note: --whole-archive is needed to force loading of all symbols in liboslexec,
|
||||
# otherwise LLVM is missing the osl_allocate_closure_component function
|
||||
list(APPEND OSL_LIBRARIES ${OSL_LIB_COMP} -Wl,--whole-archive ${OSL_LIB_EXEC} -Wl,--no-whole-archive ${OSL_LIB_QUERY})
|
||||
find_path(OSL_INCLUDES OSL/oslclosure.h PATHS ${CYCLES_OSL}/include)
|
||||
find_program(OSL_COMPILER NAMES oslc PATHS ${CYCLES_OSL}/bin)
|
||||
|
||||
if(OSL_INCLUDES AND OSL_LIBRARIES AND OSL_COMPILER)
|
||||
set(OSL_FOUND TRUE)
|
||||
message(STATUS "OSL includes = ${OSL_INCLUDES}")
|
||||
message(STATUS "OSL library = ${OSL_LIBRARIES}")
|
||||
message(STATUS "OSL compiler = ${OSL_COMPILER}")
|
||||
else()
|
||||
message(STATUS "OSL not found")
|
||||
endif()
|
||||
|
||||
include_directories(${OSL_INCLUDES})
|
||||
endif()
|
||||
|
||||
# OpenSuse needs lutil, ArchLinux not, for now keep, can avoid by using --as-needed
|
||||
set(PLATFORM_LINKLIBS "-lutil -lc -lm -lpthread -lstdc++")
|
||||
|
||||
@@ -815,6 +936,31 @@ elseif(WIN32)
|
||||
add_definitions(-D__SSE__ -D__MMX__)
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_OSL)
|
||||
set(CYCLES_OSL ${LIBDIR}/osl CACHE PATH "Path to OpenShadingLanguage installation")
|
||||
|
||||
message(STATUS "CYCLES_OSL = ${CYCLES_OSL}")
|
||||
|
||||
find_library(OSL_LIB_EXEC NAMES oslexec PATHS ${CYCLES_OSL}/lib)
|
||||
find_library(OSL_LIB_COMP NAMES oslcomp PATHS ${CYCLES_OSL}/lib)
|
||||
find_library(OSL_LIB_QUERY NAMES oslquery PATHS ${CYCLES_OSL}/lib)
|
||||
# WARNING! depends on correct order of OSL libs linking
|
||||
list(APPEND OSL_LIBRARIES ${OSL_LIB_COMP} ${OSL_LIB_EXEC} ${OSL_LIB_QUERY})
|
||||
find_path(OSL_INCLUDES OSL/oslclosure.h PATHS ${CYCLES_OSL}/include)
|
||||
find_program(OSL_COMPILER NAMES oslc PATHS ${CYCLES_OSL}/bin)
|
||||
|
||||
if(OSL_INCLUDES AND OSL_LIBRARIES AND OSL_COMPILER)
|
||||
set(OSL_FOUND TRUE)
|
||||
message(STATUS "OSL includes = ${OSL_INCLUDES}")
|
||||
message(STATUS "OSL library = ${OSL_LIBRARIES}")
|
||||
message(STATUS "OSL compiler = ${OSL_COMPILER}")
|
||||
else()
|
||||
message(STATUS "OSL not found")
|
||||
endif()
|
||||
|
||||
include_directories(${OSL_INCLUDES})
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
set(PLATFORM_LINKLIBS ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 advapi32 shfolder shell32 ole32 oleaut32 uuid)
|
||||
|
||||
@@ -856,7 +1002,7 @@ elseif(WIN32)
|
||||
if(WITH_MOD_CLOTH_ELTOPO)
|
||||
set(LAPACK ${LIBDIR}/lapack)
|
||||
# set(LAPACK_INCLUDE_DIR ${LAPACK}/include)
|
||||
set_lib_path(LAPACK_LIBPATH ${LAPACK}/lib)
|
||||
set(LAPACK_LIBPATH ${LAPACK}/lib)
|
||||
set(LAPACK_LIBRARIES
|
||||
${LIBDIR}/lapack/lib/libf2c.lib
|
||||
${LIBDIR}/lapack/lib/clapack_nowrap.lib
|
||||
@@ -896,6 +1042,7 @@ elseif(WIN32)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENCOLLADA)
|
||||
set(OPENCOLLADA ${LIBDIR}/opencollada)
|
||||
|
||||
set(OPENCOLLADA_INCLUDE_DIRS
|
||||
${LIBDIR}/opencollada/include/COLLADAStreamWriter/include
|
||||
@@ -904,23 +1051,22 @@ elseif(WIN32)
|
||||
${LIBDIR}/opencollada/include/COLLADASaxFrameworkLoader/include
|
||||
${LIBDIR}/opencollada/include/GeneratedSaxParser/include
|
||||
)
|
||||
|
||||
set_lib_path(OPENCOLLADA_LIBPATH "opencollada/lib")
|
||||
set_lib_path(OPENCOLLADA_LIBPATH "opencollada")
|
||||
|
||||
set(OPENCOLLADA_LIBRARIES
|
||||
${OPENCOLLADA_LIBPATH}/OpenCOLLADASaxFrameworkLoader.lib
|
||||
${OPENCOLLADA_LIBPATH}/OpenCOLLADAFramework.lib
|
||||
${OPENCOLLADA_LIBPATH}/OpenCOLLADABaseUtils.lib
|
||||
${OPENCOLLADA_LIBPATH}/OpenCOLLADAStreamWriter.lib
|
||||
${OPENCOLLADA_LIBPATH}/MathMLSolver.lib
|
||||
${OPENCOLLADA_LIBPATH}/GeneratedSaxParser.lib
|
||||
${OPENCOLLADA_LIBPATH}/xml2.lib
|
||||
${OPENCOLLADA_LIBPATH}/buffer.lib
|
||||
${OPENCOLLADA_LIBPATH}/ftoa.lib
|
||||
${OPENCOLLADA_LIBPATH}/UTF.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/OpenCOLLADASaxFrameworkLoader.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/OpenCOLLADAFramework.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/OpenCOLLADABaseUtils.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/OpenCOLLADAStreamWriter.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/MathMLSolver.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/GeneratedSaxParser.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/xml2.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/buffer.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/ftoa.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/UTF.lib
|
||||
)
|
||||
set(PCRE_LIBRARIES
|
||||
${OPENCOLLADA_LIBPATH}/pcre.lib
|
||||
${OPENCOLLADA_LIBPATH}/lib/pcre.lib
|
||||
)
|
||||
|
||||
unset(OPENCOLLADA_LIBPATH)
|
||||
@@ -943,7 +1089,8 @@ elseif(WIN32)
|
||||
|
||||
if(WITH_IMAGE_OPENEXR)
|
||||
set_lib_path(OPENEXR "openexr")
|
||||
set_lib_path(OPENEXR_LIBPATH "openexr/lib")
|
||||
set(OPENEXR_INCLUDE_DIR ${OPENEXR}/include)
|
||||
set(OPENEXR_LIBPATH ${OPENEXR}/lib)
|
||||
set(OPENEXR_LIBRARIES
|
||||
${OPENEXR_LIBPATH}/Iex.lib
|
||||
${OPENEXR_LIBPATH}/Half.lib
|
||||
@@ -951,15 +1098,12 @@ elseif(WIN32)
|
||||
${OPENEXR_LIBPATH}/Imath.lib
|
||||
${OPENEXR_LIBPATH}/IlmThread.lib
|
||||
)
|
||||
set_lib_path(OPENEXR_INCUDE "openexr/include")
|
||||
set(OPENEXR_INCLUDE_DIRS
|
||||
${OPENEXR_INCUDE}
|
||||
${OPENEXR_INCUDE}/IlmImf
|
||||
${OPENEXR_INCUDE}/Iex
|
||||
${OPENEXR_INCUDE}/Imath
|
||||
${OPENEXR_INCLUDE_DIR}
|
||||
${OPENEXR_INCLUDE_DIR}/IlmImf
|
||||
${OPENEXR_INCLUDE_DIR}/Iex
|
||||
${OPENEXR_INCLUDE_DIR}/Imath
|
||||
)
|
||||
unset(OPENEXR_INCUDE)
|
||||
unset(OPENEXR_LIBPATH)
|
||||
endif()
|
||||
|
||||
if(WITH_IMAGE_TIFF)
|
||||
@@ -978,9 +1122,11 @@ elseif(WIN32)
|
||||
if(WITH_PYTHON)
|
||||
# normally cached but not since we include them with blender
|
||||
set(PYTHON_VERSION 3.2) # CACHE STRING)
|
||||
set_lib_path(PYTHON_INCLUDE_DIR "python/include/python${PYTHON_VERSION}")
|
||||
set_lib_path(PYTHON_LIBRARY "python/lib/python32.lib") #CACHE FILEPATH)
|
||||
|
||||
set_lib_path(PYTHON "python")
|
||||
set(PYTHON_LIBRARY ${PYTHON}/lib/python32.lib) #CACHE FILEPATH
|
||||
#Shared includes for both vc2008 and vc2010
|
||||
set(PYTHON_INCLUDE_DIR ${LIBDIR}/python/include/python${PYTHON_VERSION})
|
||||
|
||||
# uncached vars
|
||||
set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}")
|
||||
set(PYTHON_LIBRARIES "${PYTHON_LIBRARY}")
|
||||
@@ -990,22 +1136,27 @@ elseif(WIN32)
|
||||
set(BOOST ${LIBDIR}/boost)
|
||||
set(BOOST_INCLUDE_DIR ${BOOST}/include)
|
||||
if(MSVC10)
|
||||
set(BOOST_POSTFIX "vc100-mt-s-1_47.lib")
|
||||
set(BOOST_DEBUG_POSTFIX "vc100-mt-sgd-1_47.lib")
|
||||
set(BOOST_LIBPATH ${BOOST}/vc2010/lib)
|
||||
set(BOOST_POSTFIX "vc100-mt-s-1_49.lib")
|
||||
set(BOOST_DEBUG_POSTFIX "vc100-mt-sgd-1_49.lib")
|
||||
else()
|
||||
set(BOOST_LIBPATH ${BOOST}/lib)
|
||||
set(BOOST_POSTFIX "vc90-mt-s-1_49.lib")
|
||||
set(BOOST_DEBUG_POSTFIX "vc90-mt-sgd-1_49.lib")
|
||||
endif()
|
||||
set(BOOST_LIBRARIES
|
||||
optimized libboost_date_time-${BOOST_POSTFIX} optimized libboost_filesystem-${BOOST_POSTFIX}
|
||||
optimized libboost_regex-${BOOST_POSTFIX} optimized libboost_system-${BOOST_POSTFIX} optimized libboost_thread-${BOOST_POSTFIX}
|
||||
optimized libboost_regex-${BOOST_POSTFIX}
|
||||
optimized libboost_system-${BOOST_POSTFIX} optimized libboost_thread-${BOOST_POSTFIX}
|
||||
debug libboost_date_time-${BOOST_DEBUG_POSTFIX} debug libboost_filesystem-${BOOST_DEBUG_POSTFIX}
|
||||
debug libboost_regex-${BOOST_DEBUG_POSTFIX} debug libboost_system-${BOOST_DEBUG_POSTFIX} debug libboost_thread-${BOOST_DEBUG_POSTFIX})
|
||||
if(MSVC10)
|
||||
set(BOOST_LIBPATH ${BOOST}/lib/vc_10)
|
||||
else()
|
||||
set(BOOST_LIBPATH ${BOOST}/lib)
|
||||
endif()
|
||||
debug libboost_regex-${BOOST_DEBUG_POSTFIX}
|
||||
debug libboost_system-${BOOST_DEBUG_POSTFIX} debug libboost_thread-${BOOST_DEBUG_POSTFIX})
|
||||
if(WITH_CYCLES_OSL)
|
||||
set(BOOST_LIBRARIES ${BOOST_LIBRARIES}
|
||||
optimized libboost_python3-${BOOST_POSTFIX}
|
||||
debug libboost_python3-${BOOST_DEBUG_POSTFIX})
|
||||
endif(WITH_CYCLES_OSL)
|
||||
|
||||
set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB")
|
||||
endif()
|
||||
|
||||
@@ -1013,10 +1164,18 @@ elseif(WIN32)
|
||||
set(OPENIMAGEIO ${LIBDIR}/openimageio)
|
||||
set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO}/include)
|
||||
set(OPENIMAGEIO_LIBRARIES OpenImageIO)
|
||||
set_lib_path(OPENIMAGEIO_LIBPATH "openimageio/lib")
|
||||
set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib)
|
||||
set(OPENIMAGEIO_DEFINITIONS)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENCOLORIO)
|
||||
set(OPENCOLORIO ${LIBDIR}/opencolorio)
|
||||
set(OPENCOLORIO_INCLUDE_DIRS ${OPENCOLORIO}/include)
|
||||
set(OPENCOLORIO_LIBRARIES OpenColorIO)
|
||||
set(OPENCOLORIO_LIBPATH ${LIBDIR}/opencolorio/lib)
|
||||
set(OPENCOLORIO_DEFINITIONS)
|
||||
endif()
|
||||
|
||||
set(PLATFORM_LINKFLAGS "/SUBSYSTEM:CONSOLE /STACK:2097152 /INCREMENTAL:NO /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:msvcmrt.lib /NODEFAULTLIB:msvcurt.lib /NODEFAULTLIB:msvcrtd.lib")
|
||||
|
||||
# MSVC only, Mingw doesnt need
|
||||
@@ -1029,7 +1188,7 @@ elseif(WIN32)
|
||||
set(PLATFORM_LINKFLAGS_DEBUG "/NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libc.lib")
|
||||
|
||||
# used in many places so include globally, like OpenGL
|
||||
blender_include_dirs("${PTHREADS_INCLUDE_DIRS}")
|
||||
blender_include_dirs_sys("${PTHREADS_INCLUDE_DIRS}")
|
||||
|
||||
elseif(CMAKE_COMPILER_IS_GNUCC)
|
||||
# keep GCC specific stuff here
|
||||
@@ -1045,6 +1204,8 @@ elseif(WIN32)
|
||||
set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS} -lpthread")
|
||||
|
||||
add_definitions(-DFREE_WINDOWS64 -DMS_WIN64)
|
||||
#Turn off OpenMP since it causes crashes on render for subsurfed/multiresolution meshes
|
||||
set(WITH_OPENMP OFF)
|
||||
endif()
|
||||
|
||||
add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE)
|
||||
@@ -1166,14 +1327,22 @@ elseif(WIN32)
|
||||
set(BOOST_POSTFIX "mgw47-mt-s-1_49")
|
||||
set(BOOST_DEBUG_POSTFIX "mgw47-mt-sd-1_49")
|
||||
else()
|
||||
set(BOOST_POSTFIX "mgw46-mt-s-1_47")
|
||||
set(BOOST_DEBUG_POSTFIX "mgw46-mt-sd-1_47")
|
||||
set(BOOST_POSTFIX "mgw46-mt-s-1_49")
|
||||
set(BOOST_DEBUG_POSTFIX "mgw46-mt-sd-1_49")
|
||||
endif()
|
||||
set(BOOST_LIBRARIES
|
||||
optimized boost_date_time-${BOOST_POSTFIX} boost_filesystem-${BOOST_POSTFIX}
|
||||
boost_regex-${BOOST_POSTFIX} boost_system-${BOOST_POSTFIX} boost_thread-${BOOST_POSTFIX}
|
||||
boost_regex-${BOOST_POSTFIX}
|
||||
boost_system-${BOOST_POSTFIX} boost_thread-${BOOST_POSTFIX}
|
||||
debug boost_date_time-${BOOST_DEBUG_POSTFIX} boost_filesystem-${BOOST_DEBUG_POSTFIX}
|
||||
boost_regex-${BOOST_DEBUG_POSTFIX} boost_system-${BOOST_DEBUG_POSTFIX} boost_thread-${BOOST_DEBUG_POSTFIX})
|
||||
boost_regex-${BOOST_DEBUG_POSTFIX}
|
||||
boost_system-${BOOST_DEBUG_POSTFIX} boost_thread-${BOOST_DEBUG_POSTFIX})
|
||||
if(WITH_CYCLES_OSL)
|
||||
set(BOOST_LIBRARIES ${BOOST_LIBRARIES}
|
||||
optimized libboost_python3-${BOOST_POSTFIX}
|
||||
debug libboost_python3-${BOOST_DEBUG_POSTFIX})
|
||||
endif(WITH_CYCLES_OSL)
|
||||
|
||||
set(BOOST_LIBPATH ${BOOST}/lib)
|
||||
set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB -DBOOST_THREAD_USE_LIB ")
|
||||
endif()
|
||||
@@ -1186,10 +1355,18 @@ elseif(WIN32)
|
||||
set(OPENIMAGEIO_DEFINITIONS)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENCOLORIO)
|
||||
set(OPENCOLORIO ${LIBDIR}/opencolorio)
|
||||
set(OPENCOLORIO_INCLUDE_DIRS ${OPENCOLORIO}/include)
|
||||
set(OPENCOLORIO_LIBRARIES OpenColorIO)
|
||||
set(OPENCOLORIO_LIBPATH ${OPENCOLORIO}/lib)
|
||||
set(OPENCOLORIO_DEFINITIONS)
|
||||
endif()
|
||||
|
||||
set(PLATFORM_LINKFLAGS "-Xlinker --stack=2097152")
|
||||
|
||||
## DISABLE - causes linking errors
|
||||
## for re-distrobution, so users dont need mingw installed
|
||||
## for re-distribution, so users dont need mingw installed
|
||||
# set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -static-libgcc -static-libstdc++")
|
||||
|
||||
endif()
|
||||
@@ -1301,6 +1478,7 @@ elseif(APPLE)
|
||||
|
||||
if(WITH_IMAGE_OPENEXR)
|
||||
set(OPENEXR ${LIBDIR}/openexr)
|
||||
set(OPENEXR_INCLUDE_DIR ${OPENEXR}/include)
|
||||
set(OPENEXR_INCLUDE_DIRS ${OPENEXR}/include/OpenEXR)
|
||||
set(OPENEXR_LIBRARIES Iex Half IlmImf Imath IlmThread)
|
||||
set(OPENEXR_LIBPATH ${OPENEXR}/lib)
|
||||
@@ -1419,7 +1597,11 @@ elseif(APPLE)
|
||||
if(WITH_BOOST)
|
||||
set(BOOST ${LIBDIR}/boost)
|
||||
set(BOOST_INCLUDE_DIR ${BOOST}/include)
|
||||
set(BOOST_LIBRARIES boost_date_time-mt boost_filesystem-mt boost_regex-mt boost_system-mt boost_thread-mt)
|
||||
if(WITH_CYCLES_OSL)
|
||||
set(BOOST_LIBRARIES boost_date_time-mt boost_filesystem-mt boost_python3-mt boost_regex-mt boost_system-mt boost_thread-mt)
|
||||
else(WITH_CYCLES_OSL)
|
||||
set(BOOST_LIBRARIES boost_date_time-mt boost_filesystem-mt boost_regex-mt boost_system-mt boost_thread-mt)
|
||||
endif(WITH_CYCLES_OSL)
|
||||
set(BOOST_LIBPATH ${BOOST}/lib)
|
||||
set(BOOST_DEFINITIONS)
|
||||
endif()
|
||||
@@ -1427,21 +1609,105 @@ elseif(APPLE)
|
||||
if(WITH_OPENIMAGEIO)
|
||||
set(OPENIMAGEIO ${LIBDIR}/openimageio)
|
||||
set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO}/include)
|
||||
set(OPENIMAGEIO_LIBRARIES OpenImageIO ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${TIFF_LIBRARY} ${OPENEXR_LIBRARIES} ${ZLIB_LIBRARIES})
|
||||
set(OPENIMAGEIO_LIBRARIES -force_load ${OPENIMAGEIO}/lib/libOpenImageIO.a ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${TIFF_LIBRARY} ${OPENEXR_LIBRARIES} ${ZLIB_LIBRARIES})
|
||||
set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib ${JPEG_LIBPATH} ${PNG_LIBPATH} ${TIFF_LIBPATH} ${OPENEXR_LIBPATH} ${ZLIB_LIBPATH})
|
||||
set(OPENIMAGEIO_DEFINITIONS "-DOIIO_STATIC_BUILD")
|
||||
endif()
|
||||
|
||||
if(WITH_OPENCOLORIO)
|
||||
set(OPENCOLORIO ${LIBDIR}/opencolorio)
|
||||
set(OPENCOLORIO_INCLUDE_DIRS ${OPENCOLORIO}/include)
|
||||
set(OPENCOLORIO_LIBRARIES OpenColorIO tinyxml yaml-cpp)
|
||||
set(OPENCOLORIO_LIBPATH ${OPENCOLORIO}/lib)
|
||||
set(OPENCOLORIO_DEFINITIONS "-DOCIO_STATIC_BUILD")
|
||||
endif()
|
||||
|
||||
if(WITH_LLVM)
|
||||
set(LLVM_DIRECTORY ${LIBDIR}/llvm CACHE PATH "Path to the LLVM installation")
|
||||
set(LLVM_VERSION "3.1" CACHE STRING "Version of LLVM to use" "")
|
||||
set(LLVM_STATIC YES)
|
||||
if(LLVM_DIRECTORY)
|
||||
set(LLVM_CONFIG "${LLVM_DIRECTORY}/bin/llvm-config")
|
||||
else()
|
||||
set(LLVM_CONFIG llvm-config)
|
||||
endif()
|
||||
execute_process(COMMAND ${LLVM_CONFIG} --version
|
||||
OUTPUT_VARIABLE LLVM_VERSION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${LLVM_CONFIG} --prefix
|
||||
OUTPUT_VARIABLE LLVM_DIRECTORY
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${LLVM_CONFIG} --libdir
|
||||
OUTPUT_VARIABLE LLVM_LIB_DIR
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${LLVM_CONFIG} --includedir
|
||||
OUTPUT_VARIABLE LLVM_INCLUDES
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
find_library(LLVM_LIBRARY
|
||||
NAMES libLLVMAnalysis.a # first of a whole bunch of libs to get
|
||||
PATHS ${LLVM_LIB_DIR})
|
||||
message(STATUS "LLVM version = ${LLVM_VERSION}")
|
||||
message(STATUS "LLVM dir = ${LLVM_DIRECTORY}")
|
||||
message(STATUS "LLVM includes = ${LLVM_INCLUDES}")
|
||||
message(STATUS "LLVM lib dir = ${LLVM_LIB_DIR}")
|
||||
|
||||
if(LLVM_LIBRARY AND LLVM_INCLUDES AND LLVM_DIRECTORY AND LLVM_LIB_DIR)
|
||||
# ensure include directory is added (in case of non-standard locations
|
||||
include_directories(BEFORE "${LLVM_INCLUDES}")
|
||||
string(REGEX REPLACE "\\." "" OSL_LLVM_VERSION ${LLVM_VERSION})
|
||||
message(STATUS "LLVM OSL_LLVM_VERSION = ${OSL_LLVM_VERSION}")
|
||||
add_definitions("-DOSL_LLVM_VERSION=${OSL_LLVM_VERSION}")
|
||||
if(LLVM_STATIC)
|
||||
# if static LLVM libraries were requested, use llvm-config to generate
|
||||
# the list of what libraries we need, and substitute that in the right
|
||||
# way for LLVM_LIBRARY.
|
||||
execute_process(COMMAND ${LLVM_CONFIG} --libfiles
|
||||
OUTPUT_VARIABLE LLVM_LIBRARY
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
string(REPLACE " " ";" LLVM_LIBRARY ${LLVM_LIBRARY})
|
||||
endif()
|
||||
message(STATUS "LLVM library = ${LLVM_LIBRARY}")
|
||||
else()
|
||||
message(FATAL_ERROR "LLVM not found.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_OSL)
|
||||
set(CYCLES_OSL ${LIBDIR}/osl CACHE PATH "Path to OpenShadingLanguage installation")
|
||||
|
||||
message(STATUS "CYCLES_OSL = ${CYCLES_OSL}")
|
||||
|
||||
find_library(OSL_LIB_EXEC NAMES oslexec PATHS ${CYCLES_OSL}/lib)
|
||||
find_library(OSL_LIB_COMP NAMES oslcomp PATHS ${CYCLES_OSL}/lib)
|
||||
find_library(OSL_LIB_QUERY NAMES oslquery PATHS ${CYCLES_OSL}/lib)
|
||||
# WARNING! depends on correct order of OSL libs linking
|
||||
list(APPEND OSL_LIBRARIES ${OSL_LIB_COMP} -force_load ${OSL_LIB_EXEC} ${OSL_LIB_QUERY})
|
||||
find_path(OSL_INCLUDES OSL/oslclosure.h PATHS ${CYCLES_OSL}/include)
|
||||
find_program(OSL_COMPILER NAMES oslc PATHS ${CYCLES_OSL}/bin)
|
||||
|
||||
if(OSL_INCLUDES AND OSL_LIBRARIES AND OSL_COMPILER)
|
||||
set(OSL_FOUND TRUE)
|
||||
message(STATUS "OSL includes = ${OSL_INCLUDES}")
|
||||
message(STATUS "OSL library = ${OSL_LIBRARIES}")
|
||||
message(STATUS "OSL compiler = ${OSL_COMPILER}")
|
||||
else()
|
||||
message(STATUS "OSL not found")
|
||||
endif()
|
||||
|
||||
include_directories(${OSL_INCLUDES})
|
||||
endif()
|
||||
|
||||
set(EXETYPE MACOSX_BUNDLE)
|
||||
|
||||
set(CMAKE_C_FLAGS_DEBUG "-fno-strict-aliasing -g")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-fno-strict-aliasing -g")
|
||||
if(CMAKE_OSX_ARCHITECTURES MATCHES "i386")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -fvariable-expansion-in-unroller")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O2 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -fvariable-expansion-in-unroller")
|
||||
elseif(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -msse3 -mssse3 -fvariable-expansion-in-unroller")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O2 -mdynamic-no-pic -ftree-vectorize -msse -msse2 -msse3 -mssse3 -fvariable-expansion-in-unroller")
|
||||
if(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64" OR CMAKE_OSX_ARCHITECTURES MATCHES "i386")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -mdynamic-no-pic -msse -msse2 -msse3 -mssse3")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O2 -mdynamic-no-pic -msse -msse2 -msse3 -mssse3")
|
||||
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -ftree-vectorize -fvariable-expansion-in-unroller")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ftree-vectorize -fvariable-expansion-in-unroller")
|
||||
endif()
|
||||
else()
|
||||
set(CMAKE_C_FLAGS_RELEASE "-mdynamic-no-pic -fno-strict-aliasing")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-mdynamic-no-pic -fno-strict-aliasing")
|
||||
@@ -1464,6 +1730,12 @@ if(WITH_CYCLES)
|
||||
if(NOT WITH_BOOST)
|
||||
message(FATAL_ERROR "Cycles reqires WITH_BOOST, the library may not have been found. Configure BOOST or disable WITH_CYCLES")
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_OSL)
|
||||
if(NOT WITH_LLVM)
|
||||
message(FATAL_ERROR "Cycles OSL reqires WITH_LLVM, the library may not have been found. Configure LLVM or disable WITH_CYCLES_OSL")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -1488,6 +1760,16 @@ endif()
|
||||
if(MSVC)
|
||||
# for some reason this fails on msvc
|
||||
add_definitions(-D__LITTLE_ENDIAN__)
|
||||
|
||||
# OSX-Note: as we do crosscompiling with specific set architecture,
|
||||
# endianess-detection and autosetting is counterproductive
|
||||
# so we just set endianess according CMAKE_OSX_ARCHITECTURES
|
||||
|
||||
elseif(CMAKE_OSX_ARCHITECTURES MATCHES i386 OR CMAKE_OSX_ARCHITECTURES MATCHES x86_64)
|
||||
add_definitions(-D__LITTLE_ENDIAN__)
|
||||
elseif(CMAKE_OSX_ARCHITECTURES MATCHES ppc OR CMAKE_OSX_ARCHITECTURES MATCHES ppc64)
|
||||
add_definitions(-D__BIG_ENDIAN__)
|
||||
|
||||
else()
|
||||
include(TestBigEndian)
|
||||
test_big_endian(_SYSTEM_BIG_ENDIAN)
|
||||
@@ -1588,17 +1870,22 @@ if(CMAKE_COMPILER_IS_GNUCC)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_CAST_ALIGN -Wcast-align)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ERROR_DECLARATION_AFTER_STATEMENT -Werror=declaration-after-statement)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ERROR_IMPLICIT_FUNCTION_DECLARATION -Werror=implicit-function-declaration)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ERROR_RETURN_TYPE -Werror=return-type)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ERROR_RETURN_TYPE -Werror=return-type)
|
||||
# system headers sometimes do this, disable for now, was: -Werror=strict-prototypes
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_STRICT_PROTOTYPES -Wstrict-prototypes)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_STRICT_PROTOTYPES -Wstrict-prototypes)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_MISSING_PROTOTYPES -Wmissing-prototypes)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_POINTER_ARITH -Wpointer-arith)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNUSED_PARAMETER -Wunused-parameter)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_WRITE_STRINGS -Wwrite-strings)
|
||||
|
||||
# # this causes too many warnings, disable
|
||||
# ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNDEFINED -Wundef)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_LOGICAL_OP -Wlogical-op)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNDEF -Wundef)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNINITIALIZED -Wuninitialized)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_INIT_SELF -Winit-self) # needs -Wuninitialized
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_NULL -Wnonnull) # C only
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_MISSING_INCLUDE_DIRS -Wmissing-include-dirs)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_DIV_BY_ZERO -Wno-div-by-zero)
|
||||
|
||||
# disable because it gives warnings for printf() & friends.
|
||||
# ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_DOUBLE_PROMOTION -Wdouble-promotion -Wno-error=double-promotion)
|
||||
@@ -1610,9 +1897,17 @@ if(CMAKE_COMPILER_IS_GNUCC)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_ALL -Wall)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_SIGN_COMPARE -Wno-sign-compare)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_LOGICAL_OP -Wlogical-op)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNINITIALIZED -Wuninitialized)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_INIT_SELF -Winit-self) # needs -Wuninitialized
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_MISSING_INCLUDE_DIRS -Wmissing-include-dirs)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_DIV_BY_ZERO -Wno-div-by-zero)
|
||||
|
||||
# # this causes too many warnings, disable
|
||||
# ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNDEFINED -Wundef)
|
||||
# causes too many warnings
|
||||
if(NOT APPLE)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNDEF -Wundef)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_MISSING_DECLARATIONS -Wmissing-declarations)
|
||||
endif()
|
||||
|
||||
# flags to undo strict flags
|
||||
ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_DEPRECATED_DECLARATIONS -Wno-deprecated-declarations)
|
||||
@@ -1624,17 +1919,22 @@ if(CMAKE_COMPILER_IS_GNUCC)
|
||||
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
|
||||
# strange, clang complains these are not supported, but then yses them.
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ALL -Wall)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_AUTOLOGICAL_COMPARE -Wno-tautological-compare)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_STRICT_PROTOTYPES -Wstrict-prototypes)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_MISSING_PROTOTYPES -Wmissing-prototypes)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNUSED_MACROS -Wunused-macros)
|
||||
|
||||
ADD_CHECK_C_COMPILER_FLAG(CXX_WARNINGS C_WARN_ALL -Wall)
|
||||
ADD_CHECK_C_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_AUTOLOGICAL_COMPARE -Wno-tautological-compare)
|
||||
ADD_CHECK_C_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
|
||||
ADD_CHECK_C_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
|
||||
ADD_CHECK_C_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_OVERLOADED_VIRTUAL -Wno-overloaded-virtual) # we get a lot of these, if its a problem a dev needs to look into it.
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_ALL -Wall)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_AUTOLOGICAL_COMPARE -Wno-tautological-compare)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_OVERLOADED_VIRTUAL -Wno-overloaded-virtual) # we get a lot of these, if its a problem a dev needs to look into it.
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNUSED_MACROS -Wunused-macros)
|
||||
|
||||
elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
|
||||
|
||||
@@ -1654,9 +1954,6 @@ endif()
|
||||
|
||||
# MSVC2010 fails to links C++ libs right
|
||||
if(MSVC10)
|
||||
if(WITH_IMAGE_OPENEXR)
|
||||
message(WARNING "MSVC 2010 does not support OpenEXR, disabling WITH_IMAGE_OPENEXR. To enable support use Use MSVC 2008")
|
||||
endif()
|
||||
if(WITH_OPENCOLLADA)
|
||||
message(WARNING "MSVC 2010 does not support OpenCollada, disabling WITH_OPENCOLLADA. To enable support use Use MSVC 2008")
|
||||
endif()
|
||||
@@ -1792,12 +2089,14 @@ if(FIRST_RUN)
|
||||
info_cfg_option(WITH_GAMEENGINE)
|
||||
info_cfg_option(WITH_PLAYER)
|
||||
info_cfg_option(WITH_BULLET)
|
||||
info_cfg_option(WITH_IK_SOLVER)
|
||||
info_cfg_option(WITH_IK_ITASC)
|
||||
info_cfg_option(WITH_OPENCOLLADA)
|
||||
info_cfg_option(WITH_FFTW3)
|
||||
info_cfg_option(WITH_INTERNATIONAL)
|
||||
info_cfg_option(WITH_INPUT_NDOF)
|
||||
info_cfg_option(WITH_CYCLES)
|
||||
info_cfg_option(WITH_OPENCOLORIO)
|
||||
|
||||
info_cfg_text("Compiler Options:")
|
||||
info_cfg_option(WITH_BUILDINFO)
|
||||
@@ -1825,6 +2124,7 @@ if(FIRST_RUN)
|
||||
info_cfg_option(WITH_OPENAL)
|
||||
info_cfg_option(WITH_SDL)
|
||||
info_cfg_option(WITH_JACK)
|
||||
info_cfg_option(WITH_CODEC_AVI)
|
||||
info_cfg_option(WITH_CODEC_FFMPEG)
|
||||
info_cfg_option(WITH_CODEC_SNDFILE)
|
||||
|
||||
|
||||
16
GNUmakefile
16
GNUmakefile
@@ -19,9 +19,9 @@
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# This Makefile does an out-of-source CMake build in ../build/`OS`_`CPU`
|
||||
# This Makefile does an out-of-source CMake build in ../build_`OS`_`CPU`
|
||||
# eg:
|
||||
# ../build/Linux_i386
|
||||
# ../build_linux_i386
|
||||
# This is for users who like to configure & build blender with a single command.
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ ifndef BUILD_CMAKE_ARGS
|
||||
endif
|
||||
|
||||
ifndef BUILD_DIR
|
||||
BUILD_DIR:=$(shell dirname $(BLENDER_DIR))/build/$(OS_NCASE)
|
||||
BUILD_DIR:=$(shell dirname $(BLENDER_DIR))/build_$(OS_NCASE)
|
||||
endif
|
||||
|
||||
|
||||
@@ -171,8 +171,10 @@ help:
|
||||
@echo ""
|
||||
@echo "Static Source Code Checking (not associated with building blender)"
|
||||
@echo " * check_cppcheck - run blender source through cppcheck (C & C++)"
|
||||
@echo " * check_clang_array - run blender source through clang array checking script (C & C++)"
|
||||
@echo " * check_splint - run blenders source through splint (C only)"
|
||||
@echo " * check_sparse - run blenders source through sparse (C only)"
|
||||
@echo " * check_smatch - run blenders source through smatch (C only)"
|
||||
@echo " * check_spelling_c - check for spelling errors (C/C++ only)"
|
||||
@echo " * check_spelling_py - check for spelling errors (Python only)"
|
||||
@echo ""
|
||||
@@ -243,6 +245,10 @@ check_cppcheck:
|
||||
$(CMAKE_CONFIG)
|
||||
cd $(BUILD_DIR) ; python3.2 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py
|
||||
|
||||
check_clang_array:
|
||||
$(CMAKE_CONFIG)
|
||||
cd $(BUILD_DIR) ; python3.2 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_clang_array.py
|
||||
|
||||
check_splint:
|
||||
$(CMAKE_CONFIG)
|
||||
cd $(BUILD_DIR) ; python3.2 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_splint.py
|
||||
@@ -251,6 +257,10 @@ check_sparse:
|
||||
$(CMAKE_CONFIG)
|
||||
cd $(BUILD_DIR) ; python3.2 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_sparse.py
|
||||
|
||||
check_smatch:
|
||||
$(CMAKE_CONFIG)
|
||||
cd $(BUILD_DIR) ; python3.2 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_smatch.py
|
||||
|
||||
check_spelling_py:
|
||||
cd $(BUILD_DIR) ; PYTHONIOENCODING=utf_8 python3.2 $(BLENDER_DIR)/source/tools/spell_check_source.py $(BLENDER_DIR)/release/scripts
|
||||
|
||||
|
||||
197
SConstruct
197
SConstruct
@@ -92,7 +92,7 @@ if platform=='win32':
|
||||
|
||||
if not use_color=='1':
|
||||
B.bc.disable()
|
||||
|
||||
|
||||
#on defaut white Os X terminal, some colors are totally unlegible
|
||||
if platform=='darwin':
|
||||
B.bc.OKGREEN = '\033[34m'
|
||||
@@ -123,7 +123,7 @@ if bitness:
|
||||
B.bitness = bitness
|
||||
else:
|
||||
B.bitness = tempbitness
|
||||
|
||||
|
||||
|
||||
# first check cmdline for toolset and we create env to work on
|
||||
quickie = B.arguments.get('BF_QUICK', None)
|
||||
@@ -138,7 +138,7 @@ if quickie:
|
||||
B.quickie=string.split(quickie,',')
|
||||
else:
|
||||
B.quickie=[]
|
||||
|
||||
|
||||
toolset = B.arguments.get('BF_TOOLSET', None)
|
||||
if toolset:
|
||||
print "Using " + toolset
|
||||
@@ -270,7 +270,7 @@ if 'blenderlite' in B.targets:
|
||||
target_env_defs['WITH_BF_PYTHON'] = False
|
||||
target_env_defs['WITH_BF_3DMOUSE'] = False
|
||||
target_env_defs['WITH_BF_LIBMV'] = False
|
||||
|
||||
|
||||
# Merge blenderlite, let command line to override
|
||||
for k,v in target_env_defs.iteritems():
|
||||
if k not in B.arguments:
|
||||
@@ -280,8 +280,10 @@ if 'blenderlite' in B.targets:
|
||||
if env['OURPLATFORM']=='darwin':
|
||||
print B.bc.OKGREEN + "Detected Xcode version: -- " + B.bc.ENDC + env['XCODE_CUR_VER'] + " --"
|
||||
print "Available " + env['MACOSX_SDK_CHECK']
|
||||
if not 'Mac OS X 10.5' in env['MACOSX_SDK_CHECK']:
|
||||
print B.bc.OKGREEN + "MacOSX10.5.sdk not available:" + B.bc.ENDC + " using MacOSX10.6.sdk"
|
||||
if not 'Mac OS X 10.6' in env['MACOSX_SDK_CHECK']:
|
||||
print B.bc.OKGREEN + "Auto-setting available MacOSX SDK -> " + B.bc.ENDC + "MacOSX10.7.sdk"
|
||||
elif not 'Mac OS X 10.5' in env['MACOSX_SDK_CHECK']:
|
||||
print B.bc.OKGREEN + "Auto-setting available MacOSX SDK -> " + B.bc.ENDC + "MacOSX10.6.sdk"
|
||||
else:
|
||||
print B.bc.OKGREEN + "Found recommended sdk :" + B.bc.ENDC + " using MacOSX10.5.sdk"
|
||||
|
||||
@@ -317,7 +319,7 @@ if env['WITH_BF_OPENMP'] == 1:
|
||||
|
||||
if env['WITH_GHOST_COCOA'] == True:
|
||||
env.Append(CPPFLAGS=['-DGHOST_COCOA'])
|
||||
|
||||
|
||||
if env['USE_QTKIT'] == True:
|
||||
env.Append(CPPFLAGS=['-DUSE_QTKIT'])
|
||||
|
||||
@@ -364,6 +366,7 @@ else:
|
||||
|
||||
# TODO, make optional
|
||||
env['CPPFLAGS'].append('-DWITH_AUDASPACE')
|
||||
env['CPPFLAGS'].append('-DWITH_AVI')
|
||||
|
||||
# lastly we check for root_build_dir ( we should not do before, otherwise we might do wrong builddir
|
||||
B.root_build_dir = env['BF_BUILDDIR']
|
||||
@@ -372,7 +375,7 @@ if not B.root_build_dir[-1]==os.sep:
|
||||
B.root_build_dir += os.sep
|
||||
if not B.doc_build_dir[-1]==os.sep:
|
||||
B.doc_build_dir += os.sep
|
||||
|
||||
|
||||
# We do a shortcut for clean when no quicklist is given: just delete
|
||||
# builddir without reading in SConscripts
|
||||
do_clean = None
|
||||
@@ -420,16 +423,16 @@ if not quickie and do_clean:
|
||||
# with _any_ library but since we used a fixed python version this tends to
|
||||
# be most problematic.
|
||||
if env['WITH_BF_PYTHON']:
|
||||
py_h = os.path.join(Dir(env.subst('${BF_PYTHON_INC}')).abspath, "Python.h")
|
||||
py_h = os.path.join(Dir(env.subst('${BF_PYTHON_INC}')).abspath, "Python.h")
|
||||
|
||||
if not os.path.exists(py_h):
|
||||
print("\nMissing: \"" + env.subst('${BF_PYTHON_INC}') + os.sep + "Python.h\",\n"
|
||||
" Set 'BF_PYTHON_INC' to point "
|
||||
"to a valid python include path.\n Containing "
|
||||
"Python.h for python version \"" + env.subst('${BF_PYTHON_VERSION}') + "\"")
|
||||
if not os.path.exists(py_h):
|
||||
print("\nMissing: \"" + env.subst('${BF_PYTHON_INC}') + os.sep + "Python.h\",\n"
|
||||
" Set 'BF_PYTHON_INC' to point "
|
||||
"to a valid python include path.\n Containing "
|
||||
"Python.h for python version \"" + env.subst('${BF_PYTHON_VERSION}') + "\"")
|
||||
|
||||
Exit()
|
||||
del py_h
|
||||
Exit()
|
||||
del py_h
|
||||
|
||||
|
||||
if not os.path.isdir ( B.root_build_dir):
|
||||
@@ -443,9 +446,116 @@ if not os.path.isdir ( B.root_build_dir):
|
||||
# if not os.path.isdir(B.doc_build_dir) and env['WITH_BF_DOCS']:
|
||||
# os.makedirs ( B.doc_build_dir )
|
||||
|
||||
###################################
|
||||
# Ensure all data files are valid #
|
||||
###################################
|
||||
if not os.path.isdir ( B.root_build_dir + 'data_headers'):
|
||||
os.makedirs ( B.root_build_dir + 'data_headers' )
|
||||
if not os.path.isdir ( B.root_build_dir + 'data_sources'):
|
||||
os.makedirs ( B.root_build_dir + 'data_sources' )
|
||||
# use for includes
|
||||
env['DATA_HEADERS'] = os.path.join(os.path.abspath(env['BF_BUILDDIR']), "data_headers")
|
||||
env['DATA_SOURCES'] = os.path.join(os.path.abspath(env['BF_BUILDDIR']), "data_sources")
|
||||
def data_to_c(FILE_FROM, FILE_TO, VAR_NAME):
|
||||
if os.sep == "\\":
|
||||
FILE_FROM = FILE_FROM.replace("/", "\\")
|
||||
FILE_TO = FILE_TO.replace("/", "\\")
|
||||
|
||||
# first check if we need to bother.
|
||||
if os.path.exists(FILE_TO):
|
||||
if os.path.getmtime(FILE_FROM) < os.path.getmtime(FILE_TO):
|
||||
return
|
||||
|
||||
print(B.bc.HEADER + "Generating: " + B.bc.ENDC + "%r" % os.path.basename(FILE_TO))
|
||||
fpin = open(FILE_FROM, "rb")
|
||||
fpin.seek(0, os.SEEK_END)
|
||||
size = fpin.tell()
|
||||
fpin.seek(0)
|
||||
|
||||
fpout = open(FILE_TO, "w")
|
||||
fpout.write("int %s_size = %d;\n" % (VAR_NAME, size))
|
||||
fpout.write("char %s[] = {\n" % VAR_NAME)
|
||||
|
||||
while size > 0:
|
||||
size -= 1
|
||||
if size % 32 == 31:
|
||||
fpout.write("\n")
|
||||
|
||||
fpout.write("%3d," % ord(fpin.read(1)))
|
||||
fpout.write("\n 0};\n\n")
|
||||
|
||||
fpin.close()
|
||||
fpout.close()
|
||||
|
||||
def data_to_c_simple(FILE_FROM):
|
||||
filename_only = os.path.basename(FILE_FROM)
|
||||
FILE_TO = os.path.join(env['DATA_SOURCES'], filename_only + ".c")
|
||||
VAR_NAME = "datatoc_" + filename_only.replace(".", "_")
|
||||
|
||||
data_to_c(FILE_FROM, FILE_TO, VAR_NAME)
|
||||
|
||||
|
||||
data_to_c("source/blender/compositor/operations/COM_OpenCLKernels.cl",
|
||||
B.root_build_dir + "data_headers/COM_OpenCLKernels.cl.h",
|
||||
"datatoc_COM_OpenCLKernels_cl")
|
||||
|
||||
data_to_c_simple("release/datafiles/startup.blend")
|
||||
data_to_c_simple("release/datafiles/preview.blend")
|
||||
|
||||
# --- glsl ---
|
||||
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_material.glsl")
|
||||
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vertex.glsl")
|
||||
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl")
|
||||
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_vert.glsl")
|
||||
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_material.glsl")
|
||||
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vsm_store_frag.glsl")
|
||||
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_vsm_store_vert.glsl")
|
||||
|
||||
# --- blender ---
|
||||
data_to_c_simple("release/datafiles/bfont.pfb")
|
||||
data_to_c_simple("release/datafiles/bfont.ttf")
|
||||
data_to_c_simple("release/datafiles/bmonofont.ttf")
|
||||
|
||||
data_to_c_simple("release/datafiles/splash.png")
|
||||
data_to_c_simple("release/datafiles/blender_icons.png")
|
||||
data_to_c_simple("release/datafiles/prvicons.png")
|
||||
|
||||
data_to_c_simple("release/datafiles/brushicons/add.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/blob.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/blur.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/clay.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/claystrips.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/clone.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/crease.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/darken.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/draw.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/fill.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/flatten.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/grab.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/inflate.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/layer.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/lighten.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/mask.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/mix.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/multiply.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/nudge.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/pinch.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/scrape.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/smear.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/smooth.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/snake_hook.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/soften.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/subtract.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/texdraw.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/thumb.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/twist.png")
|
||||
data_to_c_simple("release/datafiles/brushicons/vertexdraw.png")
|
||||
|
||||
##### END DATAFILES ##########
|
||||
|
||||
Help(opts.GenerateHelpText(env))
|
||||
|
||||
# default is new quieter output, but if you need to see the
|
||||
# default is new quieter output, but if you need to see the
|
||||
# commands, do 'scons BF_QUIET=0'
|
||||
bf_quietoutput = B.arguments.get('BF_QUIET', '1')
|
||||
if env['BF_QUIET']:
|
||||
@@ -532,7 +642,7 @@ if env['OURPLATFORM']!='darwin':
|
||||
for targetdir,srcfile in zip(datafilestargetlist, datafileslist):
|
||||
td, tf = os.path.split(targetdir)
|
||||
dotblenderinstall.append(env.Install(dir=td, source=srcfile))
|
||||
|
||||
|
||||
if env['WITH_BF_PYTHON']:
|
||||
#-- local/VERSION/scripts
|
||||
scriptpaths=['release/scripts']
|
||||
@@ -609,13 +719,33 @@ if env['OURPLATFORM']!='darwin':
|
||||
kernel_build_dir = os.path.join(B.root_build_dir, 'intern/cycles/kernel')
|
||||
cubin_file = os.path.join(kernel_build_dir, "kernel_%s.cubin" % arch)
|
||||
scriptinstall.append(env.Install(dir=dir,source=cubin_file))
|
||||
|
||||
|
||||
if env['WITH_BF_OCIO']:
|
||||
colormanagement = os.path.join('release', 'datafiles', 'colormanagement')
|
||||
|
||||
for dp, dn, df in os.walk(colormanagement):
|
||||
if '.svn' in dn:
|
||||
dn.remove('.svn')
|
||||
if '_svn' in dn:
|
||||
dn.remove('_svn')
|
||||
|
||||
dir = os.path.join(env['BF_INSTALLDIR'], VERSION, 'datafiles')
|
||||
dir += os.sep + os.path.basename(colormanagement) + dp[len(colormanagement):]
|
||||
|
||||
source = [os.path.join(dp, f) for f in df if not f.endswith(".pyc")]
|
||||
|
||||
# To ensure empty dirs are created too
|
||||
if len(source) == 0:
|
||||
env.Execute(Mkdir(dir))
|
||||
|
||||
scriptinstall.append(env.Install(dir=dir,source=source))
|
||||
|
||||
if env['WITH_BF_INTERNATIONAL']:
|
||||
internationalpaths=['release' + os.sep + 'datafiles']
|
||||
|
||||
|
||||
def check_path(path, member):
|
||||
return (member in path.split(os.sep))
|
||||
|
||||
|
||||
for intpath in internationalpaths:
|
||||
for dp, dn, df in os.walk(intpath):
|
||||
if '.svn' in dn:
|
||||
@@ -628,7 +758,7 @@ if env['OURPLATFORM']!='darwin':
|
||||
pass
|
||||
else:
|
||||
continue
|
||||
|
||||
|
||||
dir = os.path.join(env['BF_INSTALLDIR'], VERSION)
|
||||
dir += os.sep + os.path.basename(intpath) + dp[len(intpath):]
|
||||
|
||||
@@ -736,12 +866,19 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'):
|
||||
# strict: the x86 build fails on x64 Windows. We need to ship
|
||||
# both builds in x86 packages.
|
||||
if bitness == 32:
|
||||
dllsources.append('${LCGDIR}/thumbhandler/lib/BlendThumb.dll')
|
||||
dllsources.append('${LCGDIR}/thumbhandler/lib/BlendThumb.dll')
|
||||
dllsources.append('${LCGDIR}/thumbhandler/lib/BlendThumb64.dll')
|
||||
|
||||
if env['WITH_BF_OIIO'] and env['OURPLATFORM'] != 'win32-mingw':
|
||||
dllsources.append('${LCGDIR}/openimageio/bin/OpenImageIO.dll')
|
||||
|
||||
if env['WITH_BF_OCIO']:
|
||||
if not env['OURPLATFORM'] in ('win32-mingw', 'linuxcross'):
|
||||
dllsources.append('${LCGDIR}/opencolorio/bin/OpenColorIO.dll')
|
||||
|
||||
else:
|
||||
dllsources.append('${LCGDIR}/opencolorio/bin/libOpenColorIO.dll')
|
||||
|
||||
dllsources.append('#source/icons/blender.exe.manifest')
|
||||
|
||||
windlls = env.Install(dir=env['BF_INSTALLDIR'], source = dllsources)
|
||||
@@ -749,7 +886,7 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'):
|
||||
|
||||
if env['OURPLATFORM'] == 'win64-mingw':
|
||||
dllsources = []
|
||||
|
||||
|
||||
if env['WITH_BF_PYTHON']:
|
||||
if env['BF_DEBUG']:
|
||||
dllsources.append('${BF_PYTHON_LIBPATH}/${BF_PYTHON_DLL}_d.dll')
|
||||
@@ -768,9 +905,17 @@ if env['OURPLATFORM'] == 'win64-mingw':
|
||||
|
||||
if env['WITH_BF_SDL']:
|
||||
dllsources.append('${LCGDIR}/sdl/lib/SDL.dll')
|
||||
|
||||
|
||||
if(env['WITH_BF_OPENMP']):
|
||||
dllsources.append('${LCGDIR}/binaries/libgomp-1.dll')
|
||||
|
||||
if env['WITH_BF_OCIO']:
|
||||
dllsources.append('${LCGDIR}/opencolorio/bin/libOpenColorIO.dll')
|
||||
|
||||
dllsources.append('${LCGDIR}/thumbhandler/lib/BlendThumb64.dll')
|
||||
dllsources.append('${LCGDIR}/binaries/pthreadGC2-w64.dll')
|
||||
dllsources.append('${LCGDIR}/binaries/libgcc_s_sjlj-1.dll')
|
||||
dllsources.append('${LCGDIR}/binaries/libwinpthread-1.dll')
|
||||
dllsources.append('${LCGDIR}/binaries/libstdc++-6.dll')
|
||||
dllsources.append('#source/icons/blender.exe.manifest')
|
||||
|
||||
windlls = env.Install(dir=env['BF_INSTALLDIR'], source = dllsources)
|
||||
|
||||
@@ -106,6 +106,14 @@ BF_OIIO_INC = '${BF_OIIO}/include'
|
||||
BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a'
|
||||
BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
|
||||
|
||||
# Color management
|
||||
WITH_BF_OCIO = True
|
||||
WITH_BF_STATICOCIO = True
|
||||
BF_OCIO = '/opt/ocio'
|
||||
BF_OCIO_INC = '${BF_OCIO}/include'
|
||||
BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a'
|
||||
BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
|
||||
|
||||
WITH_BF_BOOST = True
|
||||
WITH_BF_STATICBOOST = True
|
||||
BF_BOOST = '/opt/boost'
|
||||
|
||||
@@ -82,6 +82,14 @@ WITH_BF_STATIC3DMOUSE = True
|
||||
BF_3DMOUSE = '/home/sources/staticlibs/spnav'
|
||||
BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib32'
|
||||
|
||||
# Color management
|
||||
WITH_BF_OCIO = True
|
||||
WITH_BF_STATICOCIO = True
|
||||
BF_OCIO = '/opt/ocio'
|
||||
BF_OCIO_INC = '${BF_OCIO}/include'
|
||||
BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a'
|
||||
BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
|
||||
|
||||
# JACK
|
||||
WITH_BF_JACK = True
|
||||
|
||||
|
||||
@@ -82,6 +82,14 @@ WITH_BF_STATIC3DMOUSE = True
|
||||
BF_3DMOUSE = '/home/sources/staticlibs/spnav'
|
||||
BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib64'
|
||||
|
||||
# Color management
|
||||
WITH_BF_OCIO = True
|
||||
WITH_BF_STATICOCIO = True
|
||||
BF_OCIO = '/opt/ocio'
|
||||
BF_OCIO_INC = '${BF_OCIO}/include'
|
||||
BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a'
|
||||
BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
|
||||
|
||||
# JACK
|
||||
WITH_BF_JACK = True
|
||||
|
||||
|
||||
@@ -106,6 +106,14 @@ BF_OIIO_INC = '${BF_OIIO}/include'
|
||||
BF_OIIO_LIB_STATIC = '${BF_OIIO_LIBPATH}/libOpenImageIO.a ${BF_OPENEXR}/lib/libIlmImf.a'
|
||||
BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
|
||||
|
||||
# Color management
|
||||
WITH_BF_OCIO = True
|
||||
WITH_BF_STATICOCIO = True
|
||||
BF_OCIO = '/opt/ocio'
|
||||
BF_OCIO_INC = '${BF_OCIO}/include'
|
||||
BF_OCIO_LIB_STATIC = '${BF_OCIO_LIBPATH}/libOpenColorIO.a ${BF_OCIO_LIBPATH}/libtinyxml.a ${BF_OCIO_LIBPATH}/libyaml-cpp.a'
|
||||
BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
|
||||
|
||||
WITH_BF_BOOST = True
|
||||
WITH_BF_STATICBOOST = True
|
||||
BF_BOOST = '/opt/boost'
|
||||
|
||||
@@ -28,8 +28,8 @@ c['slavePortnum'] = 9989
|
||||
from buildbot.changes.svnpoller import SVNPoller
|
||||
|
||||
c['change_source'] = SVNPoller(
|
||||
'https://svn.blender.org/svnroot/bf-blender/trunk/',
|
||||
pollinterval=1200)
|
||||
'https://svn.blender.org/svnroot/bf-blender/trunk/',
|
||||
pollinterval=1200)
|
||||
|
||||
# BUILDERS
|
||||
#
|
||||
@@ -137,7 +137,8 @@ c['schedulers'] = []
|
||||
# builderNames=buildernames,
|
||||
# periodicBuildTimer=24*60*60))
|
||||
|
||||
c['schedulers'].append(timed.Nightly(name='nightly',
|
||||
c['schedulers'].append(timed.Nightly(
|
||||
name='nightly',
|
||||
builderNames=buildernames,
|
||||
hour=3,
|
||||
minute=0))
|
||||
|
||||
@@ -112,7 +112,7 @@ branch = get_branch(packagename)
|
||||
|
||||
if platform == '':
|
||||
sys.stderr.write('Failed to detect platform ' +
|
||||
'from package: %r\n' % packagename)
|
||||
'from package: %r\n' % packagename)
|
||||
sys.exit(1)
|
||||
|
||||
# extract
|
||||
|
||||
@@ -50,16 +50,19 @@ if builder.find('scons') != -1:
|
||||
install_dir = os.path.join('..', 'install', builder)
|
||||
|
||||
scons_options += ['WITH_BF_NOBLENDER=True', 'WITH_BF_PLAYER=False',
|
||||
'BF_BUILDDIR=' + build_dir,
|
||||
'BF_INSTALLDIR=' + install_dir,
|
||||
'WITHOUT_BF_INSTALL=True']
|
||||
'BF_BUILDDIR=' + build_dir,
|
||||
'BF_INSTALLDIR=' + install_dir,
|
||||
'WITHOUT_BF_INSTALL=True']
|
||||
|
||||
config = None
|
||||
bits = None
|
||||
|
||||
if builder.endswith('linux_x86_64_scons'):
|
||||
config = 'user-config-x86_64.py'
|
||||
bits = 64
|
||||
elif builder.endswith('linux_i386_scons'):
|
||||
config = 'user-config-x86_64.py'
|
||||
config = 'user-config-i686.py'
|
||||
bits = 32
|
||||
|
||||
if config is not None:
|
||||
config_fpath = os.path.join(config_dir, config)
|
||||
@@ -69,7 +72,16 @@ if builder.find('scons') != -1:
|
||||
blenderplayer = os.path.join(install_dir, 'blenderplayer')
|
||||
subprocess.call(['strip', '--strip-all', blender, blenderplayer])
|
||||
|
||||
extra = '/' + os.path.join('home', 'sources', 'release-builder', 'extra')
|
||||
mesalibs = os.path.join(extra, 'mesalibs' + str(bits) + '.tar.bz2')
|
||||
software_gl = os.path.join(extra, 'blender-softwaregl')
|
||||
|
||||
os.system('tar -xpf %s -C %s' % (mesalibs, install_dir))
|
||||
os.system('cp %s %s' % (software_gl, install_dir))
|
||||
os.system('chmod 755 %s' % (os.path.join(install_dir, 'blender-softwaregl')))
|
||||
|
||||
retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options)
|
||||
|
||||
sys.exit(retcode)
|
||||
else:
|
||||
if builder.find('win') != -1:
|
||||
|
||||
@@ -81,6 +81,7 @@ FOREACH(COMPONENT ${_opencollada_FIND_INCLUDES})
|
||||
# Alternative would be to suffix all members of search path
|
||||
# but this is less trouble, just looks strange.
|
||||
include/opencollada/${COMPONENT}
|
||||
include/${COMPONENT}/include
|
||||
HINTS
|
||||
${_opencollada_SEARCH_DIRS}
|
||||
)
|
||||
|
||||
85
build_files/cmake/Modules/FindOpenColorIO.cmake
Normal file
85
build_files/cmake/Modules/FindOpenColorIO.cmake
Normal file
@@ -0,0 +1,85 @@
|
||||
# - Find OpenColorIO library
|
||||
# Find the native OpenColorIO includes and library
|
||||
# This module defines
|
||||
# OPENCOLORIO_INCLUDE_DIRS, where to find OpenColorIO.h, Set when
|
||||
# OPENCOLORIO_INCLUDE_DIR is found.
|
||||
# OPENCOLORIO_LIBRARIES, libraries to link against to use OpenColorIO.
|
||||
# OPENCOLORIO_ROOT_DIR, The base directory to search for OpenColorIO.
|
||||
# This can also be an environment variable.
|
||||
# OPENCOLORIO_FOUND, If false, do not try to use OpenColorIO.
|
||||
#
|
||||
# also defined, but not for general use are
|
||||
# OPENCOLORIO_LIBRARY, where to find the OpenColorIO library.
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2012 Blender Foundation.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
|
||||
# If OPENCOLORIO_ROOT_DIR was defined in the environment, use it.
|
||||
IF(NOT OPENCOLORIO_ROOT_DIR AND NOT $ENV{OPENCOLORIO_ROOT_DIR} STREQUAL "")
|
||||
SET(OPENCOLORIO_ROOT_DIR $ENV{OPENCOLORIO_ROOT_DIR})
|
||||
ENDIF()
|
||||
|
||||
SET(_opencolorio_FIND_COMPONENTS
|
||||
OpenColorIO
|
||||
yaml-cpp
|
||||
tinyxml
|
||||
)
|
||||
|
||||
SET(_opencolorio_SEARCH_DIRS
|
||||
${OPENCOLORIO_ROOT_DIR}
|
||||
/usr/local
|
||||
/sw # Fink
|
||||
/opt/local # DarwinPorts
|
||||
/opt/csw # Blastwave
|
||||
)
|
||||
|
||||
FIND_PATH(OPENCOLORIO_INCLUDE_DIR
|
||||
NAMES
|
||||
OpenColorIO/OpenColorIO.h
|
||||
HINTS
|
||||
${_opencolorio_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
include
|
||||
)
|
||||
|
||||
SET(_opencolorio_LIBRARIES)
|
||||
FOREACH(COMPONENT ${_opencolorio_FIND_COMPONENTS})
|
||||
STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT)
|
||||
|
||||
FIND_LIBRARY(OPENCOLORIO_${UPPERCOMPONENT}_LIBRARY
|
||||
NAMES
|
||||
${COMPONENT}
|
||||
HINTS
|
||||
${_opencolorio_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
lib64 lib
|
||||
)
|
||||
if(OPENCOLORIO_${UPPERCOMPONENT}_LIBRARY)
|
||||
LIST(APPEND _opencolorio_LIBRARIES "${OPENCOLORIO_${UPPERCOMPONENT}_LIBRARY}")
|
||||
endif()
|
||||
ENDFOREACH()
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set OPENCOLORIO_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenColorIO DEFAULT_MSG
|
||||
_opencolorio_LIBRARIES OPENCOLORIO_INCLUDE_DIR)
|
||||
|
||||
IF(OPENCOLORIO_FOUND)
|
||||
SET(OPENCOLORIO_LIBRARIES ${_opencolorio_LIBRARIES})
|
||||
SET(OPENCOLORIO_INCLUDE_DIRS ${OPENCOLORIO_INCLUDE_DIR})
|
||||
ENDIF(OPENCOLORIO_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
OPENCOLORIO_INCLUDE_DIR
|
||||
OPENCOLORIO_LIBRARY
|
||||
)
|
||||
|
||||
353
build_files/cmake/clang_array_check.py
Normal file
353
build_files/cmake/clang_array_check.py
Normal file
@@ -0,0 +1,353 @@
|
||||
# ---
|
||||
# * 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
|
||||
# ---
|
||||
# by Campbell Barton
|
||||
|
||||
"""
|
||||
Invocation:
|
||||
|
||||
export CLANG_BIND_DIR="/dsk/src/llvm/tools/clang/bindings/python"
|
||||
export CLANG_LIB_DIR="/opt/llvm/lib"
|
||||
|
||||
python2 clang_array_check.py somefile.c -DSOME_DEFINE -I/some/include
|
||||
|
||||
... defines and includes are optional
|
||||
|
||||
"""
|
||||
|
||||
# delay parsing functions until we need them
|
||||
USE_LAZY_INIT = True
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# predefined function/arg sizes, handy sometimes, but not complete...
|
||||
|
||||
defs_precalc = {
|
||||
"glColor3bv": {0: 3},
|
||||
"glColor4bv": {0: 4},
|
||||
|
||||
"glColor3ubv": {0: 3},
|
||||
"glColor4ubv": {0: 4},
|
||||
|
||||
"glColor4usv": {0: 3},
|
||||
"glColor4usv": {0: 4},
|
||||
|
||||
"glColor3fv": {0: 3},
|
||||
"glColor4fv": {0: 4},
|
||||
|
||||
"glColor3dv": {0: 3},
|
||||
"glColor4dv": {0: 4},
|
||||
|
||||
"glVertex2fv": {0: 2},
|
||||
"glVertex3fv": {0: 3},
|
||||
"glVertex4fv": {0: 4},
|
||||
|
||||
"glEvalCoord1fv": {0: 1},
|
||||
"glEvalCoord1dv": {0: 1},
|
||||
"glEvalCoord2fv": {0: 2},
|
||||
"glEvalCoord2dv": {0: 2},
|
||||
|
||||
"glRasterPos2dv": {0: 2},
|
||||
"glRasterPos3dv": {0: 3},
|
||||
"glRasterPos4dv": {0: 4},
|
||||
|
||||
"glRasterPos2fv": {0: 2},
|
||||
"glRasterPos3fv": {0: 3},
|
||||
"glRasterPos4fv": {0: 4},
|
||||
|
||||
"glRasterPos2sv": {0: 2},
|
||||
"glRasterPos3sv": {0: 3},
|
||||
"glRasterPos4sv": {0: 4},
|
||||
|
||||
"glTexCoord2fv": {0: 2},
|
||||
"glTexCoord3fv": {0: 3},
|
||||
"glTexCoord4fv": {0: 4},
|
||||
|
||||
"glTexCoord2dv": {0: 2},
|
||||
"glTexCoord3dv": {0: 3},
|
||||
"glTexCoord4dv": {0: 4},
|
||||
|
||||
"glNormal3fv": {0: 3},
|
||||
"glNormal3dv": {0: 3},
|
||||
"glNormal3bv": {0: 3},
|
||||
"glNormal3iv": {0: 3},
|
||||
"glNormal3sv": {0: 3},
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
import sys
|
||||
|
||||
if 0:
|
||||
# Examples with LLVM as the root dir: '/dsk/src/llvm'
|
||||
|
||||
# path containing 'clang/__init__.py'
|
||||
CLANG_BIND_DIR = "/dsk/src/llvm/tools/clang/bindings/python"
|
||||
|
||||
# path containing libclang.so
|
||||
CLANG_LIB_DIR = "/opt/llvm/lib"
|
||||
else:
|
||||
import os
|
||||
CLANG_BIND_DIR = os.environ.get("CLANG_BIND_DIR")
|
||||
CLANG_LIB_DIR = os.environ.get("CLANG_LIB_DIR")
|
||||
|
||||
if CLANG_BIND_DIR is None:
|
||||
print("$CLANG_BIND_DIR python binding dir not set")
|
||||
if CLANG_LIB_DIR is None:
|
||||
print("$CLANG_LIB_DIR clang lib dir not set")
|
||||
|
||||
sys.path.append(CLANG_BIND_DIR)
|
||||
|
||||
import clang
|
||||
import clang.cindex
|
||||
from clang.cindex import (CursorKind,
|
||||
TypeKind,
|
||||
TokenKind)
|
||||
|
||||
clang.cindex.Config.set_library_path(CLANG_LIB_DIR)
|
||||
|
||||
index = clang.cindex.Index.create()
|
||||
|
||||
args = sys.argv[2:]
|
||||
# print(args)
|
||||
|
||||
tu = index.parse(sys.argv[1], args)
|
||||
print('Translation unit: %s' % tu.spelling)
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
def function_parm_wash_tokens(parm):
|
||||
# print(parm.kind)
|
||||
assert parm.kind in (CursorKind.PARM_DECL,
|
||||
CursorKind.VAR_DECL, # XXX, double check this
|
||||
CursorKind.FIELD_DECL,
|
||||
)
|
||||
|
||||
"""
|
||||
Return tolens without trailing commads and 'const'
|
||||
"""
|
||||
|
||||
tokens = [t for t in parm.get_tokens()]
|
||||
if not tokens:
|
||||
return tokens
|
||||
|
||||
#if tokens[-1].kind == To
|
||||
# remove trailing char
|
||||
if tokens[-1].kind == TokenKind.PUNCTUATION:
|
||||
if tokens[-1].spelling in (",", ")", ";"):
|
||||
tokens.pop()
|
||||
#else:
|
||||
# print(tokens[-1].spelling)
|
||||
|
||||
t_new = []
|
||||
for t in tokens:
|
||||
t_kind = t.kind
|
||||
t_spelling = t.spelling
|
||||
ok = True
|
||||
if t_kind == TokenKind.KEYWORD:
|
||||
if t_spelling in ("const", "restrict", "volatile"):
|
||||
ok = False
|
||||
elif t_spelling.startswith("__"):
|
||||
ok = False # __restrict
|
||||
elif t_kind in (TokenKind.COMMENT, ):
|
||||
ok = False
|
||||
|
||||
# Use these
|
||||
elif t_kind in (TokenKind.LITERAL,
|
||||
TokenKind.PUNCTUATION,
|
||||
TokenKind.IDENTIFIER):
|
||||
# use but ignore
|
||||
pass
|
||||
|
||||
else:
|
||||
print("Unknown!", t_kind, t_spelling)
|
||||
|
||||
# if its OK we will add
|
||||
if ok:
|
||||
t_new.append(t)
|
||||
return t_new
|
||||
|
||||
|
||||
def parm_size(node_child):
|
||||
tokens = function_parm_wash_tokens(node_child)
|
||||
|
||||
# print(" ".join([t.spelling for t in tokens]))
|
||||
|
||||
# NOT PERFECT CODE, EXTRACT SIZE FROM TOKENS
|
||||
if len(tokens) >= 3: # foo [ 1 ]
|
||||
if ((tokens[-3].kind == TokenKind.PUNCTUATION and tokens[-3].spelling == "[") and
|
||||
(tokens[-2].kind == TokenKind.LITERAL and tokens[-2].spelling.isdigit()) and
|
||||
(tokens[-1].kind == TokenKind.PUNCTUATION and tokens[-1].spelling == "]")):
|
||||
# ---
|
||||
return int(tokens[-2].spelling)
|
||||
return -1
|
||||
|
||||
|
||||
def function_get_arg_sizes(node):
|
||||
# Return a dict if (index: size) items
|
||||
# {arg_indx: arg_array_size, ... ]
|
||||
arg_sizes = {}
|
||||
|
||||
if 1: # node.spelling == "BM_vert_create", for debugging
|
||||
node_parms = [node_child for node_child in node.get_children()
|
||||
if node_child.kind == CursorKind.PARM_DECL]
|
||||
|
||||
for i, node_child in enumerate(node_parms):
|
||||
|
||||
# print(node_child.kind, node_child.spelling)
|
||||
#print(node_child.type.kind, node_child.spelling) # TypeKind.POINTER
|
||||
|
||||
if node_child.type.kind == TypeKind.POINTER:
|
||||
pointee = node_child.type.get_pointee()
|
||||
if pointee.is_pod():
|
||||
size = parm_size(node_child)
|
||||
if size != -1:
|
||||
arg_sizes[i] = size
|
||||
|
||||
return arg_sizes
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
_defs = {}
|
||||
|
||||
|
||||
def lookup_function_size_def(func_id):
|
||||
if USE_LAZY_INIT:
|
||||
result = _defs.get(func_id, {})
|
||||
if type(result) != dict:
|
||||
result = _defs[func_id] = function_get_arg_sizes(result)
|
||||
return result
|
||||
else:
|
||||
return _defs.get(func_id, {})
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
def file_check_arg_sizes(tu):
|
||||
|
||||
# main checking function
|
||||
def validate_arg_size(node):
|
||||
"""
|
||||
Loop over args and validate sizes for args we KNOW the size of.
|
||||
"""
|
||||
assert node.kind == CursorKind.CALL_EXPR
|
||||
|
||||
if 0:
|
||||
print("---",
|
||||
" <~> ".join(
|
||||
[" ".join([t.spelling for t in C.get_tokens()])
|
||||
for C in node.get_children()]
|
||||
))
|
||||
# print(node.location)
|
||||
|
||||
# first child is the function call, skip that.
|
||||
children = list(node.get_children())
|
||||
|
||||
if not children:
|
||||
return # XXX, look into this, happens on C++
|
||||
|
||||
func = children[0]
|
||||
|
||||
# get the func declaration!
|
||||
# works but we can better scan for functions ahead of time.
|
||||
if 0:
|
||||
func_dec = func.get_definition()
|
||||
if func_dec:
|
||||
print("FD", " ".join([t.spelling for t in func_dec.get_tokens()]))
|
||||
else:
|
||||
# HRMP'f - why does this fail?
|
||||
print("AA", " ".join([t.spelling for t in node.get_tokens()]))
|
||||
else:
|
||||
args_size_definition = () # dummy
|
||||
|
||||
# get the key
|
||||
tok = list(func.get_tokens())
|
||||
if tok:
|
||||
func_id = tok[0].spelling
|
||||
args_size_definition = lookup_function_size_def(func_id)
|
||||
|
||||
if not args_size_definition:
|
||||
return
|
||||
|
||||
children = children[1:]
|
||||
for i, node_child in enumerate(children):
|
||||
children = list(node_child.get_children())
|
||||
|
||||
# skip if we dont have an index...
|
||||
size_def = args_size_definition.get(i, -1)
|
||||
|
||||
if size_def == -1:
|
||||
continue
|
||||
|
||||
#print([c.kind for c in children])
|
||||
# print(" ".join([t.spelling for t in node_child.get_tokens()]))
|
||||
|
||||
if len(children) == 1:
|
||||
arg = children[0]
|
||||
if arg.kind in (CursorKind.DECL_REF_EXPR,
|
||||
CursorKind.UNEXPOSED_EXPR):
|
||||
|
||||
if arg.type.kind == TypeKind.POINTER:
|
||||
dec = arg.get_definition()
|
||||
if dec:
|
||||
size = parm_size(dec)
|
||||
|
||||
# size == 0 is for 'float *a'
|
||||
if size != -1 and size != 0:
|
||||
|
||||
# nice print!
|
||||
if 0:
|
||||
print("".join([t.spelling for t in func.get_tokens()]),
|
||||
i,
|
||||
" ".join([t.spelling for t in dec.get_tokens()]))
|
||||
|
||||
# testing
|
||||
# size_def = 100
|
||||
if size < size_def and size != 1:
|
||||
location = node.location
|
||||
print("%s:%d:%d: argument %d is size %d, should be %d" %
|
||||
(location.file,
|
||||
location.line,
|
||||
location.column,
|
||||
i + 1, size, size_def
|
||||
))
|
||||
|
||||
# we dont really care what we are looking at, just scan entire file for
|
||||
# function calls.
|
||||
|
||||
def recursive_func_call_check(node):
|
||||
if node.kind == CursorKind.CALL_EXPR:
|
||||
validate_arg_size(node)
|
||||
|
||||
for c in node.get_children():
|
||||
recursive_func_call_check(c)
|
||||
|
||||
recursive_func_call_check(tu.cursor)
|
||||
|
||||
|
||||
# -- first pass, cache function definitions sizes
|
||||
|
||||
# PRINT FUNC DEFINES
|
||||
def recursive_arg_sizes(node, ):
|
||||
# print(node.kind, node.spelling)
|
||||
if node.kind == CursorKind.FUNCTION_DECL:
|
||||
if USE_LAZY_INIT:
|
||||
args_sizes = node
|
||||
else:
|
||||
args_sizes = function_get_arg_sizes(node)
|
||||
#if args_sizes:
|
||||
# print(node.spelling, args_sizes)
|
||||
_defs[node.spelling] = args_sizes
|
||||
# print("adding", node.spelling)
|
||||
for c in node.get_children():
|
||||
recursive_arg_sizes(c)
|
||||
# cache function sizes
|
||||
recursive_arg_sizes(tu.cursor)
|
||||
_defs.update(defs_precalc)
|
||||
|
||||
# --- second pass, check against def's
|
||||
file_check_arg_sizes(tu)
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
"""
|
||||
Example linux usage
|
||||
python .~/blenderSVN/blender/build_files/cmake/cmake_netbeans_project.py ~/blenderSVN/cmake
|
||||
python3 ~/blenderSVN/blender/build_files/cmake/cmake_netbeans_project.py ~/blenderSVN/cmake
|
||||
|
||||
Windows not supported so far
|
||||
"""
|
||||
|
||||
@@ -105,7 +105,13 @@ def create_qtc_project_main():
|
||||
|
||||
qtc_cfg = os.path.join(PROJECT_DIR, "%s.config" % FILE_NAME)
|
||||
f = open(qtc_cfg, 'w')
|
||||
f.write("// ADD PREDEFINED MACROS HERE!\n")
|
||||
f.write("// ADD PREDEFINED MACROS TO %s_custom.config!\n" % FILE_NAME)
|
||||
qtc_custom_cfg = os.path.join(PROJECT_DIR, "%s_custom.config" % FILE_NAME)
|
||||
if os.path.exists(qtc_custom_cfg):
|
||||
fc = open(qtc_custom_cfg, 'r')
|
||||
f.write(fc.read())
|
||||
fc.close()
|
||||
f.write("\n")
|
||||
defines_final = [("#define %s %s" % (item[0], quote_define(item[1]))) for item in defines]
|
||||
if sys.platform != "win32":
|
||||
defines_final += cmake_compiler_defines()
|
||||
|
||||
77
build_files/cmake/cmake_static_check_clang_array.py
Normal file
77
build_files/cmake/cmake_static_check_clang_array.py
Normal file
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env python3.2
|
||||
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# Contributor(s): Campbell Barton
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
import project_source_info
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
|
||||
CHECKER_IGNORE_PREFIX = [
|
||||
"extern",
|
||||
"intern/moto",
|
||||
"blender/intern/opennl",
|
||||
]
|
||||
|
||||
CHECKER_BIN = "python2"
|
||||
|
||||
CHECKER_ARGS = [
|
||||
os.path.join(os.path.dirname(__file__), "clang_array_check.py"),
|
||||
# not sure why this is needed, but it is.
|
||||
"-I" + os.path.join(project_source_info.SOURCE_DIR, "extern", "glew", "include"),
|
||||
]
|
||||
|
||||
|
||||
def main():
|
||||
source_info = project_source_info.build_info(ignore_prefix_list=CHECKER_IGNORE_PREFIX)
|
||||
|
||||
check_commands = []
|
||||
for c, inc_dirs, defs in source_info:
|
||||
cmd = ([CHECKER_BIN] +
|
||||
CHECKER_ARGS +
|
||||
[c] +
|
||||
[("-I%s" % i) for i in inc_dirs] +
|
||||
[("-D%s" % d) for d in defs]
|
||||
)
|
||||
|
||||
check_commands.append((c, cmd))
|
||||
|
||||
process_functions = []
|
||||
|
||||
def my_process(i, c, cmd):
|
||||
percent = 100.0 * (i / (len(check_commands) - 1))
|
||||
percent_str = "[" + ("%.2f]" % percent).rjust(7) + " %:"
|
||||
|
||||
sys.stdout.flush()
|
||||
sys.stdout.write("%s " % percent_str)
|
||||
|
||||
return subprocess.Popen(cmd)
|
||||
|
||||
for i, (c, cmd) in enumerate(check_commands):
|
||||
process_functions.append((my_process, (i, c, cmd)))
|
||||
|
||||
project_source_info.queue_processes(process_functions)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -30,6 +30,7 @@ import os
|
||||
CHECKER_IGNORE_PREFIX = [
|
||||
"extern",
|
||||
"intern/moto",
|
||||
"blender/intern/opennl",
|
||||
]
|
||||
|
||||
CHECKER_BIN = "cppcheck"
|
||||
@@ -54,7 +55,7 @@ def main():
|
||||
[c] +
|
||||
[("-I%s" % i) for i in inc_dirs] +
|
||||
[("-D%s" % d) for d in defs]
|
||||
)
|
||||
)
|
||||
|
||||
check_commands.append((c, cmd))
|
||||
|
||||
|
||||
74
build_files/cmake/cmake_static_check_smatch.py
Normal file
74
build_files/cmake/cmake_static_check_smatch.py
Normal file
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env python3.2
|
||||
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# Contributor(s): Campbell Barton
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
CHECKER_IGNORE_PREFIX = [
|
||||
"extern",
|
||||
"intern/moto",
|
||||
"blender/intern/opennl",
|
||||
]
|
||||
|
||||
CHECKER_BIN = "smatch"
|
||||
CHECKER_ARGS = [
|
||||
"--full-path",
|
||||
"--two-passes",
|
||||
]
|
||||
|
||||
import project_source_info
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
source_info = project_source_info.build_info(use_cxx=False, ignore_prefix_list=CHECKER_IGNORE_PREFIX)
|
||||
|
||||
check_commands = []
|
||||
for c, inc_dirs, defs in source_info:
|
||||
|
||||
cmd = ([CHECKER_BIN] +
|
||||
CHECKER_ARGS +
|
||||
[c] +
|
||||
[("-I%s" % i) for i in inc_dirs] +
|
||||
[("-D%s" % d) for d in defs]
|
||||
)
|
||||
|
||||
check_commands.append((c, cmd))
|
||||
|
||||
def my_process(i, c, cmd):
|
||||
percent = 100.0 * (i / (len(check_commands) - 1))
|
||||
percent_str = "[" + ("%.2f]" % percent).rjust(7) + " %:"
|
||||
|
||||
sys.stdout.flush()
|
||||
sys.stdout.write("%s %s\n" % (percent_str, c))
|
||||
|
||||
return subprocess.Popen(cmd)
|
||||
|
||||
process_functions = []
|
||||
for i, (c, cmd) in enumerate(check_commands):
|
||||
process_functions.append((my_process, (i, c, cmd)))
|
||||
|
||||
project_source_info.queue_processes(process_functions)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -25,6 +25,7 @@
|
||||
CHECKER_IGNORE_PREFIX = [
|
||||
"extern",
|
||||
"intern/moto",
|
||||
"blender/intern/opennl",
|
||||
]
|
||||
|
||||
CHECKER_BIN = "sparse"
|
||||
@@ -47,7 +48,7 @@ def main():
|
||||
[c] +
|
||||
[("-I%s" % i) for i in inc_dirs] +
|
||||
[("-D%s" % d) for d in defs]
|
||||
)
|
||||
)
|
||||
|
||||
check_commands.append((c, cmd))
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
CHECKER_IGNORE_PREFIX = [
|
||||
"extern",
|
||||
"intern/moto",
|
||||
"blender/intern/opennl",
|
||||
]
|
||||
|
||||
CHECKER_BIN = "splint"
|
||||
@@ -79,7 +80,7 @@ def main():
|
||||
[c] +
|
||||
[("-I%s" % i) for i in inc_dirs] +
|
||||
[("-D%s" % d) for d in defs]
|
||||
)
|
||||
)
|
||||
|
||||
check_commands.append((c, cmd))
|
||||
|
||||
|
||||
@@ -10,14 +10,16 @@ set(WITH_SYSTEM_GLEW ON CACHE FORCE BOOL)
|
||||
|
||||
set(WITH_BUILDINFO OFF CACHE FORCE BOOL)
|
||||
set(WITH_BULLET OFF CACHE FORCE BOOL)
|
||||
set(WITH_CODEC_AVI OFF CACHE FORCE BOOL)
|
||||
set(WITH_CODEC_FFMPEG OFF CACHE FORCE BOOL)
|
||||
set(WITH_CODEC_SNDFILE OFF CACHE FORCE BOOL)
|
||||
set(WITH_CYCLES OFF CACHE FORCE BOOL)
|
||||
set(WITH_FFTW3 OFF CACHE FORCE BOOL)
|
||||
set(WITH_LIBMV OFF CACHE FORCE BOOL)
|
||||
set(WITH_CARVE OFF CACHE FORCE BOOL)
|
||||
set(WITH_GAMEENGINE OFF CACHE FORCE BOOL)
|
||||
set(WITH_COMPOSITOR OFF CACHE FORCE BOOL)
|
||||
set(WITH_GHOST_XDND OFF CACHE FORCE BOOL)
|
||||
set(WITH_IK_SOLVER OFF CACHE FORCE BOOL)
|
||||
set(WITH_IK_ITASC OFF CACHE FORCE BOOL)
|
||||
set(WITH_IMAGE_CINEON OFF CACHE FORCE BOOL)
|
||||
set(WITH_IMAGE_DDS OFF CACHE FORCE BOOL)
|
||||
@@ -41,6 +43,7 @@ set(WITH_MOD_OCEANSIM OFF CACHE FORCE BOOL)
|
||||
set(WITH_AUDASPACE OFF CACHE FORCE BOOL)
|
||||
set(WITH_OPENAL OFF CACHE FORCE BOOL)
|
||||
set(WITH_OPENCOLLADA OFF CACHE FORCE BOOL)
|
||||
set(WITH_OPENCOLORIO OFF CACHE FORCE BOOL)
|
||||
set(WITH_OPENMP OFF CACHE FORCE BOOL)
|
||||
set(WITH_PYTHON_INSTALL OFF CACHE FORCE BOOL)
|
||||
set(WITH_RAYOPTIMIZATION OFF CACHE FORCE BOOL)
|
||||
|
||||
@@ -23,6 +23,31 @@
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
macro(list_insert_after
|
||||
list_id item_check item_add
|
||||
)
|
||||
set(_index)
|
||||
list(FIND "${list_id}" "${item_check}" _index)
|
||||
if("${_index}" MATCHES "-1")
|
||||
message(FATAL_ERROR "'${list_id}' doesn't contain '${item_check}'")
|
||||
endif()
|
||||
math(EXPR _index "${_index} + 1")
|
||||
list(INSERT ${list_id} "${_index}" ${item_add})
|
||||
unset(_index)
|
||||
endmacro()
|
||||
|
||||
macro(list_insert_before
|
||||
list_id item_check item_add
|
||||
)
|
||||
set(_index)
|
||||
list(FIND "${list_id}" "${item_check}" _index)
|
||||
if("${_index}" MATCHES "-1")
|
||||
message(FATAL_ERROR "'${list_id}' doesn't contain '${item_check}'")
|
||||
endif()
|
||||
list(INSERT ${list_id} "${_index}" ${item_add})
|
||||
unset(_index)
|
||||
endmacro()
|
||||
|
||||
# foo_bar.spam --> foo_barMySuffix.spam
|
||||
macro(file_suffix
|
||||
file_name_new file_name file_suffix
|
||||
@@ -193,6 +218,9 @@ macro(SETUP_LIBDIRS)
|
||||
if(WITH_OPENIMAGEIO)
|
||||
link_directories(${OPENIMAGEIO_LIBPATH})
|
||||
endif()
|
||||
if(WITH_OPENCOLORIO)
|
||||
link_directories(${OPENCOLORIO_LIBPATH})
|
||||
endif()
|
||||
if(WITH_IMAGE_OPENJPEG AND WITH_SYSTEM_OPENJPEG)
|
||||
link_directories(${OPENJPEG_LIBPATH})
|
||||
endif()
|
||||
@@ -216,6 +244,9 @@ macro(SETUP_LIBDIRS)
|
||||
link_directories(${PCRE_LIBPATH})
|
||||
link_directories(${EXPAT_LIBPATH})
|
||||
endif()
|
||||
if(WITH_LLVM)
|
||||
link_directories(${LLVM_LIB_DIR})
|
||||
endif()
|
||||
if(WITH_MEM_JEMALLOC)
|
||||
link_directories(${JEMALLOC_LIBPATH})
|
||||
endif()
|
||||
@@ -288,6 +319,9 @@ macro(setup_liblinks
|
||||
if(WITH_OPENIMAGEIO)
|
||||
target_link_libraries(${target} ${OPENIMAGEIO_LIBRARIES})
|
||||
endif()
|
||||
if(WITH_OPENCOLORIO)
|
||||
target_link_libraries(${target} ${OPENCOLORIO_LIBRARIES})
|
||||
endif()
|
||||
if(WITH_BOOST)
|
||||
target_link_libraries(${target} ${BOOST_LIBRARIES})
|
||||
endif()
|
||||
@@ -348,6 +382,12 @@ macro(setup_liblinks
|
||||
if(WITH_MOD_CLOTH_ELTOPO)
|
||||
target_link_libraries(${target} ${LAPACK_LIBRARIES})
|
||||
endif()
|
||||
if(WITH_CYCLES_OSL)
|
||||
target_link_libraries(${target} ${OSL_LIBRARIES})
|
||||
endif()
|
||||
if(WITH_LLVM)
|
||||
target_link_libraries(${target} ${LLVM_LIBRARY})
|
||||
endif()
|
||||
if(WIN32 AND NOT UNIX)
|
||||
target_link_libraries(${target} ${PTHREADS_LIBRARIES})
|
||||
endif()
|
||||
@@ -442,6 +482,7 @@ macro(remove_strict_flags)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
remove_cc_flag("-Wstrict-prototypes")
|
||||
remove_cc_flag("-Wmissing-prototypes")
|
||||
remove_cc_flag("-Wunused-parameter")
|
||||
remove_cc_flag("-Wwrite-strings")
|
||||
remove_cc_flag("-Wundef")
|
||||
@@ -619,7 +660,7 @@ macro(blender_project_hack_post)
|
||||
# --------------
|
||||
# MINGW HACK END
|
||||
if (_reset_standard_libraries)
|
||||
# Must come after project(...)
|
||||
# Must come after projecINCt(...)
|
||||
#
|
||||
# MINGW workaround for -ladvapi32 being included which surprisingly causes
|
||||
# string formatting of floats, eg: printf("%.*f", 3, value). to crash blender
|
||||
@@ -700,12 +741,51 @@ macro(set_lib_path
|
||||
lvar
|
||||
lproj)
|
||||
|
||||
|
||||
if(MSVC10 AND EXISTS ${LIBDIR}/vc2010/${lproj})
|
||||
set(${lvar} ${LIBDIR}/vc2010/${lproj})
|
||||
if(MSVC10)
|
||||
set(${lvar} ${LIBDIR}/${lproj}/vc2010)
|
||||
else()
|
||||
set(${lvar} ${LIBDIR}/${lproj})
|
||||
endif()
|
||||
|
||||
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(data_to_c
|
||||
file_from file_to
|
||||
list_to_add)
|
||||
|
||||
list(APPEND ${list_to_add} ${file_to})
|
||||
|
||||
get_filename_component(_file_to_path ${file_to} PATH)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${file_to}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${_file_to_path}
|
||||
COMMAND ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/datatoc ${file_from} ${file_to}
|
||||
DEPENDS ${file_from} datatoc)
|
||||
unset(_file_to_path)
|
||||
endmacro()
|
||||
|
||||
|
||||
# same as above but generates the var name and output automatic.
|
||||
macro(data_to_c_simple
|
||||
file_from
|
||||
list_to_add)
|
||||
|
||||
# remove ../'s
|
||||
get_filename_component(_file_from ${CMAKE_CURRENT_SOURCE_DIR}/${file_from} REALPATH)
|
||||
get_filename_component(_file_to ${CMAKE_CURRENT_BINARY_DIR}/${file_from}.c REALPATH)
|
||||
|
||||
list(APPEND ${list_to_add} ${_file_to})
|
||||
|
||||
get_filename_component(_file_to_path ${_file_to} PATH)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${_file_to}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${_file_to_path}
|
||||
COMMAND ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/datatoc ${_file_from} ${_file_to}
|
||||
DEPENDS ${_file_from} datatoc)
|
||||
|
||||
unset(_file_from)
|
||||
unset(_file_to)
|
||||
unset(_file_to_path)
|
||||
endmacro()
|
||||
|
||||
@@ -85,7 +85,7 @@ def makefile_log():
|
||||
print("running make with --dry-run ...")
|
||||
process = subprocess.Popen(["make", "--always-make", "--dry-run", "--keep-going", "VERBOSE=1"],
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
)
|
||||
|
||||
while process.poll():
|
||||
time.sleep(1)
|
||||
|
||||
@@ -76,6 +76,7 @@ fi || :
|
||||
%defattr(-,root,root,-)
|
||||
%{_bindir}/%{name}
|
||||
%{_datadir}/%{name}/%{blender_api}/datafiles/fonts
|
||||
%{_datadir}/%{name}/%{blender_api}/datafiles/colormanagement
|
||||
%{_datadir}/%{name}/%{blender_api}/scripts
|
||||
%{_datadir}/icons/hicolor/*/apps/%{name}.*
|
||||
%{_datadir}/applications/%{name}.desktop
|
||||
|
||||
@@ -32,6 +32,8 @@ elif cmd_res[:2]=='10':
|
||||
MAC_CUR_VER='10.6'
|
||||
elif cmd_res[:2]=='11':
|
||||
MAC_CUR_VER='10.7'
|
||||
elif cmd_res[:2]=='12':
|
||||
MAC_CUR_VER='10.8'
|
||||
cmd = 'xcodebuild -version'
|
||||
cmd_xcode=commands.getoutput(cmd)
|
||||
XCODE_CUR_VER=cmd_xcode[6:][:3] # truncate output to major.minor version
|
||||
@@ -75,7 +77,7 @@ else :
|
||||
LCGDIR = '#../lib/darwin-9.x.universal'
|
||||
CC = 'gcc-4.2'
|
||||
CXX = 'g++-4.2'
|
||||
else:
|
||||
elif 'Mac OS X 10.6' in MACOSX_SDK_CHECK:
|
||||
# OSX 10.6/7 with Xcode 4.x
|
||||
MAC_MIN_VERS = '10.6'
|
||||
MACOSX_DEPLOYMENT_TARGET = '10.6'
|
||||
@@ -83,6 +85,14 @@ else :
|
||||
LCGDIR = '#../lib/darwin-9.x.universal'
|
||||
CC = 'gcc-4.2'
|
||||
CXX = 'g++-4.2'
|
||||
else:
|
||||
# OSX 10.8 with Xcode 4.4 and higher (no 10.6sdk! )
|
||||
MAC_MIN_VERS = '10.6'
|
||||
MACOSX_DEPLOYMENT_TARGET = '10.6'
|
||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.7.sdk'
|
||||
LCGDIR = '#../lib/darwin-9.x.universal'
|
||||
CC = 'gcc'
|
||||
CXX = 'g++'
|
||||
|
||||
LIBDIR = '${LCGDIR}'
|
||||
|
||||
@@ -277,6 +287,12 @@ BF_OIIO_INC = BF_OIIO + '/include'
|
||||
BF_OIIO_LIB = 'OpenImageIO'
|
||||
BF_OIIO_LIBPATH = BF_OIIO + '/lib'
|
||||
|
||||
WITH_BF_OCIO = True
|
||||
BF_OCIO = LIBDIR + '/opencolorio'
|
||||
BF_OCIO_INC = BF_OCIO + '/include'
|
||||
BF_OCIO_LIB = 'OpenColorIO tinyxml yaml-cpp'
|
||||
BF_OCIO_LIBPATH = BF_OCIO + '/lib'
|
||||
|
||||
WITH_BF_BOOST = True
|
||||
BF_BOOST = LIBDIR + '/boost'
|
||||
BF_BOOST_INC = BF_BOOST + '/include'
|
||||
@@ -333,8 +349,8 @@ if not WITH_OSX_STATICPYTHON:
|
||||
|
||||
|
||||
#note to build succesfully on 10.3.9 SDK you need to patch 10.3.9 by adding the SystemStubs.a lib from 10.4
|
||||
#for 10.7.sdk, SystemStubs needs to be excluded (lib doesn't exist anymore)
|
||||
if MACOSX_DEPLOYMENT_TARGET == '10.7':
|
||||
#for > 10.7.sdk, SystemStubs needs to be excluded (lib doesn't exist anymore)
|
||||
if MACOSX_SDK.endswith("10.7.sdk") or MACOSX_SDK.endswith("10.8.sdk"):
|
||||
LLIBS = ['stdc++']
|
||||
else:
|
||||
LLIBS = ['stdc++', 'SystemStubs']
|
||||
|
||||
@@ -105,6 +105,11 @@ BF_BULLET = '#extern/bullet2/src'
|
||||
BF_BULLET_INC = '${BF_BULLET}'
|
||||
BF_BULLET_LIB = 'extern_bullet'
|
||||
|
||||
WITH_BF_ELTOPO = False
|
||||
BF_LAPACK = '/usr'
|
||||
BF_LAPACK_LIB = 'lapack3gf blas clapack'
|
||||
BF_LAPACK_LIBPATH = '${BF_LAPACK}/lib'
|
||||
|
||||
BF_FREETYPE = '/usr'
|
||||
BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
|
||||
BF_FREETYPE_LIB = 'freetype'
|
||||
@@ -210,6 +215,16 @@ BF_OIIO_INC = BF_OIIO + '/include'
|
||||
BF_OIIO_LIB = 'OpenImageIO'
|
||||
BF_OIIO_LIBPATH = BF_OIIO + '/lib'
|
||||
|
||||
WITH_BF_OCIO = True
|
||||
WITH_BF_STATICOCIO = False
|
||||
BF_OCIO = LIBDIR + '/ocio'
|
||||
if not os.path.exists(LCGDIR + '/ocio'):
|
||||
WITH_BF_OCIO = False
|
||||
BF_OCIO = '/usr'
|
||||
BF_OCIO_INC = BF_OCIO + '/include'
|
||||
BF_OCIO_LIB = 'OpenColorIO yaml-cpp tinyxml'
|
||||
BF_OCIO_LIBPATH = BF_OCIO + '/lib'
|
||||
|
||||
WITH_BF_BOOST = True
|
||||
WITH_BF_STATICBOOST = False
|
||||
BF_BOOST = LIBDIR + '/boost'
|
||||
@@ -224,7 +239,7 @@ WITH_BF_CYCLES = WITH_BF_OIIO and WITH_BF_BOOST
|
||||
|
||||
WITH_BF_CYCLES_CUDA_BINARIES = False
|
||||
BF_CYCLES_CUDA_NVCC = '/usr/local/cuda/bin/nvcc'
|
||||
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21']
|
||||
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
|
||||
|
||||
WITH_BF_OPENMP = True
|
||||
|
||||
|
||||
@@ -159,10 +159,16 @@ BF_OIIO_INC = BF_OIIO + '/include'
|
||||
BF_OIIO_LIB = 'OpenImageIO'
|
||||
BF_OIIO_LIBPATH = BF_OIIO + '/lib'
|
||||
|
||||
WITH_BF_OCIO = True
|
||||
BF_OCIO = LIBDIR + '/opencolorio'
|
||||
BF_OCIO_INC = BF_OCIO + '/include'
|
||||
BF_OCIO_LIB = 'OpenColorIO'
|
||||
BF_OCIO_LIBPATH = BF_OCIO + '/lib'
|
||||
|
||||
WITH_BF_BOOST = True
|
||||
BF_BOOST = LIBDIR + '/boost'
|
||||
BF_BOOST_INC = BF_BOOST + '/include'
|
||||
BF_BOOST_LIB = 'boost_date_time-mgw46-mt-s-1_47 boost_filesystem-mgw46-mt-s-1_47 boost_regex-mgw46-mt-s-1_47 boost_system-mgw46-mt-s-1_47 boost_thread-mgw46-mt-s-1_47'
|
||||
BF_BOOST_LIB = 'boost_date_time-mgw46-mt-s-1_49 boost_filesystem-mgw46-mt-s-1_49 boost_regex-mgw46-mt-s-1_49 boost_system-mgw46-mt-s-1_49 boost_thread-mgw46-mt-s-1_49'
|
||||
BF_BOOST_LIBPATH = BF_BOOST + '/lib'
|
||||
|
||||
#Ray trace optimization
|
||||
@@ -172,7 +178,7 @@ BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse']
|
||||
#CUDA
|
||||
WITH_BF_CYCLES_CUDA_BINARIES = False
|
||||
#BF_CYCLES_CUDA_NVCC = "" # Path to the nvidia compiler
|
||||
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21'] # don't build sm_13 until the compile can fit in 32bit process again :)
|
||||
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
|
||||
|
||||
##
|
||||
CC = 'gcc'
|
||||
@@ -195,7 +201,7 @@ LLIBS = ['-lshell32', '-lshfolder', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32
|
||||
PLATFORM_LINKFLAGS = ['-Xlinker', '--stack=2097152']
|
||||
|
||||
## DISABLED, causes linking errors!
|
||||
## for re-distrobution, so users dont need mingw installed
|
||||
## for re-distribution, so users dont need mingw installed
|
||||
# PLATFORM_LINKFLAGS += ["-static-libgcc", "-static-libstdc++"]
|
||||
|
||||
BF_DEBUG = False
|
||||
|
||||
@@ -101,6 +101,11 @@ BF_BULLET = '#extern/bullet2/src'
|
||||
BF_BULLET_INC = '${BF_BULLET}'
|
||||
BF_BULLET_LIB = 'extern_bullet'
|
||||
|
||||
WITH_BF_ELTOPO = False
|
||||
BF_LAPACK = LIBDIR + '/lapack'
|
||||
BF_LAPACK_LIB = 'libf2c clapack_nowrap BLAS_nowrap'
|
||||
BF_LAPACK_LIBPATH = '${BF_LAPACK}/lib'
|
||||
|
||||
BF_WINTAB = LIBDIR + '/wintab'
|
||||
BF_WINTAB_INC = '${BF_WINTAB}/INCLUDE'
|
||||
|
||||
@@ -156,6 +161,12 @@ BF_OIIO_INC = '${BF_OIIO}/include'
|
||||
BF_OIIO_LIB = 'OpenImageIO'
|
||||
BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
|
||||
|
||||
WITH_BF_OCIO = True
|
||||
BF_OCIO = '${LIBDIR}/opencolorio'
|
||||
BF_OCIO_INC = '${BF_OCIO}/include'
|
||||
BF_OCIO_LIB = 'OpenColorIO'
|
||||
BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
|
||||
|
||||
WITH_BF_BOOST = True
|
||||
BF_BOOST = '${LIBDIR}/boost'
|
||||
BF_BOOST_INC = '${BF_BOOST}/include'
|
||||
|
||||
@@ -151,7 +151,7 @@ BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
|
||||
WITH_BF_CYCLES = True
|
||||
WITH_BF_CYCLES_CUDA_BINARIES = False
|
||||
BF_CYCLES_CUDA_NVCC = "" # Path to the NVIDIA CUDA compiler
|
||||
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21']
|
||||
BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_13', 'sm_20', 'sm_21', 'sm_30']
|
||||
|
||||
WITH_BF_OIIO = True
|
||||
BF_OIIO = LIBDIR + '/openimageio'
|
||||
@@ -159,6 +159,12 @@ BF_OIIO_INC = '${BF_OIIO}/include'
|
||||
BF_OIIO_LIB = 'OpenImageIO'
|
||||
BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
|
||||
|
||||
WITH_BF_OCIO = True
|
||||
BF_OCIO = LIBDIR + '/opencolorio'
|
||||
BF_OCIO_INC = '${BF_OCIO}/include'
|
||||
BF_OCIO_LIB = 'OpenColorIO'
|
||||
BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
|
||||
|
||||
WITH_BF_BOOST = True
|
||||
BF_BOOST = LIBDIR + '/boost'
|
||||
BF_BOOST_INC = BF_BOOST + '/include'
|
||||
@@ -169,7 +175,7 @@ BF_BOOST_LIBPATH = BF_BOOST + '/lib'
|
||||
WITH_BF_RAYOPTIMIZATION = True
|
||||
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-mmmx', '-msse', '-msse2']
|
||||
|
||||
#Produces errors while rendering with subsurf/multires,
|
||||
#May produce errors with unsupported MinGW-w64 builds
|
||||
WITH_BF_OPENMP = False
|
||||
|
||||
##
|
||||
@@ -193,7 +199,7 @@ LLIBS = ['-lshell32', '-lshfolder', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32
|
||||
PLATFORM_LINKFLAGS = ['-Xlinker', '--stack=2097152']
|
||||
|
||||
## DISABLED, causes linking errors!
|
||||
## for re-distrobution, so users dont need mingw installed
|
||||
## for re-distribution, so users dont need mingw installed
|
||||
# PLATFORM_LINKFLAGS += ["-static-libgcc", "-static-libstdc++"]
|
||||
|
||||
BF_DEBUG = False
|
||||
|
||||
@@ -97,6 +97,11 @@ BF_BULLET = '#extern/bullet2/src'
|
||||
BF_BULLET_INC = '${BF_BULLET}'
|
||||
BF_BULLET_LIB = 'extern_bullet'
|
||||
|
||||
WITH_BF_ELTOPO = False
|
||||
BF_LAPACK = LIBDIR + '/lapack'
|
||||
BF_LAPACK_LIB = 'libf2c clapack_nowrap BLAS_nowrap'
|
||||
BF_LAPACK_LIBPATH = '${BF_LAPACK}/lib'
|
||||
|
||||
BF_WINTAB = LIBDIR + '/wintab'
|
||||
BF_WINTAB_INC = '${BF_WINTAB}/INCLUDE'
|
||||
|
||||
@@ -153,6 +158,13 @@ BF_OIIO_LIB = 'OpenImageIO'
|
||||
BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
|
||||
BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
|
||||
|
||||
WITH_BF_OCIO = True
|
||||
BF_OCIO = '${LIBDIR}/opencolorio'
|
||||
BF_OCIO_INC = '${BF_OCIO}/include'
|
||||
BF_OCIO_LIB = 'OpenColorIO'
|
||||
BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
|
||||
BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
|
||||
|
||||
WITH_BF_BOOST = True
|
||||
BF_BOOST = '${LIBDIR}/boost'
|
||||
BF_BOOST_INC = '${BF_BOOST}/include'
|
||||
|
||||
@@ -159,6 +159,10 @@ def setup_staticlibs(lenv):
|
||||
libincs += Split(lenv['BF_FFTW3_LIBPATH'])
|
||||
if lenv['WITH_BF_STATICFFTW3']:
|
||||
statlibs += Split(lenv['BF_FFTW3_LIB_STATIC'])
|
||||
if lenv['WITH_BF_ELTOPO']:
|
||||
libincs += Split(lenv['BF_LAPACK_LIBPATH'])
|
||||
if lenv['WITH_BF_STATICLAPACK']:
|
||||
statlibs += Split(lenv['BF_LAPACK_LIB_STATIC'])
|
||||
if lenv['WITH_BF_FFMPEG'] and lenv['WITH_BF_STATICFFMPEG']:
|
||||
statlibs += Split(lenv['BF_FFMPEG_LIB_STATIC'])
|
||||
if lenv['WITH_BF_INTERNATIONAL']:
|
||||
@@ -200,6 +204,11 @@ def setup_staticlibs(lenv):
|
||||
if lenv['WITH_BF_STATICOIIO']:
|
||||
statlibs += Split(lenv['BF_OIIO_LIB_STATIC'])
|
||||
|
||||
if lenv['WITH_BF_OCIO']:
|
||||
libincs += Split(lenv['BF_OCIO_LIBPATH'])
|
||||
if lenv['WITH_BF_STATICOCIO']:
|
||||
statlibs += Split(lenv['BF_OCIO_LIB_STATIC'])
|
||||
|
||||
if lenv['WITH_BF_BOOST']:
|
||||
libincs += Split(lenv['BF_BOOST_LIBPATH'])
|
||||
if lenv['WITH_BF_STATICBOOST']:
|
||||
@@ -248,6 +257,10 @@ def setup_syslibs(lenv):
|
||||
if not lenv['WITH_BF_STATICOIIO']:
|
||||
syslibs += Split(lenv['BF_OIIO_LIB'])
|
||||
|
||||
if lenv['WITH_BF_OCIO']:
|
||||
if not lenv['WITH_BF_STATICOCIO']:
|
||||
syslibs += Split(lenv['BF_OCIO_LIB'])
|
||||
|
||||
if lenv['WITH_BF_OPENEXR'] and not lenv['WITH_BF_STATICOPENEXR']:
|
||||
syslibs += Split(lenv['BF_OPENEXR_LIB'])
|
||||
if lenv['WITH_BF_TIFF'] and not lenv['WITH_BF_STATICTIFF']:
|
||||
@@ -264,6 +277,8 @@ def setup_syslibs(lenv):
|
||||
syslibs += Split(lenv['BF_SNDFILE_LIB'])
|
||||
if lenv['WITH_BF_FFTW3'] and not lenv['WITH_BF_STATICFFTW3']:
|
||||
syslibs += Split(lenv['BF_FFTW3_LIB'])
|
||||
if lenv['WITH_BF_ELTOPO']:
|
||||
syslibs += Split(lenv['BF_LAPACK_LIB'])
|
||||
if lenv['WITH_BF_SDL']:
|
||||
syslibs += Split(lenv['BF_SDL_LIB'])
|
||||
if not lenv['WITH_BF_STATICOPENGL']:
|
||||
@@ -578,6 +593,9 @@ def AppIt(target=None, source=None, env=None):
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'cp -R %s/release/datafiles/fonts %s/%s.app/Contents/MacOS/%s/datafiles/'%(bldroot,installdir,binary,VERSION)
|
||||
commands.getoutput(cmd)
|
||||
if env['WITH_BF_OCIO']:
|
||||
cmd = 'cp -R %s/release/datafiles/colormanagement %s/%s.app/Contents/MacOS/%s/datafiles/'%(bldroot,installdir,binary,VERSION)
|
||||
commands.getoutput(cmd)
|
||||
cmd = 'cp -R %s/release/scripts %s/%s.app/Contents/MacOS/%s/'%(bldroot,installdir,binary,VERSION)
|
||||
commands.getoutput(cmd)
|
||||
|
||||
@@ -693,11 +711,23 @@ def UnixPyBundle(target=None, source=None, env=None):
|
||||
run("rm -r '%s/turtle.py'" % py_target)
|
||||
run("rm -f '%s/lib-dynload/_tkinter.so'" % py_target)
|
||||
|
||||
if env['WITH_BF_PYTHON_INSTALL_NUMPY']:
|
||||
numpy_src = py_src + "/site-packages/numpy"
|
||||
numpy_target = py_target + "/site-packages/numpy"
|
||||
|
||||
if os.path.exists(numpy_src):
|
||||
print 'Install numpy from:'
|
||||
print '\t"%s" into...' % numpy_src
|
||||
print '\t"%s"\n' % numpy_target
|
||||
|
||||
run("cp -R '%s' '%s'" % (numpy_src, os.path.dirname(numpy_target)))
|
||||
else:
|
||||
print 'Failed to find numpy at %s, skipping copying' % numpy_src
|
||||
|
||||
run("find '%s' -type d -name 'test' -prune -exec rm -rf {} ';'" % py_target)
|
||||
run("find '%s' -type d -name '__pycache__' -exec rm -rf {} ';'" % py_target)
|
||||
run("find '%s' -name '*.py[co]' -exec rm -rf {} ';'" % py_target)
|
||||
run("find '%s' -name '*.so' -exec strip -s {} ';'" % py_target)
|
||||
|
||||
|
||||
#### END ACTION STUFF #########
|
||||
|
||||
@@ -827,6 +857,8 @@ class BlenderEnvironment(SConsEnvironment):
|
||||
print bc.HEADER+'Configuring program '+bc.ENDC+bc.OKGREEN+progname+bc.ENDC
|
||||
lenv = self.Clone()
|
||||
lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
|
||||
if lenv['OURPLATFORM'] in ('win32-mingw', 'win64-mingw', 'linuxcross', 'cygwin', 'linux'):
|
||||
lenv.Replace(LINK = '$CXX')
|
||||
if lenv['OURPLATFORM'] in ('win32-vc', 'cygwin', 'win64-vc'):
|
||||
if lenv['BF_DEBUG']:
|
||||
lenv.Prepend(LINKFLAGS = ['/DEBUG','/PDB:'+progname+'.pdb','/NODEFAULTLIB:libcmt'])
|
||||
|
||||
@@ -108,7 +108,7 @@ def validate_arguments(args, bc):
|
||||
'WITH_BF_STATICFFMPEG', 'BF_FFMPEG_LIB_STATIC',
|
||||
'WITH_BF_OGG', 'BF_OGG', 'BF_OGG_LIB',
|
||||
'WITH_BF_FRAMESERVER',
|
||||
'WITH_BF_COMPOSITOR',
|
||||
'WITH_BF_COMPOSITOR', 'WITH_BF_COMPOSITOR_LEGACY',
|
||||
'WITH_BF_JPEG', 'BF_JPEG', 'BF_JPEG_INC', 'BF_JPEG_LIB', 'BF_JPEG_LIBPATH',
|
||||
'WITH_BF_OPENJPEG', 'BF_OPENJPEG', 'BF_OPENJPEG_INC', 'BF_OPENJPEG_LIB', 'BF_OPENJPEG_LIBPATH',
|
||||
'WITH_BF_REDCODE', 'BF_REDCODE', 'BF_REDCODE_INC', 'BF_REDCODE_LIB', 'BF_REDCODE_LIBPATH',
|
||||
@@ -120,7 +120,7 @@ def validate_arguments(args, bc):
|
||||
'WITH_BF_ICONV', 'BF_ICONV', 'BF_ICONV_INC', 'BF_ICONV_LIB', 'BF_ICONV_LIBPATH',
|
||||
'WITH_BF_GAMEENGINE',
|
||||
'WITH_BF_BULLET', 'BF_BULLET', 'BF_BULLET_INC', 'BF_BULLET_LIB',
|
||||
'WITH_BF_ELTOPO',
|
||||
'WITH_BF_ELTOPO', 'BF_LAPACK', 'BF_LAPACK_LIB', 'BF_LAPACK_LIBPATH', 'BF_LAPACK_LIB_STATIC',
|
||||
'BF_WINTAB', 'BF_WINTAB_INC',
|
||||
'BF_FREETYPE', 'BF_FREETYPE_INC', 'BF_FREETYPE_LIB', 'BF_FREETYPE_LIBPATH', 'BF_FREETYPE_LIB_STATIC', 'WITH_BF_FREETYPE_STATIC',
|
||||
'WITH_BF_QUICKTIME', 'BF_QUICKTIME', 'BF_QUICKTIME_INC', 'BF_QUICKTIME_LIB', 'BF_QUICKTIME_LIBPATH',
|
||||
@@ -135,7 +135,7 @@ def validate_arguments(args, bc):
|
||||
'BF_CXX', 'WITH_BF_STATICCXX', 'BF_CXX_LIB_STATIC',
|
||||
'BF_TWEAK_MODE', 'BF_SPLIT_SRC',
|
||||
'WITHOUT_BF_INSTALL',
|
||||
'WITHOUT_BF_PYTHON_INSTALL', 'WITHOUT_BF_PYTHON_UNPACK',
|
||||
'WITHOUT_BF_PYTHON_INSTALL', 'WITHOUT_BF_PYTHON_UNPACK', 'WITH_BF_PYTHON_INSTALL_NUMPY'
|
||||
'WITHOUT_BF_OVERWRITE_INSTALL',
|
||||
'WITH_BF_OPENMP', 'BF_OPENMP', 'BF_OPENMP_LIBPATH',
|
||||
'WITH_GHOST_COCOA',
|
||||
@@ -163,8 +163,9 @@ def validate_arguments(args, bc):
|
||||
'WITH_BF_3DMOUSE', 'WITH_BF_STATIC3DMOUSE', 'BF_3DMOUSE', 'BF_3DMOUSE_INC', 'BF_3DMOUSE_LIB', 'BF_3DMOUSE_LIBPATH', 'BF_3DMOUSE_LIB_STATIC',
|
||||
'WITH_BF_CYCLES', 'WITH_BF_CYCLES_CUDA_BINARIES', 'BF_CYCLES_CUDA_NVCC', 'BF_CYCLES_CUDA_NVCC', 'WITH_BF_CYCLES_CUDA_THREADED_COMPILE',
|
||||
'WITH_BF_OIIO', 'WITH_BF_STATICOIIO', 'BF_OIIO', 'BF_OIIO_INC', 'BF_OIIO_LIB', 'BF_OIIO_LIB_STATIC', 'BF_OIIO_LIBPATH',
|
||||
'WITH_BF_OCIO', 'WITH_BF_STATICOCIO', 'BF_OCIO', 'BF_OCIO_INC', 'BF_OCIO_LIB', 'BF_OCIO_LIB_STATIC', 'BF_OCIO_LIBPATH',
|
||||
'WITH_BF_BOOST', 'WITH_BF_STATICBOOST', 'BF_BOOST', 'BF_BOOST_INC', 'BF_BOOST_LIB', 'BF_BOOST_LIB_STATIC', 'BF_BOOST_LIBPATH',
|
||||
'WITH_BF_LIBMV', 'WITH_BF_CARVE'
|
||||
'WITH_BF_LIBMV'
|
||||
]
|
||||
|
||||
# Have options here that scons expects to be lists
|
||||
@@ -393,7 +394,13 @@ def read_opts(env, cfg, args):
|
||||
(BoolVariable('WITH_BF_GAMEENGINE', 'Build with gameengine' , False)),
|
||||
|
||||
(BoolVariable('WITH_BF_BULLET', 'Use Bullet if true', True)),
|
||||
|
||||
(BoolVariable('WITH_BF_ELTOPO', 'Use Eltopo collision library if true', False)),
|
||||
('BF_LAPACK', 'LAPACK base path', ''),
|
||||
('BF_LAPACK_LIB', 'LAPACK library', ''),
|
||||
('BF_LAPACK_LIB_STATIC', 'LAPACK library', ''),
|
||||
('BF_LAPACK_LIBPATH', 'LAPACK library path', ''),
|
||||
(BoolVariable('WITH_BF_STATICLAPACK', 'Staticly link to LAPACK', False)),
|
||||
|
||||
('BF_BULLET', 'Bullet base dir', ''),
|
||||
('BF_BULLET_INC', 'Bullet include path', ''),
|
||||
@@ -520,6 +527,7 @@ def read_opts(env, cfg, args):
|
||||
(BoolVariable('BF_SPLIT_SRC', 'Split src lib into several chunks if true', False)),
|
||||
(BoolVariable('WITHOUT_BF_INSTALL', 'dont install if true', False)),
|
||||
(BoolVariable('WITHOUT_BF_PYTHON_INSTALL', 'dont install Python modules if true', False)),
|
||||
(BoolVariable('WITH_BF_PYTHON_INSTALL_NUMPY', 'install Python mumpy module', False)),
|
||||
(BoolVariable('WITHOUT_BF_PYTHON_UNPACK', 'dont remove and unpack Python modules everytime if true', False)),
|
||||
(BoolVariable('WITHOUT_BF_OVERWRITE_INSTALL', 'dont remove existing files before breating the new install directory (set to False when making packages for others)', False)),
|
||||
(BoolVariable('BF_FANCY', 'Enable fancy output if true', True)),
|
||||
@@ -529,7 +537,6 @@ def read_opts(env, cfg, args):
|
||||
|
||||
(BoolVariable('WITH_BF_LZO', 'Enable fast LZO pointcache compression', True)),
|
||||
(BoolVariable('WITH_BF_LZMA', 'Enable best LZMA pointcache compression', True)),
|
||||
(BoolVariable('WITH_BF_CARVE', 'Enable carve library for mesh boolean operations', True)),
|
||||
|
||||
(BoolVariable('WITH_BF_LIBMV', 'Enable libmv structure from motion library', True)),
|
||||
|
||||
@@ -569,6 +576,14 @@ def read_opts(env, cfg, args):
|
||||
('BF_OIIO_LIBPATH', 'OIIO library path', ''),
|
||||
('BF_OIIO_LIB_STATIC', 'OIIO static library', ''),
|
||||
|
||||
(BoolVariable('WITH_BF_OCIO', 'Build with OpenColorIO', False)),
|
||||
(BoolVariable('WITH_BF_STATICOCIO', 'Staticly link to OpenColorIO', False)),
|
||||
('BF_OCIO', 'OCIO root path', ''),
|
||||
('BF_OCIO_INC', 'OCIO include path', ''),
|
||||
('BF_OCIO_LIB', 'OCIO library', ''),
|
||||
('BF_OCIO_LIBPATH', 'OCIO library path', ''),
|
||||
('BF_OCIO_LIB_STATIC', 'OCIO static library', ''),
|
||||
|
||||
(BoolVariable('WITH_BF_BOOST', 'Build with Boost', False)),
|
||||
(BoolVariable('WITH_BF_STATICBOOST', 'Staticly link to boost', False)),
|
||||
('BF_BOOST', 'Boost root path', ''),
|
||||
@@ -577,7 +592,8 @@ def read_opts(env, cfg, args):
|
||||
('BF_BOOST_LIBPATH', 'Boost library path', ''),
|
||||
('BF_BOOST_LIB_STATIC', 'Boost static library', ''),
|
||||
|
||||
(BoolVariable('WITH_GHOST_XDND', 'Build with drag-n-drop support on Linux platforms using XDND protocol', True))
|
||||
(BoolVariable('WITH_GHOST_XDND', 'Build with drag-n-drop support on Linux platforms using XDND protocol', True)),
|
||||
(BoolVariable('WITH_BF_COMPOSITOR_LEGACY', 'Enable the legacy compositor', False))
|
||||
) # end of opts.AddOptions()
|
||||
|
||||
return localopts
|
||||
|
||||
@@ -50,7 +50,7 @@ Contents
|
||||
- It works with only OpenGL calls, for the full 100%. This means that it has some quirks
|
||||
built-in to work with all OS's and OpenGL versions. Especially frontbuffer drawing is
|
||||
a continuous point of attention. Buttons can be drawn with any window matrix. However,
|
||||
errors can still occor when buttons are created in windows with non-standard glViewports.
|
||||
errors can still occur when buttons are created in windows with non-standard glViewports.
|
||||
|
||||
- The code was written to replace the old 1.8 button system, but under high pressure. Quite
|
||||
some button methods from the old system were copied for that reason.
|
||||
@@ -95,7 +95,7 @@ blender/source/blender/src/toolbox.c (extra GUI elements built on top of this AP
|
||||
All GUI elements are collected in uiBlocks, which in turn are linked together in a list that's
|
||||
part of a Blender Area-window.
|
||||
|
||||
uiBlock *block= uiNewBlock(&curarea->uiblocks, "stuff", UI_EMBOSSX, UI_HELV, curarea->win);
|
||||
uiBlock *block = uiNewBlock(&curarea->uiblocks, "stuff", UI_EMBOSSX, UI_HELV, curarea->win);
|
||||
|
||||
The next code example makes a new block, and puts it in the list of blocks of the current active
|
||||
Area:
|
||||
@@ -221,7 +221,7 @@ void uiBlockSetButmFunc(uiBlock *block, void (*menufunc)(void *arg, int event),
|
||||
void uiAutoBlock(uiBlock *block, float minx, float miny, float sizex, float sizey, UI_BLOCK_ROWS)
|
||||
|
||||
Sets the buttons in this block to automatically align, and fit within boundaries.
|
||||
Internally it allows multiple collums or rows as well. Only 'row order' has been implemented.
|
||||
Internally it allows multiple colums or rows as well. Only 'row order' has been implemented.
|
||||
The uiDefBut definitions don't need coordinates as input here, but instead:
|
||||
- first value (x1) to indicate row number
|
||||
- width and height values (if filled in) will be used to define a relative width/height.
|
||||
@@ -346,7 +346,7 @@ type:
|
||||
without returnvalues, the first item gets value 0 (incl. title!)
|
||||
Example: "Do something %t| turn left %2| turn right %1| nothing %0"
|
||||
|
||||
11. COL
|
||||
11. COLOR
|
||||
A special button that only visualizes a RGB value
|
||||
In 'retval' you can put a code, which is used to identify for sliders if it needs
|
||||
redraws while using the sliders. Check button '5'.
|
||||
@@ -363,7 +363,7 @@ uiBut *uiDefIconBut(uiBlock *block, int type, int retval, int icon,
|
||||
float min, float max, float a1, float a2, char *tip)
|
||||
|
||||
Same syntax and types available as previous uiDefBut, but now with an icon code
|
||||
instead of a name. THe icons are numbered in resources.c
|
||||
instead of a name. The icons are numbered in resources.c
|
||||
|
||||
uiBut *uiDefIconTextButF(uiBlock *block, int type, int retval, int icon, char *str,
|
||||
short x1, short y1, short x2, short y2, float *poin,
|
||||
@@ -397,9 +397,9 @@ void uiDefBlockBut(uiBlock *block, uiBlockFuncFP func, void *arg, char *str,
|
||||
static uiBlock *info_file_importmenu(void *arg_unused)
|
||||
{
|
||||
uiBlock *block;
|
||||
short yco= 0, xco = 20;
|
||||
short yco = 0, xco = 20;
|
||||
|
||||
block= uiNewBlock(&curarea->uiblocks, "importmenu", UI_EMBOSSW, UI_HELV, G.curscreen->mainwin);
|
||||
block = uiNewBlock(&curarea->uiblocks, "importmenu", UI_EMBOSSW, UI_HELV, G.curscreen->mainwin);
|
||||
uiBlockSetXOfs(block, -40); // offset to parent button
|
||||
|
||||
/* flags are defines */
|
||||
@@ -409,7 +409,7 @@ void uiDefBlockBut(uiBlock *block, uiBlockFuncFP func, void *arg, char *str,
|
||||
uiDefButS(block, TOG|BIT|2, 0, "Two Sided", xco, yco-=20, 75, 19, &U.vrmlflag, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
uiBlockSetDirection(block, UI_RIGHT);
|
||||
uiTextBoundsBlock(block, 50); // checks for fontsize
|
||||
uiTextBoundsBlock(block, 50); /* checks for fontsize */
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,4 @@
|
||||
.TH "BLENDER" "1" "April 26, 2012" "Blender Blender 2\&.63 (sub 0)
|
||||
build date: 2012-04-26
|
||||
build time: 19:38:31
|
||||
build revision: 45987
|
||||
build platform: Linux
|
||||
build type: Debug
|
||||
build c flags: -fopenmp -msse2 -msse -pipe -fPIC -funsigned-char -fno-strict-aliasing -Wall -Wcast-align -Werror=declaration-after-statement -Werror=implicit-function-declaration -Werror=return-type -Wstrict-prototypes -Wno-char-subscripts -Wno-unknown-pragmas -Wpointer-arith -Wunused-parameter -Wwrite-strings
|
||||
build c++ flags: -D__STDC_CONSTANT_MACROS -fopenmp -msse2 -msse -pipe -fPIC -funsigned-char -fno-strict-aliasing -Wall -Wno-invalid-offsetof -Wno-sign-compare
|
||||
build link flags: -pthread
|
||||
build system: CMake"
|
||||
.TH "BLENDER" "1" "October 04, 2012" "Blender Blender 2\&.64 (sub 0)"
|
||||
|
||||
.SH NAME
|
||||
blender \- a 3D modelling and rendering package
|
||||
@@ -24,7 +15,7 @@ Use Blender to create TV commercials, to make technical visualizations, business
|
||||
http://www.blender.org
|
||||
.SH OPTIONS
|
||||
|
||||
Blender 2.63 (sub 0)
|
||||
Blender 2.64 (sub 0)
|
||||
Usage: blender [args ...] [file] [args ...]
|
||||
.br
|
||||
.SS "Render Options:"
|
||||
@@ -223,18 +214,6 @@ Turn debugging on
|
||||
Enable floating point exceptions
|
||||
.br
|
||||
|
||||
.TP
|
||||
.B \-\-debug\-ffmpeg
|
||||
.br
|
||||
Enable debug messages from FFmpeg library
|
||||
.br
|
||||
|
||||
.TP
|
||||
.B \-\-debug\-libmv
|
||||
.br
|
||||
Enable debug messages from libmv library
|
||||
.br
|
||||
|
||||
.IP
|
||||
|
||||
.TP
|
||||
@@ -257,12 +236,6 @@ Set the BLENDER_SYSTEM_DATAFILES environment variable
|
||||
Set the BLENDER_SYSTEM_SCRIPTS environment variable
|
||||
.br
|
||||
|
||||
.TP
|
||||
.B \-\-env\-system\-plugins
|
||||
.br
|
||||
Set the BLENDER_SYSTEM_PLUGINS environment variable
|
||||
.br
|
||||
|
||||
.TP
|
||||
.B \-\-env\-system\-python
|
||||
.br
|
||||
@@ -316,7 +289,7 @@ Enable automatic python script execution, (default)
|
||||
.TP
|
||||
.B \-Y or \-\-disable\-autoexec
|
||||
.br
|
||||
Disable automatic python script execution (pydrivers, pyconstraints, pynodes)
|
||||
Disable automatic python script execution (pydrivers & startup scripts)
|
||||
.br
|
||||
|
||||
.IP
|
||||
@@ -383,6 +356,26 @@ Enable debug messages for the window manager
|
||||
Enable all debug messages (excludes libmv)
|
||||
.br
|
||||
|
||||
.TP
|
||||
.B \-\-debug\-value <value>
|
||||
.br
|
||||
Set debug value of <value> on startup
|
||||
.br
|
||||
|
||||
.IP
|
||||
|
||||
.TP
|
||||
.B \-\-debug\-jobs
|
||||
.br
|
||||
Enable time profiling for background jobs.
|
||||
.br
|
||||
|
||||
.TP
|
||||
.B \-\-verbose <verbose>
|
||||
.br
|
||||
Set logging verbosity level.
|
||||
.br
|
||||
|
||||
.TP
|
||||
.B \-R
|
||||
.br
|
||||
@@ -421,7 +414,6 @@ Arguments are executed in the order they are given. eg
|
||||
\fIBLENDER_SYSTEM_DATAFILES\fR Directory for system wide data files.
|
||||
\fIBLENDER_SYSTEM_PYTHON\fR Directory for system python libraries.
|
||||
\fITMP\fR or \fITMPDIR\fR Store temporary files here.
|
||||
\fISDL_AUDIODRIVER\fR LibSDL audio driver \- alsa, esd, dma.
|
||||
\fIPYTHONHOME\fR Path to the python directory, eg. /usr/lib/python.
|
||||
.br
|
||||
.br
|
||||
|
||||
@@ -19,4 +19,4 @@ The execution context is as a non keyword, string argument in:
|
||||
|
||||
# group add popup
|
||||
import bpy
|
||||
bpy.ops.object.group_instance_add('INVOKE_DEFAULT')
|
||||
bpy.ops.object.group_instance_add('INVOKE_DEFAULT')
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
Game Logic (bge.logic)
|
||||
======================
|
||||
|
||||
*****
|
||||
Intro
|
||||
*****
|
||||
************
|
||||
Introduction
|
||||
************
|
||||
|
||||
Module to access logic functions, imported automatically into the python controllers namespace.
|
||||
|
||||
@@ -172,7 +172,7 @@ General functions
|
||||
|
||||
Restarts the current game by reloading the .blend file (the last saved version, not what is currently running).
|
||||
|
||||
.. function:: LibLoad(blend, type, data, load_actions=False, verbose=False)
|
||||
.. function:: LibLoad(blend, type, data, load_actions=False, verbose=False, load_scripts=True)
|
||||
|
||||
Converts the all of the datablocks of the given type from the given blend.
|
||||
|
||||
@@ -186,6 +186,8 @@ General functions
|
||||
:type load_actions: bool
|
||||
:arg verbose: Whether or not to print debugging information (e.g., "SceneName: Scene")
|
||||
:type verbose: bool
|
||||
:arg load_scripts: Whether or not to load text datablocks as well (can be disabled for some extra security)
|
||||
:type load_scripts: bool
|
||||
|
||||
.. function:: LibNew(name, type, data)
|
||||
|
||||
|
||||
@@ -4,6 +4,33 @@ Game Types (bge.types)
|
||||
|
||||
.. module:: bge.types
|
||||
|
||||
************
|
||||
Introduction
|
||||
************
|
||||
|
||||
This module contains the classes that appear as instances in the Game Engine. A
|
||||
script must interact with these classes if it is to affect the behaviour of
|
||||
objects in a game.
|
||||
|
||||
The following example would move an object (i.e. an instance of
|
||||
:class:`KX_GameObject`) one unit up.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# bge.types.SCA_PythonController
|
||||
cont = bge.logic.getCurrentController()
|
||||
|
||||
# bge.types.KX_GameObject
|
||||
obj = cont.owner
|
||||
obj.worldPosition.z += 1
|
||||
|
||||
To run the code, it could be placed in a Blender text block and executed with
|
||||
a :class:`SCA_PythonController` logic brick.
|
||||
|
||||
*****
|
||||
Types
|
||||
*****
|
||||
|
||||
.. class:: PyObjectPlus
|
||||
|
||||
PyObjectPlus base class of most other types in the Game Engine.
|
||||
@@ -306,7 +333,8 @@ Game Types (bge.types)
|
||||
|
||||
.. attribute:: useContinue
|
||||
|
||||
The actions continue option, True or False. When True, the action will always play from where last left off, otherwise negative events to this actuator will reset it to its start frame.
|
||||
The actions continue option, True or False. When True, the action will always play from where last left off,
|
||||
otherwise negative events to this actuator will reset it to its start frame.
|
||||
|
||||
:type: boolean
|
||||
|
||||
@@ -852,7 +880,54 @@ Game Types (bge.types)
|
||||
|
||||
.. note::
|
||||
|
||||
Calling ANY method or attribute on an object that has been removed from a scene will raise a SystemError, if an object may have been removed since last accessing it use the :data:`invalid` attribute to check.
|
||||
Calling ANY method or attribute on an object that has been removed from a scene will raise a SystemError,
|
||||
if an object may have been removed since last accessing it use the :data:`invalid` attribute to check.
|
||||
|
||||
KX_GameObject can be subclassed to extend functionality. For example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import bge
|
||||
|
||||
class CustomGameObject(bge.types.KX_GameObject):
|
||||
RATE = 0.05
|
||||
|
||||
def __init__(self, old_owner):
|
||||
# "old_owner" can just be ignored. At this point, "self" is
|
||||
# already the object in the scene, and "old_owner" has been
|
||||
# destroyed.
|
||||
|
||||
# New attributes can be defined - but we could also use a game
|
||||
# property, like "self['rate']".
|
||||
self.rate = CustomGameObject.RATE
|
||||
|
||||
def update(self):
|
||||
self.worldPosition.z += self.rate
|
||||
|
||||
# switch direction
|
||||
if self.worldPosition.z > 1.0:
|
||||
self.rate = -CustomGameObject.RATE
|
||||
elif self.worldPosition.z < 0.0:
|
||||
self.rate = CustomGameObject.RATE
|
||||
|
||||
# Called first
|
||||
def mutate(cont):
|
||||
old_object = cont.owner
|
||||
mutated_object = CustomGameObject(cont.owner)
|
||||
|
||||
# After calling the constructor above, references to the old object
|
||||
# should not be used.
|
||||
assert(old_object is not mutated_object)
|
||||
assert(old_object.invalid)
|
||||
assert(mutated_object is cont.owner)
|
||||
|
||||
# Called later - note we are now working with the mutated object.
|
||||
def update(cont):
|
||||
cont.owner.update()
|
||||
|
||||
When subclassing objects other than empties and meshes, the specific type
|
||||
should be used - e.g. inherit from :class:`BL_ArmatureObject` when the object
|
||||
to mutate is an armature.
|
||||
|
||||
.. attribute:: name
|
||||
|
||||
@@ -913,6 +988,24 @@ Game Types (bge.types)
|
||||
The object's parent object. (read-only).
|
||||
|
||||
:type: :class:`KX_GameObject` or None
|
||||
|
||||
.. attribute:: group_children
|
||||
|
||||
Returns the list of group members if the object is a group object, otherwise None is returned.
|
||||
|
||||
:type: :class:`CListValue` of :class:`KX_GameObject` or None
|
||||
|
||||
.. attribute:: group_parent
|
||||
|
||||
Returns the group object that the object belongs to or None if the object is not part of a group.
|
||||
|
||||
:type: :class:`KX_GameObject` or None
|
||||
|
||||
.. attribute:: scene
|
||||
|
||||
The object's scene. (read-only).
|
||||
|
||||
:type: :class:`KX_Scene` or None
|
||||
|
||||
.. attribute:: visible
|
||||
|
||||
@@ -1335,18 +1428,10 @@ Game Types (bge.types)
|
||||
|
||||
Rigid body physics allows the object to roll on collisions.
|
||||
|
||||
.. note::
|
||||
|
||||
This is not working with bullet physics yet.
|
||||
|
||||
.. method:: disableRigidBody()
|
||||
|
||||
Disables rigid body physics for this object.
|
||||
|
||||
.. note::
|
||||
|
||||
This is not working with bullet physics yet. The angular is removed but rigid body physics can still rotate it later.
|
||||
|
||||
.. method:: setParent(parent, compound=True, ghost=True)
|
||||
|
||||
Sets this object's parent.
|
||||
@@ -4222,6 +4307,10 @@ Game Types (bge.types)
|
||||
.. attribute:: projection_matrix
|
||||
|
||||
This camera's 4x4 projection matrix.
|
||||
|
||||
.. note::
|
||||
|
||||
This is the identity matrix prior to rendering the first frame (any Python done on frame 1).
|
||||
|
||||
:type: 4x4 Matrix [[float]]
|
||||
|
||||
@@ -4233,7 +4322,7 @@ Game Types (bge.types)
|
||||
|
||||
.. note::
|
||||
|
||||
This matrix is regenerated every frame from the camera's position and orientation.
|
||||
This matrix is regenerated every frame from the camera's position and orientation. Also, this is the identity matrix prior to rendering the first frame (any Python done on frame 1).
|
||||
|
||||
.. attribute:: camera_to_world
|
||||
|
||||
@@ -4477,7 +4566,9 @@ Game Types (bge.types)
|
||||
|
||||
.. data:: KX_ACT_ARMATURE_RUN
|
||||
|
||||
Just make sure the armature will be updated on the next graphic frame. This is the only persistent mode of the actuator: it executes automatically once per frame until stopped by a controller
|
||||
Just make sure the armature will be updated on the next graphic frame.
|
||||
This is the only persistent mode of the actuator:
|
||||
it executes automatically once per frame until stopped by a controller
|
||||
|
||||
:value: 0
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -56,7 +56,69 @@ To enable line length checks use this instead.
|
||||
User Interface Layout
|
||||
=====================
|
||||
|
||||
TODO: Thomas
|
||||
Some notes to keep in mind when writing UI layouts:
|
||||
|
||||
* UI code is quite simple. Layout declarations are there to easily create a decent layout.
|
||||
|
||||
General rule here: If you need more code for the layout declaration, then for the actual properties, you do it wrong.
|
||||
|
||||
Example layouts:
|
||||
|
||||
* layout()
|
||||
|
||||
The basic layout is a simple Top -> Bottom layout.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
layout.prop()
|
||||
layout.prop()
|
||||
|
||||
* layout.row()
|
||||
|
||||
Use row(), when you want more than 1 property in one line.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
row = layout.row()
|
||||
row.prop()
|
||||
row.prop()
|
||||
|
||||
* layout.column()
|
||||
|
||||
Use column(), when you want your properties in a column.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
col = layout.column()
|
||||
col.prop()
|
||||
col.prop()
|
||||
|
||||
* layout.split()
|
||||
|
||||
This can be used to create more complex layouts. For example you can split the layout and create two column() layouts next to each other.
|
||||
Don't use split, when you simply want two properties in a row. Use row() for that.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.prop()
|
||||
col.prop()
|
||||
|
||||
col = split.column()
|
||||
col.prop()
|
||||
col.prop()
|
||||
|
||||
Declaration names:
|
||||
|
||||
Try to only use these variable names for layout declarations:
|
||||
|
||||
* row for a row() layout
|
||||
* col for a column() layout
|
||||
* split for a split() layout
|
||||
* flow for a column_flow() layout
|
||||
* sub for a sub layout (a column inside a column for example)
|
||||
|
||||
|
||||
Script Efficiency
|
||||
@@ -83,7 +145,7 @@ Even though you're not looping on the list data **python is**, so you need to be
|
||||
|
||||
Modifying Lists
|
||||
^^^^^^^^^^^^^^^
|
||||
In python we can add and remove from a list, This is slower when the list length is modified, especially at the start of the list, since all the data after the index of modification needs to be moved up or down 1 place.
|
||||
In python we can add and remove from a list, this is slower when the list length is modified, especially at the start of the list, since all the data after the index of modification needs to be moved up or down 1 place.
|
||||
|
||||
The most simple way to add onto the end of the list is to use ``my_list.append(list_item)`` or ``my_list.extend(some_list)`` and the fastest way to remove an item is ``my_list.pop()`` or ``del my_list[-1]``.
|
||||
|
||||
@@ -92,13 +154,13 @@ To use an index you can use ``my_list.insert(index, list_item)`` or ``list.pop(i
|
||||
Sometimes its faster (but more memory hungry) to just rebuild the list.
|
||||
|
||||
|
||||
Say you want to remove all triangle faces in a list.
|
||||
Say you want to remove all triangular faces in a list.
|
||||
|
||||
Rather than...
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
faces = mesh.faces[:] # make a list copy of the meshes faces
|
||||
faces = mesh.tessfaces[:] # make a list copy of the meshes faces
|
||||
f_idx = len(faces) # Loop backwards
|
||||
while f_idx: # while the value is not 0
|
||||
f_idx -= 1
|
||||
@@ -111,13 +173,13 @@ It's faster to build a new list with list comprehension.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
faces = [f for f in mesh.faces if len(f.vertices) != 3]
|
||||
faces = [f for f in mesh.tessfaces if len(f.vertices) != 3]
|
||||
|
||||
|
||||
Adding List Items
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you have a list that you want to add onto another list, rather then...
|
||||
If you have a list that you want to add onto another list, rather than...
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -143,6 +205,14 @@ This example shows a very sub-optimal way of making a reversed list.
|
||||
reverse_list.insert(0, list_item)
|
||||
|
||||
|
||||
Python provides more convenient ways to reverse a list using the slice method, but you may want to time this before relying on it too much:
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
some_reversed_list = some_list[::-1]
|
||||
|
||||
|
||||
Removing List Items
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -162,7 +232,7 @@ Here is an example of how to remove items in 1 loop, removing the last items fir
|
||||
my_list.pop(list_index)
|
||||
|
||||
|
||||
This example shows a fast way of removing items, for use in cases were where you can alter the list order without breaking the scripts functionality. This works by swapping 2 list items, so the item you remove is always last.
|
||||
This example shows a fast way of removing items, for use in cases where you can alter the list order without breaking the scripts functionality. This works by swapping 2 list items, so the item you remove is always last.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -181,9 +251,9 @@ When removing many items in a large list this can provide a good speedup.
|
||||
Avoid Copying Lists
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When passing a list/dictionary to a function, it is faster to have the function modify the list rather then returning a new list so python doesn't have to duplicate the list in memory.
|
||||
When passing a list/dictionary to a function, it is faster to have the function modify the list rather than returning a new list so python doesn't have to duplicate the list in memory.
|
||||
|
||||
Functions that modify a list in-place are more efficient then functions that create new lists.
|
||||
Functions that modify a list in-place are more efficient than functions that create new lists.
|
||||
|
||||
|
||||
This is generally slower so only use for functions when it makes sense not to modify the list in place.
|
||||
@@ -211,22 +281,22 @@ Here are 3 ways of joining multiple strings into 1 string for writing
|
||||
This really applies to any area of your code that involves a lot of string joining.
|
||||
|
||||
|
||||
Pythons string addition, *don't use if you can help it, especially when writing data in a loop.*
|
||||
Python’s string addition, *don't use if you can help it, especially when writing data in a loop.*
|
||||
|
||||
>>> file.write(str1 + " " + str2 + " " + str3 + "\n")
|
||||
|
||||
|
||||
String formatting. Use this when you're writing string data from floats and int's
|
||||
String formatting. Use this when you're writing string data from floats and ints
|
||||
|
||||
>>> file.write("%s %s %s\n" % (str1, str2, str3))
|
||||
|
||||
|
||||
Pythons string joining function. To join a list of strings
|
||||
Python’s string joining function. To join a list of strings
|
||||
|
||||
>>> file.write(" ".join([str1, str2, str3, "\n"]))
|
||||
|
||||
|
||||
join is fastest on many strings, string formatting is quite fast too (better for converting data types). String arithmetic is slowest.
|
||||
join is fastest on many strings, `string formatting <http://docs.python.org/py3k/library/string.html#string-formatting>`_ is quite fast too (better for converting data types). String arithmetic is slowest.
|
||||
|
||||
|
||||
Parsing Strings (Import/Exporting)
|
||||
@@ -234,12 +304,12 @@ Parsing Strings (Import/Exporting)
|
||||
|
||||
Since many file formats are ASCII, the way you parse/export strings can make a large difference in how fast your script runs.
|
||||
|
||||
When importing strings to make into blender there are a few ways to parse the string.
|
||||
There are a few ways to parse strings when importing them into Blender.
|
||||
|
||||
Parsing Numbers
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Use ``float(string)`` rather than ``eval(string)``, if you know the value will be an int then ``int(string)``, float() will work for an int too but its faster to read ints with int().
|
||||
Use ``float(string)`` rather than ``eval(string)``, if you know the value will be an int then ``int(string)``, float() will work for an int too but it's faster to read ints with int().
|
||||
|
||||
Checking String Start/End
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -256,7 +326,7 @@ Using ``startswith()`` is slightly faster (approx 5%) and also avoids a possible
|
||||
|
||||
my_string.endswith("foo_bar") can be used for line endings too.
|
||||
|
||||
if your unsure whether the text is upper or lower case use lower or upper string function.
|
||||
If you are unsure whether the text is upper or lower case use ``lower()`` or ``upper()`` string function.
|
||||
|
||||
>>> if line.lower().startswith("vert ")
|
||||
|
||||
@@ -266,7 +336,7 @@ Use try/except Sparingly
|
||||
|
||||
The **try** statement is useful to save time writing error checking code.
|
||||
|
||||
However **try** is significantly slower then an **if** since an exception has to be set each time, so avoid using **try** in areas of your code that execute in a loop and runs many times.
|
||||
However **try** is significantly slower than an **if** since an exception has to be set each time, so avoid using **try** in areas of your code that execute in a loop and runs many times.
|
||||
|
||||
There are cases where using **try** is faster than checking whether the condition will raise an error, so it is worth experimenting.
|
||||
|
||||
@@ -274,7 +344,7 @@ There are cases where using **try** is faster than checking whether the conditio
|
||||
Value Comparison
|
||||
----------------
|
||||
|
||||
Python has two ways to compare values ``a == b`` and ``a is b``, The difference is that ``==`` may run the objects comparison function ``__cmp__()`` where as ``is`` compares identity, that both variables reference the same item in memory.
|
||||
Python has two ways to compare values ``a == b`` and ``a is b``, the difference is that ``==`` may run the objects comparison function ``__cmp__()`` whereas ``is`` compares identity, that both variables reference the same item in memory.
|
||||
|
||||
In cases where you know you are checking for the same value which is referenced from multiple places, ``is`` is faster.
|
||||
|
||||
@@ -282,7 +352,7 @@ In cases where you know you are checking for the same value which is referenced
|
||||
Time Your Code
|
||||
--------------
|
||||
|
||||
While developing a script its good to time it to be aware of any changes in performance, this can be done simply.
|
||||
While developing a script it's good to time it to be aware of any changes in performance, this can be done simply.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
|
||||
@@ -137,11 +137,11 @@ For the time being this limitation just has to be worked around but we're aware
|
||||
NGons and Tessellation Faces
|
||||
============================
|
||||
|
||||
Since 2.63 NGons are supported, this adds some complexity since in some cases you need to access triangles still (some exporters for example).
|
||||
Since 2.63 NGons are supported, this adds some complexity since in some cases you need to access triangles/quads still (some exporters for example).
|
||||
|
||||
There are now 3 ways to access faces:
|
||||
|
||||
* :class:`bpy.types.MeshPolygon` - this is the data stricture which now stores faces in object mode (access as ``mesh.polygons`` rather then ``mesh.faces``).
|
||||
* :class:`bpy.types.MeshPolygon` - this is the data structure which now stores faces in object mode (access as ``mesh.polygons`` rather then ``mesh.faces``).
|
||||
* :class:`bpy.types.MeshTessFace` - the result of triangulating (tessellated) polygons, the main method of face access in 2.62 or older (access as ``mesh.tessfaces``).
|
||||
* :class:`bmesh.types.BMFace` - the polygons as used in editmode.
|
||||
|
||||
|
||||
@@ -28,15 +28,15 @@ blender --background --python doc/python_api/sphinx_changelog_gen.py -- --dump
|
||||
|
||||
# create changelog
|
||||
blender --background --python doc/python_api/sphinx_changelog_gen.py -- \
|
||||
--api_from blender_2_56_1.py \
|
||||
--api_to blender_2_57_0.py \
|
||||
--api_from blender_2_63_0.py \
|
||||
--api_to blender_2_64_0.py \
|
||||
--api_out changes.rst
|
||||
|
||||
|
||||
# Api comparison can also run without blender
|
||||
python doc/python_api/sphinx_changelog_gen.py \
|
||||
--api_from blender_api_2_56_6.py \
|
||||
--api_to blender_api_2_57.py \
|
||||
python doc/python_api/sphinx_changelog_gen.py -- \
|
||||
--api_from blender_api_2_63_0.py \
|
||||
--api_to blender_api_2_64_0.py \
|
||||
--api_out changes.rst
|
||||
|
||||
# Save the latest API dump in this folder, renaming it with its revision.
|
||||
@@ -307,6 +307,8 @@ def api_changelog(api_from, api_to, api_out):
|
||||
|
||||
fout.close()
|
||||
|
||||
print("Written: %r" % api_out)
|
||||
|
||||
|
||||
def main():
|
||||
import sys
|
||||
@@ -347,6 +349,7 @@ def main():
|
||||
args = parser.parse_args(argv) # In this example we wont use the args
|
||||
|
||||
if not argv:
|
||||
print("No args given!")
|
||||
parser.print_help()
|
||||
return
|
||||
|
||||
|
||||
@@ -399,7 +399,7 @@ SPHINX_THEMES = {'bf': ['blender-org'], # , 'naiad',
|
||||
|
||||
available_themes = SPHINX_THEMES['bf'] + SPHINX_THEMES['sphinx']
|
||||
if ARGS.sphinx_theme not in available_themes:
|
||||
print ("Please choose a theme among: %s" % ', '.join(available_themes))
|
||||
print("Please choose a theme among: %s" % ', '.join(available_themes))
|
||||
sys.exit()
|
||||
|
||||
if ARGS.sphinx_theme in SPHINX_THEMES['bf']:
|
||||
@@ -849,7 +849,7 @@ def pymodule2sphinx(basepath, module_name, module, title):
|
||||
elif value_type in (bool, int, float, str, tuple):
|
||||
# constant, not much fun we can do here except to list it.
|
||||
# TODO, figure out some way to document these!
|
||||
#fw(".. data:: %s\n\n" % attribute)
|
||||
fw(".. data:: %s\n\n" % attribute)
|
||||
write_indented_lines(" ", fw, "constant value %s" % repr(value), False)
|
||||
fw("\n")
|
||||
else:
|
||||
@@ -971,6 +971,7 @@ def pycontext2sphinx(basepath):
|
||||
"meta_ball": ("MetaBall", False),
|
||||
"object": ("Object", False),
|
||||
"particle_edit_object": ("Object", False),
|
||||
"particle_settings": ("ParticleSettings", False),
|
||||
"particle_system": ("ParticleSystem", False),
|
||||
"particle_system_editable": ("ParticleSystem", False),
|
||||
"pose_bone": ("PoseBone", False),
|
||||
|
||||
2
extern/CMakeLists.txt
vendored
2
extern/CMakeLists.txt
vendored
@@ -68,7 +68,7 @@ if(WITH_LIBMV)
|
||||
add_subdirectory(libmv)
|
||||
endif()
|
||||
|
||||
if(WITH_CARVE)
|
||||
if(WITH_MOD_BOOLEAN)
|
||||
add_subdirectory(carve)
|
||||
endif()
|
||||
|
||||
|
||||
2
extern/SConscript
vendored
2
extern/SConscript
vendored
@@ -32,7 +32,7 @@ if env['WITH_BF_LZMA']:
|
||||
if env['WITH_BF_LIBMV']:
|
||||
SConscript(['libmv/SConscript'])
|
||||
|
||||
if env['WITH_BF_CARVE']:
|
||||
if env['WITH_BF_BOOLEAN']:
|
||||
SConscript(['carve/SConscript'])
|
||||
|
||||
if env['WITH_GHOST_XDND']:
|
||||
|
||||
2
extern/bullet2/CMakeLists.txt
vendored
2
extern/bullet2/CMakeLists.txt
vendored
@@ -314,6 +314,7 @@ set(SRC
|
||||
src/BulletDynamics/Character/btKinematicCharacterController.h
|
||||
|
||||
src/BulletSoftBody/btSoftBody.h
|
||||
src/BulletSoftBody/btSoftBodyInternals.h
|
||||
src/BulletSoftBody/btSoftBodyData.h
|
||||
src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h
|
||||
src/BulletSoftBody/btSoftBodyHelpers.h
|
||||
@@ -355,6 +356,7 @@ set(SRC
|
||||
|
||||
src/btBulletCollisionCommon.h
|
||||
src/btBulletDynamicsCommon.h
|
||||
src/Bullet-C-Api.h
|
||||
)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
|
||||
28
extern/bullet2/patches/ghost_character.patch
vendored
Normal file
28
extern/bullet2/patches/ghost_character.patch
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
Index: extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.cpp
|
||||
===================================================================
|
||||
--- extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.cpp (revision 49183)
|
||||
+++ extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.cpp (working copy)
|
||||
@@ -77,6 +77,9 @@
|
||||
if (convexResult.m_hitCollisionObject == m_me)
|
||||
return btScalar(1.0);
|
||||
|
||||
+ if (!convexResult.m_hitCollisionObject->hasContactResponse())
|
||||
+ return btScalar(1.0);
|
||||
+
|
||||
btVector3 hitNormalWorld;
|
||||
if (normalInWorldSpace)
|
||||
{
|
||||
@@ -173,7 +176,12 @@
|
||||
m_manifoldArray.resize(0);
|
||||
|
||||
btBroadphasePair* collisionPair = &m_ghostObject->getOverlappingPairCache()->getOverlappingPairArray()[i];
|
||||
-
|
||||
+ btCollisionObject* obj0 = static_cast<btCollisionObject*>(collisionPair->m_pProxy0->m_clientObject);
|
||||
+ btCollisionObject* obj1 = static_cast<btCollisionObject*>(collisionPair->m_pProxy1->m_clientObject);
|
||||
+
|
||||
+ if ((obj0 && !obj0->hasContactResponse()) || (obj1 && !obj1->hasContactResponse()))
|
||||
+ continue;
|
||||
+
|
||||
if (collisionPair->m_algorithm)
|
||||
collisionPair->m_algorithm->getAllContactManifolds(m_manifoldArray);
|
||||
|
||||
4
extern/bullet2/readme.txt
vendored
4
extern/bullet2/readme.txt
vendored
@@ -13,3 +13,7 @@ Originally committed in blender svn revision: 45908.
|
||||
Apply patches/make_id.patch to prevent duplicated define of MAKE_ID macro in blender
|
||||
side and bullet side.
|
||||
Sergey
|
||||
|
||||
Apply patches/ghost_character.path to prevent characters from colliding with ghost objects.
|
||||
Mitchell
|
||||
|
||||
|
||||
@@ -77,6 +77,9 @@ public:
|
||||
if (convexResult.m_hitCollisionObject == m_me)
|
||||
return btScalar(1.0);
|
||||
|
||||
if (!convexResult.m_hitCollisionObject->hasContactResponse())
|
||||
return btScalar(1.0);
|
||||
|
||||
btVector3 hitNormalWorld;
|
||||
if (normalInWorldSpace)
|
||||
{
|
||||
@@ -173,7 +176,12 @@ bool btKinematicCharacterController::recoverFromPenetration ( btCollisionWorld*
|
||||
m_manifoldArray.resize(0);
|
||||
|
||||
btBroadphasePair* collisionPair = &m_ghostObject->getOverlappingPairCache()->getOverlappingPairArray()[i];
|
||||
|
||||
btCollisionObject* obj0 = static_cast<btCollisionObject*>(collisionPair->m_pProxy0->m_clientObject);
|
||||
btCollisionObject* obj1 = static_cast<btCollisionObject*>(collisionPair->m_pProxy1->m_clientObject);
|
||||
|
||||
if ((obj0 && !obj0->hasContactResponse()) || (obj1 && !obj1->hasContactResponse()))
|
||||
continue;
|
||||
|
||||
if (collisionPair->m_algorithm)
|
||||
collisionPair->m_algorithm->getAllContactManifolds(m_manifoldArray);
|
||||
|
||||
|
||||
2
extern/carve/CMakeLists.txt
vendored
2
extern/carve/CMakeLists.txt
vendored
@@ -158,7 +158,7 @@ if(WITH_BOOST)
|
||||
-DCARVE_SYSTEM_BOOST
|
||||
)
|
||||
|
||||
list(APPEND INC
|
||||
list(APPEND INC_SYS
|
||||
${BOOST_INCLUDE_DIR}
|
||||
)
|
||||
endif()
|
||||
|
||||
46
extern/carve/include/carve/csg.hpp
vendored
46
extern/carve/include/carve/csg.hpp
vendored
@@ -174,34 +174,34 @@ namespace carve {
|
||||
|
||||
void groupIntersections();
|
||||
|
||||
void _generateVertexVertexIntersections(carve::mesh::MeshSet<3>::vertex_t *va,
|
||||
carve::mesh::MeshSet<3>::edge_t *eb);
|
||||
void generateVertexVertexIntersections(carve::mesh::MeshSet<3>::face_t *a,
|
||||
const std::vector<carve::mesh::MeshSet<3>::face_t *> &b);
|
||||
void _generateVertexVertexIntersections(meshset_t::vertex_t *va,
|
||||
meshset_t::edge_t *eb);
|
||||
void generateVertexVertexIntersections(meshset_t::face_t *a,
|
||||
const std::vector<meshset_t::face_t *> &b);
|
||||
|
||||
void _generateVertexEdgeIntersections(carve::mesh::MeshSet<3>::vertex_t *va,
|
||||
carve::mesh::MeshSet<3>::edge_t *eb);
|
||||
void generateVertexEdgeIntersections(carve::mesh::MeshSet<3>::face_t *a,
|
||||
const std::vector<carve::mesh::MeshSet<3>::face_t *> &b);
|
||||
void _generateVertexEdgeIntersections(meshset_t::vertex_t *va,
|
||||
meshset_t::edge_t *eb);
|
||||
void generateVertexEdgeIntersections(meshset_t::face_t *a,
|
||||
const std::vector<meshset_t::face_t *> &b);
|
||||
|
||||
void _generateEdgeEdgeIntersections(carve::mesh::MeshSet<3>::edge_t *ea,
|
||||
carve::mesh::MeshSet<3>::edge_t *eb);
|
||||
void generateEdgeEdgeIntersections(carve::mesh::MeshSet<3>::face_t *a,
|
||||
const std::vector<carve::mesh::MeshSet<3>::face_t *> &b);
|
||||
void _generateEdgeEdgeIntersections(meshset_t::edge_t *ea,
|
||||
meshset_t::edge_t *eb);
|
||||
void generateEdgeEdgeIntersections(meshset_t::face_t *a,
|
||||
const std::vector<meshset_t::face_t *> &b);
|
||||
|
||||
void _generateVertexFaceIntersections(carve::mesh::MeshSet<3>::face_t *fa,
|
||||
carve::mesh::MeshSet<3>::edge_t *eb);
|
||||
void generateVertexFaceIntersections(carve::mesh::MeshSet<3>::face_t *a,
|
||||
const std::vector<carve::mesh::MeshSet<3>::face_t *> &b);
|
||||
void _generateVertexFaceIntersections(meshset_t::face_t *fa,
|
||||
meshset_t::edge_t *eb);
|
||||
void generateVertexFaceIntersections(meshset_t::face_t *a,
|
||||
const std::vector<meshset_t::face_t *> &b);
|
||||
|
||||
void _generateEdgeFaceIntersections(carve::mesh::MeshSet<3>::face_t *fa,
|
||||
carve::mesh::MeshSet<3>::edge_t *eb);
|
||||
void generateEdgeFaceIntersections(carve::mesh::MeshSet<3>::face_t *a,
|
||||
const std::vector<carve::mesh::MeshSet<3>::face_t *> &b);
|
||||
void _generateEdgeFaceIntersections(meshset_t::face_t *fa,
|
||||
meshset_t::edge_t *eb);
|
||||
void generateEdgeFaceIntersections(meshset_t::face_t *a,
|
||||
const std::vector<meshset_t::face_t *> &b);
|
||||
|
||||
void generateIntersectionCandidates(carve::mesh::MeshSet<3> *a,
|
||||
void generateIntersectionCandidates(meshset_t *a,
|
||||
const face_rtree_t *a_node,
|
||||
carve::mesh::MeshSet<3> *b,
|
||||
meshset_t *b,
|
||||
const face_rtree_t *b_node,
|
||||
face_pairs_t &face_pairs,
|
||||
bool descend_a = true);
|
||||
@@ -287,7 +287,7 @@ namespace carve {
|
||||
* @param[out] out_loops A list of grouped face loops.
|
||||
*/
|
||||
void groupFaceLoops(
|
||||
carve::mesh::MeshSet<3> *src,
|
||||
meshset_t *src,
|
||||
FaceLoopList &face_loops,
|
||||
const detail::LoopEdges &loop_edges,
|
||||
const V2Set &no_cross,
|
||||
|
||||
5
extern/carve/include/carve/polyline_decl.hpp
vendored
5
extern/carve/include/carve/polyline_decl.hpp
vendored
@@ -138,6 +138,11 @@ namespace carve {
|
||||
PolylineSet(const std::vector<carve::geom3d::Vector> &points);
|
||||
PolylineSet() {
|
||||
}
|
||||
~PolylineSet() {
|
||||
for (line_iter i = lines.begin(); i != lines.end(); ++i) {
|
||||
delete *i;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename iter_t>
|
||||
void addPolyline(bool closed, iter_t begin, iter_t end);
|
||||
|
||||
13
extern/carve/include/carve/rtree.hpp
vendored
13
extern/carve/include/carve/rtree.hpp
vendored
@@ -49,8 +49,6 @@ namespace carve {
|
||||
|
||||
aabb_t getAABB() const { return bbox; }
|
||||
|
||||
|
||||
|
||||
struct data_aabb_t {
|
||||
aabb_t bbox;
|
||||
data_t data;
|
||||
@@ -164,6 +162,17 @@ namespace carve {
|
||||
_fill(begin, end, typename std::iterator_traits<iter_t>::value_type());
|
||||
}
|
||||
|
||||
~RTreeNode() {
|
||||
if (child) {
|
||||
RTreeNode *next = child;
|
||||
while (next) {
|
||||
RTreeNode *curr = next;
|
||||
next = next->sibling;
|
||||
delete curr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// functor for ordering nodes by increasing aabb midpoint, along a specified axis.
|
||||
|
||||
4
extern/carve/lib/csg_data.hpp
vendored
4
extern/carve/lib/csg_data.hpp
vendored
@@ -30,7 +30,7 @@ struct carve::csg::detail::Data {
|
||||
VVMap vmap;
|
||||
|
||||
// map from intersected edge to intersection points.
|
||||
EVSMap emap;
|
||||
EIntMap emap;
|
||||
|
||||
// map from intersected face to intersection points.
|
||||
FVSMap fmap;
|
||||
@@ -39,7 +39,7 @@ struct carve::csg::detail::Data {
|
||||
VFSMap fmap_rev;
|
||||
|
||||
// created by divideEdges().
|
||||
// holds, for each edge, a
|
||||
// holds, for each edge, an ordered vector of inserted vertices.
|
||||
EVVMap divided_edges;
|
||||
|
||||
// created by faceSplitEdges.
|
||||
|
||||
30
extern/carve/lib/csg_detail.hpp
vendored
30
extern/carve/lib/csg_detail.hpp
vendored
@@ -24,30 +24,32 @@
|
||||
namespace carve {
|
||||
namespace csg {
|
||||
namespace detail {
|
||||
typedef std::map<carve::mesh::MeshSet<3>::vertex_t *,
|
||||
std::set<std::pair<carve::mesh::MeshSet<3>::face_t *, double> > > EdgeIntInfo;
|
||||
|
||||
typedef std::unordered_set<carve::mesh::MeshSet<3>::vertex_t *> VSet;
|
||||
typedef std::unordered_set<carve::mesh::MeshSet<3>::face_t *> FSet;
|
||||
typedef std::unordered_set<carve::mesh::MeshSet<3>::vertex_t *> VSet;
|
||||
typedef std::unordered_set<carve::mesh::MeshSet<3>::face_t *> FSet;
|
||||
|
||||
typedef std::set<carve::mesh::MeshSet<3>::vertex_t *> VSetSmall;
|
||||
typedef std::set<csg::V2> V2SetSmall;
|
||||
typedef std::set<carve::mesh::MeshSet<3>::face_t *> FSetSmall;
|
||||
typedef std::set<carve::mesh::MeshSet<3>::vertex_t *> VSetSmall;
|
||||
typedef std::set<csg::V2> V2SetSmall;
|
||||
typedef std::set<carve::mesh::MeshSet<3>::face_t *> FSetSmall;
|
||||
|
||||
typedef std::unordered_map<carve::mesh::MeshSet<3>::vertex_t *, VSetSmall> VVSMap;
|
||||
typedef std::unordered_map<carve::mesh::MeshSet<3>::edge_t *, VSetSmall> EVSMap;
|
||||
typedef std::unordered_map<carve::mesh::MeshSet<3>::face_t *, VSetSmall> FVSMap;
|
||||
typedef std::unordered_map<carve::mesh::MeshSet<3>::vertex_t *, VSetSmall> VVSMap;
|
||||
typedef std::unordered_map<carve::mesh::MeshSet<3>::edge_t *, EdgeIntInfo> EIntMap;
|
||||
typedef std::unordered_map<carve::mesh::MeshSet<3>::face_t *, VSetSmall> FVSMap;
|
||||
|
||||
typedef std::unordered_map<carve::mesh::MeshSet<3>::vertex_t *, FSetSmall> VFSMap;
|
||||
typedef std::unordered_map<carve::mesh::MeshSet<3>::face_t *, V2SetSmall> FV2SMap;
|
||||
typedef std::unordered_map<carve::mesh::MeshSet<3>::vertex_t *, FSetSmall> VFSMap;
|
||||
typedef std::unordered_map<carve::mesh::MeshSet<3>::face_t *, V2SetSmall> FV2SMap;
|
||||
|
||||
typedef std::unordered_map<
|
||||
carve::mesh::MeshSet<3>::edge_t *,
|
||||
std::vector<carve::mesh::MeshSet<3>::vertex_t *> > EVVMap;
|
||||
typedef std::unordered_map<
|
||||
carve::mesh::MeshSet<3>::edge_t *,
|
||||
std::vector<carve::mesh::MeshSet<3>::vertex_t *> > EVVMap;
|
||||
|
||||
typedef std::unordered_map<carve::mesh::MeshSet<3>::vertex_t *,
|
||||
std::vector<carve::mesh::MeshSet<3>::edge_t *> > VEVecMap;
|
||||
|
||||
|
||||
class LoopEdges : public std::unordered_map<V2, std::list<FaceLoop *> > {
|
||||
class LoopEdges : public std::unordered_map<V2, std::list<FaceLoop *> > {
|
||||
typedef std::unordered_map<V2, std::list<FaceLoop *> > super;
|
||||
|
||||
public:
|
||||
|
||||
291
extern/carve/lib/intersect.cpp
vendored
291
extern/carve/lib/intersect.cpp
vendored
@@ -41,6 +41,7 @@
|
||||
#include <carve/timing.hpp>
|
||||
#include <carve/colour.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
|
||||
@@ -114,7 +115,7 @@ namespace {
|
||||
ordered_vertices.reserve(std::distance(beg, end));
|
||||
|
||||
for (; beg != end; ++beg) {
|
||||
carve::mesh::MeshSet<3>::vertex_t *v = (*beg);
|
||||
carve::mesh::MeshSet<3>::vertex_t *v = *beg;
|
||||
ordered_vertices.push_back(std::make_pair(carve::geom::dot(v->v - base, dir), v));
|
||||
}
|
||||
|
||||
@@ -130,6 +131,37 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
template<typename iter_t>
|
||||
void orderEdgeIntersectionVertices(iter_t beg, const iter_t end,
|
||||
const carve::mesh::MeshSet<3>::vertex_t::vector_t &dir,
|
||||
const carve::mesh::MeshSet<3>::vertex_t::vector_t &base,
|
||||
std::vector<carve::mesh::MeshSet<3>::vertex_t *> &out) {
|
||||
typedef std::vector<std::pair<std::pair<double, double>, carve::mesh::MeshSet<3>::vertex_t *> > DVVector;
|
||||
DVVector ordered_vertices;
|
||||
|
||||
ordered_vertices.reserve(std::distance(beg, end));
|
||||
|
||||
for (; beg != end; ++beg) {
|
||||
carve::mesh::MeshSet<3>::vertex_t *v = (*beg).first;
|
||||
double ovec = 0.0;
|
||||
for (carve::csg::detail::EdgeIntInfo::mapped_type::const_iterator j = (*beg).second.begin(); j != (*beg).second.end(); ++j) {
|
||||
ovec += (*j).second;
|
||||
}
|
||||
ordered_vertices.push_back(std::make_pair(std::make_pair(carve::geom::dot(v->v - base, dir), -ovec), v));
|
||||
}
|
||||
|
||||
std::sort(ordered_vertices.begin(), ordered_vertices.end());
|
||||
|
||||
out.clear();
|
||||
out.reserve(ordered_vertices.size());
|
||||
for (DVVector::const_iterator
|
||||
i = ordered_vertices.begin(), e = ordered_vertices.end();
|
||||
i != e;
|
||||
++i) {
|
||||
out.push_back((*i).second);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@@ -346,7 +378,7 @@ bool carve::csg::CSG::Hooks::hasHook(unsigned hook_num) {
|
||||
return hooks[hook_num].size() > 0;
|
||||
}
|
||||
|
||||
void carve::csg::CSG::Hooks::intersectionVertex(const carve::mesh::MeshSet<3>::vertex_t *vertex,
|
||||
void carve::csg::CSG::Hooks::intersectionVertex(const meshset_t::vertex_t *vertex,
|
||||
const IObjPairSet &intersections) {
|
||||
for (std::list<Hook *>::iterator j = hooks[INTERSECTION_VERTEX_HOOK].begin();
|
||||
j != hooks[INTERSECTION_VERTEX_HOOK].end();
|
||||
@@ -355,8 +387,8 @@ void carve::csg::CSG::Hooks::intersectionVertex(const carve::mesh::MeshSet<3>::v
|
||||
}
|
||||
}
|
||||
|
||||
void carve::csg::CSG::Hooks::processOutputFace(std::vector<carve::mesh::MeshSet<3>::face_t *> &faces,
|
||||
const carve::mesh::MeshSet<3>::face_t *orig_face,
|
||||
void carve::csg::CSG::Hooks::processOutputFace(std::vector<meshset_t::face_t *> &faces,
|
||||
const meshset_t::face_t *orig_face,
|
||||
bool flipped) {
|
||||
for (std::list<Hook *>::iterator j = hooks[PROCESS_OUTPUT_FACE_HOOK].begin();
|
||||
j != hooks[PROCESS_OUTPUT_FACE_HOOK].end();
|
||||
@@ -365,8 +397,8 @@ void carve::csg::CSG::Hooks::processOutputFace(std::vector<carve::mesh::MeshSet<
|
||||
}
|
||||
}
|
||||
|
||||
void carve::csg::CSG::Hooks::resultFace(const carve::mesh::MeshSet<3>::face_t *new_face,
|
||||
const carve::mesh::MeshSet<3>::face_t *orig_face,
|
||||
void carve::csg::CSG::Hooks::resultFace(const meshset_t::face_t *new_face,
|
||||
const meshset_t::face_t *orig_face,
|
||||
bool flipped) {
|
||||
for (std::list<Hook *>::iterator j = hooks[RESULT_FACE_HOOK].begin();
|
||||
j != hooks[RESULT_FACE_HOOK].end();
|
||||
@@ -425,7 +457,7 @@ void carve::csg::CSG::makeVertexIntersections() {
|
||||
j != je;
|
||||
++j) {
|
||||
const IObj &i_tgt = ((*j).first);
|
||||
carve::mesh::MeshSet<3>::vertex_t *i_pt = ((*j).second);
|
||||
meshset_t::vertex_t *i_pt = ((*j).second);
|
||||
|
||||
vertex_intersections[i_pt].insert(std::make_pair(i_src, i_tgt));
|
||||
}
|
||||
@@ -499,7 +531,7 @@ void carve::csg::CSG::groupIntersections() {
|
||||
|
||||
carve::TimingBlock block(GROUP_INTERSECTONS);
|
||||
|
||||
std::vector<carve::mesh::MeshSet<3>::vertex_t *> vertices;
|
||||
std::vector<meshset_t::vertex_t *> vertices;
|
||||
detail::VVSMap graph;
|
||||
#if defined(CARVE_DEBUG)
|
||||
std::cerr << "groupIntersections()" << ": vertex_intersections.size()==" << vertex_intersections.size() << std::endl;
|
||||
@@ -521,7 +553,7 @@ void carve::csg::CSG::groupIntersections() {
|
||||
|
||||
vertex_intersections_octree.addVertices(vertices);
|
||||
|
||||
std::vector<carve::mesh::MeshSet<3>::vertex_t *> out;
|
||||
std::vector<meshset_t::vertex_t *> out;
|
||||
for (size_t i = 0, l = vertices.size(); i != l; ++i) {
|
||||
// let's find all the vertices near this one.
|
||||
out.clear();
|
||||
@@ -546,7 +578,7 @@ void carve::csg::CSG::groupIntersections() {
|
||||
open.insert((*i).first);
|
||||
while (open.size()) {
|
||||
detail::VSet::iterator t = open.begin();
|
||||
const carve::mesh::MeshSet<3>::vertex_t *o = (*t);
|
||||
const meshset_t::vertex_t *o = (*t);
|
||||
open.erase(t);
|
||||
i = graph.find(o);
|
||||
CARVE_ASSERT(i != graph.end());
|
||||
@@ -568,6 +600,19 @@ void carve::csg::CSG::groupIntersections() {
|
||||
}
|
||||
|
||||
|
||||
static void recordEdgeIntersectionInfo(carve::mesh::MeshSet<3>::vertex_t *intersection,
|
||||
carve::mesh::MeshSet<3>::edge_t *edge,
|
||||
const carve::csg::detail::VFSMap::mapped_type &intersected_faces,
|
||||
carve::csg::detail::Data &data) {
|
||||
carve::mesh::MeshSet<3>::vertex_t::vector_t edge_dir = edge->v2()->v - edge->v1()->v;
|
||||
carve::csg::detail::EdgeIntInfo::mapped_type &eint_info = data.emap[edge][intersection];
|
||||
|
||||
for (carve::csg::detail::VFSMap::mapped_type::const_iterator i = intersected_faces.begin(); i != intersected_faces.end(); ++i) {
|
||||
carve::mesh::MeshSet<3>::vertex_t::vector_t normal = (*i)->plane.N;
|
||||
eint_info.insert(std::make_pair((*i), carve::geom::dot(edge_dir, normal)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void carve::csg::CSG::intersectingFacePairs(detail::Data &data) {
|
||||
static carve::TimingName FUNC_NAME("CSG::intersectingFacePairs()");
|
||||
@@ -575,30 +620,36 @@ void carve::csg::CSG::intersectingFacePairs(detail::Data &data) {
|
||||
|
||||
// iterate over all intersection points.
|
||||
for (VertexIntersections::const_iterator i = vertex_intersections.begin(), ie = vertex_intersections.end(); i != ie; ++i) {
|
||||
carve::mesh::MeshSet<3>::vertex_t *i_pt = ((*i).first);
|
||||
meshset_t::vertex_t *i_pt = ((*i).first);
|
||||
detail::VFSMap::mapped_type &face_set = (data.fmap_rev[i_pt]);
|
||||
|
||||
detail::VFSMap::mapped_type src_face_set;
|
||||
detail::VFSMap::mapped_type tgt_face_set;
|
||||
// for all pairs of intersecting objects at this point
|
||||
for (VertexIntersections::data_type::const_iterator j = (*i).second.begin(), je = (*i).second.end(); j != je; ++j) {
|
||||
const IObj &i_src = ((*j).first);
|
||||
const IObj &i_tgt = ((*j).second);
|
||||
|
||||
// work out the faces involved. this updates fmap_rev.
|
||||
facesForObject(i_src, data.vert_to_edges, face_set);
|
||||
facesForObject(i_tgt, data.vert_to_edges, face_set);
|
||||
src_face_set.clear();
|
||||
tgt_face_set.clear();
|
||||
// work out the faces involved.
|
||||
facesForObject(i_src, data.vert_to_edges, src_face_set);
|
||||
facesForObject(i_tgt, data.vert_to_edges, tgt_face_set);
|
||||
// this updates fmap_rev.
|
||||
std::copy(src_face_set.begin(), src_face_set.end(), set_inserter(face_set));
|
||||
std::copy(tgt_face_set.begin(), tgt_face_set.end(), set_inserter(face_set));
|
||||
|
||||
// record the intersection with respect to any involved vertex.
|
||||
if (i_src.obtype == IObj::OBTYPE_VERTEX) data.vmap[i_src.vertex] = i_pt;
|
||||
if (i_tgt.obtype == IObj::OBTYPE_VERTEX) data.vmap[i_tgt.vertex] = i_pt;
|
||||
|
||||
// record the intersection with respect to any involved edge.
|
||||
if (i_src.obtype == IObj::OBTYPE_EDGE) data.emap[i_src.edge].insert(i_pt);
|
||||
if (i_tgt.obtype == IObj::OBTYPE_EDGE) data.emap[i_tgt.edge].insert(i_pt);
|
||||
if (i_src.obtype == IObj::OBTYPE_EDGE) recordEdgeIntersectionInfo(i_pt, i_src.edge, tgt_face_set, data);
|
||||
if (i_tgt.obtype == IObj::OBTYPE_EDGE) recordEdgeIntersectionInfo(i_pt, i_tgt.edge, src_face_set, data);
|
||||
}
|
||||
|
||||
// record the intersection with respect to each face.
|
||||
for (carve::csg::detail::VFSMap::mapped_type::const_iterator k = face_set.begin(), ke = face_set.end(); k != ke; ++k) {
|
||||
carve::mesh::MeshSet<3>::face_t *f = (*k);
|
||||
meshset_t::face_t *f = (*k);
|
||||
data.fmap[f].insert(i_pt);
|
||||
}
|
||||
}
|
||||
@@ -606,8 +657,8 @@ void carve::csg::CSG::intersectingFacePairs(detail::Data &data) {
|
||||
|
||||
|
||||
|
||||
void carve::csg::CSG::_generateVertexVertexIntersections(carve::mesh::MeshSet<3>::vertex_t *va,
|
||||
carve::mesh::MeshSet<3>::edge_t *eb) {
|
||||
void carve::csg::CSG::_generateVertexVertexIntersections(meshset_t::vertex_t *va,
|
||||
meshset_t::edge_t *eb) {
|
||||
if (intersections.intersects(va, eb->v1())) {
|
||||
return;
|
||||
}
|
||||
@@ -621,14 +672,14 @@ void carve::csg::CSG::_generateVertexVertexIntersections(carve::mesh::MeshSet<3>
|
||||
|
||||
|
||||
|
||||
void carve::csg::CSG::generateVertexVertexIntersections(carve::mesh::MeshSet<3>::face_t *a,
|
||||
const std::vector<carve::mesh::MeshSet<3>::face_t *> &b) {
|
||||
carve::mesh::MeshSet<3>::edge_t *ea, *eb;
|
||||
void carve::csg::CSG::generateVertexVertexIntersections(meshset_t::face_t *a,
|
||||
const std::vector<meshset_t::face_t *> &b) {
|
||||
meshset_t::edge_t *ea, *eb;
|
||||
|
||||
ea = a->edge;
|
||||
do {
|
||||
for (size_t i = 0; i < b.size(); ++i) {
|
||||
carve::mesh::MeshSet<3>::face_t *t = b[i];
|
||||
meshset_t::face_t *t = b[i];
|
||||
eb = t->edge;
|
||||
do {
|
||||
_generateVertexVertexIntersections(ea->v1(), eb);
|
||||
@@ -641,8 +692,8 @@ void carve::csg::CSG::generateVertexVertexIntersections(carve::mesh::MeshSet<3>:
|
||||
|
||||
|
||||
|
||||
void carve::csg::CSG::_generateVertexEdgeIntersections(carve::mesh::MeshSet<3>::vertex_t *va,
|
||||
carve::mesh::MeshSet<3>::edge_t *eb) {
|
||||
void carve::csg::CSG::_generateVertexEdgeIntersections(meshset_t::vertex_t *va,
|
||||
meshset_t::edge_t *eb) {
|
||||
if (intersections.intersects(va, eb)) {
|
||||
return;
|
||||
}
|
||||
@@ -665,14 +716,14 @@ void carve::csg::CSG::_generateVertexEdgeIntersections(carve::mesh::MeshSet<3>::
|
||||
|
||||
|
||||
|
||||
void carve::csg::CSG::generateVertexEdgeIntersections(carve::mesh::MeshSet<3>::face_t *a,
|
||||
const std::vector<carve::mesh::MeshSet<3>::face_t *> &b) {
|
||||
carve::mesh::MeshSet<3>::edge_t *ea, *eb;
|
||||
void carve::csg::CSG::generateVertexEdgeIntersections(meshset_t::face_t *a,
|
||||
const std::vector<meshset_t::face_t *> &b) {
|
||||
meshset_t::edge_t *ea, *eb;
|
||||
|
||||
ea = a->edge;
|
||||
do {
|
||||
for (size_t i = 0; i < b.size(); ++i) {
|
||||
carve::mesh::MeshSet<3>::face_t *t = b[i];
|
||||
meshset_t::face_t *t = b[i];
|
||||
eb = t->edge;
|
||||
do {
|
||||
_generateVertexEdgeIntersections(ea->v1(), eb);
|
||||
@@ -685,21 +736,21 @@ void carve::csg::CSG::generateVertexEdgeIntersections(carve::mesh::MeshSet<3>::f
|
||||
|
||||
|
||||
|
||||
void carve::csg::CSG::_generateEdgeEdgeIntersections(carve::mesh::MeshSet<3>::edge_t *ea,
|
||||
carve::mesh::MeshSet<3>::edge_t *eb) {
|
||||
void carve::csg::CSG::_generateEdgeEdgeIntersections(meshset_t::edge_t *ea,
|
||||
meshset_t::edge_t *eb) {
|
||||
if (intersections.intersects(ea, eb)) {
|
||||
return;
|
||||
}
|
||||
|
||||
carve::mesh::MeshSet<3>::vertex_t *v1 = ea->v1(), *v2 = ea->v2();
|
||||
carve::mesh::MeshSet<3>::vertex_t *v3 = eb->v1(), *v4 = eb->v2();
|
||||
meshset_t::vertex_t *v1 = ea->v1(), *v2 = ea->v2();
|
||||
meshset_t::vertex_t *v3 = eb->v1(), *v4 = eb->v2();
|
||||
|
||||
carve::geom::aabb<3> ea_aabb, eb_aabb;
|
||||
ea_aabb.fit(v1->v, v2->v);
|
||||
eb_aabb.fit(v3->v, v4->v);
|
||||
if (ea_aabb.maxAxisSeparation(eb_aabb) > EPSILON) return;
|
||||
|
||||
carve::mesh::MeshSet<3>::vertex_t::vector_t p1, p2;
|
||||
meshset_t::vertex_t::vector_t p1, p2;
|
||||
double mu1, mu2;
|
||||
|
||||
switch (carve::geom3d::rayRayIntersection(carve::geom3d::Ray(v2->v - v1->v, v1->v),
|
||||
@@ -708,7 +759,7 @@ void carve::csg::CSG::_generateEdgeEdgeIntersections(carve::mesh::MeshSet<3>::ed
|
||||
case carve::RR_INTERSECTION: {
|
||||
// edges intersect
|
||||
if (mu1 >= 0.0 && mu1 <= 1.0 && mu2 >= 0.0 && mu2 <= 1.0) {
|
||||
carve::mesh::MeshSet<3>::vertex_t *p = vertex_pool.get((p1 + p2) / 2.0);
|
||||
meshset_t::vertex_t *p = vertex_pool.get((p1 + p2) / 2.0);
|
||||
intersections.record(ea, eb, p);
|
||||
if (ea->rev) intersections.record(ea->rev, eb, p);
|
||||
if (eb->rev) intersections.record(ea, eb->rev, p);
|
||||
@@ -733,14 +784,14 @@ void carve::csg::CSG::_generateEdgeEdgeIntersections(carve::mesh::MeshSet<3>::ed
|
||||
|
||||
|
||||
|
||||
void carve::csg::CSG::generateEdgeEdgeIntersections(carve::mesh::MeshSet<3>::face_t *a,
|
||||
const std::vector<carve::mesh::MeshSet<3>::face_t *> &b) {
|
||||
carve::mesh::MeshSet<3>::edge_t *ea, *eb;
|
||||
void carve::csg::CSG::generateEdgeEdgeIntersections(meshset_t::face_t *a,
|
||||
const std::vector<meshset_t::face_t *> &b) {
|
||||
meshset_t::edge_t *ea, *eb;
|
||||
|
||||
ea = a->edge;
|
||||
do {
|
||||
for (size_t i = 0; i < b.size(); ++i) {
|
||||
carve::mesh::MeshSet<3>::face_t *t = b[i];
|
||||
meshset_t::face_t *t = b[i];
|
||||
eb = t->edge;
|
||||
do {
|
||||
_generateEdgeEdgeIntersections(ea, eb);
|
||||
@@ -753,8 +804,8 @@ void carve::csg::CSG::generateEdgeEdgeIntersections(carve::mesh::MeshSet<3>::fac
|
||||
|
||||
|
||||
|
||||
void carve::csg::CSG::_generateVertexFaceIntersections(carve::mesh::MeshSet<3>::face_t *fa,
|
||||
carve::mesh::MeshSet<3>::edge_t *eb) {
|
||||
void carve::csg::CSG::_generateVertexFaceIntersections(meshset_t::face_t *fa,
|
||||
meshset_t::edge_t *eb) {
|
||||
if (intersections.intersects(eb->v1(), fa)) {
|
||||
return;
|
||||
}
|
||||
@@ -769,12 +820,12 @@ void carve::csg::CSG::_generateVertexFaceIntersections(carve::mesh::MeshSet<3>::
|
||||
|
||||
|
||||
|
||||
void carve::csg::CSG::generateVertexFaceIntersections(carve::mesh::MeshSet<3>::face_t *a,
|
||||
const std::vector<carve::mesh::MeshSet<3>::face_t *> &b) {
|
||||
carve::mesh::MeshSet<3>::edge_t *ea, *eb;
|
||||
void carve::csg::CSG::generateVertexFaceIntersections(meshset_t::face_t *a,
|
||||
const std::vector<meshset_t::face_t *> &b) {
|
||||
meshset_t::edge_t *eb;
|
||||
|
||||
for (size_t i = 0; i < b.size(); ++i) {
|
||||
carve::mesh::MeshSet<3>::face_t *t = b[i];
|
||||
meshset_t::face_t *t = b[i];
|
||||
eb = t->edge;
|
||||
do {
|
||||
_generateVertexFaceIntersections(a, eb);
|
||||
@@ -785,15 +836,15 @@ void carve::csg::CSG::generateVertexFaceIntersections(carve::mesh::MeshSet<3>::f
|
||||
|
||||
|
||||
|
||||
void carve::csg::CSG::_generateEdgeFaceIntersections(carve::mesh::MeshSet<3>::face_t *fa,
|
||||
carve::mesh::MeshSet<3>::edge_t *eb) {
|
||||
void carve::csg::CSG::_generateEdgeFaceIntersections(meshset_t::face_t *fa,
|
||||
meshset_t::edge_t *eb) {
|
||||
if (intersections.intersects(eb, fa)) {
|
||||
return;
|
||||
}
|
||||
|
||||
carve::mesh::MeshSet<3>::vertex_t::vector_t _p;
|
||||
meshset_t::vertex_t::vector_t _p;
|
||||
if (fa->simpleLineSegmentIntersection(carve::geom3d::LineSegment(eb->v1()->v, eb->v2()->v), _p)) {
|
||||
carve::mesh::MeshSet<3>::vertex_t *p = vertex_pool.get(_p);
|
||||
meshset_t::vertex_t *p = vertex_pool.get(_p);
|
||||
intersections.record(eb, fa, p);
|
||||
if (eb->rev) intersections.record(eb->rev, fa, p);
|
||||
}
|
||||
@@ -801,12 +852,12 @@ void carve::csg::CSG::_generateEdgeFaceIntersections(carve::mesh::MeshSet<3>::fa
|
||||
|
||||
|
||||
|
||||
void carve::csg::CSG::generateEdgeFaceIntersections(carve::mesh::MeshSet<3>::face_t *a,
|
||||
const std::vector<carve::mesh::MeshSet<3>::face_t *> &b) {
|
||||
carve::mesh::MeshSet<3>::edge_t *ea, *eb;
|
||||
void carve::csg::CSG::generateEdgeFaceIntersections(meshset_t::face_t *a,
|
||||
const std::vector<meshset_t::face_t *> &b) {
|
||||
meshset_t::edge_t *eb;
|
||||
|
||||
for (size_t i = 0; i < b.size(); ++i) {
|
||||
carve::mesh::MeshSet<3>::face_t *t = b[i];
|
||||
meshset_t::face_t *t = b[i];
|
||||
eb = t->edge;
|
||||
do {
|
||||
_generateEdgeFaceIntersections(a, eb);
|
||||
@@ -817,9 +868,9 @@ void carve::csg::CSG::generateEdgeFaceIntersections(carve::mesh::MeshSet<3>::fac
|
||||
|
||||
|
||||
|
||||
void carve::csg::CSG::generateIntersectionCandidates(carve::mesh::MeshSet<3> *a,
|
||||
void carve::csg::CSG::generateIntersectionCandidates(meshset_t *a,
|
||||
const face_rtree_t *a_node,
|
||||
carve::mesh::MeshSet<3> *b,
|
||||
meshset_t *b,
|
||||
const face_rtree_t *b_node,
|
||||
face_pairs_t &face_pairs,
|
||||
bool descend_a) {
|
||||
@@ -837,12 +888,12 @@ void carve::csg::CSG::generateIntersectionCandidates(carve::mesh::MeshSet<3> *a,
|
||||
}
|
||||
} else {
|
||||
for (size_t i = 0; i < a_node->data.size(); ++i) {
|
||||
carve::mesh::MeshSet<3>::face_t *fa = a_node->data[i];
|
||||
meshset_t::face_t *fa = a_node->data[i];
|
||||
carve::geom::aabb<3> aabb_a = fa->getAABB();
|
||||
if (aabb_a.maxAxisSeparation(b_node->bbox) > carve::EPSILON) continue;
|
||||
|
||||
for (size_t j = 0; j < b_node->data.size(); ++j) {
|
||||
carve::mesh::MeshSet<3>::face_t *fb = b_node->data[j];
|
||||
meshset_t::face_t *fb = b_node->data[j];
|
||||
carve::geom::aabb<3> aabb_b = fb->getAABB();
|
||||
if (aabb_b.maxAxisSeparation(aabb_a) > carve::EPSILON) continue;
|
||||
|
||||
@@ -866,17 +917,17 @@ void carve::csg::CSG::generateIntersectionCandidates(carve::mesh::MeshSet<3> *a,
|
||||
|
||||
|
||||
|
||||
void carve::csg::CSG::generateIntersections(carve::mesh::MeshSet<3> *a,
|
||||
void carve::csg::CSG::generateIntersections(meshset_t *a,
|
||||
const face_rtree_t *a_rtree,
|
||||
carve::mesh::MeshSet<3> *b,
|
||||
meshset_t *b,
|
||||
const face_rtree_t *b_rtree,
|
||||
detail::Data &data) {
|
||||
face_pairs_t face_pairs;
|
||||
generateIntersectionCandidates(a, a_rtree, b, b_rtree, face_pairs);
|
||||
|
||||
for (face_pairs_t::const_iterator i = face_pairs.begin(); i != face_pairs.end(); ++i) {
|
||||
carve::mesh::MeshSet<3>::face_t *f = (*i).first;
|
||||
carve::mesh::MeshSet<3>::edge_t *e = f->edge;
|
||||
meshset_t::face_t *f = (*i).first;
|
||||
meshset_t::edge_t *e = f->edge;
|
||||
do {
|
||||
data.vert_to_edges[e->v1()].push_back(e);
|
||||
e = e->next;
|
||||
@@ -958,13 +1009,13 @@ void carve::csg::CSG::divideIntersectedEdges(detail::Data &data) {
|
||||
static carve::TimingName FUNC_NAME("CSG::divideIntersectedEdges()");
|
||||
carve::TimingBlock block(FUNC_NAME);
|
||||
|
||||
for (detail::EVSMap::const_iterator i = data.emap.begin(), ei = data.emap.end(); i != ei; ++i) {
|
||||
carve::mesh::MeshSet<3>::edge_t *edge = (*i).first;
|
||||
const detail::EVSMap::mapped_type &vertices = (*i).second;
|
||||
std::vector<carve::mesh::MeshSet<3>::vertex_t *> &verts = data.divided_edges[edge];
|
||||
orderVertices(vertices.begin(), vertices.end(),
|
||||
edge->v2()->v - edge->v1()->v, edge->v1()->v,
|
||||
verts);
|
||||
for (detail::EIntMap::const_iterator i = data.emap.begin(), ei = data.emap.end(); i != ei; ++i) {
|
||||
meshset_t::edge_t *edge = (*i).first;
|
||||
const detail::EIntMap::mapped_type &int_info = (*i).second;
|
||||
std::vector<meshset_t::vertex_t *> &verts = data.divided_edges[edge];
|
||||
orderEdgeIntersectionVertices(int_info.begin(), int_info.end(),
|
||||
edge->v2()->v - edge->v1()->v, edge->v1()->v,
|
||||
verts);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -982,7 +1033,7 @@ void carve::csg::CSG::makeFaceEdges(carve::csg::EdgeClassification &eclass,
|
||||
i = data.fmap.begin(), ie = data.fmap.end();
|
||||
i != ie;
|
||||
++i) {
|
||||
carve::mesh::MeshSet<3>::face_t *face_a = (*i).first;
|
||||
meshset_t::face_t *face_a = (*i).first;
|
||||
const detail::FVSMap::mapped_type &face_a_intersections = ((*i).second);
|
||||
face_b_set.clear();
|
||||
|
||||
@@ -995,7 +1046,7 @@ void carve::csg::CSG::makeFaceEdges(carve::csg::EdgeClassification &eclass,
|
||||
k = data.fmap_rev[*j].begin(), ke = data.fmap_rev[*j].end();
|
||||
k != ke;
|
||||
++k) {
|
||||
carve::mesh::MeshSet<3>::face_t *face_b = (*k);
|
||||
meshset_t::face_t *face_b = (*k);
|
||||
if (face_a != face_b && face_b->mesh->meshset != face_a->mesh->meshset) {
|
||||
face_b_set.insert(face_b);
|
||||
}
|
||||
@@ -1007,10 +1058,10 @@ void carve::csg::CSG::makeFaceEdges(carve::csg::EdgeClassification &eclass,
|
||||
j = face_b_set.begin(), je = face_b_set.end();
|
||||
j != je;
|
||||
++j) {
|
||||
carve::mesh::MeshSet<3>::face_t *face_b = (*j);
|
||||
meshset_t::face_t *face_b = (*j);
|
||||
const detail::FVSMap::mapped_type &face_b_intersections = (data.fmap[face_b]);
|
||||
|
||||
std::vector<carve::mesh::MeshSet<3>::vertex_t *> vertices;
|
||||
std::vector<meshset_t::vertex_t *> vertices;
|
||||
vertices.reserve(std::min(face_a_intersections.size(), face_b_intersections.size()));
|
||||
|
||||
// record the points of intersection between face_a and face_b
|
||||
@@ -1024,7 +1075,7 @@ void carve::csg::CSG::makeFaceEdges(carve::csg::EdgeClassification &eclass,
|
||||
std::cerr << "face pair: "
|
||||
<< face_a << ":" << face_b
|
||||
<< " N(verts) " << vertices.size() << std::endl;
|
||||
for (std::vector<carve::mesh::MeshSet<3>::vertex_t *>::const_iterator i = vertices.begin(), e = vertices.end(); i != e; ++i) {
|
||||
for (std::vector<meshset_t::vertex_t *>::const_iterator i = vertices.begin(), e = vertices.end(); i != e; ++i) {
|
||||
std::cerr << (*i) << " " << (*i)->v << " ("
|
||||
<< carve::geom::distance(face_a->plane, (*i)->v) << ","
|
||||
<< carve::geom::distance(face_b->plane, (*i)->v) << ")"
|
||||
@@ -1036,8 +1087,8 @@ void carve::csg::CSG::makeFaceEdges(carve::csg::EdgeClassification &eclass,
|
||||
|
||||
// if there are two points of intersection, then the added edge is simple to determine.
|
||||
if (vertices.size() == 2) {
|
||||
carve::mesh::MeshSet<3>::vertex_t *v1 = vertices[0];
|
||||
carve::mesh::MeshSet<3>::vertex_t *v2 = vertices[1];
|
||||
meshset_t::vertex_t *v1 = vertices[0];
|
||||
meshset_t::vertex_t *v2 = vertices[1];
|
||||
carve::geom3d::Vector c = (v1->v + v2->v) / 2;
|
||||
|
||||
// determine whether the midpoint of the implied edge is contained in face_a and face_b
|
||||
@@ -1065,7 +1116,7 @@ void carve::csg::CSG::makeFaceEdges(carve::csg::EdgeClassification &eclass,
|
||||
|
||||
// otherwise, it's more complex.
|
||||
carve::geom3d::Vector base, dir;
|
||||
std::vector<carve::mesh::MeshSet<3>::vertex_t *> ordered;
|
||||
std::vector<meshset_t::vertex_t *> ordered;
|
||||
|
||||
// skip coplanar edges. this simplifies the resulting
|
||||
// mesh. eventually all coplanar face regions of two polyhedra
|
||||
@@ -1080,8 +1131,8 @@ void carve::csg::CSG::makeFaceEdges(carve::csg::EdgeClassification &eclass,
|
||||
// for each possible edge in the ordering, test the midpoint,
|
||||
// and record if it's contained in face_a and face_b.
|
||||
for (int k = 0, ke = (int)ordered.size() - 1; k < ke; ++k) {
|
||||
carve::mesh::MeshSet<3>::vertex_t *v1 = ordered[k];
|
||||
carve::mesh::MeshSet<3>::vertex_t *v2 = ordered[k + 1];
|
||||
meshset_t::vertex_t *v1 = ordered[k];
|
||||
meshset_t::vertex_t *v2 = ordered[k + 1];
|
||||
carve::geom3d::Vector c = (v1->v + v2->v) / 2;
|
||||
|
||||
#if defined(CARVE_DEBUG)
|
||||
@@ -1125,7 +1176,7 @@ void carve::csg::CSG::makeFaceEdges(carve::csg::EdgeClassification &eclass,
|
||||
|
||||
carve::line::PolylineSet intersection_graph;
|
||||
intersection_graph.vertices.resize(vertices.size());
|
||||
std::map<const carve::mesh::MeshSet<3>::vertex_t *, size_t> vmap;
|
||||
std::map<const meshset_t::vertex_t *, size_t> vmap;
|
||||
|
||||
size_t j = 0;
|
||||
for (detail::VSet::const_iterator i = vertices.begin(); i != vertices.end(); ++i) {
|
||||
@@ -1195,9 +1246,9 @@ static void checkFaceLoopIntegrity(carve::csg::FaceLoopList &fll) {
|
||||
* @param b_edge_count
|
||||
* @param hooks
|
||||
*/
|
||||
void carve::csg::CSG::calc(carve::mesh::MeshSet<3> *a,
|
||||
void carve::csg::CSG::calc(meshset_t *a,
|
||||
const face_rtree_t *a_rtree,
|
||||
carve::mesh::MeshSet<3> *b,
|
||||
meshset_t *b,
|
||||
const face_rtree_t *b_rtree,
|
||||
carve::csg::VertexClassification &vclass,
|
||||
carve::csg::EdgeClassification &eclass,
|
||||
@@ -1260,12 +1311,12 @@ void carve::csg::CSG::calc(carve::mesh::MeshSet<3> *a,
|
||||
|
||||
#if defined(CARVE_DEBUG_WRITE_PLY_DATA)
|
||||
{
|
||||
std::string out("/tmp/a_split.ply");
|
||||
writePLY(out, faceLoopsToPolyhedron(a_face_loops), false);
|
||||
std::auto_ptr<carve::mesh::MeshSet<3> > poly(faceLoopsToPolyhedron(a_face_loops));
|
||||
writePLY("/tmp/a_split.ply", poly.get(), false);
|
||||
}
|
||||
{
|
||||
std::string out("/tmp/b_split.ply");
|
||||
writePLY(out, faceLoopsToPolyhedron(b_face_loops), false);
|
||||
std::auto_ptr<carve::mesh::MeshSet<3> > poly(faceLoopsToPolyhedron(b_face_loops));
|
||||
writePLY("/tmp/b_split.ply", poly.get(), false);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1276,11 +1327,11 @@ void carve::csg::CSG::calc(carve::mesh::MeshSet<3> *a,
|
||||
std::cerr << "classify" << std::endl;
|
||||
#endif
|
||||
// initialize some classification information.
|
||||
for (std::vector<carve::mesh::MeshSet<3>::vertex_t>::iterator
|
||||
for (std::vector<meshset_t::vertex_t>::iterator
|
||||
i = a->vertex_storage.begin(), e = a->vertex_storage.end(); i != e; ++i) {
|
||||
vclass[map_vertex(data.vmap, &(*i))].cls[0] = POINT_ON;
|
||||
}
|
||||
for (std::vector<carve::mesh::MeshSet<3>::vertex_t>::iterator
|
||||
for (std::vector<meshset_t::vertex_t>::iterator
|
||||
i = b->vertex_storage.begin(), e = b->vertex_storage.end(); i != e; ++i) {
|
||||
vclass[map_vertex(data.vmap, &(*i))].cls[1] = POINT_ON;
|
||||
}
|
||||
@@ -1351,8 +1402,8 @@ void returnSharedEdges(carve::csg::V2Set &shared_edges,
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
carve::mesh::MeshSet<3> *carve::csg::CSG::compute(carve::mesh::MeshSet<3> *a,
|
||||
carve::mesh::MeshSet<3> *b,
|
||||
carve::mesh::MeshSet<3> *carve::csg::CSG::compute(meshset_t *a,
|
||||
meshset_t *b,
|
||||
carve::csg::CSG::Collector &collector,
|
||||
carve::csg::V2Set *shared_edges_ptr,
|
||||
CLASSIFY_TYPE classify_type) {
|
||||
@@ -1371,13 +1422,13 @@ carve::mesh::MeshSet<3> *carve::csg::CSG::compute(carve::mesh::MeshSet<3> *a,
|
||||
size_t a_edge_count;
|
||||
size_t b_edge_count;
|
||||
|
||||
face_rtree_t *a_rtree = face_rtree_t::construct_STR(a->faceBegin(), a->faceEnd(), 4, 4);
|
||||
face_rtree_t *b_rtree = face_rtree_t::construct_STR(b->faceBegin(), b->faceEnd(), 4, 4);
|
||||
std::auto_ptr<face_rtree_t> a_rtree(face_rtree_t::construct_STR(a->faceBegin(), a->faceEnd(), 4, 4));
|
||||
std::auto_ptr<face_rtree_t> b_rtree(face_rtree_t::construct_STR(b->faceBegin(), b->faceEnd(), 4, 4));
|
||||
|
||||
{
|
||||
static carve::TimingName FUNC_NAME("CSG::compute - calc()");
|
||||
carve::TimingBlock block(FUNC_NAME);
|
||||
calc(a, a_rtree, b, b_rtree, vclass, eclass,a_face_loops, b_face_loops, a_edge_count, b_edge_count);
|
||||
calc(a, a_rtree.get(), b, b_rtree.get(), vclass, eclass,a_face_loops, b_face_loops, a_edge_count, b_edge_count);
|
||||
}
|
||||
|
||||
detail::LoopEdges a_edge_map;
|
||||
@@ -1445,11 +1496,11 @@ carve::mesh::MeshSet<3> *carve::csg::CSG::compute(carve::mesh::MeshSet<3> *a,
|
||||
classifyFaceGroupsEdge(shared_edges,
|
||||
vclass,
|
||||
a,
|
||||
a_rtree,
|
||||
a_rtree.get(),
|
||||
a_loops_grouped,
|
||||
a_edge_map,
|
||||
b,
|
||||
b_rtree,
|
||||
b_rtree.get(),
|
||||
b_loops_grouped,
|
||||
b_edge_map,
|
||||
collector);
|
||||
@@ -1458,20 +1509,20 @@ carve::mesh::MeshSet<3> *carve::csg::CSG::compute(carve::mesh::MeshSet<3> *a,
|
||||
classifyFaceGroups(shared_edges,
|
||||
vclass,
|
||||
a,
|
||||
a_rtree,
|
||||
a_rtree.get(),
|
||||
a_loops_grouped,
|
||||
a_edge_map,
|
||||
b,
|
||||
b_rtree,
|
||||
b_rtree.get(),
|
||||
b_loops_grouped,
|
||||
b_edge_map,
|
||||
collector);
|
||||
break;
|
||||
}
|
||||
|
||||
carve::mesh::MeshSet<3> *result = collector.done(hooks);
|
||||
meshset_t *result = collector.done(hooks);
|
||||
if (result != NULL && shared_edges_ptr != NULL) {
|
||||
std::list<carve::mesh::MeshSet<3> *> result_list;
|
||||
std::list<meshset_t *> result_list;
|
||||
result_list.push_back(result);
|
||||
returnSharedEdges(shared_edges, result_list, shared_edges_ptr);
|
||||
}
|
||||
@@ -1492,15 +1543,15 @@ carve::mesh::MeshSet<3> *carve::csg::CSG::compute(carve::mesh::MeshSet<3> *a,
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
carve::mesh::MeshSet<3> *carve::csg::CSG::compute(carve::mesh::MeshSet<3> *a,
|
||||
carve::mesh::MeshSet<3> *b,
|
||||
carve::mesh::MeshSet<3> *carve::csg::CSG::compute(meshset_t *a,
|
||||
meshset_t *b,
|
||||
carve::csg::CSG::OP op,
|
||||
carve::csg::V2Set *shared_edges,
|
||||
CLASSIFY_TYPE classify_type) {
|
||||
Collector *coll = makeCollector(op, a, b);
|
||||
if (!coll) return NULL;
|
||||
|
||||
carve::mesh::MeshSet<3> *result = compute(a, b, *coll, shared_edges, classify_type);
|
||||
meshset_t *result = compute(a, b, *coll, shared_edges, classify_type);
|
||||
|
||||
delete coll;
|
||||
|
||||
@@ -1521,9 +1572,9 @@ carve::mesh::MeshSet<3> *carve::csg::CSG::compute(carve::mesh::MeshSet<3> *a,
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
bool carve::csg::CSG::sliceAndClassify(carve::mesh::MeshSet<3> *closed,
|
||||
carve::mesh::MeshSet<3> *open,
|
||||
std::list<std::pair<FaceClass, carve::mesh::MeshSet<3> *> > &result,
|
||||
bool carve::csg::CSG::sliceAndClassify(meshset_t *closed,
|
||||
meshset_t *open,
|
||||
std::list<std::pair<FaceClass, meshset_t *> > &result,
|
||||
carve::csg::V2Set *shared_edges_ptr) {
|
||||
if (!closed->isClosed()) return false;
|
||||
carve::csg::VertexClassification vclass;
|
||||
@@ -1538,10 +1589,10 @@ bool carve::csg::CSG::sliceAndClassify(carve::mesh::MeshSet<3> *closed,
|
||||
size_t a_edge_count;
|
||||
size_t b_edge_count;
|
||||
|
||||
face_rtree_t *closed_rtree = face_rtree_t::construct_STR(closed->faceBegin(), closed->faceEnd(), 4, 4);
|
||||
face_rtree_t *open_rtree = face_rtree_t::construct_STR(open->faceBegin(), open->faceEnd(), 4, 4);
|
||||
std::auto_ptr<face_rtree_t> closed_rtree(face_rtree_t::construct_STR(closed->faceBegin(), closed->faceEnd(), 4, 4));
|
||||
std::auto_ptr<face_rtree_t> open_rtree(face_rtree_t::construct_STR(open->faceBegin(), open->faceEnd(), 4, 4));
|
||||
|
||||
calc(closed, closed_rtree, open, open_rtree, vclass, eclass,a_face_loops, b_face_loops, a_edge_count, b_edge_count);
|
||||
calc(closed, closed_rtree.get(), open, open_rtree.get(), vclass, eclass,a_face_loops, b_face_loops, a_edge_count, b_edge_count);
|
||||
|
||||
detail::LoopEdges a_edge_map;
|
||||
detail::LoopEdges b_edge_map;
|
||||
@@ -1559,18 +1610,18 @@ bool carve::csg::CSG::sliceAndClassify(carve::mesh::MeshSet<3> *closed,
|
||||
halfClassifyFaceGroups(shared_edges,
|
||||
vclass,
|
||||
closed,
|
||||
closed_rtree,
|
||||
closed_rtree.get(),
|
||||
a_loops_grouped,
|
||||
a_edge_map,
|
||||
open,
|
||||
open_rtree,
|
||||
open_rtree.get(),
|
||||
b_loops_grouped,
|
||||
b_edge_map,
|
||||
result);
|
||||
|
||||
if (shared_edges_ptr != NULL) {
|
||||
std::list<carve::mesh::MeshSet<3> *> result_list;
|
||||
for (std::list<std::pair<FaceClass, carve::mesh::MeshSet<3> *> >::iterator it = result.begin(); it != result.end(); it++) {
|
||||
std::list<meshset_t *> result_list;
|
||||
for (std::list<std::pair<FaceClass, meshset_t *> >::iterator it = result.begin(); it != result.end(); it++) {
|
||||
result_list.push_back(it->second);
|
||||
}
|
||||
returnSharedEdges(shared_edges, result_list, shared_edges_ptr);
|
||||
@@ -1590,10 +1641,10 @@ bool carve::csg::CSG::sliceAndClassify(carve::mesh::MeshSet<3> *closed,
|
||||
* @param hooks
|
||||
* @param shared_edges_ptr
|
||||
*/
|
||||
void carve::csg::CSG::slice(carve::mesh::MeshSet<3> *a,
|
||||
carve::mesh::MeshSet<3> *b,
|
||||
std::list<carve::mesh::MeshSet<3> *> &a_sliced,
|
||||
std::list<carve::mesh::MeshSet<3> *> &b_sliced,
|
||||
void carve::csg::CSG::slice(meshset_t *a,
|
||||
meshset_t *b,
|
||||
std::list<meshset_t *> &a_sliced,
|
||||
std::list<meshset_t *> &b_sliced,
|
||||
carve::csg::V2Set *shared_edges_ptr) {
|
||||
carve::csg::VertexClassification vclass;
|
||||
carve::csg::EdgeClassification eclass;
|
||||
@@ -1607,10 +1658,10 @@ void carve::csg::CSG::slice(carve::mesh::MeshSet<3> *a,
|
||||
size_t a_edge_count;
|
||||
size_t b_edge_count;
|
||||
|
||||
face_rtree_t *a_rtree = face_rtree_t::construct_STR(a->faceBegin(), a->faceEnd(), 4, 4);
|
||||
face_rtree_t *b_rtree = face_rtree_t::construct_STR(b->faceBegin(), b->faceEnd(), 4, 4);
|
||||
std::auto_ptr<face_rtree_t> a_rtree(face_rtree_t::construct_STR(a->faceBegin(), a->faceEnd(), 4, 4));
|
||||
std::auto_ptr<face_rtree_t> b_rtree(face_rtree_t::construct_STR(b->faceBegin(), b->faceEnd(), 4, 4));
|
||||
|
||||
calc(a, a_rtree, b, b_rtree, vclass, eclass,a_face_loops, b_face_loops, a_edge_count, b_edge_count);
|
||||
calc(a, a_rtree.get(), b, b_rtree.get(), vclass, eclass,a_face_loops, b_face_loops, a_edge_count, b_edge_count);
|
||||
|
||||
detail::LoopEdges a_edge_map;
|
||||
detail::LoopEdges b_edge_map;
|
||||
@@ -1645,7 +1696,7 @@ void carve::csg::CSG::slice(carve::mesh::MeshSet<3> *a,
|
||||
delete all;
|
||||
}
|
||||
if (shared_edges_ptr != NULL) {
|
||||
std::list<carve::mesh::MeshSet<3> *> result_list;
|
||||
std::list<meshset_t *> result_list;
|
||||
result_list.insert(result_list.end(), a_sliced.begin(), a_sliced.end());
|
||||
result_list.insert(result_list.end(), b_sliced.begin(), b_sliced.end());
|
||||
returnSharedEdges(shared_edges, result_list, shared_edges_ptr);
|
||||
|
||||
6
extern/carve/patches/strict_flags.patch
vendored
6
extern/carve/patches/strict_flags.patch
vendored
@@ -9,9 +9,9 @@ diff -r 47dfdaff1dd5 include/carve/csg_triangulator.hpp
|
||||
}
|
||||
|
||||
carve::mesh::MeshSet<3>::face_t *mergeQuad(edge_map_t::iterator i, edge_map_t &edge_map) {
|
||||
diff -r 47dfdaff1dd5 src/selfintersect.cpp
|
||||
--- a/src/selfintersect.cpp Thu Jan 12 15:49:04 2012 -0500
|
||||
+++ b/src/selfintersect.cpp Fri Jan 13 03:13:32 2012 +0600
|
||||
diff -r 47dfdaff1dd5 lib/selfintersect.cpp
|
||||
--- a/lib/selfintersect.cpp Thu Jan 12 15:49:04 2012 -0500
|
||||
+++ b/lib/selfintersect.cpp Fri Jan 13 03:13:32 2012 +0600
|
||||
@@ -465,6 +465,7 @@
|
||||
|
||||
// returns true if no intersection, based upon edge^a_i and edge^b_j separating axis.
|
||||
|
||||
13
extern/libmv/CMakeLists.txt
vendored
13
extern/libmv/CMakeLists.txt
vendored
@@ -40,19 +40,6 @@ set(INC_SYS
|
||||
${ZLIB_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
|
||||
# XXX - FIXME
|
||||
# this is a momentary hack to find unwind.h in 10.6.sdk
|
||||
if(APPLE)
|
||||
if(${CMAKE_OSX_DEPLOYMENT_TARGET} STREQUAL "10.6")
|
||||
list(APPEND INC_SYS
|
||||
${CMAKE_OSX_SYSROOT}/Developer/usr/llvm-gcc-4.2/lib/gcc/i686-apple-darwin10/4.2.1/include
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
# XXX - END
|
||||
|
||||
|
||||
set(SRC
|
||||
libmv-capi.cpp
|
||||
libmv/image/array_nd.cc
|
||||
|
||||
4
extern/libmv/libmv-capi.cpp
vendored
4
extern/libmv/libmv-capi.cpp
vendored
@@ -523,7 +523,7 @@ int libmv_refineParametersAreValid(int parameters) {
|
||||
LIBMV_REFINE_RADIAL_DISTORTION_K1));
|
||||
}
|
||||
|
||||
void libmv_solveRefineIntrinsics(libmv::Tracks *tracks, libmv::CameraIntrinsics *intrinsics,
|
||||
static void libmv_solveRefineIntrinsics(libmv::Tracks *tracks, libmv::CameraIntrinsics *intrinsics,
|
||||
libmv::EuclideanReconstruction *reconstruction, int refine_intrinsics,
|
||||
reconstruct_progress_update_cb progress_update_callback, void *callback_customdata)
|
||||
{
|
||||
@@ -1027,7 +1027,7 @@ void libmv_InvertIntrinsics(double focal_length, double principal_x, double prin
|
||||
|
||||
/* ************ point clouds ************ */
|
||||
|
||||
void libmvTransformToMat4(libmv::Mat3 &R, libmv::Vec3 &S, libmv::Vec3 &t, double M[4][4])
|
||||
static void libmvTransformToMat4(libmv::Mat3 &R, libmv::Vec3 &S, libmv::Vec3 &t, double M[4][4])
|
||||
{
|
||||
for (int j = 0; j < 3; ++j)
|
||||
for (int k = 0; k < 3; ++k)
|
||||
|
||||
8
extern/libmv/libmv-capi.h
vendored
8
extern/libmv/libmv-capi.h
vendored
@@ -147,14 +147,14 @@ void libmv_CameraIntrinsicsDistortFloat(struct libmv_CameraIntrinsics *libmvIntr
|
||||
|
||||
/* dsitortion */
|
||||
void libmv_undistortByte(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
|
||||
unsigned char *src, unsigned char *dst, int width, int height, int channels);
|
||||
unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels);
|
||||
void libmv_undistortFloat(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
|
||||
float *src, float *dst, int width, int height, int channels);
|
||||
float *src, float *dst, int width, int height, float overscan, int channels);
|
||||
|
||||
void libmv_distortByte(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
|
||||
unsigned char *src, unsigned char *dst, int width, int height, int channels);
|
||||
unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels);
|
||||
void libmv_distortFloat(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
|
||||
float *src, float *dst, int width, int height, int channels);
|
||||
float *src, float *dst, int width, int height, float overscan, int channels);
|
||||
|
||||
/* utils */
|
||||
void libmv_applyCameraIntrinsics(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
|
||||
|
||||
@@ -351,9 +351,9 @@ void EuclideanResectionAnsarDaniilidis(const Mat2X &x_camera,
|
||||
}
|
||||
|
||||
// Selects 4 virtual control points using mean and PCA.
|
||||
void SelectControlPoints(const Mat3X &X_world,
|
||||
Mat *X_centered,
|
||||
Mat34 *X_control_points) {
|
||||
static void SelectControlPoints(const Mat3X &X_world,
|
||||
Mat *X_centered,
|
||||
Mat34 *X_control_points) {
|
||||
size_t num_points = X_world.cols();
|
||||
|
||||
// The first virtual control point, C0, is the centroid.
|
||||
@@ -377,9 +377,9 @@ void SelectControlPoints(const Mat3X &X_world,
|
||||
}
|
||||
|
||||
// Computes the barycentric coordinates for all real points
|
||||
void ComputeBarycentricCoordinates(const Mat3X &X_world_centered,
|
||||
const Mat34 &X_control_points,
|
||||
Mat4X *alphas) {
|
||||
static void ComputeBarycentricCoordinates(const Mat3X &X_world_centered,
|
||||
const Mat34 &X_control_points,
|
||||
Mat4X *alphas) {
|
||||
size_t num_points = X_world_centered.cols();
|
||||
Mat3 C2 ;
|
||||
for (size_t c = 1; c < 4; c++) {
|
||||
@@ -398,7 +398,7 @@ void ComputeBarycentricCoordinates(const Mat3X &X_world_centered,
|
||||
}
|
||||
|
||||
// Estimates the coordinates of all real points in the camera coordinate frame
|
||||
void ComputePointsCoordinatesInCameraFrame(
|
||||
static void ComputePointsCoordinatesInCameraFrame(
|
||||
const Mat4X &alphas,
|
||||
const Vec4 &betas,
|
||||
const Eigen::Matrix<double, 12, 12> &U,
|
||||
@@ -535,7 +535,16 @@ bool EuclideanResectionEPnP(const Mat2X &x_camera,
|
||||
vector<Vec3> ts(3);
|
||||
Vec rmse(3);
|
||||
|
||||
// TODO(julien): Document where the "1e-3" magical constant comes from below.
|
||||
// At one point this threshold was 1e-3, and caused no end of problems in
|
||||
// Blender by causing frames to not resect when they would have worked fine.
|
||||
// When the resect failed, the projective followup is run leading to worse
|
||||
// results, and often the dreaded "flipping" where objects get flipped
|
||||
// between frames. Instead, disable the check for now, always succeeding. The
|
||||
// ultimate check is always reprojection error anyway.
|
||||
//
|
||||
// TODO(keir): Decide if setting this to infinity, effectively disabling the
|
||||
// check, is the right approach. So far this seems the case.
|
||||
double kSuccessThreshold = std::numeric_limits<double>::max();
|
||||
|
||||
// Find the first possible solution for R, t corresponding to:
|
||||
// Betas = [b00 b01 b11 b02 b12 b22 b03 b13 b23 b33]
|
||||
@@ -548,7 +557,7 @@ bool EuclideanResectionEPnP(const Mat2X &x_camera,
|
||||
Eigen::JacobiSVD<Mat> svd_of_l4(l_6x4,
|
||||
Eigen::ComputeFullU | Eigen::ComputeFullV);
|
||||
Vec4 b4 = svd_of_l4.solve(rho);
|
||||
if ((l_6x4 * b4).isApprox(rho, 1e-3)) {
|
||||
if ((l_6x4 * b4).isApprox(rho, kSuccessThreshold)) {
|
||||
if (b4(0) < 0) {
|
||||
b4 = -b4;
|
||||
}
|
||||
@@ -574,7 +583,7 @@ bool EuclideanResectionEPnP(const Mat2X &x_camera,
|
||||
Vec3 b3 = svdOfL3.solve(rho);
|
||||
VLOG(2) << " rho = " << rho;
|
||||
VLOG(2) << " l_6x3 * b3 = " << l_6x3 * b3;
|
||||
if ((l_6x3 * b3).isApprox(rho, 1e-3)) {
|
||||
if ((l_6x3 * b3).isApprox(rho, kSuccessThreshold)) {
|
||||
if (b3(0) < 0) {
|
||||
betas(0) = std::sqrt(-b3(0));
|
||||
betas(1) = (b3(2) < 0) ? std::sqrt(-b3(2)) : 0;
|
||||
@@ -605,7 +614,7 @@ bool EuclideanResectionEPnP(const Mat2X &x_camera,
|
||||
Eigen::JacobiSVD<Mat> svdOfL5(l_6x5,
|
||||
Eigen::ComputeFullU | Eigen::ComputeFullV);
|
||||
Vec5 b5 = svdOfL5.solve(rho);
|
||||
if ((l_6x5 * b5).isApprox(rho, 1e-3)) {
|
||||
if ((l_6x5 * b5).isApprox(rho, kSuccessThreshold)) {
|
||||
if (b5(0) < 0) {
|
||||
betas(0) = std::sqrt(-b5(0));
|
||||
if (b5(2) < 0) {
|
||||
|
||||
@@ -29,6 +29,9 @@ namespace euclidean_resection {
|
||||
|
||||
enum ResectionMethod {
|
||||
RESECTION_ANSAR_DANIILIDIS,
|
||||
|
||||
// The "EPnP" algorithm by Lepetit et al.
|
||||
// http://cvlab.epfl.ch/~lepetit/papers/lepetit_ijcv08.pdf
|
||||
RESECTION_EPNP,
|
||||
};
|
||||
|
||||
|
||||
4
extern/libmv/libmv/multiview/fundamental.cc
vendored
4
extern/libmv/libmv/multiview/fundamental.cc
vendored
@@ -28,7 +28,7 @@
|
||||
|
||||
namespace libmv {
|
||||
|
||||
void EliminateRow(const Mat34 &P, int row, Mat *X) {
|
||||
static void EliminateRow(const Mat34 &P, int row, Mat *X) {
|
||||
X->resize(2, 4);
|
||||
|
||||
int first_row = (row + 1) % 3;
|
||||
@@ -69,7 +69,7 @@ void FundamentalFromProjections(const Mat34 &P1, const Mat34 &P2, Mat3 *F) {
|
||||
|
||||
// HZ 11.1 pag.279 (x1 = x, x2 = x')
|
||||
// http://www.cs.unc.edu/~marc/tutorial/node54.html
|
||||
double EightPointSolver(const Mat &x1, const Mat &x2, Mat3 *F) {
|
||||
static double EightPointSolver(const Mat &x1, const Mat &x2, Mat3 *F) {
|
||||
DCHECK_EQ(x1.rows(), 2);
|
||||
DCHECK_GE(x1.cols(), 8);
|
||||
DCHECK_EQ(x1.rows(), x2.rows());
|
||||
|
||||
2
extern/libmv/libmv/multiview/homography.cc
vendored
2
extern/libmv/libmv/multiview/homography.cc
vendored
@@ -40,7 +40,7 @@ namespace libmv {
|
||||
* (a-x1*g)*y1 + (b-x1*h)*y2 + c-x1 = |0|
|
||||
* (-x2*a+x1*d)*y1 + (-x2*b+x1*e)*y2 + -x2*c+x1*f |0|
|
||||
*/
|
||||
bool Homography2DFromCorrespondencesLinearEuc(
|
||||
static bool Homography2DFromCorrespondencesLinearEuc(
|
||||
const Mat &x1,
|
||||
const Mat &x2,
|
||||
Mat3 *H,
|
||||
|
||||
10
extern/libmv/libmv/numeric/levenberg_marquardt.h
vendored
10
extern/libmv/libmv/numeric/levenberg_marquardt.h
vendored
@@ -124,11 +124,11 @@ class LevenbergMarquardt {
|
||||
Parameters dx, x_new;
|
||||
int i;
|
||||
for (i = 0; results.status == RUNNING && i < params.max_iterations; ++i) {
|
||||
VLOG(1) << "iteration: " << i;
|
||||
VLOG(1) << "||f(x)||: " << f_(x).norm();
|
||||
VLOG(1) << "max(g): " << g.array().abs().maxCoeff();
|
||||
VLOG(1) << "u: " << u;
|
||||
VLOG(1) << "v: " << v;
|
||||
VLOG(3) << "iteration: " << i;
|
||||
VLOG(3) << "||f(x)||: " << f_(x).norm();
|
||||
VLOG(3) << "max(g): " << g.array().abs().maxCoeff();
|
||||
VLOG(3) << "u: " << u;
|
||||
VLOG(3) << "v: " << v;
|
||||
|
||||
AMatrixType A_augmented = A + u*AMatrixType::Identity(J.cols(), J.cols());
|
||||
Solver solver(A_augmented);
|
||||
|
||||
@@ -209,7 +209,7 @@ void CameraIntrinsics::ComputeLookupGrid(Grid* grid, int width, int height, doub
|
||||
if( ix >= width-2 ) ix = width-2;
|
||||
if( iy >= height-2 ) iy = height-2;
|
||||
|
||||
Offset offset = { ix-x, iy-y, fx, fy };
|
||||
Offset offset = { (short)(ix-x), (short)(iy-y), (unsigned char)fx, (unsigned char)fy };
|
||||
grid->offset[y*width+x] = offset;
|
||||
}
|
||||
}
|
||||
|
||||
6
extern/libmv/libmv/simple_pipeline/detect.cc
vendored
6
extern/libmv/libmv/simple_pipeline/detect.cc
vendored
@@ -35,7 +35,7 @@ namespace libmv {
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
||||
int featurecmp(const void *a_v, const void *b_v)
|
||||
static int featurecmp(const void *a_v, const void *b_v)
|
||||
{
|
||||
Feature *a = (Feature*)a_v;
|
||||
Feature *b = (Feature*)b_v;
|
||||
@@ -66,7 +66,7 @@ std::vector<Feature> DetectFAST(const unsigned char* data, int width, int height
|
||||
Feature *all_features = new Feature[num_features];
|
||||
|
||||
for(int i = 0; i < num_features; ++i) {
|
||||
Feature a = { nonmax[i].x, nonmax[i].y, scores[i], 0 };
|
||||
Feature a = { (float)nonmax[i].x, (float)nonmax[i].y, (float)scores[i], 0 };
|
||||
all_features[i] = a;
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ void DetectMORAVEC(ubyte* image, int stride, int width, int height, Feature* det
|
||||
for(int y=16; y<height-16; y++) {
|
||||
for(int x=16; x<width-16; x++) {
|
||||
int s = scores[y*width+x];
|
||||
Feature f = { x+8, y+8, s, 16 };
|
||||
Feature f = { (float)x+8.0f, (float)y+8.0f, (float)s, 16 };
|
||||
if(s>min) detected[i++] = f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "libmv/multiview/projection.h"
|
||||
#include "libmv/numeric/levenberg_marquardt.h"
|
||||
#include "libmv/numeric/numeric.h"
|
||||
#include "libmv/simple_pipeline/initialize_reconstruction.h"
|
||||
#include "libmv/simple_pipeline/reconstruction.h"
|
||||
#include "libmv/simple_pipeline/tracks.h"
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "libmv/multiview/projection.h"
|
||||
#include "libmv/numeric/numeric.h"
|
||||
#include "libmv/numeric/levenberg_marquardt.h"
|
||||
#include "libmv/simple_pipeline/intersect.h"
|
||||
#include "libmv/simple_pipeline/reconstruction.h"
|
||||
#include "libmv/simple_pipeline/tracks.h"
|
||||
|
||||
|
||||
@@ -242,9 +242,9 @@ void InternalCompleteReconstruction(
|
||||
(double)tot_resects/(max_image));
|
||||
if (PipelineRoutines::Resect(reconstructed_markers, reconstruction, true)) {
|
||||
num_resects++;
|
||||
LG << "Ran Resect() for image " << image;
|
||||
LG << "Ran final Resect() for image " << image;
|
||||
} else {
|
||||
LG << "Failed Resect() for image " << image;
|
||||
LG << "Failed final Resect() for image " << image;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
5
extern/libmv/libmv/simple_pipeline/resect.cc
vendored
5
extern/libmv/libmv/simple_pipeline/resect.cc
vendored
@@ -27,6 +27,7 @@
|
||||
#include "libmv/multiview/projection.h"
|
||||
#include "libmv/numeric/numeric.h"
|
||||
#include "libmv/numeric/levenberg_marquardt.h"
|
||||
#include "libmv/simple_pipeline/resect.h"
|
||||
#include "libmv/simple_pipeline/reconstruction.h"
|
||||
#include "libmv/simple_pipeline/tracks.h"
|
||||
|
||||
@@ -107,6 +108,10 @@ bool EuclideanResect(const vector<Marker> &markers,
|
||||
// printf("Resection for image %d failed\n", markers[0].image);
|
||||
LG << "Resection for image " << markers[0].image << " failed;"
|
||||
<< " trying fallback projective resection.";
|
||||
|
||||
LG << "No fallback; failing resection for " << markers[0].image;
|
||||
return false;
|
||||
|
||||
if (!final_pass) return false;
|
||||
// Euclidean resection failed. Fall back to projective resection, which is
|
||||
// less reliable but better conditioned when there are many points.
|
||||
|
||||
213
extern/libmv/libmv/tracking/track_region.cc
vendored
213
extern/libmv/libmv/tracking/track_region.cc
vendored
@@ -18,7 +18,7 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//
|
||||
// Author: mierle@google.com (Keir Mierle)
|
||||
// Author: mierle@gmail.com (Keir Mierle)
|
||||
//
|
||||
// TODO(keir): While this tracking code works rather well, it has some
|
||||
// outragous inefficiencies. There is probably a 5-10x speedup to be had if a
|
||||
@@ -41,6 +41,85 @@
|
||||
#include "libmv/multiview/homography.h"
|
||||
#include "libmv/numeric/numeric.h"
|
||||
|
||||
// Expand the Jet functionality of Ceres to allow mixed numeric/autodiff.
|
||||
//
|
||||
// TODO(keir): Push this (or something similar) into upstream Ceres.
|
||||
namespace ceres {
|
||||
|
||||
// A jet traits class to make it easier to work with mixed auto / numeric diff.
|
||||
template<typename T>
|
||||
struct JetOps {
|
||||
static bool IsScalar() {
|
||||
return true;
|
||||
}
|
||||
static T GetScalar(const T& t) {
|
||||
return t;
|
||||
}
|
||||
static void SetScalar(const T& scalar, T* t) {
|
||||
*t = scalar;
|
||||
}
|
||||
static void ScaleDerivative(double scale_by, T *value) {
|
||||
// For double, there is no derivative to scale.
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, int N>
|
||||
struct JetOps<Jet<T, N> > {
|
||||
static bool IsScalar() {
|
||||
return false;
|
||||
}
|
||||
static T GetScalar(const Jet<T, N>& t) {
|
||||
return t.a;
|
||||
}
|
||||
static void SetScalar(const T& scalar, Jet<T, N>* t) {
|
||||
t->a = scalar;
|
||||
}
|
||||
static void ScaleDerivative(double scale_by, Jet<T, N> *value) {
|
||||
value->v *= scale_by;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename FunctionType, int kNumArgs, typename ArgumentType>
|
||||
struct Chain {
|
||||
static ArgumentType Rule(const FunctionType &f,
|
||||
const FunctionType dfdx[kNumArgs],
|
||||
const ArgumentType x[kNumArgs]) {
|
||||
// In the default case of scalars, there's nothing to do since there are no
|
||||
// derivatives to propagate.
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
||||
// XXX Add documentation here!
|
||||
template<typename FunctionType, int kNumArgs, typename T, int N>
|
||||
struct Chain<FunctionType, kNumArgs, Jet<T, N> > {
|
||||
static Jet<T, N> Rule(const FunctionType &f,
|
||||
const FunctionType dfdx[kNumArgs],
|
||||
const Jet<T, N> x[kNumArgs]) {
|
||||
// x is itself a function of another variable ("z"); what this function
|
||||
// needs to return is "f", but with the derivative with respect to z
|
||||
// attached to the jet. So combine the derivative part of x's jets to form
|
||||
// a Jacobian matrix between x and z (i.e. dx/dz).
|
||||
Eigen::Matrix<T, kNumArgs, N> dxdz;
|
||||
for (int i = 0; i < kNumArgs; ++i) {
|
||||
dxdz.row(i) = x[i].v.transpose();
|
||||
}
|
||||
|
||||
// Map the input gradient dfdx into an Eigen row vector.
|
||||
Eigen::Map<const Eigen::Matrix<FunctionType, 1, kNumArgs> >
|
||||
vector_dfdx(dfdx, 1, kNumArgs);
|
||||
|
||||
// Now apply the chain rule to obtain df/dz. Combine the derivative with
|
||||
// the scalar part to obtain f with full derivative information.
|
||||
Jet<T, N> jet_f;
|
||||
jet_f.a = f;
|
||||
jet_f.v = vector_dfdx.template cast<T>() * dxdz; // Also known as dfdz.
|
||||
return jet_f;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ceres
|
||||
|
||||
namespace libmv {
|
||||
|
||||
using ceres::Jet;
|
||||
@@ -57,6 +136,7 @@ TrackRegionOptions::TrackRegionOptions()
|
||||
sigma(0.9),
|
||||
num_extra_points(0),
|
||||
regularization_coefficient(0.0),
|
||||
minimum_corner_shift_tolerance_pixels(0.005),
|
||||
image1_mask(NULL) {
|
||||
}
|
||||
|
||||
@@ -108,45 +188,93 @@ static T SampleWithDerivative(const FloatImage &image_and_gradient,
|
||||
}
|
||||
|
||||
template<typename Warp>
|
||||
class BoundaryCheckingCallback : public ceres::IterationCallback {
|
||||
class TerminationCheckingCallback : public ceres::IterationCallback {
|
||||
public:
|
||||
BoundaryCheckingCallback(const FloatImage& image2,
|
||||
const Warp &warp,
|
||||
const double *x1, const double *y1)
|
||||
: image2_(image2), warp_(warp), x1_(x1), y1_(y1) {}
|
||||
TerminationCheckingCallback(const TrackRegionOptions &options,
|
||||
const FloatImage& image2,
|
||||
const Warp &warp,
|
||||
const double *x1, const double *y1)
|
||||
: options_(options), image2_(image2), warp_(warp), x1_(x1), y1_(y1),
|
||||
have_last_successful_step_(false) {}
|
||||
|
||||
virtual ceres::CallbackReturnType operator()(
|
||||
const ceres::IterationSummary& summary) {
|
||||
// If the step wasn't successful, there's nothing to do.
|
||||
if (!summary.step_is_successful) {
|
||||
return ceres::SOLVER_CONTINUE;
|
||||
}
|
||||
// Warp the original 4 points with the current warp into image2.
|
||||
double x2[4];
|
||||
double y2[4];
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
warp_.Forward(warp_.parameters, x1_[i], y1_[i], x2 + i, y2 + i);
|
||||
}
|
||||
// Enusre they are all in bounds.
|
||||
// Ensure the corners are all in bounds.
|
||||
if (!AllInBounds(image2_, x2, y2)) {
|
||||
LG << "Successful step fell outside of the pattern bounds; aborting.";
|
||||
return ceres::SOLVER_ABORT;
|
||||
}
|
||||
|
||||
// Ensure the minimizer is making large enough shifts to bother continuing.
|
||||
// Ideally, this check would happen on the parameters themselves which
|
||||
// Ceres supports directly; however, the mapping from parameter change
|
||||
// magnitude to corner movement in pixels is not a simple norm. Hence, the
|
||||
// need for a stateful callback which tracks the last successful set of
|
||||
// parameters (and the position of the projected patch corners).
|
||||
if (have_last_successful_step_) {
|
||||
// Compute the maximum shift of any corner in pixels since the last
|
||||
// successful iteration.
|
||||
double max_change_pixels = 0;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
double dx = x2[i] - x2_last_successful_[i];
|
||||
double dy = y2[i] - y2_last_successful_[i];
|
||||
double change_pixels = dx*dx + dy*dy;
|
||||
if (change_pixels > max_change_pixels) {
|
||||
max_change_pixels = change_pixels;
|
||||
}
|
||||
}
|
||||
max_change_pixels = sqrt(max_change_pixels);
|
||||
LG << "Max patch corner shift is " << max_change_pixels;
|
||||
|
||||
// Bail if the shift is too small.
|
||||
if (max_change_pixels < options_.minimum_corner_shift_tolerance_pixels) {
|
||||
LG << "Max patch corner shift is " << max_change_pixels
|
||||
<< " from the last iteration; returning success.";
|
||||
return ceres::SOLVER_TERMINATE_SUCCESSFULLY;
|
||||
}
|
||||
}
|
||||
|
||||
// Save the projected corners for checking on the next successful iteration.
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
x2_last_successful_[i] = x2[i];
|
||||
y2_last_successful_[i] = y2[i];
|
||||
}
|
||||
have_last_successful_step_ = true;
|
||||
return ceres::SOLVER_CONTINUE;
|
||||
}
|
||||
|
||||
private:
|
||||
const TrackRegionOptions &options_;
|
||||
const FloatImage &image2_;
|
||||
const Warp &warp_;
|
||||
const double *x1_;
|
||||
const double *y1_;
|
||||
|
||||
bool have_last_successful_step_;
|
||||
double x2_last_successful_[4];
|
||||
double y2_last_successful_[4];
|
||||
};
|
||||
|
||||
template<typename Warp>
|
||||
class PixelDifferenceCostFunctor {
|
||||
public:
|
||||
PixelDifferenceCostFunctor(const TrackRegionOptions &options,
|
||||
const FloatImage &image_and_gradient1,
|
||||
const FloatImage &image_and_gradient2,
|
||||
const Mat3 &canonical_to_image1,
|
||||
int num_samples_x,
|
||||
int num_samples_y,
|
||||
const Warp &warp)
|
||||
const FloatImage &image_and_gradient1,
|
||||
const FloatImage &image_and_gradient2,
|
||||
const Mat3 &canonical_to_image1,
|
||||
int num_samples_x,
|
||||
int num_samples_y,
|
||||
const Warp &warp)
|
||||
: options_(options),
|
||||
image_and_gradient1_(image_and_gradient1),
|
||||
image_and_gradient2_(image_and_gradient2),
|
||||
@@ -1044,6 +1172,9 @@ void CreateBrutePattern(const double *x1, const double *y1,
|
||||
// correlation. Instead, this is a dumb implementation. Surprisingly, it is
|
||||
// fast enough in practice.
|
||||
//
|
||||
// Returns true if any alignment was found, and false if the projected pattern
|
||||
// is zero sized.
|
||||
//
|
||||
// TODO(keir): The normalization is less effective for the brute force search
|
||||
// than it is with the Ceres solver. It's unclear if this is a bug or due to
|
||||
// the original frame being too different from the reprojected reference in the
|
||||
@@ -1054,7 +1185,7 @@ void CreateBrutePattern(const double *x1, const double *y1,
|
||||
// totally different warping interface, since access to more than a the source
|
||||
// and current destination frame is necessary.
|
||||
template<typename Warp>
|
||||
void BruteTranslationOnlyInitialize(const FloatImage &image1,
|
||||
bool BruteTranslationOnlyInitialize(const FloatImage &image1,
|
||||
const FloatImage *image1_mask,
|
||||
const FloatImage &image2,
|
||||
const int num_extra_points,
|
||||
@@ -1100,6 +1231,7 @@ void BruteTranslationOnlyInitialize(const FloatImage &image1,
|
||||
int best_c = -1;
|
||||
int w = pattern.cols();
|
||||
int h = pattern.rows();
|
||||
|
||||
for (int r = 0; r < (image2.Height() - h); ++r) {
|
||||
for (int c = 0; c < (image2.Width() - w); ++c) {
|
||||
// Compute the weighted sum of absolute differences, Eigen style. Note
|
||||
@@ -1124,8 +1256,12 @@ void BruteTranslationOnlyInitialize(const FloatImage &image1,
|
||||
}
|
||||
}
|
||||
}
|
||||
CHECK_NE(best_r, -1);
|
||||
CHECK_NE(best_c, -1);
|
||||
|
||||
// This mean the effective pattern area is zero. This check could go earlier,
|
||||
// but this is less code.
|
||||
if (best_r == -1 || best_c == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LG << "Brute force translation found a shift. "
|
||||
<< "best_c: " << best_c << ", best_r: " << best_r << ", "
|
||||
@@ -1140,6 +1276,7 @@ void BruteTranslationOnlyInitialize(const FloatImage &image1,
|
||||
x2[i] += best_c - origin_x;
|
||||
y2[i] += best_r - origin_y;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -1191,12 +1328,19 @@ void TemplatedTrackRegion(const FloatImage &image1,
|
||||
if (SearchAreaTooBigForDescent(image2, x2, y2) &&
|
||||
options.use_brute_initialization) {
|
||||
LG << "Running brute initialization...";
|
||||
BruteTranslationOnlyInitialize<Warp>(image_and_gradient1,
|
||||
options.image1_mask,
|
||||
image2,
|
||||
options.num_extra_points,
|
||||
options.use_normalized_intensities,
|
||||
x1, y1, x2, y2);
|
||||
bool found_any_alignment = BruteTranslationOnlyInitialize<Warp>(
|
||||
image_and_gradient1,
|
||||
options.image1_mask,
|
||||
image2,
|
||||
options.num_extra_points,
|
||||
options.use_normalized_intensities,
|
||||
x1, y1, x2, y2);
|
||||
if (!found_any_alignment) {
|
||||
LG << "Brute failed to find an alignment; pattern too small. "
|
||||
<< "Failing entire track operation.";
|
||||
result->termination = TrackRegionResult::INSUFFICIENT_PATTERN_AREA;
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
LG << "P" << i << ": (" << x1[i] << ", " << y1[i] << "); brute ("
|
||||
<< x2[i] << ", " << y2[i] << "); (dx, dy): (" << (x2[i] - x1[i])
|
||||
@@ -1260,14 +1404,15 @@ void TemplatedTrackRegion(const FloatImage &image1,
|
||||
|
||||
// Configure the solve.
|
||||
ceres::Solver::Options solver_options;
|
||||
solver_options.linear_solver_type = ceres::DENSE_QR;
|
||||
solver_options.linear_solver_type = ceres::DENSE_NORMAL_CHOLESKY;
|
||||
solver_options.max_num_iterations = options.max_iterations;
|
||||
solver_options.update_state_every_iteration = true;
|
||||
solver_options.parameter_tolerance = 1e-16;
|
||||
solver_options.function_tolerance = 1e-16;
|
||||
|
||||
// Prevent the corners from going outside the destination image.
|
||||
BoundaryCheckingCallback<Warp> callback(image2, warp, x1, y1);
|
||||
// Prevent the corners from going outside the destination image and
|
||||
// terminate if the optimizer is making tiny moves (converged).
|
||||
TerminationCheckingCallback<Warp> callback(options, image2, warp, x1, y1);
|
||||
solver_options.callbacks.push_back(&callback);
|
||||
|
||||
// Run the solve.
|
||||
@@ -1290,11 +1435,21 @@ void TemplatedTrackRegion(const FloatImage &image1,
|
||||
// TODO(keir): Update the result statistics.
|
||||
// TODO(keir): Add a normalize-cross-correlation variant.
|
||||
|
||||
CHECK_NE(summary.termination_type, ceres::USER_ABORT) << "Libmv bug.";
|
||||
if (summary.termination_type == ceres::USER_ABORT) {
|
||||
result->termination = TrackRegionResult::FELL_OUT_OF_BOUNDS;
|
||||
return;
|
||||
}
|
||||
|
||||
// This happens when the minimum corner shift tolerance is reached. Due to
|
||||
// how the tolerance is computed this can't be done by Ceres. So return the
|
||||
// same termination enum as Ceres, even though this is slightly different
|
||||
// than Ceres's parameter tolerance, which operates on the raw parameter
|
||||
// values rather than the pixel shifts of the patch corners.
|
||||
if (summary.termination_type == ceres::USER_SUCCESS) {
|
||||
result->termination = TrackRegionResult::PARAMETER_TOLERANCE;
|
||||
return;
|
||||
}
|
||||
|
||||
#define HANDLE_TERMINATION(termination_enum) \
|
||||
if (summary.termination_type == ceres::termination_enum) { \
|
||||
result->termination = TrackRegionResult::termination_enum; \
|
||||
@@ -1377,11 +1532,11 @@ bool SamplePlanarPatch(const FloatImage &image,
|
||||
image_position(0),
|
||||
&(*patch)(r, c, 0));
|
||||
if (mask) {
|
||||
float maskValue = SampleLinear(*mask, image_position(1),
|
||||
image_position(0), 0);
|
||||
float mask_value = SampleLinear(*mask, image_position(1),
|
||||
image_position(0), 0);
|
||||
|
||||
for (int d = 0; d < image.Depth(); d++)
|
||||
(*patch)(r, c, d) *= maskValue;
|
||||
(*patch)(r, c, d) *= mask_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
6
extern/libmv/libmv/tracking/track_region.h
vendored
6
extern/libmv/libmv/tracking/track_region.h
vendored
@@ -90,6 +90,11 @@ struct TrackRegionOptions {
|
||||
// If zero, no regularization is used.
|
||||
double regularization_coefficient;
|
||||
|
||||
// If the maximum shift of any patch corner between successful iterations of
|
||||
// the solver is less than this amount, then the tracking is declared
|
||||
// successful. The solver termination becomes PARAMETER_TOLERANCE.
|
||||
double minimum_corner_shift_tolerance_pixels;
|
||||
|
||||
// If non-null, this is used as the pattern mask. It should match the size of
|
||||
// image1, even though only values inside the image1 quad are examined. The
|
||||
// values must be in the range 0.0 to 0.1.
|
||||
@@ -111,6 +116,7 @@ struct TrackRegionResult {
|
||||
DESTINATION_OUT_OF_BOUNDS,
|
||||
FELL_OUT_OF_BOUNDS,
|
||||
INSUFFICIENT_CORRELATION,
|
||||
INSUFFICIENT_PATTERN_AREA,
|
||||
CONFIGURATION_ERROR,
|
||||
};
|
||||
Termination termination;
|
||||
|
||||
48
extern/libmv/third_party/ceres/CMakeLists.txt
vendored
48
extern/libmv/third_party/ceres/CMakeLists.txt
vendored
@@ -38,6 +38,7 @@ set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
internal/ceres/array_utils.cc
|
||||
internal/ceres/block_evaluate_preparer.cc
|
||||
internal/ceres/block_jacobian_writer.cc
|
||||
internal/ceres/block_jacobi_preconditioner.cc
|
||||
@@ -53,16 +54,19 @@ set(SRC
|
||||
internal/ceres/conditioned_cost_function.cc
|
||||
internal/ceres/conjugate_gradients_solver.cc
|
||||
internal/ceres/corrector.cc
|
||||
internal/ceres/cxsparse.cc
|
||||
internal/ceres/dense_normal_cholesky_solver.cc
|
||||
internal/ceres/dense_qr_solver.cc
|
||||
internal/ceres/dense_sparse_matrix.cc
|
||||
internal/ceres/detect_structure.cc
|
||||
internal/ceres/dogleg_strategy.cc
|
||||
internal/ceres/evaluator.cc
|
||||
internal/ceres/file.cc
|
||||
internal/ceres/generated/schur_eliminator_d_d_d.cc
|
||||
internal/ceres/gradient_checking_cost_function.cc
|
||||
internal/ceres/implicit_schur_complement.cc
|
||||
internal/ceres/iterative_schur_complement_solver.cc
|
||||
internal/ceres/levenberg_marquardt.cc
|
||||
internal/ceres/levenberg_marquardt_strategy.cc
|
||||
internal/ceres/linear_least_squares_problems.cc
|
||||
internal/ceres/linear_operator.cc
|
||||
internal/ceres/linear_solver.cc
|
||||
@@ -70,6 +74,7 @@ set(SRC
|
||||
internal/ceres/loss_function.cc
|
||||
internal/ceres/normal_prior.cc
|
||||
internal/ceres/partitioned_matrix_view.cc
|
||||
internal/ceres/polynomial_solver.cc
|
||||
internal/ceres/problem.cc
|
||||
internal/ceres/problem_impl.cc
|
||||
internal/ceres/program.cc
|
||||
@@ -88,6 +93,8 @@ set(SRC
|
||||
internal/ceres/stringprintf.cc
|
||||
internal/ceres/suitesparse.cc
|
||||
internal/ceres/triplet_sparse_matrix.cc
|
||||
internal/ceres/trust_region_minimizer.cc
|
||||
internal/ceres/trust_region_strategy.cc
|
||||
internal/ceres/types.cc
|
||||
internal/ceres/visibility_based_preconditioner.cc
|
||||
internal/ceres/visibility.cc
|
||||
@@ -96,6 +103,8 @@ set(SRC
|
||||
include/ceres/ceres.h
|
||||
include/ceres/conditioned_cost_function.h
|
||||
include/ceres/cost_function.h
|
||||
include/ceres/crs_matrix.h
|
||||
include/ceres/fpclassify.h
|
||||
include/ceres/internal/autodiff.h
|
||||
include/ceres/internal/eigen.h
|
||||
include/ceres/internal/fixed_array.h
|
||||
@@ -114,6 +123,7 @@ set(SRC
|
||||
include/ceres/sized_cost_function.h
|
||||
include/ceres/solver.h
|
||||
include/ceres/types.h
|
||||
internal/ceres/array_utils.h
|
||||
internal/ceres/block_evaluate_preparer.h
|
||||
internal/ceres/block_jacobian_writer.h
|
||||
internal/ceres/block_jacobi_preconditioner.h
|
||||
@@ -131,10 +141,13 @@ set(SRC
|
||||
internal/ceres/compressed_row_sparse_matrix.h
|
||||
internal/ceres/conjugate_gradients_solver.h
|
||||
internal/ceres/corrector.h
|
||||
internal/ceres/cxsparse.h
|
||||
internal/ceres/dense_jacobian_writer.h
|
||||
internal/ceres/dense_normal_cholesky_solver.h
|
||||
internal/ceres/dense_qr_solver.h
|
||||
internal/ceres/dense_sparse_matrix.h
|
||||
internal/ceres/detect_structure.h
|
||||
internal/ceres/dogleg_strategy.h
|
||||
internal/ceres/evaluator.h
|
||||
internal/ceres/file.h
|
||||
internal/ceres/gradient_checking_cost_function.h
|
||||
@@ -143,7 +156,7 @@ set(SRC
|
||||
internal/ceres/implicit_schur_complement.h
|
||||
internal/ceres/integral_types.h
|
||||
internal/ceres/iterative_schur_complement_solver.h
|
||||
internal/ceres/levenberg_marquardt.h
|
||||
internal/ceres/levenberg_marquardt_strategy.h
|
||||
internal/ceres/linear_least_squares_problems.h
|
||||
internal/ceres/linear_operator.h
|
||||
internal/ceres/linear_solver.h
|
||||
@@ -153,6 +166,7 @@ set(SRC
|
||||
internal/ceres/mutex.h
|
||||
internal/ceres/parameter_block.h
|
||||
internal/ceres/partitioned_matrix_view.h
|
||||
internal/ceres/polynomial_solver.h
|
||||
internal/ceres/problem_impl.h
|
||||
internal/ceres/program_evaluator.h
|
||||
internal/ceres/program.h
|
||||
@@ -168,10 +182,13 @@ set(SRC
|
||||
internal/ceres/solver_impl.h
|
||||
internal/ceres/sparse_matrix.h
|
||||
internal/ceres/sparse_normal_cholesky_solver.h
|
||||
internal/ceres/split.h
|
||||
internal/ceres/stl_util.h
|
||||
internal/ceres/stringprintf.h
|
||||
internal/ceres/suitesparse.h
|
||||
internal/ceres/triplet_sparse_matrix.h
|
||||
internal/ceres/trust_region_minimizer.h
|
||||
internal/ceres/trust_region_strategy.h
|
||||
internal/ceres/visibility_based_preconditioner.h
|
||||
internal/ceres/visibility.h
|
||||
)
|
||||
@@ -203,7 +220,7 @@ if(WIN32)
|
||||
|
||||
if(NOT MINGW)
|
||||
list(APPEND INC
|
||||
third_party/msinttypes
|
||||
../msinttypes
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
@@ -214,11 +231,30 @@ endif()
|
||||
|
||||
add_definitions(
|
||||
-DCERES_HAVE_PTHREAD
|
||||
-D"CERES_HASH_NAMESPACE_START=namespace std { namespace tr1 {"
|
||||
-D"CERES_HASH_NAMESPACE_END=}}"
|
||||
-DCERES_NO_SUITESPARSE
|
||||
-DCERES_DONT_HAVE_PROTOCOL_BUFFERS
|
||||
-DCERES_NO_CXSPARSE
|
||||
-DCERES_NO_PROTOCOL_BUFFERS
|
||||
-DCERES_RESTRICT_SCHUR_SPECIALIZATION
|
||||
)
|
||||
|
||||
if(MSVC10)
|
||||
add_definitions(
|
||||
-D"CERES_HASH_NAMESPACE_START=namespace std {"
|
||||
-D"CERES_HASH_NAMESPACE_END=}"
|
||||
)
|
||||
else()
|
||||
add_definitions(
|
||||
-D"CERES_HASH_NAMESPACE_START=namespace std { namespace tr1 {"
|
||||
-D"CERES_HASH_NAMESPACE_END=}}"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
if(CMAKE_OSX_DEPLOYMENT_TARGET STREQUAL "10.5")
|
||||
add_definitions(
|
||||
-DCERES_NO_TR1
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
blender_add_lib(extern_ceres "${SRC}" "${INC}" "${INC_SYS}")
|
||||
|
||||
780
extern/libmv/third_party/ceres/ChangeLog
vendored
780
extern/libmv/third_party/ceres/ChangeLog
vendored
@@ -1,324 +1,524 @@
|
||||
commit ca72152362ae1f4b9928c012e74b4d49d094a4ca
|
||||
Merge: d297f8d 0a04199
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Wed May 9 13:10:59 2012 -0700
|
||||
commit 552f9f85bba89f00ca307bc18fbda1dff23bd0e4
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Fri Aug 31 07:27:22 2012 -0700
|
||||
|
||||
Merge branch 'master' into windows
|
||||
|
||||
commit 0a04199ef279cc9ea97f665fed8e7fae717813c3
|
||||
Merge: fdeb577 f2571f1
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Wed May 9 12:54:56 2012 -0700
|
||||
|
||||
Merge branch 'master' of https://code.google.com/p/ceres-solver
|
||||
|
||||
commit fdeb5772cc5eeebca4d776d220d80cc91b6d0f74
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Wed May 9 07:38:07 2012 -0700
|
||||
|
||||
Support varying numbers of residuals in autodiff.
|
||||
Various minor bug fixes to the solver logic.
|
||||
|
||||
This commit modifies the only function in autodiff that takes a
|
||||
templated number of outputs (i.e. residuals) and makes that
|
||||
template parameter a normal parameter. With that change, it
|
||||
is a trivial matter to support a dynamic number of residuals.
|
||||
1. CostFunction returning false is handled better.
|
||||
If only the cost is being evaluated, it is possible to
|
||||
use the false value as an infinite value signal/outside
|
||||
a region of validity. This allows a weak form of constraint
|
||||
handling. Useful for example in handling infinities.
|
||||
|
||||
The API for dynamic residuals is to pass a fake number of
|
||||
residuals as the second template argument to
|
||||
AutoDiffCostFunction, and to pass the real number of
|
||||
parameters as a second constructor argument.
|
||||
|
||||
commit da3e0563cc12e08e7b3e0fbf11d9cc8cfe9658aa
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Wed May 9 11:57:47 2012 -0700
|
||||
|
||||
Typo corrections in the documentation from Bing
|
||||
|
||||
commit aa9526d8e8fb34c23d63e3af5bf9239b0c4ea603
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Tue May 8 21:22:09 2012 -0700
|
||||
|
||||
Share search paths across various library searches.
|
||||
Fix typos in glog search.
|
||||
Split the error messages for include and lib.
|
||||
Enable building of tests by default.
|
||||
Made building on homebrew installations a bit better.
|
||||
Remove temporary variables for glog and gflags.
|
||||
|
||||
commit f2571f186850ed3dd316236ac4be488979df7d30
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Wed May 9 11:57:47 2012 -0700
|
||||
|
||||
Typo corrections in the documentation from Bing
|
||||
|
||||
commit 8f7f11ff7d07737435428a2620c52419cf99f98e
|
||||
Merge: e6c17c4 eaccbb3
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Wed May 9 11:34:15 2012 -0700
|
||||
|
||||
Merge branch 'master' of https://code.google.com/p/ceres-solver
|
||||
|
||||
commit e6c17c4c9d9307218f6f739cea39bc2d87733d4d
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Tue May 8 21:22:09 2012 -0700
|
||||
|
||||
Share search paths across various library searches.
|
||||
Fix typos in glog search.
|
||||
Split the error messages for include and lib.
|
||||
Enable building of tests by default.
|
||||
Made building on homebrew installations a bit better.
|
||||
Remove temporary variables for glog and gflags.
|
||||
|
||||
commit eaccbb345614c0d24c5e21fa931f470cfda874df
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Wed May 9 05:31:29 2012 -0700
|
||||
|
||||
Remove unused template parameter from VariadicEvaluate.
|
||||
|
||||
commit 82f4b88c34b0b2cf85064e5fc20e374e978b2e3b
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Sun May 6 21:05:28 2012 -0700
|
||||
|
||||
Extend support writing linear least squares problems to disk.
|
||||
2. Changed the way how the slop around zero when model_cost
|
||||
is larger than the current cost. Relative instead of absolute
|
||||
tolerances are used. The same logic is propagated how the
|
||||
corresponding clamping of the model_cost is done.
|
||||
|
||||
1. Make the mechanism for writing problems to disk, generic and
|
||||
controllable using an enum DumpType visible in the API.
|
||||
3. Fixed a minor indexing bug in nist.cc.
|
||||
|
||||
2. Instead of single file containing protocol buffers, now matrices can
|
||||
be written in a matlab/octave friendly format. This is now the default.
|
||||
4. Some minor logging fixes to nist.cc to make it more
|
||||
compatible with the rest of ceres.
|
||||
|
||||
3. The support for writing problems to disk is moved into
|
||||
linear_least_squares_problem.cc/h
|
||||
Together these changes, take the successful solve count from
|
||||
41/54 to 46/54 and eliminate all NUMERICAL_FAILURE problems.
|
||||
|
||||
4. SparseMatrix now has a ToTextFile virtual method which is
|
||||
implemented by each of its subclasses to write a (i,j,s) triplets.
|
||||
|
||||
5. Minor changes to simple_bundle_adjuster to enable logging at startup.
|
||||
Change-Id: If94170ea4731af5b243805c0200963dd31aa94a7
|
||||
|
||||
commit d297f8d3d3f5025c24752f0f4c1ec2469a769f99
|
||||
Merge: 7e74d81 f8bd7fa
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Tue May 8 05:39:56 2012 -0700
|
||||
|
||||
Merge branch 'master' into windows
|
||||
|
||||
commit f8bd7fa9aa9dbf64b6165606630287cf8cf21194
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Tue May 8 05:39:32 2012 -0700
|
||||
|
||||
Small tweaks to the block jacobi preconditioner.
|
||||
|
||||
commit 7e74d81ad57a159f14110eb5348b3bc7990b8bd4
|
||||
Merge: ecd7c8d e2a6cdc
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Mon May 7 07:02:49 2012 -0700
|
||||
|
||||
Merge branch 'master' into windows
|
||||
|
||||
commit e2a6cdc0816af9d0c77933f5017f137da3d52a35
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Mon May 7 06:39:56 2012 -0700
|
||||
|
||||
Address some of the comments on CGNR patch
|
||||
|
||||
- Rename BlockDiagonalPreconditioner to BlockJacobiPreconditioner
|
||||
- Include the diagonal in the block jacobi preconditioner.
|
||||
- Better flag help for eta.
|
||||
- Enable test for CGNR
|
||||
- Rename CONJUGATE_GRADIENTS to CGNR.
|
||||
- etc.
|
||||
|
||||
commit 1b95dc580aa5d89be021c0915e26df83f18013bb
|
||||
Merge: 211812a 7646039
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Mon May 7 04:34:10 2012 -0700
|
||||
|
||||
Merge branch 'master' of https://code.google.com/p/ceres-solver
|
||||
|
||||
commit 211812a57360d2011cbcfd115cd55e0eb73600db
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Mon May 7 04:33:50 2012 -0700
|
||||
|
||||
Better error handling in bundle_adjuster.cc
|
||||
|
||||
commit 7646039ad9672b267495f5b31925473ad3022ac8
|
||||
commit 0b776b5cc9634d3b88d623905b96006f7647ce3e
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Sun May 6 22:02:19 2012 -0700
|
||||
Date: Thu Aug 30 15:26:17 2012 -0700
|
||||
|
||||
Kashif's corrections to the docs
|
||||
|
||||
commit 0d2d34148d10c5c7e924b3ca82ad2b237573ef64
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Sun May 6 21:16:03 2012 -0700
|
||||
|
||||
glog minimum version requirements
|
||||
Update docs.
|
||||
|
||||
Building Ceres requires version 0.3.1 or better of glog.
|
||||
Fedora 16 ships with a busted version 0.3.
|
||||
Change-Id: I69d50bcd37aed3bea2190ca614f023e83172901b
|
||||
|
||||
commit 2d7176ad7c8fb7238ca8abd6de73415d95877494
|
||||
Author: Petter Strandmark <petter.strandmark@gmail.com>
|
||||
Date: Thu Aug 30 19:51:24 2012 -0700
|
||||
|
||||
max_consecutive_nonmonotonic_steps should be int
|
||||
|
||||
issue 15 contains the gory details.
|
||||
Found via Visual Studio warning.
|
||||
|
||||
Added a note to the build documentation to this effect.
|
||||
Change-Id: Id2cd7de562dfc8cd35df5d5f5220dd2d7350eb2c
|
||||
|
||||
commit 39efc5ec4b64b8f5a2c5a3dbacdbc45421221547
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Sun May 6 16:09:52 2012 -0700
|
||||
|
||||
Fix tests broken by the CGNR change.
|
||||
|
||||
commit 3faa08b7f7c4ac73661c6a15a6824c12080dfcb1
|
||||
commit 1a89bcc94e88933f89b20427a45bc40cdd23c056
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Sun May 6 16:08:22 2012 -0700
|
||||
Date: Thu Aug 30 15:26:17 2012 -0700
|
||||
|
||||
Formatting fixed based on Keir's comments and extended the tests
|
||||
|
||||
commit 4f21c68409bc478c431a9b6aedf9e5cfdf11d2f3
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Sun May 6 15:33:47 2012 -0700
|
||||
|
||||
Fix the struct weak ordering used by independent set ordering, tests for it
|
||||
|
||||
commit 887b156b917ccd4c172484452b059d33ea45f4f0
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Sun May 6 15:14:47 2012 -0700
|
||||
|
||||
fix he degree ordering routine
|
||||
|
||||
commit ecd7c8df2af19404dc394b36bbe96e9db3bce840
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Sun May 6 00:09:41 2012 -0700
|
||||
|
||||
First step towards windows compatibilty
|
||||
Better reporting on the NIST problems.
|
||||
|
||||
This adds some small changes to Ceres to make it mostly
|
||||
compile on Windows. There are still issues with the
|
||||
hash map use in schur_ordering.cc but I will fix those
|
||||
shortly.
|
||||
Change-Id: I7cf774ec3242c0612dbe52fc233c3fc6cff3f031
|
||||
|
||||
commit f7898fba1b92f0e996571b5bfa22a37f5e3644de
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Sat May 5 20:55:08 2012 -0700
|
||||
commit ea11704857a1e4a735e096896e4d775d83981499
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Wed Aug 29 18:18:48 2012 -0700
|
||||
|
||||
Add a general sparse iterative solver: CGNR
|
||||
Basic harness for testing NIST problems.
|
||||
|
||||
This adds a new LinearOperator which implements symmetric
|
||||
products of a matrix, and a new CGNR solver to leverage
|
||||
CG to directly solve the normal equations. This also
|
||||
includes a block diagonal preconditioner. In experiments
|
||||
on problem-16, the non-preconditioned version is about
|
||||
1/5 the speed of SPARSE_SCHUR, and the preconditioned
|
||||
version using block cholesky is about 20% slower than
|
||||
SPARSE_SCHUR.
|
||||
Change-Id: I5baaa24dbf0506ceedf4a9be4ed17c84974d71a1
|
||||
|
||||
commit 0a359d6198d257776a8831c3eb98f64ee91cf836
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Sat May 5 20:33:46 2012 -0700
|
||||
commit 98bf14d2b95386c2c4a6c29154637943dae4c36c
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Thu Aug 30 10:26:44 2012 -0700
|
||||
|
||||
Comment formatting.
|
||||
|
||||
commit db4ec9312bb2f1ca7b2337812f6bad6cdd75b227
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Sat May 5 20:33:16 2012 -0700
|
||||
|
||||
Comment formatting
|
||||
|
||||
commit f10163aaf3e57f52551bcd60bbdae873890a49dd
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Fri May 4 21:33:53 2012 -0700
|
||||
|
||||
Warn about disabled schur specializations.
|
||||
Miscellaneous fixes.
|
||||
|
||||
This commit brought to you from 30,000ft.
|
||||
Change-Id: I521e11f2d20bf24960bbc6b5dab4ec8bb1503d23
|
||||
|
||||
commit ad7b2b4aaf3ccc51f2b854febd53a9df54686cfe
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Fri May 4 20:15:28 2012 -0700
|
||||
commit 1e3cbd9a4442cdd8fda43a7fb452f19dac8c74af
|
||||
Author: Petter Strandmark <strandmark@google.com>
|
||||
Date: Wed Aug 29 09:39:56 2012 -0700
|
||||
|
||||
Add vim swapfiles to .gitignore
|
||||
|
||||
commit 6447219826bf6e47b0c99d9ff0eaf5e2ba573d79
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Thu May 3 21:53:07 2012 -0700
|
||||
|
||||
1. Changes the tutorial to refer to BriefReport.
|
||||
2. Some of the enums have commas at the end.
|
||||
3. Fix a bug in the default value of circle_fit.cc in the examples.
|
||||
|
||||
commit 30c5f93c7f88dec49f76168663372772e06f17f5
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Thu May 3 10:44:43 2012 -0700
|
||||
|
||||
Rework the glog and gtest path checking to be consistent with the rest of the file and disable the dashboard support enabled by the earlier ctesting related patch.
|
||||
|
||||
commit f10b033eb4aca77919987bc551d16d8a88b10110
|
||||
Merge: cc38774 e0a52a9
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Thu May 3 08:45:20 2012 -0700
|
||||
|
||||
Merge branch 'ctest'
|
||||
|
||||
commit e0a52a993394e73bc7f7db8d520728926feab83e
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Thu May 3 08:43:34 2012 -0700
|
||||
|
||||
Arnaus Gelas' patch to add better path searching for gflags and glog
|
||||
|
||||
commit a9b8e815e1c026599734510399b10f4cf014c9cd
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Thu May 3 08:41:52 2012 -0700
|
||||
|
||||
Arnaus Gelas' patch to add .gitignore
|
||||
|
||||
commit a0cefc3347c32b2065053bbaff4f34d11529d931
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Thu May 3 08:38:33 2012 -0700
|
||||
|
||||
Arnaus Gelas' patch to move to Ctest
|
||||
|
||||
commit cc38774d74e287704915282425fbd16818a72ec3
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Thu May 3 01:27:50 2012 -0700
|
||||
|
||||
Clarify ProgramEvaluator comments.
|
||||
|
||||
commit 017c9530df557863f78212fb5ccd02814baa9fa8
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Wed May 2 08:21:59 2012 -0700
|
||||
|
||||
Mac OS X build instructions are much simpler, as homebrew takes care of gflags when glog is brought in. Also CMAKE does not need any flags to do the default thing
|
||||
|
||||
commit 92d5ab5f8ae6fe355c30b606a5f230415ee0494b
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Tue May 1 18:33:08 2012 -0700
|
||||
|
||||
Link BLAS explicitly on non-Mac platforms
|
||||
Caching the symbolic Cholesky factorization when using CXSparse
|
||||
|
||||
Fixes issue #3.
|
||||
|
||||
commit df3e54eb4a6b001b7f0560a2da73a5bd7f18615e
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Tue May 1 18:22:51 2012 -0700
|
||||
|
||||
Fix link order of CHOLMOD
|
||||
Average factorization times for bundle adjustment test problem:
|
||||
SuiteSparse: 0.2794 s.
|
||||
CXSparse: 0.4039 s.
|
||||
CXSparse cached: 0.2399 s.
|
||||
|
||||
This was working by accident due to dynamic linking. Fixes issue #2.
|
||||
|
||||
commit f477a3835329e2b48eb20c34c631a480b0f0d5bf
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Tue May 1 18:10:48 2012 -0700
|
||||
|
||||
Fix Eigen search paths
|
||||
CXSparse will still be slower, though, because it has to compute
|
||||
the transpose and J^T * J.
|
||||
|
||||
Fixes issue #1 on http://code.google.com/p/ceres-solver.
|
||||
Change-Id: If9cdaa3dd520bee84b56e5fd4953b56a93db6bde
|
||||
|
||||
commit 17fbc8ebb894c1d22bb3b0b02ea1394b580120f8
|
||||
commit 8b64140878ccd1e183d3715c38942a81fdecefde
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Tue May 1 00:21:19 2012 -0700
|
||||
Date: Wed Aug 29 05:41:22 2012 -0700
|
||||
|
||||
Minor changes to the documentation. Formatting, and typos.
|
||||
Documentation update
|
||||
|
||||
Change-Id: I271a0422e7f6f42bcfd1dc6b5dc10c7a18f6a179
|
||||
|
||||
commit 8ebb0730388045570f22b89fe8672c860cd2ad1b
|
||||
commit a5353acd85a9fd19370b3d74035d87b0f0bac230
|
||||
Author: Petter Strandmark <petter.strandmark@gmail.com>
|
||||
Date: Tue Aug 28 18:16:41 2012 -0700
|
||||
|
||||
Adding gflags include to test_util.cc
|
||||
|
||||
test_util seems to need gflags.
|
||||
|
||||
Change-Id: I0c4757960f8ac69ad599c138aea58e3c88a4ea28
|
||||
|
||||
commit 87ca1b2ba28ec512752bbcf5fc994ce1434eb765
|
||||
Author: Petter Strandmark <petter.strandmark@gmail.com>
|
||||
Date: Tue Aug 28 18:05:20 2012 -0700
|
||||
|
||||
Changing random.h to use cstdlib for Windows compability.
|
||||
|
||||
As discussed with Sameer today.
|
||||
|
||||
Change-Id: If3d0284830c6591c71cc77b8400cafb45c0da61f
|
||||
|
||||
commit aeb00a07323808a0a1816e733ad18a87d5109ea3
|
||||
Author: Petter Strandmark <strandmark@google.com>
|
||||
Date: Mon Aug 27 22:22:57 2012 -0700
|
||||
|
||||
Removing gomp for Visual Studio
|
||||
|
||||
Linking currently fails in Visual Studio due to a missing library
|
||||
"gomp.lib". This is not needed in Visual Studio. OpenMP works
|
||||
without it.
|
||||
|
||||
Change-Id: I39e204a8dd4f1b7425df7d4b222d86a8bb961432
|
||||
|
||||
commit 6f362464ba99b800494d2f15c27768a342ddaa68
|
||||
Author: Markus Moll <markus.moll@esat.kuleuven.be>
|
||||
Date: Tue Aug 28 01:03:38 2012 +0200
|
||||
|
||||
Add some tests for DoglegStrategy.
|
||||
|
||||
Not necessarily a complete set.
|
||||
|
||||
Change-Id: I14eb3a38c6fe976c8212f3934655411b6d1e0aa4
|
||||
|
||||
commit 122cf836a6dc9726489ce2fbecc6143bddc1caaf
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Fri Aug 24 16:28:27 2012 -0700
|
||||
|
||||
Documentation update.
|
||||
|
||||
Change-Id: I0a3c5ae4bc981a8f5bdd5a8905f923dc5f09a024
|
||||
|
||||
commit 69081719f73da8de2935774a42d237837a91952a
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Mon Apr 30 23:09:08 2012 -0700
|
||||
Date: Mon Aug 27 13:28:56 2012 -0700
|
||||
|
||||
Initial commit of Ceres Solver.
|
||||
Remove unnecessary overload for hash<>
|
||||
|
||||
The overload for pointers in hash tables was applied in normal
|
||||
usage of schur_ordering.cc. However, the tests did not include the
|
||||
overload since they only included collections_port.h. As a result,
|
||||
the routines in schur_ordering.cc were using a different hash
|
||||
function than that inside the tests.
|
||||
|
||||
The fix is to remove the specialization. If this breaks one of the
|
||||
compiler configurations, we will find a workaround at that time.
|
||||
|
||||
Change-Id: Idbf60415d5e2aec0c865b514ad0c577d21b91405
|
||||
|
||||
commit 1762420b6ed76b1c4d30b913b2cac1927b666534
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Wed Aug 22 10:01:31 2012 -0700
|
||||
|
||||
Update changelog.
|
||||
|
||||
Change-Id: Idf5af69d5a9dbe35f58e30a8afcbfcd29bb7ebfe
|
||||
|
||||
commit 976ab7aca908309b8282cb40bc080ca859136854
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Thu Aug 23 18:21:36 2012 -0700
|
||||
|
||||
Remove Google-era vestigial unit test.
|
||||
|
||||
Change-Id: Ia7a295a5c759a17c1675a3055d287d3e40e9e0fe
|
||||
|
||||
commit 6ad6257de0e2152ac5e77dc003758de45187d6ea
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Wed Aug 22 11:10:31 2012 -0700
|
||||
|
||||
Add a workaround for an Android NDK compiler bug.
|
||||
|
||||
On certain NDK build configurations, one of the innermost
|
||||
parts of the Schur eliminator would get compiled
|
||||
incorrectly. The compiler changed a -= to a +=.
|
||||
|
||||
The normal Ceres unit tests caught the problem; however,
|
||||
since it is not possible to build the tests with the NDK
|
||||
(only with the standalone toolchain) this was difficult to
|
||||
track down. Finding the issue involved pasting the schur
|
||||
eliminator unit test inside of solver_impl.cc and other such
|
||||
hacks.
|
||||
|
||||
Change-Id: Ie91bb545d74fe39f0c8cbd1a6eb69ee4d8b25fb2
|
||||
|
||||
commit aecb2dc92b4aa7f3bf77a1ac918e62953602392b
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Wed Aug 22 10:08:17 2012 -0700
|
||||
|
||||
Fix relative path bug in bibtex call.
|
||||
|
||||
Change-Id: I0d31786564320a6831259bcdf4c75a6b665c43ad
|
||||
|
||||
commit 1e2892009e591804df6286caebd5c960e7e3b099
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Tue Aug 21 18:00:54 2012 -0700
|
||||
|
||||
Update Summary::FullReport to report dogleg type.
|
||||
|
||||
Change-Id: I0b4be8d7486c1c4b36b299693b3fe8b0d3426537
|
||||
|
||||
commit 295ade1122a86b83e1ea605d5ca394f315874717
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Wed Aug 22 06:51:22 2012 -0700
|
||||
|
||||
Fix Eigen3 Row/Column Major storage issue.
|
||||
|
||||
Eigen3 does not allow column vectors to be stored in row-major
|
||||
format. NumericDiffCostFunction by default stores its Jacobian
|
||||
matrices in row-major format. This works fine if the residual
|
||||
contains more than one variable. But if the residual block
|
||||
depends on one variable and has more than one residuals, the
|
||||
resulting Jacobian matrix is a column matrix in row-major format
|
||||
resulting in a compile time error.
|
||||
|
||||
The fix is to check the template parameters and switch to column-major
|
||||
storage as needed.
|
||||
|
||||
Thanks to Lena Gieseke for reporting this.
|
||||
|
||||
Change-Id: Icc51c5b38e1f3609e0e1ecb3c4e4a02aecd72c3b
|
||||
|
||||
commit 9ad27e8e9fb1bbd2054e2f6ae37623e01428f1c0
|
||||
Author: Arnaud Gelas <arnaudgelas@gmail.com>
|
||||
Date: Tue Aug 21 09:56:30 2012 +0200
|
||||
|
||||
Add one uninstall target to remove all installed files
|
||||
|
||||
Change-Id: Ifcf89a6c27b25f28403d95a50e29c093a525298f
|
||||
|
||||
commit 0c3a748ee49e04fe334f8f5a433649d18003d550
|
||||
Author: Markus Moll <markus.moll@esat.kuleuven.be>
|
||||
Date: Tue Aug 21 14:44:59 2012 +0200
|
||||
|
||||
Allow equal lower and upper bound for diagonal scaling.
|
||||
|
||||
This way, setting the lower and upper bound both to 1.0, one can disable
|
||||
the automatic trust region scaling.
|
||||
|
||||
Change-Id: Ifa317a6911b813a89c1cf7fdfde25af603705319
|
||||
|
||||
commit 3d644b76adefac6475b91dc53c3ae5e01c4f4d66
|
||||
Author: Arnaud Gelas <arnaudgelas@gmail.com>
|
||||
Date: Thu Aug 16 17:33:21 2012 +0200
|
||||
|
||||
Install headers, libraries and pdf
|
||||
|
||||
Headers are installed in ${CMAKE_INSTALL_PREFIX}/include/ceres
|
||||
Libraries are installed in ${CMAKE_INSTALL_PREFIX}/lib
|
||||
pdf is installed in ${CMAKE_INSTALL_PREFIX}/share/ceres/docs
|
||||
|
||||
Change-Id: Ic175f2c2f5fa86820a1e8c64c2ed171f4a302a68
|
||||
|
||||
commit d2fb5adea4d8c2aeb43c4289c6976798a54d3cf1
|
||||
Author: Arnaud Gelas <arnaudgelas@gmail.com>
|
||||
Date: Fri Aug 17 10:11:02 2012 +0200
|
||||
|
||||
Configure gerrit hook at CMake time
|
||||
|
||||
If the source directory is a clone, at CMake time the commit-msg hook gets
|
||||
downloaded and installed in the right location.
|
||||
|
||||
Change-Id: I5fee17d050ca22d8b92a49fdcc2a1cd6659f209b
|
||||
|
||||
commit 73166098fc4b1072adc30321c666188a3909c43c
|
||||
Author: Arnaud Gelas <arnaudgelas@gmail.com>
|
||||
Date: Mon Aug 20 15:40:41 2012 +0200
|
||||
|
||||
Add one CMake option to build the examples.
|
||||
|
||||
Currently the examples are always built. For external projects, it is useful
|
||||
not to compile the examples.
|
||||
|
||||
Change-Id: I41d3bde19c7e742818e60f78222d39c43992ca8b
|
||||
|
||||
commit 86d4f1ba41ef14eb1b6b61a7936af83387b35eb2
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Mon Aug 20 11:52:04 2012 -0700
|
||||
|
||||
Add missing return statement.
|
||||
|
||||
Change-Id: I5eaf718318e27040e3c97e32ee46cf0a11176a37
|
||||
|
||||
commit 51eb229da34187a4e8ce73ed9cc0e731998bb2be
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Mon Aug 20 11:46:12 2012 -0700
|
||||
|
||||
Add Program::ToString() to aid debugging.
|
||||
|
||||
Change-Id: I0ab37ed2fe0947ca87a152919d4e7dc9b56dedc6
|
||||
|
||||
commit bcc7100635e2047dc2b77df19a4ded8a6ab4d4b9
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Mon Aug 20 11:45:04 2012 -0700
|
||||
|
||||
Ignore minted.sty.
|
||||
|
||||
Change-Id: I2467a6f801812b9007b51bf14b00757f026e4322
|
||||
|
||||
commit 9705a736dd3d6fbead0d8a6ff77102c69bbcdc08
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Mon Aug 20 11:24:05 2012 -0700
|
||||
|
||||
Add ParameterBlock::ToString() to aid debugging.
|
||||
|
||||
Change-Id: Id3f5cb27b855c536dd65a986f345bd8eb2799dfa
|
||||
|
||||
commit 0c714a70e6123ceb68e5cfcd3cfbee0d09deb1db
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Mon Aug 20 11:18:16 2012 -0700
|
||||
|
||||
Fix blanks before private in loss_function.h
|
||||
|
||||
Change-Id: I068bed6431bc7c9b7958af391655df61499000b2
|
||||
|
||||
commit 51cf7cbe3bac45c6807c2703a2fc3175d76a1b47
|
||||
Author: Markus Moll <markus.moll@esat.kuleuven.be>
|
||||
Date: Mon Aug 20 20:10:20 2012 +0200
|
||||
|
||||
Add the two-dimensional subspace search to DoglegStrategy
|
||||
|
||||
Change-Id: I5163744c100cdf07dd93343d0734ffe0e80364f3
|
||||
|
||||
commit ad1f7b772e559a911ac3a3b078b0aee1836fe785
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Mon Aug 20 11:10:34 2012 -0700
|
||||
|
||||
Add ArcTanLoss, TolerantLoss and ComposedLossFunction.
|
||||
|
||||
Based on work by James Roseborough.
|
||||
|
||||
Change-Id: Idc4e0b099028f67702bfc7fe3e43dbd96b6f9256
|
||||
|
||||
commit 05292bf8fc5208b86b4a13544615b584f6efa936
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Mon Aug 20 07:40:45 2012 -0700
|
||||
|
||||
Add a TrustRegionStrategy::Summary object.
|
||||
|
||||
Change-Id: I7caee35a3408ee4a0ec16ba407410d822929340d
|
||||
|
||||
commit b12b906c4d21c3949f0dce62c4c0d083c8edecf1
|
||||
Author: Arnaud Gelas <arnaudgelas@gmail.com>
|
||||
Date: Wed Aug 15 16:27:38 2012 +0200
|
||||
|
||||
Add one option to generate the PDF from CMake at build time
|
||||
|
||||
Make sure pygmentize is installed
|
||||
|
||||
Change-Id: I068ba45c33a8e96acc906a464b12d10d58b3e231
|
||||
|
||||
commit b9f15a59361c609ffc4a328aea9be3d265b5da81
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Sat Aug 18 13:06:19 2012 -0700
|
||||
|
||||
Add a dense Cholesky factorization based linear solver.
|
||||
|
||||
For problems with a small number of variables, but a large
|
||||
number of residuals, it is sometimes beneficial to use the
|
||||
Cholesky factorization on the normal equations, instead of
|
||||
the dense QR factorization of the Jacobian, even though it
|
||||
is numerically the better thing to do.
|
||||
|
||||
Change-Id: I3506b006195754018deec964e6e190b7e8c9ac8f
|
||||
|
||||
commit b3fa009435acf476cd373052e62988f6437970b1
|
||||
Author: Arnaud Gelas <arnaudgelas@gmail.com>
|
||||
Date: Fri Aug 17 10:31:41 2012 +0200
|
||||
|
||||
Set CMAKE_*_OUTPUT_DIRECTORY
|
||||
|
||||
Gather
|
||||
* all executables in ${CMAKE_BINARY_DIR}/bin
|
||||
* all libraries (static and dynamic) in ${CMAKE_BINARY_DIR}/lib
|
||||
|
||||
Change-Id: Ibc2fa1adfb6f0aea65d66d570259b79546bf3b07
|
||||
|
||||
commit 1b8a4d5d11671ed83cf6077e363dd95333f08ef8
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Fri Aug 17 16:49:11 2012 -0700
|
||||
|
||||
Fix a minor bug in detect_structure logging.
|
||||
|
||||
Change-Id: I117f7745e4c67595b3ff9244cde82b5b5b34ee4b
|
||||
|
||||
commit 31c1e784ab2cb9294c6e05414cf06aae2b3766de
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Fri Aug 17 16:16:32 2012 -0700
|
||||
|
||||
Minor cleanups.
|
||||
|
||||
Change-Id: Ida4866997deeaa1bc2cebd6b69313a05ac82e457
|
||||
|
||||
commit e83f7879a8b21c6976e116958caf35bcdcf41cb0
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Fri Aug 17 15:34:42 2012 -0700
|
||||
|
||||
Fix SuiteSparse3 UFConfig.h detection really.
|
||||
|
||||
Change-Id: Id187102e755b7d778dff4363f22f9a4697ed12dd
|
||||
|
||||
commit 96f25dc57658d296ee6b6633818b4f1e51d7d587
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Fri Aug 17 15:34:42 2012 -0700
|
||||
|
||||
Fix SuiteSparse3 UFConfig.h detection.
|
||||
|
||||
Change-Id: Ia59aefdb0ad7f713f76ed79692f2db4fa2821e5b
|
||||
|
||||
commit c497bd6cd9aa944f518aa491d3bc645851ff9594
|
||||
Author: Markus Moll <markus.moll@esat.kuleuven.be>
|
||||
Date: Fri Aug 17 14:40:13 2012 +0200
|
||||
|
||||
Add UFconfig and/or SuiteSparse_config test to CMakeLists.txt
|
||||
|
||||
SuiteSparse 4 requires linking to libsuitesparseconfig.a.
|
||||
Both SuiteSparse 3 and SuiteSparse 4 require an additional header
|
||||
(either UFconfig.h or SuiteSparse_config.h) that is not found if it is
|
||||
in a separate path. Therefore, add explicit checks.
|
||||
|
||||
Change-Id: I699902b5db4f1b7f17134b5a54f9aa681445e294
|
||||
|
||||
commit 383c04f4236d92801c7c674892814362dedf7ad6
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Fri Aug 17 10:14:04 2012 -0700
|
||||
|
||||
Fix QuaternionToAngleAxis to ensure rotations are between -pi and pi.
|
||||
|
||||
Thanks to Guoxuan Zhang for reporting this.
|
||||
|
||||
Change-Id: I2831ca3a04d5dc6467849c290461adbe23faaea3
|
||||
|
||||
commit dd2b17d7dd9750801ba4720bdece2062e59b7ae3
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Thu Aug 16 19:34:57 2012 -0700
|
||||
|
||||
CERES_DONT_HAVE_PROTOCOL_BUFFERS -> CERES_NO_PROTOCOL_BUFFERS.
|
||||
|
||||
Change-Id: I6c9f50e4c006faf4e75a8f417455db18357f3187
|
||||
|
||||
commit 8b4cb7aa2c74a0da62c638b2023566aa242af995
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Thu Aug 16 19:26:55 2012 -0700
|
||||
|
||||
Fix sparse linear algebra library logging in Summary::FullReport.
|
||||
|
||||
Change-Id: Id2c902dc86c00954fde7749c7b4a67dd94215a31
|
||||
|
||||
commit 47d26bcd3b38b5ff53b34768c33b499d47b26bd0
|
||||
Author: Markus Moll <markus.moll@esat.kuleuven.be>
|
||||
Date: Thu Aug 16 00:23:38 2012 +0200
|
||||
|
||||
Do not implicitly negate the step in the TrustRegionMinimizer.
|
||||
|
||||
In the TrustRegionMinimizer, the step is currently implicitly negated.
|
||||
This is done so that the linearized residual is |r - J*step|^2, which
|
||||
corresponds to J*step = r, so neither J nor r have to be modified.
|
||||
However, it leads to the rather unintuitive situation that the strategy
|
||||
returns a step in positive gradient direction, which you would expect to
|
||||
increase the function value. One way is to rename the "step" parameter in
|
||||
the strategy to "negative_step" and document it.
|
||||
This patch instead moves the negation inside the strategy, just around
|
||||
the linear solver call, so that it is done in a local context and easier
|
||||
to document.
|
||||
|
||||
Change-Id: Idb258149a01f61c64e22128ea221c5a30cd89c89
|
||||
|
||||
commit 51da590c8457e6664f76fe9813425a0c71351497
|
||||
Author: Markus Moll <markus.moll@esat.kuleuven.be>
|
||||
Date: Fri Aug 17 12:56:09 2012 +0200
|
||||
|
||||
Remove tmp file
|
||||
|
||||
Change-Id: I07496fafae7b0c5c12cc26ae336e0db3b5592735
|
||||
|
||||
commit 7006a1f2b1701b8d89b8d1525fc0101943802221
|
||||
Author: Sameer Agarwal <sameeragarwal@google.com>
|
||||
Date: Thu Aug 16 18:04:22 2012 -0700
|
||||
|
||||
Correct example code in Powell's function example.
|
||||
|
||||
Thanks to Petter Strandmark for pointing this out.
|
||||
|
||||
Change-Id: I967632235dccdb481396e94904bb911c9a1efe1e
|
||||
|
||||
commit 57a44b27bc6fc95b4e70fdc25c25c9925a2072a0
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Thu Aug 16 17:04:50 2012 -0700
|
||||
|
||||
Remove unnecessary flags in NDK build.
|
||||
|
||||
Change-Id: Ib5b4d0b7f2d898671252734978c789b8171d96a8
|
||||
|
||||
commit f21bee247251a8b2e836c215a84c4668c31d75cd
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Thu Aug 16 16:27:10 2012 -0700
|
||||
|
||||
Fix for fpclassify.h NDK porting work.
|
||||
|
||||
Change-Id: I69df1b4caf2941ed96a53e35e43ec54073f84f59
|
||||
|
||||
commit 8ceb02cb75b66602de44a35e413225386cb21c27
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Thu Aug 16 14:23:47 2012 -0700
|
||||
|
||||
Add Android NDK build files.
|
||||
|
||||
This adds a Android.mk build that builds a Ceres static library
|
||||
suitable for embetting in larger Android applications. This is
|
||||
useful when needing to build Ceres without GPL'd components, since
|
||||
the standalone toolchain (needed for the CMake Android build) does
|
||||
not work with STLPort.
|
||||
|
||||
Change-Id: I8d857237f6f82658741017d161b2e31d9a20e5a7
|
||||
|
||||
11
extern/libmv/third_party/ceres/SConscript
vendored
11
extern/libmv/third_party/ceres/SConscript
vendored
@@ -20,11 +20,20 @@ defs.append('CERES_HAVE_PTHREAD')
|
||||
defs.append('CERES_HASH_NAMESPACE_START=namespace std { namespace tr1 {')
|
||||
defs.append('CERES_HASH_NAMESPACE_END=}}')
|
||||
defs.append('CERES_NO_SUITESPARSE')
|
||||
defs.append('CERES_DONT_HAVE_PROTOCOL_BUFFERS')
|
||||
defs.append('CERES_NO_CXSPARSE')
|
||||
defs.append('CERES_NO_PROTOCOL_BUFFERS')
|
||||
defs.append('CERES_RESTRICT_SCHUR_SPECIALIZATION')
|
||||
|
||||
if 'Mac OS X 10.5' in env['MACOSX_SDK_CHECK']:
|
||||
defs.append('CERES_NO_TR1')
|
||||
|
||||
incs = '. ../../ ../../../Eigen3 ./include ./internal ../gflags'
|
||||
|
||||
# work around broken hashtable in 10.5 SDK
|
||||
if env['OURPLATFORM'] == 'darwin' and env['WITH_BF_BOOST']:
|
||||
incs += ' ' + env['BF_BOOST_INC']
|
||||
defs.append('CERES_HASH_BOOST')
|
||||
|
||||
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
|
||||
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
|
||||
incs += ' ../msinttypes'
|
||||
|
||||
55
extern/libmv/third_party/ceres/bundle.sh
vendored
55
extern/libmv/third_party/ceres/bundle.sh
vendored
@@ -1,6 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
if false; then
|
||||
if [ "x$1" = "x--i-really-know-what-im-doing" ] ; then
|
||||
echo Proceeding as requested by command line ...
|
||||
else
|
||||
@@ -8,16 +7,22 @@ else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
repo="https://code.google.com/p/ceres-solver/"
|
||||
branch="windows"
|
||||
repo="https://ceres-solver.googlesource.com/ceres-solver"
|
||||
branch="master"
|
||||
tag="1.3.0"
|
||||
tmp=`mktemp -d`
|
||||
checkout="$tmp/ceres"
|
||||
|
||||
GIT="git --git-dir $tmp/ceres/.git --work-tree $tmp/ceres"
|
||||
GIT="git --git-dir $tmp/ceres/.git --work-tree $checkout"
|
||||
|
||||
git clone $repo $tmp/ceres
|
||||
git clone $repo $checkout
|
||||
|
||||
if [ $branch != "master" ]; then
|
||||
$GIT checkout -t remotes/origin/$branch
|
||||
else
|
||||
if [ "x$tag" != "x" ]; then
|
||||
$GIT checkout $tag
|
||||
fi
|
||||
fi
|
||||
|
||||
$GIT log -n 50 > ChangeLog
|
||||
@@ -37,8 +42,6 @@ done
|
||||
|
||||
rm -rf $tmp
|
||||
|
||||
fi
|
||||
|
||||
sources=`find ./include ./internal -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//\t/' | grep -v -E 'schur_eliminator_[0-9]_[0-9]_[0-9d].cc' | sort -d`
|
||||
generated_sources=`find ./include ./internal -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//#\t\t/' | grep -E 'schur_eliminator_[0-9]_[0-9]_[0-9d].cc' | sort -d`
|
||||
headers=`find ./include ./internal -type f -iname '*.h' | sed -r 's/^\.\//\t/' | sort -d`
|
||||
@@ -142,7 +145,7 @@ if(WIN32)
|
||||
|
||||
if(NOT MINGW)
|
||||
list(APPEND INC
|
||||
third_party/msinttypes
|
||||
../msinttypes
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
@@ -153,13 +156,32 @@ endif()
|
||||
|
||||
add_definitions(
|
||||
-DCERES_HAVE_PTHREAD
|
||||
-D"CERES_HASH_NAMESPACE_START=namespace std { namespace tr1 {"
|
||||
-D"CERES_HASH_NAMESPACE_END=}}"
|
||||
-DCERES_NO_SUITESPARSE
|
||||
-DCERES_DONT_HAVE_PROTOCOL_BUFFERS
|
||||
-DCERES_NO_CXSPARSE
|
||||
-DCERES_NO_PROTOCOL_BUFFERS
|
||||
-DCERES_RESTRICT_SCHUR_SPECIALIZATION
|
||||
)
|
||||
|
||||
if(MSVC10)
|
||||
add_definitions(
|
||||
-D"CERES_HASH_NAMESPACE_START=namespace std {"
|
||||
-D"CERES_HASH_NAMESPACE_END=}"
|
||||
)
|
||||
else()
|
||||
add_definitions(
|
||||
-D"CERES_HASH_NAMESPACE_START=namespace std { namespace tr1 {"
|
||||
-D"CERES_HASH_NAMESPACE_END=}}"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
if(CMAKE_OSX_DEPLOYMENT_TARGET STREQUAL "10.5")
|
||||
add_definitions(
|
||||
-DCERES_NO_TR1
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
blender_add_lib(extern_ceres "\${SRC}" "\${INC}" "\${INC_SYS}")
|
||||
EOF
|
||||
|
||||
@@ -186,11 +208,20 @@ defs.append('CERES_HAVE_PTHREAD')
|
||||
defs.append('CERES_HASH_NAMESPACE_START=namespace std { namespace tr1 {')
|
||||
defs.append('CERES_HASH_NAMESPACE_END=}}')
|
||||
defs.append('CERES_NO_SUITESPARSE')
|
||||
defs.append('CERES_DONT_HAVE_PROTOCOL_BUFFERS')
|
||||
defs.append('CERES_NO_CXSPARSE')
|
||||
defs.append('CERES_NO_PROTOCOL_BUFFERS')
|
||||
defs.append('CERES_RESTRICT_SCHUR_SPECIALIZATION')
|
||||
|
||||
if 'Mac OS X 10.5' in env['MACOSX_SDK_CHECK']:
|
||||
defs.append('CERES_NO_TR1')
|
||||
|
||||
incs = '. ../../ ../../../Eigen3 ./include ./internal ../gflags'
|
||||
|
||||
# work around broken hashtable in 10.5 SDK
|
||||
if env['OURPLATFORM'] == 'darwin' and env['WITH_BF_BOOST']:
|
||||
incs += ' ' + env['BF_BOOST_INC']
|
||||
defs.append('CERES_HASH_BOOST')
|
||||
|
||||
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
|
||||
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
|
||||
incs += ' ../msinttypes'
|
||||
|
||||
22
extern/libmv/third_party/ceres/files.txt
vendored
22
extern/libmv/third_party/ceres/files.txt
vendored
@@ -2,6 +2,8 @@ include/ceres/autodiff_cost_function.h
|
||||
include/ceres/ceres.h
|
||||
include/ceres/conditioned_cost_function.h
|
||||
include/ceres/cost_function.h
|
||||
include/ceres/crs_matrix.h
|
||||
include/ceres/fpclassify.h
|
||||
include/ceres/internal/autodiff.h
|
||||
include/ceres/internal/eigen.h
|
||||
include/ceres/internal/fixed_array.h
|
||||
@@ -20,6 +22,8 @@ include/ceres/rotation.h
|
||||
include/ceres/sized_cost_function.h
|
||||
include/ceres/solver.h
|
||||
include/ceres/types.h
|
||||
internal/ceres/array_utils.cc
|
||||
internal/ceres/array_utils.h
|
||||
internal/ceres/block_evaluate_preparer.cc
|
||||
internal/ceres/block_evaluate_preparer.h
|
||||
internal/ceres/block_jacobian_writer.cc
|
||||
@@ -52,13 +56,19 @@ internal/ceres/conjugate_gradients_solver.cc
|
||||
internal/ceres/conjugate_gradients_solver.h
|
||||
internal/ceres/corrector.cc
|
||||
internal/ceres/corrector.h
|
||||
internal/ceres/cxsparse.cc
|
||||
internal/ceres/cxsparse.h
|
||||
internal/ceres/dense_jacobian_writer.h
|
||||
internal/ceres/dense_normal_cholesky_solver.cc
|
||||
internal/ceres/dense_normal_cholesky_solver.h
|
||||
internal/ceres/dense_qr_solver.cc
|
||||
internal/ceres/dense_qr_solver.h
|
||||
internal/ceres/dense_sparse_matrix.cc
|
||||
internal/ceres/dense_sparse_matrix.h
|
||||
internal/ceres/detect_structure.cc
|
||||
internal/ceres/detect_structure.h
|
||||
internal/ceres/dogleg_strategy.cc
|
||||
internal/ceres/dogleg_strategy.h
|
||||
internal/ceres/evaluator.cc
|
||||
internal/ceres/evaluator.h
|
||||
internal/ceres/file.cc
|
||||
@@ -79,6 +89,7 @@ internal/ceres/generated/schur_eliminator_4_4_3.cc
|
||||
internal/ceres/generated/schur_eliminator_4_4_4.cc
|
||||
internal/ceres/generated/schur_eliminator_4_4_d.cc
|
||||
internal/ceres/generated/schur_eliminator_d_d_d.cc
|
||||
internal/ceres/generate_eliminator_specialization.py
|
||||
internal/ceres/gradient_checking_cost_function.cc
|
||||
internal/ceres/gradient_checking_cost_function.h
|
||||
internal/ceres/graph_algorithms.h
|
||||
@@ -88,8 +99,8 @@ internal/ceres/implicit_schur_complement.h
|
||||
internal/ceres/integral_types.h
|
||||
internal/ceres/iterative_schur_complement_solver.cc
|
||||
internal/ceres/iterative_schur_complement_solver.h
|
||||
internal/ceres/levenberg_marquardt.cc
|
||||
internal/ceres/levenberg_marquardt.h
|
||||
internal/ceres/levenberg_marquardt_strategy.cc
|
||||
internal/ceres/levenberg_marquardt_strategy.h
|
||||
internal/ceres/linear_least_squares_problems.cc
|
||||
internal/ceres/linear_least_squares_problems.h
|
||||
internal/ceres/linear_operator.cc
|
||||
@@ -106,6 +117,8 @@ internal/ceres/normal_prior.cc
|
||||
internal/ceres/parameter_block.h
|
||||
internal/ceres/partitioned_matrix_view.cc
|
||||
internal/ceres/partitioned_matrix_view.h
|
||||
internal/ceres/polynomial_solver.cc
|
||||
internal/ceres/polynomial_solver.h
|
||||
internal/ceres/problem.cc
|
||||
internal/ceres/problem_impl.cc
|
||||
internal/ceres/problem_impl.h
|
||||
@@ -136,6 +149,7 @@ internal/ceres/sparse_matrix.h
|
||||
internal/ceres/sparse_normal_cholesky_solver.cc
|
||||
internal/ceres/sparse_normal_cholesky_solver.h
|
||||
internal/ceres/split.cc
|
||||
internal/ceres/split.h
|
||||
internal/ceres/stl_util.h
|
||||
internal/ceres/stringprintf.cc
|
||||
internal/ceres/stringprintf.h
|
||||
@@ -143,6 +157,10 @@ internal/ceres/suitesparse.cc
|
||||
internal/ceres/suitesparse.h
|
||||
internal/ceres/triplet_sparse_matrix.cc
|
||||
internal/ceres/triplet_sparse_matrix.h
|
||||
internal/ceres/trust_region_minimizer.cc
|
||||
internal/ceres/trust_region_minimizer.h
|
||||
internal/ceres/trust_region_strategy.cc
|
||||
internal/ceres/trust_region_strategy.h
|
||||
internal/ceres/types.cc
|
||||
internal/ceres/visibility_based_preconditioner.cc
|
||||
internal/ceres/visibility_based_preconditioner.h
|
||||
|
||||
@@ -163,7 +163,7 @@ class AutoDiffCostFunction :
|
||||
explicit AutoDiffCostFunction(CostFunctor* functor)
|
||||
: functor_(functor) {
|
||||
CHECK_NE(M, DYNAMIC) << "Can't run the fixed-size constructor if the "
|
||||
<< "number of residuals is set to ceres::DYNAMIC.";
|
||||
<< "number of residuals is set to ceres::DYNAMIC.";
|
||||
}
|
||||
|
||||
// Takes ownership of functor. Ignores the template-provided number of
|
||||
@@ -174,7 +174,7 @@ class AutoDiffCostFunction :
|
||||
AutoDiffCostFunction(CostFunctor* functor, int num_residuals)
|
||||
: functor_(functor) {
|
||||
CHECK_EQ(M, DYNAMIC) << "Can't run the dynamic-size constructor if the "
|
||||
<< "number of residuals is not ceres::DYNAMIC.";
|
||||
<< "number of residuals is not ceres::DYNAMIC.";
|
||||
SizedCostFunction<M, N0, N1, N2, N3, N4, N5>::set_num_residuals(num_residuals);
|
||||
}
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ class CostFunction {
|
||||
// number of outputs (residuals).
|
||||
vector<int16> parameter_block_sizes_;
|
||||
int num_residuals_;
|
||||
DISALLOW_COPY_AND_ASSIGN(CostFunction);
|
||||
CERES_DISALLOW_COPY_AND_ASSIGN(CostFunction);
|
||||
};
|
||||
|
||||
} // namespace ceres
|
||||
|
||||
65
extern/libmv/third_party/ceres/include/ceres/crs_matrix.h
vendored
Normal file
65
extern/libmv/third_party/ceres/include/ceres/crs_matrix.h
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
// Ceres Solver - A fast non-linear least squares minimizer
|
||||
// Copyright 2012 Google Inc. All rights reserved.
|
||||
// http://code.google.com/p/ceres-solver/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: sameeragarwal@google.com (Sameer Agarwal)
|
||||
|
||||
#ifndef CERES_PUBLIC_CRS_MATRIX_H_
|
||||
#define CERES_PUBLIC_CRS_MATRIX_H_
|
||||
|
||||
#include <vector>
|
||||
#include "ceres/internal/port.h"
|
||||
|
||||
namespace ceres {
|
||||
|
||||
// A compressed row sparse matrix used primarily for communicating the
|
||||
// Jacobian matrix to the user.
|
||||
struct CRSMatrix {
|
||||
CRSMatrix() : num_rows(0), num_cols(0) {}
|
||||
|
||||
int num_rows;
|
||||
int num_cols;
|
||||
|
||||
// A compressed row matrix stores its contents in three arrays.
|
||||
// The non-zero pattern of the i^th row is given by
|
||||
//
|
||||
// rows[cols[i] ... cols[i + 1]]
|
||||
//
|
||||
// and the corresponding values by
|
||||
//
|
||||
// values[cols[i] ... cols[i + 1]]
|
||||
//
|
||||
// Thus, cols is a vector of size num_cols + 1, and rows and values
|
||||
// have as many entries as number of non-zeros in the matrix.
|
||||
vector<int> cols;
|
||||
vector<int> rows;
|
||||
vector<double> values;
|
||||
};
|
||||
|
||||
} // namespace ceres
|
||||
|
||||
#endif // CERES_PUBLIC_CRS_MATRIX_H_
|
||||
88
extern/libmv/third_party/ceres/include/ceres/fpclassify.h
vendored
Normal file
88
extern/libmv/third_party/ceres/include/ceres/fpclassify.h
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
// Ceres Solver - A fast non-linear least squares minimizer
|
||||
// Copyright 2012 Google Inc. All rights reserved.
|
||||
// http://code.google.com/p/ceres-solver/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: keir@google.com (Keir Mierle)
|
||||
//
|
||||
// Portable floating point classification. The names are picked such that they
|
||||
// do not collide with macros. For example, "isnan" in C99 is a macro and hence
|
||||
// does not respect namespaces.
|
||||
//
|
||||
// TODO(keir): Finish porting!
|
||||
|
||||
#ifndef CERES_PUBLIC_FPCLASSIFY_H_
|
||||
#define CERES_PUBLIC_FPCLASSIFY_H_
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <float.h>
|
||||
#endif
|
||||
|
||||
namespace ceres {
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
inline bool IsFinite (double x) { return _finite(x); }
|
||||
inline bool IsInfinite(double x) { return !_finite(x) && !_isnan(x); }
|
||||
inline bool IsNaN (double x) { return _isnan(x); }
|
||||
inline bool IsNormal (double x) {
|
||||
int classification = _fpclass(x);
|
||||
return classification == _FPCLASS_NN ||
|
||||
classification == _FPCLASS_PN;
|
||||
}
|
||||
#elif defined(ANDROID)
|
||||
|
||||
// On Android when using the GNU STL, the C++ fpclassify functions are not
|
||||
// available. Strictly speaking, the std functions are are not standard until
|
||||
// C++11. Instead use the C99 macros on Android.
|
||||
inline bool IsNaN (double x) { return isnan(x); }
|
||||
inline bool IsNormal (double x) { return isnormal(x); }
|
||||
|
||||
// On Android NDK r6, when using STLPort, the isinf and isfinite functions are
|
||||
// not available, so reimplement them.
|
||||
# if defined(_STLPORT_VERSION)
|
||||
inline bool IsInfinite(double x) {
|
||||
return x == std::numeric_limits<double>::infinity() ||
|
||||
x == -std::numeric_limits<double>::infinity();
|
||||
}
|
||||
inline bool IsFinite(double x) {
|
||||
return !isnan(x) && !IsInfinite(x);
|
||||
}
|
||||
# else
|
||||
inline bool IsFinite (double x) { return isfinite(x); }
|
||||
inline bool IsInfinite(double x) { return isinf(x); }
|
||||
# endif // defined(_STLPORT_VERSION)
|
||||
#else
|
||||
// These definitions are for the normal Unix suspects.
|
||||
// TODO(keir): Test the "else" with more platforms.
|
||||
inline bool IsFinite (double x) { return std::isfinite(x); }
|
||||
inline bool IsInfinite(double x) { return std::isinf(x); }
|
||||
inline bool IsNaN (double x) { return std::isnan(x); }
|
||||
inline bool IsNormal (double x) { return std::isnormal(x); }
|
||||
#endif
|
||||
|
||||
} // namespace ceres
|
||||
|
||||
#endif // CERES_PUBLIC_FPCLASSIFY_H_
|
||||
@@ -34,6 +34,8 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <glog/logging.h>
|
||||
#include "Eigen/Core"
|
||||
#include "ceres/internal/macros.h"
|
||||
#include "ceres/internal/manual_constructor.h"
|
||||
|
||||
namespace ceres {
|
||||
@@ -136,7 +138,6 @@ class FixedArray {
|
||||
// and T must be the same, otherwise callers' assumptions about use
|
||||
// of this code will be broken.
|
||||
struct InnerContainer {
|
||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
|
||||
T element;
|
||||
};
|
||||
|
||||
|
||||
@@ -43,11 +43,13 @@
|
||||
//
|
||||
// For disallowing only assign or copy, write the code directly, but declare
|
||||
// the intend in a comment, for example:
|
||||
// void operator=(const TypeName&); // DISALLOW_ASSIGN
|
||||
// Note, that most uses of DISALLOW_ASSIGN and DISALLOW_COPY are broken
|
||||
// semantically, one should either use disallow both or neither. Try to
|
||||
// avoid these in new code.
|
||||
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
||||
//
|
||||
// void operator=(const TypeName&); // _DISALLOW_ASSIGN
|
||||
|
||||
// Note, that most uses of CERES_DISALLOW_ASSIGN and CERES_DISALLOW_COPY
|
||||
// are broken semantically, one should either use disallow both or
|
||||
// neither. Try to avoid these in new code.
|
||||
#define CERES_DISALLOW_COPY_AND_ASSIGN(TypeName) \
|
||||
TypeName(const TypeName&); \
|
||||
void operator=(const TypeName&)
|
||||
|
||||
@@ -57,9 +59,9 @@
|
||||
// This should be used in the private: declarations for a class
|
||||
// that wants to prevent anyone from instantiating it. This is
|
||||
// especially useful for classes containing only static methods.
|
||||
#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
|
||||
#define CERES_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
|
||||
TypeName(); \
|
||||
DISALLOW_COPY_AND_ASSIGN(TypeName)
|
||||
CERES_DISALLOW_COPY_AND_ASSIGN(TypeName)
|
||||
|
||||
// The arraysize(arr) macro returns the # of elements in an array arr.
|
||||
// The expression is a compile-time constant, and therefore can be
|
||||
@@ -151,4 +153,19 @@ char (&ArraySizeHelper(const T (&array)[N]))[N];
|
||||
#define MUST_USE_RESULT
|
||||
#endif
|
||||
|
||||
// Platform independent macros to get aligned memory allocations.
|
||||
// For example
|
||||
//
|
||||
// MyFoo my_foo CERES_ALIGN_ATTRIBUTE(16);
|
||||
//
|
||||
// Gives us an instance of MyFoo which is aligned at a 16 byte
|
||||
// boundary.
|
||||
#if defined(_MSC_VER)
|
||||
#define CERES_ALIGN_ATTRIBUTE(n) __declspec(align(n))
|
||||
#define CERES_ALIGN_OF(T) __alignof(T)
|
||||
#elif defined(__GNUC__)
|
||||
#define CERES_ALIGN_ATTRIBUTE(n) __attribute__((aligned(n)))
|
||||
#define CERES_ALIGN_OF(T) __alignof(T)
|
||||
#endif
|
||||
|
||||
#endif // CERES_PUBLIC_INTERNAL_MACROS_H_
|
||||
|
||||
@@ -45,60 +45,49 @@
|
||||
namespace ceres {
|
||||
namespace internal {
|
||||
|
||||
// ------- Define ALIGNED_CHAR_ARRAY --------------------------------
|
||||
// ------- Define CERES_ALIGNED_CHAR_ARRAY --------------------------------
|
||||
|
||||
#ifndef ALIGNED_CHAR_ARRAY
|
||||
#ifndef CERES_ALIGNED_CHAR_ARRAY
|
||||
|
||||
// Because MSVC and older GCCs require that the argument to their alignment
|
||||
// construct to be a literal constant integer, we use a template instantiated
|
||||
// at all the possible powers of two.
|
||||
template<int alignment, int size> struct AlignType { };
|
||||
template<int size> struct AlignType<0, size> { typedef char result[size]; };
|
||||
#if defined(_MSC_VER)
|
||||
#define BASE_PORT_H_ALIGN_ATTRIBUTE(X) __declspec(align(X))
|
||||
#define BASE_PORT_H_ALIGN_OF(T) __alignof(T)
|
||||
#elif defined(__GNUC__)
|
||||
#define BASE_PORT_H_ALIGN_ATTRIBUTE(X) __attribute__((aligned(X)))
|
||||
#define BASE_PORT_H_ALIGN_OF(T) __alignof__(T)
|
||||
#endif
|
||||
|
||||
#if defined(BASE_PORT_H_ALIGN_ATTRIBUTE)
|
||||
#if !defined(CERES_ALIGN_ATTRIBUTE)
|
||||
#define CERES_ALIGNED_CHAR_ARRAY you_must_define_CERES_ALIGNED_CHAR_ARRAY_for_your_compiler
|
||||
#else // !defined(CERES_ALIGN_ATTRIBUTE)
|
||||
|
||||
#define BASE_PORT_H_ALIGNTYPE_TEMPLATE(X) \
|
||||
#define CERES_ALIGN_TYPE_TEMPLATE(X) \
|
||||
template<int size> struct AlignType<X, size> { \
|
||||
typedef BASE_PORT_H_ALIGN_ATTRIBUTE(X) char result[size]; \
|
||||
typedef CERES_ALIGN_ATTRIBUTE(X) char result[size]; \
|
||||
}
|
||||
|
||||
BASE_PORT_H_ALIGNTYPE_TEMPLATE(1);
|
||||
BASE_PORT_H_ALIGNTYPE_TEMPLATE(2);
|
||||
BASE_PORT_H_ALIGNTYPE_TEMPLATE(4);
|
||||
BASE_PORT_H_ALIGNTYPE_TEMPLATE(8);
|
||||
BASE_PORT_H_ALIGNTYPE_TEMPLATE(16);
|
||||
BASE_PORT_H_ALIGNTYPE_TEMPLATE(32);
|
||||
BASE_PORT_H_ALIGNTYPE_TEMPLATE(64);
|
||||
BASE_PORT_H_ALIGNTYPE_TEMPLATE(128);
|
||||
BASE_PORT_H_ALIGNTYPE_TEMPLATE(256);
|
||||
BASE_PORT_H_ALIGNTYPE_TEMPLATE(512);
|
||||
BASE_PORT_H_ALIGNTYPE_TEMPLATE(1024);
|
||||
BASE_PORT_H_ALIGNTYPE_TEMPLATE(2048);
|
||||
BASE_PORT_H_ALIGNTYPE_TEMPLATE(4096);
|
||||
BASE_PORT_H_ALIGNTYPE_TEMPLATE(8192);
|
||||
CERES_ALIGN_TYPE_TEMPLATE(1);
|
||||
CERES_ALIGN_TYPE_TEMPLATE(2);
|
||||
CERES_ALIGN_TYPE_TEMPLATE(4);
|
||||
CERES_ALIGN_TYPE_TEMPLATE(8);
|
||||
CERES_ALIGN_TYPE_TEMPLATE(16);
|
||||
CERES_ALIGN_TYPE_TEMPLATE(32);
|
||||
CERES_ALIGN_TYPE_TEMPLATE(64);
|
||||
CERES_ALIGN_TYPE_TEMPLATE(128);
|
||||
CERES_ALIGN_TYPE_TEMPLATE(256);
|
||||
CERES_ALIGN_TYPE_TEMPLATE(512);
|
||||
CERES_ALIGN_TYPE_TEMPLATE(1024);
|
||||
CERES_ALIGN_TYPE_TEMPLATE(2048);
|
||||
CERES_ALIGN_TYPE_TEMPLATE(4096);
|
||||
CERES_ALIGN_TYPE_TEMPLATE(8192);
|
||||
// Any larger and MSVC++ will complain.
|
||||
|
||||
#define ALIGNED_CHAR_ARRAY(T, Size) \
|
||||
typename AlignType<BASE_PORT_H_ALIGN_OF(T), sizeof(T) * Size>::result
|
||||
#undef CERES_ALIGN_TYPE_TEMPLATE
|
||||
|
||||
#undef BASE_PORT_H_ALIGNTYPE_TEMPLATE
|
||||
#undef BASE_PORT_H_ALIGN_ATTRIBUTE
|
||||
#define CERES_ALIGNED_CHAR_ARRAY(T, Size) \
|
||||
typename AlignType<CERES_ALIGN_OF(T), sizeof(T) * Size>::result
|
||||
|
||||
#else // defined(BASE_PORT_H_ALIGN_ATTRIBUTE)
|
||||
#define ALIGNED_CHAR_ARRAY you_must_define_ALIGNED_CHAR_ARRAY_for_your_compiler
|
||||
#endif // defined(BASE_PORT_H_ALIGN_ATTRIBUTE)
|
||||
#endif // !defined(CERES_ALIGN_ATTRIBUTE)
|
||||
|
||||
#undef BASE_PORT_H_ALIGNTYPE_TEMPLATE
|
||||
#undef BASE_PORT_H_ALIGN_ATTRIBUTE
|
||||
|
||||
#endif // ALIGNED_CHAR_ARRAY
|
||||
#endif // CERES_ALIGNED_CHAR_ARRAY
|
||||
|
||||
template <typename Type>
|
||||
class ManualConstructor {
|
||||
@@ -203,10 +192,10 @@ class ManualConstructor {
|
||||
}
|
||||
|
||||
private:
|
||||
ALIGNED_CHAR_ARRAY(Type, 1) space_;
|
||||
CERES_ALIGNED_CHAR_ARRAY(Type, 1) space_;
|
||||
};
|
||||
|
||||
#undef ALIGNED_CHAR_ARRAY
|
||||
#undef CERES_ALIGNED_CHAR_ARRAY
|
||||
|
||||
} // namespace internal
|
||||
} // namespace ceres
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#ifndef CERES_PUBLIC_INTERNAL_PORT_H_
|
||||
#define CERES_PUBLIC_INTERNAL_PORT_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ceres {
|
||||
|
||||
// It is unfortunate that this import of the entire standard namespace is
|
||||
@@ -39,6 +41,10 @@ namespace ceres {
|
||||
// things outside of the Ceres optimization package.
|
||||
using namespace std;
|
||||
|
||||
// This is necessary to properly handle the case that there is a different
|
||||
// "string" implementation in the global namespace.
|
||||
using std::string;
|
||||
|
||||
} // namespace ceres
|
||||
|
||||
#endif // CERES_PUBLIC_INTERNAL_PORT_H_
|
||||
|
||||
@@ -28,8 +28,9 @@
|
||||
//
|
||||
// Author: sameeragarwal@google.com (Sameer Agarwal)
|
||||
//
|
||||
// When an iteration callback is specified, Ceres calls the callback after each
|
||||
// optimizer step and pass it an IterationSummary object, defined below.
|
||||
// When an iteration callback is specified, Ceres calls the callback
|
||||
// after each minimizer step (if the minimizer has not converged) and
|
||||
// passes it an IterationSummary object, defined below.
|
||||
|
||||
#ifndef CERES_PUBLIC_ITERATION_CALLBACK_H_
|
||||
#define CERES_PUBLIC_ITERATION_CALLBACK_H_
|
||||
@@ -44,7 +45,15 @@ struct IterationSummary {
|
||||
// Current iteration number.
|
||||
int32 iteration;
|
||||
|
||||
// Step was numerically valid, i.e., all values are finite and the
|
||||
// step reduces the value of the linearized model.
|
||||
//
|
||||
// Note: step_is_valid is false when iteration = 0.
|
||||
bool step_is_valid;
|
||||
|
||||
// Whether or not the algorithm made progress in this iteration.
|
||||
//
|
||||
// Note: step_is_successful is false when iteration = 0.
|
||||
bool step_is_successful;
|
||||
|
||||
// Value of the objective function.
|
||||
@@ -66,9 +75,10 @@ struct IterationSummary {
|
||||
// cost and the change in the cost of the linearized approximation.
|
||||
double relative_decrease;
|
||||
|
||||
// Value of the regularization parameter for Levenberg-Marquardt
|
||||
// algorithm at the end of the current iteration.
|
||||
double mu;
|
||||
// Size of the trust region at the end of the current iteration. For
|
||||
// the Levenberg-Marquardt algorithm, the regularization parameter
|
||||
// mu = 1.0 / trust_region_radius.
|
||||
double trust_region_radius;
|
||||
|
||||
// For the inexact step Levenberg-Marquardt algorithm, this is the
|
||||
// relative accuracy with which the Newton(LM) step is solved. This
|
||||
@@ -81,13 +91,15 @@ struct IterationSummary {
|
||||
// Newton step.
|
||||
int linear_solver_iterations;
|
||||
|
||||
// TODO(sameeragarwal): Change to use a higher precision timer using
|
||||
// clock_gettime.
|
||||
// Time (in seconds) spent inside the linear least squares solver.
|
||||
int iteration_time_sec;
|
||||
// Time (in seconds) spent inside the minimizer loop in the current
|
||||
// iteration.
|
||||
double iteration_time_in_seconds;
|
||||
|
||||
// Time (in seconds) spent inside the linear least squares solver.
|
||||
int linear_solver_time_sec;
|
||||
// Time (in seconds) spent inside the trust region step solver.
|
||||
double step_solver_time_in_seconds;
|
||||
|
||||
// Time (in seconds) since the user called Solve().
|
||||
double cumulative_time_in_seconds;
|
||||
};
|
||||
|
||||
// Interface for specifying callbacks that are executed at the end of
|
||||
@@ -133,7 +145,7 @@ struct IterationSummary {
|
||||
// summary.gradient_max_norm,
|
||||
// summary.step_norm,
|
||||
// summary.relative_decrease,
|
||||
// summary.mu,
|
||||
// summary.trust_region_radius,
|
||||
// summary.eta,
|
||||
// summary.linear_solver_iterations);
|
||||
// if (log_to_stdout_) {
|
||||
|
||||
163
extern/libmv/third_party/ceres/include/ceres/jet.h
vendored
163
extern/libmv/third_party/ceres/include/ceres/jet.h
vendored
@@ -162,16 +162,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "Eigen/Core"
|
||||
|
||||
// Visual Studio 2010 or older version
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1600
|
||||
namespace std {
|
||||
inline bool isfinite(double x) { return _finite(x); }
|
||||
inline bool isinf (double x) { return !_finite(x) && !_isnan(x); }
|
||||
inline bool isnan (double x) { return _isnan(x); }
|
||||
inline bool isnormal(double x) { return _finite(x) && x != 0.0; }
|
||||
} // namespace std
|
||||
#endif
|
||||
#include "ceres/fpclassify.h"
|
||||
|
||||
namespace ceres {
|
||||
|
||||
@@ -184,7 +175,9 @@ struct Jet {
|
||||
// (where T is a Jet<T, N>). This usually only happens in opt mode. Note that
|
||||
// the C++ standard mandates that e.g. default constructed doubles are
|
||||
// initialized to 0.0; see sections 8.5 of the C++03 standard.
|
||||
Jet() : a() {}
|
||||
Jet() : a() {
|
||||
v.setZero();
|
||||
}
|
||||
|
||||
// Constructor from scalar: a + 0.
|
||||
explicit Jet(const T& value) {
|
||||
@@ -199,18 +192,6 @@ struct Jet {
|
||||
v[k] = T(1.0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
// Construct from an array where the first element is the scalar.
|
||||
// This is templated to support converting from other data types.
|
||||
template<typename D>
|
||||
Jet(const D* scalar_and_derivatives) {
|
||||
a = T(scalar_and_derivatives[0]);
|
||||
v = Eigen::Map<const Eigen::Matrix<D, N, 1> >(
|
||||
scalar_and_derivatives + 1, N).cast<T>();
|
||||
}
|
||||
*/
|
||||
|
||||
// Compound operators
|
||||
Jet<T, N>& operator+=(const Jet<T, N> &y) {
|
||||
*this = *this + y;
|
||||
@@ -232,8 +213,25 @@ struct Jet {
|
||||
return *this;
|
||||
}
|
||||
|
||||
T a; // The scalar part.
|
||||
Eigen::Matrix<T, N, 1> v; // The infinitesimal part.
|
||||
// The scalar part.
|
||||
T a;
|
||||
|
||||
// The infinitesimal part.
|
||||
//
|
||||
// Note the Eigen::DontAlign bit is needed here because this object
|
||||
// gets allocated on the stack and as part of other arrays and
|
||||
// structs. Forcing the right alignment there is the source of much
|
||||
// pain and suffering. Even if that works, passing Jets around to
|
||||
// functions by value has problems because the C++ ABI does not
|
||||
// guarantee alignment for function arguments.
|
||||
//
|
||||
// Setting the DontAlign bit prevents Eigen from using SSE for the
|
||||
// various operations on Jets. This is a small performance penalty
|
||||
// since the AutoDiff code will still expose much of the code as
|
||||
// statically sized loops to the compiler. But given the subtle
|
||||
// issues that arise due to alignment, especially when dealing with
|
||||
// multiple platforms, it seems to be a trade off worth making.
|
||||
Eigen::Matrix<T, N, 1, Eigen::DontAlign> v;
|
||||
};
|
||||
|
||||
// Unary +
|
||||
@@ -411,10 +409,6 @@ inline double cos (double x) { return std::cos(x); }
|
||||
inline double acos (double x) { return std::acos(x); }
|
||||
inline double sin (double x) { return std::sin(x); }
|
||||
inline double asin (double x) { return std::asin(x); }
|
||||
inline bool isfinite(double x) { return std::isfinite(x); }
|
||||
inline bool isinf (double x) { return std::isinf(x); }
|
||||
inline bool isnan (double x) { return std::isnan(x); }
|
||||
inline bool isnormal(double x) { return std::isnormal(x); }
|
||||
inline double pow (double x, double y) { return std::pow(x, y); }
|
||||
inline double atan2(double y, double x) { return std::atan2(y, x); }
|
||||
|
||||
@@ -492,22 +486,23 @@ Jet<T, N> asin(const Jet<T, N>& f) {
|
||||
}
|
||||
|
||||
// Jet Classification. It is not clear what the appropriate semantics are for
|
||||
// these classifications. This picks that isfinite and isnormal are "all"
|
||||
// operations, i.e. all elements of the jet must be finite for the jet itself to
|
||||
// be finite (or normal). For isnan and isinf, the answer is less clear. This
|
||||
// takes a "any" approach for isnan and isinf such that if any part of a jet is
|
||||
// nan or inf, then the entire jet is nan or inf. This leads to strange
|
||||
// situations like a jet can be both isinf and isnan, but in practice the "any"
|
||||
// semantics are the most useful for e.g. checking that derivatives are sane.
|
||||
// these classifications. This picks that IsFinite and isnormal are "all"
|
||||
// operations, i.e. all elements of the jet must be finite for the jet itself
|
||||
// to be finite (or normal). For IsNaN and IsInfinite, the answer is less
|
||||
// clear. This takes a "any" approach for IsNaN and IsInfinite such that if any
|
||||
// part of a jet is nan or inf, then the entire jet is nan or inf. This leads
|
||||
// to strange situations like a jet can be both IsInfinite and IsNaN, but in
|
||||
// practice the "any" semantics are the most useful for e.g. checking that
|
||||
// derivatives are sane.
|
||||
|
||||
// The jet is finite if all parts of the jet are finite.
|
||||
template <typename T, int N> inline
|
||||
bool isfinite(const Jet<T, N>& f) {
|
||||
if (!isfinite(f.a)) {
|
||||
bool IsFinite(const Jet<T, N>& f) {
|
||||
if (!IsFinite(f.a)) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < N; ++i) {
|
||||
if (!isfinite(f.v[i])) {
|
||||
if (!IsFinite(f.v[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -516,12 +511,12 @@ bool isfinite(const Jet<T, N>& f) {
|
||||
|
||||
// The jet is infinite if any part of the jet is infinite.
|
||||
template <typename T, int N> inline
|
||||
bool isinf(const Jet<T, N>& f) {
|
||||
if (isinf(f.a)) {
|
||||
bool IsInfinite(const Jet<T, N>& f) {
|
||||
if (IsInfinite(f.a)) {
|
||||
return true;
|
||||
}
|
||||
for (int i = 0; i < N; i++) {
|
||||
if (isinf(f.v[i])) {
|
||||
if (IsInfinite(f.v[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -530,12 +525,12 @@ bool isinf(const Jet<T, N>& f) {
|
||||
|
||||
// The jet is NaN if any part of the jet is NaN.
|
||||
template <typename T, int N> inline
|
||||
bool isnan(const Jet<T, N>& f) {
|
||||
if (isnan(f.a)) {
|
||||
bool IsNaN(const Jet<T, N>& f) {
|
||||
if (IsNaN(f.a)) {
|
||||
return true;
|
||||
}
|
||||
for (int i = 0; i < N; ++i) {
|
||||
if (isnan(f.v[i])) {
|
||||
if (IsNaN(f.v[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -544,12 +539,12 @@ bool isnan(const Jet<T, N>& f) {
|
||||
|
||||
// The jet is normal if all parts of the jet are normal.
|
||||
template <typename T, int N> inline
|
||||
bool isnormal(const Jet<T, N>& f) {
|
||||
if (!isnormal(f.a)) {
|
||||
bool IsNormal(const Jet<T, N>& f) {
|
||||
if (!IsNormal(f.a)) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < N; ++i) {
|
||||
if (!isnormal(f.v[i])) {
|
||||
if (!IsNormal(f.v[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -650,78 +645,6 @@ inline std::ostream &operator<<(std::ostream &s, const Jet<T, N>& z) {
|
||||
return s << "[" << z.a << " ; " << z.v.transpose() << "]";
|
||||
}
|
||||
|
||||
// A jet traits class to make it easier to work with mixed auto / numeric diff.
|
||||
template<typename T>
|
||||
struct JetOps {
|
||||
static bool IsScalar() {
|
||||
return true;
|
||||
}
|
||||
static T GetScalar(const T& t) {
|
||||
return t;
|
||||
}
|
||||
static void SetScalar(const T& scalar, T* t) {
|
||||
*t = scalar;
|
||||
}
|
||||
static void ScaleDerivative(double scale_by, T *value) {
|
||||
// For double, there is no derivative to scale.
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, int N>
|
||||
struct JetOps<Jet<T, N> > {
|
||||
static bool IsScalar() {
|
||||
return false;
|
||||
}
|
||||
static T GetScalar(const Jet<T, N>& t) {
|
||||
return t.a;
|
||||
}
|
||||
static void SetScalar(const T& scalar, Jet<T, N>* t) {
|
||||
t->a = scalar;
|
||||
}
|
||||
static void ScaleDerivative(double scale_by, Jet<T, N> *value) {
|
||||
value->v *= scale_by;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename FunctionType, int kNumArgs, typename ArgumentType>
|
||||
struct Chain {
|
||||
static ArgumentType Rule(const FunctionType &f,
|
||||
const FunctionType dfdx[kNumArgs],
|
||||
const ArgumentType x[kNumArgs]) {
|
||||
// In the default case of scalars, there's nothing to do since there are no
|
||||
// derivatives to propagate.
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
||||
// XXX Add documentation here!
|
||||
template<typename FunctionType, int kNumArgs, typename T, int N>
|
||||
struct Chain<FunctionType, kNumArgs, Jet<T, N> > {
|
||||
static Jet<T, N> Rule(const FunctionType &f,
|
||||
const FunctionType dfdx[kNumArgs],
|
||||
const Jet<T, N> x[kNumArgs]) {
|
||||
// x is itself a function of another variable ("z"); what this function
|
||||
// needs to return is "f", but with the derivative with respect to z
|
||||
// attached to the jet. So combine the derivative part of x's jets to form
|
||||
// a Jacobian matrix between x and z (i.e. dx/dz).
|
||||
Eigen::Matrix<T, kNumArgs, N> dxdz;
|
||||
for (int i = 0; i < kNumArgs; ++i) {
|
||||
dxdz.row(i) = x[i].v.transpose();
|
||||
}
|
||||
|
||||
// Map the input gradient dfdx into an Eigen row vector.
|
||||
Eigen::Map<const Eigen::Matrix<FunctionType, 1, kNumArgs> >
|
||||
vector_dfdx(dfdx, 1, kNumArgs);
|
||||
|
||||
// Now apply the chain rule to obtain df/dz. Combine the derivative with
|
||||
// the scalar part to obtain f with full derivative information.
|
||||
Jet<T, N> jet_f;
|
||||
jet_f.a = f;
|
||||
jet_f.v = vector_dfdx.template cast<T>() * dxdz; // Also known as dfdz.
|
||||
return jet_f;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ceres
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
@@ -175,6 +175,7 @@ class HuberLoss : public LossFunction {
|
||||
public:
|
||||
explicit HuberLoss(double a) : a_(a), b_(a * a) { }
|
||||
virtual void Evaluate(double, double*) const;
|
||||
|
||||
private:
|
||||
const double a_;
|
||||
// b = a^2.
|
||||
@@ -190,6 +191,7 @@ class SoftLOneLoss : public LossFunction {
|
||||
public:
|
||||
explicit SoftLOneLoss(double a) : b_(a * a), c_(1 / b_) { }
|
||||
virtual void Evaluate(double, double*) const;
|
||||
|
||||
private:
|
||||
// b = a^2.
|
||||
const double b_;
|
||||
@@ -206,6 +208,7 @@ class CauchyLoss : public LossFunction {
|
||||
public:
|
||||
explicit CauchyLoss(double a) : b_(a * a), c_(1 / b_) { }
|
||||
virtual void Evaluate(double, double*) const;
|
||||
|
||||
private:
|
||||
// b = a^2.
|
||||
const double b_;
|
||||
@@ -213,6 +216,78 @@ class CauchyLoss : public LossFunction {
|
||||
const double c_;
|
||||
};
|
||||
|
||||
// Loss that is capped beyond a certain level using the arc-tangent function.
|
||||
// The scaling parameter 'a' determines the level where falloff occurs.
|
||||
// For costs much smaller than 'a', the loss function is linear and behaves like
|
||||
// TrivialLoss, and for values much larger than 'a' the value asymptotically
|
||||
// approaches the constant value of a * PI / 2.
|
||||
//
|
||||
// rho(s) = a atan(s / a).
|
||||
//
|
||||
// At s = 0: rho = [0, 1, 0].
|
||||
class ArctanLoss : public LossFunction {
|
||||
public:
|
||||
explicit ArctanLoss(double a) : a_(a), b_(1 / (a * a)) { }
|
||||
virtual void Evaluate(double, double*) const;
|
||||
|
||||
private:
|
||||
const double a_;
|
||||
// b = 1 / a^2.
|
||||
const double b_;
|
||||
};
|
||||
|
||||
// Loss function that maps to approximately zero cost in a range around the
|
||||
// origin, and reverts to linear in error (quadratic in cost) beyond this range.
|
||||
// The tolerance parameter 'a' sets the nominal point at which the
|
||||
// transition occurs, and the transition size parameter 'b' sets the nominal
|
||||
// distance over which most of the transition occurs. Both a and b must be
|
||||
// greater than zero, and typically b will be set to a fraction of a.
|
||||
// The slope rho'[s] varies smoothly from about 0 at s <= a - b to
|
||||
// about 1 at s >= a + b.
|
||||
//
|
||||
// The term is computed as:
|
||||
//
|
||||
// rho(s) = b log(1 + exp((s - a) / b)) - c0.
|
||||
//
|
||||
// where c0 is chosen so that rho(0) == 0
|
||||
//
|
||||
// c0 = b log(1 + exp(-a / b)
|
||||
//
|
||||
// This has the following useful properties:
|
||||
//
|
||||
// rho(s) == 0 for s = 0
|
||||
// rho'(s) ~= 0 for s << a - b
|
||||
// rho'(s) ~= 1 for s >> a + b
|
||||
// rho''(s) > 0 for all s
|
||||
//
|
||||
// In addition, all derivatives are continuous, and the curvature is
|
||||
// concentrated in the range a - b to a + b.
|
||||
//
|
||||
// At s = 0: rho = [0, ~0, ~0].
|
||||
class TolerantLoss : public LossFunction {
|
||||
public:
|
||||
explicit TolerantLoss(double a, double b);
|
||||
virtual void Evaluate(double, double*) const;
|
||||
|
||||
private:
|
||||
const double a_, b_, c_;
|
||||
};
|
||||
|
||||
// Composition of two loss functions. The error is the result of first
|
||||
// evaluating g followed by f to yield the composition f(g(s)).
|
||||
// The loss functions must not be NULL.
|
||||
class ComposedLoss : public LossFunction {
|
||||
public:
|
||||
explicit ComposedLoss(const LossFunction* f, Ownership ownership_f,
|
||||
const LossFunction* g, Ownership ownership_g);
|
||||
virtual ~ComposedLoss();
|
||||
virtual void Evaluate(double, double*) const;
|
||||
|
||||
private:
|
||||
internal::scoped_ptr<const LossFunction> f_, g_;
|
||||
const Ownership ownership_f_, ownership_g_;
|
||||
};
|
||||
|
||||
// The discussion above has to do with length scaling: it affects the space
|
||||
// in which s is measured. Sometimes you want to simply scale the output
|
||||
// value of the robustifier. For example, you might want to weight
|
||||
@@ -249,7 +324,7 @@ class ScaledLoss : public LossFunction {
|
||||
internal::scoped_ptr<const LossFunction> rho_;
|
||||
const double a_;
|
||||
const Ownership ownership_;
|
||||
DISALLOW_COPY_AND_ASSIGN(ScaledLoss);
|
||||
CERES_DISALLOW_COPY_AND_ASSIGN(ScaledLoss);
|
||||
};
|
||||
|
||||
// Sometimes after the optimization problem has been constructed, we
|
||||
@@ -314,7 +389,7 @@ class LossFunctionWrapper : public LossFunction {
|
||||
private:
|
||||
internal::scoped_ptr<const LossFunction> rho_;
|
||||
Ownership ownership_;
|
||||
DISALLOW_COPY_AND_ASSIGN(LossFunctionWrapper);
|
||||
CERES_DISALLOW_COPY_AND_ASSIGN(LossFunctionWrapper);
|
||||
};
|
||||
|
||||
} // namespace ceres
|
||||
|
||||
@@ -93,11 +93,13 @@ struct Differencer {
|
||||
using Eigen::Map;
|
||||
using Eigen::Matrix;
|
||||
using Eigen::RowMajor;
|
||||
using Eigen::ColMajor;
|
||||
|
||||
typedef Matrix<double, num_residuals, 1> ResidualVector;
|
||||
typedef Matrix<double, parameter_block_size, 1> ParameterVector;
|
||||
typedef Matrix<double, num_residuals, parameter_block_size, RowMajor>
|
||||
JacobianMatrix;
|
||||
typedef Matrix<double, num_residuals, parameter_block_size,
|
||||
(parameter_block_size == 1 &&
|
||||
num_residuals > 1) ? ColMajor : RowMajor> JacobianMatrix;
|
||||
|
||||
Map<JacobianMatrix> parameter_jacobian(jacobians[parameter_block],
|
||||
num_residuals,
|
||||
|
||||
@@ -50,13 +50,13 @@ namespace ceres {
|
||||
class CostFunction;
|
||||
class LossFunction;
|
||||
class LocalParameterization;
|
||||
class Solver;
|
||||
|
||||
namespace internal {
|
||||
class Preprocessor;
|
||||
class ProblemImpl;
|
||||
class ParameterBlock;
|
||||
class ResidualBlock;
|
||||
class SolverImpl;
|
||||
} // namespace internal
|
||||
|
||||
// A ResidualBlockId is a handle clients can use to delete residual
|
||||
@@ -255,9 +255,9 @@ class Problem {
|
||||
int NumResiduals() const;
|
||||
|
||||
private:
|
||||
friend class internal::SolverImpl;
|
||||
friend class Solver;
|
||||
internal::scoped_ptr<internal::ProblemImpl> problem_impl_;
|
||||
DISALLOW_COPY_AND_ASSIGN(Problem);
|
||||
CERES_DISALLOW_COPY_AND_ASSIGN(Problem);
|
||||
};
|
||||
|
||||
} // namespace ceres
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include "glog/logging.h"
|
||||
|
||||
namespace ceres {
|
||||
|
||||
@@ -145,18 +146,11 @@ void AngleAxisRotatePoint(const T angle_axis[3], const T pt[3], T result[3]);
|
||||
|
||||
// --- IMPLEMENTATION
|
||||
|
||||
// Duplicate rather than decorate every use of cmath with _USE_MATH_CONSTANTS.
|
||||
// Necessitated by Windows.
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#define CERES_NEED_M_PI_UNDEF
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
inline void AngleAxisToQuaternion(const T* angle_axis, T* quaternion) {
|
||||
const T &a0 = angle_axis[0];
|
||||
const T &a1 = angle_axis[1];
|
||||
const T &a2 = angle_axis[2];
|
||||
const T& a0 = angle_axis[0];
|
||||
const T& a1 = angle_axis[1];
|
||||
const T& a2 = angle_axis[2];
|
||||
const T theta_squared = a0 * a0 + a1 * a1 + a2 * a2;
|
||||
|
||||
// For points not at the origin, the full conversion is numerically stable.
|
||||
@@ -183,16 +177,35 @@ inline void AngleAxisToQuaternion(const T* angle_axis, T* quaternion) {
|
||||
|
||||
template<typename T>
|
||||
inline void QuaternionToAngleAxis(const T* quaternion, T* angle_axis) {
|
||||
const T &q1 = quaternion[1];
|
||||
const T &q2 = quaternion[2];
|
||||
const T &q3 = quaternion[3];
|
||||
const T sin_squared = q1 * q1 + q2 * q2 + q3 * q3;
|
||||
const T& q1 = quaternion[1];
|
||||
const T& q2 = quaternion[2];
|
||||
const T& q3 = quaternion[3];
|
||||
const T sin_squared_theta = q1 * q1 + q2 * q2 + q3 * q3;
|
||||
|
||||
// For quaternions representing non-zero rotation, the conversion
|
||||
// is numerically stable.
|
||||
if (sin_squared > T(0.0)) {
|
||||
const T sin_theta = sqrt(sin_squared);
|
||||
const T k = T(2.0) * atan2(sin_theta, quaternion[0]) / sin_theta;
|
||||
if (sin_squared_theta > T(0.0)) {
|
||||
const T sin_theta = sqrt(sin_squared_theta);
|
||||
const T& cos_theta = quaternion[0];
|
||||
|
||||
// If cos_theta is negative, theta is greater than pi/2, which
|
||||
// means that angle for the angle_axis vector which is 2 * theta
|
||||
// would be greater than pi.
|
||||
//
|
||||
// While this will result in the correct rotation, it does not
|
||||
// result in a normalized angle-axis vector.
|
||||
//
|
||||
// In that case we observe that 2 * theta ~ 2 * theta - 2 * pi,
|
||||
// which is equivalent saying
|
||||
//
|
||||
// theta - pi = atan(sin(theta - pi), cos(theta - pi))
|
||||
// = atan(-sin(theta), -cos(theta))
|
||||
//
|
||||
const T two_theta =
|
||||
T(2.0) * ((cos_theta < 0.0)
|
||||
? atan2(-sin_theta, -cos_theta)
|
||||
: atan2(sin_theta, cos_theta));
|
||||
const T k = two_theta / sin_theta;
|
||||
angle_axis[0] = q1 * k;
|
||||
angle_axis[1] = q2 * k;
|
||||
angle_axis[2] = q3 * k;
|
||||
@@ -259,7 +272,7 @@ inline void RotationMatrixToAngleAxis(const T * R, T * angle_axis) {
|
||||
|
||||
// Case 2: theta ~ 0, means sin(theta) ~ theta to a good
|
||||
// approximation.
|
||||
if (costheta > 0) {
|
||||
if (costheta > 0.0) {
|
||||
const T kHalf = T(0.5);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
angle_axis[i] *= kHalf;
|
||||
@@ -284,8 +297,8 @@ inline void RotationMatrixToAngleAxis(const T * R, T * angle_axis) {
|
||||
// angle_axis[i] should be positive, otherwise negative.
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
angle_axis[i] = theta * sqrt((R[i*4] - costheta) * inv_one_minus_costheta);
|
||||
if (((sintheta < 0) && (angle_axis[i] > 0)) ||
|
||||
((sintheta > 0) && (angle_axis[i] < 0))) {
|
||||
if (((sintheta < 0.0) && (angle_axis[i] > 0.0)) ||
|
||||
((sintheta > 0.0) && (angle_axis[i] < 0.0))) {
|
||||
angle_axis[i] = -angle_axis[i];
|
||||
}
|
||||
}
|
||||
@@ -334,7 +347,8 @@ template <typename T>
|
||||
inline void EulerAnglesToRotationMatrix(const T* euler,
|
||||
const int row_stride,
|
||||
T* R) {
|
||||
const T degrees_to_radians(M_PI / 180.0);
|
||||
const double kPi = 3.14159265358979323846;
|
||||
const T degrees_to_radians(kPi / 180.0);
|
||||
|
||||
const T pitch(euler[0] * degrees_to_radians);
|
||||
const T roll(euler[1] * degrees_to_radians);
|
||||
@@ -517,10 +531,4 @@ void AngleAxisRotatePoint(const T angle_axis[3], const T pt[3], T result[3]) {
|
||||
|
||||
} // namespace ceres
|
||||
|
||||
// Clean define pollution.
|
||||
#ifdef CERES_NEED_M_PI_UNDEF
|
||||
#undef CERES_NEED_M_PI_UNDEF
|
||||
#undef M_PI
|
||||
#endif
|
||||
|
||||
#endif // CERES_PUBLIC_ROTATION_H_
|
||||
|
||||
@@ -34,10 +34,10 @@
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "ceres/iteration_callback.h"
|
||||
#include "ceres/crs_matrix.h"
|
||||
#include "ceres/internal/macros.h"
|
||||
#include "ceres/internal/port.h"
|
||||
#include "ceres/iteration_callback.h"
|
||||
#include "ceres/types.h"
|
||||
|
||||
namespace ceres {
|
||||
@@ -57,24 +57,47 @@ class Solver {
|
||||
struct Options {
|
||||
// Default constructor that sets up a generic sparse problem.
|
||||
Options() {
|
||||
minimizer_type = LEVENBERG_MARQUARDT;
|
||||
trust_region_strategy_type = LEVENBERG_MARQUARDT;
|
||||
dogleg_type = TRADITIONAL_DOGLEG;
|
||||
use_nonmonotonic_steps = false;
|
||||
max_consecutive_nonmonotonic_steps = 5;
|
||||
max_num_iterations = 50;
|
||||
max_solver_time_sec = 1.0e9;
|
||||
max_solver_time_in_seconds = 1e9;
|
||||
num_threads = 1;
|
||||
tau = 1e-4;
|
||||
initial_trust_region_radius = 1e4;
|
||||
max_trust_region_radius = 1e16;
|
||||
min_trust_region_radius = 1e-32;
|
||||
min_relative_decrease = 1e-3;
|
||||
lm_min_diagonal = 1e-6;
|
||||
lm_max_diagonal = 1e32;
|
||||
max_num_consecutive_invalid_steps = 5;
|
||||
function_tolerance = 1e-6;
|
||||
gradient_tolerance = 1e-10;
|
||||
parameter_tolerance = 1e-8;
|
||||
#ifndef CERES_NO_SUITESPARSE
|
||||
linear_solver_type = SPARSE_NORMAL_CHOLESKY;
|
||||
#else
|
||||
|
||||
#if defined(CERES_NO_SUITESPARSE) && defined(CERES_NO_CXSPARSE)
|
||||
linear_solver_type = DENSE_QR;
|
||||
#endif // CERES_NO_SUITESPARSE
|
||||
#else
|
||||
linear_solver_type = SPARSE_NORMAL_CHOLESKY;
|
||||
#endif
|
||||
|
||||
preconditioner_type = JACOBI;
|
||||
|
||||
sparse_linear_algebra_library = SUITE_SPARSE;
|
||||
#if defined(CERES_NO_SUITESPARSE) && !defined(CERES_NO_CXSPARSE)
|
||||
sparse_linear_algebra_library = CX_SPARSE;
|
||||
#endif
|
||||
|
||||
num_linear_solver_threads = 1;
|
||||
num_eliminate_blocks = 0;
|
||||
ordering_type = NATURAL;
|
||||
|
||||
#if defined(CERES_NO_SUITESPARSE)
|
||||
use_block_amd = false;
|
||||
#else
|
||||
use_block_amd = true;
|
||||
#endif
|
||||
|
||||
linear_solver_min_num_iterations = 1;
|
||||
linear_solver_max_num_iterations = 500;
|
||||
eta = 1e-1;
|
||||
@@ -82,10 +105,13 @@ class Solver {
|
||||
logging_type = PER_MINIMIZER_ITERATION;
|
||||
minimizer_progress_to_stdout = false;
|
||||
return_initial_residuals = false;
|
||||
return_initial_gradient = false;
|
||||
return_initial_jacobian = false;
|
||||
return_final_residuals = false;
|
||||
return_final_gradient = false;
|
||||
return_final_jacobian = false;
|
||||
lsqp_dump_directory = "/tmp";
|
||||
lsqp_dump_format_type = TEXTFILE;
|
||||
crash_and_dump_lsqp_on_failure = false;
|
||||
check_gradients = false;
|
||||
gradient_check_relative_precision = 1e-8;
|
||||
numeric_derivative_relative_step_size = 1e-6;
|
||||
@@ -94,27 +120,78 @@ class Solver {
|
||||
|
||||
// Minimizer options ----------------------------------------
|
||||
|
||||
MinimizerType minimizer_type;
|
||||
TrustRegionStrategyType trust_region_strategy_type;
|
||||
|
||||
// Type of dogleg strategy to use.
|
||||
DoglegType dogleg_type;
|
||||
|
||||
// The classical trust region methods are descent methods, in that
|
||||
// they only accept a point if it strictly reduces the value of
|
||||
// the objective function.
|
||||
//
|
||||
// Relaxing this requirement allows the algorithm to be more
|
||||
// efficient in the long term at the cost of some local increase
|
||||
// in the value of the objective function.
|
||||
//
|
||||
// This is because allowing for non-decreasing objective function
|
||||
// values in a princpled manner allows the algorithm to "jump over
|
||||
// boulders" as the method is not restricted to move into narrow
|
||||
// valleys while preserving its convergence properties.
|
||||
//
|
||||
// Setting use_nonmonotonic_steps to true enables the
|
||||
// non-monotonic trust region algorithm as described by Conn,
|
||||
// Gould & Toint in "Trust Region Methods", Section 10.1.
|
||||
//
|
||||
// The parameter max_consecutive_nonmonotonic_steps controls the
|
||||
// window size used by the step selection algorithm to accept
|
||||
// non-monotonic steps.
|
||||
//
|
||||
// Even though the value of the objective function may be larger
|
||||
// than the minimum value encountered over the course of the
|
||||
// optimization, the final parameters returned to the user are the
|
||||
// ones corresponding to the minimum cost over all iterations.
|
||||
bool use_nonmonotonic_steps;
|
||||
int max_consecutive_nonmonotonic_steps;
|
||||
|
||||
// Maximum number of iterations for the minimizer to run for.
|
||||
int max_num_iterations;
|
||||
|
||||
// Maximum time for which the minimizer should run for.
|
||||
double max_solver_time_sec;
|
||||
double max_solver_time_in_seconds;
|
||||
|
||||
// Number of threads used by Ceres for evaluating the cost and
|
||||
// jacobians.
|
||||
int num_threads;
|
||||
|
||||
// For Levenberg-Marquardt, the initial value for the
|
||||
// regularizer. This is the inversely related to the size of the
|
||||
// initial trust region.
|
||||
double tau;
|
||||
// Trust region minimizer settings.
|
||||
double initial_trust_region_radius;
|
||||
double max_trust_region_radius;
|
||||
|
||||
// For trust region methods, this is lower threshold for the
|
||||
// relative decrease before a step is accepted.
|
||||
// Minimizer terminates when the trust region radius becomes
|
||||
// smaller than this value.
|
||||
double min_trust_region_radius;
|
||||
|
||||
// Lower bound for the relative decrease before a step is
|
||||
// accepted.
|
||||
double min_relative_decrease;
|
||||
|
||||
// For the Levenberg-Marquadt algorithm, the scaled diagonal of
|
||||
// the normal equations J'J is used to control the size of the
|
||||
// trust region. Extremely small and large values along the
|
||||
// diagonal can make this regularization scheme
|
||||
// fail. lm_max_diagonal and lm_min_diagonal, clamp the values of
|
||||
// diag(J'J) from above and below. In the normal course of
|
||||
// operation, the user should not have to modify these parameters.
|
||||
double lm_min_diagonal;
|
||||
double lm_max_diagonal;
|
||||
|
||||
// Sometimes due to numerical conditioning problems or linear
|
||||
// solver flakiness, the trust region strategy may return a
|
||||
// numerically invalid step that can be fixed by reducing the
|
||||
// trust region size. So the TrustRegionMinimizer allows for a few
|
||||
// successive invalid steps before it declares NUMERICAL_FAILURE.
|
||||
int max_num_consecutive_invalid_steps;
|
||||
|
||||
// Minimizer terminates when
|
||||
//
|
||||
// (new_cost - old_cost) < function_tolerance * old_cost;
|
||||
@@ -141,6 +218,12 @@ class Solver {
|
||||
// Type of preconditioner to use with the iterative linear solvers.
|
||||
PreconditionerType preconditioner_type;
|
||||
|
||||
// Ceres supports using multiple sparse linear algebra libraries
|
||||
// for sparse matrix ordering and factorizations. Currently,
|
||||
// SUITE_SPARSE and CX_SPARSE are the valid choices, depending on
|
||||
// whether they are linked into Ceres at build time.
|
||||
SparseLinearAlgebraLibraryType sparse_linear_algebra_library;
|
||||
|
||||
// Number of threads used by Ceres to solve the Newton
|
||||
// step. Currently only the SPARSE_SCHUR solver is capable of
|
||||
// using this setting.
|
||||
@@ -170,6 +253,19 @@ class Solver {
|
||||
// non-empty.
|
||||
vector<double*> ordering;
|
||||
|
||||
// By virtue of the modeling layer in Ceres being block oriented,
|
||||
// all the matrices used by Ceres are also block oriented. When
|
||||
// doing sparse direct factorization of these matrices (for
|
||||
// SPARSE_NORMAL_CHOLESKY, SPARSE_SCHUR and ITERATIVE in
|
||||
// conjunction with CLUSTER_TRIDIAGONAL AND CLUSTER_JACOBI
|
||||
// preconditioners), the fill-reducing ordering algorithms can
|
||||
// either be run on the block or the scalar form of these matrices.
|
||||
// Running it on the block form exposes more of the super-nodal
|
||||
// structure of the matrix to the factorization routines. Setting
|
||||
// this parameter to true runs the ordering algorithms in block
|
||||
// form. Currently this option only makes sense with
|
||||
// sparse_linear_algebra_library = SUITE_SPARSE.
|
||||
bool use_block_amd;
|
||||
|
||||
// Minimum number of iterations for which the linear solver should
|
||||
// run, even if the convergence criterion is satisfied.
|
||||
@@ -206,7 +302,12 @@ class Solver {
|
||||
bool minimizer_progress_to_stdout;
|
||||
|
||||
bool return_initial_residuals;
|
||||
bool return_initial_gradient;
|
||||
bool return_initial_jacobian;
|
||||
|
||||
bool return_final_residuals;
|
||||
bool return_final_gradient;
|
||||
bool return_final_jacobian;
|
||||
|
||||
// List of iterations at which the optimizer should dump the
|
||||
// linear least squares problem to disk. Useful for testing and
|
||||
@@ -217,15 +318,6 @@ class Solver {
|
||||
string lsqp_dump_directory;
|
||||
DumpFormatType lsqp_dump_format_type;
|
||||
|
||||
// Dump the linear least squares problem to disk if the minimizer
|
||||
// fails due to NUMERICAL_FAILURE and crash the process. This flag
|
||||
// is useful for generating debugging information. The problem is
|
||||
// dumped in a file whose name is determined by
|
||||
// Solver::Options::lsqp_dump_format.
|
||||
//
|
||||
// Note: This requires a version of Ceres built with protocol buffers.
|
||||
bool crash_and_dump_lsqp_on_failure;
|
||||
|
||||
// Finite differences options ----------------------------------------------
|
||||
|
||||
// Check all jacobians computed by each residual block with finite
|
||||
@@ -273,16 +365,25 @@ class Solver {
|
||||
bool update_state_every_iteration;
|
||||
|
||||
// Callbacks that are executed at the end of each iteration of the
|
||||
// Minimizer. They are executed in the order that they are
|
||||
// specified in this vector. By default, parameter blocks are
|
||||
// updated only at the end of the optimization, i.e when the
|
||||
// Minimizer terminates. This behaviour is controlled by
|
||||
// Minimizer. An iteration may terminate midway, either due to
|
||||
// numerical failures or because one of the convergence tests has
|
||||
// been satisfied. In this case none of the callbacks are
|
||||
// executed.
|
||||
|
||||
// Callbacks are executed in the order that they are specified in
|
||||
// this vector. By default, parameter blocks are updated only at
|
||||
// the end of the optimization, i.e when the Minimizer
|
||||
// terminates. This behaviour is controlled by
|
||||
// update_state_every_variable. If the user wishes to have access
|
||||
// to the update parameter blocks when his/her callbacks are
|
||||
// executed, then set update_state_every_iteration to true.
|
||||
//
|
||||
// The solver does NOT take ownership of these pointers.
|
||||
vector<IterationCallback*> callbacks;
|
||||
|
||||
// If non-empty, a summary of the execution of the solver is
|
||||
// recorded to this file.
|
||||
string solver_log;
|
||||
};
|
||||
|
||||
struct Summary {
|
||||
@@ -313,20 +414,74 @@ class Solver {
|
||||
// blocks that they depend on were fixed.
|
||||
double fixed_cost;
|
||||
|
||||
// Residuals before and after the optimization. Each vector
|
||||
// contains problem.NumResiduals() elements. Residuals are in the
|
||||
// same order in which they were added to the problem object when
|
||||
// constructing this problem.
|
||||
// Vectors of residuals before and after the optimization. The
|
||||
// entries of these vectors are in the order in which
|
||||
// ResidualBlocks were added to the Problem object.
|
||||
//
|
||||
// Whether the residual vectors are populated with values is
|
||||
// controlled by Solver::Options::return_initial_residuals and
|
||||
// Solver::Options::return_final_residuals respectively.
|
||||
vector<double> initial_residuals;
|
||||
vector<double> final_residuals;
|
||||
|
||||
// Gradient vectors, before and after the optimization. The rows
|
||||
// are in the same order in which the ParameterBlocks were added
|
||||
// to the Problem object.
|
||||
//
|
||||
// NOTE: Since AddResidualBlock adds ParameterBlocks to the
|
||||
// Problem automatically if they do not already exist, if you wish
|
||||
// to have explicit control over the ordering of the vectors, then
|
||||
// use Problem::AddParameterBlock to explicitly add the
|
||||
// ParameterBlocks in the order desired.
|
||||
//
|
||||
// Whether the vectors are populated with values is controlled by
|
||||
// Solver::Options::return_initial_gradient and
|
||||
// Solver::Options::return_final_gradient respectively.
|
||||
vector<double> initial_gradient;
|
||||
vector<double> final_gradient;
|
||||
|
||||
// Jacobian matrices before and after the optimization. The rows
|
||||
// of these matrices are in the same order in which the
|
||||
// ResidualBlocks were added to the Problem object. The columns
|
||||
// are in the same order in which the ParameterBlocks were added
|
||||
// to the Problem object.
|
||||
//
|
||||
// NOTE: Since AddResidualBlock adds ParameterBlocks to the
|
||||
// Problem automatically if they do not already exist, if you wish
|
||||
// to have explicit control over the column ordering of the
|
||||
// matrix, then use Problem::AddParameterBlock to explicitly add
|
||||
// the ParameterBlocks in the order desired.
|
||||
//
|
||||
// The Jacobian matrices are stored as compressed row sparse
|
||||
// matrices. Please see ceres/crs_matrix.h for more details of the
|
||||
// format.
|
||||
//
|
||||
// Whether the Jacboan matrices are populated with values is
|
||||
// controlled by Solver::Options::return_initial_jacobian and
|
||||
// Solver::Options::return_final_jacobian respectively.
|
||||
CRSMatrix initial_jacobian;
|
||||
CRSMatrix final_jacobian;
|
||||
|
||||
vector<IterationSummary> iterations;
|
||||
|
||||
int num_successful_steps;
|
||||
int num_unsuccessful_steps;
|
||||
|
||||
// When the user calls Solve, before the actual optimization
|
||||
// occurs, Ceres performs a number of preprocessing steps. These
|
||||
// include error checks, memory allocations, and reorderings. This
|
||||
// time is accounted for as preprocessing time.
|
||||
double preprocessor_time_in_seconds;
|
||||
|
||||
// Time spent in the TrustRegionMinimizer.
|
||||
double minimizer_time_in_seconds;
|
||||
|
||||
// After the Minimizer is finished, some time is spent in
|
||||
// re-evaluating residuals etc. This time is accounted for in the
|
||||
// postprocessor time.
|
||||
double postprocessor_time_in_seconds;
|
||||
|
||||
// Some total of all time spent inside Ceres when Solve is called.
|
||||
double total_time_in_seconds;
|
||||
|
||||
// Preprocessor summary.
|
||||
@@ -354,6 +509,10 @@ class Solver {
|
||||
|
||||
PreconditionerType preconditioner_type;
|
||||
OrderingType ordering_type;
|
||||
|
||||
TrustRegionStrategyType trust_region_strategy_type;
|
||||
DoglegType dogleg_type;
|
||||
SparseLinearAlgebraLibraryType sparse_linear_algebra_library;
|
||||
};
|
||||
|
||||
// Once a least squares problem has been built, this function takes
|
||||
|
||||
@@ -59,14 +59,18 @@ enum LinearSolverType {
|
||||
// normal equations A'A x = A'b. They are direct solvers and do not
|
||||
// assume any special problem structure.
|
||||
|
||||
// Solve the normal equations using a sparse cholesky solver; based
|
||||
// on CHOLMOD.
|
||||
SPARSE_NORMAL_CHOLESKY,
|
||||
// Solve the normal equations using a dense Cholesky solver; based
|
||||
// on Eigen.
|
||||
DENSE_NORMAL_CHOLESKY,
|
||||
|
||||
// Solve the normal equations using a dense QR solver; based on
|
||||
// Eigen.
|
||||
DENSE_QR,
|
||||
|
||||
// Solve the normal equations using a sparse cholesky solver; requires
|
||||
// SuiteSparse or CXSparse.
|
||||
SPARSE_NORMAL_CHOLESKY,
|
||||
|
||||
// Specialized solvers, specific to problems with a generalized
|
||||
// bi-partitite structure.
|
||||
|
||||
@@ -110,6 +114,15 @@ enum PreconditionerType {
|
||||
CLUSTER_TRIDIAGONAL
|
||||
};
|
||||
|
||||
enum SparseLinearAlgebraLibraryType {
|
||||
// High performance sparse Cholesky factorization and approximate
|
||||
// minimum degree ordering.
|
||||
SUITE_SPARSE,
|
||||
|
||||
// A lightweight replacment for SuiteSparse.
|
||||
CX_SPARSE
|
||||
};
|
||||
|
||||
enum LinearSolverTerminationType {
|
||||
// Termination criterion was met. For factorization based solvers
|
||||
// the tolerance is assumed to be zero. Any user provided values are
|
||||
@@ -149,8 +162,47 @@ enum LoggingType {
|
||||
PER_MINIMIZER_ITERATION
|
||||
};
|
||||
|
||||
enum MinimizerType {
|
||||
LEVENBERG_MARQUARDT
|
||||
// Ceres supports different strategies for computing the trust region
|
||||
// step.
|
||||
enum TrustRegionStrategyType {
|
||||
// The default trust region strategy is to use the step computation
|
||||
// used in the Levenberg-Marquardt algorithm. For more details see
|
||||
// levenberg_marquardt_strategy.h
|
||||
LEVENBERG_MARQUARDT,
|
||||
|
||||
// Powell's dogleg algorithm interpolates between the Cauchy point
|
||||
// and the Gauss-Newton step. It is particularly useful if the
|
||||
// LEVENBERG_MARQUARDT algorithm is making a large number of
|
||||
// unsuccessful steps. For more details see dogleg_strategy.h.
|
||||
//
|
||||
// NOTES:
|
||||
//
|
||||
// 1. This strategy has not been experimented with or tested as
|
||||
// extensively as LEVENBERG_MARQUARDT, and therefore it should be
|
||||
// considered EXPERIMENTAL for now.
|
||||
//
|
||||
// 2. For now this strategy should only be used with exact
|
||||
// factorization based linear solvers, i.e., SPARSE_SCHUR,
|
||||
// DENSE_SCHUR, DENSE_QR and SPARSE_NORMAL_CHOLESKY.
|
||||
DOGLEG
|
||||
};
|
||||
|
||||
// Ceres supports two different dogleg strategies.
|
||||
// The "traditional" dogleg method by Powell and the
|
||||
// "subspace" method described in
|
||||
// R. H. Byrd, R. B. Schnabel, and G. A. Shultz,
|
||||
// "Approximate solution of the trust region problem by minimization
|
||||
// over two-dimensional subspaces", Mathematical Programming,
|
||||
// 40 (1988), pp. 247--263
|
||||
enum DoglegType {
|
||||
// The traditional approach constructs a dogleg path
|
||||
// consisting of two line segments and finds the furthest
|
||||
// point on that path that is still inside the trust region.
|
||||
TRADITIONAL_DOGLEG,
|
||||
|
||||
// The subspace approach finds the exact minimum of the model
|
||||
// constrained to the subspace spanned by the dogleg path.
|
||||
SUBSPACE_DOGLEG
|
||||
};
|
||||
|
||||
enum SolverTerminationType {
|
||||
@@ -246,11 +298,15 @@ enum DimensionType {
|
||||
|
||||
const char* LinearSolverTypeToString(LinearSolverType type);
|
||||
const char* PreconditionerTypeToString(PreconditionerType type);
|
||||
const char* SparseLinearAlgebraLibraryTypeToString(
|
||||
SparseLinearAlgebraLibraryType type);
|
||||
const char* LinearSolverTerminationTypeToString(
|
||||
LinearSolverTerminationType type);
|
||||
const char* OrderingTypeToString(OrderingType type);
|
||||
const char* SolverTerminationTypeToString(SolverTerminationType type);
|
||||
|
||||
const char* SparseLinearAlgebraLibraryTypeToString(
|
||||
SparseLinearAlgebraLibraryType type);
|
||||
const char* TrustRegionStrategyTypeToString( TrustRegionStrategyType type);
|
||||
bool IsSchurType(LinearSolverType type);
|
||||
|
||||
} // namespace ceres
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Ceres Solver - A fast non-linear least squares minimizer
|
||||
// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
|
||||
// Copyright 2012 Google Inc. All rights reserved.
|
||||
// http://code.google.com/p/ceres-solver/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
@@ -27,39 +27,41 @@
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: sameeragarwal@google.com (Sameer Agarwal)
|
||||
//
|
||||
// Implmentation of Levenberg Marquardt algorithm based on "Methods for
|
||||
// Nonlinear Least Squares" by K. Madsen, H.B. Nielsen and
|
||||
// O. Tingleff. Available to download from
|
||||
//
|
||||
// http://www2.imm.dtu.dk/pubdb/views/edoc_download.php/3215/pdf/imm3215.pdf
|
||||
//
|
||||
|
||||
#ifndef CERES_INTERNAL_LEVENBERG_MARQUARDT_H_
|
||||
#define CERES_INTERNAL_LEVENBERG_MARQUARDT_H_
|
||||
#include "ceres/array_utils.h"
|
||||
|
||||
#include "ceres/minimizer.h"
|
||||
#include "ceres/solver.h"
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include "ceres/fpclassify.h"
|
||||
|
||||
namespace ceres {
|
||||
namespace internal {
|
||||
|
||||
class Evaluator;
|
||||
class LinearSolver;
|
||||
// It is a near impossibility that user code generates this exact
|
||||
// value in normal operation, thus we will use it to fill arrays
|
||||
// before passing them to user code. If on return an element of the
|
||||
// array still contains this value, we will assume that the user code
|
||||
// did not write to that memory location.
|
||||
const double kImpossibleValue = 1e302;
|
||||
|
||||
class LevenbergMarquardt : public Minimizer {
|
||||
public:
|
||||
virtual ~LevenbergMarquardt();
|
||||
bool IsArrayValid(const int size, const double* x) {
|
||||
if (x != NULL) {
|
||||
for (int i = 0; i < size; ++i) {
|
||||
if (!IsFinite(x[i]) || (x[i] == kImpossibleValue)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void Minimize(const Minimizer::Options& options,
|
||||
Evaluator* evaluator,
|
||||
LinearSolver* linear_solver,
|
||||
const double* initial_parameters,
|
||||
double* final_parameters,
|
||||
Solver::Summary* summary);
|
||||
};
|
||||
void InvalidateArray(const int size, double* x) {
|
||||
if (x != NULL) {
|
||||
for (int i = 0; i < size; ++i) {
|
||||
x[i] = kImpossibleValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace ceres
|
||||
|
||||
#endif // CERES_INTERNAL_LEVENBERG_MARQUARDT_H_
|
||||
65
extern/libmv/third_party/ceres/internal/ceres/array_utils.h
vendored
Normal file
65
extern/libmv/third_party/ceres/internal/ceres/array_utils.h
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
// Ceres Solver - A fast non-linear least squares minimizer
|
||||
// Copyright 2012 Google Inc. All rights reserved.
|
||||
// http://code.google.com/p/ceres-solver/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without
|
||||
// specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: sameeragarwal@google.com (Sameer Agarwal)
|
||||
//
|
||||
// Utility routines for validating arrays.
|
||||
//
|
||||
// These are useful for detecting two common class of errors.
|
||||
//
|
||||
// 1. Uninitialized memory - where the user for some reason did not
|
||||
// compute part of an array, but the code expects it.
|
||||
//
|
||||
// 2. Numerical failure while computing the cost/residual/jacobian,
|
||||
// e.g. NaN, infinities etc. This is particularly useful since the
|
||||
// automatic differentiation code does computations that are not
|
||||
// evident to the user and can silently generate hard to debug errors.
|
||||
|
||||
#ifndef CERES_INTERNAL_ARRAY_UTILS_H_
|
||||
#define CERES_INTERNAL_ARRAY_UTILS_H_
|
||||
|
||||
#include "ceres/internal/port.h"
|
||||
|
||||
namespace ceres {
|
||||
namespace internal {
|
||||
|
||||
// Fill the array x with an impossible value that the user code is
|
||||
// never expected to compute.
|
||||
void InvalidateArray(int size, double* x);
|
||||
|
||||
// Check if all the entries of the array x are valid, i.e. all the
|
||||
// values in the array should be finite and none of them should be
|
||||
// equal to the "impossible" value used by InvalidateArray.
|
||||
bool IsArrayValid(int size, const double* x);
|
||||
|
||||
extern const double kImpossibleValue;
|
||||
|
||||
} // namespace internal
|
||||
} // namespace ceres
|
||||
|
||||
#endif // CERES_INTERNAL_ARRAY_UTILS_H_
|
||||
@@ -40,16 +40,26 @@
|
||||
namespace ceres {
|
||||
namespace internal {
|
||||
|
||||
void BlockEvaluatePreparer::Init(int** jacobian_layout) {
|
||||
void BlockEvaluatePreparer::Init(int const* const* jacobian_layout,
|
||||
int max_derivatives_per_residual_block) {
|
||||
jacobian_layout_ = jacobian_layout;
|
||||
scratch_evaluate_preparer_.Init(max_derivatives_per_residual_block);
|
||||
}
|
||||
|
||||
// Point the jacobian blocks directly into the block sparse matrix.
|
||||
void BlockEvaluatePreparer::Prepare(const ResidualBlock* residual_block,
|
||||
int residual_block_index,
|
||||
SparseMatrix* jacobian,
|
||||
double** jacobians) const {
|
||||
CHECK(jacobian != NULL);
|
||||
double** jacobians) {
|
||||
// If the overall jacobian is not available, use the scratch space.
|
||||
if (jacobian == NULL) {
|
||||
scratch_evaluate_preparer_.Prepare(residual_block,
|
||||
residual_block_index,
|
||||
jacobian,
|
||||
jacobians);
|
||||
return;
|
||||
}
|
||||
|
||||
double* jacobian_values =
|
||||
down_cast<BlockSparseMatrix*>(jacobian)->mutable_values();
|
||||
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
#ifndef CERES_INTERNAL_BLOCK_EVALUATE_PREPARER_H_
|
||||
#define CERES_INTERNAL_BLOCK_EVALUATE_PREPARER_H_
|
||||
|
||||
#include "ceres/scratch_evaluate_preparer.h"
|
||||
|
||||
namespace ceres {
|
||||
namespace internal {
|
||||
|
||||
@@ -47,18 +49,26 @@ class BlockEvaluatePreparer {
|
||||
// Using Init() instead of a constructor allows for allocating this structure
|
||||
// with new[]. This is because C++ doesn't allow passing arguments to objects
|
||||
// constructed with new[] (as opposed to plain 'new').
|
||||
void Init(int** jacobian_layout);
|
||||
void Init(int const* const* jacobian_layout,
|
||||
int max_derivatives_per_residual_block);
|
||||
|
||||
// EvaluatePreparer interface
|
||||
|
||||
// Point the jacobian blocks directly into the block sparse matrix.
|
||||
// Point the jacobian blocks directly into the block sparse matrix, if
|
||||
// jacobian is non-null. Otherwise, uses an internal per-thread buffer to
|
||||
// store the jacobians temporarily.
|
||||
void Prepare(const ResidualBlock* residual_block,
|
||||
int residual_block_index,
|
||||
SparseMatrix* jacobian,
|
||||
double** jacobians) const;
|
||||
double** jacobians);
|
||||
|
||||
private:
|
||||
int const* const* jacobian_layout_;
|
||||
|
||||
// For the case that the overall jacobian is not available, but the
|
||||
// individual jacobians are requested, use a pass-through scratch evaluate
|
||||
// preparer.
|
||||
ScratchEvaluatePreparer scratch_evaluate_preparer_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
@@ -40,11 +40,10 @@
|
||||
namespace ceres {
|
||||
namespace internal {
|
||||
|
||||
BlockJacobiPreconditioner::BlockJacobiPreconditioner(
|
||||
const LinearOperator& A)
|
||||
: block_structure_(
|
||||
*(down_cast<const BlockSparseMatrix*>(&A)->block_structure())),
|
||||
num_rows_(A.num_rows()) {
|
||||
BlockJacobiPreconditioner::BlockJacobiPreconditioner(const LinearOperator& A)
|
||||
: num_rows_(A.num_rows()),
|
||||
block_structure_(
|
||||
*(down_cast<const BlockSparseMatrix*>(&A)->block_structure())) {
|
||||
// Calculate the amount of storage needed.
|
||||
int storage_needed = 0;
|
||||
for (int c = 0; c < block_structure_.cols.size(); ++c) {
|
||||
|
||||
@@ -136,9 +136,12 @@ BlockJacobianWriter::BlockJacobianWriter(const Evaluator::Options& options,
|
||||
// makes the final Write() a nop.
|
||||
BlockEvaluatePreparer* BlockJacobianWriter::CreateEvaluatePreparers(
|
||||
int num_threads) {
|
||||
int max_derivatives_per_residual_block =
|
||||
program_->MaxDerivativesPerResidualBlock();
|
||||
|
||||
BlockEvaluatePreparer* preparers = new BlockEvaluatePreparer[num_threads];
|
||||
for (int i = 0; i < num_threads; i++) {
|
||||
preparers[i].Init(&jacobian_layout_[0]);
|
||||
preparers[i].Init(&jacobian_layout_[0], max_derivatives_per_residual_block);
|
||||
}
|
||||
return preparers;
|
||||
}
|
||||
|
||||
@@ -28,10 +28,10 @@
|
||||
//
|
||||
// Author: sameeragarwal@google.com (Sameer Agarwal)
|
||||
|
||||
#include "glog/logging.h"
|
||||
#include "ceres/block_random_access_dense_matrix.h"
|
||||
|
||||
#include <vector>
|
||||
#include <glog/logging.h>
|
||||
#include "ceres/internal/eigen.h"
|
||||
#include "ceres/internal/scoped_ptr.h"
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user